diff --git a/MODULE.bazel b/MODULE.bazel index 9b477670cf..8c64f4efae 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,6 +1,6 @@ module( name = "rules_go", - version = "0.41.0", + version = "0.42.0", compatibility_level = 0, repo_name = "io_bazel_rules_go", ) @@ -19,13 +19,13 @@ use_repo( go_sdk = use_extension("//go:extensions.bzl", "go_sdk") go_sdk.download( name = "go_default_sdk", - version = "1.20.7", + version = "1.21.1", ) use_repo(go_sdk, "go_toolchains") register_toolchains("@go_toolchains//:all") -bazel_dep(name = "gazelle", version = "0.30.0") +bazel_dep(name = "gazelle", version = "0.33.0") go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//:go.mod") diff --git a/go/private/repositories.bzl b/go/private/repositories.bzl index dc16e06c1f..4756234367 100644 --- a/go/private/repositories.bzl +++ b/go/private/repositories.bzl @@ -50,7 +50,7 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "bazel_skylib", - # 1.4.2, latest as of 2023-06-08 + # 1.4.2, latest as of 2023-09-18 urls = [ "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz", "https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz", @@ -64,13 +64,13 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "org_golang_x_tools", - # v0.7.0, latest as of 2023-03-27 + # v0.13.0, latest as of 2023-09-18 urls = [ - "https://mirror.bazel.build/github.com/golang/tools/archive/refs/tags/v0.7.0.zip", - "https://github.com/golang/tools/archive/refs/tags/v0.7.0.zip", + "https://mirror.bazel.build/github.com/golang/tools/archive/refs/tags/v0.13.0.zip", + "https://github.com/golang/tools/archive/refs/tags/v0.13.0.zip", ], - sha256 = "9f20a20f29f4008d797a8be882ef82b69cf8f7f2b96dbdfe3814c57d8280fa4b", - strip_prefix = "tools-0.7.0", + sha256 = "a44668d121ccf39fb2112ea38ab76e043f89f949c280c738f3d2a4d40a473942", + strip_prefix = "tools-0.13.0", patches = [ # deletegopls removes the gopls subdirectory. It contains a nested # module with additional dependencies. It's not needed by rules_go. @@ -83,7 +83,7 @@ def go_rules_dependencies(force = False): ) # Needed for go/tools/fetch_repo - # releaser:upgrade-dep golang tools + # releaser:upgrade-dep golang tools go vcs wrapper( http_archive, name = "org_golang_x_tools_go_vcs", @@ -105,13 +105,13 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "org_golang_x_sys", - # v0.8.0, latest as of 2023-06-08 + # v0.12.0, latest as of 2023-09-18 urls = [ - "https://mirror.bazel.build/github.com/golang/sys/archive/refs/tags/v0.8.0.zip", - "https://github.com/golang/sys/archive/refs/tags/v0.8.0.zip", + "https://mirror.bazel.build/github.com/golang/sys/archive/refs/tags/v0.12.0.zip", + "https://github.com/golang/sys/archive/refs/tags/v0.12.0.zip", ], - sha256 = "58ef1f478ba923715bc493f2e0a431d4b2d428f1e3409f6acaac452945f6fd2f", - strip_prefix = "sys-0.8.0", + sha256 = "229b079d23d18f5b1a0c46335020cddc6e5d543da2dae6e45b59d84b5d074e3a", + strip_prefix = "sys-0.12.0", patches = [ # releaser:patch-cmd gazelle -repo_root . -go_prefix golang.org/x/sys -go_naming_convention import_alias Label("//third_party:org_golang_x_sys-gazelle.patch"), @@ -124,7 +124,7 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "org_golang_x_xerrors", - # master, as of 2023-06-08 + # master, as of 2023-09-18 urls = [ "https://mirror.bazel.build/github.com/golang/xerrors/archive/04be3eba64a22a838cdb17b8dca15a52871c08b4.zip", "https://github.com/golang/xerrors/archive/04be3eba64a22a838cdb17b8dca15a52871c08b4.zip", @@ -159,13 +159,13 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "org_golang_google_protobuf", - sha256 = "cb1a05581c33b3705ede6c08edf9b9c1dbc579559ba30f532704c324e42bf801", - # v1.30.0, latest as of 2023-06-08 + sha256 = "f5d1f6d0e9b836aceb715f1df2dc065083a55b07ecec3b01b5e89d039b14da02", + # v1.31.0, latest as of 2023-09-18 urls = [ - "https://mirror.bazel.build/github.com/protocolbuffers/protobuf-go/archive/refs/tags/v1.30.0.zip", - "https://github.com/protocolbuffers/protobuf-go/archive/refs/tags/v1.30.0.zip", + "https://mirror.bazel.build/github.com/protocolbuffers/protobuf-go/archive/refs/tags/v1.31.0.zip", + "https://github.com/protocolbuffers/protobuf-go/archive/refs/tags/v1.31.0.zip", ], - strip_prefix = "protobuf-go-1.30.0", + strip_prefix = "protobuf-go-1.31.0", patches = [ # releaser:patch-cmd gazelle -repo_root . -go_prefix google.golang.org/protobuf -go_naming_convention import_alias -proto disable_global Label("//third_party:org_golang_google_protobuf-gazelle.patch"), @@ -182,7 +182,7 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "com_github_golang_protobuf", - # v1.5.3, latest as of 2023-06-08 + # v1.5.3, latest as of 2023-09-18 urls = [ "https://mirror.bazel.build/github.com/golang/protobuf/archive/refs/tags/v1.5.3.zip", "https://github.com/golang/protobuf/archive/refs/tags/v1.5.3.zip", @@ -202,7 +202,7 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "com_github_mwitkow_go_proto_validators", - # v0.3.2, latest as of 2023-06-08 + # v0.3.2, latest as of 2023-09-18 urls = [ "https://mirror.bazel.build/github.com/mwitkow/go-proto-validators/archive/refs/tags/v0.3.2.zip", "https://github.com/mwitkow/go-proto-validators/archive/refs/tags/v0.3.2.zip", @@ -216,7 +216,7 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "com_github_gogo_protobuf", - # v1.3.2, latest as of 2023-06-08 + # v1.3.2, latest as of 2023-09-18 urls = [ "https://mirror.bazel.build/github.com/gogo/protobuf/archive/refs/tags/v1.3.2.zip", "https://github.com/gogo/protobuf/archive/refs/tags/v1.3.2.zip", @@ -242,13 +242,13 @@ def go_rules_dependencies(force = False): wrapper( http_archive, name = "org_golang_google_genproto", - # main, as of 2023-06-08 + # main, as of 2023-09-18 urls = [ - "https://mirror.bazel.build/github.com/googleapis/go-genproto/archive/e85fd2cbaebc35e54b279b5e9b1057db87dacd57.zip", - "https://github.com/googleapis/go-genproto/archive/e85fd2cbaebc35e54b279b5e9b1057db87dacd57.zip", + "https://mirror.bazel.build/github.com/googleapis/go-genproto/archive/007df8e322eb3e384d36c0821e2337825c203ca6.zip", + "https://github.com/googleapis/go-genproto/archive/007df8e322eb3e384d36c0821e2337825c203ca6.zip", ], - sha256 = "da966a75fdc2f9d8006bc51e683490ff969ff637bbc030812cd9c5697e3a7cab", - strip_prefix = "go-genproto-e85fd2cbaebc35e54b279b5e9b1057db87dacd57", + sha256 = "e7d0f3faed86258ed4e8e5527a8e98ff00fbd5b1a9b379a99a4aa2f76ce8bbcc", + strip_prefix = "go-genproto-007df8e322eb3e384d36c0821e2337825c203ca6", patches = [ # releaser:patch-cmd gazelle -repo_root . -go_prefix google.golang.org/genproto -go_naming_convention import_alias -proto disable_global Label("//third_party:org_golang_google_genproto-gazelle.patch"), @@ -260,7 +260,7 @@ def go_rules_dependencies(force = False): _maybe( http_archive, name = "com_github_golang_mock", - # v1.7.0-rc.1, latest as of 2023-06-08 + # v1.7.0-rc.1, latest as of 2023-09-18 urls = [ "https://mirror.bazel.build/github.com/golang/mock/archive/refs/tags/v1.7.0-rc.1.zip", "https://github.com/golang/mock/archive/refs/tags/v1.7.0-rc.1.zip", diff --git a/tests/bcr/MODULE.bazel b/tests/bcr/MODULE.bazel index 024731c6de..58a15cba95 100644 --- a/tests/bcr/MODULE.bazel +++ b/tests/bcr/MODULE.bazel @@ -18,7 +18,7 @@ local_path_override( path = "../..", ) -bazel_dep(name = "gazelle", version = "0.32.0") +bazel_dep(name = "gazelle", version = "0.33.0") bazel_dep(name = "protobuf", version = "3.19.6") go_sdk = use_extension("@my_rules_go//go:extensions.bzl", "go_sdk") diff --git a/tests/integration/popular_repos/BUILD.bazel b/tests/integration/popular_repos/BUILD.bazel index 7b92e2c83d..b2121417ea 100644 --- a/tests/integration/popular_repos/BUILD.bazel +++ b/tests/integration/popular_repos/BUILD.bazel @@ -172,12 +172,10 @@ test_suite( "@org_golang_x_tools//go/callgraph/static:static_test", "@org_golang_x_tools//go/callgraph/vta/internal/trie:trie_test", "@org_golang_x_tools//go/cfg:cfg_test", - "@org_golang_x_tools//go/vcs:vcs_test", "@org_golang_x_tools//godoc/redirect:redirect_test", "@org_golang_x_tools//godoc/vfs:vfs_test", "@org_golang_x_tools//godoc/vfs/gatefs:gatefs_test", "@org_golang_x_tools//godoc/vfs/mapfs:mapfs_test", - "@org_golang_x_tools//internal/bug:bug_test", "@org_golang_x_tools//internal/diff:diff_test", "@org_golang_x_tools//internal/diff/lcs:lcs_test", "@org_golang_x_tools//internal/diff/myers:myers_test", @@ -326,7 +324,6 @@ build_test( "@org_golang_x_tools//go/packages/packagestest/testdata:testdata", "@org_golang_x_tools//go/packages/packagestest:packagestest", "@org_golang_x_tools//go/packages:packages", - "@org_golang_x_tools//go/pointer:pointer", "@org_golang_x_tools//go/ssa/interp:interp", "@org_golang_x_tools//go/ssa/ssautil:ssautil", "@org_golang_x_tools//go/ssa:ssa", diff --git a/third_party/com_github_gogo_protobuf-gazelle.patch b/third_party/com_github_gogo_protobuf-gazelle.patch index 4f5d47d429..ea516403ad 100644 --- a/third_party/com_github_gogo_protobuf-gazelle.patch +++ b/third_party/com_github_gogo_protobuf-gazelle.patch @@ -1,5 +1,5 @@ diff -urN a/codec/BUILD.bazel b/codec/BUILD.bazel ---- a/codec/BUILD.bazel 1969-12-31 16:00:00 +--- a/codec/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/codec/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -25,7 +25,7 @@ diff -urN a/codec/BUILD.bazel b/codec/BUILD.bazel + deps = ["//test"], +) diff -urN a/conformance/BUILD.bazel b/conformance/BUILD.bazel ---- a/conformance/BUILD.bazel 1969-12-31 16:00:00 +--- a/conformance/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/conformance/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -48,7 +48,7 @@ diff -urN a/conformance/BUILD.bazel b/conformance/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/conformance/internal/conformance_proto/BUILD.bazel b/conformance/internal/conformance_proto/BUILD.bazel ---- a/conformance/internal/conformance_proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/conformance/internal/conformance_proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/conformance/internal/conformance_proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -76,7 +76,7 @@ diff -urN a/conformance/internal/conformance_proto/BUILD.bazel b/conformance/int + visibility = ["//conformance:__subpackages__"], +) diff -urN a/gogoproto/BUILD.bazel b/gogoproto/BUILD.bazel ---- a/gogoproto/BUILD.bazel 1969-12-31 16:00:00 +--- a/gogoproto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/gogoproto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -108,7 +108,7 @@ diff -urN a/gogoproto/BUILD.bazel b/gogoproto/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/gogoreplace/BUILD.bazel b/gogoreplace/BUILD.bazel ---- a/gogoreplace/BUILD.bazel 1969-12-31 16:00:00 +--- a/gogoreplace/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/gogoreplace/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -126,7 +126,7 @@ diff -urN a/gogoreplace/BUILD.bazel b/gogoreplace/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/io/BUILD.bazel b/io/BUILD.bazel ---- a/io/BUILD.bazel 1969-12-31 16:00:00 +--- a/io/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/io/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -163,7 +163,7 @@ diff -urN a/io/BUILD.bazel b/io/BUILD.bazel + ], +) diff -urN a/jsonpb/BUILD.bazel b/jsonpb/BUILD.bazel ---- a/jsonpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/jsonpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/jsonpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -197,7 +197,7 @@ diff -urN a/jsonpb/BUILD.bazel b/jsonpb/BUILD.bazel + ], +) diff -urN a/jsonpb/jsonpb_test_proto/BUILD.bazel b/jsonpb/jsonpb_test_proto/BUILD.bazel ---- a/jsonpb/jsonpb_test_proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/jsonpb/jsonpb_test_proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/jsonpb/jsonpb_test_proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -232,7 +232,7 @@ diff -urN a/jsonpb/jsonpb_test_proto/BUILD.bazel b/jsonpb/jsonpb_test_proto/BUIL + visibility = ["//visibility:public"], +) diff -urN a/plugin/compare/BUILD.bazel b/plugin/compare/BUILD.bazel ---- a/plugin/compare/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/compare/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/compare/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -261,7 +261,7 @@ diff -urN a/plugin/compare/BUILD.bazel b/plugin/compare/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/defaultcheck/BUILD.bazel b/plugin/defaultcheck/BUILD.bazel ---- a/plugin/defaultcheck/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/defaultcheck/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/defaultcheck/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -283,7 +283,7 @@ diff -urN a/plugin/defaultcheck/BUILD.bazel b/plugin/defaultcheck/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/description/BUILD.bazel b/plugin/description/BUILD.bazel ---- a/plugin/description/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/description/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/description/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -311,7 +311,7 @@ diff -urN a/plugin/description/BUILD.bazel b/plugin/description/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/embedcheck/BUILD.bazel b/plugin/embedcheck/BUILD.bazel ---- a/plugin/embedcheck/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/embedcheck/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/embedcheck/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -333,7 +333,7 @@ diff -urN a/plugin/embedcheck/BUILD.bazel b/plugin/embedcheck/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/enumstringer/BUILD.bazel b/plugin/enumstringer/BUILD.bazel ---- a/plugin/enumstringer/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/enumstringer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/enumstringer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -355,7 +355,7 @@ diff -urN a/plugin/enumstringer/BUILD.bazel b/plugin/enumstringer/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/equal/BUILD.bazel b/plugin/equal/BUILD.bazel ---- a/plugin/equal/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/equal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/equal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -384,7 +384,7 @@ diff -urN a/plugin/equal/BUILD.bazel b/plugin/equal/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/face/BUILD.bazel b/plugin/face/BUILD.bazel ---- a/plugin/face/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/face/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/face/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -410,7 +410,7 @@ diff -urN a/plugin/face/BUILD.bazel b/plugin/face/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/gostring/BUILD.bazel b/plugin/gostring/BUILD.bazel ---- a/plugin/gostring/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/gostring/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/gostring/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -436,7 +436,7 @@ diff -urN a/plugin/gostring/BUILD.bazel b/plugin/gostring/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/marshalto/BUILD.bazel b/plugin/marshalto/BUILD.bazel ---- a/plugin/marshalto/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/marshalto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/marshalto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -461,7 +461,7 @@ diff -urN a/plugin/marshalto/BUILD.bazel b/plugin/marshalto/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/oneofcheck/BUILD.bazel b/plugin/oneofcheck/BUILD.bazel ---- a/plugin/oneofcheck/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/oneofcheck/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/oneofcheck/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -483,7 +483,7 @@ diff -urN a/plugin/oneofcheck/BUILD.bazel b/plugin/oneofcheck/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/populate/BUILD.bazel b/plugin/populate/BUILD.bazel ---- a/plugin/populate/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/populate/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/populate/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -508,7 +508,7 @@ diff -urN a/plugin/populate/BUILD.bazel b/plugin/populate/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/size/BUILD.bazel b/plugin/size/BUILD.bazel ---- a/plugin/size/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/size/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/size/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -537,7 +537,7 @@ diff -urN a/plugin/size/BUILD.bazel b/plugin/size/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/stringer/BUILD.bazel b/plugin/stringer/BUILD.bazel ---- a/plugin/stringer/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/stringer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/stringer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -563,7 +563,7 @@ diff -urN a/plugin/stringer/BUILD.bazel b/plugin/stringer/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/testgen/BUILD.bazel b/plugin/testgen/BUILD.bazel ---- a/plugin/testgen/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/testgen/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/testgen/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -585,7 +585,7 @@ diff -urN a/plugin/testgen/BUILD.bazel b/plugin/testgen/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/union/BUILD.bazel b/plugin/union/BUILD.bazel ---- a/plugin/union/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/union/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/union/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -611,7 +611,7 @@ diff -urN a/plugin/union/BUILD.bazel b/plugin/union/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/plugin/unmarshal/BUILD.bazel b/plugin/unmarshal/BUILD.bazel ---- a/plugin/unmarshal/BUILD.bazel 1969-12-31 16:00:00 +--- a/plugin/unmarshal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plugin/unmarshal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -635,7 +635,7 @@ diff -urN a/plugin/unmarshal/BUILD.bazel b/plugin/unmarshal/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/proto/BUILD.bazel b/proto/BUILD.bazel ---- a/proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,78 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -717,7 +717,7 @@ diff -urN a/proto/BUILD.bazel b/proto/BUILD.bazel + ], +) diff -urN a/proto/proto3_proto/BUILD.bazel b/proto/proto3_proto/BUILD.bazel ---- a/proto/proto3_proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/proto/proto3_proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/proto/proto3_proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -746,7 +746,7 @@ diff -urN a/proto/proto3_proto/BUILD.bazel b/proto/proto3_proto/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/proto/test_proto/BUILD.bazel b/proto/test_proto/BUILD.bazel ---- a/proto/test_proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/proto/test_proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/proto/test_proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -771,7 +771,7 @@ diff -urN a/proto/test_proto/BUILD.bazel b/proto/test_proto/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protobuf/google/protobuf/BUILD.bazel b/protobuf/google/protobuf/BUILD.bazel ---- a/protobuf/google/protobuf/BUILD.bazel 1969-12-31 16:00:00 +--- a/protobuf/google/protobuf/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protobuf/google/protobuf/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +filegroup( @@ -792,7 +792,7 @@ diff -urN a/protobuf/google/protobuf/BUILD.bazel b/protobuf/google/protobuf/BUIL + visibility = ["//visibility:public"], +) diff -urN a/protobuf/google/protobuf/compiler/BUILD.bazel b/protobuf/google/protobuf/compiler/BUILD.bazel ---- a/protobuf/google/protobuf/compiler/BUILD.bazel 1969-12-31 16:00:00 +--- a/protobuf/google/protobuf/compiler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protobuf/google/protobuf/compiler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,5 @@ +filegroup( @@ -801,7 +801,7 @@ diff -urN a/protobuf/google/protobuf/compiler/BUILD.bazel b/protobuf/google/prot + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-combo/BUILD.bazel b/protoc-gen-combo/BUILD.bazel ---- a/protoc-gen-combo/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-combo/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-combo/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -820,7 +820,7 @@ diff -urN a/protoc-gen-combo/BUILD.bazel b/protoc-gen-combo/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gofast/BUILD.bazel b/protoc-gen-gofast/BUILD.bazel ---- a/protoc-gen-gofast/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gofast/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gofast/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -842,7 +842,7 @@ diff -urN a/protoc-gen-gofast/BUILD.bazel b/protoc-gen-gofast/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/BUILD.bazel b/protoc-gen-gogo/BUILD.bazel ---- a/protoc-gen-gogo/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -867,7 +867,7 @@ diff -urN a/protoc-gen-gogo/BUILD.bazel b/protoc-gen-gogo/BUILD.bazel + embed = [":protoc-gen-gogo_lib"], +) diff -urN a/protoc-gen-gogo/descriptor/BUILD.bazel b/protoc-gen-gogo/descriptor/BUILD.bazel ---- a/protoc-gen-gogo/descriptor/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/descriptor/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/descriptor/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -900,7 +900,7 @@ diff -urN a/protoc-gen-gogo/descriptor/BUILD.bazel b/protoc-gen-gogo/descriptor/ + ], +) diff -urN a/protoc-gen-gogo/generator/BUILD.bazel b/protoc-gen-gogo/generator/BUILD.bazel ---- a/protoc-gen-gogo/generator/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/generator/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/generator/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -935,7 +935,7 @@ diff -urN a/protoc-gen-gogo/generator/BUILD.bazel b/protoc-gen-gogo/generator/BU + deps = ["//protoc-gen-gogo/descriptor"], +) diff -urN a/protoc-gen-gogo/generator/internal/remap/BUILD.bazel b/protoc-gen-gogo/generator/internal/remap/BUILD.bazel ---- a/protoc-gen-gogo/generator/internal/remap/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/generator/internal/remap/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/generator/internal/remap/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -959,7 +959,7 @@ diff -urN a/protoc-gen-gogo/generator/internal/remap/BUILD.bazel b/protoc-gen-go + embed = [":remap"], +) diff -urN a/protoc-gen-gogo/grpc/BUILD.bazel b/protoc-gen-gogo/grpc/BUILD.bazel ---- a/protoc-gen-gogo/grpc/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/grpc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/grpc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -981,7 +981,7 @@ diff -urN a/protoc-gen-gogo/grpc/BUILD.bazel b/protoc-gen-gogo/grpc/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/plugin/BUILD.bazel b/protoc-gen-gogo/plugin/BUILD.bazel ---- a/protoc-gen-gogo/plugin/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/plugin/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/plugin/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1003,7 +1003,7 @@ diff -urN a/protoc-gen-gogo/plugin/BUILD.bazel b/protoc-gen-gogo/plugin/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/BUILD.bazel b/protoc-gen-gogo/testdata/BUILD.bazel ---- a/protoc-gen-gogo/testdata/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,16 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -1023,7 +1023,7 @@ diff -urN a/protoc-gen-gogo/testdata/BUILD.bazel b/protoc-gen-gogo/testdata/BUIL + ], +) diff -urN a/protoc-gen-gogo/testdata/deprecated/BUILD.bazel b/protoc-gen-gogo/testdata/deprecated/BUILD.bazel ---- a/protoc-gen-gogo/testdata/deprecated/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/deprecated/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/deprecated/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1053,7 +1053,7 @@ diff -urN a/protoc-gen-gogo/testdata/deprecated/BUILD.bazel b/protoc-gen-gogo/te + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/extension_base/BUILD.bazel b/protoc-gen-gogo/testdata/extension_base/BUILD.bazel ---- a/protoc-gen-gogo/testdata/extension_base/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/extension_base/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/extension_base/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1078,7 +1078,7 @@ diff -urN a/protoc-gen-gogo/testdata/extension_base/BUILD.bazel b/protoc-gen-gog + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/extension_extra/BUILD.bazel b/protoc-gen-gogo/testdata/extension_extra/BUILD.bazel ---- a/protoc-gen-gogo/testdata/extension_extra/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/extension_extra/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/extension_extra/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1103,7 +1103,7 @@ diff -urN a/protoc-gen-gogo/testdata/extension_extra/BUILD.bazel b/protoc-gen-go + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/extension_user/BUILD.bazel b/protoc-gen-gogo/testdata/extension_user/BUILD.bazel ---- a/protoc-gen-gogo/testdata/extension_user/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/extension_user/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/extension_user/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1132,7 +1132,7 @@ diff -urN a/protoc-gen-gogo/testdata/extension_user/BUILD.bazel b/protoc-gen-gog + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/grpc/BUILD.bazel b/protoc-gen-gogo/testdata/grpc/BUILD.bazel ---- a/protoc-gen-gogo/testdata/grpc/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/grpc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/grpc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1168,7 +1168,7 @@ diff -urN a/protoc-gen-gogo/testdata/grpc/BUILD.bazel b/protoc-gen-gogo/testdata + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/import_public/BUILD.bazel b/protoc-gen-gogo/testdata/import_public/BUILD.bazel ---- a/protoc-gen-gogo/testdata/import_public/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/import_public/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/import_public/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1202,7 +1202,7 @@ diff -urN a/protoc-gen-gogo/testdata/import_public/BUILD.bazel b/protoc-gen-gogo + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/import_public/importing/BUILD.bazel b/protoc-gen-gogo/testdata/import_public/importing/BUILD.bazel ---- a/protoc-gen-gogo/testdata/import_public/importing/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/import_public/importing/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/import_public/importing/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1231,7 +1231,7 @@ diff -urN a/protoc-gen-gogo/testdata/import_public/importing/BUILD.bazel b/proto + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/import_public/sub/BUILD.bazel b/protoc-gen-gogo/testdata/import_public/sub/BUILD.bazel ---- a/protoc-gen-gogo/testdata/import_public/sub/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/import_public/sub/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/import_public/sub/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1262,7 +1262,7 @@ diff -urN a/protoc-gen-gogo/testdata/import_public/sub/BUILD.bazel b/protoc-gen- + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/imports/BUILD.bazel b/protoc-gen-gogo/testdata/imports/BUILD.bazel ---- a/protoc-gen-gogo/testdata/imports/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/imports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/imports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1301,7 +1301,7 @@ diff -urN a/protoc-gen-gogo/testdata/imports/BUILD.bazel b/protoc-gen-gogo/testd + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/imports/fmt/BUILD.bazel b/protoc-gen-gogo/testdata/imports/fmt/BUILD.bazel ---- a/protoc-gen-gogo/testdata/imports/fmt/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/imports/fmt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/imports/fmt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1326,7 +1326,7 @@ diff -urN a/protoc-gen-gogo/testdata/imports/fmt/BUILD.bazel b/protoc-gen-gogo/t + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/imports/test_a_1/BUILD.bazel b/protoc-gen-gogo/testdata/imports/test_a_1/BUILD.bazel ---- a/protoc-gen-gogo/testdata/imports/test_a_1/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/imports/test_a_1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/imports/test_a_1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1357,7 +1357,7 @@ diff -urN a/protoc-gen-gogo/testdata/imports/test_a_1/BUILD.bazel b/protoc-gen-g + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/imports/test_a_2/BUILD.bazel b/protoc-gen-gogo/testdata/imports/test_a_2/BUILD.bazel ---- a/protoc-gen-gogo/testdata/imports/test_a_2/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/imports/test_a_2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/imports/test_a_2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1388,7 +1388,7 @@ diff -urN a/protoc-gen-gogo/testdata/imports/test_a_2/BUILD.bazel b/protoc-gen-g + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/imports/test_b_1/BUILD.bazel b/protoc-gen-gogo/testdata/imports/test_b_1/BUILD.bazel ---- a/protoc-gen-gogo/testdata/imports/test_b_1/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/imports/test_b_1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/imports/test_b_1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1419,7 +1419,7 @@ diff -urN a/protoc-gen-gogo/testdata/imports/test_b_1/BUILD.bazel b/protoc-gen-g + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/multi/BUILD.bazel b/protoc-gen-gogo/testdata/multi/BUILD.bazel ---- a/protoc-gen-gogo/testdata/multi/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/multi/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/multi/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,9 @@ +filegroup( @@ -1432,7 +1432,7 @@ diff -urN a/protoc-gen-gogo/testdata/multi/BUILD.bazel b/protoc-gen-gogo/testdat + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/my_test/BUILD.bazel b/protoc-gen-gogo/testdata/my_test/BUILD.bazel ---- a/protoc-gen-gogo/testdata/my_test/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/my_test/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/my_test/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1457,7 +1457,7 @@ diff -urN a/protoc-gen-gogo/testdata/my_test/BUILD.bazel b/protoc-gen-gogo/testd + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogo/testdata/proto3/BUILD.bazel b/protoc-gen-gogo/testdata/proto3/BUILD.bazel ---- a/protoc-gen-gogo/testdata/proto3/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogo/testdata/proto3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogo/testdata/proto3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1482,7 +1482,7 @@ diff -urN a/protoc-gen-gogo/testdata/proto3/BUILD.bazel b/protoc-gen-gogo/testda + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogofast/BUILD.bazel b/protoc-gen-gogofast/BUILD.bazel ---- a/protoc-gen-gogofast/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogofast/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogofast/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1504,7 +1504,7 @@ diff -urN a/protoc-gen-gogofast/BUILD.bazel b/protoc-gen-gogofast/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogofaster/BUILD.bazel b/protoc-gen-gogofaster/BUILD.bazel ---- a/protoc-gen-gogofaster/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogofaster/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogofaster/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1526,7 +1526,7 @@ diff -urN a/protoc-gen-gogofaster/BUILD.bazel b/protoc-gen-gogofaster/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogoslick/BUILD.bazel b/protoc-gen-gogoslick/BUILD.bazel ---- a/protoc-gen-gogoslick/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogoslick/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogoslick/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1548,7 +1548,7 @@ diff -urN a/protoc-gen-gogoslick/BUILD.bazel b/protoc-gen-gogoslick/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gogotypes/BUILD.bazel b/protoc-gen-gogotypes/BUILD.bazel ---- a/protoc-gen-gogotypes/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gogotypes/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gogotypes/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1570,7 +1570,7 @@ diff -urN a/protoc-gen-gogotypes/BUILD.bazel b/protoc-gen-gogotypes/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-gostring/BUILD.bazel b/protoc-gen-gostring/BUILD.bazel ---- a/protoc-gen-gostring/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-gostring/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-gostring/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1592,7 +1592,7 @@ diff -urN a/protoc-gen-gostring/BUILD.bazel b/protoc-gen-gostring/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-min-version/BUILD.bazel b/protoc-min-version/BUILD.bazel ---- a/protoc-min-version/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-min-version/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-min-version/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -1611,7 +1611,7 @@ diff -urN a/protoc-min-version/BUILD.bazel b/protoc-min-version/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/sortkeys/BUILD.bazel b/sortkeys/BUILD.bazel ---- a/sortkeys/BUILD.bazel 1969-12-31 16:00:00 +--- a/sortkeys/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sortkeys/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1628,8 +1628,45 @@ diff -urN a/sortkeys/BUILD.bazel b/sortkeys/BUILD.bazel + actual = ":sortkeys", + visibility = ["//visibility:public"], +) +diff -urN a/test/asymetric-issue125/BUILD.bazel b/test/asymetric-issue125/BUILD.bazel +--- a/test/asymetric-issue125/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/test/asymetric-issue125/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,33 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++filegroup( ++ name = "go_default_library_protos", ++ srcs = ["asym.proto"], ++ visibility = ["//visibility:public"], ++) ++ ++go_library( ++ name = "asymetric-issue125", ++ srcs = [ ++ "asym.pb.go", ++ "pop.go", ++ ], ++ importpath = "github.com/gogo/protobuf/test/asymetric-issue125", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "//gogoproto", ++ "//proto", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":asymetric-issue125", ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "asymetric-issue125_test", ++ srcs = ["asym_test.go"], ++ embed = [":asymetric-issue125"], ++) diff -urN a/test/BUILD.bazel b/test/BUILD.bazel ---- a/test/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,48 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1680,45 +1717,8 @@ diff -urN a/test/BUILD.bazel b/test/BUILD.bazel + "//proto", + ], +) -diff -urN a/test/asymetric-issue125/BUILD.bazel b/test/asymetric-issue125/BUILD.bazel ---- a/test/asymetric-issue125/BUILD.bazel 1969-12-31 16:00:00 -+++ b/test/asymetric-issue125/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,33 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+filegroup( -+ name = "go_default_library_protos", -+ srcs = ["asym.proto"], -+ visibility = ["//visibility:public"], -+) -+ -+go_library( -+ name = "asymetric-issue125", -+ srcs = [ -+ "asym.pb.go", -+ "pop.go", -+ ], -+ importpath = "github.com/gogo/protobuf/test/asymetric-issue125", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "//gogoproto", -+ "//proto", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":asymetric-issue125", -+ visibility = ["//visibility:public"], -+) -+ -+go_test( -+ name = "asymetric-issue125_test", -+ srcs = ["asym_test.go"], -+ embed = [":asymetric-issue125"], -+) diff -urN a/test/cachedsize/BUILD.bazel b/test/cachedsize/BUILD.bazel ---- a/test/cachedsize/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/cachedsize/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/cachedsize/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1753,7 +1753,7 @@ diff -urN a/test/cachedsize/BUILD.bazel b/test/cachedsize/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/casttype/BUILD.bazel b/test/casttype/BUILD.bazel ---- a/test/casttype/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/casttype/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/casttype/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1777,7 +1777,7 @@ diff -urN a/test/casttype/BUILD.bazel b/test/casttype/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/casttype/combos/both/BUILD.bazel b/test/casttype/combos/both/BUILD.bazel ---- a/test/casttype/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/casttype/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/casttype/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1819,7 +1819,7 @@ diff -urN a/test/casttype/combos/both/BUILD.bazel b/test/casttype/combos/both/BU + ], +) diff -urN a/test/casttype/combos/marshaler/BUILD.bazel b/test/casttype/combos/marshaler/BUILD.bazel ---- a/test/casttype/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/casttype/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/casttype/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1861,7 +1861,7 @@ diff -urN a/test/casttype/combos/marshaler/BUILD.bazel b/test/casttype/combos/ma + ], +) diff -urN a/test/casttype/combos/neither/BUILD.bazel b/test/casttype/combos/neither/BUILD.bazel ---- a/test/casttype/combos/neither/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/casttype/combos/neither/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/casttype/combos/neither/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1903,7 +1903,7 @@ diff -urN a/test/casttype/combos/neither/BUILD.bazel b/test/casttype/combos/neit + ], +) diff -urN a/test/casttype/combos/unmarshaler/BUILD.bazel b/test/casttype/combos/unmarshaler/BUILD.bazel ---- a/test/casttype/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/casttype/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/casttype/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1945,7 +1945,7 @@ diff -urN a/test/casttype/combos/unmarshaler/BUILD.bazel b/test/casttype/combos/ + ], +) diff -urN a/test/castvalue/BUILD.bazel b/test/castvalue/BUILD.bazel ---- a/test/castvalue/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/castvalue/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/castvalue/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1989,7 +1989,7 @@ diff -urN a/test/castvalue/BUILD.bazel b/test/castvalue/BUILD.bazel + ], +) diff -urN a/test/castvalue/combos/both/BUILD.bazel b/test/castvalue/combos/both/BUILD.bazel ---- a/test/castvalue/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/castvalue/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/castvalue/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2033,7 +2033,7 @@ diff -urN a/test/castvalue/combos/both/BUILD.bazel b/test/castvalue/combos/both/ + ], +) diff -urN a/test/castvalue/combos/marshaler/BUILD.bazel b/test/castvalue/combos/marshaler/BUILD.bazel ---- a/test/castvalue/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/castvalue/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/castvalue/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2077,7 +2077,7 @@ diff -urN a/test/castvalue/combos/marshaler/BUILD.bazel b/test/castvalue/combos/ + ], +) diff -urN a/test/castvalue/combos/unmarshaler/BUILD.bazel b/test/castvalue/combos/unmarshaler/BUILD.bazel ---- a/test/castvalue/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/castvalue/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/castvalue/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2121,7 +2121,7 @@ diff -urN a/test/castvalue/combos/unmarshaler/BUILD.bazel b/test/castvalue/combo + ], +) diff -urN a/test/combos/both/BUILD.bazel b/test/combos/both/BUILD.bazel ---- a/test/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,46 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2171,7 +2171,7 @@ diff -urN a/test/combos/both/BUILD.bazel b/test/combos/both/BUILD.bazel + ], +) diff -urN a/test/combos/marshaler/BUILD.bazel b/test/combos/marshaler/BUILD.bazel ---- a/test/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,46 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2221,7 +2221,7 @@ diff -urN a/test/combos/marshaler/BUILD.bazel b/test/combos/marshaler/BUILD.baze + ], +) diff -urN a/test/combos/unmarshaler/BUILD.bazel b/test/combos/unmarshaler/BUILD.bazel ---- a/test/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,46 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2271,7 +2271,7 @@ diff -urN a/test/combos/unmarshaler/BUILD.bazel b/test/combos/unmarshaler/BUILD. + ], +) diff -urN a/test/custom/BUILD.bazel b/test/custom/BUILD.bazel ---- a/test/custom/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/custom/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/custom/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2294,26 +2294,8 @@ diff -urN a/test/custom/BUILD.bazel b/test/custom/BUILD.bazel + srcs = ["custom_test.go"], + embed = [":custom"], +) -diff -urN a/test/custom-dash-type/BUILD.bazel b/test/custom-dash-type/BUILD.bazel ---- a/test/custom-dash-type/BUILD.bazel 1969-12-31 16:00:00 -+++ b/test/custom-dash-type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "custom-dash-type", -+ srcs = ["customdash.go"], -+ importpath = "github.com/gogo/protobuf/test/custom-dash-type", -+ visibility = ["//visibility:public"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":custom-dash-type", -+ visibility = ["//visibility:public"], -+) diff -urN a/test/custombytesnonstruct/BUILD.bazel b/test/custombytesnonstruct/BUILD.bazel ---- a/test/custombytesnonstruct/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/custombytesnonstruct/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/custombytesnonstruct/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2349,8 +2331,26 @@ diff -urN a/test/custombytesnonstruct/BUILD.bazel b/test/custombytesnonstruct/BU + srcs = ["custombytesnonstruct_test.go"], + embed = [":custombytesnonstruct"], +) +diff -urN a/test/custom-dash-type/BUILD.bazel b/test/custom-dash-type/BUILD.bazel +--- a/test/custom-dash-type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/test/custom-dash-type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "custom-dash-type", ++ srcs = ["customdash.go"], ++ importpath = "github.com/gogo/protobuf/test/custom-dash-type", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":custom-dash-type", ++ visibility = ["//visibility:public"], ++) diff -urN a/test/dashfilename/BUILD.bazel b/test/dashfilename/BUILD.bazel ---- a/test/dashfilename/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/dashfilename/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/dashfilename/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2380,7 +2380,7 @@ diff -urN a/test/dashfilename/BUILD.bazel b/test/dashfilename/BUILD.bazel + embed = [":dashfilename"], +) diff -urN a/test/data/BUILD.bazel b/test/data/BUILD.bazel ---- a/test/data/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/data/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/data/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2419,7 +2419,7 @@ diff -urN a/test/data/BUILD.bazel b/test/data/BUILD.bazel + ], +) diff -urN a/test/defaultconflict/BUILD.bazel b/test/defaultconflict/BUILD.bazel ---- a/test/defaultconflict/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/defaultconflict/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/defaultconflict/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2455,7 +2455,7 @@ diff -urN a/test/defaultconflict/BUILD.bazel b/test/defaultconflict/BUILD.bazel + embed = [":defaultconflict"], +) diff -urN a/test/deterministic/BUILD.bazel b/test/deterministic/BUILD.bazel ---- a/test/deterministic/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/deterministic/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/deterministic/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2491,7 +2491,7 @@ diff -urN a/test/deterministic/BUILD.bazel b/test/deterministic/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/embedconflict/BUILD.bazel b/test/embedconflict/BUILD.bazel ---- a/test/embedconflict/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/embedconflict/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/embedconflict/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2528,7 +2528,7 @@ diff -urN a/test/embedconflict/BUILD.bazel b/test/embedconflict/BUILD.bazel + embed = [":embedconflict"], +) diff -urN a/test/empty-issue70/BUILD.bazel b/test/empty-issue70/BUILD.bazel ---- a/test/empty-issue70/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/empty-issue70/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/empty-issue70/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2562,7 +2562,7 @@ diff -urN a/test/empty-issue70/BUILD.bazel b/test/empty-issue70/BUILD.bazel + embed = [":empty-issue70"], +) diff -urN a/test/enumcustomname/BUILD.bazel b/test/enumcustomname/BUILD.bazel ---- a/test/enumcustomname/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/enumcustomname/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/enumcustomname/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2591,7 +2591,7 @@ diff -urN a/test/enumcustomname/BUILD.bazel b/test/enumcustomname/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/enumdecl/BUILD.bazel b/test/enumdecl/BUILD.bazel ---- a/test/enumdecl/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/enumdecl/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/enumdecl/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2633,7 +2633,7 @@ diff -urN a/test/enumdecl/BUILD.bazel b/test/enumdecl/BUILD.bazel + ], +) diff -urN a/test/enumdecl_all/BUILD.bazel b/test/enumdecl_all/BUILD.bazel ---- a/test/enumdecl_all/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/enumdecl_all/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/enumdecl_all/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2675,7 +2675,7 @@ diff -urN a/test/enumdecl_all/BUILD.bazel b/test/enumdecl_all/BUILD.bazel + ], +) diff -urN a/test/enumprefix/BUILD.bazel b/test/enumprefix/BUILD.bazel ---- a/test/enumprefix/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/enumprefix/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/enumprefix/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2704,7 +2704,7 @@ diff -urN a/test/enumprefix/BUILD.bazel b/test/enumprefix/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/enumstringer/BUILD.bazel b/test/enumstringer/BUILD.bazel ---- a/test/enumstringer/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/enumstringer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/enumstringer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2746,7 +2746,7 @@ diff -urN a/test/enumstringer/BUILD.bazel b/test/enumstringer/BUILD.bazel + ], +) diff -urN a/test/example/BUILD.bazel b/test/example/BUILD.bazel ---- a/test/example/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/example/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/example/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2791,7 +2791,7 @@ diff -urN a/test/example/BUILD.bazel b/test/example/BUILD.bazel + ], +) diff -urN a/test/filedotname/BUILD.bazel b/test/filedotname/BUILD.bazel ---- a/test/filedotname/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/filedotname/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/filedotname/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2831,7 +2831,7 @@ diff -urN a/test/filedotname/BUILD.bazel b/test/filedotname/BUILD.bazel + ], +) diff -urN a/test/fuzztests/BUILD.bazel b/test/fuzztests/BUILD.bazel ---- a/test/fuzztests/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/fuzztests/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/fuzztests/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2866,7 +2866,7 @@ diff -urN a/test/fuzztests/BUILD.bazel b/test/fuzztests/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/group/BUILD.bazel b/test/group/BUILD.bazel ---- a/test/group/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/group/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/group/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2906,7 +2906,7 @@ diff -urN a/test/group/BUILD.bazel b/test/group/BUILD.bazel + ], +) diff -urN a/test/importcustom-issue389/imported/BUILD.bazel b/test/importcustom-issue389/imported/BUILD.bazel ---- a/test/importcustom-issue389/imported/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/importcustom-issue389/imported/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/importcustom-issue389/imported/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2948,7 +2948,7 @@ diff -urN a/test/importcustom-issue389/imported/BUILD.bazel b/test/importcustom- + ], +) diff -urN a/test/importcustom-issue389/importing/BUILD.bazel b/test/importcustom-issue389/importing/BUILD.bazel ---- a/test/importcustom-issue389/importing/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/importcustom-issue389/importing/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/importcustom-issue389/importing/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2989,7 +2989,7 @@ diff -urN a/test/importcustom-issue389/importing/BUILD.bazel b/test/importcustom + ], +) diff -urN a/test/importdedup/BUILD.bazel b/test/importdedup/BUILD.bazel ---- a/test/importdedup/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/importdedup/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/importdedup/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3024,7 +3024,7 @@ diff -urN a/test/importdedup/BUILD.bazel b/test/importdedup/BUILD.bazel + embed = [":importdedup"], +) diff -urN a/test/importdedup/subpkg/BUILD.bazel b/test/importdedup/subpkg/BUILD.bazel ---- a/test/importdedup/subpkg/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/importdedup/subpkg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/importdedup/subpkg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3055,7 +3055,7 @@ diff -urN a/test/importdedup/subpkg/BUILD.bazel b/test/importdedup/subpkg/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/test/importduplicate/BUILD.bazel b/test/importduplicate/BUILD.bazel ---- a/test/importduplicate/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/importduplicate/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/importduplicate/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3102,7 +3102,7 @@ diff -urN a/test/importduplicate/BUILD.bazel b/test/importduplicate/BUILD.bazel + ], +) diff -urN a/test/importduplicate/proto/BUILD.bazel b/test/importduplicate/proto/BUILD.bazel ---- a/test/importduplicate/proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/importduplicate/proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/importduplicate/proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3141,7 +3141,7 @@ diff -urN a/test/importduplicate/proto/BUILD.bazel b/test/importduplicate/proto/ + ], +) diff -urN a/test/importduplicate/sortkeys/BUILD.bazel b/test/importduplicate/sortkeys/BUILD.bazel ---- a/test/importduplicate/sortkeys/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/importduplicate/sortkeys/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/importduplicate/sortkeys/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3180,7 +3180,7 @@ diff -urN a/test/importduplicate/sortkeys/BUILD.bazel b/test/importduplicate/sor + ], +) diff -urN a/test/indeximport-issue72/BUILD.bazel b/test/indeximport-issue72/BUILD.bazel ---- a/test/indeximport-issue72/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/indeximport-issue72/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/indeximport-issue72/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3221,7 +3221,7 @@ diff -urN a/test/indeximport-issue72/BUILD.bazel b/test/indeximport-issue72/BUIL + ], +) diff -urN a/test/indeximport-issue72/index/BUILD.bazel b/test/indeximport-issue72/index/BUILD.bazel ---- a/test/indeximport-issue72/index/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/indeximport-issue72/index/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/indeximport-issue72/index/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3260,7 +3260,7 @@ diff -urN a/test/indeximport-issue72/index/BUILD.bazel b/test/indeximport-issue7 + ], +) diff -urN a/test/int64support/BUILD.bazel b/test/int64support/BUILD.bazel ---- a/test/int64support/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/int64support/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/int64support/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3305,7 +3305,7 @@ diff -urN a/test/int64support/BUILD.bazel b/test/int64support/BUILD.bazel + ], +) diff -urN a/test/issue260/BUILD.bazel b/test/issue260/BUILD.bazel ---- a/test/issue260/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue260/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue260/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3350,7 +3350,7 @@ diff -urN a/test/issue260/BUILD.bazel b/test/issue260/BUILD.bazel + ], +) diff -urN a/test/issue261/BUILD.bazel b/test/issue261/BUILD.bazel ---- a/test/issue261/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue261/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue261/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3380,7 +3380,7 @@ diff -urN a/test/issue261/BUILD.bazel b/test/issue261/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/issue262/BUILD.bazel b/test/issue262/BUILD.bazel ---- a/test/issue262/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue262/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue262/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3408,8 +3408,29 @@ diff -urN a/test/issue262/BUILD.bazel b/test/issue262/BUILD.bazel + actual = ":issue262", + visibility = ["//visibility:public"], +) +diff -urN a/test/issue270/a/BUILD.bazel b/test/issue270/a/BUILD.bazel +--- a/test/issue270/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/test/issue270/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,8 @@ ++filegroup( ++ name = "go_default_library_protos", ++ srcs = [ ++ "a1.proto", ++ "a2.proto", ++ ], ++ visibility = ["//visibility:public"], ++) +diff -urN a/test/issue270/b/BUILD.bazel b/test/issue270/b/BUILD.bazel +--- a/test/issue270/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/test/issue270/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,5 @@ ++filegroup( ++ name = "go_default_library_protos", ++ srcs = ["b.proto"], ++ visibility = ["//visibility:public"], ++) diff -urN a/test/issue270/BUILD.bazel b/test/issue270/BUILD.bazel ---- a/test/issue270/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue270/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue270/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3432,29 +3453,8 @@ diff -urN a/test/issue270/BUILD.bazel b/test/issue270/BUILD.bazel + srcs = ["issue270_test.go"], + embed = [":issue270"], +) -diff -urN a/test/issue270/a/BUILD.bazel b/test/issue270/a/BUILD.bazel ---- a/test/issue270/a/BUILD.bazel 1969-12-31 16:00:00 -+++ b/test/issue270/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,8 @@ -+filegroup( -+ name = "go_default_library_protos", -+ srcs = [ -+ "a1.proto", -+ "a2.proto", -+ ], -+ visibility = ["//visibility:public"], -+) -diff -urN a/test/issue270/b/BUILD.bazel b/test/issue270/b/BUILD.bazel ---- a/test/issue270/b/BUILD.bazel 1969-12-31 16:00:00 -+++ b/test/issue270/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,5 @@ -+filegroup( -+ name = "go_default_library_protos", -+ srcs = ["b.proto"], -+ visibility = ["//visibility:public"], -+) diff -urN a/test/issue312/BUILD.bazel b/test/issue312/BUILD.bazel ---- a/test/issue312/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue312/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue312/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3482,7 +3482,7 @@ diff -urN a/test/issue312/BUILD.bazel b/test/issue312/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/issue312/events/BUILD.bazel b/test/issue312/events/BUILD.bazel ---- a/test/issue312/events/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue312/events/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue312/events/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3523,7 +3523,7 @@ diff -urN a/test/issue312/events/BUILD.bazel b/test/issue312/events/BUILD.bazel + ], +) diff -urN a/test/issue322/BUILD.bazel b/test/issue322/BUILD.bazel ---- a/test/issue322/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue322/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue322/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3562,7 +3562,7 @@ diff -urN a/test/issue322/BUILD.bazel b/test/issue322/BUILD.bazel + ], +) diff -urN a/test/issue330/BUILD.bazel b/test/issue330/BUILD.bazel ---- a/test/issue330/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue330/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue330/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3604,7 +3604,7 @@ diff -urN a/test/issue330/BUILD.bazel b/test/issue330/BUILD.bazel + ], +) diff -urN a/test/issue34/BUILD.bazel b/test/issue34/BUILD.bazel ---- a/test/issue34/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue34/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue34/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3639,7 +3639,7 @@ diff -urN a/test/issue34/BUILD.bazel b/test/issue34/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/issue411/BUILD.bazel b/test/issue411/BUILD.bazel ---- a/test/issue411/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue411/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue411/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3680,7 +3680,7 @@ diff -urN a/test/issue411/BUILD.bazel b/test/issue411/BUILD.bazel + ], +) diff -urN a/test/issue427/BUILD.bazel b/test/issue427/BUILD.bazel ---- a/test/issue427/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue427/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue427/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,5 @@ +filegroup( @@ -3689,7 +3689,7 @@ diff -urN a/test/issue427/BUILD.bazel b/test/issue427/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/issue42order/BUILD.bazel b/test/issue42order/BUILD.bazel ---- a/test/issue42order/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue42order/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue42order/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3724,7 +3724,7 @@ diff -urN a/test/issue42order/BUILD.bazel b/test/issue42order/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/issue435/BUILD.bazel b/test/issue435/BUILD.bazel ---- a/test/issue435/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue435/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue435/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3759,7 +3759,7 @@ diff -urN a/test/issue435/BUILD.bazel b/test/issue435/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/issue438/BUILD.bazel b/test/issue438/BUILD.bazel ---- a/test/issue438/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue438/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue438/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3788,7 +3788,7 @@ diff -urN a/test/issue438/BUILD.bazel b/test/issue438/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/issue444/BUILD.bazel b/test/issue444/BUILD.bazel ---- a/test/issue444/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue444/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue444/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3822,7 +3822,7 @@ diff -urN a/test/issue444/BUILD.bazel b/test/issue444/BUILD.bazel + embed = [":issue444"], +) diff -urN a/test/issue449/BUILD.bazel b/test/issue449/BUILD.bazel ---- a/test/issue449/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue449/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue449/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3857,7 +3857,7 @@ diff -urN a/test/issue449/BUILD.bazel b/test/issue449/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/issue498/BUILD.bazel b/test/issue498/BUILD.bazel ---- a/test/issue498/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue498/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue498/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3896,7 +3896,7 @@ diff -urN a/test/issue498/BUILD.bazel b/test/issue498/BUILD.bazel + ], +) diff -urN a/test/issue503/BUILD.bazel b/test/issue503/BUILD.bazel ---- a/test/issue503/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue503/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue503/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3931,7 +3931,7 @@ diff -urN a/test/issue503/BUILD.bazel b/test/issue503/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/issue530/BUILD.bazel b/test/issue530/BUILD.bazel ---- a/test/issue530/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue530/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue530/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3974,7 +3974,7 @@ diff -urN a/test/issue530/BUILD.bazel b/test/issue530/BUILD.bazel + ], +) diff -urN a/test/issue617/BUILD.bazel b/test/issue617/BUILD.bazel ---- a/test/issue617/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue617/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue617/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4002,7 +4002,7 @@ diff -urN a/test/issue617/BUILD.bazel b/test/issue617/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/issue620/BUILD.bazel b/test/issue620/BUILD.bazel ---- a/test/issue620/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue620/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue620/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4037,7 +4037,7 @@ diff -urN a/test/issue620/BUILD.bazel b/test/issue620/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/issue630/BUILD.bazel b/test/issue630/BUILD.bazel ---- a/test/issue630/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue630/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue630/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4071,7 +4071,7 @@ diff -urN a/test/issue630/BUILD.bazel b/test/issue630/BUILD.bazel + embed = [":issue630"], +) diff -urN a/test/issue8/BUILD.bazel b/test/issue8/BUILD.bazel ---- a/test/issue8/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/issue8/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/issue8/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4110,7 +4110,7 @@ diff -urN a/test/issue8/BUILD.bazel b/test/issue8/BUILD.bazel + ], +) diff -urN a/test/jsonpb-gogo/BUILD.bazel b/test/jsonpb-gogo/BUILD.bazel ---- a/test/jsonpb-gogo/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/jsonpb-gogo/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/jsonpb-gogo/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4135,7 +4135,7 @@ diff -urN a/test/jsonpb-gogo/BUILD.bazel b/test/jsonpb-gogo/BUILD.bazel + deps = ["//jsonpb"], +) diff -urN a/test/mapdefaults/BUILD.bazel b/test/mapdefaults/BUILD.bazel ---- a/test/mapdefaults/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapdefaults/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapdefaults/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4160,7 +4160,7 @@ diff -urN a/test/mapdefaults/BUILD.bazel b/test/mapdefaults/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/mapdefaults/combos/both/BUILD.bazel b/test/mapdefaults/combos/both/BUILD.bazel ---- a/test/mapdefaults/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapdefaults/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapdefaults/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4205,7 +4205,7 @@ diff -urN a/test/mapdefaults/combos/both/BUILD.bazel b/test/mapdefaults/combos/b + ], +) diff -urN a/test/mapdefaults/combos/marshaler/BUILD.bazel b/test/mapdefaults/combos/marshaler/BUILD.bazel ---- a/test/mapdefaults/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapdefaults/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapdefaults/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4249,7 +4249,7 @@ diff -urN a/test/mapdefaults/combos/marshaler/BUILD.bazel b/test/mapdefaults/com + ], +) diff -urN a/test/mapdefaults/combos/neither/BUILD.bazel b/test/mapdefaults/combos/neither/BUILD.bazel ---- a/test/mapdefaults/combos/neither/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapdefaults/combos/neither/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapdefaults/combos/neither/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4293,7 +4293,7 @@ diff -urN a/test/mapdefaults/combos/neither/BUILD.bazel b/test/mapdefaults/combo + ], +) diff -urN a/test/mapdefaults/combos/unmarshaler/BUILD.bazel b/test/mapdefaults/combos/unmarshaler/BUILD.bazel ---- a/test/mapdefaults/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapdefaults/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapdefaults/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4338,7 +4338,7 @@ diff -urN a/test/mapdefaults/combos/unmarshaler/BUILD.bazel b/test/mapdefaults/c + ], +) diff -urN a/test/mapsproto2/BUILD.bazel b/test/mapsproto2/BUILD.bazel ---- a/test/mapsproto2/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapsproto2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapsproto2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4365,7 +4365,7 @@ diff -urN a/test/mapsproto2/BUILD.bazel b/test/mapsproto2/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/mapsproto2/combos/both/BUILD.bazel b/test/mapsproto2/combos/both/BUILD.bazel ---- a/test/mapsproto2/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapsproto2/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapsproto2/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4411,7 +4411,7 @@ diff -urN a/test/mapsproto2/combos/both/BUILD.bazel b/test/mapsproto2/combos/bot + ], +) diff -urN a/test/mapsproto2/combos/marshaler/BUILD.bazel b/test/mapsproto2/combos/marshaler/BUILD.bazel ---- a/test/mapsproto2/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapsproto2/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapsproto2/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4457,7 +4457,7 @@ diff -urN a/test/mapsproto2/combos/marshaler/BUILD.bazel b/test/mapsproto2/combo + ], +) diff -urN a/test/mapsproto2/combos/neither/BUILD.bazel b/test/mapsproto2/combos/neither/BUILD.bazel ---- a/test/mapsproto2/combos/neither/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapsproto2/combos/neither/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapsproto2/combos/neither/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4503,7 +4503,7 @@ diff -urN a/test/mapsproto2/combos/neither/BUILD.bazel b/test/mapsproto2/combos/ + ], +) diff -urN a/test/mapsproto2/combos/unmarshaler/BUILD.bazel b/test/mapsproto2/combos/unmarshaler/BUILD.bazel ---- a/test/mapsproto2/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mapsproto2/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mapsproto2/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4549,7 +4549,7 @@ diff -urN a/test/mapsproto2/combos/unmarshaler/BUILD.bazel b/test/mapsproto2/com + ], +) diff -urN a/test/merge/BUILD.bazel b/test/merge/BUILD.bazel ---- a/test/merge/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/merge/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/merge/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4584,7 +4584,7 @@ diff -urN a/test/merge/BUILD.bazel b/test/merge/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/mixbench/BUILD.bazel b/test/mixbench/BUILD.bazel ---- a/test/mixbench/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/mixbench/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/mixbench/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -4602,7 +4602,7 @@ diff -urN a/test/mixbench/BUILD.bazel b/test/mixbench/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/moredefaults/BUILD.bazel b/test/moredefaults/BUILD.bazel ---- a/test/moredefaults/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/moredefaults/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/moredefaults/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4646,7 +4646,7 @@ diff -urN a/test/moredefaults/BUILD.bazel b/test/moredefaults/BUILD.bazel + ], +) diff -urN a/test/nopackage/BUILD.bazel b/test/nopackage/BUILD.bazel ---- a/test/nopackage/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/nopackage/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/nopackage/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4677,7 +4677,7 @@ diff -urN a/test/nopackage/BUILD.bazel b/test/nopackage/BUILD.bazel + embed = [":nopackage"], +) diff -urN a/test/oneof/BUILD.bazel b/test/oneof/BUILD.bazel ---- a/test/oneof/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4701,7 +4701,7 @@ diff -urN a/test/oneof/BUILD.bazel b/test/oneof/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/oneof/combos/both/BUILD.bazel b/test/oneof/combos/both/BUILD.bazel ---- a/test/oneof/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4743,7 +4743,7 @@ diff -urN a/test/oneof/combos/both/BUILD.bazel b/test/oneof/combos/both/BUILD.ba + ], +) diff -urN a/test/oneof/combos/marshaler/BUILD.bazel b/test/oneof/combos/marshaler/BUILD.bazel ---- a/test/oneof/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4785,7 +4785,7 @@ diff -urN a/test/oneof/combos/marshaler/BUILD.bazel b/test/oneof/combos/marshale + ], +) diff -urN a/test/oneof/combos/neither/BUILD.bazel b/test/oneof/combos/neither/BUILD.bazel ---- a/test/oneof/combos/neither/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof/combos/neither/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof/combos/neither/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4827,7 +4827,7 @@ diff -urN a/test/oneof/combos/neither/BUILD.bazel b/test/oneof/combos/neither/BU + ], +) diff -urN a/test/oneof/combos/unmarshaler/BUILD.bazel b/test/oneof/combos/unmarshaler/BUILD.bazel ---- a/test/oneof/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4869,7 +4869,7 @@ diff -urN a/test/oneof/combos/unmarshaler/BUILD.bazel b/test/oneof/combos/unmars + ], +) diff -urN a/test/oneof3/BUILD.bazel b/test/oneof3/BUILD.bazel ---- a/test/oneof3/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4893,7 +4893,7 @@ diff -urN a/test/oneof3/BUILD.bazel b/test/oneof3/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/oneof3/combos/both/BUILD.bazel b/test/oneof3/combos/both/BUILD.bazel ---- a/test/oneof3/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof3/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof3/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4933,7 +4933,7 @@ diff -urN a/test/oneof3/combos/both/BUILD.bazel b/test/oneof3/combos/both/BUILD. + ], +) diff -urN a/test/oneof3/combos/marshaler/BUILD.bazel b/test/oneof3/combos/marshaler/BUILD.bazel ---- a/test/oneof3/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof3/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof3/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -4973,7 +4973,7 @@ diff -urN a/test/oneof3/combos/marshaler/BUILD.bazel b/test/oneof3/combos/marsha + ], +) diff -urN a/test/oneof3/combos/neither/BUILD.bazel b/test/oneof3/combos/neither/BUILD.bazel ---- a/test/oneof3/combos/neither/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof3/combos/neither/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof3/combos/neither/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5013,7 +5013,7 @@ diff -urN a/test/oneof3/combos/neither/BUILD.bazel b/test/oneof3/combos/neither/ + ], +) diff -urN a/test/oneof3/combos/unmarshaler/BUILD.bazel b/test/oneof3/combos/unmarshaler/BUILD.bazel ---- a/test/oneof3/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneof3/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneof3/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5053,7 +5053,7 @@ diff -urN a/test/oneof3/combos/unmarshaler/BUILD.bazel b/test/oneof3/combos/unma + ], +) diff -urN a/test/oneofembed/BUILD.bazel b/test/oneofembed/BUILD.bazel ---- a/test/oneofembed/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/oneofembed/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/oneofembed/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5092,7 +5092,7 @@ diff -urN a/test/oneofembed/BUILD.bazel b/test/oneofembed/BUILD.bazel + ], +) diff -urN a/test/packed/BUILD.bazel b/test/packed/BUILD.bazel ---- a/test/packed/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/packed/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/packed/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5130,7 +5130,7 @@ diff -urN a/test/packed/BUILD.bazel b/test/packed/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/proto3extension/BUILD.bazel b/test/proto3extension/BUILD.bazel ---- a/test/proto3extension/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/proto3extension/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/proto3extension/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5158,7 +5158,7 @@ diff -urN a/test/proto3extension/BUILD.bazel b/test/proto3extension/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/protobuffer/BUILD.bazel b/test/protobuffer/BUILD.bazel ---- a/test/protobuffer/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/protobuffer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/protobuffer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5193,7 +5193,7 @@ diff -urN a/test/protobuffer/BUILD.bazel b/test/protobuffer/BUILD.bazel + deps = ["//proto"], +) diff -urN a/test/protosize/BUILD.bazel b/test/protosize/BUILD.bazel ---- a/test/protosize/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/protosize/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/protosize/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5235,7 +5235,7 @@ diff -urN a/test/protosize/BUILD.bazel b/test/protosize/BUILD.bazel + ], +) diff -urN a/test/registration/BUILD.bazel b/test/registration/BUILD.bazel ---- a/test/registration/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/registration/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/registration/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,5 @@ +filegroup( @@ -5244,7 +5244,7 @@ diff -urN a/test/registration/BUILD.bazel b/test/registration/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/required/BUILD.bazel b/test/required/BUILD.bazel ---- a/test/required/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/required/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/required/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5282,7 +5282,7 @@ diff -urN a/test/required/BUILD.bazel b/test/required/BUILD.bazel + ], +) diff -urN a/test/setextensionbytes/BUILD.bazel b/test/setextensionbytes/BUILD.bazel ---- a/test/setextensionbytes/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/setextensionbytes/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/setextensionbytes/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5317,7 +5317,7 @@ diff -urN a/test/setextensionbytes/BUILD.bazel b/test/setextensionbytes/BUILD.ba + deps = ["//proto"], +) diff -urN a/test/sizerconflict/BUILD.bazel b/test/sizerconflict/BUILD.bazel ---- a/test/sizerconflict/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/sizerconflict/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/sizerconflict/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5347,7 +5347,7 @@ diff -urN a/test/sizerconflict/BUILD.bazel b/test/sizerconflict/BUILD.bazel + embed = [":sizerconflict"], +) diff -urN a/test/sizeunderscore/BUILD.bazel b/test/sizeunderscore/BUILD.bazel ---- a/test/sizeunderscore/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/sizeunderscore/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/sizeunderscore/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5386,7 +5386,7 @@ diff -urN a/test/sizeunderscore/BUILD.bazel b/test/sizeunderscore/BUILD.bazel + ], +) diff -urN a/test/stdtypes/BUILD.bazel b/test/stdtypes/BUILD.bazel ---- a/test/stdtypes/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/stdtypes/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/stdtypes/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5431,7 +5431,7 @@ diff -urN a/test/stdtypes/BUILD.bazel b/test/stdtypes/BUILD.bazel + ], +) diff -urN a/test/tags/BUILD.bazel b/test/tags/BUILD.bazel ---- a/test/tags/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/tags/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/tags/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5468,7 +5468,7 @@ diff -urN a/test/tags/BUILD.bazel b/test/tags/BUILD.bazel + embed = [":tags"], +) diff -urN a/test/theproto3/BUILD.bazel b/test/theproto3/BUILD.bazel ---- a/test/theproto3/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/theproto3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/theproto3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5497,7 +5497,7 @@ diff -urN a/test/theproto3/BUILD.bazel b/test/theproto3/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/theproto3/combos/both/BUILD.bazel b/test/theproto3/combos/both/BUILD.bazel ---- a/test/theproto3/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/theproto3/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/theproto3/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5544,7 +5544,7 @@ diff -urN a/test/theproto3/combos/both/BUILD.bazel b/test/theproto3/combos/both/ + ], +) diff -urN a/test/theproto3/combos/marshaler/BUILD.bazel b/test/theproto3/combos/marshaler/BUILD.bazel ---- a/test/theproto3/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/theproto3/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/theproto3/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5591,7 +5591,7 @@ diff -urN a/test/theproto3/combos/marshaler/BUILD.bazel b/test/theproto3/combos/ + ], +) diff -urN a/test/theproto3/combos/neither/BUILD.bazel b/test/theproto3/combos/neither/BUILD.bazel ---- a/test/theproto3/combos/neither/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/theproto3/combos/neither/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/theproto3/combos/neither/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5638,7 +5638,7 @@ diff -urN a/test/theproto3/combos/neither/BUILD.bazel b/test/theproto3/combos/ne + ], +) diff -urN a/test/theproto3/combos/unmarshaler/BUILD.bazel b/test/theproto3/combos/unmarshaler/BUILD.bazel ---- a/test/theproto3/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/theproto3/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/theproto3/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5685,7 +5685,7 @@ diff -urN a/test/theproto3/combos/unmarshaler/BUILD.bazel b/test/theproto3/combo + ], +) diff -urN a/test/typedecl/BUILD.bazel b/test/typedecl/BUILD.bazel ---- a/test/typedecl/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/typedecl/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/typedecl/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5728,7 +5728,7 @@ diff -urN a/test/typedecl/BUILD.bazel b/test/typedecl/BUILD.bazel + ], +) diff -urN a/test/typedecl_all/BUILD.bazel b/test/typedecl_all/BUILD.bazel ---- a/test/typedecl_all/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/typedecl_all/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/typedecl_all/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5771,7 +5771,7 @@ diff -urN a/test/typedecl_all/BUILD.bazel b/test/typedecl_all/BUILD.bazel + ], +) diff -urN a/test/typedeclimport/BUILD.bazel b/test/typedeclimport/BUILD.bazel ---- a/test/typedeclimport/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/typedeclimport/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/typedeclimport/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5809,7 +5809,7 @@ diff -urN a/test/typedeclimport/BUILD.bazel b/test/typedeclimport/BUILD.bazel + embed = [":typedeclimport"], +) diff -urN a/test/typedeclimport/subpkg/BUILD.bazel b/test/typedeclimport/subpkg/BUILD.bazel ---- a/test/typedeclimport/subpkg/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/typedeclimport/subpkg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/typedeclimport/subpkg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5837,7 +5837,7 @@ diff -urN a/test/typedeclimport/subpkg/BUILD.bazel b/test/typedeclimport/subpkg/ + visibility = ["//visibility:public"], +) diff -urN a/test/types/BUILD.bazel b/test/types/BUILD.bazel ---- a/test/types/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/types/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/types/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,5 @@ +filegroup( @@ -5846,7 +5846,7 @@ diff -urN a/test/types/BUILD.bazel b/test/types/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/test/types/combos/both/BUILD.bazel b/test/types/combos/both/BUILD.bazel ---- a/test/types/combos/both/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/types/combos/both/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/types/combos/both/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5890,7 +5890,7 @@ diff -urN a/test/types/combos/both/BUILD.bazel b/test/types/combos/both/BUILD.ba + ], +) diff -urN a/test/types/combos/marshaler/BUILD.bazel b/test/types/combos/marshaler/BUILD.bazel ---- a/test/types/combos/marshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/types/combos/marshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/types/combos/marshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5934,7 +5934,7 @@ diff -urN a/test/types/combos/marshaler/BUILD.bazel b/test/types/combos/marshale + ], +) diff -urN a/test/types/combos/neither/BUILD.bazel b/test/types/combos/neither/BUILD.bazel ---- a/test/types/combos/neither/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/types/combos/neither/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/types/combos/neither/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -5978,7 +5978,7 @@ diff -urN a/test/types/combos/neither/BUILD.bazel b/test/types/combos/neither/BU + ], +) diff -urN a/test/types/combos/unmarshaler/BUILD.bazel b/test/types/combos/unmarshaler/BUILD.bazel ---- a/test/types/combos/unmarshaler/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/types/combos/unmarshaler/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/types/combos/unmarshaler/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6022,7 +6022,7 @@ diff -urN a/test/types/combos/unmarshaler/BUILD.bazel b/test/types/combos/unmars + ], +) diff -urN a/test/unmarshalmerge/BUILD.bazel b/test/unmarshalmerge/BUILD.bazel ---- a/test/unmarshalmerge/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/unmarshalmerge/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/unmarshalmerge/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6064,7 +6064,7 @@ diff -urN a/test/unmarshalmerge/BUILD.bazel b/test/unmarshalmerge/BUILD.bazel + ], +) diff -urN a/test/unrecognized/BUILD.bazel b/test/unrecognized/BUILD.bazel ---- a/test/unrecognized/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/unrecognized/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/unrecognized/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6107,7 +6107,7 @@ diff -urN a/test/unrecognized/BUILD.bazel b/test/unrecognized/BUILD.bazel + ], +) diff -urN a/test/unrecognizedgroup/BUILD.bazel b/test/unrecognizedgroup/BUILD.bazel ---- a/test/unrecognizedgroup/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/unrecognizedgroup/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/unrecognizedgroup/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6150,7 +6150,7 @@ diff -urN a/test/unrecognizedgroup/BUILD.bazel b/test/unrecognizedgroup/BUILD.ba + ], +) diff -urN a/test/xxxfields/BUILD.bazel b/test/xxxfields/BUILD.bazel ---- a/test/xxxfields/BUILD.bazel 1969-12-31 16:00:00 +--- a/test/xxxfields/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/test/xxxfields/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6189,7 +6189,7 @@ diff -urN a/test/xxxfields/BUILD.bazel b/test/xxxfields/BUILD.bazel + ], +) diff -urN a/types/BUILD.bazel b/types/BUILD.bazel ---- a/types/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,51 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6244,7 +6244,7 @@ diff -urN a/types/BUILD.bazel b/types/BUILD.bazel + ], +) diff -urN a/vanity/BUILD.bazel b/vanity/BUILD.bazel ---- a/vanity/BUILD.bazel 1969-12-31 16:00:00 +--- a/vanity/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/vanity/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6273,7 +6273,7 @@ diff -urN a/vanity/BUILD.bazel b/vanity/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/vanity/command/BUILD.bazel b/vanity/command/BUILD.bazel ---- a/vanity/command/BUILD.bazel 1969-12-31 16:00:00 +--- a/vanity/command/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/vanity/command/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6313,7 +6313,7 @@ diff -urN a/vanity/command/BUILD.bazel b/vanity/command/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/vanity/test/BUILD.bazel b/vanity/test/BUILD.bazel ---- a/vanity/test/BUILD.bazel 1969-12-31 16:00:00 +--- a/vanity/test/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/vanity/test/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -6352,7 +6352,7 @@ diff -urN a/vanity/test/BUILD.bazel b/vanity/test/BUILD.bazel + ], +) diff -urN a/vanity/test/fast/BUILD.bazel b/vanity/test/fast/BUILD.bazel ---- a/vanity/test/fast/BUILD.bazel 1969-12-31 16:00:00 +--- a/vanity/test/fast/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/vanity/test/fast/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6378,7 +6378,7 @@ diff -urN a/vanity/test/fast/BUILD.bazel b/vanity/test/fast/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/vanity/test/faster/BUILD.bazel b/vanity/test/faster/BUILD.bazel ---- a/vanity/test/faster/BUILD.bazel 1969-12-31 16:00:00 +--- a/vanity/test/faster/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/vanity/test/faster/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6404,7 +6404,7 @@ diff -urN a/vanity/test/faster/BUILD.bazel b/vanity/test/faster/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/vanity/test/slick/BUILD.bazel b/vanity/test/slick/BUILD.bazel ---- a/vanity/test/slick/BUILD.bazel 1969-12-31 16:00:00 +--- a/vanity/test/slick/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/vanity/test/slick/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6430,7 +6430,7 @@ diff -urN a/vanity/test/slick/BUILD.bazel b/vanity/test/slick/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/version/BUILD.bazel b/version/BUILD.bazel ---- a/version/BUILD.bazel 1969-12-31 16:00:00 +--- a/version/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/version/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/third_party/com_github_golang_mock-gazelle.patch b/third_party/com_github_golang_mock-gazelle.patch index ac6576d533..6cf261577f 100644 --- a/third_party/com_github_golang_mock-gazelle.patch +++ b/third_party/com_github_golang_mock-gazelle.patch @@ -1,5 +1,5 @@ diff -urN a/gomock/BUILD.bazel b/gomock/BUILD.bazel ---- a/gomock/BUILD.bazel 1969-12-31 16:00:00 +--- a/gomock/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/gomock/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -37,7 +37,7 @@ diff -urN a/gomock/BUILD.bazel b/gomock/BUILD.bazel + deps = ["//gomock/internal/mock_gomock"], +) diff -urN a/gomock/internal/mock_gomock/BUILD.bazel b/gomock/internal/mock_gomock/BUILD.bazel ---- a/gomock/internal/mock_gomock/BUILD.bazel 1969-12-31 16:00:00 +--- a/gomock/internal/mock_gomock/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/gomock/internal/mock_gomock/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -56,7 +56,7 @@ diff -urN a/gomock/internal/mock_gomock/BUILD.bazel b/gomock/internal/mock_gomoc + visibility = ["//gomock:__subpackages__"], +) diff -urN a/mockgen/BUILD.bazel b/mockgen/BUILD.bazel ---- a/mockgen/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -96,7 +96,7 @@ diff -urN a/mockgen/BUILD.bazel b/mockgen/BUILD.bazel + deps = ["//mockgen/model"], +) diff -urN a/mockgen/internal/tests/aux_imports_embedded_interface/BUILD.bazel b/mockgen/internal/tests/aux_imports_embedded_interface/BUILD.bazel ---- a/mockgen/internal/tests/aux_imports_embedded_interface/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/aux_imports_embedded_interface/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/aux_imports_embedded_interface/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -128,7 +128,7 @@ diff -urN a/mockgen/internal/tests/aux_imports_embedded_interface/BUILD.bazel b/ + deps = ["//gomock"], +) diff -urN a/mockgen/internal/tests/aux_imports_embedded_interface/faux/BUILD.bazel b/mockgen/internal/tests/aux_imports_embedded_interface/faux/BUILD.bazel ---- a/mockgen/internal/tests/aux_imports_embedded_interface/faux/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/aux_imports_embedded_interface/faux/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/aux_imports_embedded_interface/faux/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -146,7 +146,7 @@ diff -urN a/mockgen/internal/tests/aux_imports_embedded_interface/faux/BUILD.baz + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/const_array_length/BUILD.bazel b/mockgen/internal/tests/const_array_length/BUILD.bazel ---- a/mockgen/internal/tests/const_array_length/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/const_array_length/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/const_array_length/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -168,7 +168,7 @@ diff -urN a/mockgen/internal/tests/const_array_length/BUILD.bazel b/mockgen/inte + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/copyright_file/BUILD.bazel b/mockgen/internal/tests/copyright_file/BUILD.bazel ---- a/mockgen/internal/tests/copyright_file/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/copyright_file/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/copyright_file/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -190,7 +190,7 @@ diff -urN a/mockgen/internal/tests/copyright_file/BUILD.bazel b/mockgen/internal + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/custom_package_name/client/v1/BUILD.bazel b/mockgen/internal/tests/custom_package_name/client/v1/BUILD.bazel ---- a/mockgen/internal/tests/custom_package_name/client/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/custom_package_name/client/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/custom_package_name/client/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -208,7 +208,7 @@ diff -urN a/mockgen/internal/tests/custom_package_name/client/v1/BUILD.bazel b/m + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/custom_package_name/greeter/BUILD.bazel b/mockgen/internal/tests/custom_package_name/greeter/BUILD.bazel ---- a/mockgen/internal/tests/custom_package_name/greeter/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/custom_package_name/greeter/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/custom_package_name/greeter/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -243,7 +243,7 @@ diff -urN a/mockgen/internal/tests/custom_package_name/greeter/BUILD.bazel b/moc + ], +) diff -urN a/mockgen/internal/tests/custom_package_name/validator/BUILD.bazel b/mockgen/internal/tests/custom_package_name/validator/BUILD.bazel ---- a/mockgen/internal/tests/custom_package_name/validator/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/custom_package_name/validator/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/custom_package_name/validator/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -261,7 +261,7 @@ diff -urN a/mockgen/internal/tests/custom_package_name/validator/BUILD.bazel b/m + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/dot_imports/BUILD.bazel b/mockgen/internal/tests/dot_imports/BUILD.bazel ---- a/mockgen/internal/tests/dot_imports/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/dot_imports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/dot_imports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -283,7 +283,7 @@ diff -urN a/mockgen/internal/tests/dot_imports/BUILD.bazel b/mockgen/internal/te + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/empty_interface/BUILD.bazel b/mockgen/internal/tests/empty_interface/BUILD.bazel ---- a/mockgen/internal/tests/empty_interface/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/empty_interface/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/empty_interface/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -305,7 +305,7 @@ diff -urN a/mockgen/internal/tests/empty_interface/BUILD.bazel b/mockgen/interna + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/extra_import/BUILD.bazel b/mockgen/internal/tests/extra_import/BUILD.bazel ---- a/mockgen/internal/tests/extra_import/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/extra_import/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/extra_import/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -327,7 +327,7 @@ diff -urN a/mockgen/internal/tests/extra_import/BUILD.bazel b/mockgen/internal/t + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/generated_identifier_conflict/BUILD.bazel b/mockgen/internal/tests/generated_identifier_conflict/BUILD.bazel ---- a/mockgen/internal/tests/generated_identifier_conflict/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/generated_identifier_conflict/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/generated_identifier_conflict/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -356,7 +356,7 @@ diff -urN a/mockgen/internal/tests/generated_identifier_conflict/BUILD.bazel b/m + deps = ["//gomock"], +) diff -urN a/mockgen/internal/tests/generics/BUILD.bazel b/mockgen/internal/tests/generics/BUILD.bazel ---- a/mockgen/internal/tests/generics/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/generics/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/generics/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -381,7 +381,7 @@ diff -urN a/mockgen/internal/tests/generics/BUILD.bazel b/mockgen/internal/tests + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/generics/other/BUILD.bazel b/mockgen/internal/tests/generics/other/BUILD.bazel ---- a/mockgen/internal/tests/generics/other/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/generics/other/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/generics/other/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -399,7 +399,7 @@ diff -urN a/mockgen/internal/tests/generics/other/BUILD.bazel b/mockgen/internal + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/generics/source/BUILD.bazel b/mockgen/internal/tests/generics/source/BUILD.bazel ---- a/mockgen/internal/tests/generics/source/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/generics/source/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/generics/source/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -418,7 +418,7 @@ diff -urN a/mockgen/internal/tests/generics/source/BUILD.bazel b/mockgen/interna + ], +) diff -urN a/mockgen/internal/tests/import_embedded_interface/BUILD.bazel b/mockgen/internal/tests/import_embedded_interface/BUILD.bazel ---- a/mockgen/internal/tests/import_embedded_interface/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/import_embedded_interface/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/import_embedded_interface/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -458,7 +458,7 @@ diff -urN a/mockgen/internal/tests/import_embedded_interface/BUILD.bazel b/mockg + deps = ["//gomock"], +) diff -urN a/mockgen/internal/tests/import_embedded_interface/ersatz/BUILD.bazel b/mockgen/internal/tests/import_embedded_interface/ersatz/BUILD.bazel ---- a/mockgen/internal/tests/import_embedded_interface/ersatz/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/import_embedded_interface/ersatz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/import_embedded_interface/ersatz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -476,7 +476,7 @@ diff -urN a/mockgen/internal/tests/import_embedded_interface/ersatz/BUILD.bazel + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/import_embedded_interface/faux/BUILD.bazel b/mockgen/internal/tests/import_embedded_interface/faux/BUILD.bazel ---- a/mockgen/internal/tests/import_embedded_interface/faux/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/import_embedded_interface/faux/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/import_embedded_interface/faux/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -501,7 +501,7 @@ diff -urN a/mockgen/internal/tests/import_embedded_interface/faux/BUILD.bazel b/ + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/import_embedded_interface/other/ersatz/BUILD.bazel b/mockgen/internal/tests/import_embedded_interface/other/ersatz/BUILD.bazel ---- a/mockgen/internal/tests/import_embedded_interface/other/ersatz/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/import_embedded_interface/other/ersatz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/import_embedded_interface/other/ersatz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -519,7 +519,7 @@ diff -urN a/mockgen/internal/tests/import_embedded_interface/other/ersatz/BUILD. + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/import_embedded_interface/other/log/BUILD.bazel b/mockgen/internal/tests/import_embedded_interface/other/log/BUILD.bazel ---- a/mockgen/internal/tests/import_embedded_interface/other/log/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/import_embedded_interface/other/log/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/import_embedded_interface/other/log/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -537,7 +537,7 @@ diff -urN a/mockgen/internal/tests/import_embedded_interface/other/log/BUILD.baz + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/import_source/BUILD.bazel b/mockgen/internal/tests/import_source/BUILD.bazel ---- a/mockgen/internal/tests/import_source/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/import_source/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/import_source/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -559,7 +559,7 @@ diff -urN a/mockgen/internal/tests/import_source/BUILD.bazel b/mockgen/internal/ + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/import_source/definition/BUILD.bazel b/mockgen/internal/tests/import_source/definition/BUILD.bazel ---- a/mockgen/internal/tests/import_source/definition/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/import_source/definition/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/import_source/definition/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -581,7 +581,7 @@ diff -urN a/mockgen/internal/tests/import_source/definition/BUILD.bazel b/mockge + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/internal_pkg/BUILD.bazel b/mockgen/internal/tests/internal_pkg/BUILD.bazel ---- a/mockgen/internal/tests/internal_pkg/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/internal_pkg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/internal_pkg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -599,7 +599,7 @@ diff -urN a/mockgen/internal/tests/internal_pkg/BUILD.bazel b/mockgen/internal/t + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/BUILD.bazel b/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/BUILD.bazel ---- a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -617,7 +617,7 @@ diff -urN a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/BUILD.bazel + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/reflect_output/BUILD.bazel b/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/reflect_output/BUILD.bazel ---- a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/reflect_output/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/reflect_output/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/reflect_output/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -639,7 +639,7 @@ diff -urN a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/reflect_outp + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/source_output/BUILD.bazel b/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/source_output/BUILD.bazel ---- a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/source_output/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/source_output/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/source_output/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -661,7 +661,7 @@ diff -urN a/mockgen/internal/tests/internal_pkg/subdir/internal/pkg/source_outpu + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/missing_import/output/BUILD.bazel b/mockgen/internal/tests/missing_import/output/BUILD.bazel ---- a/mockgen/internal/tests/missing_import/output/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/missing_import/output/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/missing_import/output/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -683,7 +683,7 @@ diff -urN a/mockgen/internal/tests/missing_import/output/BUILD.bazel b/mockgen/i + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/missing_import/source/BUILD.bazel b/mockgen/internal/tests/missing_import/source/BUILD.bazel ---- a/mockgen/internal/tests/missing_import/source/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/missing_import/source/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/missing_import/source/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -701,7 +701,7 @@ diff -urN a/mockgen/internal/tests/missing_import/source/BUILD.bazel b/mockgen/i + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/mock_in_test_package/BUILD.bazel b/mockgen/internal/tests/mock_in_test_package/BUILD.bazel ---- a/mockgen/internal/tests/mock_in_test_package/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/mock_in_test_package/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/mock_in_test_package/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -728,7 +728,7 @@ diff -urN a/mockgen/internal/tests/mock_in_test_package/BUILD.bazel b/mockgen/in + ], +) diff -urN a/mockgen/internal/tests/overlapping_methods/BUILD.bazel b/mockgen/internal/tests/overlapping_methods/BUILD.bazel ---- a/mockgen/internal/tests/overlapping_methods/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/overlapping_methods/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/overlapping_methods/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -758,7 +758,7 @@ diff -urN a/mockgen/internal/tests/overlapping_methods/BUILD.bazel b/mockgen/int + deps = ["//gomock"], +) diff -urN a/mockgen/internal/tests/panicing_test/BUILD.bazel b/mockgen/internal/tests/panicing_test/BUILD.bazel ---- a/mockgen/internal/tests/panicing_test/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/panicing_test/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/panicing_test/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -783,7 +783,7 @@ diff -urN a/mockgen/internal/tests/panicing_test/BUILD.bazel b/mockgen/internal/ + deps = ["//gomock"], +) diff -urN a/mockgen/internal/tests/parenthesized_parameter_type/BUILD.bazel b/mockgen/internal/tests/parenthesized_parameter_type/BUILD.bazel ---- a/mockgen/internal/tests/parenthesized_parameter_type/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/parenthesized_parameter_type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/parenthesized_parameter_type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -805,7 +805,7 @@ diff -urN a/mockgen/internal/tests/parenthesized_parameter_type/BUILD.bazel b/mo + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/performance/big_interface/BUILD.bazel b/mockgen/internal/tests/performance/big_interface/BUILD.bazel ---- a/mockgen/internal/tests/performance/big_interface/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/performance/big_interface/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/performance/big_interface/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -823,7 +823,7 @@ diff -urN a/mockgen/internal/tests/performance/big_interface/BUILD.bazel b/mockg + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/self_package/BUILD.bazel b/mockgen/internal/tests/self_package/BUILD.bazel ---- a/mockgen/internal/tests/self_package/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/self_package/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/self_package/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -845,7 +845,7 @@ diff -urN a/mockgen/internal/tests/self_package/BUILD.bazel b/mockgen/internal/t + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/test_package/BUILD.bazel b/mockgen/internal/tests/test_package/BUILD.bazel ---- a/mockgen/internal/tests/test_package/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/test_package/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/test_package/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -872,7 +872,7 @@ diff -urN a/mockgen/internal/tests/test_package/BUILD.bazel b/mockgen/internal/t + deps = ["//gomock"], +) diff -urN a/mockgen/internal/tests/unexported_method/BUILD.bazel b/mockgen/internal/tests/unexported_method/BUILD.bazel ---- a/mockgen/internal/tests/unexported_method/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/unexported_method/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/unexported_method/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -901,7 +901,7 @@ diff -urN a/mockgen/internal/tests/unexported_method/BUILD.bazel b/mockgen/inter + deps = ["//gomock"], +) diff -urN a/mockgen/internal/tests/vendor_dep/BUILD.bazel b/mockgen/internal/tests/vendor_dep/BUILD.bazel ---- a/mockgen/internal/tests/vendor_dep/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/vendor_dep/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/vendor_dep/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -927,7 +927,7 @@ diff -urN a/mockgen/internal/tests/vendor_dep/BUILD.bazel b/mockgen/internal/tes + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/vendor_dep/source_mock_package/BUILD.bazel b/mockgen/internal/tests/vendor_dep/source_mock_package/BUILD.bazel ---- a/mockgen/internal/tests/vendor_dep/source_mock_package/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/vendor_dep/source_mock_package/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/vendor_dep/source_mock_package/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -949,7 +949,7 @@ diff -urN a/mockgen/internal/tests/vendor_dep/source_mock_package/BUILD.bazel b/ + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/internal/tests/vendor_pkg/BUILD.bazel b/mockgen/internal/tests/vendor_pkg/BUILD.bazel ---- a/mockgen/internal/tests/vendor_pkg/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/internal/tests/vendor_pkg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/internal/tests/vendor_pkg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -971,7 +971,7 @@ diff -urN a/mockgen/internal/tests/vendor_pkg/BUILD.bazel b/mockgen/internal/tes + visibility = ["//mockgen:__subpackages__"], +) diff -urN a/mockgen/model/BUILD.bazel b/mockgen/model/BUILD.bazel ---- a/mockgen/model/BUILD.bazel 1969-12-31 16:00:00 +--- a/mockgen/model/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/mockgen/model/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -995,7 +995,7 @@ diff -urN a/mockgen/model/BUILD.bazel b/mockgen/model/BUILD.bazel + embed = [":model"], +) diff -urN a/sample/BUILD.bazel b/sample/BUILD.bazel ---- a/sample/BUILD.bazel 1969-12-31 16:00:00 +--- a/sample/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sample/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1035,7 +1035,7 @@ diff -urN a/sample/BUILD.bazel b/sample/BUILD.bazel + ], +) diff -urN a/sample/concurrent/BUILD.bazel b/sample/concurrent/BUILD.bazel ---- a/sample/concurrent/BUILD.bazel 1969-12-31 16:00:00 +--- a/sample/concurrent/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sample/concurrent/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1063,7 +1063,7 @@ diff -urN a/sample/concurrent/BUILD.bazel b/sample/concurrent/BUILD.bazel + ], +) diff -urN a/sample/concurrent/mock/BUILD.bazel b/sample/concurrent/mock/BUILD.bazel ---- a/sample/concurrent/mock/BUILD.bazel 1969-12-31 16:00:00 +--- a/sample/concurrent/mock/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sample/concurrent/mock/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1082,7 +1082,7 @@ diff -urN a/sample/concurrent/mock/BUILD.bazel b/sample/concurrent/mock/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/sample/imp1/BUILD.bazel b/sample/imp1/BUILD.bazel ---- a/sample/imp1/BUILD.bazel 1969-12-31 16:00:00 +--- a/sample/imp1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sample/imp1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1100,7 +1100,7 @@ diff -urN a/sample/imp1/BUILD.bazel b/sample/imp1/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/sample/imp2/BUILD.bazel b/sample/imp2/BUILD.bazel ---- a/sample/imp2/BUILD.bazel 1969-12-31 16:00:00 +--- a/sample/imp2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sample/imp2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1118,7 +1118,7 @@ diff -urN a/sample/imp2/BUILD.bazel b/sample/imp2/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/sample/imp3/BUILD.bazel b/sample/imp3/BUILD.bazel ---- a/sample/imp3/BUILD.bazel 1969-12-31 16:00:00 +--- a/sample/imp3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sample/imp3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1136,7 +1136,7 @@ diff -urN a/sample/imp3/BUILD.bazel b/sample/imp3/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/sample/imp4/BUILD.bazel b/sample/imp4/BUILD.bazel ---- a/sample/imp4/BUILD.bazel 1969-12-31 16:00:00 +--- a/sample/imp4/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/sample/imp4/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/third_party/com_github_golang_protobuf-gazelle.patch b/third_party/com_github_golang_protobuf-gazelle.patch index 01a4519dbe..c5b3510b70 100644 --- a/third_party/com_github_golang_protobuf-gazelle.patch +++ b/third_party/com_github_golang_protobuf-gazelle.patch @@ -1,5 +1,5 @@ diff -urN a/descriptor/BUILD.bazel b/descriptor/BUILD.bazel ---- a/descriptor/BUILD.bazel 1969-12-31 16:00:00 +--- a/descriptor/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/descriptor/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,46 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -49,7 +49,7 @@ diff -urN a/descriptor/BUILD.bazel b/descriptor/BUILD.bazel + ], +) diff -urN a/internal/cmd/generate-alias/BUILD.bazel b/internal/cmd/generate-alias/BUILD.bazel ---- a/internal/cmd/generate-alias/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/cmd/generate-alias/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/cmd/generate-alias/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -82,7 +82,7 @@ diff -urN a/internal/cmd/generate-alias/BUILD.bazel b/internal/cmd/generate-alia + visibility = ["//:__subpackages__"], +) diff -urN a/internal/gengogrpc/BUILD.bazel b/internal/gengogrpc/BUILD.bazel ---- a/internal/gengogrpc/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/gengogrpc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/gengogrpc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -104,7 +104,7 @@ diff -urN a/internal/gengogrpc/BUILD.bazel b/internal/gengogrpc/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/jsonpb_proto/BUILD.bazel b/internal/testprotos/jsonpb_proto/BUILD.bazel ---- a/internal/testprotos/jsonpb_proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/jsonpb_proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/jsonpb_proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -133,7 +133,7 @@ diff -urN a/internal/testprotos/jsonpb_proto/BUILD.bazel b/internal/testprotos/j + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/proto2_proto/BUILD.bazel b/internal/testprotos/proto2_proto/BUILD.bazel ---- a/internal/testprotos/proto2_proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/proto2_proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/proto2_proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -152,7 +152,7 @@ diff -urN a/internal/testprotos/proto2_proto/BUILD.bazel b/internal/testprotos/p + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/proto3_proto/BUILD.bazel b/internal/testprotos/proto3_proto/BUILD.bazel ---- a/internal/testprotos/proto3_proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/proto3_proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/proto3_proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -175,7 +175,7 @@ diff -urN a/internal/testprotos/proto3_proto/BUILD.bazel b/internal/testprotos/p + visibility = ["//:__subpackages__"], +) diff -urN a/jsonpb/BUILD.bazel b/jsonpb/BUILD.bazel ---- a/jsonpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/jsonpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/jsonpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,50 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -229,7 +229,7 @@ diff -urN a/jsonpb/BUILD.bazel b/jsonpb/BUILD.bazel + ], +) diff -urN a/proto/BUILD.bazel b/proto/BUILD.bazel ---- a/proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,61 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -294,7 +294,7 @@ diff -urN a/proto/BUILD.bazel b/proto/BUILD.bazel + ], +) diff -urN a/protoc-gen-go/BUILD.bazel b/protoc-gen-go/BUILD.bazel ---- a/protoc-gen-go/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-go/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-go/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -317,7 +317,7 @@ diff -urN a/protoc-gen-go/BUILD.bazel b/protoc-gen-go/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-go/descriptor/BUILD.bazel b/protoc-gen-go/descriptor/BUILD.bazel ---- a/protoc-gen-go/descriptor/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-go/descriptor/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-go/descriptor/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -340,7 +340,7 @@ diff -urN a/protoc-gen-go/descriptor/BUILD.bazel b/protoc-gen-go/descriptor/BUIL + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-go/generator/BUILD.bazel b/protoc-gen-go/generator/BUILD.bazel ---- a/protoc-gen-go/generator/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-go/generator/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-go/generator/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -377,7 +377,7 @@ diff -urN a/protoc-gen-go/generator/BUILD.bazel b/protoc-gen-go/generator/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-go/generator/internal/remap/BUILD.bazel b/protoc-gen-go/generator/internal/remap/BUILD.bazel ---- a/protoc-gen-go/generator/internal/remap/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-go/generator/internal/remap/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-go/generator/internal/remap/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -401,7 +401,7 @@ diff -urN a/protoc-gen-go/generator/internal/remap/BUILD.bazel b/protoc-gen-go/g + embed = [":remap"], +) diff -urN a/protoc-gen-go/grpc/BUILD.bazel b/protoc-gen-go/grpc/BUILD.bazel ---- a/protoc-gen-go/grpc/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-go/grpc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-go/grpc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -423,7 +423,7 @@ diff -urN a/protoc-gen-go/grpc/BUILD.bazel b/protoc-gen-go/grpc/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protoc-gen-go/plugin/BUILD.bazel b/protoc-gen-go/plugin/BUILD.bazel ---- a/protoc-gen-go/plugin/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoc-gen-go/plugin/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoc-gen-go/plugin/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -445,8 +445,31 @@ diff -urN a/protoc-gen-go/plugin/BUILD.bazel b/protoc-gen-go/plugin/BUILD.bazel + actual = ":plugin", + visibility = ["//visibility:public"], +) +diff -urN a/ptypes/any/BUILD.bazel b/ptypes/any/BUILD.bazel +--- a/ptypes/any/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/ptypes/any/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,19 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "any", ++ srcs = ["any.pb.go"], ++ importpath = "github.com/golang/protobuf/ptypes/any", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", ++ "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", ++ "@org_golang_google_protobuf//types/known/anypb:go_default_library", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":any", ++ visibility = ["//visibility:public"], ++) diff -urN a/ptypes/BUILD.bazel b/ptypes/BUILD.bazel ---- a/ptypes/BUILD.bazel 1969-12-31 16:00:00 +--- a/ptypes/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/ptypes/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,64 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -513,31 +536,8 @@ diff -urN a/ptypes/BUILD.bazel b/ptypes/BUILD.bazel + "//ptypes/timestamp", + ], +) -diff -urN a/ptypes/any/BUILD.bazel b/ptypes/any/BUILD.bazel ---- a/ptypes/any/BUILD.bazel 1969-12-31 16:00:00 -+++ b/ptypes/any/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,19 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "any", -+ srcs = ["any.pb.go"], -+ importpath = "github.com/golang/protobuf/ptypes/any", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", -+ "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", -+ "@org_golang_google_protobuf//types/known/anypb:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":any", -+ visibility = ["//visibility:public"], -+) diff -urN a/ptypes/duration/BUILD.bazel b/ptypes/duration/BUILD.bazel ---- a/ptypes/duration/BUILD.bazel 1969-12-31 16:00:00 +--- a/ptypes/duration/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/ptypes/duration/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -560,7 +560,7 @@ diff -urN a/ptypes/duration/BUILD.bazel b/ptypes/duration/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/ptypes/empty/BUILD.bazel b/ptypes/empty/BUILD.bazel ---- a/ptypes/empty/BUILD.bazel 1969-12-31 16:00:00 +--- a/ptypes/empty/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/ptypes/empty/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -583,7 +583,7 @@ diff -urN a/ptypes/empty/BUILD.bazel b/ptypes/empty/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/ptypes/struct/BUILD.bazel b/ptypes/struct/BUILD.bazel ---- a/ptypes/struct/BUILD.bazel 1969-12-31 16:00:00 +--- a/ptypes/struct/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/ptypes/struct/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -606,7 +606,7 @@ diff -urN a/ptypes/struct/BUILD.bazel b/ptypes/struct/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/ptypes/timestamp/BUILD.bazel b/ptypes/timestamp/BUILD.bazel ---- a/ptypes/timestamp/BUILD.bazel 1969-12-31 16:00:00 +--- a/ptypes/timestamp/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/ptypes/timestamp/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -629,7 +629,7 @@ diff -urN a/ptypes/timestamp/BUILD.bazel b/ptypes/timestamp/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/ptypes/wrappers/BUILD.bazel b/ptypes/wrappers/BUILD.bazel ---- a/ptypes/wrappers/BUILD.bazel 1969-12-31 16:00:00 +--- a/ptypes/wrappers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/ptypes/wrappers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/third_party/org_golang_google_genproto-gazelle.patch b/third_party/org_golang_google_genproto-gazelle.patch index 92b0901e2d..7722045464 100644 --- a/third_party/org_golang_google_genproto-gazelle.patch +++ b/third_party/org_golang_google_genproto-gazelle.patch @@ -1,5 +1,5 @@ diff -urN a/firestore/bundle/BUILD.bazel b/firestore/bundle/BUILD.bazel ---- a/firestore/bundle/BUILD.bazel 1969-12-31 16:00:00 +--- a/firestore/bundle/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/firestore/bundle/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -24,7 +24,7 @@ diff -urN a/firestore/bundle/BUILD.bazel b/firestore/bundle/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/actions/sdk/v2/BUILD.bazel b/googleapis/actions/sdk/v2/BUILD.bazel ---- a/googleapis/actions/sdk/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/actions/sdk/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/actions/sdk/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,51 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -79,7 +79,7 @@ diff -urN a/googleapis/actions/sdk/v2/BUILD.bazel b/googleapis/actions/sdk/v2/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/actions/sdk/v2/conversation/BUILD.bazel b/googleapis/actions/sdk/v2/conversation/BUILD.bazel ---- a/googleapis/actions/sdk/v2/conversation/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/actions/sdk/v2/conversation/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/actions/sdk/v2/conversation/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -118,7 +118,7 @@ diff -urN a/googleapis/actions/sdk/v2/conversation/BUILD.bazel b/googleapis/acti + visibility = ["//visibility:public"], +) diff -urN a/googleapis/actions/sdk/v2/interactionmodel/BUILD.bazel b/googleapis/actions/sdk/v2/interactionmodel/BUILD.bazel ---- a/googleapis/actions/sdk/v2/interactionmodel/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/actions/sdk/v2/interactionmodel/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/actions/sdk/v2/interactionmodel/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -153,7 +153,7 @@ diff -urN a/googleapis/actions/sdk/v2/interactionmodel/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/actions/sdk/v2/interactionmodel/prompt/BUILD.bazel b/googleapis/actions/sdk/v2/interactionmodel/prompt/BUILD.bazel ---- a/googleapis/actions/sdk/v2/interactionmodel/prompt/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/actions/sdk/v2/interactionmodel/prompt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/actions/sdk/v2/interactionmodel/prompt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -193,7 +193,7 @@ diff -urN a/googleapis/actions/sdk/v2/interactionmodel/prompt/BUILD.bazel b/goog + visibility = ["//visibility:public"], +) diff -urN a/googleapis/actions/sdk/v2/interactionmodel/type/BUILD.bazel b/googleapis/actions/sdk/v2/interactionmodel/type/BUILD.bazel ---- a/googleapis/actions/sdk/v2/interactionmodel/type/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/actions/sdk/v2/interactionmodel/type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/actions/sdk/v2/interactionmodel/type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -223,7 +223,7 @@ diff -urN a/googleapis/actions/sdk/v2/interactionmodel/type/BUILD.bazel b/google + visibility = ["//visibility:public"], +) diff -urN a/googleapis/analytics/admin/v1alpha/BUILD.bazel b/googleapis/analytics/admin/v1alpha/BUILD.bazel ---- a/googleapis/analytics/admin/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/analytics/admin/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/analytics/admin/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -245,7 +245,7 @@ diff -urN a/googleapis/analytics/admin/v1alpha/BUILD.bazel b/googleapis/analytic + visibility = ["//visibility:public"], +) diff -urN a/googleapis/analytics/admin/v1beta/BUILD.bazel b/googleapis/analytics/admin/v1beta/BUILD.bazel ---- a/googleapis/analytics/admin/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/analytics/admin/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/analytics/admin/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -279,7 +279,7 @@ diff -urN a/googleapis/analytics/admin/v1beta/BUILD.bazel b/googleapis/analytics + visibility = ["//visibility:public"], +) diff -urN a/googleapis/analytics/data/v1alpha/BUILD.bazel b/googleapis/analytics/data/v1alpha/BUILD.bazel ---- a/googleapis/analytics/data/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/analytics/data/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/analytics/data/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -309,7 +309,7 @@ diff -urN a/googleapis/analytics/data/v1alpha/BUILD.bazel b/googleapis/analytics + visibility = ["//visibility:public"], +) diff -urN a/googleapis/analytics/data/v1beta/BUILD.bazel b/googleapis/analytics/data/v1beta/BUILD.bazel ---- a/googleapis/analytics/data/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/analytics/data/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/analytics/data/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -338,7 +338,7 @@ diff -urN a/googleapis/analytics/data/v1beta/BUILD.bazel b/googleapis/analytics/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/analytics/management/v1alpha/BUILD.bazel b/googleapis/analytics/management/v1alpha/BUILD.bazel ---- a/googleapis/analytics/management/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/analytics/management/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/analytics/management/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -370,30 +370,8 @@ diff -urN a/googleapis/analytics/management/v1alpha/BUILD.bazel b/googleapis/ana + actual = ":v1alpha", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/api/BUILD.bazel b/googleapis/api/BUILD.bazel ---- a/googleapis/api/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/api/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "api", -+ srcs = ["launch_stage.pb.go"], -+ importpath = "google.golang.org/genproto/googleapis/api", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", -+ "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":api", -+ visibility = ["//visibility:public"], -+) diff -urN a/googleapis/api/annotations/BUILD.bazel b/googleapis/api/annotations/BUILD.bazel ---- a/googleapis/api/annotations/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/annotations/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/annotations/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -425,7 +403,7 @@ diff -urN a/googleapis/api/annotations/BUILD.bazel b/googleapis/api/annotations/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/apikeys/v2/BUILD.bazel b/googleapis/api/apikeys/v2/BUILD.bazel ---- a/googleapis/api/apikeys/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/apikeys/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/apikeys/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -446,8 +424,30 @@ diff -urN a/googleapis/api/apikeys/v2/BUILD.bazel b/googleapis/api/apikeys/v2/BU + actual = ":apikeys", + visibility = ["//visibility:public"], +) +diff -urN a/googleapis/api/BUILD.bazel b/googleapis/api/BUILD.bazel +--- a/googleapis/api/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/googleapis/api/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,18 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "api", ++ srcs = ["launch_stage.pb.go"], ++ importpath = "google.golang.org/genproto/googleapis/api", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", ++ "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":api", ++ visibility = ["//visibility:public"], ++) diff -urN a/googleapis/api/configchange/BUILD.bazel b/googleapis/api/configchange/BUILD.bazel ---- a/googleapis/api/configchange/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/configchange/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/configchange/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -469,7 +469,7 @@ diff -urN a/googleapis/api/configchange/BUILD.bazel b/googleapis/api/configchang + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/distribution/BUILD.bazel b/googleapis/api/distribution/BUILD.bazel ---- a/googleapis/api/distribution/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/distribution/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/distribution/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -493,7 +493,7 @@ diff -urN a/googleapis/api/distribution/BUILD.bazel b/googleapis/api/distributio + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/error_reason/BUILD.bazel b/googleapis/api/error_reason/BUILD.bazel ---- a/googleapis/api/error_reason/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/error_reason/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/error_reason/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -515,7 +515,7 @@ diff -urN a/googleapis/api/error_reason/BUILD.bazel b/googleapis/api/error_reaso + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/expr/conformance/v1alpha1/BUILD.bazel b/googleapis/api/expr/conformance/v1alpha1/BUILD.bazel ---- a/googleapis/api/expr/conformance/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/expr/conformance/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/expr/conformance/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -543,7 +543,7 @@ diff -urN a/googleapis/api/expr/conformance/v1alpha1/BUILD.bazel b/googleapis/ap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/expr/v1alpha1/BUILD.bazel b/googleapis/api/expr/v1alpha1/BUILD.bazel ---- a/googleapis/api/expr/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/expr/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/expr/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -577,7 +577,7 @@ diff -urN a/googleapis/api/expr/v1alpha1/BUILD.bazel b/googleapis/api/expr/v1alp + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/expr/v1beta1/BUILD.bazel b/googleapis/api/expr/v1beta1/BUILD.bazel ---- a/googleapis/api/expr/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/expr/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/expr/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -608,7 +608,7 @@ diff -urN a/googleapis/api/expr/v1beta1/BUILD.bazel b/googleapis/api/expr/v1beta + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/httpbody/BUILD.bazel b/googleapis/api/httpbody/BUILD.bazel ---- a/googleapis/api/httpbody/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/httpbody/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/httpbody/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -631,7 +631,7 @@ diff -urN a/googleapis/api/httpbody/BUILD.bazel b/googleapis/api/httpbody/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/label/BUILD.bazel b/googleapis/api/label/BUILD.bazel ---- a/googleapis/api/label/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/label/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/label/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -653,7 +653,7 @@ diff -urN a/googleapis/api/label/BUILD.bazel b/googleapis/api/label/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/metric/BUILD.bazel b/googleapis/api/metric/BUILD.bazel ---- a/googleapis/api/metric/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/metric/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/metric/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -678,7 +678,7 @@ diff -urN a/googleapis/api/metric/BUILD.bazel b/googleapis/api/metric/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/monitoredres/BUILD.bazel b/googleapis/api/monitoredres/BUILD.bazel ---- a/googleapis/api/monitoredres/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/monitoredres/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/monitoredres/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -703,9 +703,9 @@ diff -urN a/googleapis/api/monitoredres/BUILD.bazel b/googleapis/api/monitoredre + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/serviceconfig/BUILD.bazel b/googleapis/api/serviceconfig/BUILD.bazel ---- a/googleapis/api/serviceconfig/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/serviceconfig/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/serviceconfig/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,43 @@ +@@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( @@ -722,6 +722,7 @@ diff -urN a/googleapis/api/serviceconfig/BUILD.bazel b/googleapis/api/servicecon + "log.pb.go", + "logging.pb.go", + "monitoring.pb.go", ++ "policy.pb.go", + "quota.pb.go", + "service.pb.go", + "source_info.pb.go", @@ -737,6 +738,7 @@ diff -urN a/googleapis/api/serviceconfig/BUILD.bazel b/googleapis/api/servicecon + "//googleapis/api/monitoredres", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", ++ "@org_golang_google_protobuf//types/descriptorpb:go_default_library", + "@org_golang_google_protobuf//types/known/anypb:go_default_library", + "@org_golang_google_protobuf//types/known/apipb:go_default_library", + "@org_golang_google_protobuf//types/known/typepb:go_default_library", @@ -750,7 +752,7 @@ diff -urN a/googleapis/api/serviceconfig/BUILD.bazel b/googleapis/api/servicecon + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/servicecontrol/v1/BUILD.bazel b/googleapis/api/servicecontrol/v1/BUILD.bazel ---- a/googleapis/api/servicecontrol/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/servicecontrol/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/servicecontrol/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -772,7 +774,7 @@ diff -urN a/googleapis/api/servicecontrol/v1/BUILD.bazel b/googleapis/api/servic + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/servicecontrol/v2/BUILD.bazel b/googleapis/api/servicecontrol/v2/BUILD.bazel ---- a/googleapis/api/servicecontrol/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/servicecontrol/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/servicecontrol/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -800,7 +802,7 @@ diff -urN a/googleapis/api/servicecontrol/v2/BUILD.bazel b/googleapis/api/servic + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/servicemanagement/v1/BUILD.bazel b/googleapis/api/servicemanagement/v1/BUILD.bazel ---- a/googleapis/api/servicemanagement/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/servicemanagement/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/servicemanagement/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -822,7 +824,7 @@ diff -urN a/googleapis/api/servicemanagement/v1/BUILD.bazel b/googleapis/api/ser + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/serviceusage/v1/BUILD.bazel b/googleapis/api/serviceusage/v1/BUILD.bazel ---- a/googleapis/api/serviceusage/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/serviceusage/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/serviceusage/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -844,7 +846,7 @@ diff -urN a/googleapis/api/serviceusage/v1/BUILD.bazel b/googleapis/api/serviceu + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/serviceusage/v1beta1/BUILD.bazel b/googleapis/api/serviceusage/v1beta1/BUILD.bazel ---- a/googleapis/api/serviceusage/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/serviceusage/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/serviceusage/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -878,7 +880,7 @@ diff -urN a/googleapis/api/serviceusage/v1beta1/BUILD.bazel b/googleapis/api/ser + visibility = ["//visibility:public"], +) diff -urN a/googleapis/api/visibility/BUILD.bazel b/googleapis/api/visibility/BUILD.bazel ---- a/googleapis/api/visibility/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/api/visibility/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/api/visibility/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -901,7 +903,7 @@ diff -urN a/googleapis/api/visibility/BUILD.bazel b/googleapis/api/visibility/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/appengine/legacy/BUILD.bazel b/googleapis/appengine/legacy/BUILD.bazel ---- a/googleapis/appengine/legacy/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/appengine/legacy/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/appengine/legacy/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -923,7 +925,7 @@ diff -urN a/googleapis/appengine/legacy/BUILD.bazel b/googleapis/appengine/legac + visibility = ["//visibility:public"], +) diff -urN a/googleapis/appengine/logging/v1/BUILD.bazel b/googleapis/appengine/logging/v1/BUILD.bazel ---- a/googleapis/appengine/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/appengine/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/appengine/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -948,7 +950,7 @@ diff -urN a/googleapis/appengine/logging/v1/BUILD.bazel b/googleapis/appengine/l + visibility = ["//visibility:public"], +) diff -urN a/googleapis/appengine/v1/BUILD.bazel b/googleapis/appengine/v1/BUILD.bazel ---- a/googleapis/appengine/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/appengine/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/appengine/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -970,7 +972,7 @@ diff -urN a/googleapis/appengine/v1/BUILD.bazel b/googleapis/appengine/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/appengine/v1beta/BUILD.bazel b/googleapis/appengine/v1beta/BUILD.bazel ---- a/googleapis/appengine/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/appengine/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/appengine/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1019,7 +1021,7 @@ diff -urN a/googleapis/appengine/v1beta/BUILD.bazel b/googleapis/appengine/v1bet + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/alertcenter/v1beta1/BUILD.bazel b/googleapis/apps/alertcenter/v1beta1/BUILD.bazel ---- a/googleapis/apps/alertcenter/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/alertcenter/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/alertcenter/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1049,7 +1051,7 @@ diff -urN a/googleapis/apps/alertcenter/v1beta1/BUILD.bazel b/googleapis/apps/al + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/drive/activity/v2/BUILD.bazel b/googleapis/apps/drive/activity/v2/BUILD.bazel ---- a/googleapis/apps/drive/activity/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/drive/activity/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/drive/activity/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1084,7 +1086,7 @@ diff -urN a/googleapis/apps/drive/activity/v2/BUILD.bazel b/googleapis/apps/driv + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/drive/labels/v2/BUILD.bazel b/googleapis/apps/drive/labels/v2/BUILD.bazel ---- a/googleapis/apps/drive/labels/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/drive/labels/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/drive/labels/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1122,7 +1124,7 @@ diff -urN a/googleapis/apps/drive/labels/v2/BUILD.bazel b/googleapis/apps/drive/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/drive/labels/v2beta/BUILD.bazel b/googleapis/apps/drive/labels/v2beta/BUILD.bazel ---- a/googleapis/apps/drive/labels/v2beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/drive/labels/v2beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/drive/labels/v2beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,39 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1165,7 +1167,7 @@ diff -urN a/googleapis/apps/drive/labels/v2beta/BUILD.bazel b/googleapis/apps/dr + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/script/type/BUILD.bazel b/googleapis/apps/script/type/BUILD.bazel ---- a/googleapis/apps/script/type/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/script/type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/script/type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1193,7 +1195,7 @@ diff -urN a/googleapis/apps/script/type/BUILD.bazel b/googleapis/apps/script/typ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/script/type/calendar/BUILD.bazel b/googleapis/apps/script/type/calendar/BUILD.bazel ---- a/googleapis/apps/script/type/calendar/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/script/type/calendar/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/script/type/calendar/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1217,7 +1219,7 @@ diff -urN a/googleapis/apps/script/type/calendar/BUILD.bazel b/googleapis/apps/s + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/script/type/docs/BUILD.bazel b/googleapis/apps/script/type/docs/BUILD.bazel ---- a/googleapis/apps/script/type/docs/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/script/type/docs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/script/type/docs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1241,7 +1243,7 @@ diff -urN a/googleapis/apps/script/type/docs/BUILD.bazel b/googleapis/apps/scrip + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/script/type/drive/BUILD.bazel b/googleapis/apps/script/type/drive/BUILD.bazel ---- a/googleapis/apps/script/type/drive/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/script/type/drive/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/script/type/drive/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1264,7 +1266,7 @@ diff -urN a/googleapis/apps/script/type/drive/BUILD.bazel b/googleapis/apps/scri + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/script/type/gmail/BUILD.bazel b/googleapis/apps/script/type/gmail/BUILD.bazel ---- a/googleapis/apps/script/type/gmail/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/script/type/gmail/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/script/type/gmail/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1287,7 +1289,7 @@ diff -urN a/googleapis/apps/script/type/gmail/BUILD.bazel b/googleapis/apps/scri + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/script/type/sheets/BUILD.bazel b/googleapis/apps/script/type/sheets/BUILD.bazel ---- a/googleapis/apps/script/type/sheets/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/script/type/sheets/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/script/type/sheets/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1311,7 +1313,7 @@ diff -urN a/googleapis/apps/script/type/sheets/BUILD.bazel b/googleapis/apps/scr + visibility = ["//visibility:public"], +) diff -urN a/googleapis/apps/script/type/slides/BUILD.bazel b/googleapis/apps/script/type/slides/BUILD.bazel ---- a/googleapis/apps/script/type/slides/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/apps/script/type/slides/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/apps/script/type/slides/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1335,7 +1337,7 @@ diff -urN a/googleapis/apps/script/type/slides/BUILD.bazel b/googleapis/apps/scr + visibility = ["//visibility:public"], +) diff -urN a/googleapis/area120/tables/v1alpha1/BUILD.bazel b/googleapis/area120/tables/v1alpha1/BUILD.bazel ---- a/googleapis/area120/tables/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/area120/tables/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/area120/tables/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1357,7 +1359,7 @@ diff -urN a/googleapis/area120/tables/v1alpha1/BUILD.bazel b/googleapis/area120/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/assistant/embedded/v1alpha1/BUILD.bazel b/googleapis/assistant/embedded/v1alpha1/BUILD.bazel ---- a/googleapis/assistant/embedded/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/assistant/embedded/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/assistant/embedded/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1384,7 +1386,7 @@ diff -urN a/googleapis/assistant/embedded/v1alpha1/BUILD.bazel b/googleapis/assi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/assistant/embedded/v1alpha2/BUILD.bazel b/googleapis/assistant/embedded/v1alpha2/BUILD.bazel ---- a/googleapis/assistant/embedded/v1alpha2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/assistant/embedded/v1alpha2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/assistant/embedded/v1alpha2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1411,7 +1413,7 @@ diff -urN a/googleapis/assistant/embedded/v1alpha2/BUILD.bazel b/googleapis/assi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/bigtable/admin/cluster/v1/BUILD.bazel b/googleapis/bigtable/admin/cluster/v1/BUILD.bazel ---- a/googleapis/bigtable/admin/cluster/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/bigtable/admin/cluster/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/bigtable/admin/cluster/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1445,7 +1447,7 @@ diff -urN a/googleapis/bigtable/admin/cluster/v1/BUILD.bazel b/googleapis/bigtab + visibility = ["//visibility:public"], +) diff -urN a/googleapis/bigtable/admin/table/v1/BUILD.bazel b/googleapis/bigtable/admin/table/v1/BUILD.bazel ---- a/googleapis/bigtable/admin/table/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/bigtable/admin/table/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/bigtable/admin/table/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1479,7 +1481,7 @@ diff -urN a/googleapis/bigtable/admin/table/v1/BUILD.bazel b/googleapis/bigtable + visibility = ["//visibility:public"], +) diff -urN a/googleapis/bigtable/admin/v2/BUILD.bazel b/googleapis/bigtable/admin/v2/BUILD.bazel ---- a/googleapis/bigtable/admin/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/bigtable/admin/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/bigtable/admin/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1520,7 +1522,7 @@ diff -urN a/googleapis/bigtable/admin/v2/BUILD.bazel b/googleapis/bigtable/admin + visibility = ["//visibility:public"], +) diff -urN a/googleapis/bigtable/v1/BUILD.bazel b/googleapis/bigtable/v1/BUILD.bazel ---- a/googleapis/bigtable/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/bigtable/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/bigtable/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1553,7 +1555,7 @@ diff -urN a/googleapis/bigtable/v1/BUILD.bazel b/googleapis/bigtable/v1/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/bigtable/v2/BUILD.bazel b/googleapis/bigtable/v2/BUILD.bazel ---- a/googleapis/bigtable/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/bigtable/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/bigtable/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1589,7 +1591,7 @@ diff -urN a/googleapis/bigtable/v2/BUILD.bazel b/googleapis/bigtable/v2/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/bytestream/BUILD.bazel b/googleapis/bytestream/BUILD.bazel ---- a/googleapis/bytestream/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/bytestream/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/bytestream/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1616,7 +1618,7 @@ diff -urN a/googleapis/bytestream/BUILD.bazel b/googleapis/bytestream/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/ccc/hosted/marketplace/v2/BUILD.bazel b/googleapis/ccc/hosted/marketplace/v2/BUILD.bazel ---- a/googleapis/ccc/hosted/marketplace/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/ccc/hosted/marketplace/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/ccc/hosted/marketplace/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1645,7 +1647,7 @@ diff -urN a/googleapis/ccc/hosted/marketplace/v2/BUILD.bazel b/googleapis/ccc/ho + visibility = ["//visibility:public"], +) diff -urN a/googleapis/chat/dynamite/integration/logging/v1/BUILD.bazel b/googleapis/chat/dynamite/integration/logging/v1/BUILD.bazel ---- a/googleapis/chat/dynamite/integration/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/chat/dynamite/integration/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/chat/dynamite/integration/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1668,7 +1670,7 @@ diff -urN a/googleapis/chat/dynamite/integration/logging/v1/BUILD.bazel b/google + visibility = ["//visibility:public"], +) diff -urN a/googleapis/chat/logging/v1/BUILD.bazel b/googleapis/chat/logging/v1/BUILD.bazel ---- a/googleapis/chat/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/chat/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/chat/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1691,7 +1693,7 @@ diff -urN a/googleapis/chat/logging/v1/BUILD.bazel b/googleapis/chat/logging/v1/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/chromeos/moblab/v1beta1/BUILD.bazel b/googleapis/chromeos/moblab/v1beta1/BUILD.bazel ---- a/googleapis/chromeos/moblab/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/chromeos/moblab/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/chromeos/moblab/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1723,7 +1725,7 @@ diff -urN a/googleapis/chromeos/moblab/v1beta1/BUILD.bazel b/googleapis/chromeos + visibility = ["//visibility:public"], +) diff -urN a/googleapis/chromeos/uidetection/v1/BUILD.bazel b/googleapis/chromeos/uidetection/v1/BUILD.bazel ---- a/googleapis/chromeos/uidetection/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/chromeos/uidetection/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/chromeos/uidetection/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1749,7 +1751,7 @@ diff -urN a/googleapis/chromeos/uidetection/v1/BUILD.bazel b/googleapis/chromeos + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/accessapproval/v1/BUILD.bazel b/googleapis/cloud/accessapproval/v1/BUILD.bazel ---- a/googleapis/cloud/accessapproval/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/accessapproval/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/accessapproval/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1771,7 +1773,7 @@ diff -urN a/googleapis/cloud/accessapproval/v1/BUILD.bazel b/googleapis/cloud/ac + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/logging/BUILD.bazel b/googleapis/cloud/aiplatform/logging/BUILD.bazel ---- a/googleapis/cloud/aiplatform/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1794,7 +1796,7 @@ diff -urN a/googleapis/cloud/aiplatform/logging/BUILD.bazel b/googleapis/cloud/a + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1/BUILD.bazel b/googleapis/cloud/aiplatform/v1/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1816,7 +1818,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1/BUILD.bazel b/googleapis/cloud/aiplat + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1/schema/predict/instance/BUILD.bazel b/googleapis/cloud/aiplatform/v1/schema/predict/instance/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1/schema/predict/instance/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1/schema/predict/instance/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1/schema/predict/instance/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1848,7 +1850,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1/schema/predict/instance/BUILD.bazel b + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1/schema/predict/params/BUILD.bazel b/googleapis/cloud/aiplatform/v1/schema/predict/params/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1/schema/predict/params/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1/schema/predict/params/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1/schema/predict/params/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1877,7 +1879,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1/schema/predict/params/BUILD.bazel b/g + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1/schema/predict/prediction/BUILD.bazel b/googleapis/cloud/aiplatform/v1/schema/predict/prediction/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1/schema/predict/prediction/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1/schema/predict/prediction/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1/schema/predict/prediction/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1913,7 +1915,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1/schema/predict/prediction/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1/schema/trainingjob/definition/BUILD.bazel b/googleapis/cloud/aiplatform/v1/schema/trainingjob/definition/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1/schema/trainingjob/definition/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1/schema/trainingjob/definition/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1/schema/trainingjob/definition/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1950,7 +1952,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1/schema/trainingjob/definition/BUILD.b + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1beta1/BUILD.bazel b/googleapis/cloud/aiplatform/v1beta1/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1972,7 +1974,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1beta1/BUILD.bazel b/googleapis/cloud/a + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/BUILD.bazel b/googleapis/cloud/aiplatform/v1beta1/schema/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1beta1/schema/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1beta1/schema/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1beta1/schema/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2007,7 +2009,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/predict/instance/BUILD.bazel b/googleapis/cloud/aiplatform/v1beta1/schema/predict/instance/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1beta1/schema/predict/instance/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1beta1/schema/predict/instance/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1beta1/schema/predict/instance/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2039,7 +2041,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/predict/instance/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/predict/params/BUILD.bazel b/googleapis/cloud/aiplatform/v1beta1/schema/predict/params/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1beta1/schema/predict/params/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1beta1/schema/predict/params/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1beta1/schema/predict/params/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2068,7 +2070,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/predict/params/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/predict/prediction/BUILD.bazel b/googleapis/cloud/aiplatform/v1beta1/schema/predict/prediction/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1beta1/schema/predict/prediction/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1beta1/schema/predict/prediction/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1beta1/schema/predict/prediction/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2105,7 +2107,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/predict/prediction/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/trainingjob/definition/BUILD.bazel b/googleapis/cloud/aiplatform/v1beta1/schema/trainingjob/definition/BUILD.bazel ---- a/googleapis/cloud/aiplatform/v1beta1/schema/trainingjob/definition/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/aiplatform/v1beta1/schema/trainingjob/definition/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/aiplatform/v1beta1/schema/trainingjob/definition/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2140,7 +2142,7 @@ diff -urN a/googleapis/cloud/aiplatform/v1beta1/schema/trainingjob/definition/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/apigateway/v1/BUILD.bazel b/googleapis/cloud/apigateway/v1/BUILD.bazel ---- a/googleapis/cloud/apigateway/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/apigateway/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/apigateway/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2162,7 +2164,7 @@ diff -urN a/googleapis/cloud/apigateway/v1/BUILD.bazel b/googleapis/cloud/apigat + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/apigeeconnect/v1/BUILD.bazel b/googleapis/cloud/apigeeconnect/v1/BUILD.bazel ---- a/googleapis/cloud/apigeeconnect/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/apigeeconnect/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/apigeeconnect/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2184,7 +2186,7 @@ diff -urN a/googleapis/cloud/apigeeconnect/v1/BUILD.bazel b/googleapis/cloud/api + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/apigeeregistry/v1/BUILD.bazel b/googleapis/cloud/apigeeregistry/v1/BUILD.bazel ---- a/googleapis/cloud/apigeeregistry/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/apigeeregistry/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/apigeeregistry/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2206,7 +2208,7 @@ diff -urN a/googleapis/cloud/apigeeregistry/v1/BUILD.bazel b/googleapis/cloud/ap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/asset/v1/BUILD.bazel b/googleapis/cloud/asset/v1/BUILD.bazel ---- a/googleapis/cloud/asset/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/asset/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/asset/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2228,7 +2230,7 @@ diff -urN a/googleapis/cloud/asset/v1/BUILD.bazel b/googleapis/cloud/asset/v1/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/asset/v1p1beta1/BUILD.bazel b/googleapis/cloud/asset/v1p1beta1/BUILD.bazel ---- a/googleapis/cloud/asset/v1p1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/asset/v1p1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/asset/v1p1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2258,7 +2260,7 @@ diff -urN a/googleapis/cloud/asset/v1p1beta1/BUILD.bazel b/googleapis/cloud/asse + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/asset/v1p2beta1/BUILD.bazel b/googleapis/cloud/asset/v1p2beta1/BUILD.bazel ---- a/googleapis/cloud/asset/v1p2beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/asset/v1p2beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/asset/v1p2beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2280,7 +2282,7 @@ diff -urN a/googleapis/cloud/asset/v1p2beta1/BUILD.bazel b/googleapis/cloud/asse + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/asset/v1p4beta1/BUILD.bazel b/googleapis/cloud/asset/v1p4beta1/BUILD.bazel ---- a/googleapis/cloud/asset/v1p4beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/asset/v1p4beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/asset/v1p4beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2313,7 +2315,7 @@ diff -urN a/googleapis/cloud/asset/v1p4beta1/BUILD.bazel b/googleapis/cloud/asse + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/asset/v1p5beta1/BUILD.bazel b/googleapis/cloud/asset/v1p5beta1/BUILD.bazel ---- a/googleapis/cloud/asset/v1p5beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/asset/v1p5beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/asset/v1p5beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2335,7 +2337,7 @@ diff -urN a/googleapis/cloud/asset/v1p5beta1/BUILD.bazel b/googleapis/cloud/asse + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/asset/v1p7beta1/BUILD.bazel b/googleapis/cloud/asset/v1p7beta1/BUILD.bazel ---- a/googleapis/cloud/asset/v1p7beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/asset/v1p7beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/asset/v1p7beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2370,7 +2372,7 @@ diff -urN a/googleapis/cloud/asset/v1p7beta1/BUILD.bazel b/googleapis/cloud/asse + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/assuredworkloads/regulatoryintercept/logging/v1/BUILD.bazel b/googleapis/cloud/assuredworkloads/regulatoryintercept/logging/v1/BUILD.bazel ---- a/googleapis/cloud/assuredworkloads/regulatoryintercept/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/assuredworkloads/regulatoryintercept/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/assuredworkloads/regulatoryintercept/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2392,7 +2394,7 @@ diff -urN a/googleapis/cloud/assuredworkloads/regulatoryintercept/logging/v1/BUI + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/assuredworkloads/v1/BUILD.bazel b/googleapis/cloud/assuredworkloads/v1/BUILD.bazel ---- a/googleapis/cloud/assuredworkloads/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/assuredworkloads/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/assuredworkloads/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2414,7 +2416,7 @@ diff -urN a/googleapis/cloud/assuredworkloads/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/assuredworkloads/v1beta1/BUILD.bazel b/googleapis/cloud/assuredworkloads/v1beta1/BUILD.bazel ---- a/googleapis/cloud/assuredworkloads/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/assuredworkloads/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/assuredworkloads/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2436,7 +2438,7 @@ diff -urN a/googleapis/cloud/assuredworkloads/v1beta1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/audit/BUILD.bazel b/googleapis/cloud/audit/BUILD.bazel ---- a/googleapis/cloud/audit/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/audit/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/audit/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2469,7 +2471,7 @@ diff -urN a/googleapis/cloud/audit/BUILD.bazel b/googleapis/cloud/audit/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/automl/v1/BUILD.bazel b/googleapis/cloud/automl/v1/BUILD.bazel ---- a/googleapis/cloud/automl/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/automl/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/automl/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2491,7 +2493,7 @@ diff -urN a/googleapis/cloud/automl/v1/BUILD.bazel b/googleapis/cloud/automl/v1/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/automl/v1beta1/BUILD.bazel b/googleapis/cloud/automl/v1beta1/BUILD.bazel ---- a/googleapis/cloud/automl/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/automl/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/automl/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2513,7 +2515,7 @@ diff -urN a/googleapis/cloud/automl/v1beta1/BUILD.bazel b/googleapis/cloud/autom + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/backupdr/logging/v1/BUILD.bazel b/googleapis/cloud/backupdr/logging/v1/BUILD.bazel ---- a/googleapis/cloud/backupdr/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/backupdr/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/backupdr/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2536,7 +2538,7 @@ diff -urN a/googleapis/cloud/backupdr/logging/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/baremetalsolution/v2/BUILD.bazel b/googleapis/cloud/baremetalsolution/v2/BUILD.bazel ---- a/googleapis/cloud/baremetalsolution/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/baremetalsolution/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/baremetalsolution/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2558,7 +2560,7 @@ diff -urN a/googleapis/cloud/baremetalsolution/v2/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/batch/v1/BUILD.bazel b/googleapis/cloud/batch/v1/BUILD.bazel ---- a/googleapis/cloud/batch/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/batch/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/batch/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2580,7 +2582,7 @@ diff -urN a/googleapis/cloud/batch/v1/BUILD.bazel b/googleapis/cloud/batch/v1/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/batch/v1alpha/BUILD.bazel b/googleapis/cloud/batch/v1alpha/BUILD.bazel ---- a/googleapis/cloud/batch/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/batch/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/batch/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2615,7 +2617,7 @@ diff -urN a/googleapis/cloud/batch/v1alpha/BUILD.bazel b/googleapis/cloud/batch/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/batch/v1alpha1/BUILD.bazel b/googleapis/cloud/batch/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/batch/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/batch/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/batch/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2649,7 +2651,7 @@ diff -urN a/googleapis/cloud/batch/v1alpha1/BUILD.bazel b/googleapis/cloud/batch + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/batch/v1main/BUILD.bazel b/googleapis/cloud/batch/v1main/BUILD.bazel ---- a/googleapis/cloud/batch/v1main/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/batch/v1main/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/batch/v1main/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2673,7 +2675,7 @@ diff -urN a/googleapis/cloud/batch/v1main/BUILD.bazel b/googleapis/cloud/batch/v + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/beyondcorp/appconnections/v1/BUILD.bazel b/googleapis/cloud/beyondcorp/appconnections/v1/BUILD.bazel ---- a/googleapis/cloud/beyondcorp/appconnections/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/beyondcorp/appconnections/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/beyondcorp/appconnections/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2695,7 +2697,7 @@ diff -urN a/googleapis/cloud/beyondcorp/appconnections/v1/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/beyondcorp/appconnectors/v1/BUILD.bazel b/googleapis/cloud/beyondcorp/appconnectors/v1/BUILD.bazel ---- a/googleapis/cloud/beyondcorp/appconnectors/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/beyondcorp/appconnectors/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/beyondcorp/appconnectors/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2717,7 +2719,7 @@ diff -urN a/googleapis/cloud/beyondcorp/appconnectors/v1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/beyondcorp/appgateways/v1/BUILD.bazel b/googleapis/cloud/beyondcorp/appgateways/v1/BUILD.bazel ---- a/googleapis/cloud/beyondcorp/appgateways/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/beyondcorp/appgateways/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/beyondcorp/appgateways/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2739,7 +2741,7 @@ diff -urN a/googleapis/cloud/beyondcorp/appgateways/v1/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/beyondcorp/clientconnectorservices/v1/BUILD.bazel b/googleapis/cloud/beyondcorp/clientconnectorservices/v1/BUILD.bazel ---- a/googleapis/cloud/beyondcorp/clientconnectorservices/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/beyondcorp/clientconnectorservices/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/beyondcorp/clientconnectorservices/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2761,7 +2763,7 @@ diff -urN a/googleapis/cloud/beyondcorp/clientconnectorservices/v1/BUILD.bazel b + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/beyondcorp/clientgateways/v1/BUILD.bazel b/googleapis/cloud/beyondcorp/clientgateways/v1/BUILD.bazel ---- a/googleapis/cloud/beyondcorp/clientgateways/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/beyondcorp/clientgateways/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/beyondcorp/clientgateways/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2783,7 +2785,7 @@ diff -urN a/googleapis/cloud/beyondcorp/clientgateways/v1/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/analyticshub/v1/BUILD.bazel b/googleapis/cloud/bigquery/analyticshub/v1/BUILD.bazel ---- a/googleapis/cloud/bigquery/analyticshub/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/analyticshub/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/analyticshub/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2805,7 +2807,7 @@ diff -urN a/googleapis/cloud/bigquery/analyticshub/v1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/connection/v1/BUILD.bazel b/googleapis/cloud/bigquery/connection/v1/BUILD.bazel ---- a/googleapis/cloud/bigquery/connection/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/connection/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/connection/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2827,7 +2829,7 @@ diff -urN a/googleapis/cloud/bigquery/connection/v1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/connection/v1beta1/BUILD.bazel b/googleapis/cloud/bigquery/connection/v1beta1/BUILD.bazel ---- a/googleapis/cloud/bigquery/connection/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/connection/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/connection/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2849,7 +2851,7 @@ diff -urN a/googleapis/cloud/bigquery/connection/v1beta1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/dataexchange/common/BUILD.bazel b/googleapis/cloud/bigquery/dataexchange/common/BUILD.bazel ---- a/googleapis/cloud/bigquery/dataexchange/common/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/dataexchange/common/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/dataexchange/common/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2871,7 +2873,7 @@ diff -urN a/googleapis/cloud/bigquery/dataexchange/common/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/dataexchange/v1beta1/BUILD.bazel b/googleapis/cloud/bigquery/dataexchange/v1beta1/BUILD.bazel ---- a/googleapis/cloud/bigquery/dataexchange/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/dataexchange/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/dataexchange/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2893,7 +2895,7 @@ diff -urN a/googleapis/cloud/bigquery/dataexchange/v1beta1/BUILD.bazel b/googlea + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/datapolicies/v1beta1/BUILD.bazel b/googleapis/cloud/bigquery/datapolicies/v1beta1/BUILD.bazel ---- a/googleapis/cloud/bigquery/datapolicies/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/datapolicies/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/datapolicies/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2915,7 +2917,7 @@ diff -urN a/googleapis/cloud/bigquery/datapolicies/v1beta1/BUILD.bazel b/googlea + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/datatransfer/v1/BUILD.bazel b/googleapis/cloud/bigquery/datatransfer/v1/BUILD.bazel ---- a/googleapis/cloud/bigquery/datatransfer/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/datatransfer/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/datatransfer/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2937,7 +2939,7 @@ diff -urN a/googleapis/cloud/bigquery/datatransfer/v1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/logging/v1/BUILD.bazel b/googleapis/cloud/bigquery/logging/v1/BUILD.bazel ---- a/googleapis/cloud/bigquery/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2963,7 +2965,7 @@ diff -urN a/googleapis/cloud/bigquery/logging/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/migration/tasks/assessment/v2alpha/BUILD.bazel b/googleapis/cloud/bigquery/migration/tasks/assessment/v2alpha/BUILD.bazel ---- a/googleapis/cloud/bigquery/migration/tasks/assessment/v2alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/migration/tasks/assessment/v2alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/migration/tasks/assessment/v2alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2986,7 +2988,7 @@ diff -urN a/googleapis/cloud/bigquery/migration/tasks/assessment/v2alpha/BUILD.b + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/migration/tasks/translation/v2alpha/BUILD.bazel b/googleapis/cloud/bigquery/migration/tasks/translation/v2alpha/BUILD.bazel ---- a/googleapis/cloud/bigquery/migration/tasks/translation/v2alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/migration/tasks/translation/v2alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/migration/tasks/translation/v2alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3012,7 +3014,7 @@ diff -urN a/googleapis/cloud/bigquery/migration/tasks/translation/v2alpha/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/migration/v2/BUILD.bazel b/googleapis/cloud/bigquery/migration/v2/BUILD.bazel ---- a/googleapis/cloud/bigquery/migration/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/migration/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/migration/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3034,7 +3036,7 @@ diff -urN a/googleapis/cloud/bigquery/migration/v2/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/migration/v2alpha/BUILD.bazel b/googleapis/cloud/bigquery/migration/v2alpha/BUILD.bazel ---- a/googleapis/cloud/bigquery/migration/v2alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/migration/v2alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/migration/v2alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3056,7 +3058,7 @@ diff -urN a/googleapis/cloud/bigquery/migration/v2alpha/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/reservation/v1/BUILD.bazel b/googleapis/cloud/bigquery/reservation/v1/BUILD.bazel ---- a/googleapis/cloud/bigquery/reservation/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/reservation/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/reservation/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3078,7 +3080,7 @@ diff -urN a/googleapis/cloud/bigquery/reservation/v1/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/reservation/v1beta1/BUILD.bazel b/googleapis/cloud/bigquery/reservation/v1beta1/BUILD.bazel ---- a/googleapis/cloud/bigquery/reservation/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/reservation/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/reservation/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3108,7 +3110,7 @@ diff -urN a/googleapis/cloud/bigquery/reservation/v1beta1/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/storage/v1/BUILD.bazel b/googleapis/cloud/bigquery/storage/v1/BUILD.bazel ---- a/googleapis/cloud/bigquery/storage/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/storage/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/storage/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3130,7 +3132,7 @@ diff -urN a/googleapis/cloud/bigquery/storage/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/storage/v1alpha2/BUILD.bazel b/googleapis/cloud/bigquery/storage/v1alpha2/BUILD.bazel ---- a/googleapis/cloud/bigquery/storage/v1alpha2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/storage/v1alpha2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/storage/v1alpha2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3167,7 +3169,7 @@ diff -urN a/googleapis/cloud/bigquery/storage/v1alpha2/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/storage/v1beta1/BUILD.bazel b/googleapis/cloud/bigquery/storage/v1beta1/BUILD.bazel ---- a/googleapis/cloud/bigquery/storage/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/storage/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/storage/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3189,7 +3191,7 @@ diff -urN a/googleapis/cloud/bigquery/storage/v1beta1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/storage/v1beta2/BUILD.bazel b/googleapis/cloud/bigquery/storage/v1beta2/BUILD.bazel ---- a/googleapis/cloud/bigquery/storage/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/storage/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/storage/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3211,7 +3213,7 @@ diff -urN a/googleapis/cloud/bigquery/storage/v1beta2/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/bigquery/v2/BUILD.bazel b/googleapis/cloud/bigquery/v2/BUILD.bazel ---- a/googleapis/cloud/bigquery/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/bigquery/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/bigquery/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3246,7 +3248,7 @@ diff -urN a/googleapis/cloud/bigquery/v2/BUILD.bazel b/googleapis/cloud/bigquery + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/billing/budgets/v1/BUILD.bazel b/googleapis/cloud/billing/budgets/v1/BUILD.bazel ---- a/googleapis/cloud/billing/budgets/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/billing/budgets/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/billing/budgets/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3268,7 +3270,7 @@ diff -urN a/googleapis/cloud/billing/budgets/v1/BUILD.bazel b/googleapis/cloud/b + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/billing/budgets/v1alpha1/BUILD.bazel b/googleapis/cloud/billing/budgets/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/billing/budgets/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/billing/budgets/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/billing/budgets/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3302,7 +3304,7 @@ diff -urN a/googleapis/cloud/billing/budgets/v1alpha1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/billing/budgets/v1beta1/BUILD.bazel b/googleapis/cloud/billing/budgets/v1beta1/BUILD.bazel ---- a/googleapis/cloud/billing/budgets/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/billing/budgets/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/billing/budgets/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3324,7 +3326,7 @@ diff -urN a/googleapis/cloud/billing/budgets/v1beta1/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/billing/v1/BUILD.bazel b/googleapis/cloud/billing/v1/BUILD.bazel ---- a/googleapis/cloud/billing/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/billing/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/billing/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3346,7 +3348,7 @@ diff -urN a/googleapis/cloud/billing/v1/BUILD.bazel b/googleapis/cloud/billing/v + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/binaryauthorization/v1/BUILD.bazel b/googleapis/cloud/binaryauthorization/v1/BUILD.bazel ---- a/googleapis/cloud/binaryauthorization/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/binaryauthorization/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/binaryauthorization/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3368,7 +3370,7 @@ diff -urN a/googleapis/cloud/binaryauthorization/v1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/binaryauthorization/v1beta1/BUILD.bazel b/googleapis/cloud/binaryauthorization/v1beta1/BUILD.bazel ---- a/googleapis/cloud/binaryauthorization/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/binaryauthorization/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/binaryauthorization/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3390,7 +3392,7 @@ diff -urN a/googleapis/cloud/binaryauthorization/v1beta1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/certificatemanager/logging/v1/BUILD.bazel b/googleapis/cloud/certificatemanager/logging/v1/BUILD.bazel ---- a/googleapis/cloud/certificatemanager/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/certificatemanager/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/certificatemanager/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3413,7 +3415,7 @@ diff -urN a/googleapis/cloud/certificatemanager/logging/v1/BUILD.bazel b/googlea + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/certificatemanager/v1/BUILD.bazel b/googleapis/cloud/certificatemanager/v1/BUILD.bazel ---- a/googleapis/cloud/certificatemanager/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/certificatemanager/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/certificatemanager/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3435,7 +3437,7 @@ diff -urN a/googleapis/cloud/certificatemanager/v1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/channel/v1/BUILD.bazel b/googleapis/cloud/channel/v1/BUILD.bazel ---- a/googleapis/cloud/channel/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/channel/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/channel/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3457,7 +3459,7 @@ diff -urN a/googleapis/cloud/channel/v1/BUILD.bazel b/googleapis/cloud/channel/v + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/clouddms/logging/v1/BUILD.bazel b/googleapis/cloud/clouddms/logging/v1/BUILD.bazel ---- a/googleapis/cloud/clouddms/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/clouddms/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/clouddms/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3483,7 +3485,7 @@ diff -urN a/googleapis/cloud/clouddms/logging/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/clouddms/v1/BUILD.bazel b/googleapis/cloud/clouddms/v1/BUILD.bazel ---- a/googleapis/cloud/clouddms/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/clouddms/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/clouddms/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3505,7 +3507,7 @@ diff -urN a/googleapis/cloud/clouddms/v1/BUILD.bazel b/googleapis/cloud/clouddms + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/cloudsetup/logging/v1/BUILD.bazel b/googleapis/cloud/cloudsetup/logging/v1/BUILD.bazel ---- a/googleapis/cloud/cloudsetup/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/cloudsetup/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/cloudsetup/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3529,7 +3531,7 @@ diff -urN a/googleapis/cloud/cloudsetup/logging/v1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/commerce/consumer/procurement/v1alpha1/BUILD.bazel b/googleapis/cloud/commerce/consumer/procurement/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/commerce/consumer/procurement/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/commerce/consumer/procurement/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/commerce/consumer/procurement/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3560,7 +3562,7 @@ diff -urN a/googleapis/cloud/commerce/consumer/procurement/v1alpha1/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/common/BUILD.bazel b/googleapis/cloud/common/BUILD.bazel ---- a/googleapis/cloud/common/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/common/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/common/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3584,7 +3586,7 @@ diff -urN a/googleapis/cloud/common/BUILD.bazel b/googleapis/cloud/common/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/compute/v1/BUILD.bazel b/googleapis/cloud/compute/v1/BUILD.bazel ---- a/googleapis/cloud/compute/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/compute/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/compute/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3606,7 +3608,7 @@ diff -urN a/googleapis/cloud/compute/v1/BUILD.bazel b/googleapis/cloud/compute/v + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/connectors/v1/BUILD.bazel b/googleapis/cloud/connectors/v1/BUILD.bazel ---- a/googleapis/cloud/connectors/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/connectors/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/connectors/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3646,7 +3648,7 @@ diff -urN a/googleapis/cloud/connectors/v1/BUILD.bazel b/googleapis/cloud/connec + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/contactcenterinsights/v1/BUILD.bazel b/googleapis/cloud/contactcenterinsights/v1/BUILD.bazel ---- a/googleapis/cloud/contactcenterinsights/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/contactcenterinsights/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/contactcenterinsights/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3668,7 +3670,7 @@ diff -urN a/googleapis/cloud/contactcenterinsights/v1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/containers/workflow/analysis/BUILD.bazel b/googleapis/cloud/containers/workflow/analysis/BUILD.bazel ---- a/googleapis/cloud/containers/workflow/analysis/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/containers/workflow/analysis/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/containers/workflow/analysis/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3690,7 +3692,7 @@ diff -urN a/googleapis/cloud/containers/workflow/analysis/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/contentwarehouse/v1/BUILD.bazel b/googleapis/cloud/contentwarehouse/v1/BUILD.bazel ---- a/googleapis/cloud/contentwarehouse/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/contentwarehouse/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/contentwarehouse/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,46 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3740,7 +3742,7 @@ diff -urN a/googleapis/cloud/contentwarehouse/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datacatalog/v1/BUILD.bazel b/googleapis/cloud/datacatalog/v1/BUILD.bazel ---- a/googleapis/cloud/datacatalog/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datacatalog/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datacatalog/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3762,7 +3764,7 @@ diff -urN a/googleapis/cloud/datacatalog/v1/BUILD.bazel b/googleapis/cloud/datac + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datacatalog/v1beta1/BUILD.bazel b/googleapis/cloud/datacatalog/v1beta1/BUILD.bazel ---- a/googleapis/cloud/datacatalog/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datacatalog/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datacatalog/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3784,7 +3786,7 @@ diff -urN a/googleapis/cloud/datacatalog/v1beta1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dataform/v1alpha2/BUILD.bazel b/googleapis/cloud/dataform/v1alpha2/BUILD.bazel ---- a/googleapis/cloud/dataform/v1alpha2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dataform/v1alpha2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dataform/v1alpha2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3806,7 +3808,7 @@ diff -urN a/googleapis/cloud/dataform/v1alpha2/BUILD.bazel b/googleapis/cloud/da + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dataform/v1beta1/BUILD.bazel b/googleapis/cloud/dataform/v1beta1/BUILD.bazel ---- a/googleapis/cloud/dataform/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dataform/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dataform/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3828,7 +3830,7 @@ diff -urN a/googleapis/cloud/dataform/v1beta1/BUILD.bazel b/googleapis/cloud/dat + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datafusion/v1/BUILD.bazel b/googleapis/cloud/datafusion/v1/BUILD.bazel ---- a/googleapis/cloud/datafusion/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datafusion/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datafusion/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3850,7 +3852,7 @@ diff -urN a/googleapis/cloud/datafusion/v1/BUILD.bazel b/googleapis/cloud/datafu + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datafusion/v1beta1/BUILD.bazel b/googleapis/cloud/datafusion/v1beta1/BUILD.bazel ---- a/googleapis/cloud/datafusion/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datafusion/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datafusion/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3881,7 +3883,7 @@ diff -urN a/googleapis/cloud/datafusion/v1beta1/BUILD.bazel b/googleapis/cloud/d + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datalabeling/v1beta1/BUILD.bazel b/googleapis/cloud/datalabeling/v1beta1/BUILD.bazel ---- a/googleapis/cloud/datalabeling/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datalabeling/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datalabeling/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3903,7 +3905,7 @@ diff -urN a/googleapis/cloud/datalabeling/v1beta1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datapipelines/logging/v1/BUILD.bazel b/googleapis/cloud/datapipelines/logging/v1/BUILD.bazel ---- a/googleapis/cloud/datapipelines/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datapipelines/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datapipelines/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3926,7 +3928,7 @@ diff -urN a/googleapis/cloud/datapipelines/logging/v1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dataplex/v1/BUILD.bazel b/googleapis/cloud/dataplex/v1/BUILD.bazel ---- a/googleapis/cloud/dataplex/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dataplex/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dataplex/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3948,7 +3950,7 @@ diff -urN a/googleapis/cloud/dataplex/v1/BUILD.bazel b/googleapis/cloud/dataplex + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dataproc/logging/BUILD.bazel b/googleapis/cloud/dataproc/logging/BUILD.bazel ---- a/googleapis/cloud/dataproc/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dataproc/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dataproc/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3971,7 +3973,7 @@ diff -urN a/googleapis/cloud/dataproc/logging/BUILD.bazel b/googleapis/cloud/dat + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dataproc/v1/BUILD.bazel b/googleapis/cloud/dataproc/v1/BUILD.bazel ---- a/googleapis/cloud/dataproc/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dataproc/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dataproc/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3982,7 +3984,7 @@ diff -urN a/googleapis/cloud/dataproc/v1/BUILD.bazel b/googleapis/cloud/dataproc + importpath = "google.golang.org/genproto/googleapis/cloud/dataproc/v1", + visibility = ["//visibility:public"], + deps = [ -+ "@com_google_cloud_go_dataproc//apiv1/dataprocpb:go_default_library", ++ "@com_google_cloud_go_dataproc_v2//apiv1/dataprocpb:go_default_library", + "@org_golang_google_grpc//:go_default_library", + ], +) @@ -3993,7 +3995,7 @@ diff -urN a/googleapis/cloud/dataproc/v1/BUILD.bazel b/googleapis/cloud/dataproc + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dataproc/v1beta2/BUILD.bazel b/googleapis/cloud/dataproc/v1beta2/BUILD.bazel ---- a/googleapis/cloud/dataproc/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dataproc/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dataproc/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4031,7 +4033,7 @@ diff -urN a/googleapis/cloud/dataproc/v1beta2/BUILD.bazel b/googleapis/cloud/dat + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dataqna/v1alpha/BUILD.bazel b/googleapis/cloud/dataqna/v1alpha/BUILD.bazel ---- a/googleapis/cloud/dataqna/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dataqna/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dataqna/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4053,7 +4055,7 @@ diff -urN a/googleapis/cloud/dataqna/v1alpha/BUILD.bazel b/googleapis/cloud/data + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datastream/logging/v1/BUILD.bazel b/googleapis/cloud/datastream/logging/v1/BUILD.bazel ---- a/googleapis/cloud/datastream/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datastream/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datastream/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4075,7 +4077,7 @@ diff -urN a/googleapis/cloud/datastream/logging/v1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datastream/v1/BUILD.bazel b/googleapis/cloud/datastream/v1/BUILD.bazel ---- a/googleapis/cloud/datastream/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datastream/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datastream/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4097,7 +4099,7 @@ diff -urN a/googleapis/cloud/datastream/v1/BUILD.bazel b/googleapis/cloud/datast + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/datastream/v1alpha1/BUILD.bazel b/googleapis/cloud/datastream/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/datastream/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/datastream/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/datastream/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4119,7 +4121,7 @@ diff -urN a/googleapis/cloud/datastream/v1alpha1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/deploy/v1/BUILD.bazel b/googleapis/cloud/deploy/v1/BUILD.bazel ---- a/googleapis/cloud/deploy/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/deploy/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/deploy/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4141,7 +4143,7 @@ diff -urN a/googleapis/cloud/deploy/v1/BUILD.bazel b/googleapis/cloud/deploy/v1/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dialogflow/cx/v3/BUILD.bazel b/googleapis/cloud/dialogflow/cx/v3/BUILD.bazel ---- a/googleapis/cloud/dialogflow/cx/v3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dialogflow/cx/v3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dialogflow/cx/v3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4163,7 +4165,7 @@ diff -urN a/googleapis/cloud/dialogflow/cx/v3/BUILD.bazel b/googleapis/cloud/dia + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dialogflow/cx/v3beta1/BUILD.bazel b/googleapis/cloud/dialogflow/cx/v3beta1/BUILD.bazel ---- a/googleapis/cloud/dialogflow/cx/v3beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dialogflow/cx/v3beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dialogflow/cx/v3beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4185,7 +4187,7 @@ diff -urN a/googleapis/cloud/dialogflow/cx/v3beta1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dialogflow/v2/BUILD.bazel b/googleapis/cloud/dialogflow/v2/BUILD.bazel ---- a/googleapis/cloud/dialogflow/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dialogflow/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dialogflow/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4207,7 +4209,7 @@ diff -urN a/googleapis/cloud/dialogflow/v2/BUILD.bazel b/googleapis/cloud/dialog + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/dialogflow/v2beta1/BUILD.bazel b/googleapis/cloud/dialogflow/v2beta1/BUILD.bazel ---- a/googleapis/cloud/dialogflow/v2beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/dialogflow/v2beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/dialogflow/v2beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4229,7 +4231,7 @@ diff -urN a/googleapis/cloud/dialogflow/v2beta1/BUILD.bazel b/googleapis/cloud/d + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/documentai/v1/BUILD.bazel b/googleapis/cloud/documentai/v1/BUILD.bazel ---- a/googleapis/cloud/documentai/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/documentai/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/documentai/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4251,7 +4253,7 @@ diff -urN a/googleapis/cloud/documentai/v1/BUILD.bazel b/googleapis/cloud/docume + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/documentai/v1beta1/BUILD.bazel b/googleapis/cloud/documentai/v1beta1/BUILD.bazel ---- a/googleapis/cloud/documentai/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/documentai/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/documentai/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4285,7 +4287,7 @@ diff -urN a/googleapis/cloud/documentai/v1beta1/BUILD.bazel b/googleapis/cloud/d + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/documentai/v1beta2/BUILD.bazel b/googleapis/cloud/documentai/v1beta2/BUILD.bazel ---- a/googleapis/cloud/documentai/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/documentai/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/documentai/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4319,7 +4321,7 @@ diff -urN a/googleapis/cloud/documentai/v1beta2/BUILD.bazel b/googleapis/cloud/d + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/documentai/v1beta3/BUILD.bazel b/googleapis/cloud/documentai/v1beta3/BUILD.bazel ---- a/googleapis/cloud/documentai/v1beta3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/documentai/v1beta3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/documentai/v1beta3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4341,7 +4343,7 @@ diff -urN a/googleapis/cloud/documentai/v1beta3/BUILD.bazel b/googleapis/cloud/d + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/domains/v1/BUILD.bazel b/googleapis/cloud/domains/v1/BUILD.bazel ---- a/googleapis/cloud/domains/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/domains/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/domains/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4372,7 +4374,7 @@ diff -urN a/googleapis/cloud/domains/v1/BUILD.bazel b/googleapis/cloud/domains/v + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/domains/v1alpha2/BUILD.bazel b/googleapis/cloud/domains/v1alpha2/BUILD.bazel ---- a/googleapis/cloud/domains/v1alpha2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/domains/v1alpha2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/domains/v1alpha2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4403,7 +4405,7 @@ diff -urN a/googleapis/cloud/domains/v1alpha2/BUILD.bazel b/googleapis/cloud/dom + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/domains/v1beta1/BUILD.bazel b/googleapis/cloud/domains/v1beta1/BUILD.bazel ---- a/googleapis/cloud/domains/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/domains/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/domains/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4425,7 +4427,7 @@ diff -urN a/googleapis/cloud/domains/v1beta1/BUILD.bazel b/googleapis/cloud/doma + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/edgecontainer/v1/BUILD.bazel b/googleapis/cloud/edgecontainer/v1/BUILD.bazel ---- a/googleapis/cloud/edgecontainer/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/edgecontainer/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/edgecontainer/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4447,7 +4449,7 @@ diff -urN a/googleapis/cloud/edgecontainer/v1/BUILD.bazel b/googleapis/cloud/edg + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/enterpriseknowledgegraph/v1/BUILD.bazel b/googleapis/cloud/enterpriseknowledgegraph/v1/BUILD.bazel ---- a/googleapis/cloud/enterpriseknowledgegraph/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/enterpriseknowledgegraph/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/enterpriseknowledgegraph/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4482,7 +4484,7 @@ diff -urN a/googleapis/cloud/enterpriseknowledgegraph/v1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/essentialcontacts/v1/BUILD.bazel b/googleapis/cloud/essentialcontacts/v1/BUILD.bazel ---- a/googleapis/cloud/essentialcontacts/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/essentialcontacts/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/essentialcontacts/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4504,7 +4506,7 @@ diff -urN a/googleapis/cloud/essentialcontacts/v1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/eventarc/publishing/v1/BUILD.bazel b/googleapis/cloud/eventarc/publishing/v1/BUILD.bazel ---- a/googleapis/cloud/eventarc/publishing/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/eventarc/publishing/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/eventarc/publishing/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4526,7 +4528,7 @@ diff -urN a/googleapis/cloud/eventarc/publishing/v1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/eventarc/v1/BUILD.bazel b/googleapis/cloud/eventarc/v1/BUILD.bazel ---- a/googleapis/cloud/eventarc/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/eventarc/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/eventarc/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4548,7 +4550,7 @@ diff -urN a/googleapis/cloud/eventarc/v1/BUILD.bazel b/googleapis/cloud/eventarc + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/extendedops/BUILD.bazel b/googleapis/cloud/extendedops/BUILD.bazel ---- a/googleapis/cloud/extendedops/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/extendedops/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/extendedops/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4571,7 +4573,7 @@ diff -urN a/googleapis/cloud/extendedops/BUILD.bazel b/googleapis/cloud/extended + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/filestore/v1/BUILD.bazel b/googleapis/cloud/filestore/v1/BUILD.bazel ---- a/googleapis/cloud/filestore/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/filestore/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/filestore/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4593,7 +4595,7 @@ diff -urN a/googleapis/cloud/filestore/v1/BUILD.bazel b/googleapis/cloud/filesto + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/filestore/v1beta1/BUILD.bazel b/googleapis/cloud/filestore/v1beta1/BUILD.bazel ---- a/googleapis/cloud/filestore/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/filestore/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/filestore/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4624,7 +4626,7 @@ diff -urN a/googleapis/cloud/filestore/v1beta1/BUILD.bazel b/googleapis/cloud/fi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/functions/v1/BUILD.bazel b/googleapis/cloud/functions/v1/BUILD.bazel ---- a/googleapis/cloud/functions/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/functions/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/functions/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4646,7 +4648,7 @@ diff -urN a/googleapis/cloud/functions/v1/BUILD.bazel b/googleapis/cloud/functio + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/functions/v1beta2/BUILD.bazel b/googleapis/cloud/functions/v1beta2/BUILD.bazel ---- a/googleapis/cloud/functions/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/functions/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/functions/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4680,7 +4682,7 @@ diff -urN a/googleapis/cloud/functions/v1beta2/BUILD.bazel b/googleapis/cloud/fu + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/functions/v2/BUILD.bazel b/googleapis/cloud/functions/v2/BUILD.bazel ---- a/googleapis/cloud/functions/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/functions/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/functions/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4702,7 +4704,7 @@ diff -urN a/googleapis/cloud/functions/v2/BUILD.bazel b/googleapis/cloud/functio + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/functions/v2alpha/BUILD.bazel b/googleapis/cloud/functions/v2alpha/BUILD.bazel ---- a/googleapis/cloud/functions/v2alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/functions/v2alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/functions/v2alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4732,7 +4734,7 @@ diff -urN a/googleapis/cloud/functions/v2alpha/BUILD.bazel b/googleapis/cloud/fu + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/functions/v2beta/BUILD.bazel b/googleapis/cloud/functions/v2beta/BUILD.bazel ---- a/googleapis/cloud/functions/v2beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/functions/v2beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/functions/v2beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4753,78 +4755,8 @@ diff -urN a/googleapis/cloud/functions/v2beta/BUILD.bazel b/googleapis/cloud/fun + actual = ":v2beta", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/cloud/gaming/allocationendpoint/v1alpha/BUILD.bazel b/googleapis/cloud/gaming/allocationendpoint/v1alpha/BUILD.bazel ---- a/googleapis/cloud/gaming/allocationendpoint/v1alpha/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/cloud/gaming/allocationendpoint/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,22 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "v1alpha", -+ srcs = ["allocation_endpoint.pb.go"], -+ importpath = "google.golang.org/genproto/googleapis/cloud/gaming/allocationendpoint/v1alpha", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "//googleapis/api/annotations", -+ "@org_golang_google_grpc//:go_default_library", -+ "@org_golang_google_grpc//codes:go_default_library", -+ "@org_golang_google_grpc//status:go_default_library", -+ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", -+ "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":v1alpha", -+ visibility = ["//visibility:public"], -+) -diff -urN a/googleapis/cloud/gaming/v1/BUILD.bazel b/googleapis/cloud/gaming/v1/BUILD.bazel ---- a/googleapis/cloud/gaming/v1/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/cloud/gaming/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "gaming", -+ srcs = ["alias.go"], -+ importpath = "google.golang.org/genproto/googleapis/cloud/gaming/v1", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "@com_google_cloud_go_gaming//apiv1/gamingpb:go_default_library", -+ "@org_golang_google_grpc//:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":gaming", -+ visibility = ["//visibility:public"], -+) -diff -urN a/googleapis/cloud/gaming/v1beta/BUILD.bazel b/googleapis/cloud/gaming/v1beta/BUILD.bazel ---- a/googleapis/cloud/gaming/v1beta/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/cloud/gaming/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "v1beta", -+ srcs = ["alias.go"], -+ importpath = "google.golang.org/genproto/googleapis/cloud/gaming/v1beta", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "@com_google_cloud_go_gaming//apiv1beta/gamingpb:go_default_library", -+ "@org_golang_google_grpc//:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":v1beta", -+ visibility = ["//visibility:public"], -+) diff -urN a/googleapis/cloud/gkebackup/logging/v1/BUILD.bazel b/googleapis/cloud/gkebackup/logging/v1/BUILD.bazel ---- a/googleapis/cloud/gkebackup/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkebackup/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkebackup/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4855,7 +4787,7 @@ diff -urN a/googleapis/cloud/gkebackup/logging/v1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkebackup/v1/BUILD.bazel b/googleapis/cloud/gkebackup/v1/BUILD.bazel ---- a/googleapis/cloud/gkebackup/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkebackup/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkebackup/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4877,7 +4809,7 @@ diff -urN a/googleapis/cloud/gkebackup/v1/BUILD.bazel b/googleapis/cloud/gkeback + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkeconnect/gateway/v1/BUILD.bazel b/googleapis/cloud/gkeconnect/gateway/v1/BUILD.bazel ---- a/googleapis/cloud/gkeconnect/gateway/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkeconnect/gateway/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkeconnect/gateway/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4901,7 +4833,7 @@ diff -urN a/googleapis/cloud/gkeconnect/gateway/v1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkeconnect/gateway/v1alpha1/BUILD.bazel b/googleapis/cloud/gkeconnect/gateway/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/gkeconnect/gateway/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkeconnect/gateway/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkeconnect/gateway/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4925,7 +4857,7 @@ diff -urN a/googleapis/cloud/gkeconnect/gateway/v1alpha1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkeconnect/gateway/v1beta1/BUILD.bazel b/googleapis/cloud/gkeconnect/gateway/v1beta1/BUILD.bazel ---- a/googleapis/cloud/gkeconnect/gateway/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkeconnect/gateway/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkeconnect/gateway/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4947,7 +4879,7 @@ diff -urN a/googleapis/cloud/gkeconnect/gateway/v1beta1/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/cloudauditlogging/v1alpha/BUILD.bazel b/googleapis/cloud/gkehub/cloudauditlogging/v1alpha/BUILD.bazel ---- a/googleapis/cloud/gkehub/cloudauditlogging/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/cloudauditlogging/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/cloudauditlogging/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4969,7 +4901,7 @@ diff -urN a/googleapis/cloud/gkehub/cloudauditlogging/v1alpha/BUILD.bazel b/goog + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/configmanagement/v1/BUILD.bazel b/googleapis/cloud/gkehub/configmanagement/v1/BUILD.bazel ---- a/googleapis/cloud/gkehub/configmanagement/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/configmanagement/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/configmanagement/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -4992,7 +4924,7 @@ diff -urN a/googleapis/cloud/gkehub/configmanagement/v1/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/configmanagement/v1alpha/BUILD.bazel b/googleapis/cloud/gkehub/configmanagement/v1alpha/BUILD.bazel ---- a/googleapis/cloud/gkehub/configmanagement/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/configmanagement/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/configmanagement/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5015,7 +4947,7 @@ diff -urN a/googleapis/cloud/gkehub/configmanagement/v1alpha/BUILD.bazel b/googl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/configmanagement/v1beta/BUILD.bazel b/googleapis/cloud/gkehub/configmanagement/v1beta/BUILD.bazel ---- a/googleapis/cloud/gkehub/configmanagement/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/configmanagement/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/configmanagement/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5038,7 +4970,7 @@ diff -urN a/googleapis/cloud/gkehub/configmanagement/v1beta/BUILD.bazel b/google + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/metering/v1alpha/BUILD.bazel b/googleapis/cloud/gkehub/metering/v1alpha/BUILD.bazel ---- a/googleapis/cloud/gkehub/metering/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/metering/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/metering/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5061,7 +4993,7 @@ diff -urN a/googleapis/cloud/gkehub/metering/v1alpha/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/metering/v1beta/BUILD.bazel b/googleapis/cloud/gkehub/metering/v1beta/BUILD.bazel ---- a/googleapis/cloud/gkehub/metering/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/metering/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/metering/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5084,7 +5016,7 @@ diff -urN a/googleapis/cloud/gkehub/metering/v1beta/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/multiclusteringress/v1/BUILD.bazel b/googleapis/cloud/gkehub/multiclusteringress/v1/BUILD.bazel ---- a/googleapis/cloud/gkehub/multiclusteringress/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/multiclusteringress/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/multiclusteringress/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5106,7 +5038,7 @@ diff -urN a/googleapis/cloud/gkehub/multiclusteringress/v1/BUILD.bazel b/googlea + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/multiclusteringress/v1alpha/BUILD.bazel b/googleapis/cloud/gkehub/multiclusteringress/v1alpha/BUILD.bazel ---- a/googleapis/cloud/gkehub/multiclusteringress/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/multiclusteringress/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/multiclusteringress/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5128,7 +5060,7 @@ diff -urN a/googleapis/cloud/gkehub/multiclusteringress/v1alpha/BUILD.bazel b/go + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/multiclusteringress/v1beta/BUILD.bazel b/googleapis/cloud/gkehub/multiclusteringress/v1beta/BUILD.bazel ---- a/googleapis/cloud/gkehub/multiclusteringress/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/multiclusteringress/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/multiclusteringress/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5150,7 +5082,7 @@ diff -urN a/googleapis/cloud/gkehub/multiclusteringress/v1beta/BUILD.bazel b/goo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/servicemesh/v1alpha/BUILD.bazel b/googleapis/cloud/gkehub/servicemesh/v1alpha/BUILD.bazel ---- a/googleapis/cloud/gkehub/servicemesh/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/servicemesh/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/servicemesh/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5174,7 +5106,7 @@ diff -urN a/googleapis/cloud/gkehub/servicemesh/v1alpha/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/v1/BUILD.bazel b/googleapis/cloud/gkehub/v1/BUILD.bazel ---- a/googleapis/cloud/gkehub/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5209,7 +5141,7 @@ diff -urN a/googleapis/cloud/gkehub/v1/BUILD.bazel b/googleapis/cloud/gkehub/v1/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/v1alpha/BUILD.bazel b/googleapis/cloud/gkehub/v1alpha/BUILD.bazel ---- a/googleapis/cloud/gkehub/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5246,7 +5178,7 @@ diff -urN a/googleapis/cloud/gkehub/v1alpha/BUILD.bazel b/googleapis/cloud/gkehu + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/v1alpha2/BUILD.bazel b/googleapis/cloud/gkehub/v1alpha2/BUILD.bazel ---- a/googleapis/cloud/gkehub/v1alpha2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/v1alpha2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/v1alpha2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5275,7 +5207,7 @@ diff -urN a/googleapis/cloud/gkehub/v1alpha2/BUILD.bazel b/googleapis/cloud/gkeh + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/v1beta/BUILD.bazel b/googleapis/cloud/gkehub/v1beta/BUILD.bazel ---- a/googleapis/cloud/gkehub/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5310,7 +5242,7 @@ diff -urN a/googleapis/cloud/gkehub/v1beta/BUILD.bazel b/googleapis/cloud/gkehub + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkehub/v1beta1/BUILD.bazel b/googleapis/cloud/gkehub/v1beta1/BUILD.bazel ---- a/googleapis/cloud/gkehub/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkehub/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkehub/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5332,7 +5264,7 @@ diff -urN a/googleapis/cloud/gkehub/v1beta1/BUILD.bazel b/googleapis/cloud/gkehu + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gkemulticloud/v1/BUILD.bazel b/googleapis/cloud/gkemulticloud/v1/BUILD.bazel ---- a/googleapis/cloud/gkemulticloud/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gkemulticloud/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gkemulticloud/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5354,7 +5286,7 @@ diff -urN a/googleapis/cloud/gkemulticloud/v1/BUILD.bazel b/googleapis/cloud/gke + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gsuiteaddons/logging/v1/BUILD.bazel b/googleapis/cloud/gsuiteaddons/logging/v1/BUILD.bazel ---- a/googleapis/cloud/gsuiteaddons/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gsuiteaddons/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gsuiteaddons/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5377,7 +5309,7 @@ diff -urN a/googleapis/cloud/gsuiteaddons/logging/v1/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/gsuiteaddons/v1/BUILD.bazel b/googleapis/cloud/gsuiteaddons/v1/BUILD.bazel ---- a/googleapis/cloud/gsuiteaddons/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/gsuiteaddons/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/gsuiteaddons/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5399,7 +5331,7 @@ diff -urN a/googleapis/cloud/gsuiteaddons/v1/BUILD.bazel b/googleapis/cloud/gsui + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/healthcare/logging/BUILD.bazel b/googleapis/cloud/healthcare/logging/BUILD.bazel ---- a/googleapis/cloud/healthcare/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/healthcare/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/healthcare/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5429,7 +5361,7 @@ diff -urN a/googleapis/cloud/healthcare/logging/BUILD.bazel b/googleapis/cloud/h + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/iap/v1/BUILD.bazel b/googleapis/cloud/iap/v1/BUILD.bazel ---- a/googleapis/cloud/iap/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/iap/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/iap/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5451,7 +5383,7 @@ diff -urN a/googleapis/cloud/iap/v1/BUILD.bazel b/googleapis/cloud/iap/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/iap/v1beta1/BUILD.bazel b/googleapis/cloud/iap/v1beta1/BUILD.bazel ---- a/googleapis/cloud/iap/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/iap/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/iap/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5478,7 +5410,7 @@ diff -urN a/googleapis/cloud/iap/v1beta1/BUILD.bazel b/googleapis/cloud/iap/v1be + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/identitytoolkit/logging/BUILD.bazel b/googleapis/cloud/identitytoolkit/logging/BUILD.bazel ---- a/googleapis/cloud/identitytoolkit/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/identitytoolkit/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/identitytoolkit/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5502,7 +5434,7 @@ diff -urN a/googleapis/cloud/identitytoolkit/logging/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/identitytoolkit/v2/BUILD.bazel b/googleapis/cloud/identitytoolkit/v2/BUILD.bazel ---- a/googleapis/cloud/identitytoolkit/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/identitytoolkit/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/identitytoolkit/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5533,7 +5465,7 @@ diff -urN a/googleapis/cloud/identitytoolkit/v2/BUILD.bazel b/googleapis/cloud/i + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/ids/logging/v1/BUILD.bazel b/googleapis/cloud/ids/logging/v1/BUILD.bazel ---- a/googleapis/cloud/ids/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/ids/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/ids/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5557,7 +5489,7 @@ diff -urN a/googleapis/cloud/ids/logging/v1/BUILD.bazel b/googleapis/cloud/ids/l + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/ids/v1/BUILD.bazel b/googleapis/cloud/ids/v1/BUILD.bazel ---- a/googleapis/cloud/ids/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/ids/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/ids/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5579,7 +5511,7 @@ diff -urN a/googleapis/cloud/ids/v1/BUILD.bazel b/googleapis/cloud/ids/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/integrations/v1alpha/BUILD.bazel b/googleapis/cloud/integrations/v1alpha/BUILD.bazel ---- a/googleapis/cloud/integrations/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/integrations/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/integrations/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5610,7 +5542,7 @@ diff -urN a/googleapis/cloud/integrations/v1alpha/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/iot/v1/BUILD.bazel b/googleapis/cloud/iot/v1/BUILD.bazel ---- a/googleapis/cloud/iot/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/iot/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/iot/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5631,41 +5563,8 @@ diff -urN a/googleapis/cloud/iot/v1/BUILD.bazel b/googleapis/cloud/iot/v1/BUILD. + actual = ":iot", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/cloud/irm/v1alpha2/BUILD.bazel b/googleapis/cloud/irm/v1alpha2/BUILD.bazel ---- a/googleapis/cloud/irm/v1alpha2/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/cloud/irm/v1alpha2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "v1alpha2", -+ srcs = [ -+ "incidents.pb.go", -+ "incidents_service.pb.go", -+ ], -+ importpath = "google.golang.org/genproto/googleapis/cloud/irm/v1alpha2", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "//googleapis/api/annotations", -+ "//protobuf/field_mask", -+ "@com_github_golang_protobuf//proto:go_default_library", -+ "@com_github_golang_protobuf//ptypes/empty:go_default_library", -+ "@com_github_golang_protobuf//ptypes/timestamp:go_default_library", -+ "@org_golang_google_grpc//:go_default_library", -+ "@org_golang_google_grpc//codes:go_default_library", -+ "@org_golang_google_grpc//status:go_default_library", -+ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", -+ "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":v1alpha2", -+ visibility = ["//visibility:public"], -+) diff -urN a/googleapis/cloud/kms/v1/BUILD.bazel b/googleapis/cloud/kms/v1/BUILD.bazel ---- a/googleapis/cloud/kms/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/kms/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/kms/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5687,7 +5586,7 @@ diff -urN a/googleapis/cloud/kms/v1/BUILD.bazel b/googleapis/cloud/kms/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/kubernetes/security/containersecurity_logging/BUILD.bazel b/googleapis/cloud/kubernetes/security/containersecurity_logging/BUILD.bazel ---- a/googleapis/cloud/kubernetes/security/containersecurity_logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/kubernetes/security/containersecurity_logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/kubernetes/security/containersecurity_logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5710,7 +5609,7 @@ diff -urN a/googleapis/cloud/kubernetes/security/containersecurity_logging/BUILD + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/language/v1/BUILD.bazel b/googleapis/cloud/language/v1/BUILD.bazel ---- a/googleapis/cloud/language/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/language/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/language/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5732,7 +5631,7 @@ diff -urN a/googleapis/cloud/language/v1/BUILD.bazel b/googleapis/cloud/language + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/language/v1beta1/BUILD.bazel b/googleapis/cloud/language/v1beta1/BUILD.bazel ---- a/googleapis/cloud/language/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/language/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/language/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5758,7 +5657,7 @@ diff -urN a/googleapis/cloud/language/v1beta1/BUILD.bazel b/googleapis/cloud/lan + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/language/v1beta2/BUILD.bazel b/googleapis/cloud/language/v1beta2/BUILD.bazel ---- a/googleapis/cloud/language/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/language/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/language/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5780,7 +5679,7 @@ diff -urN a/googleapis/cloud/language/v1beta2/BUILD.bazel b/googleapis/cloud/lan + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/lifesciences/v2beta/BUILD.bazel b/googleapis/cloud/lifesciences/v2beta/BUILD.bazel ---- a/googleapis/cloud/lifesciences/v2beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/lifesciences/v2beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/lifesciences/v2beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5802,7 +5701,7 @@ diff -urN a/googleapis/cloud/lifesciences/v2beta/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/location/BUILD.bazel b/googleapis/cloud/location/BUILD.bazel ---- a/googleapis/cloud/location/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/location/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/location/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5829,7 +5728,7 @@ diff -urN a/googleapis/cloud/location/BUILD.bazel b/googleapis/cloud/location/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/managedidentities/v1/BUILD.bazel b/googleapis/cloud/managedidentities/v1/BUILD.bazel ---- a/googleapis/cloud/managedidentities/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/managedidentities/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/managedidentities/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5851,7 +5750,7 @@ diff -urN a/googleapis/cloud/managedidentities/v1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/managedidentities/v1beta1/BUILD.bazel b/googleapis/cloud/managedidentities/v1beta1/BUILD.bazel ---- a/googleapis/cloud/managedidentities/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/managedidentities/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/managedidentities/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5883,7 +5782,7 @@ diff -urN a/googleapis/cloud/managedidentities/v1beta1/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/mediatranslation/v1alpha1/BUILD.bazel b/googleapis/cloud/mediatranslation/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/mediatranslation/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/mediatranslation/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/mediatranslation/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5910,7 +5809,7 @@ diff -urN a/googleapis/cloud/mediatranslation/v1alpha1/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/mediatranslation/v1beta1/BUILD.bazel b/googleapis/cloud/mediatranslation/v1beta1/BUILD.bazel ---- a/googleapis/cloud/mediatranslation/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/mediatranslation/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/mediatranslation/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5932,7 +5831,7 @@ diff -urN a/googleapis/cloud/mediatranslation/v1beta1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/memcache/v1/BUILD.bazel b/googleapis/cloud/memcache/v1/BUILD.bazel ---- a/googleapis/cloud/memcache/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/memcache/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/memcache/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5954,7 +5853,7 @@ diff -urN a/googleapis/cloud/memcache/v1/BUILD.bazel b/googleapis/cloud/memcache + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/memcache/v1beta2/BUILD.bazel b/googleapis/cloud/memcache/v1beta2/BUILD.bazel ---- a/googleapis/cloud/memcache/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/memcache/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/memcache/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5976,7 +5875,7 @@ diff -urN a/googleapis/cloud/memcache/v1beta2/BUILD.bazel b/googleapis/cloud/mem + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/metastore/logging/v1/BUILD.bazel b/googleapis/cloud/metastore/logging/v1/BUILD.bazel ---- a/googleapis/cloud/metastore/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/metastore/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/metastore/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -5998,7 +5897,7 @@ diff -urN a/googleapis/cloud/metastore/logging/v1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/metastore/v1/BUILD.bazel b/googleapis/cloud/metastore/v1/BUILD.bazel ---- a/googleapis/cloud/metastore/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/metastore/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/metastore/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6020,7 +5919,7 @@ diff -urN a/googleapis/cloud/metastore/v1/BUILD.bazel b/googleapis/cloud/metasto + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/metastore/v1alpha/BUILD.bazel b/googleapis/cloud/metastore/v1alpha/BUILD.bazel ---- a/googleapis/cloud/metastore/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/metastore/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/metastore/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6042,7 +5941,7 @@ diff -urN a/googleapis/cloud/metastore/v1alpha/BUILD.bazel b/googleapis/cloud/me + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/metastore/v1beta/BUILD.bazel b/googleapis/cloud/metastore/v1beta/BUILD.bazel ---- a/googleapis/cloud/metastore/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/metastore/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/metastore/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6064,7 +5963,7 @@ diff -urN a/googleapis/cloud/metastore/v1beta/BUILD.bazel b/googleapis/cloud/met + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/ml/v1/BUILD.bazel b/googleapis/cloud/ml/v1/BUILD.bazel ---- a/googleapis/cloud/ml/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/ml/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/ml/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6101,7 +6000,7 @@ diff -urN a/googleapis/cloud/ml/v1/BUILD.bazel b/googleapis/cloud/ml/v1/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networkanalyzer/logging/v1/BUILD.bazel b/googleapis/cloud/networkanalyzer/logging/v1/BUILD.bazel ---- a/googleapis/cloud/networkanalyzer/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networkanalyzer/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networkanalyzer/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6124,7 +6023,7 @@ diff -urN a/googleapis/cloud/networkanalyzer/logging/v1/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networkconnectivity/v1/BUILD.bazel b/googleapis/cloud/networkconnectivity/v1/BUILD.bazel ---- a/googleapis/cloud/networkconnectivity/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networkconnectivity/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networkconnectivity/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6146,7 +6045,7 @@ diff -urN a/googleapis/cloud/networkconnectivity/v1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networkconnectivity/v1alpha1/BUILD.bazel b/googleapis/cloud/networkconnectivity/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/networkconnectivity/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networkconnectivity/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networkconnectivity/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6168,7 +6067,7 @@ diff -urN a/googleapis/cloud/networkconnectivity/v1alpha1/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networkmanagement/v1/BUILD.bazel b/googleapis/cloud/networkmanagement/v1/BUILD.bazel ---- a/googleapis/cloud/networkmanagement/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networkmanagement/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networkmanagement/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6190,7 +6089,7 @@ diff -urN a/googleapis/cloud/networkmanagement/v1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networkmanagement/v1beta1/BUILD.bazel b/googleapis/cloud/networkmanagement/v1beta1/BUILD.bazel ---- a/googleapis/cloud/networkmanagement/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networkmanagement/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networkmanagement/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6224,7 +6123,7 @@ diff -urN a/googleapis/cloud/networkmanagement/v1beta1/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networksecurity/v1/BUILD.bazel b/googleapis/cloud/networksecurity/v1/BUILD.bazel ---- a/googleapis/cloud/networksecurity/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networksecurity/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networksecurity/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6260,7 +6159,7 @@ diff -urN a/googleapis/cloud/networksecurity/v1/BUILD.bazel b/googleapis/cloud/n + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networksecurity/v1beta1/BUILD.bazel b/googleapis/cloud/networksecurity/v1beta1/BUILD.bazel ---- a/googleapis/cloud/networksecurity/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networksecurity/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networksecurity/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6282,7 +6181,7 @@ diff -urN a/googleapis/cloud/networksecurity/v1beta1/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networkservices/v1/BUILD.bazel b/googleapis/cloud/networkservices/v1/BUILD.bazel ---- a/googleapis/cloud/networkservices/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networkservices/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networkservices/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6323,7 +6222,7 @@ diff -urN a/googleapis/cloud/networkservices/v1/BUILD.bazel b/googleapis/cloud/n + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/networkservices/v1beta1/BUILD.bazel b/googleapis/cloud/networkservices/v1beta1/BUILD.bazel ---- a/googleapis/cloud/networkservices/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/networkservices/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/networkservices/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6356,7 +6255,7 @@ diff -urN a/googleapis/cloud/networkservices/v1beta1/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/notebooks/logging/v1/BUILD.bazel b/googleapis/cloud/notebooks/logging/v1/BUILD.bazel ---- a/googleapis/cloud/notebooks/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/notebooks/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/notebooks/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6379,7 +6278,7 @@ diff -urN a/googleapis/cloud/notebooks/logging/v1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/notebooks/v1/BUILD.bazel b/googleapis/cloud/notebooks/v1/BUILD.bazel ---- a/googleapis/cloud/notebooks/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/notebooks/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/notebooks/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6401,7 +6300,7 @@ diff -urN a/googleapis/cloud/notebooks/v1/BUILD.bazel b/googleapis/cloud/noteboo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/notebooks/v1beta1/BUILD.bazel b/googleapis/cloud/notebooks/v1beta1/BUILD.bazel ---- a/googleapis/cloud/notebooks/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/notebooks/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/notebooks/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6423,7 +6322,7 @@ diff -urN a/googleapis/cloud/notebooks/v1beta1/BUILD.bazel b/googleapis/cloud/no + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/optimization/v1/BUILD.bazel b/googleapis/cloud/optimization/v1/BUILD.bazel ---- a/googleapis/cloud/optimization/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/optimization/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/optimization/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6445,7 +6344,7 @@ diff -urN a/googleapis/cloud/optimization/v1/BUILD.bazel b/googleapis/cloud/opti + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/orchestration/airflow/service/v1/BUILD.bazel b/googleapis/cloud/orchestration/airflow/service/v1/BUILD.bazel ---- a/googleapis/cloud/orchestration/airflow/service/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/orchestration/airflow/service/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/orchestration/airflow/service/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6467,7 +6366,7 @@ diff -urN a/googleapis/cloud/orchestration/airflow/service/v1/BUILD.bazel b/goog + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/orchestration/airflow/service/v1beta1/BUILD.bazel b/googleapis/cloud/orchestration/airflow/service/v1beta1/BUILD.bazel ---- a/googleapis/cloud/orchestration/airflow/service/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/orchestration/airflow/service/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/orchestration/airflow/service/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6501,7 +6400,7 @@ diff -urN a/googleapis/cloud/orchestration/airflow/service/v1beta1/BUILD.bazel b + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/orgpolicy/v1/BUILD.bazel b/googleapis/cloud/orgpolicy/v1/BUILD.bazel ---- a/googleapis/cloud/orgpolicy/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/orgpolicy/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/orgpolicy/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6524,7 +6423,7 @@ diff -urN a/googleapis/cloud/orgpolicy/v1/BUILD.bazel b/googleapis/cloud/orgpoli + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/orgpolicy/v2/BUILD.bazel b/googleapis/cloud/orgpolicy/v2/BUILD.bazel ---- a/googleapis/cloud/orgpolicy/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/orgpolicy/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/orgpolicy/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6546,7 +6445,7 @@ diff -urN a/googleapis/cloud/orgpolicy/v2/BUILD.bazel b/googleapis/cloud/orgpoli + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/osconfig/agentendpoint/v1/BUILD.bazel b/googleapis/cloud/osconfig/agentendpoint/v1/BUILD.bazel ---- a/googleapis/cloud/osconfig/agentendpoint/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/osconfig/agentendpoint/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/osconfig/agentendpoint/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6568,7 +6467,7 @@ diff -urN a/googleapis/cloud/osconfig/agentendpoint/v1/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/osconfig/agentendpoint/v1beta/BUILD.bazel b/googleapis/cloud/osconfig/agentendpoint/v1beta/BUILD.bazel ---- a/googleapis/cloud/osconfig/agentendpoint/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/osconfig/agentendpoint/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/osconfig/agentendpoint/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6590,7 +6489,7 @@ diff -urN a/googleapis/cloud/osconfig/agentendpoint/v1beta/BUILD.bazel b/googlea + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/osconfig/logging/BUILD.bazel b/googleapis/cloud/osconfig/logging/BUILD.bazel ---- a/googleapis/cloud/osconfig/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/osconfig/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/osconfig/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6613,7 +6512,7 @@ diff -urN a/googleapis/cloud/osconfig/logging/BUILD.bazel b/googleapis/cloud/osc + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/osconfig/v1/BUILD.bazel b/googleapis/cloud/osconfig/v1/BUILD.bazel ---- a/googleapis/cloud/osconfig/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/osconfig/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/osconfig/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6635,7 +6534,7 @@ diff -urN a/googleapis/cloud/osconfig/v1/BUILD.bazel b/googleapis/cloud/osconfig + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/osconfig/v1alpha/BUILD.bazel b/googleapis/cloud/osconfig/v1alpha/BUILD.bazel ---- a/googleapis/cloud/osconfig/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/osconfig/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/osconfig/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6657,7 +6556,7 @@ diff -urN a/googleapis/cloud/osconfig/v1alpha/BUILD.bazel b/googleapis/cloud/osc + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/osconfig/v1beta/BUILD.bazel b/googleapis/cloud/osconfig/v1beta/BUILD.bazel ---- a/googleapis/cloud/osconfig/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/osconfig/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/osconfig/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6679,7 +6578,7 @@ diff -urN a/googleapis/cloud/osconfig/v1beta/BUILD.bazel b/googleapis/cloud/osco + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/oslogin/common/BUILD.bazel b/googleapis/cloud/oslogin/common/BUILD.bazel ---- a/googleapis/cloud/oslogin/common/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/oslogin/common/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/oslogin/common/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6702,7 +6601,7 @@ diff -urN a/googleapis/cloud/oslogin/common/BUILD.bazel b/googleapis/cloud/oslog + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/oslogin/v1/BUILD.bazel b/googleapis/cloud/oslogin/v1/BUILD.bazel ---- a/googleapis/cloud/oslogin/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/oslogin/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/oslogin/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6724,7 +6623,7 @@ diff -urN a/googleapis/cloud/oslogin/v1/BUILD.bazel b/googleapis/cloud/oslogin/v + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/oslogin/v1alpha/BUILD.bazel b/googleapis/cloud/oslogin/v1alpha/BUILD.bazel ---- a/googleapis/cloud/oslogin/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/oslogin/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/oslogin/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6753,7 +6652,7 @@ diff -urN a/googleapis/cloud/oslogin/v1alpha/BUILD.bazel b/googleapis/cloud/oslo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/oslogin/v1beta/BUILD.bazel b/googleapis/cloud/oslogin/v1beta/BUILD.bazel ---- a/googleapis/cloud/oslogin/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/oslogin/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/oslogin/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6775,7 +6674,7 @@ diff -urN a/googleapis/cloud/oslogin/v1beta/BUILD.bazel b/googleapis/cloud/oslog + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/paymentgateway/issuerswitch/v1/BUILD.bazel b/googleapis/cloud/paymentgateway/issuerswitch/v1/BUILD.bazel ---- a/googleapis/cloud/paymentgateway/issuerswitch/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/paymentgateway/issuerswitch/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/paymentgateway/issuerswitch/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6814,7 +6713,7 @@ diff -urN a/googleapis/cloud/paymentgateway/issuerswitch/v1/BUILD.bazel b/google + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/phishingprotection/v1beta1/BUILD.bazel b/googleapis/cloud/phishingprotection/v1beta1/BUILD.bazel ---- a/googleapis/cloud/phishingprotection/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/phishingprotection/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/phishingprotection/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6836,7 +6735,7 @@ diff -urN a/googleapis/cloud/phishingprotection/v1beta1/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/policytroubleshooter/v1/BUILD.bazel b/googleapis/cloud/policytroubleshooter/v1/BUILD.bazel ---- a/googleapis/cloud/policytroubleshooter/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/policytroubleshooter/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/policytroubleshooter/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6858,7 +6757,7 @@ diff -urN a/googleapis/cloud/policytroubleshooter/v1/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/privatecatalog/v1beta1/BUILD.bazel b/googleapis/cloud/privatecatalog/v1beta1/BUILD.bazel ---- a/googleapis/cloud/privatecatalog/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/privatecatalog/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/privatecatalog/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6880,7 +6779,7 @@ diff -urN a/googleapis/cloud/privatecatalog/v1beta1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/pubsublite/v1/BUILD.bazel b/googleapis/cloud/pubsublite/v1/BUILD.bazel ---- a/googleapis/cloud/pubsublite/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/pubsublite/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/pubsublite/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6902,7 +6801,7 @@ diff -urN a/googleapis/cloud/pubsublite/v1/BUILD.bazel b/googleapis/cloud/pubsub + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/recaptchaenterprise/v1/BUILD.bazel b/googleapis/cloud/recaptchaenterprise/v1/BUILD.bazel ---- a/googleapis/cloud/recaptchaenterprise/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/recaptchaenterprise/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/recaptchaenterprise/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6924,9 +6823,9 @@ diff -urN a/googleapis/cloud/recaptchaenterprise/v1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/recaptchaenterprise/v1beta1/BUILD.bazel b/googleapis/cloud/recaptchaenterprise/v1beta1/BUILD.bazel ---- a/googleapis/cloud/recaptchaenterprise/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/recaptchaenterprise/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/recaptchaenterprise/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,15 @@ +@@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( @@ -6934,7 +6833,10 @@ diff -urN a/googleapis/cloud/recaptchaenterprise/v1beta1/BUILD.bazel b/googleapi + srcs = ["alias.go"], + importpath = "google.golang.org/genproto/googleapis/cloud/recaptchaenterprise/v1beta1", + visibility = ["//visibility:public"], -+ deps = ["@org_golang_google_grpc//:go_default_library"], ++ deps = [ ++ "@com_google_cloud_go_recaptchaenterprise_v2//apiv1beta1/recaptchaenterprisepb:go_default_library", ++ "@org_golang_google_grpc//:go_default_library", ++ ], +) + +alias( @@ -6943,7 +6845,7 @@ diff -urN a/googleapis/cloud/recaptchaenterprise/v1beta1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/recommendationengine/v1beta1/BUILD.bazel b/googleapis/cloud/recommendationengine/v1beta1/BUILD.bazel ---- a/googleapis/cloud/recommendationengine/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/recommendationengine/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/recommendationengine/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6965,7 +6867,7 @@ diff -urN a/googleapis/cloud/recommendationengine/v1beta1/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/recommender/logging/v1/BUILD.bazel b/googleapis/cloud/recommender/logging/v1/BUILD.bazel ---- a/googleapis/cloud/recommender/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/recommender/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/recommender/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -6989,7 +6891,7 @@ diff -urN a/googleapis/cloud/recommender/logging/v1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/recommender/logging/v1beta1/BUILD.bazel b/googleapis/cloud/recommender/logging/v1beta1/BUILD.bazel ---- a/googleapis/cloud/recommender/logging/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/recommender/logging/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/recommender/logging/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7013,7 +6915,7 @@ diff -urN a/googleapis/cloud/recommender/logging/v1beta1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/recommender/v1/BUILD.bazel b/googleapis/cloud/recommender/v1/BUILD.bazel ---- a/googleapis/cloud/recommender/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/recommender/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/recommender/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7035,7 +6937,7 @@ diff -urN a/googleapis/cloud/recommender/v1/BUILD.bazel b/googleapis/cloud/recom + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/recommender/v1beta1/BUILD.bazel b/googleapis/cloud/recommender/v1beta1/BUILD.bazel ---- a/googleapis/cloud/recommender/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/recommender/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/recommender/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7057,7 +6959,7 @@ diff -urN a/googleapis/cloud/recommender/v1beta1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/redis/v1/BUILD.bazel b/googleapis/cloud/redis/v1/BUILD.bazel ---- a/googleapis/cloud/redis/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/redis/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/redis/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7079,7 +6981,7 @@ diff -urN a/googleapis/cloud/redis/v1/BUILD.bazel b/googleapis/cloud/redis/v1/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/redis/v1beta1/BUILD.bazel b/googleapis/cloud/redis/v1beta1/BUILD.bazel ---- a/googleapis/cloud/redis/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/redis/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/redis/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7101,7 +7003,7 @@ diff -urN a/googleapis/cloud/redis/v1beta1/BUILD.bazel b/googleapis/cloud/redis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/resourcemanager/v2/BUILD.bazel b/googleapis/cloud/resourcemanager/v2/BUILD.bazel ---- a/googleapis/cloud/resourcemanager/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/resourcemanager/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/resourcemanager/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7123,7 +7025,7 @@ diff -urN a/googleapis/cloud/resourcemanager/v2/BUILD.bazel b/googleapis/cloud/r + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/resourcemanager/v3/BUILD.bazel b/googleapis/cloud/resourcemanager/v3/BUILD.bazel ---- a/googleapis/cloud/resourcemanager/v3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/resourcemanager/v3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/resourcemanager/v3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7145,7 +7047,7 @@ diff -urN a/googleapis/cloud/resourcemanager/v3/BUILD.bazel b/googleapis/cloud/r + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/resourcesettings/v1/BUILD.bazel b/googleapis/cloud/resourcesettings/v1/BUILD.bazel ---- a/googleapis/cloud/resourcesettings/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/resourcesettings/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/resourcesettings/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7167,7 +7069,7 @@ diff -urN a/googleapis/cloud/resourcesettings/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/retail/logging/BUILD.bazel b/googleapis/cloud/retail/logging/BUILD.bazel ---- a/googleapis/cloud/retail/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/retail/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/retail/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7191,7 +7093,7 @@ diff -urN a/googleapis/cloud/retail/logging/BUILD.bazel b/googleapis/cloud/retai + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/retail/v2/BUILD.bazel b/googleapis/cloud/retail/v2/BUILD.bazel ---- a/googleapis/cloud/retail/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/retail/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/retail/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7213,7 +7115,7 @@ diff -urN a/googleapis/cloud/retail/v2/BUILD.bazel b/googleapis/cloud/retail/v2/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/retail/v2alpha/BUILD.bazel b/googleapis/cloud/retail/v2alpha/BUILD.bazel ---- a/googleapis/cloud/retail/v2alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/retail/v2alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/retail/v2alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7235,7 +7137,7 @@ diff -urN a/googleapis/cloud/retail/v2alpha/BUILD.bazel b/googleapis/cloud/retai + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/retail/v2beta/BUILD.bazel b/googleapis/cloud/retail/v2beta/BUILD.bazel ---- a/googleapis/cloud/retail/v2beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/retail/v2beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/retail/v2beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7257,7 +7159,7 @@ diff -urN a/googleapis/cloud/retail/v2beta/BUILD.bazel b/googleapis/cloud/retail + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/run/v2/BUILD.bazel b/googleapis/cloud/run/v2/BUILD.bazel ---- a/googleapis/cloud/run/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/run/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/run/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7279,7 +7181,7 @@ diff -urN a/googleapis/cloud/run/v2/BUILD.bazel b/googleapis/cloud/run/v2/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/runtimeconfig/v1beta1/BUILD.bazel b/googleapis/cloud/runtimeconfig/v1beta1/BUILD.bazel ---- a/googleapis/cloud/runtimeconfig/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/runtimeconfig/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/runtimeconfig/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7313,7 +7215,7 @@ diff -urN a/googleapis/cloud/runtimeconfig/v1beta1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/saasaccelerator/management/logs/v1/BUILD.bazel b/googleapis/cloud/saasaccelerator/management/logs/v1/BUILD.bazel ---- a/googleapis/cloud/saasaccelerator/management/logs/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/saasaccelerator/management/logs/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/saasaccelerator/management/logs/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7339,7 +7241,7 @@ diff -urN a/googleapis/cloud/saasaccelerator/management/logs/v1/BUILD.bazel b/go + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/scheduler/v1/BUILD.bazel b/googleapis/cloud/scheduler/v1/BUILD.bazel ---- a/googleapis/cloud/scheduler/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/scheduler/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/scheduler/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7361,7 +7263,7 @@ diff -urN a/googleapis/cloud/scheduler/v1/BUILD.bazel b/googleapis/cloud/schedul + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/scheduler/v1beta1/BUILD.bazel b/googleapis/cloud/scheduler/v1beta1/BUILD.bazel ---- a/googleapis/cloud/scheduler/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/scheduler/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/scheduler/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7383,7 +7285,7 @@ diff -urN a/googleapis/cloud/scheduler/v1beta1/BUILD.bazel b/googleapis/cloud/sc + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/secretmanager/logging/v1/BUILD.bazel b/googleapis/cloud/secretmanager/logging/v1/BUILD.bazel ---- a/googleapis/cloud/secretmanager/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/secretmanager/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/secretmanager/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7405,7 +7307,7 @@ diff -urN a/googleapis/cloud/secretmanager/logging/v1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/secretmanager/v1/BUILD.bazel b/googleapis/cloud/secretmanager/v1/BUILD.bazel ---- a/googleapis/cloud/secretmanager/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/secretmanager/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/secretmanager/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7427,7 +7329,7 @@ diff -urN a/googleapis/cloud/secretmanager/v1/BUILD.bazel b/googleapis/cloud/sec + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/security/privateca/v1/BUILD.bazel b/googleapis/cloud/security/privateca/v1/BUILD.bazel ---- a/googleapis/cloud/security/privateca/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/security/privateca/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/security/privateca/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7449,7 +7351,7 @@ diff -urN a/googleapis/cloud/security/privateca/v1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/security/publicca/v1beta1/BUILD.bazel b/googleapis/cloud/security/publicca/v1beta1/BUILD.bazel ---- a/googleapis/cloud/security/publicca/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/security/publicca/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/security/publicca/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7471,7 +7373,7 @@ diff -urN a/googleapis/cloud/security/publicca/v1beta1/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/securitycenter/settings/v1beta1/BUILD.bazel b/googleapis/cloud/securitycenter/settings/v1beta1/BUILD.bazel ---- a/googleapis/cloud/securitycenter/settings/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/securitycenter/settings/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/securitycenter/settings/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7493,7 +7395,7 @@ diff -urN a/googleapis/cloud/securitycenter/settings/v1beta1/BUILD.bazel b/googl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/securitycenter/v1/BUILD.bazel b/googleapis/cloud/securitycenter/v1/BUILD.bazel ---- a/googleapis/cloud/securitycenter/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/securitycenter/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/securitycenter/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7515,7 +7417,7 @@ diff -urN a/googleapis/cloud/securitycenter/v1/BUILD.bazel b/googleapis/cloud/se + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/securitycenter/v1beta1/BUILD.bazel b/googleapis/cloud/securitycenter/v1beta1/BUILD.bazel ---- a/googleapis/cloud/securitycenter/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/securitycenter/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/securitycenter/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7537,7 +7439,7 @@ diff -urN a/googleapis/cloud/securitycenter/v1beta1/BUILD.bazel b/googleapis/clo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/securitycenter/v1p1beta1/BUILD.bazel b/googleapis/cloud/securitycenter/v1p1beta1/BUILD.bazel ---- a/googleapis/cloud/securitycenter/v1p1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/securitycenter/v1p1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/securitycenter/v1p1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7559,7 +7461,7 @@ diff -urN a/googleapis/cloud/securitycenter/v1p1beta1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/sensitiveaction/logging/v1/BUILD.bazel b/googleapis/cloud/sensitiveaction/logging/v1/BUILD.bazel ---- a/googleapis/cloud/sensitiveaction/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/sensitiveaction/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/sensitiveaction/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7583,7 +7485,7 @@ diff -urN a/googleapis/cloud/sensitiveaction/logging/v1/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/servicedirectory/v1/BUILD.bazel b/googleapis/cloud/servicedirectory/v1/BUILD.bazel ---- a/googleapis/cloud/servicedirectory/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/servicedirectory/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/servicedirectory/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7605,7 +7507,7 @@ diff -urN a/googleapis/cloud/servicedirectory/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/servicedirectory/v1beta1/BUILD.bazel b/googleapis/cloud/servicedirectory/v1beta1/BUILD.bazel ---- a/googleapis/cloud/servicedirectory/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/servicedirectory/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/servicedirectory/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7627,7 +7529,7 @@ diff -urN a/googleapis/cloud/servicedirectory/v1beta1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/shell/v1/BUILD.bazel b/googleapis/cloud/shell/v1/BUILD.bazel ---- a/googleapis/cloud/shell/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/shell/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/shell/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7649,7 +7551,7 @@ diff -urN a/googleapis/cloud/shell/v1/BUILD.bazel b/googleapis/cloud/shell/v1/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/speech/v1/BUILD.bazel b/googleapis/cloud/speech/v1/BUILD.bazel ---- a/googleapis/cloud/speech/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/speech/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/speech/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7671,7 +7573,7 @@ diff -urN a/googleapis/cloud/speech/v1/BUILD.bazel b/googleapis/cloud/speech/v1/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/speech/v1p1beta1/BUILD.bazel b/googleapis/cloud/speech/v1p1beta1/BUILD.bazel ---- a/googleapis/cloud/speech/v1p1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/speech/v1p1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/speech/v1p1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7693,7 +7595,7 @@ diff -urN a/googleapis/cloud/speech/v1p1beta1/BUILD.bazel b/googleapis/cloud/spe + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/speech/v2/BUILD.bazel b/googleapis/cloud/speech/v2/BUILD.bazel ---- a/googleapis/cloud/speech/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/speech/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/speech/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7715,7 +7617,7 @@ diff -urN a/googleapis/cloud/speech/v2/BUILD.bazel b/googleapis/cloud/speech/v2/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/sql/v1/BUILD.bazel b/googleapis/cloud/sql/v1/BUILD.bazel ---- a/googleapis/cloud/sql/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/sql/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/sql/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7755,7 +7657,7 @@ diff -urN a/googleapis/cloud/sql/v1/BUILD.bazel b/googleapis/cloud/sql/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/sql/v1beta4/BUILD.bazel b/googleapis/cloud/sql/v1beta4/BUILD.bazel ---- a/googleapis/cloud/sql/v1beta4/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/sql/v1beta4/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/sql/v1beta4/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7790,7 +7692,7 @@ diff -urN a/googleapis/cloud/sql/v1beta4/BUILD.bazel b/googleapis/cloud/sql/v1be + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/storageinsights/v1/BUILD.bazel b/googleapis/cloud/storageinsights/v1/BUILD.bazel ---- a/googleapis/cloud/storageinsights/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/storageinsights/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/storageinsights/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7822,7 +7724,7 @@ diff -urN a/googleapis/cloud/storageinsights/v1/BUILD.bazel b/googleapis/cloud/s + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/stream/logging/v1/BUILD.bazel b/googleapis/cloud/stream/logging/v1/BUILD.bazel ---- a/googleapis/cloud/stream/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/stream/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/stream/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7845,7 +7747,7 @@ diff -urN a/googleapis/cloud/stream/logging/v1/BUILD.bazel b/googleapis/cloud/st + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/support/common/BUILD.bazel b/googleapis/cloud/support/common/BUILD.bazel ---- a/googleapis/cloud/support/common/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/support/common/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/support/common/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7869,7 +7771,7 @@ diff -urN a/googleapis/cloud/support/common/BUILD.bazel b/googleapis/cloud/suppo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/support/v1alpha1/BUILD.bazel b/googleapis/cloud/support/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/support/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/support/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/support/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7898,7 +7800,7 @@ diff -urN a/googleapis/cloud/support/v1alpha1/BUILD.bazel b/googleapis/cloud/sup + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/talent/v4/BUILD.bazel b/googleapis/cloud/talent/v4/BUILD.bazel ---- a/googleapis/cloud/talent/v4/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/talent/v4/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/talent/v4/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7920,7 +7822,7 @@ diff -urN a/googleapis/cloud/talent/v4/BUILD.bazel b/googleapis/cloud/talent/v4/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/talent/v4beta1/BUILD.bazel b/googleapis/cloud/talent/v4beta1/BUILD.bazel ---- a/googleapis/cloud/talent/v4beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/talent/v4beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/talent/v4beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7942,7 +7844,7 @@ diff -urN a/googleapis/cloud/talent/v4beta1/BUILD.bazel b/googleapis/cloud/talen + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/tasks/v2/BUILD.bazel b/googleapis/cloud/tasks/v2/BUILD.bazel ---- a/googleapis/cloud/tasks/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/tasks/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/tasks/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7964,7 +7866,7 @@ diff -urN a/googleapis/cloud/tasks/v2/BUILD.bazel b/googleapis/cloud/tasks/v2/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/tasks/v2beta2/BUILD.bazel b/googleapis/cloud/tasks/v2beta2/BUILD.bazel ---- a/googleapis/cloud/tasks/v2beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/tasks/v2beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/tasks/v2beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -7986,7 +7888,7 @@ diff -urN a/googleapis/cloud/tasks/v2beta2/BUILD.bazel b/googleapis/cloud/tasks/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/tasks/v2beta3/BUILD.bazel b/googleapis/cloud/tasks/v2beta3/BUILD.bazel ---- a/googleapis/cloud/tasks/v2beta3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/tasks/v2beta3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/tasks/v2beta3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8008,7 +7910,7 @@ diff -urN a/googleapis/cloud/tasks/v2beta3/BUILD.bazel b/googleapis/cloud/tasks/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/texttospeech/v1/BUILD.bazel b/googleapis/cloud/texttospeech/v1/BUILD.bazel ---- a/googleapis/cloud/texttospeech/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/texttospeech/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/texttospeech/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8030,7 +7932,7 @@ diff -urN a/googleapis/cloud/texttospeech/v1/BUILD.bazel b/googleapis/cloud/text + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/texttospeech/v1beta1/BUILD.bazel b/googleapis/cloud/texttospeech/v1beta1/BUILD.bazel ---- a/googleapis/cloud/texttospeech/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/texttospeech/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/texttospeech/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8061,7 +7963,7 @@ diff -urN a/googleapis/cloud/texttospeech/v1beta1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/timeseriesinsights/v1/BUILD.bazel b/googleapis/cloud/timeseriesinsights/v1/BUILD.bazel ---- a/googleapis/cloud/timeseriesinsights/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/timeseriesinsights/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/timeseriesinsights/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8091,7 +7993,7 @@ diff -urN a/googleapis/cloud/timeseriesinsights/v1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/tpu/v1/BUILD.bazel b/googleapis/cloud/tpu/v1/BUILD.bazel ---- a/googleapis/cloud/tpu/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/tpu/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/tpu/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8113,7 +8015,7 @@ diff -urN a/googleapis/cloud/tpu/v1/BUILD.bazel b/googleapis/cloud/tpu/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/tpu/v2/BUILD.bazel b/googleapis/cloud/tpu/v2/BUILD.bazel ---- a/googleapis/cloud/tpu/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/tpu/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/tpu/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8142,7 +8044,7 @@ diff -urN a/googleapis/cloud/tpu/v2/BUILD.bazel b/googleapis/cloud/tpu/v2/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/tpu/v2alpha1/BUILD.bazel b/googleapis/cloud/tpu/v2alpha1/BUILD.bazel ---- a/googleapis/cloud/tpu/v2alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/tpu/v2alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/tpu/v2alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8174,7 +8076,7 @@ diff -urN a/googleapis/cloud/tpu/v2alpha1/BUILD.bazel b/googleapis/cloud/tpu/v2a + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/translate/v3/BUILD.bazel b/googleapis/cloud/translate/v3/BUILD.bazel ---- a/googleapis/cloud/translate/v3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/translate/v3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/translate/v3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8196,7 +8098,7 @@ diff -urN a/googleapis/cloud/translate/v3/BUILD.bazel b/googleapis/cloud/transla + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/translate/v3beta1/BUILD.bazel b/googleapis/cloud/translate/v3beta1/BUILD.bazel ---- a/googleapis/cloud/translate/v3beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/translate/v3beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/translate/v3beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8224,7 +8126,7 @@ diff -urN a/googleapis/cloud/translate/v3beta1/BUILD.bazel b/googleapis/cloud/tr + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/video/livestream/logging/v1/BUILD.bazel b/googleapis/cloud/video/livestream/logging/v1/BUILD.bazel ---- a/googleapis/cloud/video/livestream/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/video/livestream/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/video/livestream/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8248,7 +8150,7 @@ diff -urN a/googleapis/cloud/video/livestream/logging/v1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/video/livestream/v1/BUILD.bazel b/googleapis/cloud/video/livestream/v1/BUILD.bazel ---- a/googleapis/cloud/video/livestream/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/video/livestream/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/video/livestream/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8270,7 +8172,7 @@ diff -urN a/googleapis/cloud/video/livestream/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/video/stitcher/v1/BUILD.bazel b/googleapis/cloud/video/stitcher/v1/BUILD.bazel ---- a/googleapis/cloud/video/stitcher/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/video/stitcher/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/video/stitcher/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8292,7 +8194,7 @@ diff -urN a/googleapis/cloud/video/stitcher/v1/BUILD.bazel b/googleapis/cloud/vi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/video/transcoder/v1/BUILD.bazel b/googleapis/cloud/video/transcoder/v1/BUILD.bazel ---- a/googleapis/cloud/video/transcoder/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/video/transcoder/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/video/transcoder/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8314,7 +8216,7 @@ diff -urN a/googleapis/cloud/video/transcoder/v1/BUILD.bazel b/googleapis/cloud/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/videointelligence/v1/BUILD.bazel b/googleapis/cloud/videointelligence/v1/BUILD.bazel ---- a/googleapis/cloud/videointelligence/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/videointelligence/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/videointelligence/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8336,7 +8238,7 @@ diff -urN a/googleapis/cloud/videointelligence/v1/BUILD.bazel b/googleapis/cloud + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/videointelligence/v1beta2/BUILD.bazel b/googleapis/cloud/videointelligence/v1beta2/BUILD.bazel ---- a/googleapis/cloud/videointelligence/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/videointelligence/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/videointelligence/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8358,7 +8260,7 @@ diff -urN a/googleapis/cloud/videointelligence/v1beta2/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/videointelligence/v1p1beta1/BUILD.bazel b/googleapis/cloud/videointelligence/v1p1beta1/BUILD.bazel ---- a/googleapis/cloud/videointelligence/v1p1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/videointelligence/v1p1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/videointelligence/v1p1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8388,7 +8290,7 @@ diff -urN a/googleapis/cloud/videointelligence/v1p1beta1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/videointelligence/v1p2beta1/BUILD.bazel b/googleapis/cloud/videointelligence/v1p2beta1/BUILD.bazel ---- a/googleapis/cloud/videointelligence/v1p2beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/videointelligence/v1p2beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/videointelligence/v1p2beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8418,7 +8320,7 @@ diff -urN a/googleapis/cloud/videointelligence/v1p2beta1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/videointelligence/v1p3beta1/BUILD.bazel b/googleapis/cloud/videointelligence/v1p3beta1/BUILD.bazel ---- a/googleapis/cloud/videointelligence/v1p3beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/videointelligence/v1p3beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/videointelligence/v1p3beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8440,7 +8342,7 @@ diff -urN a/googleapis/cloud/videointelligence/v1p3beta1/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vision/v1/BUILD.bazel b/googleapis/cloud/vision/v1/BUILD.bazel ---- a/googleapis/cloud/vision/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vision/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vision/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8462,7 +8364,7 @@ diff -urN a/googleapis/cloud/vision/v1/BUILD.bazel b/googleapis/cloud/vision/v1/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vision/v1p1beta1/BUILD.bazel b/googleapis/cloud/vision/v1p1beta1/BUILD.bazel ---- a/googleapis/cloud/vision/v1p1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vision/v1p1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vision/v1p1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8484,7 +8386,7 @@ diff -urN a/googleapis/cloud/vision/v1p1beta1/BUILD.bazel b/googleapis/cloud/vis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vision/v1p2beta1/BUILD.bazel b/googleapis/cloud/vision/v1p2beta1/BUILD.bazel ---- a/googleapis/cloud/vision/v1p2beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vision/v1p2beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vision/v1p2beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8520,7 +8422,7 @@ diff -urN a/googleapis/cloud/vision/v1p2beta1/BUILD.bazel b/googleapis/cloud/vis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vision/v1p3beta1/BUILD.bazel b/googleapis/cloud/vision/v1p3beta1/BUILD.bazel ---- a/googleapis/cloud/vision/v1p3beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vision/v1p3beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vision/v1p3beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8560,7 +8462,7 @@ diff -urN a/googleapis/cloud/vision/v1p3beta1/BUILD.bazel b/googleapis/cloud/vis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vision/v1p4beta1/BUILD.bazel b/googleapis/cloud/vision/v1p4beta1/BUILD.bazel ---- a/googleapis/cloud/vision/v1p4beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vision/v1p4beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vision/v1p4beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8601,7 +8503,7 @@ diff -urN a/googleapis/cloud/vision/v1p4beta1/BUILD.bazel b/googleapis/cloud/vis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/visionai/v1/BUILD.bazel b/googleapis/cloud/visionai/v1/BUILD.bazel ---- a/googleapis/cloud/visionai/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/visionai/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/visionai/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8648,7 +8550,7 @@ diff -urN a/googleapis/cloud/visionai/v1/BUILD.bazel b/googleapis/cloud/visionai + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/visionai/v1alpha1/BUILD.bazel b/googleapis/cloud/visionai/v1alpha1/BUILD.bazel ---- a/googleapis/cloud/visionai/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/visionai/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/visionai/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8695,7 +8597,7 @@ diff -urN a/googleapis/cloud/visionai/v1alpha1/BUILD.bazel b/googleapis/cloud/vi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/visualinspection/v1beta1/BUILD.bazel b/googleapis/cloud/visualinspection/v1beta1/BUILD.bazel ---- a/googleapis/cloud/visualinspection/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/visualinspection/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/visualinspection/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,46 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8745,7 +8647,7 @@ diff -urN a/googleapis/cloud/visualinspection/v1beta1/BUILD.bazel b/googleapis/c + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vmmigration/v1/BUILD.bazel b/googleapis/cloud/vmmigration/v1/BUILD.bazel ---- a/googleapis/cloud/vmmigration/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vmmigration/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vmmigration/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8767,7 +8669,7 @@ diff -urN a/googleapis/cloud/vmmigration/v1/BUILD.bazel b/googleapis/cloud/vmmig + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vmwareengine/v1/BUILD.bazel b/googleapis/cloud/vmwareengine/v1/BUILD.bazel ---- a/googleapis/cloud/vmwareengine/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vmwareengine/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vmwareengine/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8789,7 +8691,7 @@ diff -urN a/googleapis/cloud/vmwareengine/v1/BUILD.bazel b/googleapis/cloud/vmwa + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/vpcaccess/v1/BUILD.bazel b/googleapis/cloud/vpcaccess/v1/BUILD.bazel ---- a/googleapis/cloud/vpcaccess/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/vpcaccess/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/vpcaccess/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8811,7 +8713,7 @@ diff -urN a/googleapis/cloud/vpcaccess/v1/BUILD.bazel b/googleapis/cloud/vpcacce + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/webrisk/v1/BUILD.bazel b/googleapis/cloud/webrisk/v1/BUILD.bazel ---- a/googleapis/cloud/webrisk/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/webrisk/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/webrisk/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8833,7 +8735,7 @@ diff -urN a/googleapis/cloud/webrisk/v1/BUILD.bazel b/googleapis/cloud/webrisk/v + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/webrisk/v1beta1/BUILD.bazel b/googleapis/cloud/webrisk/v1beta1/BUILD.bazel ---- a/googleapis/cloud/webrisk/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/webrisk/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/webrisk/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8855,7 +8757,7 @@ diff -urN a/googleapis/cloud/webrisk/v1beta1/BUILD.bazel b/googleapis/cloud/webr + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/websecurityscanner/v1/BUILD.bazel b/googleapis/cloud/websecurityscanner/v1/BUILD.bazel ---- a/googleapis/cloud/websecurityscanner/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/websecurityscanner/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/websecurityscanner/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8877,7 +8779,7 @@ diff -urN a/googleapis/cloud/websecurityscanner/v1/BUILD.bazel b/googleapis/clou + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/websecurityscanner/v1alpha/BUILD.bazel b/googleapis/cloud/websecurityscanner/v1alpha/BUILD.bazel ---- a/googleapis/cloud/websecurityscanner/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/websecurityscanner/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/websecurityscanner/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8914,7 +8816,7 @@ diff -urN a/googleapis/cloud/websecurityscanner/v1alpha/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/websecurityscanner/v1beta/BUILD.bazel b/googleapis/cloud/websecurityscanner/v1beta/BUILD.bazel ---- a/googleapis/cloud/websecurityscanner/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/websecurityscanner/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/websecurityscanner/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8954,7 +8856,7 @@ diff -urN a/googleapis/cloud/websecurityscanner/v1beta/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/workflows/executions/v1/BUILD.bazel b/googleapis/cloud/workflows/executions/v1/BUILD.bazel ---- a/googleapis/cloud/workflows/executions/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/workflows/executions/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/workflows/executions/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8976,7 +8878,7 @@ diff -urN a/googleapis/cloud/workflows/executions/v1/BUILD.bazel b/googleapis/cl + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/workflows/executions/v1beta/BUILD.bazel b/googleapis/cloud/workflows/executions/v1beta/BUILD.bazel ---- a/googleapis/cloud/workflows/executions/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/workflows/executions/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/workflows/executions/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -8998,7 +8900,7 @@ diff -urN a/googleapis/cloud/workflows/executions/v1beta/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/workflows/type/BUILD.bazel b/googleapis/cloud/workflows/type/BUILD.bazel ---- a/googleapis/cloud/workflows/type/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/workflows/type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/workflows/type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9025,7 +8927,7 @@ diff -urN a/googleapis/cloud/workflows/type/BUILD.bazel b/googleapis/cloud/workf + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/workflows/v1/BUILD.bazel b/googleapis/cloud/workflows/v1/BUILD.bazel ---- a/googleapis/cloud/workflows/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/workflows/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/workflows/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9047,7 +8949,7 @@ diff -urN a/googleapis/cloud/workflows/v1/BUILD.bazel b/googleapis/cloud/workflo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/cloud/workflows/v1beta/BUILD.bazel b/googleapis/cloud/workflows/v1beta/BUILD.bazel ---- a/googleapis/cloud/workflows/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/cloud/workflows/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/cloud/workflows/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9069,7 +8971,7 @@ diff -urN a/googleapis/cloud/workflows/v1beta/BUILD.bazel b/googleapis/cloud/wor + visibility = ["//visibility:public"], +) diff -urN a/googleapis/container/v1/BUILD.bazel b/googleapis/container/v1/BUILD.bazel ---- a/googleapis/container/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/container/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/container/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9091,7 +8993,7 @@ diff -urN a/googleapis/container/v1/BUILD.bazel b/googleapis/container/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/container/v1alpha1/BUILD.bazel b/googleapis/container/v1alpha1/BUILD.bazel ---- a/googleapis/container/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/container/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/container/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9118,7 +9020,7 @@ diff -urN a/googleapis/container/v1alpha1/BUILD.bazel b/googleapis/container/v1a + visibility = ["//visibility:public"], +) diff -urN a/googleapis/container/v1beta1/BUILD.bazel b/googleapis/container/v1beta1/BUILD.bazel ---- a/googleapis/container/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/container/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/container/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9151,7 +9053,7 @@ diff -urN a/googleapis/container/v1beta1/BUILD.bazel b/googleapis/container/v1be + visibility = ["//visibility:public"], +) diff -urN a/googleapis/dataflow/v1beta3/BUILD.bazel b/googleapis/dataflow/v1beta3/BUILD.bazel ---- a/googleapis/dataflow/v1beta3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/dataflow/v1beta3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/dataflow/v1beta3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9173,7 +9075,7 @@ diff -urN a/googleapis/dataflow/v1beta3/BUILD.bazel b/googleapis/dataflow/v1beta + visibility = ["//visibility:public"], +) diff -urN a/googleapis/datastore/admin/v1/BUILD.bazel b/googleapis/datastore/admin/v1/BUILD.bazel ---- a/googleapis/datastore/admin/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/datastore/admin/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/datastore/admin/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9195,7 +9097,7 @@ diff -urN a/googleapis/datastore/admin/v1/BUILD.bazel b/googleapis/datastore/adm + visibility = ["//visibility:public"], +) diff -urN a/googleapis/datastore/admin/v1beta1/BUILD.bazel b/googleapis/datastore/admin/v1beta1/BUILD.bazel ---- a/googleapis/datastore/admin/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/datastore/admin/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/datastore/admin/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9223,7 +9125,7 @@ diff -urN a/googleapis/datastore/admin/v1beta1/BUILD.bazel b/googleapis/datastor + visibility = ["//visibility:public"], +) diff -urN a/googleapis/datastore/v1/BUILD.bazel b/googleapis/datastore/v1/BUILD.bazel ---- a/googleapis/datastore/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/datastore/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/datastore/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9258,7 +9160,7 @@ diff -urN a/googleapis/datastore/v1/BUILD.bazel b/googleapis/datastore/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/datastore/v1beta3/BUILD.bazel b/googleapis/datastore/v1beta3/BUILD.bazel ---- a/googleapis/datastore/v1beta3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/datastore/v1beta3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/datastore/v1beta3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9292,7 +9194,7 @@ diff -urN a/googleapis/datastore/v1beta3/BUILD.bazel b/googleapis/datastore/v1be + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/artifactregistry/v1/BUILD.bazel b/googleapis/devtools/artifactregistry/v1/BUILD.bazel ---- a/googleapis/devtools/artifactregistry/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/artifactregistry/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/artifactregistry/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9314,7 +9216,7 @@ diff -urN a/googleapis/devtools/artifactregistry/v1/BUILD.bazel b/googleapis/dev + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/artifactregistry/v1beta2/BUILD.bazel b/googleapis/devtools/artifactregistry/v1beta2/BUILD.bazel ---- a/googleapis/devtools/artifactregistry/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/artifactregistry/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/artifactregistry/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9336,7 +9238,7 @@ diff -urN a/googleapis/devtools/artifactregistry/v1beta2/BUILD.bazel b/googleapi + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/build/v1/BUILD.bazel b/googleapis/devtools/build/v1/BUILD.bazel ---- a/googleapis/devtools/build/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/build/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/build/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9371,7 +9273,7 @@ diff -urN a/googleapis/devtools/build/v1/BUILD.bazel b/googleapis/devtools/build + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/cloudbuild/v1/BUILD.bazel b/googleapis/devtools/cloudbuild/v1/BUILD.bazel ---- a/googleapis/devtools/cloudbuild/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/cloudbuild/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/cloudbuild/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9393,7 +9295,7 @@ diff -urN a/googleapis/devtools/cloudbuild/v1/BUILD.bazel b/googleapis/devtools/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/clouddebugger/v2/BUILD.bazel b/googleapis/devtools/clouddebugger/v2/BUILD.bazel ---- a/googleapis/devtools/clouddebugger/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/clouddebugger/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/clouddebugger/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9415,7 +9317,7 @@ diff -urN a/googleapis/devtools/clouddebugger/v2/BUILD.bazel b/googleapis/devtoo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/clouderrorreporting/v1beta1/BUILD.bazel b/googleapis/devtools/clouderrorreporting/v1beta1/BUILD.bazel ---- a/googleapis/devtools/clouderrorreporting/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/clouderrorreporting/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/clouderrorreporting/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9437,7 +9339,7 @@ diff -urN a/googleapis/devtools/clouderrorreporting/v1beta1/BUILD.bazel b/google + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/cloudprofiler/v2/BUILD.bazel b/googleapis/devtools/cloudprofiler/v2/BUILD.bazel ---- a/googleapis/devtools/cloudprofiler/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/cloudprofiler/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/cloudprofiler/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9465,7 +9367,7 @@ diff -urN a/googleapis/devtools/cloudprofiler/v2/BUILD.bazel b/googleapis/devtoo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/cloudtrace/v1/BUILD.bazel b/googleapis/devtools/cloudtrace/v1/BUILD.bazel ---- a/googleapis/devtools/cloudtrace/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/cloudtrace/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/cloudtrace/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9487,7 +9389,7 @@ diff -urN a/googleapis/devtools/cloudtrace/v1/BUILD.bazel b/googleapis/devtools/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/cloudtrace/v2/BUILD.bazel b/googleapis/devtools/cloudtrace/v2/BUILD.bazel ---- a/googleapis/devtools/cloudtrace/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/cloudtrace/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/cloudtrace/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9509,7 +9411,7 @@ diff -urN a/googleapis/devtools/cloudtrace/v2/BUILD.bazel b/googleapis/devtools/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1/BUILD.bazel b/googleapis/devtools/containeranalysis/v1/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9536,69 +9438,8 @@ diff -urN a/googleapis/devtools/containeranalysis/v1/BUILD.bazel b/googleapis/de + actual = ":containeranalysis", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/devtools/containeranalysis/v1alpha1/BUILD.bazel b/googleapis/devtools/containeranalysis/v1alpha1/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/devtools/containeranalysis/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "v1alpha1", -+ srcs = [ -+ "bill_of_materials.pb.go", -+ "containeranalysis.pb.go", -+ "image_basis.pb.go", -+ "package_vulnerability.pb.go", -+ "provenance.pb.go", -+ "source_context.pb.go", -+ ], -+ importpath = "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1alpha1", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "//googleapis/api/annotations", -+ "//googleapis/iam/v1:iam", -+ "//googleapis/longrunning", -+ "//googleapis/rpc/status", -+ "//protobuf/field_mask", -+ "@com_github_golang_protobuf//proto:go_default_library", -+ "@com_github_golang_protobuf//ptypes/any:go_default_library", -+ "@com_github_golang_protobuf//ptypes/empty:go_default_library", -+ "@com_github_golang_protobuf//ptypes/timestamp:go_default_library", -+ "@org_golang_google_grpc//:go_default_library", -+ "@org_golang_google_grpc//codes:go_default_library", -+ "@org_golang_google_grpc//status:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":v1alpha1", -+ visibility = ["//visibility:public"], -+) -diff -urN a/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "v1beta1", -+ srcs = ["alias.go"], -+ importpath = "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "@com_google_cloud_go_containeranalysis//apiv1beta1/containeranalysispb:go_default_library", -+ "@org_golang_google_grpc//:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":v1beta1", -+ visibility = ["//visibility:public"], -+) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/attestation/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/attestation/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/attestation/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/attestation/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/attestation/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9621,7 +9462,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/attestation/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/build/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/build/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/build/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/build/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/build/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9643,8 +9484,30 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/build/BUILD.bazel b/go + actual = ":build", + visibility = ["//visibility:public"], +) +diff -urN a/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel +--- a/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/googleapis/devtools/containeranalysis/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,18 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "v1beta1", ++ srcs = ["alias.go"], ++ importpath = "google.golang.org/genproto/googleapis/devtools/containeranalysis/v1beta1", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "@com_google_cloud_go_containeranalysis//apiv1beta1/containeranalysispb:go_default_library", ++ "@org_golang_google_grpc//:go_default_library", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":v1beta1", ++ visibility = ["//visibility:public"], ++) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/common/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/common/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/common/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/common/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/common/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9666,7 +9529,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/common/BUILD.bazel b/g + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/cvss/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/cvss/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/cvss/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/cvss/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/cvss/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9688,7 +9551,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/cvss/BUILD.bazel b/goo + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/deployment/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/deployment/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/deployment/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/deployment/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/deployment/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9711,7 +9574,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/deployment/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/discovery/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/discovery/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/discovery/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/discovery/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/discovery/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9736,7 +9599,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/discovery/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/grafeas/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/grafeas/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/grafeas/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/grafeas/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/grafeas/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9758,7 +9621,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/grafeas/BUILD.bazel b/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/image/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/image/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/image/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/image/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/image/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9780,7 +9643,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/image/BUILD.bazel b/go + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/package/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/package/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/package/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/package/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/package/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9802,7 +9665,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/package/BUILD.bazel b/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/provenance/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/provenance/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/provenance/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/provenance/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/provenance/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9826,7 +9689,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/provenance/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/source/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/source/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/source/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/source/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/source/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9848,7 +9711,7 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/source/BUILD.bazel b/g + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/containeranalysis/v1beta1/vulnerability/BUILD.bazel b/googleapis/devtools/containeranalysis/v1beta1/vulnerability/BUILD.bazel ---- a/googleapis/devtools/containeranalysis/v1beta1/vulnerability/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/containeranalysis/v1beta1/vulnerability/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/containeranalysis/v1beta1/vulnerability/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9873,47 +9736,8 @@ diff -urN a/googleapis/devtools/containeranalysis/v1beta1/vulnerability/BUILD.ba + actual = ":vulnerability", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/devtools/remoteworkers/v1test2/BUILD.bazel b/googleapis/devtools/remoteworkers/v1test2/BUILD.bazel ---- a/googleapis/devtools/remoteworkers/v1test2/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/devtools/remoteworkers/v1test2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "v1test2", -+ srcs = [ -+ "bots.pb.go", -+ "command.pb.go", -+ "tasks.pb.go", -+ "worker.pb.go", -+ ], -+ importpath = "google.golang.org/genproto/googleapis/devtools/remoteworkers/v1test2", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "//googleapis/api/annotations", -+ "//googleapis/rpc/status", -+ "//protobuf/field_mask", -+ "@com_github_golang_protobuf//proto:go_default_library", -+ "@com_github_golang_protobuf//ptypes/any:go_default_library", -+ "@org_golang_google_grpc//:go_default_library", -+ "@org_golang_google_grpc//codes:go_default_library", -+ "@org_golang_google_grpc//status:go_default_library", -+ "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", -+ "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", -+ "@org_golang_google_protobuf//types/known/anypb:go_default_library", -+ "@org_golang_google_protobuf//types/known/durationpb:go_default_library", -+ "@org_golang_google_protobuf//types/known/fieldmaskpb:go_default_library", -+ "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":v1test2", -+ visibility = ["//visibility:public"], -+) diff -urN a/googleapis/devtools/resultstore/v2/BUILD.bazel b/googleapis/devtools/resultstore/v2/BUILD.bazel ---- a/googleapis/devtools/resultstore/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/resultstore/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/resultstore/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9962,7 +9786,7 @@ diff -urN a/googleapis/devtools/resultstore/v2/BUILD.bazel b/googleapis/devtools + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/source/v1/BUILD.bazel b/googleapis/devtools/source/v1/BUILD.bazel ---- a/googleapis/devtools/source/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/source/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/source/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -9984,7 +9808,7 @@ diff -urN a/googleapis/devtools/source/v1/BUILD.bazel b/googleapis/devtools/sour + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/sourcerepo/v1/BUILD.bazel b/googleapis/devtools/sourcerepo/v1/BUILD.bazel ---- a/googleapis/devtools/sourcerepo/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/sourcerepo/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/sourcerepo/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10012,7 +9836,7 @@ diff -urN a/googleapis/devtools/sourcerepo/v1/BUILD.bazel b/googleapis/devtools/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/devtools/testing/v1/BUILD.bazel b/googleapis/devtools/testing/v1/BUILD.bazel ---- a/googleapis/devtools/testing/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/devtools/testing/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/devtools/testing/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10045,7 +9869,7 @@ diff -urN a/googleapis/devtools/testing/v1/BUILD.bazel b/googleapis/devtools/tes + visibility = ["//visibility:public"], +) diff -urN a/googleapis/example/library/v1/BUILD.bazel b/googleapis/example/library/v1/BUILD.bazel ---- a/googleapis/example/library/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/example/library/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/example/library/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10073,7 +9897,7 @@ diff -urN a/googleapis/example/library/v1/BUILD.bazel b/googleapis/example/libra + visibility = ["//visibility:public"], +) diff -urN a/googleapis/firebase/fcm/connection/v1alpha1/BUILD.bazel b/googleapis/firebase/fcm/connection/v1alpha1/BUILD.bazel ---- a/googleapis/firebase/fcm/connection/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/firebase/fcm/connection/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/firebase/fcm/connection/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10100,7 +9924,7 @@ diff -urN a/googleapis/firebase/fcm/connection/v1alpha1/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/firestore/admin/v1/BUILD.bazel b/googleapis/firestore/admin/v1/BUILD.bazel ---- a/googleapis/firestore/admin/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/firestore/admin/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/firestore/admin/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10122,7 +9946,7 @@ diff -urN a/googleapis/firestore/admin/v1/BUILD.bazel b/googleapis/firestore/adm + visibility = ["//visibility:public"], +) diff -urN a/googleapis/firestore/admin/v1beta1/BUILD.bazel b/googleapis/firestore/admin/v1beta1/BUILD.bazel ---- a/googleapis/firestore/admin/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/firestore/admin/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/firestore/admin/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10156,7 +9980,7 @@ diff -urN a/googleapis/firestore/admin/v1beta1/BUILD.bazel b/googleapis/firestor + visibility = ["//visibility:public"], +) diff -urN a/googleapis/firestore/admin/v1beta2/BUILD.bazel b/googleapis/firestore/admin/v1beta2/BUILD.bazel ---- a/googleapis/firestore/admin/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/firestore/admin/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/firestore/admin/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10191,7 +10015,7 @@ diff -urN a/googleapis/firestore/admin/v1beta2/BUILD.bazel b/googleapis/firestor + visibility = ["//visibility:public"], +) diff -urN a/googleapis/firestore/v1/BUILD.bazel b/googleapis/firestore/v1/BUILD.bazel ---- a/googleapis/firestore/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/firestore/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/firestore/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10213,7 +10037,7 @@ diff -urN a/googleapis/firestore/v1/BUILD.bazel b/googleapis/firestore/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/firestore/v1beta1/BUILD.bazel b/googleapis/firestore/v1beta1/BUILD.bazel ---- a/googleapis/firestore/v1beta1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/firestore/v1beta1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/firestore/v1beta1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10251,7 +10075,7 @@ diff -urN a/googleapis/firestore/v1beta1/BUILD.bazel b/googleapis/firestore/v1be + visibility = ["//visibility:public"], +) diff -urN a/googleapis/gapic/metadata/BUILD.bazel b/googleapis/gapic/metadata/BUILD.bazel ---- a/googleapis/gapic/metadata/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/gapic/metadata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/gapic/metadata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10273,7 +10097,7 @@ diff -urN a/googleapis/gapic/metadata/BUILD.bazel b/googleapis/gapic/metadata/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/genomics/v1/BUILD.bazel b/googleapis/genomics/v1/BUILD.bazel ---- a/googleapis/genomics/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/genomics/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/genomics/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,44 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10321,7 +10145,7 @@ diff -urN a/googleapis/genomics/v1/BUILD.bazel b/googleapis/genomics/v1/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/genomics/v1alpha2/BUILD.bazel b/googleapis/genomics/v1alpha2/BUILD.bazel ---- a/googleapis/genomics/v1alpha2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/genomics/v1alpha2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/genomics/v1alpha2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10352,7 +10176,7 @@ diff -urN a/googleapis/genomics/v1alpha2/BUILD.bazel b/googleapis/genomics/v1alp + visibility = ["//visibility:public"], +) diff -urN a/googleapis/geo/type/viewport/BUILD.bazel b/googleapis/geo/type/viewport/BUILD.bazel ---- a/googleapis/geo/type/viewport/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/geo/type/viewport/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/geo/type/viewport/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10375,7 +10199,7 @@ diff -urN a/googleapis/geo/type/viewport/BUILD.bazel b/googleapis/geo/type/viewp + visibility = ["//visibility:public"], +) diff -urN a/googleapis/grafeas/v1/BUILD.bazel b/googleapis/grafeas/v1/BUILD.bazel ---- a/googleapis/grafeas/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/grafeas/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/grafeas/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,49 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10428,7 +10252,7 @@ diff -urN a/googleapis/grafeas/v1/BUILD.bazel b/googleapis/grafeas/v1/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/home/enterprise/sdm/v1/BUILD.bazel b/googleapis/home/enterprise/sdm/v1/BUILD.bazel ---- a/googleapis/home/enterprise/sdm/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/home/enterprise/sdm/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/home/enterprise/sdm/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10459,7 +10283,7 @@ diff -urN a/googleapis/home/enterprise/sdm/v1/BUILD.bazel b/googleapis/home/ente + visibility = ["//visibility:public"], +) diff -urN a/googleapis/home/graph/v1/BUILD.bazel b/googleapis/home/graph/v1/BUILD.bazel ---- a/googleapis/home/graph/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/home/graph/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/home/graph/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10490,7 +10314,7 @@ diff -urN a/googleapis/home/graph/v1/BUILD.bazel b/googleapis/home/graph/v1/BUIL + visibility = ["//visibility:public"], +) diff -urN a/googleapis/iam/admin/v1/BUILD.bazel b/googleapis/iam/admin/v1/BUILD.bazel ---- a/googleapis/iam/admin/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/iam/admin/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/iam/admin/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10512,7 +10336,7 @@ diff -urN a/googleapis/iam/admin/v1/BUILD.bazel b/googleapis/iam/admin/v1/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/iam/credentials/v1/BUILD.bazel b/googleapis/iam/credentials/v1/BUILD.bazel ---- a/googleapis/iam/credentials/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/iam/credentials/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/iam/credentials/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10534,7 +10358,7 @@ diff -urN a/googleapis/iam/credentials/v1/BUILD.bazel b/googleapis/iam/credentia + visibility = ["//visibility:public"], +) diff -urN a/googleapis/iam/v1/BUILD.bazel b/googleapis/iam/v1/BUILD.bazel ---- a/googleapis/iam/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/iam/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/iam/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10556,7 +10380,7 @@ diff -urN a/googleapis/iam/v1/BUILD.bazel b/googleapis/iam/v1/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/iam/v1/logging/BUILD.bazel b/googleapis/iam/v1/logging/BUILD.bazel ---- a/googleapis/iam/v1/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/iam/v1/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/iam/v1/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10579,7 +10403,7 @@ diff -urN a/googleapis/iam/v1/logging/BUILD.bazel b/googleapis/iam/v1/logging/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/iam/v1beta/BUILD.bazel b/googleapis/iam/v1beta/BUILD.bazel ---- a/googleapis/iam/v1beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/iam/v1beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/iam/v1beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10607,7 +10431,7 @@ diff -urN a/googleapis/iam/v1beta/BUILD.bazel b/googleapis/iam/v1beta/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/iam/v2/BUILD.bazel b/googleapis/iam/v2/BUILD.bazel ---- a/googleapis/iam/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/iam/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/iam/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10629,7 +10453,7 @@ diff -urN a/googleapis/iam/v2/BUILD.bazel b/googleapis/iam/v2/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/iam/v2beta/BUILD.bazel b/googleapis/iam/v2beta/BUILD.bazel ---- a/googleapis/iam/v2beta/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/iam/v2beta/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/iam/v2beta/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10661,7 +10485,7 @@ diff -urN a/googleapis/iam/v2beta/BUILD.bazel b/googleapis/iam/v2beta/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/identity/accesscontextmanager/type/BUILD.bazel b/googleapis/identity/accesscontextmanager/type/BUILD.bazel ---- a/googleapis/identity/accesscontextmanager/type/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/identity/accesscontextmanager/type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/identity/accesscontextmanager/type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10683,7 +10507,7 @@ diff -urN a/googleapis/identity/accesscontextmanager/type/BUILD.bazel b/googleap + visibility = ["//visibility:public"], +) diff -urN a/googleapis/identity/accesscontextmanager/v1/BUILD.bazel b/googleapis/identity/accesscontextmanager/v1/BUILD.bazel ---- a/googleapis/identity/accesscontextmanager/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/identity/accesscontextmanager/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/identity/accesscontextmanager/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10705,7 +10529,7 @@ diff -urN a/googleapis/identity/accesscontextmanager/v1/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/logging/type/BUILD.bazel b/googleapis/logging/type/BUILD.bazel ---- a/googleapis/logging/type/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/logging/type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/logging/type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10731,7 +10555,7 @@ diff -urN a/googleapis/logging/type/BUILD.bazel b/googleapis/logging/type/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/logging/v2/BUILD.bazel b/googleapis/logging/v2/BUILD.bazel ---- a/googleapis/logging/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/logging/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/logging/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10753,7 +10577,7 @@ diff -urN a/googleapis/logging/v2/BUILD.bazel b/googleapis/logging/v2/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/longrunning/BUILD.bazel b/googleapis/longrunning/BUILD.bazel ---- a/googleapis/longrunning/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/longrunning/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/longrunning/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10775,7 +10599,7 @@ diff -urN a/googleapis/longrunning/BUILD.bazel b/googleapis/longrunning/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/addressvalidation/v1/BUILD.bazel b/googleapis/maps/addressvalidation/v1/BUILD.bazel ---- a/googleapis/maps/addressvalidation/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/addressvalidation/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/addressvalidation/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10797,7 +10621,7 @@ diff -urN a/googleapis/maps/addressvalidation/v1/BUILD.bazel b/googleapis/maps/a + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/fleetengine/delivery/v1/BUILD.bazel b/googleapis/maps/fleetengine/delivery/v1/BUILD.bazel ---- a/googleapis/maps/fleetengine/delivery/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/fleetengine/delivery/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/fleetengine/delivery/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10836,7 +10660,7 @@ diff -urN a/googleapis/maps/fleetengine/delivery/v1/BUILD.bazel b/googleapis/map + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/fleetengine/v1/BUILD.bazel b/googleapis/maps/fleetengine/v1/BUILD.bazel ---- a/googleapis/maps/fleetengine/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/fleetengine/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/fleetengine/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10876,7 +10700,7 @@ diff -urN a/googleapis/maps/fleetengine/v1/BUILD.bazel b/googleapis/maps/fleeten + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/playablelocations/v3/BUILD.bazel b/googleapis/maps/playablelocations/v3/BUILD.bazel ---- a/googleapis/maps/playablelocations/v3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/playablelocations/v3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/playablelocations/v3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10908,7 +10732,7 @@ diff -urN a/googleapis/maps/playablelocations/v3/BUILD.bazel b/googleapis/maps/p + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/playablelocations/v3/sample/BUILD.bazel b/googleapis/maps/playablelocations/v3/sample/BUILD.bazel ---- a/googleapis/maps/playablelocations/v3/sample/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/playablelocations/v3/sample/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/playablelocations/v3/sample/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10933,7 +10757,7 @@ diff -urN a/googleapis/maps/playablelocations/v3/sample/BUILD.bazel b/googleapis + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/regionlookup/v1alpha/BUILD.bazel b/googleapis/maps/regionlookup/v1alpha/BUILD.bazel ---- a/googleapis/maps/regionlookup/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/regionlookup/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/regionlookup/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10965,7 +10789,7 @@ diff -urN a/googleapis/maps/regionlookup/v1alpha/BUILD.bazel b/googleapis/maps/r + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/roads/v1op/BUILD.bazel b/googleapis/maps/roads/v1op/BUILD.bazel ---- a/googleapis/maps/roads/v1op/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/roads/v1op/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/roads/v1op/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -10993,7 +10817,7 @@ diff -urN a/googleapis/maps/roads/v1op/BUILD.bazel b/googleapis/maps/roads/v1op/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/routes/v1/BUILD.bazel b/googleapis/maps/routes/v1/BUILD.bazel ---- a/googleapis/maps/routes/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/routes/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/routes/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11042,7 +10866,7 @@ diff -urN a/googleapis/maps/routes/v1/BUILD.bazel b/googleapis/maps/routes/v1/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/routes/v1alpha/BUILD.bazel b/googleapis/maps/routes/v1alpha/BUILD.bazel ---- a/googleapis/maps/routes/v1alpha/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/routes/v1alpha/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/routes/v1alpha/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11069,7 +10893,7 @@ diff -urN a/googleapis/maps/routes/v1alpha/BUILD.bazel b/googleapis/maps/routes/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/routing/v2/BUILD.bazel b/googleapis/maps/routing/v2/BUILD.bazel ---- a/googleapis/maps/routing/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/routing/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/routing/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11091,7 +10915,7 @@ diff -urN a/googleapis/maps/routing/v2/BUILD.bazel b/googleapis/maps/routing/v2/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/maps/unity/BUILD.bazel b/googleapis/maps/unity/BUILD.bazel ---- a/googleapis/maps/unity/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/maps/unity/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/maps/unity/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11113,7 +10937,7 @@ diff -urN a/googleapis/maps/unity/BUILD.bazel b/googleapis/maps/unity/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/monitoring/dashboard/v1/BUILD.bazel b/googleapis/monitoring/dashboard/v1/BUILD.bazel ---- a/googleapis/monitoring/dashboard/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/monitoring/dashboard/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/monitoring/dashboard/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11135,7 +10959,7 @@ diff -urN a/googleapis/monitoring/dashboard/v1/BUILD.bazel b/googleapis/monitori + visibility = ["//visibility:public"], +) diff -urN a/googleapis/monitoring/metricsscope/v1/BUILD.bazel b/googleapis/monitoring/metricsscope/v1/BUILD.bazel ---- a/googleapis/monitoring/metricsscope/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/monitoring/metricsscope/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/monitoring/metricsscope/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11157,7 +10981,7 @@ diff -urN a/googleapis/monitoring/metricsscope/v1/BUILD.bazel b/googleapis/monit + visibility = ["//visibility:public"], +) diff -urN a/googleapis/monitoring/v3/BUILD.bazel b/googleapis/monitoring/v3/BUILD.bazel ---- a/googleapis/monitoring/v3/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/monitoring/v3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/monitoring/v3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11179,7 +11003,7 @@ diff -urN a/googleapis/monitoring/v3/BUILD.bazel b/googleapis/monitoring/v3/BUIL + visibility = ["//visibility:public"], +) diff -urN a/googleapis/networking/trafficdirector/type/BUILD.bazel b/googleapis/networking/trafficdirector/type/BUILD.bazel ---- a/googleapis/networking/trafficdirector/type/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/networking/trafficdirector/type/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/networking/trafficdirector/type/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11201,7 +11025,7 @@ diff -urN a/googleapis/networking/trafficdirector/type/BUILD.bazel b/googleapis/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/partner/aistreams/v1alpha1/BUILD.bazel b/googleapis/partner/aistreams/v1alpha1/BUILD.bazel ---- a/googleapis/partner/aistreams/v1alpha1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/partner/aistreams/v1alpha1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/partner/aistreams/v1alpha1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11230,7 +11054,7 @@ diff -urN a/googleapis/partner/aistreams/v1alpha1/BUILD.bazel b/googleapis/partn + visibility = ["//visibility:public"], +) diff -urN a/googleapis/privacy/dlp/v2/BUILD.bazel b/googleapis/privacy/dlp/v2/BUILD.bazel ---- a/googleapis/privacy/dlp/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/privacy/dlp/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/privacy/dlp/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11252,7 +11076,7 @@ diff -urN a/googleapis/privacy/dlp/v2/BUILD.bazel b/googleapis/privacy/dlp/v2/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/pubsub/v1/BUILD.bazel b/googleapis/pubsub/v1/BUILD.bazel ---- a/googleapis/pubsub/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/pubsub/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/pubsub/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11274,7 +11098,7 @@ diff -urN a/googleapis/pubsub/v1/BUILD.bazel b/googleapis/pubsub/v1/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/pubsub/v1beta2/BUILD.bazel b/googleapis/pubsub/v1beta2/BUILD.bazel ---- a/googleapis/pubsub/v1beta2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/pubsub/v1beta2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/pubsub/v1beta2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11300,7 +11124,7 @@ diff -urN a/googleapis/pubsub/v1beta2/BUILD.bazel b/googleapis/pubsub/v1beta2/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/rpc/code/BUILD.bazel b/googleapis/rpc/code/BUILD.bazel ---- a/googleapis/rpc/code/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/rpc/code/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/rpc/code/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11321,57 +11145,57 @@ diff -urN a/googleapis/rpc/code/BUILD.bazel b/googleapis/rpc/code/BUILD.bazel + actual = ":code", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/rpc/context/BUILD.bazel b/googleapis/rpc/context/BUILD.bazel ---- a/googleapis/rpc/context/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/rpc/context/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,19 @@ +diff -urN a/googleapis/rpc/context/attribute_context/BUILD.bazel b/googleapis/rpc/context/attribute_context/BUILD.bazel +--- a/googleapis/rpc/context/attribute_context/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/googleapis/rpc/context/attribute_context/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "context", -+ srcs = ["audit_context.pb.go"], -+ importpath = "google.golang.org/genproto/googleapis/rpc/context", ++ name = "attribute_context", ++ srcs = ["attribute_context.pb.go"], ++ importpath = "google.golang.org/genproto/googleapis/rpc/context/attribute_context", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", ++ "@org_golang_google_protobuf//types/known/anypb:go_default_library", ++ "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", ++ "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + ], +) + +alias( + name = "go_default_library", -+ actual = ":context", ++ actual = ":attribute_context", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/rpc/context/attribute_context/BUILD.bazel b/googleapis/rpc/context/attribute_context/BUILD.bazel ---- a/googleapis/rpc/context/attribute_context/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/rpc/context/attribute_context/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,22 @@ +diff -urN a/googleapis/rpc/context/BUILD.bazel b/googleapis/rpc/context/BUILD.bazel +--- a/googleapis/rpc/context/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/googleapis/rpc/context/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "attribute_context", -+ srcs = ["attribute_context.pb.go"], -+ importpath = "google.golang.org/genproto/googleapis/rpc/context/attribute_context", ++ name = "context", ++ srcs = ["audit_context.pb.go"], ++ importpath = "google.golang.org/genproto/googleapis/rpc/context", + visibility = ["//visibility:public"], + deps = [ + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", -+ "@org_golang_google_protobuf//types/known/anypb:go_default_library", -+ "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + "@org_golang_google_protobuf//types/known/structpb:go_default_library", -+ "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", + ], +) + +alias( + name = "go_default_library", -+ actual = ":attribute_context", ++ actual = ":context", + visibility = ["//visibility:public"], +) diff -urN a/googleapis/rpc/errdetails/BUILD.bazel b/googleapis/rpc/errdetails/BUILD.bazel ---- a/googleapis/rpc/errdetails/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/rpc/errdetails/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/rpc/errdetails/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11394,7 +11218,7 @@ diff -urN a/googleapis/rpc/errdetails/BUILD.bazel b/googleapis/rpc/errdetails/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/rpc/http/BUILD.bazel b/googleapis/rpc/http/BUILD.bazel ---- a/googleapis/rpc/http/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/rpc/http/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/rpc/http/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11416,7 +11240,7 @@ diff -urN a/googleapis/rpc/http/BUILD.bazel b/googleapis/rpc/http/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/rpc/status/BUILD.bazel b/googleapis/rpc/status/BUILD.bazel ---- a/googleapis/rpc/status/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/rpc/status/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/rpc/status/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11439,7 +11263,7 @@ diff -urN a/googleapis/rpc/status/BUILD.bazel b/googleapis/rpc/status/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/search/partnerdataingestion/logging/v1/BUILD.bazel b/googleapis/search/partnerdataingestion/logging/v1/BUILD.bazel ---- a/googleapis/search/partnerdataingestion/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/search/partnerdataingestion/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/search/partnerdataingestion/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11461,7 +11285,7 @@ diff -urN a/googleapis/search/partnerdataingestion/logging/v1/BUILD.bazel b/goog + visibility = ["//visibility:public"], +) diff -urN a/googleapis/spanner/admin/database/v1/BUILD.bazel b/googleapis/spanner/admin/database/v1/BUILD.bazel ---- a/googleapis/spanner/admin/database/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/spanner/admin/database/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/spanner/admin/database/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11483,7 +11307,7 @@ diff -urN a/googleapis/spanner/admin/database/v1/BUILD.bazel b/googleapis/spanne + visibility = ["//visibility:public"], +) diff -urN a/googleapis/spanner/admin/instance/v1/BUILD.bazel b/googleapis/spanner/admin/instance/v1/BUILD.bazel ---- a/googleapis/spanner/admin/instance/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/spanner/admin/instance/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/spanner/admin/instance/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11505,7 +11329,7 @@ diff -urN a/googleapis/spanner/admin/instance/v1/BUILD.bazel b/googleapis/spanne + visibility = ["//visibility:public"], +) diff -urN a/googleapis/spanner/v1/BUILD.bazel b/googleapis/spanner/v1/BUILD.bazel ---- a/googleapis/spanner/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/spanner/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/spanner/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11527,7 +11351,7 @@ diff -urN a/googleapis/spanner/v1/BUILD.bazel b/googleapis/spanner/v1/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/storage/clouddms/logging/v1/BUILD.bazel b/googleapis/storage/clouddms/logging/v1/BUILD.bazel ---- a/googleapis/storage/clouddms/logging/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/storage/clouddms/logging/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/storage/clouddms/logging/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11552,7 +11376,7 @@ diff -urN a/googleapis/storage/clouddms/logging/v1/BUILD.bazel b/googleapis/stor + visibility = ["//visibility:public"], +) diff -urN a/googleapis/storage/v1/BUILD.bazel b/googleapis/storage/v1/BUILD.bazel ---- a/googleapis/storage/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/storage/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/storage/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11586,7 +11410,7 @@ diff -urN a/googleapis/storage/v1/BUILD.bazel b/googleapis/storage/v1/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/storage/v2/BUILD.bazel b/googleapis/storage/v2/BUILD.bazel ---- a/googleapis/storage/v2/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/storage/v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/storage/v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11620,7 +11444,7 @@ diff -urN a/googleapis/storage/v2/BUILD.bazel b/googleapis/storage/v2/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/storagetransfer/logging/BUILD.bazel b/googleapis/storagetransfer/logging/BUILD.bazel ---- a/googleapis/storagetransfer/logging/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/storagetransfer/logging/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/storagetransfer/logging/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11644,7 +11468,7 @@ diff -urN a/googleapis/storagetransfer/logging/BUILD.bazel b/googleapis/storaget + visibility = ["//visibility:public"], +) diff -urN a/googleapis/storagetransfer/v1/BUILD.bazel b/googleapis/storagetransfer/v1/BUILD.bazel ---- a/googleapis/storagetransfer/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/storagetransfer/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/storagetransfer/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11666,7 +11490,7 @@ diff -urN a/googleapis/storagetransfer/v1/BUILD.bazel b/googleapis/storagetransf + visibility = ["//visibility:public"], +) diff -urN a/googleapis/streetview/publish/v1/BUILD.bazel b/googleapis/streetview/publish/v1/BUILD.bazel ---- a/googleapis/streetview/publish/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/streetview/publish/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/streetview/publish/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11703,7 +11527,7 @@ diff -urN a/googleapis/streetview/publish/v1/BUILD.bazel b/googleapis/streetview + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/calendarperiod/BUILD.bazel b/googleapis/type/calendarperiod/BUILD.bazel ---- a/googleapis/type/calendarperiod/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/calendarperiod/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/calendarperiod/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11725,7 +11549,7 @@ diff -urN a/googleapis/type/calendarperiod/BUILD.bazel b/googleapis/type/calenda + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/color/BUILD.bazel b/googleapis/type/color/BUILD.bazel ---- a/googleapis/type/color/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/color/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/color/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11748,7 +11572,7 @@ diff -urN a/googleapis/type/color/BUILD.bazel b/googleapis/type/color/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/date/BUILD.bazel b/googleapis/type/date/BUILD.bazel ---- a/googleapis/type/date/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/date/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/date/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11770,7 +11594,7 @@ diff -urN a/googleapis/type/date/BUILD.bazel b/googleapis/type/date/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/date_range/BUILD.bazel b/googleapis/type/date_range/BUILD.bazel ---- a/googleapis/type/date_range/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/date_range/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/date_range/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11792,54 +11616,54 @@ diff -urN a/googleapis/type/date_range/BUILD.bazel b/googleapis/type/date_range/ + actual = ":date_range", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/type/date_time_range/BUILD.bazel b/googleapis/type/date_time_range/BUILD.bazel ---- a/googleapis/type/date_time_range/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/type/date_time_range/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +diff -urN a/googleapis/type/datetime/BUILD.bazel b/googleapis/type/datetime/BUILD.bazel +--- a/googleapis/type/datetime/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/googleapis/type/datetime/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "date_time_range", -+ srcs = ["datetime_range.pb.go"], -+ importpath = "google.golang.org/genproto/googleapis/type/date_time_range", ++ name = "datetime", ++ srcs = ["datetime.pb.go"], ++ importpath = "google.golang.org/genproto/googleapis/type/datetime", + visibility = ["//visibility:public"], + deps = [ -+ "//googleapis/type/datetime", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", ++ "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + ], +) + +alias( + name = "go_default_library", -+ actual = ":date_time_range", ++ actual = ":datetime", + visibility = ["//visibility:public"], +) -diff -urN a/googleapis/type/datetime/BUILD.bazel b/googleapis/type/datetime/BUILD.bazel ---- a/googleapis/type/datetime/BUILD.bazel 1969-12-31 16:00:00 -+++ b/googleapis/type/datetime/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +diff -urN a/googleapis/type/date_time_range/BUILD.bazel b/googleapis/type/date_time_range/BUILD.bazel +--- a/googleapis/type/date_time_range/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/googleapis/type/date_time_range/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( -+ name = "datetime", -+ srcs = ["datetime.pb.go"], -+ importpath = "google.golang.org/genproto/googleapis/type/datetime", ++ name = "date_time_range", ++ srcs = ["datetime_range.pb.go"], ++ importpath = "google.golang.org/genproto/googleapis/type/date_time_range", + visibility = ["//visibility:public"], + deps = [ ++ "//googleapis/type/datetime", + "@org_golang_google_protobuf//reflect/protoreflect:go_default_library", + "@org_golang_google_protobuf//runtime/protoimpl:go_default_library", -+ "@org_golang_google_protobuf//types/known/durationpb:go_default_library", + ], +) + +alias( + name = "go_default_library", -+ actual = ":datetime", ++ actual = ":date_time_range", + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/dayofweek/BUILD.bazel b/googleapis/type/dayofweek/BUILD.bazel ---- a/googleapis/type/dayofweek/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/dayofweek/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/dayofweek/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11861,7 +11685,7 @@ diff -urN a/googleapis/type/dayofweek/BUILD.bazel b/googleapis/type/dayofweek/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/decimal/BUILD.bazel b/googleapis/type/decimal/BUILD.bazel ---- a/googleapis/type/decimal/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/decimal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/decimal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11883,7 +11707,7 @@ diff -urN a/googleapis/type/decimal/BUILD.bazel b/googleapis/type/decimal/BUILD. + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/expr/BUILD.bazel b/googleapis/type/expr/BUILD.bazel ---- a/googleapis/type/expr/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/expr/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/expr/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11905,7 +11729,7 @@ diff -urN a/googleapis/type/expr/BUILD.bazel b/googleapis/type/expr/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/fraction/BUILD.bazel b/googleapis/type/fraction/BUILD.bazel ---- a/googleapis/type/fraction/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/fraction/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/fraction/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11927,7 +11751,7 @@ diff -urN a/googleapis/type/fraction/BUILD.bazel b/googleapis/type/fraction/BUIL + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/interval/BUILD.bazel b/googleapis/type/interval/BUILD.bazel ---- a/googleapis/type/interval/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/interval/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/interval/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11950,7 +11774,7 @@ diff -urN a/googleapis/type/interval/BUILD.bazel b/googleapis/type/interval/BUIL + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/latlng/BUILD.bazel b/googleapis/type/latlng/BUILD.bazel ---- a/googleapis/type/latlng/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/latlng/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/latlng/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11972,7 +11796,7 @@ diff -urN a/googleapis/type/latlng/BUILD.bazel b/googleapis/type/latlng/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/localized_text/BUILD.bazel b/googleapis/type/localized_text/BUILD.bazel ---- a/googleapis/type/localized_text/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/localized_text/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/localized_text/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -11994,7 +11818,7 @@ diff -urN a/googleapis/type/localized_text/BUILD.bazel b/googleapis/type/localiz + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/money/BUILD.bazel b/googleapis/type/money/BUILD.bazel ---- a/googleapis/type/money/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/money/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/money/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12016,7 +11840,7 @@ diff -urN a/googleapis/type/money/BUILD.bazel b/googleapis/type/money/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/month/BUILD.bazel b/googleapis/type/month/BUILD.bazel ---- a/googleapis/type/month/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/month/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/month/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12038,7 +11862,7 @@ diff -urN a/googleapis/type/month/BUILD.bazel b/googleapis/type/month/BUILD.baze + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/phone_number/BUILD.bazel b/googleapis/type/phone_number/BUILD.bazel ---- a/googleapis/type/phone_number/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/phone_number/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/phone_number/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12060,7 +11884,7 @@ diff -urN a/googleapis/type/phone_number/BUILD.bazel b/googleapis/type/phone_num + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/postaladdress/BUILD.bazel b/googleapis/type/postaladdress/BUILD.bazel ---- a/googleapis/type/postaladdress/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/postaladdress/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/postaladdress/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12082,7 +11906,7 @@ diff -urN a/googleapis/type/postaladdress/BUILD.bazel b/googleapis/type/postalad + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/quaternion/BUILD.bazel b/googleapis/type/quaternion/BUILD.bazel ---- a/googleapis/type/quaternion/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/quaternion/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/quaternion/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12104,7 +11928,7 @@ diff -urN a/googleapis/type/quaternion/BUILD.bazel b/googleapis/type/quaternion/ + visibility = ["//visibility:public"], +) diff -urN a/googleapis/type/timeofday/BUILD.bazel b/googleapis/type/timeofday/BUILD.bazel ---- a/googleapis/type/timeofday/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/type/timeofday/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/type/timeofday/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12126,7 +11950,7 @@ diff -urN a/googleapis/type/timeofday/BUILD.bazel b/googleapis/type/timeofday/BU + visibility = ["//visibility:public"], +) diff -urN a/googleapis/watcher/v1/BUILD.bazel b/googleapis/watcher/v1/BUILD.bazel ---- a/googleapis/watcher/v1/BUILD.bazel 1969-12-31 16:00:00 +--- a/googleapis/watcher/v1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/googleapis/watcher/v1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12153,8 +11977,44 @@ diff -urN a/googleapis/watcher/v1/BUILD.bazel b/googleapis/watcher/v1/BUILD.baze + actual = ":watcher", + visibility = ["//visibility:public"], +) +diff -urN a/internal/actions/cmd/changefinder/BUILD.bazel b/internal/actions/cmd/changefinder/BUILD.bazel +--- a/internal/actions/cmd/changefinder/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/internal/actions/cmd/changefinder/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") ++ ++go_library( ++ name = "changefinder_lib", ++ srcs = ["main.go"], ++ importpath = "google.golang.org/genproto/internal/actions/cmd/changefinder", ++ visibility = ["//visibility:private"], ++) ++ ++go_binary( ++ name = "changefinder", ++ embed = [":changefinder_lib"], ++ visibility = ["//:__subpackages__"], ++) +diff -urN a/internal/actions/logg/BUILD.bazel b/internal/actions/logg/BUILD.bazel +--- a/internal/actions/logg/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/internal/actions/logg/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "logg", ++ srcs = ["logg.go"], ++ importpath = "google.golang.org/genproto/internal/actions/logg", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":logg", ++ visibility = ["//:__subpackages__"], ++) diff -urN a/internal/BUILD.bazel b/internal/BUILD.bazel ---- a/internal/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12172,7 +12032,7 @@ diff -urN a/internal/BUILD.bazel b/internal/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/protobuf/api/BUILD.bazel b/protobuf/api/BUILD.bazel ---- a/protobuf/api/BUILD.bazel 1969-12-31 16:00:00 +--- a/protobuf/api/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protobuf/api/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12191,7 +12051,7 @@ diff -urN a/protobuf/api/BUILD.bazel b/protobuf/api/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protobuf/field_mask/BUILD.bazel b/protobuf/field_mask/BUILD.bazel ---- a/protobuf/field_mask/BUILD.bazel 1969-12-31 16:00:00 +--- a/protobuf/field_mask/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protobuf/field_mask/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12210,7 +12070,7 @@ diff -urN a/protobuf/field_mask/BUILD.bazel b/protobuf/field_mask/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protobuf/ptype/BUILD.bazel b/protobuf/ptype/BUILD.bazel ---- a/protobuf/ptype/BUILD.bazel 1969-12-31 16:00:00 +--- a/protobuf/ptype/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protobuf/ptype/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -12229,7 +12089,7 @@ diff -urN a/protobuf/ptype/BUILD.bazel b/protobuf/ptype/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/protobuf/source_context/BUILD.bazel b/protobuf/source_context/BUILD.bazel ---- a/protobuf/source_context/BUILD.bazel 1969-12-31 16:00:00 +--- a/protobuf/source_context/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protobuf/source_context/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/third_party/org_golang_google_protobuf-gazelle.patch b/third_party/org_golang_google_protobuf-gazelle.patch index fa248008e9..27f75c572f 100644 --- a/third_party/org_golang_google_protobuf-gazelle.patch +++ b/third_party/org_golang_google_protobuf-gazelle.patch @@ -1,7 +1,7 @@ diff -urN a/cmd/protoc-gen-go/BUILD.bazel b/cmd/protoc-gen-go/BUILD.bazel ---- a/cmd/protoc-gen-go/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,36 @@ +@@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -35,11 +35,13 @@ diff -urN a/cmd/protoc-gen-go/BUILD.bazel b/cmd/protoc-gen-go/BUILD.bazel + "//internal/genid", + "//proto", + "//reflect/protoreflect", ++ "//testing/protocmp", + "//types/descriptorpb", ++ "@com_github_google_go_cmp//cmp:go_default_library", + ], +) diff -urN a/cmd/protoc-gen-go/internal_gengo/BUILD.bazel b/cmd/protoc-gen-go/internal_gengo/BUILD.bazel ---- a/cmd/protoc-gen-go/internal_gengo/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/internal_gengo/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/internal_gengo/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -75,8 +77,31 @@ diff -urN a/cmd/protoc-gen-go/internal_gengo/BUILD.bazel b/cmd/protoc-gen-go/int + actual = ":internal_gengo", + visibility = ["//visibility:public"], +) +diff -urN a/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel b/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel +--- a/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,19 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "annotations", ++ srcs = ["annotations.pb.go"], ++ importpath = "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/annotations", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "//proto", ++ "//reflect/protoreflect", ++ "//runtime/protoimpl", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":annotations", ++ visibility = ["//visibility:public"], ++) diff -urN a/cmd/protoc-gen-go/testdata/BUILD.bazel b/cmd/protoc-gen-go/testdata/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -113,30 +138,8 @@ diff -urN a/cmd/protoc-gen-go/testdata/BUILD.bazel b/cmd/protoc-gen-go/testdata/ + "//reflect/protoregistry", + ], +) -diff -urN a/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel b/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel 1969-12-31 16:00:00 -+++ b/cmd/protoc-gen-go/testdata/annotations/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") -+ -+go_library( -+ name = "annotations", -+ srcs = ["annotations.pb.go"], -+ importpath = "google.golang.org/protobuf/cmd/protoc-gen-go/testdata/annotations", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "//reflect/protoreflect", -+ "//runtime/protoimpl", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":annotations", -+ visibility = ["//visibility:public"], -+) diff -urN a/cmd/protoc-gen-go/testdata/comments/BUILD.bazel b/cmd/protoc-gen-go/testdata/comments/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/comments/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/comments/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/comments/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -161,7 +164,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/comments/BUILD.bazel b/cmd/protoc-gen-go/ + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/extensions/base/BUILD.bazel b/cmd/protoc-gen-go/testdata/extensions/base/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/extensions/base/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/extensions/base/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/extensions/base/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -183,7 +186,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/extensions/base/BUILD.bazel b/cmd/protoc- + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/extensions/ext/BUILD.bazel b/cmd/protoc-gen-go/testdata/extensions/ext/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/extensions/ext/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/extensions/ext/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/extensions/ext/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -207,7 +210,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/extensions/ext/BUILD.bazel b/cmd/protoc-g + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/extensions/extra/BUILD.bazel b/cmd/protoc-gen-go/testdata/extensions/extra/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/extensions/extra/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/extensions/extra/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/extensions/extra/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -229,7 +232,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/extensions/extra/BUILD.bazel b/cmd/protoc + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/extensions/proto3/BUILD.bazel b/cmd/protoc-gen-go/testdata/extensions/proto3/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/extensions/proto3/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/extensions/proto3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/extensions/proto3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -252,7 +255,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/extensions/proto3/BUILD.bazel b/cmd/proto + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/fieldnames/BUILD.bazel b/cmd/protoc-gen-go/testdata/fieldnames/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/fieldnames/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/fieldnames/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/fieldnames/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -274,7 +277,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/fieldnames/BUILD.bazel b/cmd/protoc-gen-g + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/import_public/BUILD.bazel b/cmd/protoc-gen-go/testdata/import_public/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/import_public/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/import_public/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/import_public/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -302,7 +305,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/import_public/BUILD.bazel b/cmd/protoc-ge + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/import_public/sub/BUILD.bazel b/cmd/protoc-gen-go/testdata/import_public/sub/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/import_public/sub/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/import_public/sub/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/import_public/sub/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -328,7 +331,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/import_public/sub/BUILD.bazel b/cmd/proto + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/import_public/sub2/BUILD.bazel b/cmd/protoc-gen-go/testdata/import_public/sub2/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/import_public/sub2/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/import_public/sub2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/import_public/sub2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -350,7 +353,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/import_public/sub2/BUILD.bazel b/cmd/prot + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/imports/BUILD.bazel b/cmd/protoc-gen-go/testdata/imports/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/imports/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/imports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/imports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -380,7 +383,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/imports/BUILD.bazel b/cmd/protoc-gen-go/t + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/imports/fmt/BUILD.bazel b/cmd/protoc-gen-go/testdata/imports/fmt/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/imports/fmt/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/imports/fmt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/imports/fmt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -402,7 +405,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/imports/fmt/BUILD.bazel b/cmd/protoc-gen- + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/imports/test_a_1/BUILD.bazel b/cmd/protoc-gen-go/testdata/imports/test_a_1/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/imports/test_a_1/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/imports/test_a_1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/imports/test_a_1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -427,7 +430,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/imports/test_a_1/BUILD.bazel b/cmd/protoc + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/imports/test_a_2/BUILD.bazel b/cmd/protoc-gen-go/testdata/imports/test_a_2/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/imports/test_a_2/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/imports/test_a_2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/imports/test_a_2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -452,7 +455,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/imports/test_a_2/BUILD.bazel b/cmd/protoc + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/imports/test_b_1/BUILD.bazel b/cmd/protoc-gen-go/testdata/imports/test_b_1/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/imports/test_b_1/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/imports/test_b_1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/imports/test_b_1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -477,7 +480,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/imports/test_b_1/BUILD.bazel b/cmd/protoc + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/BUILD.bazel b/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -499,7 +502,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/issue780_oneof_conflict/BUILD.bazel b/cmd + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/nopackage/BUILD.bazel b/cmd/protoc-gen-go/testdata/nopackage/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/nopackage/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/nopackage/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/nopackage/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -521,7 +524,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/nopackage/BUILD.bazel b/cmd/protoc-gen-go + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/proto2/BUILD.bazel b/cmd/protoc-gen-go/testdata/proto2/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/proto2/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/proto2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/proto2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -548,7 +551,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/proto2/BUILD.bazel b/cmd/protoc-gen-go/te + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/proto3/BUILD.bazel b/cmd/protoc-gen-go/testdata/proto3/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/proto3/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/proto3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/proto3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -573,7 +576,7 @@ diff -urN a/cmd/protoc-gen-go/testdata/proto3/BUILD.bazel b/cmd/protoc-gen-go/te + visibility = ["//visibility:public"], +) diff -urN a/cmd/protoc-gen-go/testdata/retention/BUILD.bazel b/cmd/protoc-gen-go/testdata/retention/BUILD.bazel ---- a/cmd/protoc-gen-go/testdata/retention/BUILD.bazel 1969-12-31 16:00:00 +--- a/cmd/protoc-gen-go/testdata/retention/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cmd/protoc-gen-go/testdata/retention/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -599,9 +602,9 @@ diff -urN a/cmd/protoc-gen-go/testdata/retention/BUILD.bazel b/cmd/protoc-gen-go + visibility = ["//visibility:public"], +) diff -urN a/compiler/protogen/BUILD.bazel b/compiler/protogen/BUILD.bazel ---- a/compiler/protogen/BUILD.bazel 1969-12-31 16:00:00 +--- a/compiler/protogen/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/compiler/protogen/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,39 @@ +@@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -634,15 +637,17 @@ diff -urN a/compiler/protogen/BUILD.bazel b/compiler/protogen/BUILD.bazel + srcs = ["protogen_test.go"], + embed = [":protogen"], + deps = [ ++ "//internal/genid", + "//proto", + "//reflect/protoreflect", ++ "//testing/protocmp", + "//types/descriptorpb", + "//types/pluginpb", + "@com_github_google_go_cmp//cmp:go_default_library", + ], +) diff -urN a/encoding/BUILD.bazel b/encoding/BUILD.bazel ---- a/encoding/BUILD.bazel 1969-12-31 16:00:00 +--- a/encoding/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/encoding/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -658,7 +663,7 @@ diff -urN a/encoding/BUILD.bazel b/encoding/BUILD.bazel + ], +) diff -urN a/encoding/protodelim/BUILD.bazel b/encoding/protodelim/BUILD.bazel ---- a/encoding/protodelim/BUILD.bazel 1969-12-31 16:00:00 +--- a/encoding/protodelim/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/encoding/protodelim/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -693,7 +698,7 @@ diff -urN a/encoding/protodelim/BUILD.bazel b/encoding/protodelim/BUILD.bazel + ], +) diff -urN a/encoding/protojson/BUILD.bazel b/encoding/protojson/BUILD.bazel ---- a/encoding/protojson/BUILD.bazel 1969-12-31 16:00:00 +--- a/encoding/protojson/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/encoding/protojson/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,64 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -761,7 +766,7 @@ diff -urN a/encoding/protojson/BUILD.bazel b/encoding/protojson/BUILD.bazel + ], +) diff -urN a/encoding/prototext/BUILD.bazel b/encoding/prototext/BUILD.bazel ---- a/encoding/prototext/BUILD.bazel 1969-12-31 16:00:00 +--- a/encoding/prototext/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/encoding/prototext/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,61 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -826,7 +831,7 @@ diff -urN a/encoding/prototext/BUILD.bazel b/encoding/prototext/BUILD.bazel + ], +) diff -urN a/encoding/protowire/BUILD.bazel b/encoding/protowire/BUILD.bazel ---- a/encoding/protowire/BUILD.bazel 1969-12-31 16:00:00 +--- a/encoding/protowire/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/encoding/protowire/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -851,7 +856,7 @@ diff -urN a/encoding/protowire/BUILD.bazel b/encoding/protowire/BUILD.bazel + embed = [":protowire"], +) diff -urN a/internal/benchmarks/BUILD.bazel b/internal/benchmarks/BUILD.bazel ---- a/internal/benchmarks/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/benchmarks/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/benchmarks/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -874,7 +879,7 @@ diff -urN a/internal/benchmarks/BUILD.bazel b/internal/benchmarks/BUILD.bazel + ], +) diff -urN a/internal/benchmarks/micro/BUILD.bazel b/internal/benchmarks/micro/BUILD.bazel ---- a/internal/benchmarks/micro/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/benchmarks/micro/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/benchmarks/micro/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -892,7 +897,7 @@ diff -urN a/internal/benchmarks/micro/BUILD.bazel b/internal/benchmarks/micro/BU + ], +) diff -urN a/internal/cmd/generate-corpus/BUILD.bazel b/internal/cmd/generate-corpus/BUILD.bazel ---- a/internal/cmd/generate-corpus/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/cmd/generate-corpus/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/cmd/generate-corpus/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -917,7 +922,7 @@ diff -urN a/internal/cmd/generate-corpus/BUILD.bazel b/internal/cmd/generate-cor + visibility = ["//:__subpackages__"], +) diff -urN a/internal/cmd/generate-protos/BUILD.bazel b/internal/cmd/generate-protos/BUILD.bazel ---- a/internal/cmd/generate-protos/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/cmd/generate-protos/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/cmd/generate-protos/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -940,7 +945,7 @@ diff -urN a/internal/cmd/generate-protos/BUILD.bazel b/internal/cmd/generate-pro + visibility = ["//:__subpackages__"], +) diff -urN a/internal/cmd/generate-types/BUILD.bazel b/internal/cmd/generate-types/BUILD.bazel ---- a/internal/cmd/generate-types/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/cmd/generate-types/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/cmd/generate-types/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -962,7 +967,7 @@ diff -urN a/internal/cmd/generate-types/BUILD.bazel b/internal/cmd/generate-type + visibility = ["//:__subpackages__"], +) diff -urN a/internal/cmd/pbdump/BUILD.bazel b/internal/cmd/pbdump/BUILD.bazel ---- a/internal/cmd/pbdump/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/cmd/pbdump/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/cmd/pbdump/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -1001,7 +1006,7 @@ diff -urN a/internal/cmd/pbdump/BUILD.bazel b/internal/cmd/pbdump/BUILD.bazel + ], +) diff -urN a/internal/conformance/BUILD.bazel b/internal/conformance/BUILD.bazel ---- a/internal/conformance/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/conformance/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/conformance/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,12 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_test") @@ -1017,7 +1022,7 @@ diff -urN a/internal/conformance/BUILD.bazel b/internal/conformance/BUILD.bazel + ], +) diff -urN a/internal/descfmt/BUILD.bazel b/internal/descfmt/BUILD.bazel ---- a/internal/descfmt/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/descfmt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/descfmt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1046,7 +1051,7 @@ diff -urN a/internal/descfmt/BUILD.bazel b/internal/descfmt/BUILD.bazel + embed = [":descfmt"], +) diff -urN a/internal/descopts/BUILD.bazel b/internal/descopts/BUILD.bazel ---- a/internal/descopts/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/descopts/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/descopts/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1065,7 +1070,7 @@ diff -urN a/internal/descopts/BUILD.bazel b/internal/descopts/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/detrand/BUILD.bazel b/internal/detrand/BUILD.bazel ---- a/internal/detrand/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/detrand/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/detrand/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1089,7 +1094,7 @@ diff -urN a/internal/detrand/BUILD.bazel b/internal/detrand/BUILD.bazel + embed = [":detrand"], +) diff -urN a/internal/encoding/defval/BUILD.bazel b/internal/encoding/defval/BUILD.bazel ---- a/internal/encoding/defval/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/encoding/defval/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/encoding/defval/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1122,7 +1127,7 @@ diff -urN a/internal/encoding/defval/BUILD.bazel b/internal/encoding/defval/BUIL + ], +) diff -urN a/internal/encoding/json/BUILD.bazel b/internal/encoding/json/BUILD.bazel ---- a/internal/encoding/json/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/encoding/json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/encoding/json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1166,7 +1171,7 @@ diff -urN a/internal/encoding/json/BUILD.bazel b/internal/encoding/json/BUILD.ba + ], +) diff -urN a/internal/encoding/messageset/BUILD.bazel b/internal/encoding/messageset/BUILD.bazel ---- a/internal/encoding/messageset/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/encoding/messageset/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/encoding/messageset/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1189,7 +1194,7 @@ diff -urN a/internal/encoding/messageset/BUILD.bazel b/internal/encoding/message + visibility = ["//:__subpackages__"], +) diff -urN a/internal/encoding/tag/BUILD.bazel b/internal/encoding/tag/BUILD.bazel ---- a/internal/encoding/tag/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/encoding/tag/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/encoding/tag/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1225,7 +1230,7 @@ diff -urN a/internal/encoding/tag/BUILD.bazel b/internal/encoding/tag/BUILD.baze + ], +) diff -urN a/internal/encoding/text/BUILD.bazel b/internal/encoding/text/BUILD.bazel ---- a/internal/encoding/text/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/encoding/text/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/encoding/text/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,41 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1270,7 +1275,7 @@ diff -urN a/internal/encoding/text/BUILD.bazel b/internal/encoding/text/BUILD.ba + ], +) diff -urN a/internal/errors/BUILD.bazel b/internal/errors/BUILD.bazel ---- a/internal/errors/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/errors/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/errors/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1299,7 +1304,7 @@ diff -urN a/internal/errors/BUILD.bazel b/internal/errors/BUILD.bazel + embed = [":errors"], +) diff -urN a/internal/filedesc/BUILD.bazel b/internal/filedesc/BUILD.bazel ---- a/internal/filedesc/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/filedesc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/filedesc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,55 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1358,7 +1363,7 @@ diff -urN a/internal/filedesc/BUILD.bazel b/internal/filedesc/BUILD.bazel + ], +) diff -urN a/internal/filetype/BUILD.bazel b/internal/filetype/BUILD.bazel ---- a/internal/filetype/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/filetype/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/filetype/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1383,7 +1388,7 @@ diff -urN a/internal/filetype/BUILD.bazel b/internal/filetype/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/flags/BUILD.bazel b/internal/flags/BUILD.bazel ---- a/internal/flags/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/flags/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/flags/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,17 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1404,7 +1409,7 @@ diff -urN a/internal/flags/BUILD.bazel b/internal/flags/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/fuzz/jsonfuzz/BUILD.bazel b/internal/fuzz/jsonfuzz/BUILD.bazel ---- a/internal/fuzz/jsonfuzz/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/fuzz/jsonfuzz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/fuzz/jsonfuzz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1434,7 +1439,7 @@ diff -urN a/internal/fuzz/jsonfuzz/BUILD.bazel b/internal/fuzz/jsonfuzz/BUILD.ba + deps = ["//internal/fuzztest"], +) diff -urN a/internal/fuzz/textfuzz/BUILD.bazel b/internal/fuzz/textfuzz/BUILD.bazel ---- a/internal/fuzz/textfuzz/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/fuzz/textfuzz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/fuzz/textfuzz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,26 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1464,7 +1469,7 @@ diff -urN a/internal/fuzz/textfuzz/BUILD.bazel b/internal/fuzz/textfuzz/BUILD.ba + deps = ["//internal/fuzztest"], +) diff -urN a/internal/fuzz/wirefuzz/BUILD.bazel b/internal/fuzz/wirefuzz/BUILD.bazel ---- a/internal/fuzz/wirefuzz/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/fuzz/wirefuzz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/fuzz/wirefuzz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1496,7 +1501,7 @@ diff -urN a/internal/fuzz/wirefuzz/BUILD.bazel b/internal/fuzz/wirefuzz/BUILD.ba + deps = ["//internal/fuzztest"], +) diff -urN a/internal/fuzztest/BUILD.bazel b/internal/fuzztest/BUILD.bazel ---- a/internal/fuzztest/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/fuzztest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/fuzztest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1514,7 +1519,7 @@ diff -urN a/internal/fuzztest/BUILD.bazel b/internal/fuzztest/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/genid/BUILD.bazel b/internal/genid/BUILD.bazel ---- a/internal/genid/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/genid/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/genid/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1549,7 +1554,7 @@ diff -urN a/internal/genid/BUILD.bazel b/internal/genid/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/impl/BUILD.bazel b/internal/impl/BUILD.bazel ---- a/internal/impl/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/impl/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/impl/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,111 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1664,7 +1669,7 @@ diff -urN a/internal/impl/BUILD.bazel b/internal/impl/BUILD.bazel + ], +) diff -urN a/internal/msgfmt/BUILD.bazel b/internal/msgfmt/BUILD.bazel ---- a/internal/msgfmt/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/msgfmt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/msgfmt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1711,7 +1716,7 @@ diff -urN a/internal/msgfmt/BUILD.bazel b/internal/msgfmt/BUILD.bazel + ], +) diff -urN a/internal/order/BUILD.bazel b/internal/order/BUILD.bazel ---- a/internal/order/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/order/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/order/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1743,7 +1748,7 @@ diff -urN a/internal/order/BUILD.bazel b/internal/order/BUILD.bazel + ], +) diff -urN a/internal/pragma/BUILD.bazel b/internal/pragma/BUILD.bazel ---- a/internal/pragma/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/pragma/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/pragma/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1761,7 +1766,7 @@ diff -urN a/internal/pragma/BUILD.bazel b/internal/pragma/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/protobuild/BUILD.bazel b/internal/protobuild/BUILD.bazel ---- a/internal/protobuild/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/protobuild/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/protobuild/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1783,7 +1788,7 @@ diff -urN a/internal/protobuild/BUILD.bazel b/internal/protobuild/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/protolegacy/BUILD.bazel b/internal/protolegacy/BUILD.bazel ---- a/internal/protolegacy/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/protolegacy/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/protolegacy/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1807,7 +1812,7 @@ diff -urN a/internal/protolegacy/BUILD.bazel b/internal/protolegacy/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/set/BUILD.bazel b/internal/set/BUILD.bazel ---- a/internal/set/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/set/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/set/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1831,7 +1836,7 @@ diff -urN a/internal/set/BUILD.bazel b/internal/set/BUILD.bazel + embed = [":set"], +) diff -urN a/internal/strs/BUILD.bazel b/internal/strs/BUILD.bazel ---- a/internal/strs/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/strs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/strs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,27 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -1862,7 +1867,7 @@ diff -urN a/internal/strs/BUILD.bazel b/internal/strs/BUILD.bazel + embed = [":strs"], +) diff -urN a/internal/testprotos/annotation/BUILD.bazel b/internal/testprotos/annotation/BUILD.bazel ---- a/internal/testprotos/annotation/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/annotation/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/annotation/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1885,7 +1890,7 @@ diff -urN a/internal/testprotos/annotation/BUILD.bazel b/internal/testprotos/ann + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/benchmarks/BUILD.bazel b/internal/testprotos/benchmarks/BUILD.bazel ---- a/internal/testprotos/benchmarks/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/benchmarks/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/benchmarks/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1907,7 +1912,7 @@ diff -urN a/internal/testprotos/benchmarks/BUILD.bazel b/internal/testprotos/ben + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/benchmarks/datasets/google_message1/proto2/BUILD.bazel b/internal/testprotos/benchmarks/datasets/google_message1/proto2/BUILD.bazel ---- a/internal/testprotos/benchmarks/datasets/google_message1/proto2/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/benchmarks/datasets/google_message1/proto2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/benchmarks/datasets/google_message1/proto2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1929,7 +1934,7 @@ diff -urN a/internal/testprotos/benchmarks/datasets/google_message1/proto2/BUILD + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/benchmarks/datasets/google_message1/proto3/BUILD.bazel b/internal/testprotos/benchmarks/datasets/google_message1/proto3/BUILD.bazel ---- a/internal/testprotos/benchmarks/datasets/google_message1/proto3/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/benchmarks/datasets/google_message1/proto3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/benchmarks/datasets/google_message1/proto3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1951,7 +1956,7 @@ diff -urN a/internal/testprotos/benchmarks/datasets/google_message1/proto3/BUILD + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/benchmarks/datasets/google_message2/BUILD.bazel b/internal/testprotos/benchmarks/datasets/google_message2/BUILD.bazel ---- a/internal/testprotos/benchmarks/datasets/google_message2/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/benchmarks/datasets/google_message2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/benchmarks/datasets/google_message2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -1973,7 +1978,7 @@ diff -urN a/internal/testprotos/benchmarks/datasets/google_message2/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/benchmarks/datasets/google_message3/BUILD.bazel b/internal/testprotos/benchmarks/datasets/google_message3/BUILD.bazel ---- a/internal/testprotos/benchmarks/datasets/google_message3/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/benchmarks/datasets/google_message3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/benchmarks/datasets/google_message3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2005,7 +2010,7 @@ diff -urN a/internal/testprotos/benchmarks/datasets/google_message3/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/benchmarks/datasets/google_message4/BUILD.bazel b/internal/testprotos/benchmarks/datasets/google_message4/BUILD.bazel ---- a/internal/testprotos/benchmarks/datasets/google_message4/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/benchmarks/datasets/google_message4/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/benchmarks/datasets/google_message4/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2032,7 +2037,7 @@ diff -urN a/internal/testprotos/benchmarks/datasets/google_message4/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/benchmarks/micro/BUILD.bazel b/internal/testprotos/benchmarks/micro/BUILD.bazel ---- a/internal/testprotos/benchmarks/micro/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/benchmarks/micro/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/benchmarks/micro/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2054,7 +2059,7 @@ diff -urN a/internal/testprotos/benchmarks/micro/BUILD.bazel b/internal/testprot + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/conformance/BUILD.bazel b/internal/testprotos/conformance/BUILD.bazel ---- a/internal/testprotos/conformance/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/conformance/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/conformance/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2086,7 +2091,7 @@ diff -urN a/internal/testprotos/conformance/BUILD.bazel b/internal/testprotos/co + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/enums/BUILD.bazel b/internal/testprotos/enums/BUILD.bazel ---- a/internal/testprotos/enums/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/enums/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/enums/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2108,7 +2113,7 @@ diff -urN a/internal/testprotos/enums/BUILD.bazel b/internal/testprotos/enums/BU + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/fieldtrack/BUILD.bazel b/internal/testprotos/fieldtrack/BUILD.bazel ---- a/internal/testprotos/fieldtrack/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/fieldtrack/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/fieldtrack/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2133,7 +2138,7 @@ diff -urN a/internal/testprotos/fieldtrack/BUILD.bazel b/internal/testprotos/fie + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/fuzz/BUILD.bazel b/internal/testprotos/fuzz/BUILD.bazel ---- a/internal/testprotos/fuzz/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/fuzz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/fuzz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2157,7 +2162,7 @@ diff -urN a/internal/testprotos/fuzz/BUILD.bazel b/internal/testprotos/fuzz/BUIL + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/irregular/BUILD.bazel b/internal/testprotos/irregular/BUILD.bazel ---- a/internal/testprotos/irregular/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/irregular/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/irregular/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2185,8 +2190,36 @@ diff -urN a/internal/testprotos/irregular/BUILD.bazel b/internal/testprotos/irre + actual = ":irregular", + visibility = ["//:__subpackages__"], +) +diff -urN a/internal/testprotos/legacy/bug1052/BUILD.bazel b/internal/testprotos/legacy/bug1052/BUILD.bazel +--- a/internal/testprotos/legacy/bug1052/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ b/internal/testprotos/legacy/bug1052/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,24 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "bug1052", ++ srcs = ["bug1052.pb.go"], ++ importpath = "google.golang.org/protobuf/internal/testprotos/legacy/bug1052", ++ visibility = ["//:__subpackages__"], ++ deps = [ ++ "//internal/protolegacy", ++ "//types/descriptorpb", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":bug1052", ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "bug1052_test", ++ srcs = ["bug1052_test.go"], ++ deps = [":bug1052"], ++) diff -urN a/internal/testprotos/legacy/BUILD.bazel b/internal/testprotos/legacy/BUILD.bazel ---- a/internal/testprotos/legacy/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2219,36 +2252,8 @@ diff -urN a/internal/testprotos/legacy/BUILD.bazel b/internal/testprotos/legacy/ + actual = ":legacy", + visibility = ["//:__subpackages__"], +) -diff -urN a/internal/testprotos/legacy/bug1052/BUILD.bazel b/internal/testprotos/legacy/bug1052/BUILD.bazel ---- a/internal/testprotos/legacy/bug1052/BUILD.bazel 1969-12-31 16:00:00 -+++ b/internal/testprotos/legacy/bug1052/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,24 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "bug1052", -+ srcs = ["bug1052.pb.go"], -+ importpath = "google.golang.org/protobuf/internal/testprotos/legacy/bug1052", -+ visibility = ["//:__subpackages__"], -+ deps = [ -+ "//internal/protolegacy", -+ "//types/descriptorpb", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":bug1052", -+ visibility = ["//:__subpackages__"], -+) -+ -+go_test( -+ name = "bug1052_test", -+ srcs = ["bug1052_test.go"], -+ deps = [":bug1052"], -+) diff -urN a/internal/testprotos/legacy/proto2_20160225_2fc053c5/BUILD.bazel b/internal/testprotos/legacy/proto2_20160225_2fc053c5/BUILD.bazel ---- a/internal/testprotos/legacy/proto2_20160225_2fc053c5/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto2_20160225_2fc053c5/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto2_20160225_2fc053c5/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2267,7 +2272,7 @@ diff -urN a/internal/testprotos/legacy/proto2_20160225_2fc053c5/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto2_20160519_a4ab9ec5/BUILD.bazel b/internal/testprotos/legacy/proto2_20160519_a4ab9ec5/BUILD.bazel ---- a/internal/testprotos/legacy/proto2_20160519_a4ab9ec5/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto2_20160519_a4ab9ec5/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto2_20160519_a4ab9ec5/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2286,7 +2291,7 @@ diff -urN a/internal/testprotos/legacy/proto2_20160519_a4ab9ec5/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto2_20180125_92554152/BUILD.bazel b/internal/testprotos/legacy/proto2_20180125_92554152/BUILD.bazel ---- a/internal/testprotos/legacy/proto2_20180125_92554152/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto2_20180125_92554152/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto2_20180125_92554152/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2305,7 +2310,7 @@ diff -urN a/internal/testprotos/legacy/proto2_20180125_92554152/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto2_20180430_b4deda09/BUILD.bazel b/internal/testprotos/legacy/proto2_20180430_b4deda09/BUILD.bazel ---- a/internal/testprotos/legacy/proto2_20180430_b4deda09/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto2_20180430_b4deda09/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto2_20180430_b4deda09/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2324,7 +2329,7 @@ diff -urN a/internal/testprotos/legacy/proto2_20180430_b4deda09/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto2_20180814_aa810b61/BUILD.bazel b/internal/testprotos/legacy/proto2_20180814_aa810b61/BUILD.bazel ---- a/internal/testprotos/legacy/proto2_20180814_aa810b61/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto2_20180814_aa810b61/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto2_20180814_aa810b61/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2343,7 +2348,7 @@ diff -urN a/internal/testprotos/legacy/proto2_20180814_aa810b61/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto2_20190205_c823c79e/BUILD.bazel b/internal/testprotos/legacy/proto2_20190205_c823c79e/BUILD.bazel ---- a/internal/testprotos/legacy/proto2_20190205_c823c79e/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto2_20190205_c823c79e/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto2_20190205_c823c79e/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2362,7 +2367,7 @@ diff -urN a/internal/testprotos/legacy/proto2_20190205_c823c79e/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto3_20160225_2fc053c5/BUILD.bazel b/internal/testprotos/legacy/proto3_20160225_2fc053c5/BUILD.bazel ---- a/internal/testprotos/legacy/proto3_20160225_2fc053c5/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto3_20160225_2fc053c5/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto3_20160225_2fc053c5/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2381,7 +2386,7 @@ diff -urN a/internal/testprotos/legacy/proto3_20160225_2fc053c5/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto3_20160519_a4ab9ec5/BUILD.bazel b/internal/testprotos/legacy/proto3_20160519_a4ab9ec5/BUILD.bazel ---- a/internal/testprotos/legacy/proto3_20160519_a4ab9ec5/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto3_20160519_a4ab9ec5/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto3_20160519_a4ab9ec5/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2400,7 +2405,7 @@ diff -urN a/internal/testprotos/legacy/proto3_20160519_a4ab9ec5/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto3_20180125_92554152/BUILD.bazel b/internal/testprotos/legacy/proto3_20180125_92554152/BUILD.bazel ---- a/internal/testprotos/legacy/proto3_20180125_92554152/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto3_20180125_92554152/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto3_20180125_92554152/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2419,7 +2424,7 @@ diff -urN a/internal/testprotos/legacy/proto3_20180125_92554152/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto3_20180430_b4deda09/BUILD.bazel b/internal/testprotos/legacy/proto3_20180430_b4deda09/BUILD.bazel ---- a/internal/testprotos/legacy/proto3_20180430_b4deda09/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto3_20180430_b4deda09/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto3_20180430_b4deda09/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2438,7 +2443,7 @@ diff -urN a/internal/testprotos/legacy/proto3_20180430_b4deda09/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto3_20180814_aa810b61/BUILD.bazel b/internal/testprotos/legacy/proto3_20180814_aa810b61/BUILD.bazel ---- a/internal/testprotos/legacy/proto3_20180814_aa810b61/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto3_20180814_aa810b61/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto3_20180814_aa810b61/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2457,7 +2462,7 @@ diff -urN a/internal/testprotos/legacy/proto3_20180814_aa810b61/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/legacy/proto3_20190205_c823c79e/BUILD.bazel b/internal/testprotos/legacy/proto3_20190205_c823c79e/BUILD.bazel ---- a/internal/testprotos/legacy/proto3_20190205_c823c79e/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/legacy/proto3_20190205_c823c79e/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/legacy/proto3_20190205_c823c79e/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,15 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2476,7 +2481,7 @@ diff -urN a/internal/testprotos/legacy/proto3_20190205_c823c79e/BUILD.bazel b/in + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/messageset/messagesetpb/BUILD.bazel b/internal/testprotos/messageset/messagesetpb/BUILD.bazel ---- a/internal/testprotos/messageset/messagesetpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/messageset/messagesetpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/messageset/messagesetpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2498,7 +2503,7 @@ diff -urN a/internal/testprotos/messageset/messagesetpb/BUILD.bazel b/internal/t + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/messageset/msetextpb/BUILD.bazel b/internal/testprotos/messageset/msetextpb/BUILD.bazel ---- a/internal/testprotos/messageset/msetextpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/messageset/msetextpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/messageset/msetextpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2521,7 +2526,7 @@ diff -urN a/internal/testprotos/messageset/msetextpb/BUILD.bazel b/internal/test + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/news/BUILD.bazel b/internal/testprotos/news/BUILD.bazel ---- a/internal/testprotos/news/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/news/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/news/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2545,7 +2550,7 @@ diff -urN a/internal/testprotos/news/BUILD.bazel b/internal/testprotos/news/BUIL + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/nullable/BUILD.bazel b/internal/testprotos/nullable/BUILD.bazel ---- a/internal/testprotos/nullable/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/nullable/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/nullable/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2582,7 +2587,7 @@ diff -urN a/internal/testprotos/nullable/BUILD.bazel b/internal/testprotos/nulla + ], +) diff -urN a/internal/testprotos/order/BUILD.bazel b/internal/testprotos/order/BUILD.bazel ---- a/internal/testprotos/order/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/order/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/order/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2604,7 +2609,7 @@ diff -urN a/internal/testprotos/order/BUILD.bazel b/internal/testprotos/order/BU + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/registry/BUILD.bazel b/internal/testprotos/registry/BUILD.bazel ---- a/internal/testprotos/registry/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/registry/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/registry/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2626,7 +2631,7 @@ diff -urN a/internal/testprotos/registry/BUILD.bazel b/internal/testprotos/regis + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/required/BUILD.bazel b/internal/testprotos/required/BUILD.bazel ---- a/internal/testprotos/required/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/required/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/required/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2648,7 +2653,7 @@ diff -urN a/internal/testprotos/required/BUILD.bazel b/internal/testprotos/requi + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/test/BUILD.bazel b/internal/testprotos/test/BUILD.bazel ---- a/internal/testprotos/test/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/test/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/test/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2677,7 +2682,7 @@ diff -urN a/internal/testprotos/test/BUILD.bazel b/internal/testprotos/test/BUIL + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/test/weak1/BUILD.bazel b/internal/testprotos/test/weak1/BUILD.bazel ---- a/internal/testprotos/test/weak1/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/test/weak1/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/test/weak1/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2699,7 +2704,7 @@ diff -urN a/internal/testprotos/test/weak1/BUILD.bazel b/internal/testprotos/tes + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/test/weak2/BUILD.bazel b/internal/testprotos/test/weak2/BUILD.bazel ---- a/internal/testprotos/test/weak2/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/test/weak2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/test/weak2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2721,7 +2726,7 @@ diff -urN a/internal/testprotos/test/weak2/BUILD.bazel b/internal/testprotos/tes + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/test3/BUILD.bazel b/internal/testprotos/test3/BUILD.bazel ---- a/internal/testprotos/test3/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/test3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/test3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2748,7 +2753,7 @@ diff -urN a/internal/testprotos/test3/BUILD.bazel b/internal/testprotos/test3/BU + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/textpb2/BUILD.bazel b/internal/testprotos/textpb2/BUILD.bazel ---- a/internal/testprotos/textpb2/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/textpb2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/textpb2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,25 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2777,7 +2782,7 @@ diff -urN a/internal/testprotos/textpb2/BUILD.bazel b/internal/testprotos/textpb + visibility = ["//:__subpackages__"], +) diff -urN a/internal/testprotos/textpb3/BUILD.bazel b/internal/testprotos/textpb3/BUILD.bazel ---- a/internal/testprotos/textpb3/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/testprotos/textpb3/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/testprotos/textpb3/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2799,7 +2804,7 @@ diff -urN a/internal/testprotos/textpb3/BUILD.bazel b/internal/testprotos/textpb + visibility = ["//:__subpackages__"], +) diff -urN a/internal/version/BUILD.bazel b/internal/version/BUILD.bazel ---- a/internal/version/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/version/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/version/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2817,7 +2822,7 @@ diff -urN a/internal/version/BUILD.bazel b/internal/version/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/internal/weakdeps/BUILD.bazel b/internal/weakdeps/BUILD.bazel ---- a/internal/weakdeps/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/weakdeps/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/weakdeps/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2835,7 +2840,7 @@ diff -urN a/internal/weakdeps/BUILD.bazel b/internal/weakdeps/BUILD.bazel + visibility = ["//:__subpackages__"], +) diff -urN a/proto/BUILD.bazel b/proto/BUILD.bazel ---- a/proto/BUILD.bazel 1969-12-31 16:00:00 +--- a/proto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/proto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,95 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -2934,7 +2939,7 @@ diff -urN a/proto/BUILD.bazel b/proto/BUILD.bazel + ], +) diff -urN a/protoadapt/BUILD.bazel b/protoadapt/BUILD.bazel ---- a/protoadapt/BUILD.bazel 1969-12-31 16:00:00 +--- a/protoadapt/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/protoadapt/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -2957,7 +2962,7 @@ diff -urN a/protoadapt/BUILD.bazel b/protoadapt/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/reflect/protodesc/BUILD.bazel b/reflect/protodesc/BUILD.bazel ---- a/reflect/protodesc/BUILD.bazel 1969-12-31 16:00:00 +--- a/reflect/protodesc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/reflect/protodesc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,48 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3009,7 +3014,7 @@ diff -urN a/reflect/protodesc/BUILD.bazel b/reflect/protodesc/BUILD.bazel + ], +) diff -urN a/reflect/protopath/BUILD.bazel b/reflect/protopath/BUILD.bazel ---- a/reflect/protopath/BUILD.bazel 1969-12-31 16:00:00 +--- a/reflect/protopath/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/reflect/protopath/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,22 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3035,7 +3040,7 @@ diff -urN a/reflect/protopath/BUILD.bazel b/reflect/protopath/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/reflect/protorange/BUILD.bazel b/reflect/protorange/BUILD.bazel ---- a/reflect/protorange/BUILD.bazel 1969-12-31 16:00:00 +--- a/reflect/protorange/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/reflect/protorange/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,46 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3085,7 +3090,7 @@ diff -urN a/reflect/protorange/BUILD.bazel b/reflect/protorange/BUILD.bazel + ], +) diff -urN a/reflect/protoreflect/BUILD.bazel b/reflect/protoreflect/BUILD.bazel ---- a/reflect/protoreflect/BUILD.bazel 1969-12-31 16:00:00 +--- a/reflect/protoreflect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/reflect/protoreflect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3127,7 +3132,7 @@ diff -urN a/reflect/protoreflect/BUILD.bazel b/reflect/protoreflect/BUILD.bazel + embed = [":protoreflect"], +) diff -urN a/reflect/protoregistry/BUILD.bazel b/reflect/protoregistry/BUILD.bazel ---- a/reflect/protoregistry/BUILD.bazel 1969-12-31 16:00:00 +--- a/reflect/protoregistry/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/reflect/protoregistry/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3167,7 +3172,7 @@ diff -urN a/reflect/protoregistry/BUILD.bazel b/reflect/protoregistry/BUILD.baze + ], +) diff -urN a/runtime/protoiface/BUILD.bazel b/runtime/protoiface/BUILD.bazel ---- a/runtime/protoiface/BUILD.bazel 1969-12-31 16:00:00 +--- a/runtime/protoiface/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/runtime/protoiface/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3192,7 +3197,7 @@ diff -urN a/runtime/protoiface/BUILD.bazel b/runtime/protoiface/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/runtime/protoimpl/BUILD.bazel b/runtime/protoimpl/BUILD.bazel ---- a/runtime/protoimpl/BUILD.bazel 1969-12-31 16:00:00 +--- a/runtime/protoimpl/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/runtime/protoimpl/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3219,7 +3224,7 @@ diff -urN a/runtime/protoimpl/BUILD.bazel b/runtime/protoimpl/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/testing/protocmp/BUILD.bazel b/testing/protocmp/BUILD.bazel ---- a/testing/protocmp/BUILD.bazel 1969-12-31 16:00:00 +--- a/testing/protocmp/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/testing/protocmp/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,52 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3275,7 +3280,7 @@ diff -urN a/testing/protocmp/BUILD.bazel b/testing/protocmp/BUILD.bazel + ], +) diff -urN a/testing/protopack/BUILD.bazel b/testing/protopack/BUILD.bazel ---- a/testing/protopack/BUILD.bazel 1969-12-31 16:00:00 +--- a/testing/protopack/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/testing/protopack/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3310,7 +3315,7 @@ diff -urN a/testing/protopack/BUILD.bazel b/testing/protopack/BUILD.bazel + ], +) diff -urN a/testing/prototest/BUILD.bazel b/testing/prototest/BUILD.bazel ---- a/testing/prototest/BUILD.bazel 1969-12-31 16:00:00 +--- a/testing/prototest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/testing/prototest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3356,7 +3361,7 @@ diff -urN a/testing/prototest/BUILD.bazel b/testing/prototest/BUILD.bazel + ], +) diff -urN a/types/descriptorpb/BUILD.bazel b/types/descriptorpb/BUILD.bazel ---- a/types/descriptorpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/descriptorpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/descriptorpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3378,19 +3383,23 @@ diff -urN a/types/descriptorpb/BUILD.bazel b/types/descriptorpb/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/types/dynamicpb/BUILD.bazel b/types/dynamicpb/BUILD.bazel ---- a/types/dynamicpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/dynamicpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/dynamicpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,43 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "dynamicpb", -+ srcs = ["dynamic.go"], ++ srcs = [ ++ "dynamic.go", ++ "types.go", ++ ], + importpath = "google.golang.org/protobuf/types/dynamicpb", + visibility = ["//visibility:public"], + deps = [ + "//internal/errors", + "//reflect/protoreflect", ++ "//reflect/protoregistry", + "//runtime/protoiface", + "//runtime/protoimpl", + ], @@ -3404,19 +3413,24 @@ diff -urN a/types/dynamicpb/BUILD.bazel b/types/dynamicpb/BUILD.bazel + +go_test( + name = "dynamicpb_test", -+ srcs = ["dynamic_test.go"], ++ srcs = [ ++ "dynamic_test.go", ++ "types_test.go", ++ ], + deps = [ + ":dynamicpb", ++ "//internal/testprotos/registry", + "//internal/testprotos/test", + "//internal/testprotos/test3", + "//proto", + "//reflect/protoreflect", + "//reflect/protoregistry", + "//testing/prototest", ++ "//types/descriptorpb", + ], +) diff -urN a/types/known/anypb/BUILD.bazel b/types/known/anypb/BUILD.bazel ---- a/types/known/anypb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/anypb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/anypb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3455,7 +3469,7 @@ diff -urN a/types/known/anypb/BUILD.bazel b/types/known/anypb/BUILD.bazel + ], +) diff -urN a/types/known/apipb/BUILD.bazel b/types/known/apipb/BUILD.bazel ---- a/types/known/apipb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/apipb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/apipb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3479,7 +3493,7 @@ diff -urN a/types/known/apipb/BUILD.bazel b/types/known/apipb/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/types/known/durationpb/BUILD.bazel b/types/known/durationpb/BUILD.bazel ---- a/types/known/durationpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/durationpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/durationpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3513,7 +3527,7 @@ diff -urN a/types/known/durationpb/BUILD.bazel b/types/known/durationpb/BUILD.ba + ], +) diff -urN a/types/known/emptypb/BUILD.bazel b/types/known/emptypb/BUILD.bazel ---- a/types/known/emptypb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/emptypb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/emptypb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3535,7 +3549,7 @@ diff -urN a/types/known/emptypb/BUILD.bazel b/types/known/emptypb/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/types/known/fieldmaskpb/BUILD.bazel b/types/known/fieldmaskpb/BUILD.bazel ---- a/types/known/fieldmaskpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/fieldmaskpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/fieldmaskpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3570,7 +3584,7 @@ diff -urN a/types/known/fieldmaskpb/BUILD.bazel b/types/known/fieldmaskpb/BUILD. + ], +) diff -urN a/types/known/sourcecontextpb/BUILD.bazel b/types/known/sourcecontextpb/BUILD.bazel ---- a/types/known/sourcecontextpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/sourcecontextpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/sourcecontextpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3592,7 +3606,7 @@ diff -urN a/types/known/sourcecontextpb/BUILD.bazel b/types/known/sourcecontextp + visibility = ["//visibility:public"], +) diff -urN a/types/known/structpb/BUILD.bazel b/types/known/structpb/BUILD.bazel ---- a/types/known/structpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/structpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/structpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3627,7 +3641,7 @@ diff -urN a/types/known/structpb/BUILD.bazel b/types/known/structpb/BUILD.bazel + ], +) diff -urN a/types/known/timestamppb/BUILD.bazel b/types/known/timestamppb/BUILD.bazel ---- a/types/known/timestamppb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/timestamppb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/timestamppb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -3661,7 +3675,7 @@ diff -urN a/types/known/timestamppb/BUILD.bazel b/types/known/timestamppb/BUILD. + ], +) diff -urN a/types/known/typepb/BUILD.bazel b/types/known/typepb/BUILD.bazel ---- a/types/known/typepb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/typepb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/typepb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3685,7 +3699,7 @@ diff -urN a/types/known/typepb/BUILD.bazel b/types/known/typepb/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/types/known/wrapperspb/BUILD.bazel b/types/known/wrapperspb/BUILD.bazel ---- a/types/known/wrapperspb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/known/wrapperspb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/known/wrapperspb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,18 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -3707,7 +3721,7 @@ diff -urN a/types/known/wrapperspb/BUILD.bazel b/types/known/wrapperspb/BUILD.ba + visibility = ["//visibility:public"], +) diff -urN a/types/pluginpb/BUILD.bazel b/types/pluginpb/BUILD.bazel ---- a/types/pluginpb/BUILD.bazel 1969-12-31 16:00:00 +--- a/types/pluginpb/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/types/pluginpb/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") diff --git a/third_party/org_golang_x_sys-gazelle.patch b/third_party/org_golang_x_sys-gazelle.patch index 22ccde0ae4..389982dcab 100644 --- a/third_party/org_golang_x_sys-gazelle.patch +++ b/third_party/org_golang_x_sys-gazelle.patch @@ -1,7 +1,7 @@ diff -urN a/cpu/BUILD.bazel b/cpu/BUILD.bazel ---- a/cpu/BUILD.bazel 1969-12-31 16:00:00 +--- a/cpu/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/cpu/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,67 @@ +@@ -0,0 +1,68 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -64,13 +64,14 @@ diff -urN a/cpu/BUILD.bazel b/cpu/BUILD.bazel + srcs = [ + "cpu_s390x_test.go", + "cpu_test.go", ++ "endian_test.go", + "parse_test.go", + "runtime_auxv_go121_test.go", + ], + embed = [":cpu"], +) diff -urN a/execabs/BUILD.bazel b/execabs/BUILD.bazel ---- a/execabs/BUILD.bazel 1969-12-31 16:00:00 +--- a/execabs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/execabs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -98,7 +99,7 @@ diff -urN a/execabs/BUILD.bazel b/execabs/BUILD.bazel + embed = [":execabs"], +) diff -urN a/internal/unsafeheader/BUILD.bazel b/internal/unsafeheader/BUILD.bazel ---- a/internal/unsafeheader/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/unsafeheader/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/unsafeheader/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -122,7 +123,7 @@ diff -urN a/internal/unsafeheader/BUILD.bazel b/internal/unsafeheader/BUILD.baze + deps = [":unsafeheader"], +) diff -urN a/plan9/BUILD.bazel b/plan9/BUILD.bazel ---- a/plan9/BUILD.bazel 1969-12-31 16:00:00 +--- a/plan9/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/plan9/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -171,9 +172,9 @@ diff -urN a/plan9/BUILD.bazel b/plan9/BUILD.bazel + }), +) diff -urN a/unix/BUILD.bazel b/unix/BUILD.bazel ---- a/unix/BUILD.bazel 1969-12-31 16:00:00 +--- a/unix/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/unix/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,297 @@ +@@ -0,0 +1,301 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -218,6 +219,8 @@ diff -urN a/unix/BUILD.bazel b/unix/BUILD.bazel + "ioctl_linux.go", + "ioctl_signed.go", + "ioctl_unsigned.go", ++ "mmap_nomremap.go", ++ "mremap.go", + "pagesize_unix.go", + "pledge_openbsd.go", + "ptrace_darwin.go", @@ -442,11 +445,13 @@ diff -urN a/unix/BUILD.bazel b/unix/BUILD.bazel + "example_exec_test.go", + "example_flock_test.go", + "example_sysvshm_test.go", ++ "export_mremap_test.go", + "fdset_test.go", + "getdirentries_test.go", + "getfsstat_test.go", + "ifreq_linux_test.go", + "mmap_unix_test.go", ++ "mremap_test.go", + "openbsd_test.go", + "pipe2_test.go", + "sendfile_test.go", @@ -472,7 +477,7 @@ diff -urN a/unix/BUILD.bazel b/unix/BUILD.bazel + embed = [":unix"], +) diff -urN a/unix/internal/mkmerge/BUILD.bazel b/unix/internal/mkmerge/BUILD.bazel ---- a/unix/internal/mkmerge/BUILD.bazel 1969-12-31 16:00:00 +--- a/unix/internal/mkmerge/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/unix/internal/mkmerge/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -496,7 +501,7 @@ diff -urN a/unix/internal/mkmerge/BUILD.bazel b/unix/internal/mkmerge/BUILD.baze + embed = [":mkmerge_lib"], +) diff -urN a/windows/BUILD.bazel b/windows/BUILD.bazel ---- a/windows/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,60 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -560,7 +565,7 @@ diff -urN a/windows/BUILD.bazel b/windows/BUILD.bazel + }), +) diff -urN a/windows/mkwinsyscall/BUILD.bazel b/windows/mkwinsyscall/BUILD.bazel ---- a/windows/mkwinsyscall/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/mkwinsyscall/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/mkwinsyscall/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") @@ -584,7 +589,7 @@ diff -urN a/windows/mkwinsyscall/BUILD.bazel b/windows/mkwinsyscall/BUILD.bazel + embed = [":mkwinsyscall_lib"], +) diff -urN a/windows/registry/BUILD.bazel b/windows/registry/BUILD.bazel ---- a/windows/registry/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/registry/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/registry/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -622,7 +627,7 @@ diff -urN a/windows/registry/BUILD.bazel b/windows/registry/BUILD.bazel + embed = [":registry"], +) diff -urN a/windows/svc/BUILD.bazel b/windows/svc/BUILD.bazel ---- a/windows/svc/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/svc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/svc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -662,7 +667,7 @@ diff -urN a/windows/svc/BUILD.bazel b/windows/svc/BUILD.bazel + }), +) diff -urN a/windows/svc/debug/BUILD.bazel b/windows/svc/debug/BUILD.bazel ---- a/windows/svc/debug/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/svc/debug/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/svc/debug/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,23 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") @@ -689,7 +694,7 @@ diff -urN a/windows/svc/debug/BUILD.bazel b/windows/svc/debug/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/windows/svc/eventlog/BUILD.bazel b/windows/svc/eventlog/BUILD.bazel ---- a/windows/svc/eventlog/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/svc/eventlog/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/svc/eventlog/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -728,7 +733,7 @@ diff -urN a/windows/svc/eventlog/BUILD.bazel b/windows/svc/eventlog/BUILD.bazel + }), +) diff -urN a/windows/svc/example/BUILD.bazel b/windows/svc/example/BUILD.bazel ---- a/windows/svc/example/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/svc/example/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/svc/example/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") @@ -761,7 +766,7 @@ diff -urN a/windows/svc/example/BUILD.bazel b/windows/svc/example/BUILD.bazel + visibility = ["//visibility:public"], +) diff -urN a/windows/svc/mgr/BUILD.bazel b/windows/svc/mgr/BUILD.bazel ---- a/windows/svc/mgr/BUILD.bazel 1969-12-31 16:00:00 +--- a/windows/svc/mgr/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/windows/svc/mgr/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") diff --git a/third_party/org_golang_x_tools-deletegopls.patch b/third_party/org_golang_x_tools-deletegopls.patch index 6011df551b..f1c7c6e4fe 100644 --- a/third_party/org_golang_x_tools-deletegopls.patch +++ b/third_party/org_golang_x_tools-deletegopls.patch @@ -94,7 +94,7 @@ diff -urN a/gopls/api-diff/api_diff.go b/gopls/api-diff/api_diff.go diff -urN a/gopls/doc/advanced.md b/gopls/doc/advanced.md --- a/gopls/doc/advanced.md 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/doc/advanced.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,69 +0,0 @@ +@@ -1,80 +0,0 @@ -# Advanced topics - -This documentation is for advanced `gopls` users, who may want to test @@ -139,6 +139,18 @@ diff -urN a/gopls/doc/advanced.md b/gopls/doc/advanced.md -(`export PATH=$HOME/go/bin:$PATH` on Unix systems) or by configuring your -editor. - +-To work on both `std` and `cmd` simultaneously, add a `go.work` file to +-`GOROOT/src`: +- +-``` +-cd $(go env GOROOT)/src +-go work init . cmd +-``` +- +-Note that you must work inside the `GOROOT/src` subdirectory, as the `go` +-command does not recognize `go.work` files in a parent of `GOROOT/src` +-(https://go.dev/issue/59429). +- -## Working with generic code - -Gopls has support for editing generic Go code. To enable this support, you need @@ -152,7 +164,6 @@ diff -urN a/gopls/doc/advanced.md b/gopls/doc/advanced.md - -It is strongly recommended that you install the latest version of `gopls`, or -the latest **unstable** version as [described above](#installing-unreleased-versions). --We're still working on improving our generics support. - -The `gopls` built with these instructions understands generic code. See the -[generics tutorial](https://go.dev/doc/tutorial/generics) for more information @@ -167,7 +178,7 @@ diff -urN a/gopls/doc/advanced.md b/gopls/doc/advanced.md diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md --- a/gopls/doc/analyzers.md 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/doc/analyzers.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,762 +0,0 @@ +@@ -1,822 +0,0 @@ -# Analyzers - -This document describes the analyzers that `gopls` uses inside the editor. @@ -278,6 +289,37 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - -**Enabled by default.** - +-## **defer** +- +-report common mistakes in defer statements +- +-The defer analyzer reports a diagnostic when a defer statement would +-result in a non-deferred call to time.Since, as experience has shown +-that this is nearly always a mistake. +- +-For example: +- +- start := time.Now() +- ... +- defer recordLatency(time.Since(start)) // error: call to time.Since is not deferred +- +-The correct code is: +- +- defer func() { recordLatency(time.Since(start)) }() +- +-**Enabled by default.** +- +-## **deprecated** +- +-check for use of deprecated identifiers +- +-The deprecated analyzer looks for deprecated symbols and package imports. +- +-See https://go.dev/wiki/Deprecated to learn about Go's convention +-for documenting and signaling deprecated identifiers. +- +-**Enabled by default.** +- -## **directive** - -check Go toolchain directives such as //go:debug @@ -300,10 +342,14 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - -## **embed** - --check for //go:embed directive import +-check //go:embed directive usage +- +-This analyzer checks that the embed package is imported if //go:embed +-directives are present, providing a suggested fix to add the import if +-it is missing. - --This analyzer checks that the embed package is imported when source code contains //go:embed comment directives. --The embed package must be imported for //go:embed directives to function.import _ "embed". +-This analyzer also checks that //go:embed directives precede the +-declaration of a single variable. - -**Enabled by default.** - @@ -385,23 +431,6 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -The Read method in v has a different signature than the Read method in -io.Reader, so this assertion cannot succeed. - -- --**Enabled by default.** -- --## **infertypeargs** -- --check for unnecessary type arguments in call expressions -- --Explicit type arguments may be omitted from call expressions if they can be --inferred from function arguments, or from other type arguments: -- -- func f[T any](T) {} -- -- func _() { -- f[string]("foo") // string could be inferred -- } -- -- -**Enabled by default.** - -## **loopclosure** @@ -416,43 +445,43 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -In this example, all the deferred functions run after the loop has -completed, so all observe the final value of v. - -- for _, v := range list { -- defer func() { -- use(v) // incorrect -- }() -- } +- for _, v := range list { +- defer func() { +- use(v) // incorrect +- }() +- } - -One fix is to create a new variable for each iteration of the loop: - -- for _, v := range list { -- v := v // new var per iteration -- defer func() { -- use(v) // ok -- }() -- } +- for _, v := range list { +- v := v // new var per iteration +- defer func() { +- use(v) // ok +- }() +- } - -The next example uses a go statement and has a similar problem. -In addition, it has a data race because the loop updates v -concurrent with the goroutines accessing it. - -- for _, v := range elem { -- go func() { -- use(v) // incorrect, and a data race -- }() -- } +- for _, v := range elem { +- go func() { +- use(v) // incorrect, and a data race +- }() +- } - -A fix is the same as before. The checker also reports problems -in goroutines started by golang.org/x/sync/errgroup.Group. -A hard-to-spot variant of this form is common in parallel tests: - -- func Test(t *testing.T) { -- for _, test := range tests { -- t.Run(test.name, func(t *testing.T) { -- t.Parallel() -- use(test) // incorrect, and a data race -- }) -- } -- } +- func Test(t *testing.T) { +- for _, test := range tests { +- t.Run(test.name, func(t *testing.T) { +- t.Parallel() +- use(test) // incorrect, and a data race +- }) +- } +- } - -The t.Parallel() call causes the rest of the function to execute -concurrent with the loop. @@ -523,22 +552,32 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - panic(p) - } - -- -**Disabled by default. Enable it by setting `"analyses": {"nilness": true}`.** - -## **printf** - -check consistency of Printf format strings and arguments - --The check applies to known functions (for example, those in package fmt) --as well as any detected wrappers of known functions. +-The check applies to calls of the formatting functions such as +-[fmt.Printf] and [fmt.Sprintf], as well as any detected wrappers of +-those functions. - --A function that wants to avail itself of printf checking but is not --found by this analyzer's heuristics (for example, due to use of --dynamic calls) can insert a bogus call: +-In this example, the %d format operator requires an integer operand: - -- if false { -- _ = fmt.Sprintf(format, args...) // enable printf checking +- fmt.Printf("%d", "hello") // fmt.Printf format %d has arg "hello" of wrong type string +- +-See the documentation of the fmt package for the complete set of +-format operators and their operand types. +- +-To enable printf checking on a function that is not found by this +-analyzer's heuristics (for example, because control is obscured by +-dynamic method calls), insert a bogus call: +- +- func MyPrintf(format string, args ...any) { +- if false { +- _ = fmt.Sprintf(format, args...) // enable printf checker +- } +- ... - } - -The -funcs flag specifies a comma-separated list of names of additional @@ -555,7 +594,6 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -argument list. Otherwise it is assumed to be Print-like, taking a list -of arguments with no format string. - -- -**Enabled by default.** - -## **shadow** @@ -585,7 +623,6 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - return err - } - -- -**Disabled by default. Enable it by setting `"analyses": {"shadow": true}`.** - -## **shift** @@ -638,6 +675,24 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - -**Enabled by default.** - +-## **slog** +- +-check for invalid structured logging calls +- +-The slog checker looks for calls to functions from the log/slog +-package that take alternating key-value pairs. It reports calls +-where an argument in a key position is neither a string nor a +-slog.Attr, and where a final key is missing its value. +-For example,it would report +- +- slog.Warn("message", 11, "k") // slog.Warn arg "11" should be a string or a slog.Attr +- +-and +- +- slog.Info("message", "k1", v1, "k2") // call to slog.Info missing a final value +- +-**Enabled by default.** +- -## **sortslice** - -check the argument type of sort.Slice @@ -657,19 +712,19 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -not error, to satisfy io.WriterTo: - - type myWriterTo struct{...} -- func (myWriterTo) WriteTo(w io.Writer) error { ... } +- func (myWriterTo) WriteTo(w io.Writer) error { ... } - -This check ensures that each method whose name matches one of several -well-known interface methods from the standard library has the correct -signature for that interface. - -Checked method names include: +- - Format GobEncode GobDecode MarshalJSON MarshalXML - Peek ReadByte ReadFrom ReadRune Scan Seek - UnmarshalJSON UnreadByte UnreadRune WriteByte - WriteTo - -- -**Enabled by default.** - -## **stringintconv** @@ -686,7 +741,6 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -with string(rune(x)). Otherwise, strconv.Itoa and its equivalents return the -string representation of the value in the desired base. - -- -**Enabled by default.** - -## **structtag** @@ -706,12 +760,11 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -This checker detects calls to these functions that occur within a goroutine -started by the test. For example: - --func TestFoo(t *testing.T) { -- go func() { -- t.Fatal("oops") // error: (*T).Fatal called from non-test goroutine -- }() --} -- +- func TestFoo(t *testing.T) { +- go func() { +- t.Fatal("oops") // error: (*T).Fatal called from non-test goroutine +- }() +- } - -**Enabled by default.** - @@ -719,7 +772,7 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - -check for common mistaken usages of tests and examples - --The tests checker walks Test, Benchmark and Example functions checking +-The tests checker walks Test, Benchmark, Fuzzing and Example functions checking -malformed names, wrong signatures and examples documenting non-existent -identifiers. - @@ -736,7 +789,6 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -format. Internationally, "yyyy-dd-mm" does not occur in common calendar date -standards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended. - -- -**Enabled by default.** - -## **unmarshal** @@ -779,7 +831,7 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - -To reduce false positives it ignores: -- methods --- parameters that do not have a name or are underscored +-- parameters that do not have a name or have the name '_' (the blank identifier) -- functions in test files -- functions with empty bodies or those with just a return stmt - @@ -789,9 +841,11 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - -check for unused results of calls to some functions - --Some functions like fmt.Errorf return a result and have no side effects, --so it is always a mistake to discard the result. This analyzer reports --calls to certain functions in which the result of the call is ignored. +-Some functions like fmt.Errorf return a result and have no side +-effects, so it is always a mistake to discard the result. Other +-functions may return an error that must not be ignored, or a cleanup +-operation that must be called. This analyzer reports calls to +-functions like these when the result of the call is ignored. - -The set of functions may be controlled using flags. - @@ -810,6 +864,7 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -For example: - - type T struct { x int } +- - func f(input []T) { - for i, v := range input { // v is a copy - v.x = i // unused write to field x @@ -819,11 +874,11 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md -Another example is about non-pointer receiver: - - type T struct { x int } +- - func (t T) f() { // t is a copy - t.x = i // unused write to field x - } - -- -**Disabled by default. Enable it by setting `"analyses": {"unusedwrite": true}`.** - -## **useany** @@ -920,6 +975,22 @@ diff -urN a/gopls/doc/analyzers.md b/gopls/doc/analyzers.md - -**Enabled by default.** - +-## **infertypeargs** +- +-check for unnecessary type arguments in call expressions +- +-Explicit type arguments may be omitted from call expressions if they can be +-inferred from function arguments, or from other type arguments: +- +- func f[T any](T) {} +- +- func _() { +- f[string]("foo") // string could be inferred +- } +- +- +-**Enabled by default.** +- -## **stubmethods** - -stub methods analyzer @@ -952,7 +1023,7 @@ diff -urN a/gopls/doc/command-line.md b/gopls/doc/command-line.md diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md --- a/gopls/doc/commands.md 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/doc/commands.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,467 +0,0 @@ +@@ -1,564 +0,0 @@ -# Commands - -This document describes the LSP-level commands supported by `gopls`. They cannot be invoked directly by users, and all the details are subject to change, so nobody should rely on this information. @@ -1191,6 +1262,7 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md -{ - "HeapAlloc": uint64, - "HeapInUse": uint64, +- "TotalAlloc": uint64, -} -``` - @@ -1221,6 +1293,9 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md - "URI": string, - // The module path to remove. - "ModulePath": string, +- // If the module is tidied apart from the one unused diagnostic, we can +- // run `go get module@none`, and then run `go mod tidy`. Otherwise, we +- // must make textual edits. - "OnlyDiagnostic": bool, -} -``` @@ -1243,6 +1318,21 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md -} -``` - +-### **run `go work [args...]`, and apply the resulting go.work** +-Identifier: `gopls.run_go_work_command` +- +-edits to the current go.work file. +- +-Args: +- +-``` +-{ +- "ViewID": string, +- "InitFirst": bool, +- "Args": []string, +-} +-``` +- -### **Run govulncheck.** -Identifier: `gopls.run_govulncheck` - @@ -1300,14 +1390,14 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md - // Optional: the address (including port) for the debug server to listen on. - // If not provided, the debug server will bind to "localhost:0", and the - // full debug URL will be contained in the result. -- // +- // - // If there is more than one gopls instance along the serving path (i.e. you - // are using a daemon), each gopls instance will attempt to start debugging. - // If Addr specifies a port, only the daemon will be able to bind to that - // port, and each intermediate gopls instance will fail to start debugging. - // For this reason it is recommended not to specify a port (or equivalently, - // to specify ":0"). -- // +- // - // If the server was already debugging this field has no effect, and the - // result will contain the previously configured debug URL(s). - "Addr": string, @@ -1321,7 +1411,7 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md - // The URLs to use to access the debug servers, for all gopls instances in - // the serving path. For the common case of a single gopls instance (i.e. no - // daemon), this will be exactly one address. -- // +- // - // In the case of one or more gopls instances forwarding the LSP to a daemon, - // URLs will contain debug addresses for each server in the serving path, in - // serving order. The daemon debug address will be the last entry in the @@ -1332,6 +1422,48 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md -} -``` - +-### **start capturing a profile of gopls' execution.** +-Identifier: `gopls.start_profile` +- +-Start a new pprof profile. Before using the resulting file, profiling must +-be stopped with a corresponding call to StopProfile. +- +-This command is intended for internal use only, by the gopls benchmark +-runner. +- +-Args: +- +-``` +-struct{} +-``` +- +-Result: +- +-``` +-struct{} +-``` +- +-### **stop an ongoing profile.** +-Identifier: `gopls.stop_profile` +- +-This command is intended for internal use only, by the gopls benchmark +-runner. +- +-Args: +- +-``` +-struct{} +-``` +- +-Result: +- +-``` +-{ +- // File is the profile file name. +- "File": string, +-} +-``` +- -### **Run test(s) (legacy)** -Identifier: `gopls.test` - @@ -1419,11 +1551,47 @@ diff -urN a/gopls/doc/commands.md b/gopls/doc/commands.md -} -``` - +-### **fetch workspace statistics** +-Identifier: `gopls.workspace_stats` +- +-Query statistics about workspace builds, modules, packages, and files. +- +-This command is intended for internal use only, by the gopls stats +-command. +- +-Result: +- +-``` +-{ +- "Files": { +- "Total": int, +- "Largest": int, +- "Errs": int, +- }, +- "Views": []{ +- "GoCommandVersion": string, +- "AllPackages": { +- "Packages": int, +- "LargestPackage": int, +- "CompiledGoFiles": int, +- "Modules": int, +- }, +- "WorkspacePackages": { +- "Packages": int, +- "LargestPackage": int, +- "CompiledGoFiles": int, +- "Modules": int, +- }, +- "Diagnostics": int, +- }, +-} +-``` +- - diff -urN a/gopls/doc/contributing.md b/gopls/doc/contributing.md --- a/gopls/doc/contributing.md 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/doc/contributing.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,119 +0,0 @@ +@@ -1,165 +0,0 @@ -# Documentation for contributors - -This documentation augments the general documentation for contributing to the @@ -1472,6 +1640,52 @@ diff -urN a/gopls/doc/contributing.md b/gopls/doc/contributing.md -gophers slack. Please feel free to ask any questions about your contribution or -about contributing in general. - +- +-## Error handling +- +-It is important for the user experience that, whenever practical, +-minor logic errors in a particular feature don't cause the server to +-crash. +- +-The representation of a Go program is complex. The import graph of +-package metadata, the syntax trees of parsed files, and their +-associated type information together form a huge API surface area. +-Even when the input is valid, there are many edge cases to consider, +-and this grows by an order of magnitude when you consider missing +-imports, parse errors, and type errors. +- +-What should you do when your logic must handle an error that you +-believe "can't happen"? +- +-- If it's possible to return an error, then use the `bug.Errorf` +- function to return an error to the user, but also record the bug in +- gopls' cache so that it is less likely to be ignored. +- +-- If it's safe to proceed, you can call `bug.Reportf` to record the +- error and continue as normal. +- +-- If there's no way to proceed, call `bug.Fatalf` to record the error +- and then stop the program with `log.Fatalf`. You can also use +- `bug.Panicf` if there's a chance that a recover handler might save +- the situation. +- +-- Only if you can prove locally that an error is impossible should you +- call `log.Fatal`. If the error may happen for some input, however +- unlikely, then you should use one of the approaches above. Also, if +- the proof of safety depends on invariants broadly distributed across +- the code base, then you should instead use `bug.Panicf`. +- +-Note also that panicking is preferable to `log.Fatal` because it +-allows VS Code's crash reporting to recognize and capture the stack. +- +-Bugs reported through `bug.Errorf` and friends are retrieved using the +-`gopls bug` command, which opens a GitHub Issue template and populates +-it with a summary of each bug and its frequency. +-The text of the bug is rather fastidiously printed to stdout to avoid +-sharing user names and error message strings (which could contain +-project identifiers) with GitHub. +-Users are invited to share it if they are willing. +- -## Testing - -To run tests for just `gopls/`, run, @@ -2171,14 +2385,14 @@ diff -urN a/gopls/doc/design/implementation.md b/gopls/doc/design/implementation - -[gopls]: https://github.com/golang/tools/tree/master/gopls -[internal/jsonrpc2]: https://github.com/golang/tools/tree/master/internal/jsonrpc2 --[internal/lsp]: https://github.com/golang/tools/tree/master/internal/lsp --[internal/lsp/cache]: https://github.com/golang/tools/tree/master/internal/lsp/cache --[internal/lsp/cmd]: https://github.com/golang/tools/tree/master/internal/lsp/cmd --[internal/lsp/debug]: https://github.com/golang/tools/tree/master/internal/lsp/debug --[internal/lsp/protocol]: https://github.com/golang/tools/tree/master/internal/lsp/protocol --[internal/lsp/source]: https://github.com/golang/tools/tree/master/internal/lsp/source +-[internal/lsp]: https://github.com/golang/tools/tree/master/gopls/internal/lsp +-[internal/lsp/cache]: https://github.com/golang/tools/tree/master/gopls/internal/lsp/cache +-[internal/lsp/cmd]: https://github.com/golang/tools/tree/master/gopls/internal/lsp/cmd +-[internal/lsp/debug]: https://github.com/golang/tools/tree/master/gopls/internal/lsp/debug +-[internal/lsp/protocol]: https://github.com/golang/tools/tree/master/gopls/internal/lsp/protocol +-[internal/lsp/source]: https://github.com/golang/tools/tree/master/gopls/internal/lsp/source -[internal/memoize]: https://github.com/golang/tools/tree/master/internal/memoize --[internal/span]: https://github.com/golang/tools/tree/master/internal/span +-[internal/span]: https://github.com/golang/tools/tree/master/gopls/internal/span -[x/tools]: https://github.com/golang/tools diff -urN a/gopls/doc/design/integrating.md b/gopls/doc/design/integrating.md --- a/gopls/doc/design/integrating.md 2000-01-01 00:00:00.000000000 -0000 @@ -2524,7 +2738,7 @@ diff -urN a/gopls/doc/features.md b/gopls/doc/features.md diff -urN a/gopls/doc/generate.go b/gopls/doc/generate.go --- a/gopls/doc/generate.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/doc/generate.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,778 +0,0 @@ +@@ -1,787 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -2612,9 +2826,13 @@ diff -urN a/gopls/doc/generate.go b/gopls/doc/generate.go - -// pkgDir returns the directory corresponding to the import path pkgPath. -func pkgDir(pkgPath string) (string, error) { -- out, err := exec.Command("go", "list", "-f", "{{.Dir}}", pkgPath).Output() +- cmd := exec.Command("go", "list", "-f", "{{.Dir}}", pkgPath) +- out, err := cmd.Output() - if err != nil { -- return "", err +- if ee, _ := err.(*exec.ExitError); ee != nil && len(ee.Stderr) > 0 { +- return "", fmt.Errorf("%v: %w\n%s", cmd, err, ee.Stderr) +- } +- return "", fmt.Errorf("%v: %w", cmd, err) - } - return strings.TrimSpace(string(out)), nil -} @@ -2992,7 +3210,11 @@ diff -urN a/gopls/doc/generate.go b/gopls/doc/generate.go - if fld.Doc != "" && level == 0 { - doclines := strings.Split(fld.Doc, "\n") - for _, line := range doclines { -- fmt.Fprintf(&b, "%s\t// %s\n", indent, line) +- text := "" +- if line != "" { +- text = " " + line +- } +- fmt.Fprintf(&b, "%s\t//%s\n", indent, text) - } - } - tag := strings.Split(fld.JSONTag, ",")[0] @@ -3043,6 +3265,7 @@ diff -urN a/gopls/doc/generate.go b/gopls/doc/generate.go - json = append(json, &source.AnalyzerJSON{ - Name: a.Analyzer.Name, - Doc: a.Analyzer.Doc, +- URL: a.Analyzer.URL, - Default: a.Enabled, - }) - } @@ -3306,7 +3529,7 @@ diff -urN a/gopls/doc/generate.go b/gopls/doc/generate.go diff -urN a/gopls/doc/generate_test.go b/gopls/doc/generate_test.go --- a/gopls/doc/generate_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/doc/generate_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,26 +0,0 @@ +@@ -1,28 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -3320,17 +3543,19 @@ diff -urN a/gopls/doc/generate_test.go b/gopls/doc/generate_test.go -) - -func TestGenerated(t *testing.T) { -- // This test fails on 1.18 Kokoro for unknown reasons; in any case, it -- // suffices to run this test on any builder. -- testenv.NeedsGo1Point(t, 19) -- testenv.NeedsGoBuild(t) // This is a lie. We actually need the source code. +- testenv.NeedsGoPackages(t) +- // This test fails on Kokoro, for unknown reasons, so must be run only on TryBots. +- // In any case, it suffices to run this test on any builder. +- testenv.NeedsGo1Point(t, 21) +- +- testenv.NeedsLocalXTools(t) - - ok, err := doMain(false) - if err != nil { - t.Fatal(err) - } - if !ok { -- t.Error("documentation needs updating. run: `go run doc/generate.go` from the gopls module.") +- t.Error("documentation needs updating. Run: cd gopls && go generate ./doc") - } -} diff -urN a/gopls/doc/inlayHints.md b/gopls/doc/inlayHints.md @@ -3575,7 +3800,7 @@ diff -urN a/gopls/doc/semantictokens.md b/gopls/doc/semantictokens.md diff -urN a/gopls/doc/settings.md b/gopls/doc/settings.md --- a/gopls/doc/settings.md 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/doc/settings.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,527 +0,0 @@ +@@ -1,557 +0,0 @@ -# Settings - - @@ -3920,7 +4145,21 @@ diff -urN a/gopls/doc/settings.md b/gopls/doc/settings.md - -This option must be set to a valid duration string, for example `"250ms"`. - --Default: `"250ms"`. +-Default: `"1s"`. +- +-##### **analysisProgressReporting** *bool* +- +-analysisProgressReporting controls whether gopls sends progress +-notifications when construction of its index of analysis facts is taking a +-long time. Cancelling these notifications will cancel the indexing task, +-though it will restart after the next change in the workspace. +- +-When a package is opened for the first time and heavyweight analyses such as +-staticcheck are enabled, it can take a while to construct the index of +-analysis facts for all its dependencies. The index is cached in the +-filesystem, so subsequent analysis should be faster. +- +-Default: `true`. - -#### Documentation - @@ -4034,6 +4273,22 @@ diff -urN a/gopls/doc/settings.md b/gopls/doc/settings.md - -Default: `"Dynamic"`. - +-##### **symbolScope** *enum* +- +-symbolScope controls which packages are searched for workspace/symbol +-requests. The default value, "workspace", searches only workspace +-packages. The legacy behavior, "all", causes all loaded packages to be +-searched, including dependencies; this is more expensive and may return +-unwanted results. +- +-Must be one of: +- +-* `"all"` matches symbols in any loaded package, including +-dependencies. +-* `"workspace"` matches symbols in workspace packages only. +- +-Default: `"all"`. +- -#### **verboseOutput** *bool* - -**This setting is for debugging purposes only.** @@ -4337,7 +4592,7 @@ diff -urN a/gopls/doc/vim.md b/gopls/doc/vim.md - -```json - "languageserver": { -- "golang": { +- "go": { - "command": "gopls", - "rootPatterns": ["go.work", "go.mod", ".vim/", ".git/", ".hg/"], - "filetypes": ["go"], @@ -4568,7 +4823,7 @@ diff -urN a/gopls/doc/workspace.md b/gopls/doc/workspace.md diff -urN a/gopls/go.mod b/gopls/go.mod --- a/gopls/go.mod 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/go.mod 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ +@@ -1,30 +0,0 @@ -module golang.org/x/tools/gopls - -go 1.18 @@ -4578,10 +4833,11 @@ diff -urN a/gopls/go.mod b/gopls/go.mod - github.com/jba/printsrc v0.2.2 - github.com/jba/templatecheck v0.6.0 - github.com/sergi/go-diff v1.1.0 -- golang.org/x/mod v0.9.0 -- golang.org/x/sync v0.1.0 -- golang.org/x/sys v0.6.0 -- golang.org/x/text v0.8.0 +- golang.org/x/mod v0.12.0 +- golang.org/x/sync v0.3.0 +- golang.org/x/sys v0.12.0 +- golang.org/x/telemetry v0.0.0-20230822160736-17171dbf1d76 +- golang.org/x/text v0.13.0 - golang.org/x/tools v0.6.0 - golang.org/x/vuln v0.0.0-20230110180137-6ad3e3d07815 - gopkg.in/yaml.v3 v3.0.1 @@ -4601,7 +4857,7 @@ diff -urN a/gopls/go.mod b/gopls/go.mod diff -urN a/gopls/go.sum b/gopls/go.sum --- a/gopls/go.sum 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/go.sum 1970-01-01 00:00:00.000000000 +0000 -@@ -1,101 +0,0 @@ +@@ -1,110 +0,0 @@ -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= -github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -4648,6 +4904,7 @@ diff -urN a/gopls/go.sum b/gopls/go.sum -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.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= -golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= -golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= @@ -4657,14 +4914,17 @@ diff -urN a/gopls/go.sum b/gopls/go.sum -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= --golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= --golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +-golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +-golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +-golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= --golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +-golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= --golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +-golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +-golang.org/x/sync v0.3.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.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -4672,13 +4932,18 @@ diff -urN a/gopls/go.sum b/gopls/go.sum -golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= --golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= --golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +-golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= +-golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +-golang.org/x/telemetry v0.0.0-20230822160736-17171dbf1d76 h1:Lv25uIMpljmSMN0+GCC+xgiC/4ikIdKMkQfw/EVq2Nk= +-golang.org/x/telemetry v0.0.0-20230822160736-17171dbf1d76/go.mod h1:kO7uNSGGmqCHII6C0TYfaLwSBIfcyhj53//nu0+Fy4A= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= --golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +-golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= --golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= --golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/vuln v0.0.0-20230110180137-6ad3e3d07815 h1:A9kONVi4+AnuOr1dopsibH6hLi1Huy54cbeJxnq4vmU= -golang.org/x/vuln v0.0.0-20230110180137-6ad3e3d07815/go.mod h1:XJiVExZgoZfrrxoTeVsFYrSSk1snhfpOEC95JL+A4T0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -5057,6 +5322,483 @@ diff -urN a/gopls/integration/govim/run_tests_for_cloudbuild.sh b/gopls/integrat - # Remove directories we don't care about. - find "$GOVIM_TESTSCRIPT_WORKDIR_ROOT" -type d \( -name .vim -o -name gopath \) -prune -exec rm -rf '{}' \; -fi +diff -urN a/gopls/internal/astutil/purge.go b/gopls/internal/astutil/purge.go +--- a/gopls/internal/astutil/purge.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/astutil/purge.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,74 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-// Package astutil provides various AST utility functions for gopls. +-package astutil +- +-import ( +- "bytes" +- "go/scanner" +- "go/token" +- +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +-) +- +-// PurgeFuncBodies returns a copy of src in which the contents of each +-// outermost {...} region except struct and interface types have been +-// deleted. This reduces the amount of work required to parse the +-// top-level declarations. +-// +-// PurgeFuncBodies does not preserve newlines or position information. +-// Also, if the input is invalid, parsing the output of +-// PurgeFuncBodies may result in a different tree due to its effects +-// on parser error recovery. +-func PurgeFuncBodies(src []byte) []byte { +- // Destroy the content of any {...}-bracketed regions that are +- // not immediately preceded by a "struct" or "interface" +- // token. That includes function bodies, composite literals, +- // switch/select bodies, and all blocks of statements. +- // This will lead to non-void functions that don't have return +- // statements, which of course is a type error, but that's ok. +- +- var out bytes.Buffer +- file := token.NewFileSet().AddFile("", -1, len(src)) +- var sc scanner.Scanner +- sc.Init(file, src, nil, 0) +- var prev token.Token +- var cursor int // last consumed src offset +- var braces []token.Pos // stack of unclosed braces or -1 for struct/interface type +- for { +- pos, tok, _ := sc.Scan() +- if tok == token.EOF { +- break +- } +- switch tok { +- case token.COMMENT: +- // TODO(adonovan): opt: skip, to save an estimated 20% of time. +- +- case token.LBRACE: +- if prev == token.STRUCT || prev == token.INTERFACE { +- pos = -1 +- } +- braces = append(braces, pos) +- +- case token.RBRACE: +- if last := len(braces) - 1; last >= 0 { +- top := braces[last] +- braces = braces[:last] +- if top < 0 { +- // struct/interface type: leave alone +- } else if len(braces) == 0 { // toplevel only +- // Delete {...} body. +- start, _ := safetoken.Offset(file, top) +- end, _ := safetoken.Offset(file, pos) +- out.Write(src[cursor : start+len("{")]) +- cursor = end +- } +- } +- } +- prev = tok +- } +- out.Write(src[cursor:]) +- return out.Bytes() +-} +diff -urN a/gopls/internal/astutil/purge_test.go b/gopls/internal/astutil/purge_test.go +--- a/gopls/internal/astutil/purge_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/astutil/purge_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,89 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package astutil_test +- +-import ( +- "go/ast" +- "go/parser" +- "go/token" +- "os" +- "reflect" +- "testing" +- +- "golang.org/x/tools/go/packages" +- "golang.org/x/tools/gopls/internal/astutil" +- "golang.org/x/tools/internal/testenv" +-) +- +-// TestPurgeFuncBodies tests PurgeFuncBodies by comparing it against a +-// (less efficient) reference implementation that purges after parsing. +-func TestPurgeFuncBodies(t *testing.T) { +- testenv.NeedsGoBuild(t) // we need the source code for std +- +- // Load a few standard packages. +- config := packages.Config{Mode: packages.NeedCompiledGoFiles} +- pkgs, err := packages.Load(&config, "encoding/...") +- if err != nil { +- t.Fatal(err) +- } +- +- // preorder returns the nodes of tree f in preorder. +- preorder := func(f *ast.File) (nodes []ast.Node) { +- ast.Inspect(f, func(n ast.Node) bool { +- if n != nil { +- nodes = append(nodes, n) +- } +- return true +- }) +- return nodes +- } +- +- packages.Visit(pkgs, nil, func(p *packages.Package) { +- for _, filename := range p.CompiledGoFiles { +- content, err := os.ReadFile(filename) +- if err != nil { +- t.Fatal(err) +- } +- +- fset := token.NewFileSet() +- +- // Parse then purge (reference implementation). +- f1, _ := parser.ParseFile(fset, filename, content, 0) +- ast.Inspect(f1, func(n ast.Node) bool { +- switch n := n.(type) { +- case *ast.FuncDecl: +- if n.Body != nil { +- n.Body.List = nil +- } +- case *ast.FuncLit: +- n.Body.List = nil +- case *ast.CompositeLit: +- n.Elts = nil +- } +- return true +- }) +- +- // Purge before parse (logic under test). +- f2, _ := parser.ParseFile(fset, filename, astutil.PurgeFuncBodies(content), 0) +- +- // Compare sequence of node types. +- nodes1 := preorder(f1) +- nodes2 := preorder(f2) +- if len(nodes2) < len(nodes1) { +- t.Errorf("purged file has fewer nodes: %d vs %d", +- len(nodes2), len(nodes1)) +- nodes1 = nodes1[:len(nodes2)] // truncate +- } +- for i := range nodes1 { +- x, y := nodes1[i], nodes2[i] +- if reflect.TypeOf(x) != reflect.TypeOf(y) { +- t.Errorf("%s: got %T, want %T", +- fset.Position(x.Pos()), y, x) +- break +- } +- } +- } +- }) +-} +diff -urN a/gopls/internal/astutil/util.go b/gopls/internal/astutil/util.go +--- a/gopls/internal/astutil/util.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/astutil/util.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,61 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package astutil +- +-import ( +- "go/ast" +- +- "golang.org/x/tools/internal/typeparams" +-) +- +-// UnpackRecv unpacks a receiver type expression, reporting whether it is a +-// pointer recever, along with the type name identifier and any receiver type +-// parameter identifiers. +-// +-// Copied (with modifications) from go/types. +-func UnpackRecv(rtyp ast.Expr) (ptr bool, rname *ast.Ident, tparams []*ast.Ident) { +-L: // unpack receiver type +- // This accepts invalid receivers such as ***T and does not +- // work for other invalid receivers, but we don't care. The +- // validity of receiver expressions is checked elsewhere. +- for { +- switch t := rtyp.(type) { +- case *ast.ParenExpr: +- rtyp = t.X +- case *ast.StarExpr: +- ptr = true +- rtyp = t.X +- default: +- break L +- } +- } +- +- // unpack type parameters, if any +- switch rtyp.(type) { +- case *ast.IndexExpr, *typeparams.IndexListExpr: +- var indices []ast.Expr +- rtyp, _, indices, _ = typeparams.UnpackIndexExpr(rtyp) +- for _, arg := range indices { +- var par *ast.Ident +- switch arg := arg.(type) { +- case *ast.Ident: +- par = arg +- default: +- // ignore errors +- } +- if par == nil { +- par = &ast.Ident{NamePos: arg.Pos(), Name: "_"} +- } +- tparams = append(tparams, par) +- } +- } +- +- // unpack receiver name +- if name, _ := rtyp.(*ast.Ident); name != nil { +- rname = name +- } +- +- return +-} +diff -urN a/gopls/internal/bug/bug.go b/gopls/internal/bug/bug.go +--- a/gopls/internal/bug/bug.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/bug/bug.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,142 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-// Package bug provides utilities for reporting internal bugs, and being +-// notified when they occur. +-// +-// Philosophically, because gopls runs as a sidecar process that the user does +-// not directly control, sometimes it keeps going on broken invariants rather +-// than panicking. In those cases, bug reports provide a mechanism to alert +-// developers and capture relevant metadata. +-package bug +- +-import ( +- "fmt" +- "runtime" +- "runtime/debug" +- "sort" +- "sync" +- "time" +- +- "golang.org/x/telemetry/counter" +-) +- +-// PanicOnBugs controls whether to panic when bugs are reported. +-// +-// It may be set to true during testing. +-var PanicOnBugs = false +- +-var ( +- mu sync.Mutex +- exemplars map[string]Bug +- handlers []func(Bug) +-) +- +-// A Bug represents an unexpected event or broken invariant. They are used for +-// capturing metadata that helps us understand the event. +-// +-// Bugs are JSON-serializable. +-type Bug struct { +- File string // file containing the call to bug.Report +- Line int // line containing the call to bug.Report +- Description string // description of the bug +- Key string // key identifying the bug (file:line if available) +- Stack string // call stack +- AtTime time.Time // time the bug was reported +-} +- +-// Reportf reports a formatted bug message. +-func Reportf(format string, args ...interface{}) { +- report(fmt.Sprintf(format, args...)) +-} +- +-// Errorf calls fmt.Errorf for the given arguments, and reports the resulting +-// error message as a bug. +-func Errorf(format string, args ...interface{}) error { +- err := fmt.Errorf(format, args...) +- report(err.Error()) +- return err +-} +- +-// Report records a new bug encountered on the server. +-// It uses reflection to report the position of the immediate caller. +-func Report(description string) { +- report(description) +-} +- +-// BugReportCount is a telemetry counter that tracks # of bug reports. +-var BugReportCount = counter.NewStack("gopls/bug", 16) +- +-func report(description string) { +- _, file, line, ok := runtime.Caller(2) // all exported reporting functions call report directly +- +- key := "" +- if ok { +- key = fmt.Sprintf("%s:%d", file, line) +- } +- +- if PanicOnBugs { +- panic(fmt.Sprintf("%s: %s", key, description)) +- } +- +- bug := Bug{ +- File: file, +- Line: line, +- Description: description, +- Key: key, +- Stack: string(debug.Stack()), +- AtTime: time.Now(), +- } +- +- newBug := false +- mu.Lock() +- if _, ok := exemplars[key]; !ok { +- if exemplars == nil { +- exemplars = make(map[string]Bug) +- } +- exemplars[key] = bug // capture one exemplar per key +- newBug = true +- } +- hh := handlers +- handlers = nil +- mu.Unlock() +- +- if newBug { +- BugReportCount.Inc() +- } +- // Call the handlers outside the critical section since a +- // handler may itself fail and call bug.Report. Since handlers +- // are one-shot, the inner call should be trivial. +- for _, handle := range hh { +- handle(bug) +- } +-} +- +-// Handle adds a handler function that will be called with the next +-// bug to occur on the server. The handler only ever receives one bug. +-// It is called synchronously, and should return in a timely manner. +-func Handle(h func(Bug)) { +- mu.Lock() +- defer mu.Unlock() +- handlers = append(handlers, h) +-} +- +-// List returns a slice of bug exemplars -- the first bugs to occur at each +-// callsite. +-func List() []Bug { +- mu.Lock() +- defer mu.Unlock() +- +- var bugs []Bug +- +- for _, bug := range exemplars { +- bugs = append(bugs, bug) +- } +- +- sort.Slice(bugs, func(i, j int) bool { +- return bugs[i].Key < bugs[j].Key +- }) +- +- return bugs +-} +diff -urN a/gopls/internal/bug/bug_test.go b/gopls/internal/bug/bug_test.go +--- a/gopls/internal/bug/bug_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/bug/bug_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,91 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package bug +- +-import ( +- "encoding/json" +- "fmt" +- "testing" +- "time" +- +- "github.com/google/go-cmp/cmp" +-) +- +-func resetForTesting() { +- exemplars = nil +- handlers = nil +-} +- +-func TestListBugs(t *testing.T) { +- defer resetForTesting() +- +- Report("bad") +- +- wantBugs(t, "bad") +- +- for i := 0; i < 3; i++ { +- Report(fmt.Sprintf("index:%d", i)) +- } +- +- wantBugs(t, "bad", "index:0") +-} +- +-func wantBugs(t *testing.T, want ...string) { +- t.Helper() +- +- bugs := List() +- if got, want := len(bugs), len(want); got != want { +- t.Errorf("List(): got %d bugs, want %d", got, want) +- return +- } +- +- for i, b := range bugs { +- if got, want := b.Description, want[i]; got != want { +- t.Errorf("bug.List()[%d] = %q, want %q", i, got, want) +- } +- } +-} +- +-func TestBugHandler(t *testing.T) { +- defer resetForTesting() +- +- Report("unseen") +- +- // Both handlers are called, in order of registration, only once. +- var got string +- Handle(func(b Bug) { got += "1:" + b.Description }) +- Handle(func(b Bug) { got += "2:" + b.Description }) +- +- Report("seen") +- +- Report("again") +- +- if want := "1:seen2:seen"; got != want { +- t.Errorf("got %q, want %q", got, want) +- } +-} +- +-func TestBugJSON(t *testing.T) { +- b1 := Bug{ +- File: "foo.go", +- Line: 1, +- Description: "a bug", +- Key: "foo.go:1", +- Stack: "", +- AtTime: time.Now(), +- } +- +- data, err := json.Marshal(b1) +- if err != nil { +- t.Fatal(err) +- } +- var b2 Bug +- if err := json.Unmarshal(data, &b2); err != nil { +- t.Fatal(err) +- } +- if diff := cmp.Diff(b1, b2); diff != "" { +- t.Errorf("bugs differ after JSON Marshal/Unmarshal (-b1 +b2):\n%s", diff) +- } +-} diff -urN a/gopls/internal/coverage/coverage.go b/gopls/internal/coverage/coverage.go --- a/gopls/internal/coverage/coverage.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/coverage/coverage.go 1970-01-01 00:00:00.000000000 +0000 @@ -5887,7 +6629,7 @@ diff -urN a/gopls/internal/hooks/diff.go b/gopls/internal/hooks/diff.go - "time" - - "github.com/sergi/go-diff/diffmatchpatch" -- "golang.org/x/tools/internal/bug" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/internal/diff" -) - @@ -6138,7 +6880,7 @@ diff -urN a/gopls/internal/hooks/gofumpt_117.go b/gopls/internal/hooks/gofumpt_1 diff -urN a/gopls/internal/hooks/gofumpt_118.go b/gopls/internal/hooks/gofumpt_118.go --- a/gopls/internal/hooks/gofumpt_118.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/hooks/gofumpt_118.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ +@@ -1,78 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -6150,6 +6892,7 @@ diff -urN a/gopls/internal/hooks/gofumpt_118.go b/gopls/internal/hooks/gofumpt_1 - -import ( - "context" +- "fmt" - - "golang.org/x/tools/gopls/internal/lsp/source" - "mvdan.cc/gofumpt/format" @@ -6157,12 +6900,122 @@ diff -urN a/gopls/internal/hooks/gofumpt_118.go b/gopls/internal/hooks/gofumpt_1 - -func updateGofumpt(options *source.Options) { - options.GofumptFormat = func(ctx context.Context, langVersion, modulePath string, src []byte) ([]byte, error) { +- fixedVersion, err := fixLangVersion(langVersion) +- if err != nil { +- return nil, err +- } - return format.Source(src, format.Options{ -- LangVersion: langVersion, +- LangVersion: fixedVersion, - ModulePath: modulePath, - }) - } -} +- +-// fixLangVersion function cleans the input so that gofumpt doesn't panic. It is +-// rather permissive, and accepts version strings that aren't technically valid +-// in a go.mod file. +-// +-// More specifically, it looks for an optional 'v' followed by 1-3 +-// '.'-separated numbers. The resulting string is stripped of any suffix beyond +-// this expected version number pattern. +-// +-// See also golang/go#61692: gofumpt does not accept the new language versions +-// appearing in go.mod files (e.g. go1.21rc3). +-func fixLangVersion(input string) (string, error) { +- bad := func() (string, error) { +- return "", fmt.Errorf("invalid language version syntax %q", input) +- } +- if input == "" { +- return input, nil +- } +- i := 0 +- if input[0] == 'v' { // be flexible about 'v' +- i++ +- } +- // takeDigits consumes ascii numerals 0-9 and reports if at least one was +- // consumed. +- takeDigits := func() bool { +- found := false +- for ; i < len(input) && '0' <= input[i] && input[i] <= '9'; i++ { +- found = true +- } +- return found +- } +- if !takeDigits() { // versions must start with at least one number +- return bad() +- } +- +- // Accept optional minor and patch versions. +- for n := 0; n < 2; n++ { +- if i < len(input) && input[i] == '.' { +- // Look for minor/patch version. +- i++ +- if !takeDigits() { +- i-- +- break +- } +- } +- } +- // Accept any suffix. +- return input[:i], nil +-} +diff -urN a/gopls/internal/hooks/gofumpt_118_test.go b/gopls/internal/hooks/gofumpt_118_test.go +--- a/gopls/internal/hooks/gofumpt_118_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/hooks/gofumpt_118_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,53 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.18 +-// +build go1.18 +- +-package hooks +- +-import "testing" +- +-func TestFixLangVersion(t *testing.T) { +- tests := []struct { +- input, want string +- wantErr bool +- }{ +- {"", "", false}, +- {"1.18", "1.18", false}, +- {"v1.18", "v1.18", false}, +- {"1.21", "1.21", false}, +- {"1.21rc3", "1.21", false}, +- {"1.21.0", "1.21.0", false}, +- {"1.21.1", "1.21.1", false}, +- {"v1.21.1", "v1.21.1", false}, +- {"v1.21.0rc1", "v1.21.0", false}, // not technically valid, but we're flexible +- {"v1.21.0.0", "v1.21.0", false}, // also technically invalid +- {"1.1", "1.1", false}, +- {"v1", "v1", false}, +- {"1", "1", false}, +- {"v1.21.", "v1.21", false}, // also invalid +- {"1.21.", "1.21", false}, +- +- // Error cases. +- {"rc1", "", true}, +- {"x1.2.3", "", true}, +- } +- +- for _, test := range tests { +- got, err := fixLangVersion(test.input) +- if test.wantErr { +- if err == nil { +- t.Errorf("fixLangVersion(%q) succeeded unexpectedly", test.input) +- } +- continue +- } +- if err != nil { +- t.Fatalf("fixLangVersion(%q) failed: %v", test.input, err) +- } +- if got != test.want { +- t.Errorf("fixLangVersion(%q) = %s, want %s", test.input, got, test.want) +- } +- } +-} diff -urN a/gopls/internal/hooks/hooks.go b/gopls/internal/hooks/hooks.go --- a/gopls/internal/hooks/hooks.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/hooks/hooks.go 1970-01-01 00:00:00.000000000 +0000 @@ -6395,7 +7248,7 @@ diff -urN a/gopls/internal/hooks/licenses_test.go b/gopls/internal/hooks/license - // License text differs for older Go versions because staticcheck or gofumpt - // isn't supported for those versions, and this fails for unknown, unrelated - // reasons on Kokoro legacy CI. -- testenv.NeedsGo1Point(t, 19) +- testenv.NeedsGo1Point(t, 21) - - if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { - t.Skip("generating licenses only works on Unixes") @@ -6422,28 +7275,367 @@ diff -urN a/gopls/internal/hooks/licenses_test.go b/gopls/internal/hooks/license - t.Error("combined license text needs updating. Run: `go generate ./internal/hooks` from the gopls module.") - } -} +diff -urN a/gopls/internal/lsp/analysis/deprecated/deprecated.go b/gopls/internal/lsp/analysis/deprecated/deprecated.go +--- a/gopls/internal/lsp/analysis/deprecated/deprecated.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/deprecated/deprecated.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,270 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-// Package deprecated defines an Analyzer that marks deprecated symbols and package imports. +-package deprecated +- +-import ( +- "bytes" +- "go/ast" +- "go/format" +- "go/token" +- "go/types" +- "strconv" +- "strings" +- +- "golang.org/x/tools/go/analysis" +- "golang.org/x/tools/go/analysis/passes/inspect" +- "golang.org/x/tools/go/ast/inspector" +- "golang.org/x/tools/internal/typeparams" +-) +- +-// TODO(hyangah): use analysisutil.MustExtractDoc. +-var doc = `check for use of deprecated identifiers +- +-The deprecated analyzer looks for deprecated symbols and package imports. +- +-See https://go.dev/wiki/Deprecated to learn about Go's convention +-for documenting and signaling deprecated identifiers.` +- +-var Analyzer = &analysis.Analyzer{ +- Name: "deprecated", +- Doc: doc, +- Requires: []*analysis.Analyzer{inspect.Analyzer}, +- Run: checkDeprecated, +- FactTypes: []analysis.Fact{(*deprecationFact)(nil)}, +- RunDespiteErrors: true, +-} +- +-// checkDeprecated is a simplified copy of staticcheck.CheckDeprecated. +-func checkDeprecated(pass *analysis.Pass) (interface{}, error) { +- inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) +- +- deprs, err := collectDeprecatedNames(pass, inspector) +- if err != nil || (len(deprs.packages) == 0 && len(deprs.objects) == 0) { +- return nil, err +- } +- +- reportDeprecation := func(depr *deprecationFact, node ast.Node) { +- // TODO(hyangah): staticcheck.CheckDeprecated has more complex logic. Do we need it here? +- // TODO(hyangah): Scrub depr.Msg. depr.Msg may contain Go comments +- // markdown syntaxes but LSP diagnostics do not support markdown syntax. +- +- buf := new(bytes.Buffer) +- if err := format.Node(buf, pass.Fset, node); err != nil { +- // This shouldn't happen but let's be conservative. +- buf.Reset() +- buf.WriteString("declaration") +- } +- pass.ReportRangef(node, "%s is deprecated: %s", buf, depr.Msg) +- } +- +- nodeFilter := []ast.Node{(*ast.SelectorExpr)(nil)} +- inspector.Preorder(nodeFilter, func(node ast.Node) { +- // Caveat: this misses dot-imported objects +- sel, ok := node.(*ast.SelectorExpr) +- if !ok { +- return +- } +- +- obj := pass.TypesInfo.ObjectOf(sel.Sel) +- if obj_, ok := obj.(*types.Func); ok { +- obj = typeparams.OriginMethod(obj_) +- } +- if obj == nil || obj.Pkg() == nil { +- // skip invalid sel.Sel. +- return +- } +- +- if obj.Pkg() == pass.Pkg { +- // A package is allowed to use its own deprecated objects +- return +- } +- +- // A package "foo" has two related packages "foo_test" and "foo.test", for external tests and the package main +- // generated by 'go test' respectively. "foo_test" can import and use "foo", "foo.test" imports and uses "foo" +- // and "foo_test". +- +- if strings.TrimSuffix(pass.Pkg.Path(), "_test") == obj.Pkg().Path() { +- // foo_test (the external tests of foo) can use objects from foo. +- return +- } +- if strings.TrimSuffix(pass.Pkg.Path(), ".test") == obj.Pkg().Path() { +- // foo.test (the main package of foo's tests) can use objects from foo. +- return +- } +- if strings.TrimSuffix(pass.Pkg.Path(), ".test") == strings.TrimSuffix(obj.Pkg().Path(), "_test") { +- // foo.test (the main package of foo's tests) can use objects from foo's external tests. +- return +- } +- +- if depr, ok := deprs.objects[obj]; ok { +- reportDeprecation(depr, sel) +- } +- }) +- +- for _, f := range pass.Files { +- for _, spec := range f.Imports { +- var imp *types.Package +- var obj types.Object +- if spec.Name != nil { +- obj = pass.TypesInfo.ObjectOf(spec.Name) +- } else { +- obj = pass.TypesInfo.Implicits[spec] +- } +- pkgName, ok := obj.(*types.PkgName) +- if !ok { +- continue +- } +- imp = pkgName.Imported() +- +- path, err := strconv.Unquote(spec.Path.Value) +- if err != nil { +- continue +- } +- pkgPath := pass.Pkg.Path() +- if strings.TrimSuffix(pkgPath, "_test") == path { +- // foo_test can import foo +- continue +- } +- if strings.TrimSuffix(pkgPath, ".test") == path { +- // foo.test can import foo +- continue +- } +- if strings.TrimSuffix(pkgPath, ".test") == strings.TrimSuffix(path, "_test") { +- // foo.test can import foo_test +- continue +- } +- if depr, ok := deprs.packages[imp]; ok { +- reportDeprecation(depr, spec.Path) +- } +- } +- } +- return nil, nil +-} +- +-type deprecationFact struct{ Msg string } +- +-func (*deprecationFact) AFact() {} +-func (d *deprecationFact) String() string { return "Deprecated: " + d.Msg } +- +-type deprecatedNames struct { +- objects map[types.Object]*deprecationFact +- packages map[*types.Package]*deprecationFact +-} +- +-// collectDeprecatedNames collects deprecated identifiers and publishes +-// them both as Facts and the return value. This is a simplified copy +-// of staticcheck's fact_deprecated analyzer. +-func collectDeprecatedNames(pass *analysis.Pass, ins *inspector.Inspector) (deprecatedNames, error) { +- extractDeprecatedMessage := func(docs []*ast.CommentGroup) string { +- for _, doc := range docs { +- if doc == nil { +- continue +- } +- parts := strings.Split(doc.Text(), "\n\n") +- for _, part := range parts { +- if !strings.HasPrefix(part, "Deprecated: ") { +- continue +- } +- alt := part[len("Deprecated: "):] +- alt = strings.Replace(alt, "\n", " ", -1) +- return strings.TrimSpace(alt) +- } +- } +- return "" +- } +- +- doDocs := func(names []*ast.Ident, docs *ast.CommentGroup) { +- alt := extractDeprecatedMessage([]*ast.CommentGroup{docs}) +- if alt == "" { +- return +- } +- +- for _, name := range names { +- obj := pass.TypesInfo.ObjectOf(name) +- pass.ExportObjectFact(obj, &deprecationFact{alt}) +- } +- } +- +- var docs []*ast.CommentGroup +- for _, f := range pass.Files { +- docs = append(docs, f.Doc) +- } +- if alt := extractDeprecatedMessage(docs); alt != "" { +- // Don't mark package syscall as deprecated, even though +- // it is. A lot of people still use it for simple +- // constants like SIGKILL, and I am not comfortable +- // telling them to use x/sys for that. +- if pass.Pkg.Path() != "syscall" { +- pass.ExportPackageFact(&deprecationFact{alt}) +- } +- } +- nodeFilter := []ast.Node{ +- (*ast.GenDecl)(nil), +- (*ast.FuncDecl)(nil), +- (*ast.TypeSpec)(nil), +- (*ast.ValueSpec)(nil), +- (*ast.File)(nil), +- (*ast.StructType)(nil), +- (*ast.InterfaceType)(nil), +- } +- ins.Preorder(nodeFilter, func(node ast.Node) { +- var names []*ast.Ident +- var docs *ast.CommentGroup +- switch node := node.(type) { +- case *ast.GenDecl: +- switch node.Tok { +- case token.TYPE, token.CONST, token.VAR: +- docs = node.Doc +- for i := range node.Specs { +- switch n := node.Specs[i].(type) { +- case *ast.ValueSpec: +- names = append(names, n.Names...) +- case *ast.TypeSpec: +- names = append(names, n.Name) +- } +- } +- default: +- return +- } +- case *ast.FuncDecl: +- docs = node.Doc +- names = []*ast.Ident{node.Name} +- case *ast.TypeSpec: +- docs = node.Doc +- names = []*ast.Ident{node.Name} +- case *ast.ValueSpec: +- docs = node.Doc +- names = node.Names +- case *ast.StructType: +- for _, field := range node.Fields.List { +- doDocs(field.Names, field.Doc) +- } +- case *ast.InterfaceType: +- for _, field := range node.Methods.List { +- doDocs(field.Names, field.Doc) +- } +- } +- if docs != nil && len(names) > 0 { +- doDocs(names, docs) +- } +- }) +- +- // Every identifier is potentially deprecated, so we will need +- // to look up facts a lot. Construct maps of all facts propagated +- // to this pass for fast lookup. +- out := deprecatedNames{ +- objects: map[types.Object]*deprecationFact{}, +- packages: map[*types.Package]*deprecationFact{}, +- } +- for _, fact := range pass.AllObjectFacts() { +- out.objects[fact.Object] = fact.Fact.(*deprecationFact) +- } +- for _, fact := range pass.AllPackageFacts() { +- out.packages[fact.Package] = fact.Fact.(*deprecationFact) +- } +- +- return out, nil +-} +diff -urN a/gopls/internal/lsp/analysis/deprecated/deprecated_test.go b/gopls/internal/lsp/analysis/deprecated/deprecated_test.go +--- a/gopls/internal/lsp/analysis/deprecated/deprecated_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/deprecated/deprecated_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package deprecated +- +-import ( +- "testing" +- +- "golang.org/x/tools/go/analysis/analysistest" +- "golang.org/x/tools/internal/testenv" +-) +- +-func Test(t *testing.T) { +- testenv.NeedsGo1Point(t, 19) +- testdata := analysistest.TestData() +- analysistest.Run(t, testdata, Analyzer, "a") +-} +diff -urN a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go +--- a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package usedeprecated +- +-import "io/ioutil" // want "\"io/ioutil\" is deprecated: .*" +- +-func x() { +- _, _ = ioutil.ReadFile("") // want "ioutil.ReadFile is deprecated: As of Go 1.16, .*" +- Legacy() // expect no deprecation notice. +-} +- +-// Legacy is deprecated. +-// +-// Deprecated: use X instead. +-func Legacy() {} // want Legacy:"Deprecated: use X instead." +diff -urN a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go +--- a/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/deprecated/testdata/src/a/a_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package usedeprecated +- +-import "testing" +- +-func TestF(t *testing.T) { +- Legacy() // expect no deprecation notice. +- x() +-} diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go b/gopls/internal/lsp/analysis/embeddirective/embeddirective.go --- a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/embeddirective/embeddirective.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,58 +0,0 @@ +@@ -1,134 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --// Package embeddirective defines an Analyzer that validates import for //go:embed directive. +-// Package embeddirective defines an Analyzer that validates //go:embed directives. +-// The analyzer defers fixes to its parent source.Analyzer. -package embeddirective - -import ( - "go/ast" +- "go/token" - "strings" - - "golang.org/x/tools/go/analysis" -) - --const Doc = `check for //go:embed directive import +-const Doc = `check //go:embed directive usage +- +-This analyzer checks that the embed package is imported if //go:embed +-directives are present, providing a suggested fix to add the import if +-it is missing. - --This analyzer checks that the embed package is imported when source code contains //go:embed comment directives. --The embed package must be imported for //go:embed directives to function.import _ "embed".` +-This analyzer also checks that //go:embed directives precede the +-declaration of a single variable.` - -var Analyzer = &analysis.Analyzer{ - Name: "embed", @@ -6453,36 +7645,106 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective.go b/gopls - RunDespiteErrors: true, -} - +-// source.fixedByImportingEmbed relies on this message to filter +-// out fixable diagnostics from this Analyzer. +-const MissingImportMessage = `must import "embed" when using go:embed directives` +- -func run(pass *analysis.Pass) (interface{}, error) { - for _, f := range pass.Files { -- com := hasEmbedDirectiveComment(f) -- if com != nil { -- assertEmbedImport(pass, com, f) +- comments := embedDirectiveComments(f) +- if len(comments) == 0 { +- continue // nothing to check +- } +- +- hasEmbedImport := false +- for _, imp := range f.Imports { +- if imp.Path.Value == `"embed"` { +- hasEmbedImport = true +- break +- } +- } +- +- for _, c := range comments { +- report := func(msg string) { +- pass.Report(analysis.Diagnostic{ +- Pos: c.Pos(), +- End: c.Pos() + token.Pos(len("//go:embed")), +- Message: msg, +- }) +- } +- +- if !hasEmbedImport { +- report(MissingImportMessage) +- } +- +- spec := nextVarSpec(c, f) +- switch { +- case spec == nil: +- report(`go:embed directives must precede a "var" declaration`) +- case len(spec.Names) > 1: +- report("declarations following go:embed directives must define a single variable") +- case len(spec.Values) > 0: +- report("declarations following go:embed directives must not specify a value") +- } - } - } - return nil, nil -} - --// Check if the comment contains //go:embed directive. --func hasEmbedDirectiveComment(f *ast.File) *ast.Comment { +-// embedDirectiveComments returns all comments in f that contains a //go:embed directive. +-func embedDirectiveComments(f *ast.File) []*ast.Comment { +- comments := []*ast.Comment{} - for _, cg := range f.Comments { - for _, c := range cg.List { - if strings.HasPrefix(c.Text, "//go:embed ") { -- return c +- comments = append(comments, c) - } - } - } -- return nil +- return comments -} - --// Verifies that "embed" import exists for //go:embed directive. --func assertEmbedImport(pass *analysis.Pass, com *ast.Comment, f *ast.File) { -- for _, imp := range f.Imports { -- if "\"embed\"" == imp.Path.Value { -- return +-// nextVarSpec returns the ValueSpec for the variable declaration immediately following +-// the go:embed comment, or nil if the next declaration is not a variable declaration. +-func nextVarSpec(com *ast.Comment, f *ast.File) *ast.ValueSpec { +- // Embed directives must be followed by a declaration of one variable with no value. +- // There may be comments and empty lines between the directive and the declaration. +- var nextDecl ast.Decl +- for _, d := range f.Decls { +- if com.End() < d.End() { +- nextDecl = d +- break +- } +- } +- if nextDecl == nil || nextDecl.Pos() == token.NoPos { +- return nil +- } +- decl, ok := nextDecl.(*ast.GenDecl) +- if !ok { +- return nil +- } +- if decl.Tok != token.VAR { +- return nil +- } +- +- // var declarations can be both freestanding and blocks (with parenthesis). +- // Only the first variable spec following the directive is interesting. +- var nextSpec ast.Spec +- for _, s := range decl.Specs { +- if com.End() < s.End() { +- nextSpec = s +- break - } - } -- pass.Report(analysis.Diagnostic{Pos: com.Pos(), End: com.Pos() + 10, Message: "The \"embed\" package must be imported when using go:embed directives."}) +- if nextSpec == nil { +- return nil +- } +- spec, ok := nextSpec.(*ast.ValueSpec) +- if !ok { +- // Invalid AST, but keep going. +- return nil +- } +- return spec -} diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go b/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go --- a/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go 2000-01-01 00:00:00.000000000 -0000 @@ -6510,47 +7772,140 @@ diff -urN a/gopls/internal/lsp/analysis/embeddirective/embeddirective_test.go b/ - - analysistest.RunWithSuggestedFixes(t, testdata, Analyzer, tests...) -} -diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/a.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/a.go ---- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/a.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ +diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText +--- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-Hello World +\ No newline at end of file +diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go +--- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_missing.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- -package a - -import ( - "fmt" -) - --//go:embed embedText // want "The \"embed\" package must be imported when using go:embed directives" +-//go:embed embedtext // want "must import \"embed\" when using go:embed directives" -var s string - -// This is main function -func main() { - fmt.Println(s) -} -diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/b.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/b.go ---- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/b.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/b.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ +diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go +--- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,73 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- -package a - +-// Misplaced, above imports. +-//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" +- -import ( -- _ "embed" - "fmt" +- +- _ "embed" -) - -//go:embed embedText // ok -var s string - +-// The analyzer does not check for many directives using the same var. +-// +-//go:embed embedText // ok +-//go:embed embedText // ok +-var s string +- +-// Comments and blank lines between are OK. +-// +-//go:embed embedText // ok +-// +-// foo +- +-var s string +- +-// Followed by wrong kind of decl. +-// +-//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" +-func foo() +- +-// Multiple variable specs. +-// +-//go:embed embedText // want "declarations following go:embed directives must define a single variable" +-var foo, bar []byte +- +-// Specifying a value is not allowed. +-// +-//go:embed embedText // want "declarations following go:embed directives must not specify a value" +-var s string = "foo" +- +-// TODO: This should not be OK, misplaced according to compiler. +-// +-//go:embed embedText // ok +-var ( +- s string +- x string +-) +- +-// var blocks are OK as long as the variable following the directive is OK. +-var ( +- x, y, z string +- //go:embed embedText // ok +- s string +- q, r, t string +-) +- +-//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" +-var () +- +-// This is main function +-func main() { +- fmt.Println(s) +-} +- +-// No declaration following. +-//go:embed embedText // want "go:embed directives must precede a \"var\" declaration" +diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go +--- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/import_present_go120.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.20 +-// +build go1.20 +- +-package a +- +-var ( +- // Okay directive wise but the compiler will complain that +- // imports must appear before other declarations. +- //go:embed embedText // ok +- "foo" +-) +- +-import ( +- "fmt" +- +- _ "embed" +-) +- -// This is main function -func main() { - fmt.Println(s) -} -diff -urN a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText ---- a/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/analysis/embeddirective/testdata/src/a/embedText 1970-01-01 00:00:00.000000000 +0000 -@@ -1 +0,0 @@ --Hello World -\ No newline at end of file diff -urN a/gopls/internal/lsp/analysis/fillreturns/fillreturns.go b/gopls/internal/lsp/analysis/fillreturns/fillreturns.go --- a/gopls/internal/lsp/analysis/fillreturns/fillreturns.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/fillreturns/fillreturns.go 1970-01-01 00:00:00.000000000 +0000 @@ -7167,7 +8522,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillreturns/testdata/src/a/typeparams/a. diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/internal/lsp/analysis/fillstruct/fillstruct.go --- a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/fillstruct/fillstruct.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,506 +0,0 @@ +@@ -1,515 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -7218,26 +8573,34 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/interna - RunDespiteErrors: true, -} - +-// TODO(rfindley): remove this thin wrapper around the fillstruct refactoring, +-// and eliminate the fillstruct analyzer. +-// +-// Previous iterations used the analysis framework for computing refactorings, +-// which proved inefficient. -func run(pass *analysis.Pass) (interface{}, error) { - inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) +- for _, d := range DiagnoseFillableStructs(inspect, token.NoPos, token.NoPos, pass.Pkg, pass.TypesInfo) { +- pass.Report(d) +- } +- return nil, nil +-} +- +-// DiagnoseFillableStructs computes diagnostics for fillable struct composite +-// literals overlapping with the provided start and end position. +-// +-// If either start or end is invalid, it is considered an unbounded condition. +-func DiagnoseFillableStructs(inspect *inspector.Inspector, start, end token.Pos, pkg *types.Package, info *types.Info) []analysis.Diagnostic { +- var diags []analysis.Diagnostic - nodeFilter := []ast.Node{(*ast.CompositeLit)(nil)} - inspect.Preorder(nodeFilter, func(n ast.Node) { - expr := n.(*ast.CompositeLit) - -- // Find enclosing file. -- // TODO(adonovan): use inspect.WithStack? -- var file *ast.File -- for _, f := range pass.Files { -- if f.Pos() <= expr.Pos() && expr.Pos() <= f.End() { -- file = f -- break -- } -- } -- if file == nil { -- return +- if (start.IsValid() && expr.End() < start) || (end.IsValid() && expr.Pos() > end) { +- return // non-overlapping - } - -- typ := pass.TypesInfo.TypeOf(expr) +- typ := info.TypeOf(expr) - if typ == nil { - return - } @@ -7262,7 +8625,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/interna - for i := 0; i < fieldCount; i++ { - field := tStruct.Field(i) - // Ignore fields that are not accessible in the current package. -- if field.Pkg() != nil && field.Pkg() != pass.Pkg && !field.Exported() { +- if field.Pkg() != nil && field.Pkg() != pkg && !field.Exported() { - continue - } - fillableFields = append(fillableFields, fmt.Sprintf("%s: %s", field.Name(), field.Type().String())) @@ -7275,7 +8638,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/interna - var name string - if typ != tStruct { - // named struct type (e.g. pkg.S[T]) -- name = types.TypeString(typ, types.RelativeTo(pass.Pkg)) +- name = types.TypeString(typ, types.RelativeTo(pkg)) - } else { - // anonymous struct type - totalFields := len(fillableFields) @@ -7294,13 +8657,14 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/interna - } - name = fmt.Sprintf("anonymous struct { %s }", strings.Join(fillableFields, ", ")) - } -- pass.Report(analysis.Diagnostic{ +- diags = append(diags, analysis.Diagnostic{ - Message: fmt.Sprintf("Fill %s", name), - Pos: expr.Pos(), - End: expr.End(), - }) - }) -- return nil, nil +- +- return diags -} - -// SuggestedFix computes the suggested fix for the kinds of @@ -7338,7 +8702,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/fillstruct.go b/gopls/interna - return nil, fmt.Errorf("%s is not a (pointer to) struct type", - types.TypeString(typ, types.RelativeTo(pkg))) - } -- // Inv: typ is the the possibly-named struct type. +- // Inv: typ is the possibly-named struct type. - - fieldCount := tStruct.NumFields() - @@ -7884,7 +9248,7 @@ diff -urN a/gopls/internal/lsp/analysis/fillstruct/testdata/src/typeparams/typep diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go --- a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ +@@ -1,47 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -7894,8 +9258,11 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go b/gopls/i -package infertypeargs - -import ( +- "go/token" +- - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" +- "golang.org/x/tools/go/ast/inspector" -) - -const Doc = `check for unnecessary type arguments in call expressions @@ -7916,6 +9283,19 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs.go b/gopls/i - Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: run, -} +- +-// TODO(rfindley): remove this thin wrapper around the infertypeargs refactoring, +-// and eliminate the infertypeargs analyzer. +-// +-// Previous iterations used the analysis framework for computing refactorings, +-// which proved inefficient. +-func run(pass *analysis.Pass) (interface{}, error) { +- inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) +- for _, diag := range DiagnoseInferableTypeArgs(pass.Fset, inspect, token.NoPos, token.NoPos, pass.Pkg, pass.TypesInfo) { +- pass.Report(diag) +- } +- return nil, nil +-} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go --- a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -7944,7 +9324,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/infertypeargs_test.go b/go diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go117.go b/gopls/internal/lsp/analysis/infertypeargs/run_go117.go --- a/gopls/internal/lsp/analysis/infertypeargs/run_go117.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/infertypeargs/run_go117.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ +@@ -1,22 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -7954,17 +9334,23 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go117.go b/gopls/inter - -package infertypeargs - --import "golang.org/x/tools/go/analysis" +-import ( +- "go/token" +- "go/types" - --// This analyzer only relates to go1.18+, and uses the types.CheckExpr API that --// was added in Go 1.13. --func run(pass *analysis.Pass) (interface{}, error) { -- return nil, nil +- "golang.org/x/tools/go/analysis" +- "golang.org/x/tools/go/ast/inspector" +-) +- +-// DiagnoseInferableTypeArgs returns an empty slice, as generics are not supported at +-// this go version. +-func DiagnoseInferableTypeArgs(fset *token.FileSet, inspect *inspector.Inspector, start, end token.Pos, pkg *types.Package, info *types.Info) []analysis.Diagnostic { +- return nil -} diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/internal/lsp/analysis/infertypeargs/run_go118.go --- a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/infertypeargs/run_go118.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,111 +0,0 @@ +@@ -1,120 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -7980,18 +9366,19 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/inter - "go/types" - - "golang.org/x/tools/go/analysis" -- "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/inspector" - "golang.org/x/tools/internal/typeparams" -) - --func run(pass *analysis.Pass) (interface{}, error) { -- inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) -- -- nodeFilter := []ast.Node{ -- (*ast.CallExpr)(nil), -- } +-// DiagnoseInferableTypeArgs reports diagnostics describing simplifications to type +-// arguments overlapping with the provided start and end position. +-// +-// If start or end is token.NoPos, the corresponding bound is not checked +-// (i.e. if both start and end are NoPos, all call expressions are considered). +-func DiagnoseInferableTypeArgs(fset *token.FileSet, inspect *inspector.Inspector, start, end token.Pos, pkg *types.Package, info *types.Info) []analysis.Diagnostic { +- var diags []analysis.Diagnostic - +- nodeFilter := []ast.Node{(*ast.CallExpr)(nil)} - inspect.Preorder(nodeFilter, func(node ast.Node) { - call := node.(*ast.CallExpr) - x, lbrack, indices, rbrack := typeparams.UnpackIndexExpr(call.Fun) @@ -8000,8 +9387,12 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/inter - return // no explicit args, nothing to do - } - +- if (start.IsValid() && call.End() < start) || (end.IsValid() && call.Pos() > end) { +- return // non-overlapping +- } +- - // Confirm that instantiation actually occurred at this ident. -- idata, ok := typeparams.GetInstances(pass.TypesInfo)[ident] +- idata, ok := typeparams.GetInstances(info)[ident] - if !ok { - return // something went wrong, but fail open - } @@ -8027,7 +9418,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/inter - } - info := new(types.Info) - typeparams.InitInstanceInfo(info) -- if err := types.CheckExpr(pass.Fset, pass.Pkg, call.Pos(), newCall, info); err != nil { +- if err := types.CheckExpr(fset, pkg, call.Pos(), newCall, info); err != nil { - // Most likely inference failed. - break - } @@ -8041,20 +9432,24 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/inter - required = i - } - if required < len(indices) { -- var start, end token.Pos +- var s, e token.Pos - var edit analysis.TextEdit - if required == 0 { -- start, end = lbrack, rbrack+1 // erase the entire index -- edit = analysis.TextEdit{Pos: start, End: end} +- s, e = lbrack, rbrack+1 // erase the entire index +- edit = analysis.TextEdit{Pos: s, End: e} - } else { -- start = indices[required].Pos() -- end = rbrack +- s = indices[required].Pos() +- e = rbrack - // erase from end of last arg to include last comma & white-spaces -- edit = analysis.TextEdit{Pos: indices[required-1].End(), End: end} +- edit = analysis.TextEdit{Pos: indices[required-1].End(), End: e} - } -- pass.Report(analysis.Diagnostic{ -- Pos: start, -- End: end, +- // Recheck that our (narrower) fixes overlap with the requested range. +- if (start.IsValid() && e < start) || (end.IsValid() && s > end) { +- return // non-overlapping +- } +- diags = append(diags, analysis.Diagnostic{ +- Pos: s, +- End: e, - Message: "unnecessary type arguments", - SuggestedFixes: []analysis.SuggestedFix{{ - Message: "simplify type arguments", @@ -8064,7 +9459,7 @@ diff -urN a/gopls/internal/lsp/analysis/infertypeargs/run_go118.go b/gopls/inter - } - }) - -- return nil, nil +- return diags -} - -func calledIdent(x ast.Expr) *ast.Ident { @@ -9819,7 +11214,7 @@ diff -urN a/gopls/internal/lsp/analysis/simplifyslice/testdata/src/typeparams/ty diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/internal/lsp/analysis/stubmethods/stubmethods.go --- a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/analysis/stubmethods/stubmethods.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,418 +0,0 @@ +@@ -1,449 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -9837,7 +11232,6 @@ diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/inter - "strings" - - "golang.org/x/tools/go/analysis" -- "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/internal/analysisinternal" - "golang.org/x/tools/internal/typesinternal" @@ -9851,17 +11245,17 @@ diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/inter -var Analyzer = &analysis.Analyzer{ - Name: "stubmethods", - Doc: Doc, -- Requires: []*analysis.Analyzer{inspect.Analyzer}, - Run: run, - RunDespiteErrors: true, -} - +-// TODO(rfindley): remove this thin wrapper around the stubmethods refactoring, +-// and eliminate the stubmethods analyzer. +-// +-// Previous iterations used the analysis framework for computing refactorings, +-// which proved inefficient. -func run(pass *analysis.Pass) (interface{}, error) { - for _, err := range pass.TypeErrors { -- ifaceErr := strings.Contains(err.Msg, "missing method") || strings.HasPrefix(err.Msg, "cannot convert") -- if !ifaceErr { -- continue -- } - var file *ast.File - for _, f := range pass.Files { - if f.Pos() <= err.Pos && err.Pos < f.End() { @@ -9869,33 +11263,54 @@ diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/inter - break - } - } -- if file == nil { -- continue -- } - // Get the end position of the error. -- _, _, endPos, ok := typesinternal.ReadGo116ErrorData(err) +- _, _, end, ok := typesinternal.ReadGo116ErrorData(err) - if !ok { - var buf bytes.Buffer - if err := format.Node(&buf, pass.Fset, file); err != nil { - continue - } -- endPos = analysisinternal.TypeErrorEndPos(pass.Fset, buf.Bytes(), err.Pos) +- end = analysisinternal.TypeErrorEndPos(pass.Fset, buf.Bytes(), err.Pos) - } -- path, _ := astutil.PathEnclosingInterval(file, err.Pos, endPos) -- si := GetStubInfo(pass.Fset, pass.TypesInfo, path, err.Pos) -- if si == nil { -- continue +- if diag, ok := DiagnosticForError(pass.Fset, file, err.Pos, end, err.Msg, pass.TypesInfo); ok { +- pass.Report(diag) - } -- qf := RelativeToFiles(si.Concrete.Obj().Pkg(), file, nil, nil) -- pass.Report(analysis.Diagnostic{ -- Pos: err.Pos, -- End: endPos, -- Message: fmt.Sprintf("Implement %s", types.TypeString(si.Interface.Type(), qf)), -- }) - } +- - return nil, nil -} - +-// MatchesMessage reports whether msg matches the error message sought after by +-// the stubmethods fix. +-func MatchesMessage(msg string) bool { +- return strings.Contains(msg, "missing method") || strings.HasPrefix(msg, "cannot convert") +-} +- +-// DiagnosticForError computes a diagnostic suggesting to implement an +-// interface to fix the type checking error defined by (start, end, msg). +-// +-// If no such fix is possible, the second result is false. +-// +-// TODO(rfindley): simplify this signature once the stubmethods refactoring is +-// no longer wedged into the analysis framework. +-func DiagnosticForError(fset *token.FileSet, file *ast.File, start, end token.Pos, msg string, info *types.Info) (analysis.Diagnostic, bool) { +- if !MatchesMessage(msg) { +- return analysis.Diagnostic{}, false +- } +- +- path, _ := astutil.PathEnclosingInterval(file, start, end) +- si := GetStubInfo(fset, info, path, start) +- if si == nil { +- return analysis.Diagnostic{}, false +- } +- qf := RelativeToFiles(si.Concrete.Obj().Pkg(), file, nil, nil) +- return analysis.Diagnostic{ +- Pos: start, +- End: end, +- Message: fmt.Sprintf("Implement %s", types.TypeString(si.Interface.Type(), qf)), +- }, true +-} +- -// StubInfo represents a concrete type -// that wants to stub out an interface type -type StubInfo struct { @@ -9917,7 +11332,7 @@ diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/inter -// -// TODO(adonovan): this function (and its following 5 helpers) tries -// to deduce a pair of (concrete, interface) types that are related by --// an assignment, either explictly or through a return statement or +-// an assignment, either explicitly or through a return statement or -// function call. This is essentially what the refactor/satisfy does, -// more generally. Refactor to share logic, after auditing 'satisfy' -// for safety on ill-typed code. @@ -9976,8 +11391,19 @@ diff -urN a/gopls/internal/lsp/analysis/stubmethods/stubmethods.go b/gopls/inter - if !ok { - return nil - } -- sigVar := sig.Params().At(paramIdx) -- iface := ifaceObjFromType(sigVar.Type()) +- var paramType types.Type +- if sig.Variadic() && paramIdx >= sig.Params().Len()-1 { +- v := sig.Params().At(sig.Params().Len() - 1) +- if s, _ := v.Type().(*types.Slice); s != nil { +- paramType = s.Elem() +- } +- } else if paramIdx < sig.Params().Len() { +- paramType = sig.Params().At(paramIdx).Type() +- } +- if paramType == nil { +- return nil // A type error prevents us from determining the param type. +- } +- iface := ifaceObjFromType(paramType) - if iface == nil { - return nil - } @@ -11042,7 +12468,7 @@ diff -urN a/gopls/internal/lsp/analysis/unusedparams/unusedparams.go b/gopls/int - -To reduce false positives it ignores: -- methods --- parameters that do not have a name or are underscored +-- parameters that do not have a name or have the name '_' (the blank identifier) -- functions in test files -- functions with empty bodies or those with just a return stmt` - @@ -11998,7 +13424,7 @@ diff -urN a/gopls/internal/lsp/browser/README.md b/gopls/internal/lsp/browser/RE diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/analysis.go --- a/gopls/internal/lsp/cache/analysis.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/analysis.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1247 +0,0 @@ +@@ -1,1515 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -12019,22 +13445,28 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - "go/token" - "go/types" - "log" +- urlpkg "net/url" - "reflect" +- "runtime" - "runtime/debug" - "sort" - "strings" - "sync" +- "sync/atomic" - "time" - - "golang.org/x/sync/errgroup" - "golang.org/x/tools/go/analysis" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/filecache" +- "golang.org/x/tools/gopls/internal/lsp/frob" +- "golang.org/x/tools/gopls/internal/lsp/progress" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/bug" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" - "golang.org/x/tools/internal/facts" - "golang.org/x/tools/internal/gcimporter" -- "golang.org/x/tools/internal/memoize" - "golang.org/x/tools/internal/typeparams" - "golang.org/x/tools/internal/typesinternal" -) @@ -12043,48 +13475,50 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - - DESIGN - -- An analysis request is for a set of analyzers and an individual -- package ID, notated (a*, p). The result is the set of diagnostics -- for that package. It could easily be generalized to a set of -- packages, (a*, p*), and perhaps should be, to improve performance -- versus calling it in a loop. -- -- The snapshot holds a cache (persistent.Map) of entries keyed by -- (a*, p) pairs ("analysisKey") that have been requested so far. Some -- of these entries may be invalidated during snapshot cloning after a -- modification event. The cache maps each (a*, p) to a promise of -- the analysis result or "analysisSummary". The summary contains the -- results of analysis (e.g. diagnostics) as well as the intermediate -- results required by the recursion, such as serialized types and -- facts. -- -- The promise represents the result of a call to analyzeImpl, which -- type-checks a package and then applies a graph of analyzers to it -- in parallel postorder. (These graph edges are "horizontal": within -- the same package.) First, analyzeImpl reads the source files of -- package p, and obtains (recursively) the results of the "vertical" -- dependencies (i.e. analyzers applied to the packages imported by -- p). Only the subset of analyzers that use facts need be executed -- recursively, but even if this subset is empty, the step is still -- necessary because it provides type information. It is possible that -- a package may need to be type-checked and analyzed twice, for -- different subsets of analyzers, but the overlap is typically -- insignificant. -- -- With the file contents and the results of vertical dependencies, -- analyzeImpl is then in a position to produce a key representing the -- unit of work (parsing, type-checking, and analysis) that it has to -- do. The key is a cryptographic hash of the "recipe" for this step, -- including the Metadata, the file contents, the set of analyzers, -- and the type and fact information from the vertical dependencies. +- An analysis request (Snapshot.Analyze) is for a set of Analyzers and +- PackageIDs. The result is the set of diagnostics for those +- packages. Each request constructs a transitively closed DAG of +- nodes, each representing a package, then works bottom up in +- parallel postorder calling runCached to ensure that each node's +- analysis summary is up to date. The summary contains the analysis +- diagnostics as well as the intermediate results required by the +- recursion, such as serialized types and facts. +- +- The entire DAG is ephemeral. Each node in the DAG records the set +- of analyzers to run: the complete set for the root packages, and +- the "facty" subset for dependencies. Each package is thus analyzed +- at most once. The entire DAG shares a single FileSet for parsing +- and importing. +- +- Each node is processed by runCached. It gets the source file +- content hashes for package p, and the summaries of its "vertical" +- dependencies (direct imports), and from them it computes a key +- representing the unit of work (parsing, type-checking, and +- analysis) that it has to do. The key is a cryptographic hash of the +- "recipe" for this step, including the Metadata, the file contents, +- the set of analyzers, and the type and fact information from the +- vertical dependencies. - - The key is sought in a machine-global persistent file-system based - cache. If this gopls process, or another gopls process on the same -- machine, has already performed this analysis step, analyzeImpl will +- machine, has already performed this analysis step, runCached will - make a cache hit and load the serialized summary of the results. If -- not, it will have to proceed to type-checking and analysis, and -- write a new cache entry. The entry contains serialized types -- (export data) and analysis facts. +- not, it will have to proceed to run() to parse and type-check the +- package and then apply a set of analyzers to it. (The set of +- analyzers applied to a single package itself forms a graph of +- "actions", and it too is evaluated in parallel postorder; these +- dependency edges within the same package are called "horizontal".) +- Finally it writes a new cache entry. The entry contains serialized +- types (export data) and analysis facts. +- +- Each node in the DAG acts like a go/types importer mapping, +- providing a consistent view of packages and their objects: the +- mapping for a node is a superset of its dependencies' mappings. +- Every node has an associated *types.Package, initially nil. A +- package is populated during run (cache miss) by type-checking its +- syntax; but for a cache hit, the package is populated lazily, i.e. +- not until it later becomes necessary because it is imported +- directly or referenced by export data higher up in the DAG. - - For types, we use "shallow" export data. Historically, the Go - compiler always produced a summary of the types for a given package @@ -12103,11 +13537,8 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - "Shallow" export data means that the serialized types describe only - a single package. If those types mention types from other packages, - the type checker may need to request additional packages beyond -- just the direct imports. This means type information for the entire -- transitive closure of imports may need to be available just in -- case. After a cache hit or a cache miss, the summary is -- postprocessed so that it contains the union of export data payloads -- of all its direct dependencies. +- just the direct imports. Type information for the entire transitive +- closure of imports is provided (lazily) by the DAG. - - For correct dependency analysis, the digest used as a cache key - must reflect the "deep" export data, so it is derived recursively @@ -12119,8 +13550,9 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - but if its export data is unchanged as a result, then indirect - consumers may not need to be re-executed. This allows, for example, - one to insert a print statement in a function and not "rebuild" the -- whole application (though export data does record line numbers of -- types which may be perturbed by otherwise insignificant changes.) +- whole application (though export data does record line numbers and +- offsets of types which may be perturbed by otherwise insignificant +- changes.) - - The summary must record whether a package is transitively - error-free (whether it would compile) because many analyzers are @@ -12133,13 +13565,6 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal -*/ - -// TODO(adonovan): --// - Profile + optimize: --// - on a cold run, mostly type checking + export data, unsurprisingly. --// - on a hot-disk run, mostly type checking the IWL. --// Would be nice to have a benchmark that separates this out. --// - measure and record in the code the typical operation times --// and file sizes (export data + facts = cache entries). --// - Do "port the old logic" tasks (see TODO in actuallyAnalyze). -// - Add a (white-box) test of pruning when a change doesn't affect export data. -// - Optimise pruning based on subset of packages mentioned in exportdata. -// - Better logging so that it is possible to deduce why an analyzer @@ -12147,7 +13572,6 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal -// Even if the ultimate consumer decides to ignore errors, -// tests and other situations want to be assured of freedom from -// errors, not just missing results. This should be recorded. --// - Check that the event trace is intelligible. -// - Split this into a subpackage, gopls/internal/lsp/cache/driver, -// consisting of this file and three helpers from errors.go. -// The (*snapshot).Analyze method would stay behind and make calls @@ -12155,35 +13579,47 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal -// Steps: -// - define a narrow driver.Snapshot interface with only these methods: -// Metadata(PackageID) source.Metadata --// GetFile(Context, URI) (source.FileHandle, error) +-// ReadFile(Context, URI) (source.FileHandle, error) -// View() *View // for Options --// - define a State type that encapsulates the persistent map --// (with its own mutex), and has methods: --// New() *State --// Clone(invalidate map[PackageID]bool) *State --// Destroy() -// - share cache.{goVersionRx,parseGoImpl} - --var born = time.Now() +-// AnalysisProgressTitle is the title of the progress report for ongoing +-// analysis. It is sought by regression tests for the progress reporting +-// feature. +-const AnalysisProgressTitle = "Analyzing Dependencies" - -// Analyze applies a set of analyzers to the package denoted by id, -// and returns their diagnostics for that package. -// -// The analyzers list must be duplicate free; order does not matter. -// +-// Notifications of progress may be sent to the optional reporter. +-// -// Precondition: all analyzers within the process have distinct names. -// (The names are relied on by the serialization logic.) --func (s *snapshot) Analyze(ctx context.Context, id PackageID, analyzers []*source.Analyzer) ([]*source.Diagnostic, error) { -- if false { // debugging -- log.Println("Analyze@", time.Since(born)) // called after the 7s IWL in k8s +-func (snapshot *snapshot) Analyze(ctx context.Context, pkgs map[PackageID]unit, analyzers []*source.Analyzer, reporter *progress.Tracker) ([]*source.Diagnostic, error) { +- start := time.Now() // for progress reporting +- +- var tagStr string // sorted comma-separated list of PackageIDs +- { +- // TODO(adonovan): replace with a generic map[S]any -> string +- // function in the tag package, and use maps.Keys + slices.Sort. +- keys := make([]string, 0, len(pkgs)) +- for id := range pkgs { +- keys = append(keys, string(id)) +- } +- sort.Strings(keys) +- tagStr = strings.Join(keys, ",") - } +- ctx, done := event.Start(ctx, "snapshot.Analyze", tag.Package.Of(tagStr)) +- defer done() - - // Filter and sort enabled root analyzers. - // A disabled analyzer may still be run if required by another. - toSrc := make(map[*analysis.Analyzer]*source.Analyzer) -- var enabled []*analysis.Analyzer +- var enabled []*analysis.Analyzer // enabled subset + transitive requirements - for _, a := range analyzers { -- if a.IsEnabled(s.view.Options()) { +- if a.IsEnabled(snapshot.view.Options()) { - toSrc[a.Analyzer] = a - enabled = append(enabled, a.Analyzer) - } @@ -12191,26 +13627,216 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - sort.Slice(enabled, func(i, j int) bool { - return enabled[i].Name < enabled[j].Name - }) +- analyzers = nil // prevent accidental use - - // Register fact types of required analyzers. -- for _, a := range requiredAnalyzers(enabled) { -- for _, f := range a.FactTypes { -- gob.Register(f) +- enabled = requiredAnalyzers(enabled) +- var facty []*analysis.Analyzer // facty subset of enabled + transitive requirements +- for _, a := range enabled { +- if len(a.FactTypes) > 0 { +- facty = append(facty, a) +- for _, f := range a.FactTypes { +- gob.Register(f) // <2us +- } - } - } +- facty = requiredAnalyzers(facty) - -- if false { // debugging -- // TODO(adonovan): use proper tracing. -- t0 := time.Now() +- // File set for this batch (entire graph) of analysis. +- fset := token.NewFileSet() +- +- // Starting from the root packages and following DepsByPkgPath, +- // build the DAG of packages we're going to analyze. +- // +- // Root nodes will run the enabled set of analyzers, +- // whereas dependencies will run only the facty set. +- // Because (by construction) enabled is a superset of facty, +- // we can analyze each node with exactly one set of analyzers. +- nodes := make(map[PackageID]*analysisNode) +- var leaves []*analysisNode // nodes with no unfinished successors +- var makeNode func(from *analysisNode, id PackageID) (*analysisNode, error) +- makeNode = func(from *analysisNode, id PackageID) (*analysisNode, error) { +- an, ok := nodes[id] +- if !ok { +- m := snapshot.Metadata(id) +- if m == nil { +- return nil, bug.Errorf("no metadata for %s", id) +- } +- +- // -- preorder -- +- +- an = &analysisNode{ +- fset: fset, +- m: m, +- analyzers: facty, // all nodes run at least the facty analyzers +- allDeps: make(map[PackagePath]*analysisNode), +- exportDeps: make(map[PackagePath]*analysisNode), +- } +- nodes[id] = an +- +- // -- recursion -- +- +- // Build subgraphs for dependencies. +- an.succs = make(map[PackageID]*analysisNode, len(m.DepsByPkgPath)) +- for _, depID := range m.DepsByPkgPath { +- dep, err := makeNode(an, depID) +- if err != nil { +- return nil, err +- } +- an.succs[depID] = dep +- +- // Compute the union of all dependencies. +- // (This step has quadratic complexity.) +- for pkgPath, node := range dep.allDeps { +- an.allDeps[pkgPath] = node +- } +- } +- +- // -- postorder -- +- +- an.allDeps[m.PkgPath] = an // add self entry (reflexive transitive closure) +- +- // Add leaf nodes (no successors) directly to queue. +- if len(an.succs) == 0 { +- leaves = append(leaves, an) +- } +- +- // Load the contents of each compiled Go file through +- // the snapshot's cache. (These are all cache hits as +- // files are pre-loaded following packages.Load) +- an.files = make([]source.FileHandle, len(m.CompiledGoFiles)) +- for i, uri := range m.CompiledGoFiles { +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- an.files[i] = fh +- } +- } +- // Add edge from predecessor. +- if from != nil { +- atomic.AddInt32(&from.unfinishedSuccs, 1) // TODO(adonovan): use generics +- an.preds = append(an.preds, from) +- } +- atomic.AddInt32(&an.unfinishedPreds, 1) +- return an, nil +- } +- +- // For root packages, we run the enabled set of analyzers. +- var roots []*analysisNode +- for id := range pkgs { +- root, err := makeNode(nil, id) +- if err != nil { +- return nil, err +- } +- root.analyzers = enabled +- roots = append(roots, root) +- } +- +- // Now that we have read all files, +- // we no longer need the snapshot. +- // (but options are needed for progress reporting) +- options := snapshot.view.Options() +- snapshot = nil +- +- // Progress reporting. If supported, gopls reports progress on analysis +- // passes that are taking a long time. +- maybeReport := func(completed int64) {} +- +- // Enable progress reporting if enabled by the user +- // and we have a capable reporter. +- if reporter != nil && reporter.SupportsWorkDoneProgress() && options.AnalysisProgressReporting { +- var reportAfter = options.ReportAnalysisProgressAfter // tests may set this to 0 +- const reportEvery = 1 * time.Second +- +- ctx, cancel := context.WithCancel(ctx) +- defer cancel() +- +- var ( +- reportMu sync.Mutex +- lastReport time.Time +- wd *progress.WorkDone +- ) - defer func() { -- log.Printf("%v for analyze(%s, %s)", time.Since(t0), id, enabled) +- reportMu.Lock() +- defer reportMu.Unlock() +- +- if wd != nil { +- wd.End(ctx, "Done.") // ensure that the progress report exits +- } - }() +- maybeReport = func(completed int64) { +- now := time.Now() +- if now.Sub(start) < reportAfter { +- return +- } +- +- reportMu.Lock() +- defer reportMu.Unlock() +- +- if wd == nil { +- wd = reporter.Start(ctx, AnalysisProgressTitle, "", nil, cancel) +- } +- +- if now.Sub(lastReport) > reportEvery { +- lastReport = now +- // Trailing space is intentional: some LSP clients strip newlines. +- msg := fmt.Sprintf(`Indexed %d/%d packages. (Set "analysisProgressReporting" to false to disable notifications.)`, +- completed, len(nodes)) +- pct := 100 * float64(completed) / float64(len(nodes)) +- wd.Report(ctx, msg, pct) +- } +- } - } - -- // Run the analysis. -- res, err := s.analyze(ctx, id, enabled) -- if err != nil { -- return nil, err +- // Execute phase: run leaves first, adding +- // new nodes to the queue as they become leaves. +- var g errgroup.Group +- +- // Analysis is CPU-bound. +- // +- // Note: avoid g.SetLimit here: it makes g.Go stop accepting work, which +- // prevents workers from enqeuing, and thus finishing, and thus allowing the +- // group to make progress: deadlock. +- limiter := make(chan unit, runtime.GOMAXPROCS(0)) +- var completed int64 +- +- var enqueue func(*analysisNode) +- enqueue = func(an *analysisNode) { +- g.Go(func() error { +- limiter <- unit{} +- defer func() { <-limiter }() +- +- summary, err := an.runCached(ctx) +- if err != nil { +- return err // cancelled, or failed to produce a package +- } +- maybeReport(atomic.AddInt64(&completed, 1)) +- an.summary = summary +- +- // Notify each waiting predecessor, +- // and enqueue it when it becomes a leaf. +- for _, pred := range an.preds { +- if atomic.AddInt32(&pred.unfinishedSuccs, -1) == 0 { +- enqueue(pred) +- } +- } +- +- // Notify each successor that we no longer need +- // its action summaries, which hold Result values. +- // After the last one, delete it, so that we +- // free up large results such as SSA. +- for _, succ := range an.succs { +- succ.decrefPreds() +- } +- return nil +- }) +- } +- for _, leaf := range leaves { +- enqueue(leaf) +- } +- if err := g.Wait(); err != nil { +- return nil, err // cancelled, or failed to produce a package - } - - // Report diagnostics only from enabled actions that succeeded. @@ -12224,47 +13850,162 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // Even if current callers choose to discard the - // results, we should propagate the per-action errors. - var results []*source.Diagnostic -- for _, a := range enabled { -- summary := res.Actions[a.Name] -- if summary.Err != "" { -- continue // action failed -- } -- for _, gobDiag := range summary.Diagnostics { -- results = append(results, toSourceDiagnostic(toSrc[a], &gobDiag)) +- for _, root := range roots { +- for _, a := range enabled { +- // Skip analyzers that were added only to +- // fulfil requirements of the original set. +- srcAnalyzer, ok := toSrc[a] +- if !ok { +- // Although this 'skip' operation is logically sound, +- // it is nonetheless surprising that its absence should +- // cause #60909 since none of the analyzers added for +- // requirements (e.g. ctrlflow, inspect, buildssa) +- // is capable of reporting diagnostics. +- if summary := root.summary.Actions[a.Name]; summary != nil { +- if n := len(summary.Diagnostics); n > 0 { +- bug.Reportf("Internal error: got %d unexpected diagnostics from analyzer %s. This analyzer was added only to fulfil the requirements of the requested set of analyzers, and it is not expected that such analyzers report diagnostics. Please report this in issue #60909.", n, a) +- } +- } +- continue +- } +- +- // Inv: root.summary is the successful result of run (via runCached). +- summary, ok := root.summary.Actions[a.Name] +- if summary == nil { +- panic(fmt.Sprintf("analyzeSummary.Actions[%q] = (nil, %t); got %v (#60551)", +- a.Name, ok, root.summary.Actions)) +- } +- if summary.Err != "" { +- continue // action failed +- } +- for _, gobDiag := range summary.Diagnostics { +- results = append(results, toSourceDiagnostic(srcAnalyzer, &gobDiag)) +- } - } - } - return results, nil -} - --// analysisKey is the type of keys in the snapshot.analyses map. --type analysisKey struct { -- analyzerNames string -- pkgid PackageID --} +-func (an *analysisNode) decrefPreds() { +- if atomic.AddInt32(&an.unfinishedPreds, -1) == 0 { +- an.summary.Actions = nil +- } +-} +- +-// An analysisNode is a node in a doubly-linked DAG isomorphic to the +-// import graph. Each node represents a single package, and the DAG +-// represents a batch of analysis work done at once using a single +-// realm of token.Pos or types.Object values. +-// +-// A complete DAG is created anew for each batch of analysis; +-// subgraphs are not reused over time. Each node's *types.Package +-// field is initially nil and is populated on demand, either from +-// type-checking syntax trees (typeCheck) or from importing export +-// data (_import). When this occurs, the typesOnce event becomes +-// "done". +-// +-// Each node's allDeps map is a "view" of all its dependencies keyed by +-// package path, which defines the types.Importer mapping used when +-// populating the node's types.Package. Different nodes have different +-// views (e.g. due to variants), but two nodes that are related by +-// graph ordering have views that are consistent in their overlap. +-// exportDeps is the subset actually referenced by export data; +-// this is the set for which we attempt to decode facts. +-// +-// Each node's run method is called in parallel postorder. On success, +-// its summary field is populated, either from the cache (hit), or by +-// type-checking and analyzing syntax (miss). +-type analysisNode struct { +- fset *token.FileSet // file set shared by entire batch (DAG) +- m *source.Metadata // metadata for this package +- files []source.FileHandle // contents of CompiledGoFiles +- analyzers []*analysis.Analyzer // set of analyzers to run +- preds []*analysisNode // graph edges: +- succs map[PackageID]*analysisNode // (preds -> self -> succs) +- unfinishedSuccs int32 +- unfinishedPreds int32 // effectively a summary.Actions refcount +- allDeps map[PackagePath]*analysisNode // all dependencies including self +- exportDeps map[PackagePath]*analysisNode // subset of allDeps ref'd by export data (+self) +- summary *analyzeSummary // serializable result of analyzing this package +- +- typesOnce sync.Once // guards lazy population of types and typesErr fields +- types *types.Package // type information lazily imported from summary +- typesErr error // an error producing type information +-} +- +-func (an *analysisNode) String() string { return string(an.m.ID) } +- +-// _import imports this node's types.Package from export data, if not already done. +-// Precondition: analysis was a success. +-// Postcondition: an.types and an.exportDeps are populated. +-func (an *analysisNode) _import() (*types.Package, error) { +- an.typesOnce.Do(func() { +- if an.m.PkgPath == "unsafe" { +- an.types = types.Unsafe +- return +- } +- +- an.types = types.NewPackage(string(an.m.PkgPath), string(an.m.Name)) - --func (key analysisKey) String() string { -- return fmt.Sprintf("%s@%s", key.analyzerNames, key.pkgid) +- // getPackages recursively imports each dependency +- // referenced by the export data, in parallel. +- getPackages := func(items []gcimporter.GetPackagesItem) error { +- var g errgroup.Group +- for i, item := range items { +- path := PackagePath(item.Path) +- dep, ok := an.allDeps[path] +- if !ok { +- // This early return bypasses Wait; that's ok. +- return fmt.Errorf("%s: unknown dependency %q", an.m, path) +- } +- an.exportDeps[path] = dep // record, for later fact decoding +- if dep == an { +- if an.typesErr != nil { +- return an.typesErr +- } else { +- items[i].Pkg = an.types +- } +- } else { +- i := i +- g.Go(func() error { +- depPkg, err := dep._import() +- if err == nil { +- items[i].Pkg = depPkg +- } +- return err +- }) +- } +- } +- return g.Wait() +- } +- pkg, err := gcimporter.IImportShallow(an.fset, getPackages, an.summary.Export, string(an.m.PkgPath), bug.Reportf) +- if err != nil { +- an.typesErr = bug.Errorf("%s: invalid export data: %v", an.m, err) +- an.types = nil +- } else if pkg != an.types { +- log.Fatalf("%s: inconsistent packages", an.m) +- } +- }) +- return an.types, an.typesErr -} - -// analyzeSummary is a gob-serializable summary of successfully -// applying a list of analyzers to a package. -type analyzeSummary struct { -- PkgPath PackagePath // types.Package.Path() (needed to decode export data) -- Export []byte +- Export []byte // encoded types of package - DeepExportHash source.Hash // hash of reflexive transitive closure of export data - Compiles bool // transitively free of list/parse/type errors - Actions actionsMap // map from analyzer name to analysis results (*actionSummary) -- -- // Not serialized: populated after the summary is computed or deserialized. -- allExport map[PackagePath][]byte // transitive export data -} - -// actionsMap defines a stable Gob encoding for a map. -// TODO(adonovan): generalize and move to a library when we can use generics. -type actionsMap map[string]*actionSummary - --var _ gob.GobEncoder = (actionsMap)(nil) --var _ gob.GobDecoder = (*actionsMap)(nil) +-var ( +- _ gob.GobEncoder = (actionsMap)(nil) +- _ gob.GobDecoder = (*actionsMap)(nil) +-) - -type actionsMapEntry struct { - K string @@ -12305,133 +14046,16 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - Err string // "" => success -} - --// analyze is a memoization of analyzeImpl. --func (s *snapshot) analyze(ctx context.Context, id PackageID, analyzers []*analysis.Analyzer) (*analyzeSummary, error) { -- // Use the sorted list of names of analyzers in the key. -- // -- // TODO(adonovan): opt: account for analysis results at a -- // finer grain to avoid duplicate work when a -- // a proper subset of analyzers is requested? -- // In particular, TypeErrorAnalyzers don't use facts -- // but need to request vdeps just for type information. -- names := make([]string, 0, len(analyzers)) -- for _, a := range analyzers { -- names = append(names, a.Name) -- } -- // This key describes the result of applying a list of analyzers to a package. -- key := analysisKey{strings.Join(names, ","), id} -- -- // An analysisPromise represents the result of loading, parsing, -- // type-checking and analyzing a single package. -- type analysisPromise struct { -- promise *memoize.Promise // [analyzeImplResult] -- } -- -- type analyzeImplResult struct { -- summary *analyzeSummary -- err error -- } -- -- // Access the map once, briefly, and atomically. -- s.mu.Lock() -- entry, hit := s.analyses.Get(key) -- if !hit { -- entry = analysisPromise{ -- promise: memoize.NewPromise("analysis", func(ctx context.Context, arg interface{}) interface{} { -- summary, err := analyzeImpl(ctx, arg.(*snapshot), analyzers, id) -- return analyzeImplResult{summary, err} -- }), -- } -- s.analyses.Set(key, entry, nil) // nothing needs releasing -- } -- s.mu.Unlock() -- -- // Await result. -- ap := entry.(analysisPromise) -- v, err := s.awaitPromise(ctx, ap.promise) -- if err != nil { -- return nil, err // e.g. cancelled -- } -- res := v.(analyzeImplResult) -- return res.summary, res.err --} -- --// analyzeImpl applies a list of analyzers (plus any others +-// runCached applies a list of analyzers (plus any others -// transitively required by them) to a package. It succeeds as long -// as it could produce a types.Package, even if there were direct or -// indirect list/parse/type errors, and even if all the analysis -// actions failed. It usually fails only if the package was unknown, -// a file was missing, or the operation was cancelled. -// --// Postcondition: analyzeImpl must not continue to use the snapshot +-// Postcondition: runCached must not continue to use the snapshot -// (in background goroutines) after it has returned; see memoize.RefCounted. --func analyzeImpl(ctx context.Context, snapshot *snapshot, analyzers []*analysis.Analyzer, id PackageID) (*analyzeSummary, error) { -- m := snapshot.Metadata(id) -- if m == nil { -- return nil, fmt.Errorf("no metadata for %s", id) -- } -- -- // Recursively analyze each "vertical" dependency -- // for its types.Package and (perhaps) analysis.Facts. -- // If any of them fails to produce a package, we cannot continue. -- // We request only the analyzers that produce facts. -- // -- // Also, load the contents of each "compiled" Go file through -- // the snapshot's cache. -- // -- // Both loops occur in parallel, and parallel with each other. -- vdeps := make(map[PackageID]*analyzeSummary) -- compiledGoFiles := make([]source.FileHandle, len(m.CompiledGoFiles)) -- { -- var group errgroup.Group -- -- // Analyze vertical dependencies. -- // We request only the required analyzers that use facts. -- var useFacts []*analysis.Analyzer -- for _, a := range requiredAnalyzers(analyzers) { -- if len(a.FactTypes) > 0 { -- useFacts = append(useFacts, a) -- } -- } -- var vdepsMu sync.Mutex -- for _, id := range m.DepsByPkgPath { -- id := id -- group.Go(func() error { -- res, err := snapshot.analyze(ctx, id, useFacts) -- if err != nil { -- return err // cancelled, or failed to produce a package -- } -- -- vdepsMu.Lock() -- vdeps[id] = res -- vdepsMu.Unlock() -- return nil -- }) -- } -- -- // Read file contents. -- // (In practice these will be cache hits -- // on reads done by the initial workspace load -- // or after a change modification event.) -- for i, uri := range m.CompiledGoFiles { -- i, uri := i, uri -- group.Go(func() error { -- fh, err := snapshot.GetFile(ctx, uri) // ~25us -- compiledGoFiles[i] = fh -- return err // e.g. cancelled -- }) -- } -- -- if err := group.Wait(); err != nil { -- return nil, err -- } -- } -- -- // Inv: analyze() of all vdeps succeeded (though some actions may have failed). -- -- // We no longer depend on the snapshot. -- snapshot = nil -- +-func (an *analysisNode) runCached(ctx context.Context) (*analyzeSummary, error) { - // At this point we have the action results (serialized - // packages and facts) of our immediate dependencies, - // and the metadata and content of this package. @@ -12443,62 +14067,54 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // The hash of our inputs is based on the serialized export - // data and facts so that immaterial changes can be pruned - // without decoding. -- key := analysisCacheKey(analyzers, m, compiledGoFiles, vdeps) +- key := an.cacheKey() - - // Access the cache. - var summary *analyzeSummary - const cacheKind = "analysis" - if data, err := filecache.Get(cacheKind, key); err == nil { - // cache hit -- mustDecode(data, &summary) -- +- analyzeSummaryCodec.Decode(data, &summary) - } else if err != filecache.ErrNotFound { - return nil, bug.Errorf("internal error reading shared cache: %v", err) -- - } else { - // Cache miss: do the work. - var err error -- summary, err = actuallyAnalyze(ctx, analyzers, m, vdeps, compiledGoFiles) +- summary, err = an.run(ctx) - if err != nil { - return nil, err - } -- data := mustEncode(summary) -- if false { -- log.Printf("Set key=%d value=%d id=%s\n", len(key), len(data), id) -- } -- if err := filecache.Set(cacheKind, key, data); err != nil { -- return nil, fmt.Errorf("internal error updating shared cache: %v", err) -- } -- } - -- // Hit or miss, we need to merge the export data from -- // dependencies so that it includes all the types -- // that might be summoned by the type checker. -- // -- // TODO(adonovan): opt: reduce this set by recording -- // which packages were actually summoned by insert(). -- // (Just makes map smaller; probably marginal?) -- allExport := make(map[PackagePath][]byte) -- for _, vdep := range vdeps { -- for k, v := range vdep.allExport { -- allExport[k] = v -- } +- atomic.AddInt32(&an.unfinishedPreds, +1) // incref +- go func() { +- defer an.decrefPreds() //decref +- +- cacheLimit <- unit{} // acquire token +- defer func() { <-cacheLimit }() // release token +- +- data := analyzeSummaryCodec.Encode(summary) +- if false { +- log.Printf("Set key=%d value=%d id=%s\n", len(key), len(data), an.m.ID) +- } +- if err := filecache.Set(cacheKind, key, data); err != nil { +- event.Error(ctx, "internal error updating analysis shared cache", err) +- } +- }() - } -- allExport[m.PkgPath] = summary.Export -- summary.allExport = allExport - - return summary, nil -} - +-// cacheLimit reduces parallelism of cache updates. +-// We allow more than typical GOMAXPROCS as it's a mix of CPU and I/O. +-var cacheLimit = make(chan unit, 32) +- -// analysisCacheKey returns a cache key that is a cryptographic digest -// of the all the values that might affect type checking and analysis: -// the analyzer names, package metadata, names and contents of --// compiled Go files, and vdeps information (export data and facts). --// --// TODO(adonovan): safety: define our own flavor of Metadata --// containing just the fields we need, and using it in the subsequent --// logic, to keep us honest about hashing all parts that matter? --func analysisCacheKey(analyzers []*analysis.Analyzer, m *source.Metadata, compiledGoFiles []source.FileHandle, vdeps map[PackageID]*analyzeSummary) [sha256.Size]byte { +-// compiled Go files, and vdeps (successor) information +-// (export data and facts). +-func (an *analysisNode) cacheKey() [sha256.Size]byte { - hasher := sha256.New() - - // In principle, a key must be the hash of an @@ -12506,21 +14122,21 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // If it's ambiguous, we risk collisions. - - // analyzers -- fmt.Fprintf(hasher, "analyzers: %d\n", len(analyzers)) -- for _, a := range analyzers { +- fmt.Fprintf(hasher, "analyzers: %d\n", len(an.analyzers)) +- for _, a := range an.analyzers { - fmt.Fprintln(hasher, a.Name) - } - - // package metadata +- m := an.m - fmt.Fprintf(hasher, "package: %s %s %s\n", m.ID, m.Name, m.PkgPath) - // We can ignore m.DepsBy{Pkg,Import}Path: although the logic - // uses those fields, we account for them by hashing vdeps. - - // type sizes -- // This assertion is safe, but if a black-box implementation -- // is ever needed, record Sizeof(*int) and Alignof(int64). -- sz := m.TypesSizes.(*types.StdSizes) -- fmt.Fprintf(hasher, "sizes: %d %d\n", sz.WordSize, sz.MaxAlign) +- wordSize := an.m.TypesSizes.Sizeof(types.Typ[types.Int]) +- maxAlign := an.m.TypesSizes.Alignof(types.NewPointer(types.Typ[types.Int64])) +- fmt.Fprintf(hasher, "sizes: %d %d\n", wordSize, maxAlign) - - // metadata errors: used for 'compiles' field - fmt.Fprintf(hasher, "errors: %d", len(m.Errors)) @@ -12531,30 +14147,31 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - - // file names and contents -- fmt.Fprintf(hasher, "files: %d\n", len(compiledGoFiles)) -- for _, fh := range compiledGoFiles { +- fmt.Fprintf(hasher, "files: %d\n", len(an.files)) +- for _, fh := range an.files { - fmt.Fprintln(hasher, fh.FileIdentity()) - } - - // vdeps, in PackageID order -- depIDs := make([]string, 0, len(vdeps)) -- for depID := range vdeps { +- depIDs := make([]string, 0, len(an.succs)) +- for depID := range an.succs { - depIDs = append(depIDs, string(depID)) - } -- sort.Strings(depIDs) +- sort.Strings(depIDs) // TODO(adonovan): avoid conversions by using slices.Sort[PackageID] - for _, depID := range depIDs { -- vdep := vdeps[PackageID(depID)] -- fmt.Fprintf(hasher, "dep: %s\n", vdep.PkgPath) -- fmt.Fprintf(hasher, "export: %s\n", vdep.DeepExportHash) +- vdep := an.succs[PackageID(depID)] +- fmt.Fprintf(hasher, "dep: %s\n", vdep.m.PkgPath) +- fmt.Fprintf(hasher, "export: %s\n", vdep.summary.DeepExportHash) - - // action results: errors and facts -- names := make([]string, 0, len(vdep.Actions)) -- for name := range vdep.Actions { +- actions := vdep.summary.Actions +- names := make([]string, 0, len(actions)) +- for name := range actions { - names = append(names, name) - } - sort.Strings(names) - for _, name := range names { -- summary := vdep.Actions[name] +- summary := actions[name] - fmt.Fprintf(hasher, "action %s\n", name) - if summary.Err != "" { - fmt.Fprintf(hasher, "error %s\n", summary.Err) @@ -12571,24 +14188,26 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - return hash -} - --// actuallyAnalyze implements the cache-miss case. +-// run implements the cache-miss case. -// This function does not access the snapshot. --func actuallyAnalyze(ctx context.Context, analyzers []*analysis.Analyzer, m *source.Metadata, vdeps map[PackageID]*analyzeSummary, compiledGoFiles []source.FileHandle) (*analyzeSummary, error) { -- -- // Create a local FileSet for processing this package only. -- fset := token.NewFileSet() -- +-// +-// Postcondition: on success, the analyzeSummary.Actions +-// key set is {a.Name for a in analyzers}. +-func (an *analysisNode) run(ctx context.Context) (*analyzeSummary, error) { - // Parse only the "compiled" Go files. - // Do the computation in parallel. -- parsed := make([]*source.ParsedGoFile, len(compiledGoFiles)) +- parsed := make([]*source.ParsedGoFile, len(an.files)) - { - var group errgroup.Group -- for i, fh := range compiledGoFiles { +- group.SetLimit(4) // not too much: run itself is already called in parallel +- for i, fh := range an.files { - i, fh := i, fh - group.Go(func() error { - // Call parseGoImpl directly, not the caching wrapper, - // as cached ASTs require the global FileSet. -- pgf, err := parseGoImpl(ctx, fset, fh, source.ParseFull) +- // ast.Object resolution is unfortunately an implied part of the +- // go/analysis contract. +- pgf, err := parseGoImpl(ctx, an.fset, fh, source.ParseFull&^source.SkipObjectResolution, false) - parsed[i] = pgf - return err - }) @@ -12598,23 +14217,52 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - } - -- // Type-check the package. -- pkg := typeCheckForAnalysis(fset, parsed, m, vdeps) +- // Type-check the package syntax. +- pkg := an.typeCheck(parsed) - -- // Build a map of PkgPath to *Package for all packages mentioned -- // in exportdata for use by facts. -- pkg.factsDecoder = facts.NewDecoder(pkg.types) +- // Publish the completed package. +- an.typesOnce.Do(func() { an.types = pkg.types }) +- if an.types != pkg.types { +- log.Fatalf("typesOnce prematurely done") +- } +- +- // Compute the union of exportDeps across our direct imports. +- // This is the set that will be needed by the fact decoder. +- allExportDeps := make(map[PackagePath]*analysisNode) +- for _, succ := range an.succs { +- for k, v := range succ.exportDeps { +- allExportDeps[k] = v +- } +- } +- +- // The fact decoder needs a means to look up a Package by path. +- pkg.factsDecoder = facts.NewDecoderFunc(pkg.types, func(path string) *types.Package { +- // Note: Decode is called concurrently, and thus so is this function. +- +- // Does the fact relate to a package referenced by export data? +- if dep, ok := allExportDeps[PackagePath(path)]; ok { +- dep.typesOnce.Do(func() { log.Fatal("dep.types not populated") }) +- if dep.typesErr == nil { +- return dep.types +- } +- return nil +- } +- +- // If the fact relates to a dependency not referenced +- // by export data, it is safe to ignore it. +- // (In that case dep.types exists but may be unpopulated +- // or in the process of being populated from export data.) +- if an.allDeps[PackagePath(path)] == nil { +- log.Fatalf("fact package %q is not a dependency", path) +- } +- return nil +- }) - - // Poll cancellation state. - if err := ctx.Err(); err != nil { - return nil, err - } - -- // TODO(adonovan): port the old logic to: -- // - gather go/packages diagnostics from m.Errors? (port goPackagesErrorDiagnostics) -- // - record unparseable file URIs so we can suppress type errors for these files. -- // - gather diagnostics from expandErrors + typeErrorDiagnostics + depsErrors. -- - // -- analysis -- - - // Build action graph for this package. @@ -12628,7 +14276,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - for _, req := range a.Requires { - hdeps = append(hdeps, mkAction(req)) - } -- act = &action{a: a, pkg: pkg, vdeps: vdeps, hdeps: hdeps} +- act = &action{a: a, pkg: pkg, vdeps: an.succs, hdeps: hdeps} - actions[a] = act - } - return act @@ -12636,12 +14284,13 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - - // Build actions for initial package. - var roots []*action -- for _, a := range analyzers { +- for _, a := range an.analyzers { - roots = append(roots, mkAction(a)) - } - - // Execute the graph in parallel. - execActions(roots) +- // Inv: each root's summary is set (whether success or error). - - // Don't return (or cache) the result in case of cancellation. - if err := ctx.Err(); err != nil { @@ -12650,12 +14299,14 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - - // Return summaries only for the requested actions. - summaries := make(map[string]*actionSummary) -- for _, act := range roots { -- summaries[act.a.Name] = act.summary +- for _, root := range roots { +- if root.summary == nil { +- panic("root has nil action.summary (#60551)") +- } +- summaries[root.a.Name] = root.summary - } - - return &analyzeSummary{ -- PkgPath: PackagePath(pkg.types.Path()), - Export: pkg.export, - DeepExportHash: pkg.deepExportHash, - Compiles: pkg.compiles, @@ -12663,14 +14314,17 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - }, nil -} - --func typeCheckForAnalysis(fset *token.FileSet, parsed []*source.ParsedGoFile, m *source.Metadata, vdeps map[PackageID]*analyzeSummary) *analysisPackage { +-// Postcondition: analysisPackage.types and an.exportDeps are populated. +-func (an *analysisNode) typeCheck(parsed []*source.ParsedGoFile) *analysisPackage { +- m := an.m +- - if false { // debugging -- log.Println("typeCheckForAnalysis", m.PkgPath) +- log.Println("typeCheck", m.ID) - } - - pkg := &analysisPackage{ - m: m, -- fset: fset, +- fset: an.fset, - parsed: parsed, - files: make([]*ast.File, len(parsed)), - compiles: len(m.Errors) == 0, // false => list error @@ -12687,81 +14341,22 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - typeparams.InitInstanceInfo(pkg.typesInfo) - -- for i, p := range parsed { -- pkg.files[i] = p.File -- if p.ParseErr != nil { -- pkg.compiles = false // parse error -- } -- } -- -- // Unsafe is special. +- // Unsafe has no syntax. - if m.PkgPath == "unsafe" { - pkg.types = types.Unsafe - return pkg - } - -- // Compute the union of transitive export data. -- // (The actual values are shared, and not serialized.) -- allExport := make(map[PackagePath][]byte) -- for _, vdep := range vdeps { -- for k, v := range vdep.allExport { -- allExport[k] = v -- } -- -- if !vdep.Compiles { -- pkg.compiles = false // transitive error +- for i, p := range parsed { +- pkg.files[i] = p.File +- if p.ParseErr != nil { +- pkg.compiles = false // parse error - } - } - -- // exportHasher computes a hash of the names and export data of -- // each package that was actually loaded during type checking. -- // -- // Because we use shallow export data, the hash for dependency -- // analysis must incorporate indirect dependencies. As an -- // optimization, we include only those that were actually -- // used, which may be a small subset of those available. -- // -- // TODO(adonovan): opt: even better would be to implement a -- // traversal over the package API like facts.NewDecoder does -- // and only mention that set of packages in the hash. -- // Perhaps there's a way to do that more efficiently. -- // -- // TODO(adonovan): opt: record the shallow hash alongside the -- // shallow export data in the allExport map to avoid repeatedly -- // hashing the export data. -- // -- // The writes to hasher below assume that type checking imports -- // packages in a deterministic order. -- exportHasher := sha256.New() -- hashExport := func(pkgPath PackagePath, export []byte) { -- fmt.Fprintf(exportHasher, "%s %d ", pkgPath, len(export)) -- exportHasher.Write(export) -- } -- -- // importer state -- var ( -- insert func(p *types.Package, name string) -- importMap = make(map[string]*types.Package) // keys are PackagePaths -- ) -- loadFromExportData := func(pkgPath PackagePath) (*types.Package, error) { -- export, ok := allExport[pkgPath] -- if !ok { -- return nil, bug.Errorf("missing export data for %q", pkgPath) -- } -- hashExport(pkgPath, export) -- imported, err := gcimporter.IImportShallow(fset, importMap, export, string(pkgPath), insert) -- if err != nil { -- return nil, bug.Errorf("invalid export data for %q: %v", pkgPath, err) -- } -- return imported, nil -- } -- insert = func(p *types.Package, name string) { -- imported, err := loadFromExportData(PackagePath(p.Path())) -- if err != nil { -- log.Fatalf("internal error: %v", err) -- } -- if imported != p { -- log.Fatalf("internal error: inconsistent packages") +- for _, vdep := range an.succs { +- if !vdep.summary.Compiles { +- pkg.compiles = false // transitive error - } - } - @@ -12769,19 +14364,25 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - Sizes: m.TypesSizes, - Error: func(e error) { - pkg.compiles = false // type error -- pkg.typeErrors = append(pkg.typeErrors, e.(types.Error)) +- +- // Suppress type errors in files with parse errors +- // as parser recovery can be quite lossy (#59888). +- typeError := e.(types.Error) +- for _, p := range parsed { +- if p.ParseErr != nil && source.NodeContains(p.File, typeError.Pos) { +- return +- } +- } +- pkg.typeErrors = append(pkg.typeErrors, typeError) - }, - Importer: importerFunc(func(importPath string) (*types.Package, error) { -- if importPath == "unsafe" { -- return types.Unsafe, nil // unsafe has no export data -- } -- - // Beware that returning an error from this function - // will cause the type checker to synthesize a fake - // package whose Path is importPath, potentially - // losing a vendor/ prefix. If type-checking errors - // are swallowed, these packages may be confusing. - +- // Map ImportPath to ID. - id, ok := m.DepsByImpPath[ImportPath(importPath)] - if !ok { - // The import syntax is inconsistent with the metadata. @@ -12792,22 +14393,23 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - return nil, fmt.Errorf("missing metadata for import of %q", importPath) - } - -- depResult, ok := vdeps[id] // id may be "" -- if !ok { +- // Map ID to node. (id may be "") +- dep := an.succs[id] +- if dep == nil { - // Analogous to (*snapshot).missingPkgError - // in the logic for regular type-checking, - // but without a snapshot we can't provide - // such detail, and anyway most analysis - // failures aren't surfaced in the UI. -- return nil, fmt.Errorf("no required module provides package %q (id=%q)", importPath, id) +- return nil, fmt.Errorf("no required module provides analysis package %q (id=%q)", importPath, id) - } - - // (Duplicates logic from check.go.) -- if !source.IsValidImport(m.PkgPath, depResult.PkgPath) { +- if !source.IsValidImport(an.m.PkgPath, dep.m.PkgPath) { - return nil, fmt.Errorf("invalid use of internal package %s", importPath) - } - -- return loadFromExportData(depResult.PkgPath) +- return dep._import() - }), - } - @@ -12827,7 +14429,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // TODO(adonovan): do we actually need this?? - typesinternal.SetUsesCgo(cfg) - -- check := types.NewChecker(cfg, fset, pkg.types, pkg.typesInfo) +- check := types.NewChecker(cfg, pkg.fset, pkg.types, pkg.typesInfo) - - // Type checking errors are handled via the config, so ignore them here. - _ = check.Files(pkg.files) @@ -12839,8 +14441,8 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - } - -- // Emit the export data and compute the deep hash. -- export, err := gcimporter.IExportShallow(pkg.fset, pkg.types) +- // Emit the export data and compute the recursive hash. +- export, err := gcimporter.IExportShallow(pkg.fset, pkg.types, bug.Reportf) - if err != nil { - // TODO(adonovan): in light of exporter bugs such as #57729, - // consider using bug.Report here and retrying the IExportShallow @@ -12848,12 +14450,56 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - log.Fatalf("internal error writing shallow export data: %v", err) - } - pkg.export = export -- hashExport(m.PkgPath, export) -- exportHasher.Sum(pkg.deepExportHash[:0]) +- +- // Compute a recursive hash to account for the export data of +- // this package and each dependency referenced by it. +- // Also, populate exportDeps. +- hash := sha256.New() +- fmt.Fprintf(hash, "%s %d\n", m.PkgPath, len(export)) +- hash.Write(export) +- paths, err := readShallowManifest(export) +- if err != nil { +- log.Fatalf("internal error: bad export data: %v", err) +- } +- for _, path := range paths { +- dep, ok := an.allDeps[PackagePath(path)] +- if !ok { +- log.Fatalf("%s: missing dependency: %q", an, path) +- } +- fmt.Fprintf(hash, "%s %s\n", dep.m.PkgPath, dep.summary.DeepExportHash) +- an.exportDeps[PackagePath(path)] = dep +- } +- an.exportDeps[m.PkgPath] = an // self +- hash.Sum(pkg.deepExportHash[:0]) - - return pkg -} - +-// readShallowManifest returns the manifest of packages referenced by +-// a shallow export data file for a package (excluding the package itself). +-// TODO(adonovan): add a test. +-func readShallowManifest(export []byte) ([]PackagePath, error) { +- const selfPath = "" // dummy path +- var paths []PackagePath +- getPackages := func(items []gcimporter.GetPackagesItem) error { +- paths = []PackagePath{} // non-nil +- for _, item := range items { +- if item.Path != selfPath { +- paths = append(paths, PackagePath(item.Path)) +- } +- } +- return errors.New("stop") // terminate importer +- } +- _, err := gcimporter.IImportShallow(token.NewFileSet(), getPackages, export, selfPath, bug.Reportf) +- if paths == nil { +- if err != nil { +- return nil, err // failed before getPackages callback +- } +- return nil, bug.Errorf("internal error: IImportShallow did not call getPackages") +- } +- return paths, nil // success +-} +- -// analysisPackage contains information about a package, including -// syntax trees, used transiently during its type-checking and analysis. -type analysisPackage struct { @@ -12879,8 +14525,8 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - once sync.Once - a *analysis.Analyzer - pkg *analysisPackage -- hdeps []*action // horizontal dependencies -- vdeps map[PackageID]*analyzeSummary // vertical dependencies +- hdeps []*action // horizontal dependencies +- vdeps map[PackageID]*analysisNode // vertical dependencies - - // results of action.exec(): - result interface{} // result of Run function, of type a.ResultType @@ -12893,6 +14539,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal -} - -// execActions executes a set of action graph nodes in parallel. +-// Postcondition: each action.summary is set, even in case of error. -func execActions(actions []*action) { - var wg sync.WaitGroup - for _, act := range actions { @@ -12913,6 +14560,9 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - } - }) +- if act.summary == nil { +- panic("nil action.summary (#60551)") +- } - }() - } - wg.Wait() @@ -12934,9 +14584,9 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // we return the dependencies' error' unadorned. - if hasFacts { - // TODO(adonovan): use deterministic order. -- for _, res := range act.vdeps { -- if vdep := res.Actions[analyzer.Name]; vdep.Err != "" { -- return nil, nil, errors.New(vdep.Err) +- for _, vdep := range act.vdeps { +- if summ := vdep.summary.Actions[analyzer.Name]; summ.Err != "" { +- return nil, nil, errors.New(summ.Err) - } - } - } @@ -12958,7 +14608,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - } - - // Gather analysis Result values from horizontal dependencies. -- var inputs = make(map[*analysis.Analyzer]interface{}) +- inputs := make(map[*analysis.Analyzer]interface{}) - for _, dep := range act.hdeps { - inputs[dep.a] = dep.result - } @@ -12967,26 +14617,28 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // efficient to fork and tailor it to our precise needs. - // - // We've already sharded the fact encoding by action -- // so that it can be done in parallel (hoisting the -- // ImportMap call so that we build the map once per package). +- // so that it can be done in parallel. - // We could eliminate locking. - // We could also dovetail more closely with the export data - // decoder to obtain a more compact representation of - // packages and objects (e.g. its internal IDs, instead - // of PkgPaths and objectpaths.) +- // More importantly, we should avoid re-export of +- // facts that related to objects that are discarded +- // by "deep" export data. Better still, use a "shallow" approach. - -- // Read and decode analysis facts for each imported package. -- factset, err := pkg.factsDecoder.Decode(func(imp *types.Package) ([]byte, error) { +- // Read and decode analysis facts for each direct import. +- factset, err := pkg.factsDecoder.Decode(true, func(pkgPath string) ([]byte, error) { - if !hasFacts { - return nil, nil // analyzer doesn't use facts, so no vdeps - } - - // Package.Imports() may contain a fake "C" package. Ignore it. -- if imp.Path() == "C" { +- if pkgPath == "C" { - return nil, nil - } - -- id, ok := pkg.m.DepsByPkgPath[PackagePath(imp.Path())] +- id, ok := pkg.m.DepsByPkgPath[PackagePath(pkgPath)] - if !ok { - // This may mean imp was synthesized by the type - // checker because it failed to import it for any reason @@ -13002,11 +14654,12 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - return nil, nil - } - -- vdep, ok := act.vdeps[id] -- if !ok { +- vdep := act.vdeps[id] +- if vdep == nil { - return nil, bug.Errorf("internal error in %s: missing vdep for id=%s", pkg.types.Path(), id) - } -- return vdep.Actions[analyzer.Name].Facts, nil +- +- return vdep.summary.Actions[analyzer.Name].Facts, nil - }) - if err != nil { - return nil, nil, fmt.Errorf("internal error decoding analysis facts: %w", err) @@ -13047,14 +14700,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - TypeErrors: pkg.typeErrors, - ResultOf: inputs, - Report: func(d analysis.Diagnostic) { -- // Prefix the diagnostic category with the analyzer's name. -- if d.Category == "" { -- d.Category = analyzer.Name -- } else { -- d.Category = analyzer.Name + "." + d.Category -- } -- -- diagnostic, err := toGobDiagnostic(posToLocation, d) +- diagnostic, err := toGobDiagnostic(posToLocation, analyzer, d) - if err != nil { - bug.Reportf("internal error converting diagnostic from analyzer %q: %v", analyzer.Name, err) - return @@ -13073,6 +14719,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - // (Use an anonymous function to limit the recover scope.) - var result interface{} - func() { +- start := time.Now() - defer func() { - if r := recover(); r != nil { - // An Analyzer panicked, likely due to a bug. @@ -13095,7 +14742,13 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - err = fmt.Errorf("analysis %s for package %s panicked: %v", analyzer.Name, pass.Pkg.Path(), r) - } - } +- +- // Accumulate running time for each checker. +- analyzerRunTimesMu.Lock() +- analyzerRunTimes[analyzer] += time.Since(start) +- analyzerRunTimesMu.Unlock() - }() +- - result, err = pass.Analyzer.Run(pass) - }() - if err != nil { @@ -13117,7 +14770,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - panic(fmt.Sprintf("%v: Pass.ExportPackageFact(%T) called after Run", act, fact)) - } - -- factsdata := factset.Encode() +- factsdata := factset.Encode(true) - return result, &actionSummary{ - Diagnostics: diagnostics, - Facts: factsdata, @@ -13125,6 +14778,32 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - }, nil -} - +-var ( +- analyzerRunTimesMu sync.Mutex +- analyzerRunTimes = make(map[*analysis.Analyzer]time.Duration) +-) +- +-type LabelDuration struct { +- Label string +- Duration time.Duration +-} +- +-// AnalyzerTimes returns the accumulated time spent in each Analyzer's +-// Run function since process start, in descending order. +-func AnalyzerRunTimes() []LabelDuration { +- analyzerRunTimesMu.Lock() +- defer analyzerRunTimesMu.Unlock() +- +- slice := make([]LabelDuration, 0, len(analyzerRunTimes)) +- for a, t := range analyzerRunTimes { +- slice = append(slice, LabelDuration{Label: a.Name, Duration: t}) +- } +- sort.Slice(slice, func(i, j int) bool { +- return slice[i].Duration > slice[j].Duration +- }) +- return slice +-} +- -// requiredAnalyzers returns the transitive closure of required analyzers in preorder. -func requiredAnalyzers(analyzers []*analysis.Analyzer) []*analysis.Analyzer { - var result []*analysis.Analyzer @@ -13143,22 +14822,13 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - return result -} - --func mustEncode(x interface{}) []byte { -- var buf bytes.Buffer -- if err := gob.NewEncoder(&buf).Encode(x); err != nil { -- log.Fatalf("internal error encoding %T: %v", x, err) -- } -- return buf.Bytes() --} -- --func mustDecode(data []byte, ptr interface{}) { -- if err := gob.NewDecoder(bytes.NewReader(data)).Decode(ptr); err != nil { -- log.Fatalf("internal error decoding %T: %v", ptr, err) -- } --} +-var analyzeSummaryCodec = frob.CodecFor[*analyzeSummary]() - -// -- data types for serialization of analysis.Diagnostic and source.Diagnostic -- - +-// (The name says gob but we use frob.) +-var diagnosticsCodec = frob.CodecFor[[]gobDiagnostic]() +- -type gobDiagnostic struct { - Location protocol.Location - Severity protocol.DiagnosticSeverity @@ -13196,7 +14866,7 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - -// toGobDiagnostic converts an analysis.Diagnosic to a serializable gobDiagnostic, -// which requires expanding token.Pos positions into protocol.Location form. --func toGobDiagnostic(posToLocation func(start, end token.Pos) (protocol.Location, error), diag analysis.Diagnostic) (gobDiagnostic, error) { +-func toGobDiagnostic(posToLocation func(start, end token.Pos) (protocol.Location, error), a *analysis.Analyzer, diag analysis.Diagnostic) (gobDiagnostic, error) { - var fixes []gobSuggestedFix - for _, fix := range diag.SuggestedFixes { - var gobEdits []gobTextEdit @@ -13233,23 +14903,47 @@ diff -urN a/gopls/internal/lsp/cache/analysis.go b/gopls/internal/lsp/cache/anal - return gobDiagnostic{}, err - } - +- // The Code column of VSCode's Problems table renders this +- // information as "Source(Code)" where code is a link to CodeHref. +- // (The code field must be nonempty for anything to appear.) +- diagURL := effectiveURL(a, diag) +- code := "default" +- if diag.Category != "" { +- code = diag.Category +- } +- - return gobDiagnostic{ - Location: loc, -- // Severity for analysis diagnostics is dynamic, based on user -- // configuration per analyzer. -- // Code and CodeHref are unset for Analysis diagnostics, -- // TODO(rfindley): set Code fields if/when golang/go#57906 is accepted. -- Source: diag.Category, +- // Severity for analysis diagnostics is dynamic, +- // based on user configuration per analyzer. +- Code: code, +- CodeHref: diagURL, +- Source: a.Name, - Message: diag.Message, - SuggestedFixes: fixes, - Related: related, - // Analysis diagnostics do not contain tags. - }, nil -} +- +-// effectiveURL computes the effective URL of diag, +-// using the algorithm specified at Diagnostic.URL. +-func effectiveURL(a *analysis.Analyzer, diag analysis.Diagnostic) string { +- u := diag.URL +- if u == "" && diag.Category != "" { +- u = "#" + diag.Category +- } +- if base, err := urlpkg.Parse(a.URL); err == nil { +- if rel, err := urlpkg.Parse(u); err == nil { +- u = base.ResolveReference(rel).String() +- } +- } +- return u +-} diff -urN a/gopls/internal/lsp/cache/cache.go b/gopls/internal/lsp/cache/cache.go --- a/gopls/internal/lsp/cache/cache.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/cache.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,78 +0,0 @@ +@@ -1,86 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -13261,6 +14955,7 @@ diff -urN a/gopls/internal/lsp/cache/cache.go b/gopls/internal/lsp/cache/cache.g - "reflect" - "strconv" - "sync/atomic" +- "time" - - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/internal/event" @@ -13319,6 +15014,7 @@ diff -urN a/gopls/internal/lsp/cache/cache.go b/gopls/internal/lsp/cache/cache.g - gocmdRunner: &gocommand.Runner{}, - options: options, - overlayFS: newOverlayFS(c), +- parseCache: newParseCache(1 * time.Minute), // keep recently parsed files for a minute, to optimize typing CPU - } - event.Log(ctx, "New session", KeyCreateSession.Of(s)) - return s @@ -13328,10 +15024,16 @@ diff -urN a/gopls/internal/lsp/cache/cache.go b/gopls/internal/lsp/cache/cache.g - -func (c *Cache) ID() string { return c.id } -func (c *Cache) MemStats() map[reflect.Type]int { return c.store.Stats() } +- +-// FileStats returns information about the set of files stored in the cache. +-// It is intended for debugging only. +-func (c *Cache) FileStats() (files, largest, errs int) { +- return c.fileStats() +-} diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.go --- a/gopls/internal/lsp/cache/check.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/check.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1227 +0,0 @@ +@@ -1,1866 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -13343,56 +15045,72 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - "crypto/sha256" - "fmt" - "go/ast" +- "go/parser" - "go/token" - "go/types" -- "log" - "regexp" +- "runtime" - "sort" - "strings" - "sync" +- "sync/atomic" - - "golang.org/x/mod/module" - "golang.org/x/sync/errgroup" - "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/filecache" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/source/methodsets" -- "golang.org/x/tools/gopls/internal/lsp/source/xrefs" +- "golang.org/x/tools/gopls/internal/lsp/source/typerefs" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/tag" - "golang.org/x/tools/internal/gcimporter" -- "golang.org/x/tools/internal/memoize" - "golang.org/x/tools/internal/packagesinternal" +- "golang.org/x/tools/internal/tokeninternal" - "golang.org/x/tools/internal/typeparams" - "golang.org/x/tools/internal/typesinternal" -) - +-// Various optimizations that should not affect correctness. +-const ( +- preserveImportGraph = true // hold on to the import graph for open packages +-) +- +-type unit = struct{} +- -// A typeCheckBatch holds data for a logical type-checking operation, which may -// type-check many unrelated packages. -// -// It shares state such as parsed files and imports, to optimize type-checking -// for packages with overlapping dependency graphs. -type typeCheckBatch struct { -- meta *metadataGraph -- -- parsedFiles map[span.URI]*source.ParsedGoFile // parsed files necessary for type-checking -- fset *token.FileSet // FileSet describing all parsed files +- activePackageCache interface { +- getActivePackage(id PackageID) *Package +- setActivePackage(id PackageID, pkg *Package) +- } +- syntaxIndex map[PackageID]int // requested ID -> index in ids +- pre preTypeCheck +- post postTypeCheck +- handles map[PackageID]*packageHandle +- parseCache *parseCache +- fset *token.FileSet // describes all parsed or imported files +- cpulimit chan unit // concurrency limiter for CPU-bound operations - -- // Promises holds promises to either read export data for the package, or -- // parse and type-check its syntax. -- // -- // The return value of these promises is not used: after promises are -- // awaited, they must write an entry into the imports map. -- promises map[PackageID]*memoize.Promise +- mu sync.Mutex +- syntaxPackages map[PackageID]*futurePackage // results of processing a requested package; may hold (nil, nil) +- importPackages map[PackageID]*futurePackage // package results to use for importing +-} - -- mu sync.Mutex -- needFiles map[span.URI]source.FileHandle // de-duplicated file handles required for type-checking -- imports map[PackageID]pkgOrErr // types.Packages to use for importing -- exportData map[PackageID][]byte -- packages map[PackageID]*Package +-// A futurePackage is a future result of type checking or importing a package, +-// to be cached in a map. +-// +-// The goroutine that creates the futurePackage is responsible for evaluating +-// its value, and closing the done channel. +-type futurePackage struct { +- done chan unit +- v pkgOrErr -} - -type pkgOrErr struct { @@ -13410,262 +15128,502 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g -// indicates context cancellation or otherwise significant failure to perform -// the type-checking operation. -func (s *snapshot) TypeCheck(ctx context.Context, ids ...PackageID) ([]source.Package, error) { -- // Check for existing active packages. -- // -- // Since gopls can't depend on package identity, any instance of the -- // requested package must be ok to return. -- // -- // This is an optimization to avoid redundant type-checking: following -- // changes to an open package many LSP clients send several successive -- // requests for package information for the modified package (semantic -- // tokens, code lens, inlay hints, etc.) - pkgs := make([]source.Package, len(ids)) -- needSyntax := make(map[PackageID]bool) +- +- var ( +- needIDs []PackageID // ids to type-check +- indexes []int // original index of requested ids +- ) +- +- // Check for existing active packages, as any package will do. +- // +- // This is also done inside forEachPackage, but doing it here avoids +- // unnecessary set up for type checking (e.g. assembling the package handle +- // graph). - for i, id := range ids { - if pkg := s.getActivePackage(id); pkg != nil { - pkgs[i] = pkg - } else { -- needSyntax[id] = true +- needIDs = append(needIDs, id) +- indexes = append(indexes, i) - } - } - -- if len(needSyntax) == 0 { -- return pkgs, nil +- post := func(i int, pkg *Package) { +- pkgs[indexes[i]] = pkg - } +- return pkgs, s.forEachPackage(ctx, needIDs, nil, post) +-} - -- // Build up shared state for efficient type-checking. -- b := &typeCheckBatch{ -- parsedFiles: make(map[span.URI]*source.ParsedGoFile), -- // fset is built during the parsing pass. -- needFiles: make(map[span.URI]source.FileHandle), +-// getImportGraph returns a shared import graph use for this snapshot, or nil. +-// +-// This is purely an optimization: holding on to more imports allows trading +-// memory for CPU and latency. Currently, getImportGraph returns an import +-// graph containing all packages imported by open packages, since these are +-// highly likely to be needed when packages change. +-// +-// Furthermore, since we memoize active packages, including their imports in +-// the shared import graph means we don't run the risk of pinning duplicate +-// copies of common imports, if active packages are computed in separate type +-// checking batches. +-func (s *snapshot) getImportGraph(ctx context.Context) *importGraph { +- if !preserveImportGraph { +- return nil +- } +- s.mu.Lock() - -- promises: make(map[PackageID]*memoize.Promise), -- imports: make(map[PackageID]pkgOrErr), -- exportData: make(map[PackageID][]byte), -- packages: make(map[PackageID]*Package), +- // Evaluate the shared import graph for the snapshot. There are three major +- // codepaths here: +- // +- // 1. importGraphDone == nil, importGraph == nil: it is this goroutine's +- // responsibility to type-check the shared import graph. +- // 2. importGraphDone == nil, importGraph != nil: it is this goroutine's +- // responsibility to resolve the import graph, which may result in +- // type-checking only if the existing importGraph (carried over from the +- // preceding snapshot) is invalid. +- // 3. importGraphDone != nil: some other goroutine is doing (1) or (2), wait +- // for the work to be done. +- done := s.importGraphDone +- if done == nil { +- done = make(chan unit) +- s.importGraphDone = done +- release := s.Acquire() // must acquire to use the snapshot asynchronously +- go func() { +- defer release() +- importGraph, err := s.resolveImportGraph() // may be nil +- if err != nil { +- if ctx.Err() == nil { +- event.Error(ctx, "computing the shared import graph", err) +- } +- importGraph = nil +- } +- s.mu.Lock() +- s.importGraph = importGraph +- s.mu.Unlock() +- close(done) +- }() +- } +- s.mu.Unlock() +- +- select { +- case <-done: +- return s.importGraph +- case <-ctx.Done(): +- return nil - } +-} +- +-// resolveImportGraph evaluates the shared import graph to use for +-// type-checking in this snapshot. This may involve re-using the import graph +-// of the previous snapshot (stored in s.importGraph), or computing a fresh +-// import graph. +-// +-// resolveImportGraph should only be called from getImportGraph. +-func (s *snapshot) resolveImportGraph() (*importGraph, error) { +- ctx := s.backgroundCtx +- ctx, done := event.Start(event.Detach(ctx), "cache.resolveImportGraph") +- defer done() - -- // Capture metadata once to ensure a consistent view. - s.mu.Lock() -- b.meta = s.meta +- lastImportGraph := s.importGraph - s.mu.Unlock() - -- // -- Step 1: assemble the promises graph -- +- openPackages := make(map[PackageID]bool) +- for _, fh := range s.overlays() { +- meta, err := s.MetadataForFile(ctx, fh.URI()) +- if err != nil { +- return nil, err +- } +- source.RemoveIntermediateTestVariants(&meta) +- for _, m := range meta { +- openPackages[m.ID] = true +- } +- } - -- var ( -- needExportData = make(map[PackageID]packageHandleKey) -- packageHandles = make(map[PackageID]*packageHandle) -- ) +- var openPackageIDs []source.PackageID +- for id := range openPackages { +- openPackageIDs = append(openPackageIDs, id) +- } - -- // collectPromises collects promises to load packages from export data or -- // type-check. -- var collectPromises func(PackageID) error -- collectPromises = func(id PackageID) error { -- if _, ok := b.promises[id]; ok { -- return nil -- } -- b.promises[id] = nil // break cycles +- handles, err := s.getPackageHandles(ctx, openPackageIDs) +- if err != nil { +- return nil, err +- } - -- m := b.meta.metadata[id] -- if m == nil { -- return bug.Errorf("missing metadata for %v", id) +- // Subtlety: we erase the upward cone of open packages from the shared import +- // graph, to increase reusability. +- // +- // This is easiest to understand via an example: suppose A imports B, and B +- // imports C. Now suppose A and B are open. If we preserve the entire set of +- // shared deps by open packages, deps will be {B, C}. But this means that any +- // change to the open package B will invalidate the shared import graph, +- // meaning we will experience no benefit from sharing when B is edited. +- // Consider that this will be a common scenario, when A is foo_test and B is +- // foo. Better to just preserve the shared import C. +- // +- // With precise pruning, we may want to truncate this search based on +- // reachability. +- // +- // TODO(rfindley): this logic could use a unit test. +- volatileDeps := make(map[PackageID]bool) +- var isVolatile func(*packageHandle) bool +- isVolatile = func(ph *packageHandle) (volatile bool) { +- if v, ok := volatileDeps[ph.m.ID]; ok { +- return v - } -- for _, id := range m.DepsByPkgPath { -- if err := collectPromises(id); err != nil { -- return err +- defer func() { +- volatileDeps[ph.m.ID] = volatile +- }() +- if openPackages[ph.m.ID] { +- return true +- } +- for _, dep := range ph.m.DepsByPkgPath { +- if isVolatile(handles[dep]) { +- return true - } - } +- return false +- } +- for _, dep := range handles { +- isVolatile(dep) +- } +- for id, volatile := range volatileDeps { +- if volatile { +- delete(handles, id) +- } +- } - -- // Note that we can't reuse active packages here, as they will have the -- // wrong FileSet. Any active packages that exist as dependencies of other -- // packages will need to be loaded from export data. -- ph, err := s.buildPackageHandle(ctx, id) -- if err != nil { -- return err +- // We reuse the last import graph if and only if none of the dependencies +- // have changed. Doing better would involve analyzing dependencies to find +- // subgraphs that are still valid. Not worth it, especially when in the +- // common case nothing has changed. +- unchanged := lastImportGraph != nil && len(handles) == len(lastImportGraph.depKeys) +- var ids []PackageID +- depKeys := make(map[PackageID]source.Hash) +- for id, ph := range handles { +- ids = append(ids, id) +- depKeys[id] = ph.key +- if unchanged { +- prevKey, ok := lastImportGraph.depKeys[id] +- unchanged = ok && prevKey == ph.key - } -- packageHandles[id] = ph +- } - -- if needSyntax[id] { -- // We will need to parse and type-check this package. -- // -- // We may also need to parse and type-check if export data is missing, -- // but that is handled after fetching export data below. -- b.addNeededFiles(ph) -- } else if id != "unsafe" { // we can't load export data for unsafe -- needExportData[id] = ph.key -- } -- -- debugName := fmt.Sprintf("check(%s)", id) -- b.promises[id] = memoize.NewPromise(debugName, func(ctx context.Context, _ interface{}) interface{} { -- var res pkgOrErr -- if err := b.awaitPredecessors(ctx, ph.m); err != nil { -- res.err = err -- } else { -- b.mu.Lock() -- data, ok := b.exportData[id] -- b.mu.Unlock() +- if unchanged { +- return lastImportGraph, nil +- } - -- if ok { -- // We need export data, and have it. -- res.pkg, res.err = b.importPackage(ctx, m, data) -- } else if !needSyntax[id] { -- // We need only a types.Package, but don't have export data. -- // Type-check as fast as possible (skipping function bodies). -- res.pkg, res.err = b.checkPackageForImport(ctx, ph) -- } else { -- // We need a syntax package. -- var pkg *Package -- pkg, res.err = b.checkPackage(ctx, ph) -- if res.err == nil { -- res.pkg = pkg.pkg.types -- b.mu.Lock() -- b.packages[id] = pkg -- b.mu.Unlock() -- } -- } -- } +- b, err := s.forEachPackageInternal(ctx, nil, ids, nil, nil, nil, handles) +- if err != nil { +- return nil, err +- } - -- b.mu.Lock() -- b.imports[m.ID] = res -- b.mu.Unlock() -- return nil -- }) -- return nil +- next := &importGraph{ +- fset: b.fset, +- depKeys: depKeys, +- imports: make(map[PackageID]pkgOrErr), - } -- for id := range needSyntax { -- collectPromises(id) +- for id, fut := range b.importPackages { +- if fut.v.pkg == nil && fut.v.err == nil { +- panic(fmt.Sprintf("internal error: import node %s is not evaluated", id)) +- } +- next.imports[id] = fut.v - } +- return next, nil +-} - -- // -- Step 2: collect export data -- -- // -- // This must be done before parsing in order to determine which files must be -- // parsed. -- { -- var g errgroup.Group -- for id, key := range needExportData { -- id := id -- key := key -- g.Go(func() error { -- data, err := filecache.Get(exportDataKind, key) -- if err != nil { -- if err == filecache.ErrNotFound { -- ph := packageHandles[id] -- b.addNeededFiles(ph) // we will need to parse and type check -- return nil // ok: we will type check later -- } -- return err -- } -- b.mu.Lock() -- b.exportData[id] = data -- b.mu.Unlock() -- return nil -- }) -- } -- if err := g.Wait(); err != nil { -- return pkgs, err +-// An importGraph holds selected results of a type-checking pass, to be re-used +-// by subsequent snapshots. +-type importGraph struct { +- fset *token.FileSet // fileset used for type checking imports +- depKeys map[PackageID]source.Hash // hash of direct dependencies for this graph +- imports map[PackageID]pkgOrErr // results of type checking +-} +- +-// Package visiting functions used by forEachPackage; see the documentation of +-// forEachPackage for details. +-type ( +- preTypeCheck = func(int, *packageHandle) bool // false => don't type check +- postTypeCheck = func(int, *Package) +-) +- +-// forEachPackage does a pre- and post- order traversal of the packages +-// specified by ids using the provided pre and post functions. +-// +-// The pre func is optional. If set, pre is evaluated after the package +-// handle has been constructed, but before type-checking. If pre returns false, +-// type-checking is skipped for this package handle. +-// +-// post is called with a syntax package after type-checking completes +-// successfully. It is only called if pre returned true. +-// +-// Both pre and post may be called concurrently. +-func (s *snapshot) forEachPackage(ctx context.Context, ids []PackageID, pre preTypeCheck, post postTypeCheck) error { +- s.typeCheckMu.Lock() +- defer s.typeCheckMu.Unlock() +- +- ctx, done := event.Start(ctx, "cache.forEachPackage", tag.PackageCount.Of(len(ids))) +- defer done() +- +- if len(ids) == 0 { +- return nil // short cut: many call sites do not handle empty ids +- } +- +- handles, err := s.getPackageHandles(ctx, ids) +- if err != nil { +- return err +- } +- +- impGraph := s.getImportGraph(ctx) +- _, err = s.forEachPackageInternal(ctx, impGraph, nil, ids, pre, post, handles) +- return err +-} +- +-// forEachPackageInternal is used by both forEachPackage and loadImportGraph to +-// type-check a graph of packages. +-// +-// If a non-nil importGraph is provided, imports in this graph will be reused. +-func (s *snapshot) forEachPackageInternal(ctx context.Context, importGraph *importGraph, importIDs, syntaxIDs []PackageID, pre preTypeCheck, post postTypeCheck, handles map[PackageID]*packageHandle) (*typeCheckBatch, error) { +- b := &typeCheckBatch{ +- activePackageCache: s, +- pre: pre, +- post: post, +- handles: handles, +- parseCache: s.view.parseCache, +- fset: fileSetWithBase(reservedForParsing), +- syntaxIndex: make(map[PackageID]int), +- cpulimit: make(chan unit, runtime.GOMAXPROCS(0)), +- syntaxPackages: make(map[PackageID]*futurePackage), +- importPackages: make(map[PackageID]*futurePackage), +- } +- +- if importGraph != nil { +- // Clone the file set every time, to ensure we do not leak files. +- b.fset = tokeninternal.CloneFileSet(importGraph.fset) +- // Pre-populate future cache with 'done' futures. +- done := make(chan unit) +- close(done) +- for id, res := range importGraph.imports { +- b.importPackages[id] = &futurePackage{done, res} - } +- } else { +- b.fset = fileSetWithBase(reservedForParsing) +- } +- +- for i, id := range syntaxIDs { +- b.syntaxIndex[id] = i - } - -- // -- Step 3: parse files required for type checking. -- +- // Start a single goroutine for each requested package. - // -- // Parse all necessary files in parallel. Unfortunately we can't start -- // parsing each package's file as soon as we discover that it is a syntax -- // package, because the parseCache cannot add files to an existing FileSet. -- { -- var fhs []source.FileHandle -- for _, fh := range b.needFiles { -- fhs = append(fhs, fh) +- // Other packages are reached recursively, and will not be evaluated if they +- // are not needed. +- var g errgroup.Group +- for _, id := range importIDs { +- id := id +- g.Go(func() error { +- _, err := b.getImportPackage(ctx, id) +- return err +- }) +- } +- for i, id := range syntaxIDs { +- i := i +- id := id +- g.Go(func() error { +- _, err := b.handleSyntaxPackage(ctx, i, id) +- return err +- }) +- } +- return b, g.Wait() +-} +- +-// TODO(rfindley): re-order the declarations below to read better from top-to-bottom. +- +-// getImportPackage returns the *types.Package to use for importing the +-// package referenced by id. +-// +-// This may be the package produced by type-checking syntax (as in the case +-// where id is in the set of requested IDs), a package loaded from export data, +-// or a package type-checked for import only. +-func (b *typeCheckBatch) getImportPackage(ctx context.Context, id PackageID) (pkg *types.Package, err error) { +- b.mu.Lock() +- f, ok := b.importPackages[id] +- if ok { +- b.mu.Unlock() +- +- select { +- case <-ctx.Done(): +- return nil, ctx.Err() +- case <-f.done: +- return f.v.pkg, f.v.err - } -- pgfs, fset, err := s.parseCache.parseFiles(ctx, source.ParseFull, fhs...) +- } +- +- f = &futurePackage{done: make(chan unit)} +- b.importPackages[id] = f +- b.mu.Unlock() +- +- defer func() { +- f.v = pkgOrErr{pkg, err} +- close(f.done) +- }() +- +- if index, ok := b.syntaxIndex[id]; ok { +- pkg, err := b.handleSyntaxPackage(ctx, index, id) - if err != nil { -- return pkgs, err +- return nil, err - } -- for _, pgf := range pgfs { -- b.parsedFiles[pgf.URI] = pgf +- if pkg != nil { +- return pkg, nil - } -- b.fset = fset +- // type-checking was short-circuited by the pre- func. - } - -- // -- Step 4: await type-checking. -- -- // -- // Start a single goroutine for each promise. -- { -- var g errgroup.Group -- // TODO(rfindley): find a good way to limit concurrency of type-checking, -- // which is CPU bound at this point. -- // -- // (calling g.SetLimit here is mostly ineffective, as promises are -- // recursively concurrent.) -- for _, promise := range b.promises { -- promise := promise -- g.Go(func() error { -- _, err := promise.Get(ctx, nil) -- return err -- }) -- } -- if err := g.Wait(); err != nil { -- return pkgs, err -- } +- // unsafe cannot be imported or type-checked. +- if id == "unsafe" { +- return types.Unsafe, nil - } - -- // Fill in the gaps of the results slice. -- var firstErr error -- for i, id := range ids { -- if pkgs[i] != nil { -- continue -- } -- if err := b.imports[id].err; err != nil { -- if firstErr == nil { -- firstErr = err -- } -- continue -- } -- pkg := b.packages[id] -- if pkg == nil { -- panic("nil package") -- } -- if alt := s.memoizeActivePackage(id, pkg); alt != nil && alt != pkg { -- // pkg is an open package, but we've lost a race and an existing package -- // has already been memoized. -- pkg = alt -- } -- pkgs[i] = pkg +- ph := b.handles[id] +- +- // Do a second check for "unsafe" defensively, due to golang/go#60890. +- if ph.m.PkgPath == "unsafe" { +- bug.Reportf("encountered \"unsafe\" as %s (golang/go#60890)", id) +- return types.Unsafe, nil - } - -- return pkgs, firstErr +- data, err := filecache.Get(exportDataKind, ph.key) +- if err == filecache.ErrNotFound { +- // No cached export data: type-check as fast as possible. +- return b.checkPackageForImport(ctx, ph) +- } +- if err != nil { +- return nil, fmt.Errorf("failed to read cache data for %s: %v", ph.m.ID, err) +- } +- return b.importPackage(ctx, ph.m, data) -} - --// addNeededFiles records the files necessary for type-checking ph, for later --// parsing. --func (b *typeCheckBatch) addNeededFiles(ph *packageHandle) { +-// handleSyntaxPackage handles one package from the ids slice. +-// +-// If type checking occurred while handling the package, it returns the +-// resulting types.Package so that it may be used for importing. +-// +-// handleSyntaxPackage returns (nil, nil) if pre returned false. +-func (b *typeCheckBatch) handleSyntaxPackage(ctx context.Context, i int, id PackageID) (pkg *types.Package, err error) { - b.mu.Lock() -- defer b.mu.Unlock() +- f, ok := b.syntaxPackages[id] +- if ok { +- b.mu.Unlock() +- <-f.done +- return f.v.pkg, f.v.err +- } - -- // Technically for export-only packages we only need compiledGoFiles, but -- // these slices are usually redundant. -- for _, fh := range ph.inputs.goFiles { -- b.needFiles[fh.URI()] = fh +- f = &futurePackage{done: make(chan unit)} +- b.syntaxPackages[id] = f +- b.mu.Unlock() +- defer func() { +- f.v = pkgOrErr{pkg, err} +- close(f.done) +- }() +- +- ph := b.handles[id] +- if b.pre != nil && !b.pre(i, ph) { +- return nil, nil // skip: export data only +- } +- +- // Check for existing active packages. +- // +- // Since gopls can't depend on package identity, any instance of the +- // requested package must be ok to return. +- // +- // This is an optimization to avoid redundant type-checking: following +- // changes to an open package many LSP clients send several successive +- // requests for package information for the modified package (semantic +- // tokens, code lens, inlay hints, etc.) +- if pkg := b.activePackageCache.getActivePackage(id); pkg != nil { +- b.post(i, pkg) +- return nil, nil // skip: not checked in this batch +- } +- +- if err := b.awaitPredecessors(ctx, ph.m); err != nil { +- // One failed precessesor should not fail the entire type checking +- // operation. Errors related to imports will be reported as type checking +- // diagnostics. +- if ctx.Err() != nil { +- return nil, ctx.Err() +- } +- } +- +- // Wait to acquire a CPU token. +- // +- // Note: it is important to acquire this token only after awaiting +- // predecessors, to avoid starvation. +- select { +- case <-ctx.Done(): +- return nil, ctx.Err() +- case b.cpulimit <- unit{}: +- defer func() { +- <-b.cpulimit // release CPU token +- }() - } -- for _, fh := range ph.inputs.compiledGoFiles { -- b.needFiles[fh.URI()] = fh +- +- // We need a syntax package. +- syntaxPkg, err := b.checkPackage(ctx, ph) +- if err != nil { +- return nil, err - } +- b.activePackageCache.setActivePackage(id, syntaxPkg) +- b.post(i, syntaxPkg) +- +- return syntaxPkg.pkg.types, nil -} - -// importPackage loads the given package from its export data in p.exportData -// (which must already be populated). -func (b *typeCheckBatch) importPackage(ctx context.Context, m *source.Metadata, data []byte) (*types.Package, error) { -- impMap, errMap := b.importMap(m.ID) -- // Any failure to populate an import will cause confusing errors from -- // IImportShallow below. -- for path, err := range errMap { -- return nil, fmt.Errorf("error importing %q for %q: %v", path, m.ID, err) +- ctx, done := event.Start(ctx, "cache.typeCheckBatch.importPackage", tag.Package.Of(string(m.ID))) +- defer done() +- +- impMap := b.importMap(m.ID) +- +- thisPackage := types.NewPackage(string(m.PkgPath), string(m.Name)) +- getPackages := func(items []gcimporter.GetPackagesItem) error { +- for i, item := range items { +- var id PackageID +- var pkg *types.Package +- if item.Path == string(m.PkgPath) { +- id = m.ID +- pkg = thisPackage +- } else { +- id = impMap[item.Path] +- var err error +- pkg, err = b.getImportPackage(ctx, id) +- if err != nil { +- return err +- } +- } +- items[i].Pkg = pkg +- +- // debugging issue #60904 +- if pkg.Name() != item.Name { +- return bug.Errorf("internal error: package name is %q, want %q (id=%q, path=%q) (see issue #60904)", +- pkg.Name(), item.Name, id, item.Path) +- } +- } +- return nil - } - -- // TODO(rfindley): collect "deep" hashes here using the provided +- // Importing is potentially expensive, and might not encounter cancellations +- // via dependencies (e.g. if they have already been evaluated). +- if ctx.Err() != nil { +- return nil, ctx.Err() +- } +- +- // TODO(rfindley): collect "deep" hashes here using the getPackages - // callback, for precise pruning. -- imported, err := gcimporter.IImportShallow(b.fset, impMap, data, string(m.PkgPath), func(*types.Package, string) {}) +- imported, err := gcimporter.IImportShallow(b.fset, getPackages, data, string(m.PkgPath), bug.Reportf) - if err != nil { -- return nil, bug.Errorf("invalid export data for %q: %v", m.ID, err) +- return nil, fmt.Errorf("import failed for %q: %v", m.ID, err) - } - return imported, nil -} @@ -13673,26 +15631,55 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g -// checkPackageForImport type checks, but skips function bodies and does not -// record syntax information. -func (b *typeCheckBatch) checkPackageForImport(ctx context.Context, ph *packageHandle) (*types.Package, error) { -- if ph.m.ID == "unsafe" { -- return types.Unsafe, nil -- } -- impMap, errMap := b.importMap(ph.inputs.id) +- ctx, done := event.Start(ctx, "cache.typeCheckBatch.checkPackageForImport", tag.Package.Of(string(ph.m.ID))) +- defer done() +- - onError := func(e error) { - // Ignore errors for exporting. - } -- cfg := b.typesConfig(ph.inputs, onError, impMap, errMap) -- var files []*ast.File -- for _, fh := range ph.inputs.compiledGoFiles { -- pgf := b.parsedFiles[fh.URI()] -- if pgf == nil { -- return nil, fmt.Errorf("compiled go file %q failed to parse", fh.URI().Filename()) +- cfg := b.typesConfig(ctx, ph.localInputs, onError) +- cfg.IgnoreFuncBodies = true +- +- // Parse the compiled go files, bypassing the parse cache as packages checked +- // for import are unlikely to get cache hits. Additionally, we can optimize +- // parsing slightly by not passing parser.ParseComments. +- pgfs := make([]*source.ParsedGoFile, len(ph.localInputs.compiledGoFiles)) +- { +- var group errgroup.Group +- // Set an arbitrary concurrency limit; we want some parallelism but don't +- // need GOMAXPROCS, as there is already a lot of concurrency among calls to +- // checkPackageForImport. +- // +- // TODO(rfindley): is there a better way to limit parallelism here? We could +- // have a global limit on the type-check batch, but would have to be very +- // careful to avoid starvation. +- group.SetLimit(4) +- for i, fh := range ph.localInputs.compiledGoFiles { +- i, fh := i, fh +- group.Go(func() error { +- pgf, err := parseGoImpl(ctx, b.fset, fh, parser.SkipObjectResolution, false) +- pgfs[i] = pgf +- return err +- }) +- } +- if err := group.Wait(); err != nil { +- return nil, err // cancelled, or catastrophic error (e.g. missing file) - } -- files = append(files, pgf.File) - } -- cfg.IgnoreFuncBodies = true -- pkg := types.NewPackage(string(ph.inputs.pkgPath), string(ph.inputs.name)) +- pkg := types.NewPackage(string(ph.localInputs.pkgPath), string(ph.localInputs.name)) - check := types.NewChecker(cfg, b.fset, pkg, nil) - +- files := make([]*ast.File, len(pgfs)) +- for i, pgf := range pgfs { +- files[i] = pgf.File +- } +- +- // Type checking is expensive, and we may not have ecountered cancellations +- // via parsing (e.g. if we got nothing but cache hits for parsed files). +- if ctx.Err() != nil { +- return nil, ctx.Err() +- } +- - _ = check.Files(files) // ignore errors - - // If the context was cancelled, we may have returned a ton of transient @@ -13703,7 +15690,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - - // Asynchronously record export data. - go func() { -- exportData, err := gcimporter.IExportShallow(b.fset, pkg) +- exportData, err := gcimporter.IExportShallow(b.fset, pkg, bug.Reportf) - if err != nil { - bug.Reportf("exporting package %v: %v", ph.m.ID, err) - return @@ -13717,27 +15704,34 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - -// checkPackage "fully type checks" to produce a syntax package. -func (b *typeCheckBatch) checkPackage(ctx context.Context, ph *packageHandle) (*Package, error) { +- ctx, done := event.Start(ctx, "cache.typeCheckBatch.checkPackage", tag.Package.Of(string(ph.m.ID))) +- defer done() +- - // TODO(rfindley): refactor to inline typeCheckImpl here. There is no need - // for so many layers to build up the package - // (checkPackage->typeCheckImpl->doTypeCheck). -- pkg, err := typeCheckImpl(ctx, b, ph.inputs) +- pkg, err := typeCheckImpl(ctx, b, ph.localInputs) - - if err == nil { - // Write package data to disk asynchronously. - go func() { - toCache := map[string][]byte{ -- xrefsKind: pkg.xrefs, -- methodSetsKind: pkg.methodsets.Encode(), +- xrefsKind: pkg.xrefs(), +- methodSetsKind: pkg.methodsets().Encode(), - diagnosticsKind: encodeDiagnostics(pkg.diagnostics), - } - -- if ph.m.ID != "unsafe" { // unsafe cannot be exported -- exportData, err := gcimporter.IExportShallow(pkg.fset, pkg.types) +- if ph.m.PkgPath != "unsafe" { // unsafe cannot be exported +- exportData, err := gcimporter.IExportShallow(pkg.fset, pkg.types, bug.Reportf) - if err != nil { - bug.Reportf("exporting package %v: %v", ph.m.ID, err) - } else { - toCache[exportDataKind] = exportData - } +- } else if ph.m.ID != "unsafe" { +- // golang/go#60890: we should only ever see one variant of the "unsafe" +- // package. +- bug.Reportf("encountered \"unsafe\" as %s (golang/go#60890)", ph.m.ID) - } - - for kind, data := range toCache { @@ -13751,230 +15745,583 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - return &Package{ph.m, pkg}, err -} - --// awaitPredecessors awaits all promises for m.DepsByPkgPath, returning an +-// awaitPredecessors awaits all packages for m.DepsByPkgPath, returning an -// error if awaiting failed due to context cancellation or if there was an -// unrecoverable error loading export data. +-// +-// TODO(rfindley): inline, now that this is only called in one place. -func (b *typeCheckBatch) awaitPredecessors(ctx context.Context, m *source.Metadata) error { +- // await predecessors concurrently, as some of them may be non-syntax +- // packages, and therefore will not have been started by the type-checking +- // batch. +- var g errgroup.Group - for _, depID := range m.DepsByPkgPath { - depID := depID -- if p, ok := b.promises[depID]; ok { -- if _, err := p.Get(ctx, nil); err != nil { -- return err +- g.Go(func() error { +- _, err := b.getImportPackage(ctx, depID) +- return err +- }) +- } +- return g.Wait() +-} +- +-// importMap returns the map of package path -> package ID relative to the +-// specified ID. +-func (b *typeCheckBatch) importMap(id PackageID) map[string]source.PackageID { +- impMap := make(map[string]source.PackageID) +- var populateDeps func(m *source.Metadata) +- populateDeps = func(parent *source.Metadata) { +- for _, id := range parent.DepsByPkgPath { +- m := b.handles[id].m +- if _, ok := impMap[string(m.PkgPath)]; ok { +- continue - } +- impMap[string(m.PkgPath)] = m.ID +- populateDeps(m) - } - } -- return nil +- m := b.handles[id].m +- populateDeps(m) +- return impMap -} - --// importMap returns an import map for the given package ID, populated with --// type-checked packages for its dependencies. It is intended for compatibility --// with gcimporter.IImportShallow, so the first result uses the map signature --// of that API, where keys are package path strings. +-// A packageHandle holds inputs required to compute a type-checked package, +-// including inputs to type checking itself, and a key for looking up +-// precomputed data. -// --// importMap must only be used once all promises for dependencies of id have --// been awaited. +-// packageHandles may be invalid following an invalidation via snapshot.clone, +-// but the handles returned by getPackageHandles will always be valid. -// --// For any missing packages, importMap returns an entry in the resulting errMap --// reporting the error for that package. +-// packageHandles are critical for implementing "precise pruning" in gopls: +-// packageHandle.key is a hash of a precise set of inputs, such as package +-// files and "reachable" syntax, that may affect type checking. -// --// Invariant: for all recursive dependencies, either impMap[path] or --// errMap[path] is set. --func (b *typeCheckBatch) importMap(id PackageID) (impMap map[string]*types.Package, errMap map[PackagePath]error) { -- impMap = make(map[string]*types.Package) -- outerID := id -- var populateDepsOf func(m *source.Metadata) -- populateDepsOf = func(parent *source.Metadata) { -- for _, id := range parent.DepsByPkgPath { -- m := b.meta.metadata[id] -- if _, ok := impMap[string(m.PkgPath)]; ok { -- continue +-// packageHandles also keep track of state that allows gopls to compute, and +-// then quickly recompute, these keys. This state is split into two categories: +-// - local state, which depends only on the package's local files and metadata +-// - other state, which includes data derived from dependencies. +-// +-// Dividing the data in this way allows gopls to minimize invalidation when a +-// package is modified. For example, any change to a package file fully +-// invalidates the package handle. On the other hand, if that change was not +-// metadata-affecting it may be the case that packages indirectly depending on +-// the modified package are unaffected by the change. For that reason, we have +-// two types of invalidation, corresponding to the two types of data above: +-// - deletion of the handle, which occurs when the package itself changes +-// - clearing of the validated field, which marks the package as possibly +-// invalid. +-// +-// With the second type of invalidation, packageHandles are re-evaluated from the +-// bottom up. If this process encounters a packageHandle whose deps have not +-// changed (as detected by the depkeys field), then the packageHandle in +-// question must also not have changed, and we need not re-evaluate its key. +-type packageHandle struct { +- m *source.Metadata +- +- // Local data: +- +- // localInputs holds all local type-checking localInputs, excluding +- // dependencies. +- localInputs typeCheckInputs +- // localKey is a hash of localInputs. +- localKey source.Hash +- // refs is the result of syntactic dependency analysis produced by the +- // typerefs package. +- refs map[string][]typerefs.Symbol +- +- // Data derived from dependencies: +- +- // validated indicates whether the current packageHandle is known to have a +- // valid key. Invalidated package handles are stored for packages whose +- // type information may have changed. +- validated bool +- // depKeys records the key of each dependency that was used to calculate the +- // key above. If the handle becomes invalid, we must re-check that each still +- // matches. +- depKeys map[PackageID]source.Hash +- // key is the hashed key for the package. +- // +- // It includes the all bits of the transitive closure of +- // dependencies's sources. +- key source.Hash +-} +- +-// clone returns a copy of the receiver with the validated bit set to the +-// provided value. +-func (ph *packageHandle) clone(validated bool) *packageHandle { +- copy := *ph +- copy.validated = validated +- return © +-} +- +-// getPackageHandles gets package handles for all given ids and their +-// dependencies, recursively. +-func (s *snapshot) getPackageHandles(ctx context.Context, ids []PackageID) (map[PackageID]*packageHandle, error) { +- // perform a two-pass traversal. +- // +- // On the first pass, build up a bidirectional graph of handle nodes, and collect leaves. +- // Then build package handles from bottom up. +- +- s.mu.Lock() // guard s.meta and s.packages below +- b := &packageHandleBuilder{ +- s: s, +- transitiveRefs: make(map[typerefs.IndexID]*partialRefs), +- nodes: make(map[typerefs.IndexID]*handleNode), +- } +- +- var leaves []*handleNode +- var makeNode func(*handleNode, PackageID) *handleNode +- makeNode = func(from *handleNode, id PackageID) *handleNode { +- idxID := b.s.pkgIndex.IndexID(id) +- n, ok := b.nodes[idxID] +- if !ok { +- m := s.meta.metadata[id] +- if m == nil { +- panic(fmt.Sprintf("nil metadata for %q", id)) - } -- if _, ok := errMap[m.PkgPath]; ok { -- continue +- n = &handleNode{ +- m: m, +- idxID: idxID, +- unfinishedSuccs: int32(len(m.DepsByPkgPath)), - } -- b.mu.Lock() -- result, ok := b.imports[m.ID] -- b.mu.Unlock() -- if !ok { -- panic(fmt.Sprintf("import map for %q missing package data for %q", outerID, m.ID)) +- if entry, hit := b.s.packages.Get(m.ID); hit { +- n.ph = entry - } -- // We may fail to produce a package due to e.g. context cancellation -- // (handled elsewhere), or some catastrophic failure such as a package with -- // no files. -- switch { -- case result.err != nil: -- if errMap == nil { -- errMap = make(map[PackagePath]error) -- } -- errMap[m.PkgPath] = result.err -- case result.pkg != nil: -- impMap[string(m.PkgPath)] = result.pkg -- default: -- panic("invalid import for " + id) +- if n.unfinishedSuccs == 0 { +- leaves = append(leaves, n) +- } else { +- n.succs = make(map[source.PackageID]*handleNode, n.unfinishedSuccs) - } -- populateDepsOf(m) +- b.nodes[idxID] = n +- for _, depID := range m.DepsByPkgPath { +- n.succs[depID] = makeNode(n, depID) +- } +- } +- // Add edge from predecessor. +- if from != nil { +- n.preds = append(n.preds, from) - } +- return n - } -- m := b.meta.metadata[id] -- populateDepsOf(m) -- return impMap, errMap --} +- for _, id := range ids { +- makeNode(nil, id) +- } +- s.mu.Unlock() - --// packageData holds binary data (e.g. types, xrefs) extracted from a syntax --// package. --type packageData struct { -- m *source.Metadata -- data []byte --} +- g, ctx := errgroup.WithContext(ctx) +- +- // files are preloaded, so building package handles is CPU-bound. +- // +- // Note that we can't use g.SetLimit, as that could result in starvation: +- // g.Go blocks until a slot is available, and so all existing goroutines +- // could be blocked trying to enqueue a predecessor. +- limiter := make(chan unit, runtime.GOMAXPROCS(0)) +- +- var enqueue func(*handleNode) +- enqueue = func(n *handleNode) { +- g.Go(func() error { +- limiter <- unit{} +- defer func() { <-limiter }() - --// getPackageData gets package data (e.g. types, xrefs) for the requested ids, --// either loading from the file-based cache or type-checking and extracting --// data using the provided get function. --func (s *snapshot) getPackageData(ctx context.Context, kind string, ids []PackageID, get func(*syntaxPackage) []byte) ([]*packageData, error) { -- var needIDs []PackageID -- keys := make([]packageHandleKey, len(ids)) -- pkgData := make([]*packageData, len(ids)) -- var firstErr error -- // Compute package keys and query file cache. -- for i, id := range ids { -- ph, err := s.buildPackageHandle(ctx, id) -- if err != nil { -- if firstErr == nil { -- firstErr = err -- } - if ctx.Err() != nil { -- return pkgData, firstErr +- return ctx.Err() - } -- continue -- } -- keys[i] = ph.key -- data, err := filecache.Get(kind, ph.key) -- switch err { -- case nil: -- pkgData[i] = &packageData{m: ph.m, data: data} -- case filecache.ErrNotFound: -- needIDs = append(needIDs, id) -- default: -- if firstErr == nil { -- firstErr = err +- +- b.buildPackageHandle(ctx, n) +- +- for _, pred := range n.preds { +- if atomic.AddInt32(&pred.unfinishedSuccs, -1) == 0 { +- enqueue(pred) +- } - } -- if ctx.Err() != nil { -- return pkgData, firstErr +- +- return n.err +- }) +- } +- for _, leaf := range leaves { +- enqueue(leaf) +- } +- +- if err := g.Wait(); err != nil { +- return nil, err +- } +- +- // Copy handles into the result map. +- handles := make(map[PackageID]*packageHandle, len(b.nodes)) +- for _, v := range b.nodes { +- assert(v.ph != nil, "nil handle") +- handles[v.m.ID] = v.ph +- } +- +- return handles, nil +-} +- +-// A packageHandleBuilder computes a batch of packageHandles concurrently, +-// sharing computed transitive reachability sets used to compute package keys. +-type packageHandleBuilder struct { +- meta *metadataGraph +- s *snapshot +- +- // nodes are assembled synchronously. +- nodes map[typerefs.IndexID]*handleNode +- +- // transitiveRefs is incrementally evaluated as package handles are built. +- transitiveRefsMu sync.Mutex +- transitiveRefs map[typerefs.IndexID]*partialRefs // see getTransitiveRefs +-} +- +-// A handleNode represents a to-be-computed packageHandle within a graph of +-// predecessors and successors. +-// +-// It is used to implement a bottom-up construction of packageHandles. +-type handleNode struct { +- m *source.Metadata +- idxID typerefs.IndexID +- ph *packageHandle +- err error +- preds []*handleNode +- succs map[PackageID]*handleNode +- unfinishedSuccs int32 +-} +- +-// partialRefs maps names declared by a given package to their set of +-// transitive references. +-// +-// If complete is set, refs is known to be complete for the package in +-// question. Otherwise, it may only map a subset of all names declared by the +-// package. +-type partialRefs struct { +- refs map[string]*typerefs.PackageSet +- complete bool +-} +- +-// getTransitiveRefs gets or computes the set of transitively reachable +-// packages for each exported name in the package specified by id. +-// +-// The operation may fail if building a predecessor failed. If and only if this +-// occurs, the result will be nil. +-func (b *packageHandleBuilder) getTransitiveRefs(pkgID PackageID) map[string]*typerefs.PackageSet { +- b.transitiveRefsMu.Lock() +- defer b.transitiveRefsMu.Unlock() +- +- idxID := b.s.pkgIndex.IndexID(pkgID) +- trefs, ok := b.transitiveRefs[idxID] +- if !ok { +- trefs = &partialRefs{ +- refs: make(map[string]*typerefs.PackageSet), +- } +- b.transitiveRefs[idxID] = trefs +- } +- +- if !trefs.complete { +- trefs.complete = true +- ph := b.nodes[idxID].ph +- for name := range ph.refs { +- if ('A' <= name[0] && name[0] <= 'Z') || token.IsExported(name) { +- if _, ok := trefs.refs[name]; !ok { +- pkgs := b.s.pkgIndex.NewSet() +- for _, sym := range ph.refs[name] { +- pkgs.Add(sym.Package) +- otherSet := b.getOneTransitiveRefLocked(sym) +- pkgs.Union(otherSet) +- } +- trefs.refs[name] = pkgs +- } - } - } - } - -- // Type-check the packages for which we got file-cache misses. -- pkgs, err := s.TypeCheck(ctx, needIDs...) -- if err != nil { -- return nil, err +- return trefs.refs +-} +- +-// getOneTransitiveRefLocked computes the full set packages transitively +-// reachable through the given sym reference. +-// +-// It may return nil if the reference is invalid (i.e. the referenced name does +-// not exist). +-func (b *packageHandleBuilder) getOneTransitiveRefLocked(sym typerefs.Symbol) *typerefs.PackageSet { +- assert(token.IsExported(sym.Name), "expected exported symbol") +- +- trefs := b.transitiveRefs[sym.Package] +- if trefs == nil { +- trefs = &partialRefs{ +- refs: make(map[string]*typerefs.PackageSet), +- complete: false, +- } +- b.transitiveRefs[sym.Package] = trefs - } - -- pkgMap := make(map[PackageID]source.Package) -- for i, id := range needIDs { -- pkgMap[id] = pkgs[i] +- pkgs, ok := trefs.refs[sym.Name] +- if ok && pkgs == nil { +- // See below, where refs is set to nil before recursing. +- bug.Reportf("cycle detected to %q in reference graph", sym.Name) - } - -- // Fill in the gaps using data derived from type checking. -- for i, id := range ids { -- if pkgData[i] != nil { -- continue +- // Note that if (!ok && trefs.complete), the name does not exist in the +- // referenced package, and we should not write to trefs as that may introduce +- // a race. +- if !ok && !trefs.complete { +- n := b.nodes[sym.Package] +- if n == nil { +- // We should always have IndexID in our node set, because symbol references +- // should only be recorded for packages that actually exist in the import graph. +- // +- // However, it is not easy to prove this (typerefs are serialized and +- // deserialized), so make this code temporarily defensive while we are on a +- // point release. +- // +- // TODO(rfindley): in the future, we should turn this into an assertion. +- bug.Reportf("missing reference to package %s", b.s.pkgIndex.PackageID(sym.Package)) +- return nil - } -- result := pkgMap[id] -- if result == nil { -- panic(fmt.Sprintf("missing type-check result for %s", id)) +- +- // Break cycles. This is perhaps overly defensive as cycles should not +- // exist at this point: metadata cycles should have been broken at load +- // time, and intra-package reference cycles should have been contracted by +- // the typerefs algorithm. +- // +- // See the "cycle detected" bug report above. +- trefs.refs[sym.Name] = nil +- +- pkgs := b.s.pkgIndex.NewSet() +- for _, sym2 := range n.ph.refs[sym.Name] { +- pkgs.Add(sym2.Package) +- otherSet := b.getOneTransitiveRefLocked(sym2) +- pkgs.Union(otherSet) - } -- data := get(result.(*Package).pkg) -- pkgData[i] = &packageData{m: result.Metadata(), data: data} +- trefs.refs[sym.Name] = pkgs - } - -- return pkgData, firstErr +- return pkgs -} - --type packageHandleKey source.Hash -- --// A packageHandle holds package information, some of which may not be fully --// evaluated. +-// buildPackageHandle gets or builds a package handle for the given id, storing +-// its result in the snapshot.packages map. -// --// The only methods on packageHandle that are safe to call before calling await --// are Metadata and await itself. --type packageHandle struct { -- m *source.Metadata +-// buildPackageHandle must only be called from getPackageHandles. +-func (b *packageHandleBuilder) buildPackageHandle(ctx context.Context, n *handleNode) { +- var prevPH *packageHandle +- if n.ph != nil { +- // Existing package handle: if it is valid, return it. Otherwise, create a +- // copy to update. +- if n.ph.validated { +- return +- } +- prevPH = n.ph +- // Either prevPH is still valid, or we will update the key and depKeys of +- // this copy. In either case, the result will be valid. +- n.ph = prevPH.clone(true) +- } else { +- // No package handle: read and analyze the package syntax. +- inputs, err := b.s.typeCheckInputs(ctx, n.m) +- if err != nil { +- n.err = err +- return +- } +- refs, err := b.s.typerefs(ctx, n.m, inputs.compiledGoFiles) +- if err != nil { +- n.err = err +- return +- } +- n.ph = &packageHandle{ +- m: n.m, +- localInputs: inputs, +- localKey: localPackageKey(inputs), +- refs: refs, +- validated: true, +- } +- } - -- inputs typeCheckInputs +- // ph either did not exist, or was invalid. We must re-evaluate deps and key. +- if err := b.evaluatePackageHandle(prevPH, n); err != nil { +- n.err = err +- return +- } - -- // key is the hashed key for the package. +- assert(n.ph.validated, "unvalidated handle") +- +- // Ensure the result (or an equivalent) is recorded in the snapshot. +- b.s.mu.Lock() +- defer b.s.mu.Unlock() +- +- // Check that the metadata has not changed +- // (which should invalidate this handle). - // -- // It includes the all bits of the transitive closure of -- // dependencies's sources. This is more than type checking -- // really depends on: export data of direct deps should be -- // enough. (The key for analysis actions could similarly -- // hash only Facts of direct dependencies.) -- key packageHandleKey -- -- // Note: as an optimization, we could join in-flight type-checking by -- // recording a transient ref-counted promise here. -- // (This was done previously, but proved to be a premature optimization). --} -- --// buildPackageHandle returns a handle for the future results of --// type-checking the package identified by id in the given mode. --// It assumes that the given ID already has metadata available, so it does not --// attempt to reload missing or invalid metadata. The caller must reload --// metadata if needed. --func (s *snapshot) buildPackageHandle(ctx context.Context, id PackageID) (*packageHandle, error) { -- s.mu.Lock() -- entry, hit := s.packages.Get(id) -- m := s.meta.metadata[id] -- s.mu.Unlock() +- // TODO(rfindley): eventually promote this to an assert. +- // TODO(rfindley): move this to after building the package handle graph? +- if b.s.meta.metadata[n.m.ID] != n.m { +- bug.Reportf("stale metadata for %s", n.m.ID) +- } - -- if m == nil { -- return nil, fmt.Errorf("no metadata for %s", id) +- // Check the packages map again in case another goroutine got there first. +- if alt, ok := b.s.packages.Get(n.m.ID); ok && alt.validated { +- if alt.m != n.m { +- bug.Reportf("existing package handle does not match for %s", n.m.ID) +- } +- n.ph = alt +- } else { +- b.s.packages.Set(n.m.ID, n.ph, nil) +- } +-} +- +-// evaluatePackageHandle validates and/or computes the key of ph, setting key, +-// depKeys, and the validated flag on ph. +-// +-// It uses prevPH to avoid recomputing keys that can't have changed, since +-// their depKeys did not change. +-// +-// See the documentation for packageHandle for more details about packageHandle +-// state, and see the documentation for the typerefs package for more details +-// about precise reachability analysis. +-func (b *packageHandleBuilder) evaluatePackageHandle(prevPH *packageHandle, n *handleNode) error { +- // Opt: if no dep keys have changed, we need not re-evaluate the key. +- if prevPH != nil { +- depsChanged := false +- assert(len(prevPH.depKeys) == len(n.succs), "mismatching dep count") +- for id, succ := range n.succs { +- oldKey, ok := prevPH.depKeys[id] +- assert(ok, "missing dep") +- if oldKey != succ.ph.key { +- depsChanged = true +- break +- } +- } +- if !depsChanged { +- return nil // key cannot have changed +- } +- } +- +- // Deps have changed, so we must re-evaluate the key. +- n.ph.depKeys = make(map[PackageID]source.Hash) +- +- // See the typerefs package: the reachable set of packages is defined to be +- // the set of packages containing syntax that is reachable through the +- // exported symbols in the dependencies of n.ph. +- reachable := b.s.pkgIndex.NewSet() +- for depID, succ := range n.succs { +- n.ph.depKeys[depID] = succ.ph.key +- reachable.Add(succ.idxID) +- trefs := b.getTransitiveRefs(succ.m.ID) +- if trefs == nil { +- // A predecessor failed to build due to e.g. context cancellation. +- return fmt.Errorf("missing transitive refs for %s", succ.m.ID) +- } +- for _, set := range trefs { +- reachable.Union(set) +- } +- } +- +- // Collect reachable handles. +- var reachableHandles []*packageHandle +- // In the presence of context cancellation, any package may be missing. +- // We need all dependencies to produce a valid key. +- missingReachablePackage := false +- reachable.Elems(func(id typerefs.IndexID) { +- dh := b.nodes[id] +- if dh == nil { +- missingReachablePackage = true +- } else { +- assert(dh.ph.validated, "unvalidated dependency") +- reachableHandles = append(reachableHandles, dh.ph) +- } +- }) +- if missingReachablePackage { +- return fmt.Errorf("missing reachable package") +- } +- // Sort for stability. +- sort.Slice(reachableHandles, func(i, j int) bool { +- return reachableHandles[i].m.ID < reachableHandles[j].m.ID +- }) +- +- // Key is the hash of the local key, and the local key of all reachable +- // packages. +- depHasher := sha256.New() +- depHasher.Write(n.ph.localKey[:]) +- for _, rph := range reachableHandles { +- depHasher.Write(rph.localKey[:]) - } +- depHasher.Sum(n.ph.key[:0]) +- +- return nil +-} - -- if hit { -- return entry.(*packageHandle), nil +-// typerefs returns typerefs for the package described by m and cgfs, after +-// either computing it or loading it from the file cache. +-func (s *snapshot) typerefs(ctx context.Context, m *source.Metadata, cgfs []source.FileHandle) (map[string][]typerefs.Symbol, error) { +- imports := make(map[ImportPath]*source.Metadata) +- for impPath, id := range m.DepsByImpPath { +- if id != "" { +- imports[impPath] = s.Metadata(id) +- } - } - -- inputs, err := s.typeCheckInputs(ctx, m) +- data, err := s.typerefData(ctx, m.ID, imports, cgfs) - if err != nil { - return nil, err - } -- // All the file reading has now been done. -- // Create a handle for the result of type checking. -- phKey := computePackageKey(s, inputs) -- ph := &packageHandle{ -- m: m, -- inputs: inputs, -- key: phKey, +- classes := typerefs.Decode(s.pkgIndex, m.ID, data) +- refs := make(map[string][]typerefs.Symbol) +- for _, class := range classes { +- for _, decl := range class.Decls { +- refs[decl] = class.Refs +- } - } +- return refs, nil +-} - -- s.mu.Lock() -- defer s.mu.Unlock() +-// typerefData retrieves encoded typeref data from the filecache, or computes it on +-// a cache miss. +-func (s *snapshot) typerefData(ctx context.Context, id PackageID, imports map[ImportPath]*source.Metadata, cgfs []source.FileHandle) ([]byte, error) { +- key := typerefsKey(id, imports, cgfs) +- if data, err := filecache.Get(typerefsKind, key); err == nil { +- return data, nil +- } else if err != filecache.ErrNotFound { +- bug.Reportf("internal error reading typerefs data: %v", err) +- } - -- // Check that the metadata has not changed -- // (which should invalidate this handle). -- // -- // (In future, handles should form a graph with edges from a -- // packageHandle to the handles for parsing its files and the -- // handles for type-checking its immediate deps, at which -- // point there will be no need to even access s.meta.) -- if s.meta.metadata[ph.m.ID] != ph.m { -- // TODO(rfindley): this should be bug.Errorf. -- return nil, fmt.Errorf("stale metadata for %s", ph.m.ID) +- pgfs, err := s.view.parseCache.parseFiles(ctx, token.NewFileSet(), source.ParseFull&^parser.ParseComments, true, cgfs...) +- if err != nil { +- return nil, err - } +- data := typerefs.Encode(pgfs, id, imports) - -- // Check cache again in case another goroutine got there first. -- if prev, ok := s.packages.Get(id); ok { -- prevPH := prev.(*packageHandle) -- if prevPH.m != ph.m { -- return nil, bug.Errorf("existing package handle does not match for %s", ph.m.ID) +- // Store the resulting data in the cache. +- go func() { +- if err := filecache.Set(typerefsKind, key, data); err != nil { +- event.Error(ctx, fmt.Sprintf("storing typerefs data for %s", id), err) - } -- return prevPH, nil +- }() +- +- return data, nil +-} +- +-// typerefsKey produces a key for the reference information produced by the +-// typerefs package. +-func typerefsKey(id PackageID, imports map[ImportPath]*source.Metadata, compiledGoFiles []source.FileHandle) source.Hash { +- hasher := sha256.New() +- +- fmt.Fprintf(hasher, "typerefs: %s\n", id) +- +- importPaths := make([]string, 0, len(imports)) +- for impPath := range imports { +- importPaths = append(importPaths, string(impPath)) +- } +- sort.Strings(importPaths) +- for _, importPath := range importPaths { +- imp := imports[ImportPath(importPath)] +- // TODO(rfindley): strength reduce the typerefs.Export API to guarantee +- // that it only depends on these attributes of dependencies. +- fmt.Fprintf(hasher, "import %s %s %s", importPath, imp.ID, imp.Name) - } - -- s.packages.Set(id, ph, nil) -- return ph, nil +- fmt.Fprintf(hasher, "compiledGoFiles: %d\n", len(compiledGoFiles)) +- for _, fh := range compiledGoFiles { +- fmt.Fprintln(hasher, fh.FileIdentity()) +- } +- +- var hash [sha256.Size]byte +- hasher.Sum(hash[:0]) +- return hash -} - -// typeCheckInputs contains the inputs of a call to typeCheckImpl, which @@ -13990,7 +16337,6 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - name PackageName - goFiles, compiledGoFiles []source.FileHandle - sizes types.Sizes -- deps map[PackageID]*packageHandle - depsByImpPath map[ImportPath]PackageID - goVersion string // packages.Module.GoVersion, e.g. "1.18" - @@ -14001,38 +16347,21 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g -} - -func (s *snapshot) typeCheckInputs(ctx context.Context, m *source.Metadata) (typeCheckInputs, error) { -- deps := make(map[PackageID]*packageHandle) -- for _, depID := range m.DepsByPkgPath { -- depHandle, err := s.buildPackageHandle(ctx, depID) -- if err != nil { -- // If err is non-nil, we either have an invalid dependency, or a -- // catastrophic failure to read a file (context cancellation or -- // permission issues). -- // -- // We don't want one bad dependency to prevent us from type-checking the -- // package -- we should instead get an import error. So we only abort -- // this operation if the context is cancelled. -- // -- // We could do a better job of handling permission errors on files, but -- // this is rare, and it is reasonable to treat the same an invalid -- // dependency. -- event.Error(ctx, fmt.Sprintf("%s: no dep handle for %s", m.ID, depID), err, source.SnapshotLabels(s)...) -- if ctx.Err() != nil { -- return typeCheckInputs{}, ctx.Err() // cancelled -- } -- continue -- } -- deps[depID] = depHandle -- } -- -- // Read both lists of files of this package, in parallel. +- // Read both lists of files of this package. +- // +- // Parallelism is not necessary here as the files will have already been +- // pre-read at load time. - // - // goFiles aren't presented to the type checker--nor - // are they included in the key, unsoundly--but their - // syntax trees are available from (*pkg).File(URI). - // TODO(adonovan): consider parsing them on demand? - // The need should be rare. -- goFiles, compiledGoFiles, err := readGoFiles(ctx, s, m) +- goFiles, err := readFiles(ctx, s, m.GoFiles) +- if err != nil { +- return typeCheckInputs{}, err +- } +- compiledGoFiles, err := readFiles(ctx, s, m.CompiledGoFiles) - if err != nil { - return typeCheckInputs{}, err - } @@ -14049,40 +16378,31 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - goFiles: goFiles, - compiledGoFiles: compiledGoFiles, - sizes: m.TypesSizes, -- deps: deps, - depsByImpPath: m.DepsByImpPath, - goVersion: goVersion, - - relatedInformation: s.view.Options().RelatedInformationSupported, - linkTarget: s.view.Options().LinkTarget, -- moduleMode: s.moduleMode(), +- moduleMode: s.view.moduleMode(), - }, nil -} - --// readGoFiles reads the content of Metadata.GoFiles and --// Metadata.CompiledGoFiles, in parallel. --func readGoFiles(ctx context.Context, s *snapshot, m *source.Metadata) (goFiles, compiledGoFiles []source.FileHandle, err error) { -- var group errgroup.Group -- getFileHandles := func(files []span.URI) []source.FileHandle { -- fhs := make([]source.FileHandle, len(files)) -- for i, uri := range files { -- i, uri := i, uri -- group.Go(func() (err error) { -- fhs[i], err = s.GetFile(ctx, uri) // ~25us -- return -- }) +-// readFiles reads the content of each file URL from the source +-// (e.g. snapshot or cache). +-func readFiles(ctx context.Context, fs source.FileSource, uris []span.URI) (_ []source.FileHandle, err error) { +- fhs := make([]source.FileHandle, len(uris)) +- for i, uri := range uris { +- fhs[i], err = fs.ReadFile(ctx, uri) +- if err != nil { +- return nil, err - } -- return fhs - } -- return getFileHandles(m.GoFiles), -- getFileHandles(m.CompiledGoFiles), -- group.Wait() +- return fhs, nil -} - --// computePackageKey returns a key representing the act of type checking --// a package named id containing the specified files, metadata, and --// combined dependency hash. --func computePackageKey(s *snapshot, inputs typeCheckInputs) packageHandleKey { +-// localPackageKey returns a key for local inputs into type-checking, excluding +-// dependency information: files, metadata, and configuration. +-func localPackageKey(inputs typeCheckInputs) source.Hash { - hasher := sha256.New() - - // In principle, a key must be the hash of an @@ -14105,17 +16425,6 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - fmt.Fprintf(hasher, "import %s %s", impPath, string(inputs.depsByImpPath[ImportPath(impPath)])) - } - -- // deps, in PackageID order -- depIDs := make([]string, 0, len(inputs.deps)) -- for depID := range inputs.deps { -- depIDs = append(depIDs, string(depID)) -- } -- sort.Strings(depIDs) -- for _, depID := range depIDs { -- dep := inputs.deps[PackageID(depID)] -- fmt.Fprintf(hasher, "dep: %s key:%s\n", dep.m.PkgPath, dep.key) -- } -- - // file names and contents - fmt.Fprintf(hasher, "compiledGoFiles: %d\n", len(inputs.compiledGoFiles)) - for _, fh := range inputs.compiledGoFiles { @@ -14127,8 +16436,9 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - } - - // types sizes -- sz := inputs.sizes.(*types.StdSizes) -- fmt.Fprintf(hasher, "sizes: %d %d\n", sz.WordSize, sz.MaxAlign) +- wordSize := inputs.sizes.Sizeof(types.Typ[types.Int]) +- maxAlign := inputs.sizes.Alignof(types.NewPointer(types.Typ[types.Int64])) +- fmt.Fprintf(hasher, "sizes: %d %d\n", wordSize, maxAlign) - - fmt.Fprintf(hasher, "relatedInformation: %t\n", inputs.relatedInformation) - fmt.Fprintf(hasher, "linkTarget: %s\n", inputs.linkTarget) @@ -14136,7 +16446,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - - var hash [sha256.Size]byte - hasher.Sum(hash[:0]) -- return packageHandleKey(hash) +- return hash -} - -// typeCheckImpl type checks the parsed source files in compiledGoFiles. @@ -14150,8 +16460,6 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - if err != nil { - return nil, err - } -- pkg.methodsets = methodsets.NewIndex(pkg.fset, pkg.types) -- pkg.xrefs = xrefs.Index(pkg.compiledGoFiles, pkg.types, pkg.typesInfo) - - // Our heuristic for whether to show type checking errors is: - // + If any file was 'fixed', don't show type checking errors as we @@ -14187,7 +16495,13 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - for _, e := range expandErrors(unexpanded, inputs.relatedInformation) { - diags, err := typeErrorDiagnostics(inputs.moduleMode, inputs.linkTarget, pkg, e) - if err != nil { -- event.Error(ctx, "unable to compute positions for type errors", err, tag.Package.Of(string(inputs.id))) +- // If we fail here and there are no parse errors, it means we are hiding +- // a valid type-checking error from the user. This must be a bug, with +- // one exception: relocated primary errors may fail processing, because +- // they reference locations outside of the package. +- if len(pkg.parseErrors) == 0 && !e.relocated { +- bug.Reportf("failed to compute position for type error %v: %v", e, err) +- } - continue - } - pkg.typeErrors = append(pkg.typeErrors, e.primary) @@ -14201,13 +16515,20 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - } - } - +- // Work around golang/go#61561: interface instances aren't concurrency-safe +- // as they are not completed by the type checker. +- for _, inst := range typeparams.GetInstances(pkg.typesInfo) { +- if iface, _ := inst.Type.Underlying().(*types.Interface); iface != nil { +- iface.Complete() +- } +- } +- - return pkg, nil -} - -var goVersionRx = regexp.MustCompile(`^go([1-9][0-9]*)\.(0|[1-9][0-9]*)$`) - -func doTypeCheck(ctx context.Context, b *typeCheckBatch, inputs typeCheckInputs) (*syntaxPackage, error) { -- impMap, errMap := b.importMap(inputs.id) - pkg := &syntaxPackage{ - id: inputs.id, - fset: b.fset, // must match parse call below @@ -14220,30 +16541,24 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - Selections: make(map[*ast.SelectorExpr]*types.Selection), - Scopes: make(map[ast.Node]*types.Scope), - }, -- importMap: impMap, - } - typeparams.InitInstanceInfo(pkg.typesInfo) - - // Collect parsed files from the type check pass, capturing parse errors from - // compiled files. -- for _, fh := range inputs.goFiles { -- pgf := b.parsedFiles[fh.URI()] -- if pgf == nil { -- // If go/packages told us that a file is in a package, it should be -- // parseable (after all, it was parsed by go list). -- return nil, bug.Errorf("go file %q failed to parse", fh.URI().Filename()) -- } -- pkg.goFiles = append(pkg.goFiles, pgf) +- var err error +- pkg.goFiles, err = b.parseCache.parseFiles(ctx, b.fset, source.ParseFull, false, inputs.goFiles...) +- if err != nil { +- return nil, err - } -- for _, fh := range inputs.compiledGoFiles { -- pgf := b.parsedFiles[fh.URI()] -- if pgf == nil { -- return nil, fmt.Errorf("compiled go file %q failed to parse", fh.URI().Filename()) -- } +- pkg.compiledGoFiles, err = b.parseCache.parseFiles(ctx, b.fset, source.ParseFull, false, inputs.compiledGoFiles...) +- if err != nil { +- return nil, err +- } +- for _, pgf := range pkg.compiledGoFiles { - if pgf.ParseErr != nil { - pkg.parseErrors = append(pkg.parseErrors, pgf.ParseErr) - } -- pkg.compiledGoFiles = append(pkg.compiledGoFiles, pgf) - } - - // Use the default type information for the unsafe package. @@ -14266,7 +16581,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - onError := func(e error) { - pkg.typeErrors = append(pkg.typeErrors, e.(types.Error)) - } -- cfg := b.typesConfig(inputs, onError, impMap, errMap) +- cfg := b.typesConfig(ctx, inputs, onError) - - check := types.NewChecker(cfg, pkg.fset, pkg.types, pkg.typesInfo) - @@ -14275,6 +16590,12 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - files = append(files, cgf.File) - } - +- // Type checking is expensive, and we may not have ecountered cancellations +- // via parsing (e.g. if we got nothing but cache hits for parsed files). +- if ctx.Err() != nil { +- return nil, ctx.Err() +- } +- - // Type checking errors are handled via the config, so ignore them here. - _ = check.Files(files) // 50us-15ms, depending on size of package - @@ -14283,10 +16604,26 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - if ctx.Err() != nil { - return nil, ctx.Err() - } +- +- // Collect imports by package path for the DependencyTypes API. +- pkg.importMap = make(map[PackagePath]*types.Package) +- var collectDeps func(*types.Package) +- collectDeps = func(p *types.Package) { +- pkgPath := PackagePath(p.Path()) +- if _, ok := pkg.importMap[pkgPath]; ok { +- return +- } +- pkg.importMap[pkgPath] = p +- for _, imp := range p.Imports() { +- collectDeps(imp) +- } +- } +- collectDeps(pkg.types) +- - return pkg, nil -} - --func (b *typeCheckBatch) typesConfig(inputs typeCheckInputs, onError func(e error), impMap map[string]*types.Package, errMap map[PackagePath]error) *types.Config { +-func (b *typeCheckBatch) typesConfig(ctx context.Context, inputs typeCheckInputs, onError func(e error)) *types.Config { - cfg := &types.Config{ - Sizes: inputs.sizes, - Error: onError, @@ -14302,23 +16639,15 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - // See TestFixImportDecl for an example. - return nil, fmt.Errorf("missing metadata for import of %q", path) - } -- depPH := inputs.deps[id] +- depPH := b.handles[id] - if depPH == nil { - // e.g. missing metadata for dependencies in buildPackageHandle -- return nil, missingPkgError(path, inputs.moduleMode) +- return nil, missingPkgError(inputs.id, path, inputs.moduleMode) - } - if !source.IsValidImport(inputs.pkgPath, depPH.m.PkgPath) { - return nil, fmt.Errorf("invalid use of internal package %q", path) - } -- pkg, ok := impMap[string(depPH.m.PkgPath)] -- if !ok { -- err := errMap[depPH.m.PkgPath] -- if err == nil { -- log.Fatalf("neither pkg nor error is set") -- } -- return nil, err -- } -- return pkg, nil +- return b.getImportPackage(ctx, id) - }), - } - @@ -14383,7 +16712,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - if err != nil { - return nil, err - } -- fset := source.FileSetFor(pgf.Tok) +- fset := tokeninternal.FileSetFor(pgf.Tok) - // TODO(adonovan): modify Imports() to accept a single token.File (cgf.Tok). - for _, group := range astutil.Imports(fset, pgf.File) { - for _, imp := range group { @@ -14415,14 +16744,18 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - if err != nil { - return nil, err - } -- errors = append(errors, &source.Diagnostic{ +- diag := &source.Diagnostic{ - URI: imp.cgf.URI, - Range: rng, - Severity: protocol.SeverityError, - Source: source.TypeError, - Message: fmt.Sprintf("error while importing %v: %v", item, depErr.Err), - SuggestedFixes: fixes, -- }) +- } +- if !source.BundleQuickFixes(diag) { +- bug.Reportf("failed to bundle fixes for diagnostic %q", diag.Message) +- } +- errors = append(errors, diag) - } - } - } @@ -14458,14 +16791,18 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - if err != nil { - return nil, err - } -- errors = append(errors, &source.Diagnostic{ +- diag := &source.Diagnostic{ - URI: pm.URI, - Range: rng, - Severity: protocol.SeverityError, - Source: source.TypeError, - Message: fmt.Sprintf("error while importing %v: %v", item, depErr.Err), - SuggestedFixes: fixes, -- }) +- } +- if !source.BundleQuickFixes(diag) { +- bug.Reportf("failed to bundle fixes for diagnostic %q", diag.Message) +- } +- errors = append(errors, diag) - break - } - } @@ -14474,13 +16811,17 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - -// missingPkgError returns an error message for a missing package that varies -// based on the user's workspace mode. --func missingPkgError(pkgPath string, moduleMode bool) error { +-func missingPkgError(from PackageID, pkgPath string, moduleMode bool) error { - // TODO(rfindley): improve this error. Previous versions of this error had - // access to the full snapshot, and could provide more information (such as - // the initialization error). - if moduleMode { -- // Previously, we would present the initialization error here. -- return fmt.Errorf("no required module provides package %q", pkgPath) +- if source.IsCommandLineArguments(from) { +- return fmt.Errorf("current file is not included in a workspace module") +- } else { +- // Previously, we would present the initialization error here. +- return fmt.Errorf("no required module provides package %q", pkgPath) +- } - } else { - // Previously, we would list the directories in GOROOT and GOPATH here. - return fmt.Errorf("cannot find package %q in GOROOT or GOPATH", pkgPath) @@ -14488,6 +16829,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g -} - -type extendedError struct { +- relocated bool // if set, this is a relocation of a primary error to a secondary location - primary types.Error - secondaries []types.Error -} @@ -14540,7 +16882,7 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - - // Copy over the secondary errors, noting the location of the - // current error we're cloning. -- clonedError := extendedError{primary: relocatedSecondary, secondaries: []types.Error{original.primary}} +- clonedError := extendedError{relocated: true, primary: relocatedSecondary, secondaries: []types.Error{original.primary}} - for j, secondary := range original.secondaries { - if i == j { - secondary.Msg += " (this error)" @@ -14549,7 +16891,6 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g - } - result = append(result, clonedError) - } -- - } - return result -} @@ -14559,10 +16900,10 @@ diff -urN a/gopls/internal/lsp/cache/check.go b/gopls/internal/lsp/cache/check.g -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } -diff -urN a/gopls/internal/lsp/cache/debug.go b/gopls/internal/lsp/cache/debug.go ---- a/gopls/internal/lsp/cache/debug.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/debug.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,55 +0,0 @@ +diff -urN a/gopls/internal/lsp/cache/constraints.go b/gopls/internal/lsp/cache/constraints.go +--- a/gopls/internal/lsp/cache/constraints.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cache/constraints.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,61 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -14570,58 +16911,365 @@ diff -urN a/gopls/internal/lsp/cache/debug.go b/gopls/internal/lsp/cache/debug.g -package cache - -import ( -- "fmt" -- "os" -- "sort" +- "go/ast" +- "go/build/constraint" +- "go/parser" +- "go/token" -) - --// This file contains helpers that can be used to instrument code while --// debugging. +-// isStandaloneFile reports whether a file with the given contents should be +-// considered a 'standalone main file', meaning a package that consists of only +-// a single file. +-func isStandaloneFile(src []byte, standaloneTags []string) bool { +- f, err := parser.ParseFile(token.NewFileSet(), "", src, parser.PackageClauseOnly|parser.ParseComments) +- if err != nil { +- return false +- } - --// debugEnabled toggles the helpers below. --const debugEnabled = false +- if f.Name == nil || f.Name.Name != "main" { +- return false +- } - --// If debugEnabled is true, debugf formats its arguments and prints to stderr. --// If debugEnabled is false, it is a no-op. --func debugf(format string, args ...interface{}) { -- if !debugEnabled { -- return +- found := false +- walkConstraints(f, func(c constraint.Expr) bool { +- if tag, ok := c.(*constraint.TagExpr); ok { +- for _, t := range standaloneTags { +- if t == tag.Tag { +- found = true +- return false +- } +- } +- } +- return true +- }) +- +- return found +-} +- +-// walkConstraints calls f for each constraint expression in the file, until +-// all constraints are exhausted or f returns false. +-func walkConstraints(file *ast.File, f func(constraint.Expr) bool) { +- for _, cg := range file.Comments { +- // Even with PackageClauseOnly the parser consumes the semicolon following +- // the package clause, so we must guard against comments that come after +- // the package name. +- if cg.Pos() > file.Name.Pos() { +- continue +- } +- for _, comment := range cg.List { +- if c, err := constraint.Parse(comment.Text); err == nil { +- if !f(c) { +- return +- } +- } +- } - } -- if false { -- _ = fmt.Sprintf(format, args...) // encourage vet to validate format strings +-} +diff -urN a/gopls/internal/lsp/cache/constraints_test.go b/gopls/internal/lsp/cache/constraints_test.go +--- a/gopls/internal/lsp/cache/constraints_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cache/constraints_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,96 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.16 +-// +build go1.16 +- +-package cache +- +-import ( +- "testing" +-) +- +-func TestIsStandaloneFile(t *testing.T) { +- tests := []struct { +- desc string +- contents string +- standaloneTags []string +- want bool +- }{ +- { +- "new syntax", +- "//go:build ignore\n\npackage main\n", +- []string{"ignore"}, +- true, +- }, +- { +- "legacy syntax", +- "// +build ignore\n\npackage main\n", +- []string{"ignore"}, +- true, +- }, +- { +- "multiple tags", +- "//go:build ignore\n\npackage main\n", +- []string{"exclude", "ignore"}, +- true, +- }, +- { +- "invalid tag", +- "// +build ignore\n\npackage main\n", +- []string{"script"}, +- false, +- }, +- { +- "non-main package", +- "//go:build ignore\n\npackage p\n", +- []string{"ignore"}, +- false, +- }, +- { +- "alternate tag", +- "// +build script\n\npackage main\n", +- []string{"script"}, +- true, +- }, +- { +- "both syntax", +- "//go:build ignore\n// +build ignore\n\npackage main\n", +- []string{"ignore"}, +- true, +- }, +- { +- "after comments", +- "// A non-directive comment\n//go:build ignore\n\npackage main\n", +- []string{"ignore"}, +- true, +- }, +- { +- "after package decl", +- "package main //go:build ignore\n", +- []string{"ignore"}, +- false, +- }, +- { +- "on line after package decl", +- "package main\n\n//go:build ignore\n", +- []string{"ignore"}, +- false, +- }, +- { +- "combined with other expressions", +- "\n\n//go:build ignore || darwin\n\npackage main\n", +- []string{"ignore"}, +- false, +- }, +- } +- +- for _, test := range tests { +- t.Run(test.desc, func(t *testing.T) { +- if got := isStandaloneFile([]byte(test.contents), test.standaloneTags); got != test.want { +- t.Errorf("isStandaloneFile(%q, %v) = %t, want %t", test.contents, test.standaloneTags, got, test.want) +- } +- }) - } -- fmt.Fprintf(os.Stderr, ">>> "+format+"\n", args...) -} +diff -urN a/gopls/internal/lsp/cache/cycle_test.go b/gopls/internal/lsp/cache/cycle_test.go +--- a/gopls/internal/lsp/cache/cycle_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cache/cycle_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,181 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --// If debugEnabled is true, dumpWorkspace prints a summary of workspace --// packages to stderr. If debugEnabled is false, it is a no-op. --// --// TODO(rfindley): this has served its purpose. Delete. --func (s *snapshot) dumpWorkspace(context string) { -- if !debugEnabled { -- return +-package cache +- +-import ( +- "sort" +- "strings" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/source" +-) +- +-// This is an internal test of the breakImportCycles logic. +-func TestBreakImportCycles(t *testing.T) { +- +- type Graph = map[PackageID]*source.Metadata +- +- // cyclic returns a description of a cycle, +- // if the graph is cyclic, otherwise "". +- cyclic := func(graph Graph) string { +- const ( +- unvisited = 0 +- visited = 1 +- onstack = 2 +- ) +- color := make(map[PackageID]int) +- var visit func(id PackageID) string +- visit = func(id PackageID) string { +- switch color[id] { +- case unvisited: +- color[id] = onstack +- case onstack: +- return string(id) // cycle! +- case visited: +- return "" +- } +- if m := graph[id]; m != nil { +- for _, depID := range m.DepsByPkgPath { +- if cycle := visit(depID); cycle != "" { +- return string(id) + "->" + cycle +- } +- } +- } +- color[id] = visited +- return "" +- } +- for id := range graph { +- if cycle := visit(id); cycle != "" { +- return cycle +- } +- } +- return "" - } - -- debugf("workspace (after %s):", context) -- var ids []PackageID -- for id := range s.workspacePackages { -- ids = append(ids, id) +- // parse parses an import dependency graph. +- // The input is a semicolon-separated list of node descriptions. +- // Each node description is a package ID, optionally followed by +- // "->" and a comma-separated list of successor IDs. +- // Thus "a->b;b->c,d;e" represents the set of nodes {a,b,e} +- // and the set of edges {a->b, b->c, b->d}. +- parse := func(s string) Graph { +- m := make(Graph) +- makeNode := func(name string) *source.Metadata { +- id := PackageID(name) +- n, ok := m[id] +- if !ok { +- n = &source.Metadata{ +- ID: id, +- DepsByPkgPath: make(map[PackagePath]PackageID), +- } +- m[id] = n +- } +- return n +- } +- if s != "" { +- for _, item := range strings.Split(s, ";") { +- nodeID, succIDs, ok := strings.Cut(item, "->") +- node := makeNode(nodeID) +- if ok { +- for _, succID := range strings.Split(succIDs, ",") { +- node.DepsByPkgPath[PackagePath(succID)] = PackageID(succID) +- } +- } +- } +- } +- return m - } - -- sort.Slice(ids, func(i, j int) bool { -- return ids[i] < ids[j] -- }) +- // Sanity check of cycle detector. +- { +- got := cyclic(parse("a->b;b->c;c->a,d")) +- has := func(s string) bool { return strings.Contains(got, s) } +- if !(has("a->b") && has("b->c") && has("c->a") && !has("d")) { +- t.Fatalf("cyclic: got %q, want a->b->c->a or equivalent", got) +- } +- } - -- for _, id := range ids { -- pkgPath := s.workspacePackages[id] -- _, ok := s.meta.metadata[id] -- debugf(" %s:%s (metadata: %t)", id, pkgPath, ok) +- // format formats an import graph, in lexicographic order, +- // in the notation of parse, but with a "!" after the name +- // of each node that has errors. +- format := func(graph Graph) string { +- var items []string +- for _, m := range graph { +- item := string(m.ID) +- if len(m.Errors) > 0 { +- item += "!" +- } +- var succs []string +- for _, depID := range m.DepsByPkgPath { +- succs = append(succs, string(depID)) +- } +- if succs != nil { +- sort.Strings(succs) +- item += "->" + strings.Join(succs, ",") +- } +- items = append(items, item) +- } +- sort.Strings(items) +- return strings.Join(items, ";") +- } +- +- // We needn't test self-cycles as they are eliminated at Metadata construction. +- for _, test := range []struct { +- metadata, updates, want string +- }{ +- // Simple 2-cycle. +- {"a->b", "b->a", +- "a->b;b!"}, // broke b->a +- +- {"a->b;b->c;c", "b->a,c", +- "a->b;b!->c;c"}, // broke b->a +- +- // Reversing direction of p->s edge creates pqrs cycle. +- {"a->p,q,r,s;p->q,s,z;q->r,z;r->s,z;s->z", "p->q,z;s->p,z", +- "a->p,q,r,s;p!->z;q->r,z;r->s,z;s!->z"}, // broke p->q, s->p +- +- // We break all intra-SCC edges from updated nodes, +- // which may be more than necessary (e.g. a->b). +- {"a->b;b->c;c;d->a", "a->b,e;c->d", +- "a!->e;b->c;c!;d->a"}, // broke a->b, c->d +- } { +- metadata := parse(test.metadata) +- updates := parse(test.updates) +- +- if cycle := cyclic(metadata); cycle != "" { +- t.Errorf("initial metadata %s has cycle %s: ", format(metadata), cycle) +- continue +- } +- +- t.Log("initial", format(metadata)) +- +- // Apply updates. +- // (parse doesn't have a way to express node deletions, +- // but they aren't very interesting.) +- for id, m := range updates { +- metadata[id] = m +- } +- +- t.Log("updated", format(metadata)) +- +- // breakImportCycles accesses only these fields of Metadata: +- // DepsByImpPath, ID - read +- // DepsByPkgPath - read, updated +- // Errors - updated +- breakImportCycles(metadata, updates) +- +- t.Log("acyclic", format(metadata)) +- +- if cycle := cyclic(metadata); cycle != "" { +- t.Errorf("resulting metadata %s has cycle %s: ", format(metadata), cycle) +- } +- +- got := format(metadata) +- if got != test.want { +- t.Errorf("test.metadata=%s test.updates=%s: got=%s want=%s", +- test.metadata, test.updates, got, test.want) +- } +- } +-} +diff -urN a/gopls/internal/lsp/cache/debug.go b/gopls/internal/lsp/cache/debug.go +--- a/gopls/internal/lsp/cache/debug.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cache/debug.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package cache +- +-// assert panics with the given msg if cond is not true. +-func assert(cond bool, msg string) { +- if !cond { +- panic(msg) - } -} diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors.go --- a/gopls/internal/lsp/cache/errors.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/errors.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,528 +0,0 @@ +@@ -1,545 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -14635,6 +17283,7 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors -import ( - "context" - "fmt" +- "go/parser" - "go/scanner" - "go/token" - "go/types" @@ -14644,13 +17293,13 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors - "strings" - - "golang.org/x/tools/go/packages" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/command" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" - "golang.org/x/tools/internal/analysisinternal" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/typesinternal" -) - @@ -14759,7 +17408,13 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors - for _, secondary := range e.secondaries { - _, secondaryLoc, err := typeErrorData(pkg, secondary) - if err != nil { -- return nil, err +- // We may not be able to compute type error data in scenarios where the +- // secondary position is outside of the current package. In this case, we +- // don't want to ignore the diagnostic entirely. +- // +- // See golang/go#59005 for an example where gopls was missing diagnostics +- // due to returning an error here. +- continue - } - diag.Related = append(diag.Related, protocol.DiagnosticRelatedInformation{ - Location: secondaryLoc, @@ -14866,13 +17521,13 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors - } - gobDiags = append(gobDiags, gobDiag) - } -- return mustEncode(gobDiags) +- return diagnosticsCodec.Encode(gobDiags) -} - -// decodeDiagnostics decodes the given gob-encoded diagnostics. -func decodeDiagnostics(data []byte) []*source.Diagnostic { - var gobDiags []gobDiagnostic -- mustDecode(data, &gobDiags) +- diagnosticsCodec.Decode(data, &gobDiags) - var srcDiags []*source.Diagnostic - for _, gobDiag := range gobDiags { - var srcFixes []source.SuggestedFix @@ -14893,7 +17548,7 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors - srcFix.Edits[uri] = append(srcFix.Edits[uri], srcEdit) - } - if gobCmd := gobFix.Command; gobCmd != nil { -- gobFix.Command = &gobCommand{ +- srcFix.Command = &protocol.Command{ - Title: gobCmd.Title, - Command: gobCmd.Command, - Arguments: gobCmd.Arguments, @@ -14910,6 +17565,8 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors - URI: gobDiag.Location.URI.SpanURI(), - Range: gobDiag.Location.Range, - Severity: gobDiag.Severity, +- Code: gobDiag.Code, +- CodeHref: gobDiag.CodeHref, - Source: source.AnalyzerErrorKind(gobDiag.Source), - Message: gobDiag.Message, - Tags: gobDiag.Tags, @@ -14954,17 +17611,23 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors - } - - diag := &source.Diagnostic{ -- URI: gobDiag.Location.URI.SpanURI(), -- Range: gobDiag.Location.Range, -- Severity: severity, -- Source: source.AnalyzerErrorKind(gobDiag.Source), -- Message: gobDiag.Message, -- Related: related, -- SuggestedFixes: fixes, +- URI: gobDiag.Location.URI.SpanURI(), +- Range: gobDiag.Location.Range, +- Severity: severity, +- Code: gobDiag.Code, +- CodeHref: gobDiag.CodeHref, +- Source: source.AnalyzerErrorKind(gobDiag.Source), +- Message: gobDiag.Message, +- Related: related, +- Tags: srcAnalyzer.Tag, - } +- if srcAnalyzer.FixesDiagnostic(diag) { +- diag.SuggestedFixes = fixes +- } +- - // If the fixes only delete code, assume that the diagnostic is reporting dead code. - if onlyDeletions(fixes) { -- diag.Tags = []protocol.DiagnosticTag{protocol.Unnecessary} +- diag.Tags = append(diag.Tags, protocol.Unnecessary) - } - return diag -} @@ -15052,11 +17715,11 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors -// contained in the provided FileSource. -func spanToRange(ctx context.Context, fs source.FileSource, spn span.Span) (protocol.Range, error) { - uri := spn.URI() -- fh, err := fs.GetFile(ctx, uri) +- fh, err := fs.ReadFile(ctx, uri) - if err != nil { - return protocol.Range{}, err - } -- content, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return protocol.Range{}, err - } @@ -15131,12 +17794,14 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors -// to use in a list of file of a package, for example. -// -// It returns an error if the file could not be read. --func parseGoURI(ctx context.Context, fs source.FileSource, uri span.URI, mode source.ParseMode) (*source.ParsedGoFile, error) { -- fh, err := fs.GetFile(ctx, uri) +-// +-// TODO(rfindley): eliminate this helper. +-func parseGoURI(ctx context.Context, fs source.FileSource, uri span.URI, mode parser.Mode) (*source.ParsedGoFile, error) { +- fh, err := fs.ReadFile(ctx, uri) - if err != nil { - return nil, err - } -- return parseGoImpl(ctx, token.NewFileSet(), fh, source.ParseHeader) +- return parseGoImpl(ctx, token.NewFileSet(), fh, mode, false) -} - -// parseModURI is a helper to parse the Mod file at the given URI from the file @@ -15144,7 +17809,7 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors -// -// It returns an error if the file could not be read. -func parseModURI(ctx context.Context, fs source.FileSource, uri span.URI) (*source.ParsedModule, error) { -- fh, err := fs.GetFile(ctx, uri) +- fh, err := fs.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -15153,7 +17818,7 @@ diff -urN a/gopls/internal/lsp/cache/errors.go b/gopls/internal/lsp/cache/errors diff -urN a/gopls/internal/lsp/cache/errors_test.go b/gopls/internal/lsp/cache/errors_test.go --- a/gopls/internal/lsp/cache/errors_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/errors_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,52 +0,0 @@ +@@ -1,130 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -15161,8 +17826,14 @@ diff -urN a/gopls/internal/lsp/cache/errors_test.go b/gopls/internal/lsp/cache/e -package cache - -import ( +- "encoding/json" - "strings" - "testing" +- +- "github.com/google/go-cmp/cmp" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" -) - -func TestParseErrorMessage(t *testing.T) { @@ -15206,10 +17877,82 @@ diff -urN a/gopls/internal/lsp/cache/errors_test.go b/gopls/internal/lsp/cache/e - }) - } -} +- +-func TestDiagnosticEncoding(t *testing.T) { +- diags := []*source.Diagnostic{ +- {}, // empty +- { +- URI: "file///foo", +- Range: protocol.Range{ +- Start: protocol.Position{Line: 4, Character: 2}, +- End: protocol.Position{Line: 6, Character: 7}, +- }, +- Severity: protocol.SeverityWarning, +- Code: "red", +- CodeHref: "https://go.dev", +- Source: "test", +- Message: "something bad happened", +- Tags: []protocol.DiagnosticTag{81}, +- Related: []protocol.DiagnosticRelatedInformation{ +- { +- Location: protocol.Location{ +- URI: "file:///other", +- Range: protocol.Range{ +- Start: protocol.Position{Line: 3, Character: 6}, +- End: protocol.Position{Line: 4, Character: 9}, +- }, +- }, +- Message: "psst, over here", +- }, +- }, +- +- // Fields below are used internally to generate quick fixes. They aren't +- // part of the LSP spec and don't leave the server. +- SuggestedFixes: []source.SuggestedFix{ +- { +- Title: "fix it!", +- Edits: map[span.URI][]protocol.TextEdit{ +- "file:///foo": {{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 4, Character: 2}, +- End: protocol.Position{Line: 6, Character: 7}, +- }, +- NewText: "abc", +- }}, +- "file:///other": {{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 4, Character: 2}, +- End: protocol.Position{Line: 6, Character: 7}, +- }, +- NewText: "!@#!", +- }}, +- }, +- Command: &protocol.Command{ +- Title: "run a command", +- Command: "gopls.fix", +- Arguments: []json.RawMessage{json.RawMessage(`{"a":1}`)}, +- }, +- ActionKind: protocol.QuickFix, +- }, +- }, +- }, +- { +- URI: "file//bar", +- // other fields tested above +- }, +- } +- +- data := encodeDiagnostics(diags) +- diags2 := decodeDiagnostics(data) +- +- if diff := cmp.Diff(diags, diags2); diff != "" { +- t.Errorf("decoded diagnostics do not match (-original +decoded):\n%s", diff) +- } +-} diff -urN a/gopls/internal/lsp/cache/fs_memoized.go b/gopls/internal/lsp/cache/fs_memoized.go --- a/gopls/internal/lsp/cache/fs_memoized.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/fs_memoized.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,149 +0,0 @@ +@@ -1,167 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -15239,10 +17982,6 @@ diff -urN a/gopls/internal/lsp/cache/fs_memoized.go b/gopls/internal/lsp/cache/f - filesByID map[robustio.FileID][]*DiskFile -} - --func newMemoizedFS() *memoizedFS { -- return &memoizedFS{filesByID: make(map[robustio.FileID][]*DiskFile)} --} -- -// A DiskFile is a file on the filesystem, or a failure to read one. -// It implements the source.FileHandle interface. -type DiskFile struct { @@ -15262,12 +18001,12 @@ diff -urN a/gopls/internal/lsp/cache/fs_memoized.go b/gopls/internal/lsp/cache/f - } -} - --func (h *DiskFile) Saved() bool { return true } --func (h *DiskFile) Version() int32 { return 0 } --func (h *DiskFile) Read() ([]byte, error) { return h.content, h.err } +-func (h *DiskFile) Saved() bool { return true } +-func (h *DiskFile) Version() int32 { return 0 } +-func (h *DiskFile) Content() ([]byte, error) { return h.content, h.err } - --// GetFile stats and (maybe) reads the file, updates the cache, and returns it. --func (fs *memoizedFS) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { +-// ReadFile stats and (maybe) reads the file, updates the cache, and returns it. +-func (fs *memoizedFS) ReadFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { - id, mtime, err := robustio.GetFileID(uri.Filename()) - if err != nil { - // file does not exist @@ -15328,6 +18067,28 @@ diff -urN a/gopls/internal/lsp/cache/fs_memoized.go b/gopls/internal/lsp/cache/f - return fh, nil -} - +-// fileStats returns information about the set of files stored in fs. It is +-// intended for debugging only. +-func (fs *memoizedFS) fileStats() (files, largest, errs int) { +- fs.mu.Lock() +- defer fs.mu.Unlock() +- +- files = len(fs.filesByID) +- largest = 0 +- errs = 0 +- +- for _, files := range fs.filesByID { +- rep := files[0] +- if len(rep.content) > largest { +- largest = len(rep.content) +- } +- if rep.err != nil { +- errs++ +- } +- } +- return files, largest, errs +-} +- -// ioLimit limits the number of parallel file reads per process. -var ioLimit = make(chan struct{}, 128) - @@ -15404,14 +18165,14 @@ diff -urN a/gopls/internal/lsp/cache/fs_overlay.go b/gopls/internal/lsp/cache/fs - return overlays -} - --func (fs *overlayFS) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { +-func (fs *overlayFS) ReadFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { - fs.mu.Lock() - overlay, ok := fs.overlays[uri] - fs.mu.Unlock() - if ok { - return overlay, nil - } -- return fs.delegate.GetFile(ctx, uri) +- return fs.delegate.ReadFile(ctx, uri) -} - -// An Overlay is a file open in the editor. It may have unsaved edits. @@ -15437,14 +18198,14 @@ diff -urN a/gopls/internal/lsp/cache/fs_overlay.go b/gopls/internal/lsp/cache/fs - } -} - --func (o *Overlay) Read() ([]byte, error) { return o.content, nil } --func (o *Overlay) Version() int32 { return o.version } --func (o *Overlay) Saved() bool { return o.saved } --func (o *Overlay) Kind() source.FileKind { return o.kind } +-func (o *Overlay) Content() ([]byte, error) { return o.content, nil } +-func (o *Overlay) Version() int32 { return o.version } +-func (o *Overlay) Saved() bool { return o.saved } +-func (o *Overlay) Kind() source.FileKind { return o.kind } diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.go --- a/gopls/internal/lsp/cache/graph.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/graph.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,131 +0,0 @@ +@@ -1,364 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -15454,6 +18215,8 @@ diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.g -import ( - "sort" - +- "golang.org/x/tools/go/packages" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -) @@ -15469,6 +18232,8 @@ diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.g - - // ids maps file URIs to package IDs, sorted by (!valid, cli, packageID). - // A single file may belong to multiple packages due to tests packages. +- // +- // Invariant: all IDs present in the ids map exist in the metadata map. - ids map[span.URI][]PackageID -} - @@ -15478,43 +18243,46 @@ diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.g -} - -// Clone creates a new metadataGraph, applying the given updates to the --// receiver. +-// receiver. A nil map value represents a deletion. -func (g *metadataGraph) Clone(updates map[PackageID]*source.Metadata) *metadataGraph { - if len(updates) == 0 { - // Optimization: since the graph is immutable, we can return the receiver. - return g - } -- result := &metadataGraph{metadata: make(map[PackageID]*source.Metadata, len(g.metadata))} -- // Copy metadata. +- +- // Copy metadata map then apply updates. +- metadata := make(map[PackageID]*source.Metadata, len(g.metadata)) - for id, m := range g.metadata { -- result.metadata[id] = m +- metadata[id] = m - } - for id, m := range updates { - if m == nil { -- delete(result.metadata, id) +- delete(metadata, id) - } else { -- result.metadata[id] = m +- metadata[id] = m - } - } -- result.build() -- return result +- +- // Break import cycles involving updated nodes. +- breakImportCycles(metadata, updates) +- +- return newMetadataGraph(metadata) -} - --// build constructs g.importedBy and g.uris from g.metadata. --// --// TODO(rfindley): we should enforce that the graph is acyclic here. --func (g *metadataGraph) build() { +-// newMetadataGraph returns a new metadataGraph, +-// deriving relations from the specified metadata. +-func newMetadataGraph(metadata map[PackageID]*source.Metadata) *metadataGraph { - // Build the import graph. -- g.importedBy = make(map[PackageID][]PackageID) -- for id, m := range g.metadata { +- importedBy := make(map[PackageID][]PackageID) +- for id, m := range metadata { - for _, depID := range m.DepsByPkgPath { -- g.importedBy[depID] = append(g.importedBy[depID], id) +- importedBy[depID] = append(importedBy[depID], id) - } - } - - // Collect file associations. -- g.ids = make(map[span.URI][]PackageID) -- for id, m := range g.metadata { +- uriIDs := make(map[span.URI][]PackageID) +- for id, m := range metadata { - uris := map[span.URI]struct{}{} - for _, uri := range m.CompiledGoFiles { - uris[uri] = struct{}{} @@ -15523,12 +18291,12 @@ diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.g - uris[uri] = struct{}{} - } - for uri := range uris { -- g.ids[uri] = append(g.ids[uri], id) +- uriIDs[uri] = append(uriIDs[uri], id) - } - } - - // Sort and filter file associations. -- for uri, ids := range g.ids { +- for uri, ids := range uriIDs { - sort.Slice(ids, func(i, j int) bool { - cli := source.IsCommandLineArguments(ids[i]) - clj := source.IsCommandLineArguments(ids[j]) @@ -15550,11 +18318,17 @@ diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.g - // If we've seen *anything* prior to command-line arguments package, take - // it. Note that ids[0] may itself be command-line-arguments. - if i > 0 && source.IsCommandLineArguments(id) { -- g.ids[uri] = ids[:i] +- uriIDs[uri] = ids[:i] - break - } - } - } +- +- return &metadataGraph{ +- metadata: metadata, +- importedBy: importedBy, +- ids: uriIDs, +- } -} - -// reverseReflexiveTransitiveClosure returns a new mapping containing the @@ -15576,10 +18350,230 @@ diff -urN a/gopls/internal/lsp/cache/graph.go b/gopls/internal/lsp/cache/graph.g - visitAll(ids) - return seen -} +- +-// breakImportCycles breaks import cycles in the metadata by deleting +-// Deps* edges. It modifies only metadata present in the 'updates' +-// subset. This function has an internal test. +-func breakImportCycles(metadata, updates map[PackageID]*source.Metadata) { +- // 'go list' should never report a cycle without flagging it +- // as such, but we're extra cautious since we're combining +- // information from multiple runs of 'go list'. Also, Bazel +- // may silently report cycles. +- cycles := detectImportCycles(metadata, updates) +- if len(cycles) > 0 { +- // There were cycles (uncommon). Break them. +- // +- // The naive way to break cycles would be to perform a +- // depth-first traversal and to detect and delete +- // cycle-forming edges as we encounter them. +- // However, we're not allowed to modify the existing +- // Metadata records, so we can only break edges out of +- // the 'updates' subset. +- // +- // Another possibility would be to delete not the +- // cycle forming edge but the topmost edge on the +- // stack whose tail is an updated node. +- // However, this would require that we retroactively +- // undo all the effects of the traversals that +- // occurred since that edge was pushed on the stack. +- // +- // We use a simpler scheme: we compute the set of cycles. +- // All cyclic paths necessarily involve at least one +- // updated node, so it is sufficient to break all +- // edges from each updated node to other members of +- // the strong component. +- // +- // This may result in the deletion of dominating +- // edges, causing some dependencies to appear +- // spuriously unreachable. Consider A <-> B -> C +- // where updates={A,B}. The cycle is {A,B} so the +- // algorithm will break both A->B and B->A, causing +- // A to no longer depend on B or C. +- // +- // But that's ok: any error in Metadata.Errors is +- // conservatively assumed by snapshot.clone to be a +- // potential import cycle error, and causes special +- // invalidation so that if B later drops its +- // cycle-forming import of A, both A and B will be +- // invalidated. +- for _, cycle := range cycles { +- cyclic := make(map[PackageID]bool) +- for _, m := range cycle { +- cyclic[m.ID] = true +- } +- for id := range cyclic { +- if m := updates[id]; m != nil { +- for path, depID := range m.DepsByImpPath { +- if cyclic[depID] { +- delete(m.DepsByImpPath, path) +- } +- } +- for path, depID := range m.DepsByPkgPath { +- if cyclic[depID] { +- delete(m.DepsByPkgPath, path) +- } +- } +- +- // Set m.Errors to enable special +- // invalidation logic in snapshot.clone. +- if len(m.Errors) == 0 { +- m.Errors = []packages.Error{{ +- Msg: "detected import cycle", +- Kind: packages.ListError, +- }} +- } +- } +- } +- } +- +- // double-check when debugging +- if false { +- if cycles := detectImportCycles(metadata, updates); len(cycles) > 0 { +- bug.Reportf("unbroken cycle: %v", cycles) +- } +- } +- } +-} +- +-// detectImportCycles reports cycles in the metadata graph. It returns a new +-// unordered array of all cycles (nontrivial strong components) in the +-// metadata graph reachable from a non-nil 'updates' value. +-func detectImportCycles(metadata, updates map[PackageID]*source.Metadata) [][]*source.Metadata { +- // We use the depth-first algorithm of Tarjan. +- // https://doi.org/10.1137/0201010 +- // +- // TODO(adonovan): when we can use generics, consider factoring +- // in common with the other implementation of Tarjan (in typerefs), +- // abstracting over the node and edge representation. +- +- // A node wraps a Metadata with its working state. +- // (Unfortunately we can't intrude on shared Metadata.) +- type node struct { +- rep *node +- m *source.Metadata +- index, lowlink int32 +- scc int8 // TODO(adonovan): opt: cram these 1.5 bits into previous word +- } +- nodes := make(map[PackageID]*node, len(metadata)) +- nodeOf := func(id PackageID) *node { +- n, ok := nodes[id] +- if !ok { +- m := metadata[id] +- if m == nil { +- // Dangling import edge. +- // Not sure whether a go/packages driver ever +- // emits this, but create a dummy node in case. +- // Obviously it won't be part of any cycle. +- m = &source.Metadata{ID: id} +- } +- n = &node{m: m} +- n.rep = n +- nodes[id] = n +- } +- return n +- } +- +- // find returns the canonical node decl. +- // (The nodes form a disjoint set forest.) +- var find func(*node) *node +- find = func(n *node) *node { +- rep := n.rep +- if rep != n { +- rep = find(rep) +- n.rep = rep // simple path compression (no union-by-rank) +- } +- return rep +- } +- +- // global state +- var ( +- index int32 = 1 +- stack []*node +- sccs [][]*source.Metadata // set of nontrivial strongly connected components +- ) +- +- // visit implements the depth-first search of Tarjan's SCC algorithm +- // Precondition: x is canonical. +- var visit func(*node) +- visit = func(x *node) { +- x.index = index +- x.lowlink = index +- index++ +- +- stack = append(stack, x) // push +- x.scc = -1 +- +- for _, yid := range x.m.DepsByPkgPath { +- y := nodeOf(yid) +- // Loop invariant: x is canonical. +- y = find(y) +- if x == y { +- continue // nodes already combined (self-edges are impossible) +- } +- +- switch { +- case y.scc > 0: +- // y is already a collapsed SCC +- +- case y.scc < 0: +- // y is on the stack, and thus in the current SCC. +- if y.index < x.lowlink { +- x.lowlink = y.index +- } +- +- default: +- // y is unvisited; visit it now. +- visit(y) +- // Note: x and y are now non-canonical. +- x = find(x) +- if y.lowlink < x.lowlink { +- x.lowlink = y.lowlink +- } +- } +- } +- +- // Is x the root of an SCC? +- if x.lowlink == x.index { +- // Gather all metadata in the SCC (if nontrivial). +- var scc []*source.Metadata +- for { +- // Pop y from stack. +- i := len(stack) - 1 +- y := stack[i] +- stack = stack[:i] +- if x != y || scc != nil { +- scc = append(scc, y.m) +- } +- if x == y { +- break // complete +- } +- // x becomes y's canonical representative. +- y.rep = x +- } +- if scc != nil { +- sccs = append(sccs, scc) +- } +- x.scc = 1 +- } +- } +- +- // Visit only the updated nodes: +- // the existing metadata graph has no cycles, +- // so any new cycle must involve an updated node. +- for id, m := range updates { +- if m != nil { +- if n := nodeOf(id); n.index == 0 { // unvisited +- visit(n) +- } +- } +- } +- +- return sccs +-} diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/imports.go --- a/gopls/internal/lsp/cache/imports.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/imports.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,188 +0,0 @@ +@@ -1,184 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -15611,16 +18605,12 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - cachedModFileHash source.Hash - cachedBuildFlags []string - cachedDirectoryFilters []string -- -- // runOnce records whether runProcessEnvFunc has been called at least once. -- // This is necessary to avoid resetting state before the process env is -- // populated. -- // -- // TODO(rfindley): this shouldn't be necessary. -- runOnce bool -} - --func (s *importsState) runProcessEnvFunc(ctx context.Context, snapshot *snapshot, fn func(*imports.Options) error) error { +-func (s *importsState) runProcessEnvFunc(ctx context.Context, snapshot *snapshot, fn func(context.Context, *imports.Options) error) error { +- ctx, done := event.Start(ctx, "cache.importsState.runProcessEnvFunc") +- defer done() +- - s.mu.Lock() - defer s.mu.Unlock() - @@ -15631,7 +18621,7 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - // TODO(rfindley): consider instead hashing on-disk modfiles here. - var modFileHash source.Hash - for m := range snapshot.workspaceModFiles { -- fh, err := snapshot.GetFile(ctx, m) +- fh, err := snapshot.ReadFile(ctx, m) - if err != nil { - return err - } @@ -15654,24 +18644,19 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - // update the processEnv. Clearing caches blocks on any background - // scans. - if changed { -- // As a special case, skip cleanup the first time -- we haven't fully -- // initialized the environment yet and calling GetResolver will do -- // unnecessary work and potentially mess up the go.mod file. -- if s.runOnce { -- if resolver, err := s.processEnv.GetResolver(); err == nil { -- if modResolver, ok := resolver.(*imports.ModuleResolver); ok { -- modResolver.ClearForNewMod() -- } +- if err := populateProcessEnvFromSnapshot(ctx, s.processEnv, snapshot); err != nil { +- return err +- } +- +- if resolver, err := s.processEnv.GetResolver(); err == nil { +- if modResolver, ok := resolver.(*imports.ModuleResolver); ok { +- modResolver.ClearForNewMod() - } - } - - s.cachedModFileHash = modFileHash - s.cachedBuildFlags = currentBuildFlags - s.cachedDirectoryFilters = currentDirectoryFilters -- if err := s.populateProcessEnv(ctx, snapshot); err != nil { -- return err -- } -- s.runOnce = true - } - - // Run the user function. @@ -15687,7 +18672,7 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - LocalPrefix: localPrefix, - } - -- if err := fn(opts); err != nil { +- if err := fn(ctx, opts); err != nil { - return err - } - @@ -15704,10 +18689,12 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - return nil -} - --// populateProcessEnv sets the dynamically configurable fields for the view's --// process environment. Assumes that the caller is holding the s.view.importsMu. --func (s *importsState) populateProcessEnv(ctx context.Context, snapshot *snapshot) error { -- pe := s.processEnv +-// populateProcessEnvFromSnapshot sets the dynamically configurable fields for +-// the view's process environment. Assumes that the caller is holding the +-// importsState mutex. +-func populateProcessEnvFromSnapshot(ctx context.Context, pe *imports.ProcessEnv, snapshot *snapshot) error { +- ctx, done := event.Start(ctx, "cache.populateProcessEnvFromSnapshot") +- defer done() - - if snapshot.view.Options().VerboseOutput { - pe.Logf = func(format string, args ...interface{}) { @@ -15748,6 +18735,9 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor -} - -func (s *importsState) refreshProcessEnv() { +- ctx, done := event.Start(s.ctx, "cache.importsState.refreshProcessEnv") +- defer done() +- - start := time.Now() - - s.mu.Lock() @@ -15759,9 +18749,9 @@ diff -urN a/gopls/internal/lsp/cache/imports.go b/gopls/internal/lsp/cache/impor - - event.Log(s.ctx, "background imports cache refresh starting") - if err := imports.PrimeCache(context.Background(), env); err == nil { -- event.Log(s.ctx, fmt.Sprintf("background refresh finished after %v", time.Since(start))) +- event.Log(ctx, fmt.Sprintf("background refresh finished after %v", time.Since(start))) - } else { -- event.Log(s.ctx, fmt.Sprintf("background refresh finished after %v", time.Since(start)), keys.Err.Of(err)) +- event.Log(ctx, fmt.Sprintf("background refresh finished after %v", time.Since(start)), keys.Err.Of(err)) - } - s.mu.Lock() - s.cacheRefreshDuration = time.Since(start) @@ -15827,7 +18817,7 @@ diff -urN a/gopls/internal/lsp/cache/keys.go b/gopls/internal/lsp/cache/keys.go diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go --- a/gopls/internal/lsp/cache/load.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/load.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,782 +0,0 @@ +@@ -1,762 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -15846,10 +18836,10 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - "time" - - "golang.org/x/tools/go/packages" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/tag" - "golang.org/x/tools/internal/gocommand" @@ -15866,12 +18856,15 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go -// -// The resulting error may wrap the moduleErrorMap error type, representing -// errors associated with specific modules. +-// +-// If scopes contains a file scope there must be exactly one scope. -func (s *snapshot) load(ctx context.Context, allowNetwork bool, scopes ...loadScope) (err error) { - id := atomic.AddUint64(&loadID, 1) - eventName := fmt.Sprintf("go/packages.Load #%d", id) // unique name for logging - - var query []string - var containsDir bool // for logging +- var standalone bool // whether this is a load of a standalone file - - // Keep track of module query -> module path so that we can later correlate query - // errors with errors. @@ -15885,36 +18878,39 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - query = append(query, string(scope)) - - case fileLoadScope: +- // Given multiple scopes, the resulting load might contain inaccurate +- // information. For example go/packages returns at most one command-line +- // arguments package, and does not handle a combination of standalone +- // files and packages. - uri := span.URI(scope) +- if len(scopes) > 1 { +- panic(fmt.Sprintf("internal error: load called with multiple scopes when a file scope is present (file: %s)", uri)) +- } - fh := s.FindFile(uri) -- if fh == nil || s.View().FileKind(fh) != source.Go { +- if fh == nil || s.FileKind(fh) != source.Go { - // Don't try to load a file that doesn't exist, or isn't a go file. - continue - } -- contents, err := fh.Read() +- contents, err := fh.Content() - if err != nil { - continue - } - if isStandaloneFile(contents, s.view.Options().StandaloneTags) { +- standalone = true - query = append(query, uri.Filename()) - } else { - query = append(query, fmt.Sprintf("file=%s", uri.Filename())) - } - - case moduleLoadScope: -- switch scope { -- case "std", "cmd": -- query = append(query, string(scope)) -- default: -- modQuery := fmt.Sprintf("%s/...", scope) -- query = append(query, modQuery) -- moduleQueries[modQuery] = string(scope) -- } +- modQuery := fmt.Sprintf("%s%c...", scope.dir, filepath.Separator) +- query = append(query, modQuery) +- moduleQueries[modQuery] = string(scope.modulePath) - - case viewLoadScope: - // If we are outside of GOPATH, a module, or some other known - // build system, don't load subdirectories. -- if !s.ValidBuildConfiguration() { +- if !s.validBuildConfiguration() { - query = append(query, "./") - } else { - query = append(query, "./...") @@ -15933,7 +18929,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - } - sort.Strings(query) // for determinism - -- ctx, done := event.Start(ctx, "cache.view.load", tag.Query.Of(query)) +- ctx, done := event.Start(ctx, "cache.snapshot.load", tag.Query.Of(query)) - defer done() - - flags := source.LoadWorkspace @@ -15979,6 +18975,10 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - return fmt.Errorf("packages.Load error: %w", err) - } - +- if standalone && len(pkgs) > 1 { +- return bug.Errorf("internal error: go/packages returned multiple packages for standalone file") +- } +- - moduleErrs := make(map[string][]packages.Error) // module path -> errors - filterFunc := s.view.filterFunc() - newMetadata := make(map[PackageID]*source.Metadata) @@ -16031,31 +19031,36 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - if allFilesExcluded(pkg.GoFiles, filterFunc) { - continue - } -- if err := buildMetadata(ctx, pkg, cfg, query, newMetadata, nil); err != nil { -- return err -- } +- buildMetadata(newMetadata, pkg, cfg.Dir, standalone) - } - - s.mu.Lock() - +- // Assert the invariant s.packages.Get(id).m == s.meta.metadata[id]. +- s.packages.Range(func(id PackageID, ph *packageHandle) { +- if s.meta.metadata[id] != ph.m { +- panic("inconsistent metadata") +- } +- }) +- - // Compute the minimal metadata updates (for Clone) -- // required to preserve this invariant: -- // for all id, s.packages.Get(id).m == s.meta.metadata[id]. +- // required to preserve the above invariant. +- var files []span.URI // files to preload +- seenFiles := make(map[span.URI]bool) - updates := make(map[PackageID]*source.Metadata) - for _, m := range newMetadata { - if existing := s.meta.metadata[m.ID]; existing == nil { +- // Record any new files we should pre-load. +- for _, uri := range m.CompiledGoFiles { +- if !seenFiles[uri] { +- seenFiles[uri] = true +- files = append(files, uri) +- } +- } - updates[m.ID] = m - delete(s.shouldLoad, m.ID) - } - } -- // Assert the invariant. -- s.packages.Range(func(k, v interface{}) { -- id, ph := k.(PackageID), v.(*packageHandle) -- if s.meta.metadata[id] != ph.m { -- // TODO(adonovan): upgrade to unconditional panic after Jan 2023. -- bug.Reportf("inconsistent metadata") -- } -- }) - - event.Log(ctx, fmt.Sprintf("%s: updating metadata for %d packages", eventName, len(updates))) - @@ -16065,31 +19070,26 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - meta := s.meta.Clone(updates) - workspacePackages := computeWorkspacePackagesLocked(s, meta) - for _, update := range updates { -- if err := computeLoadDiagnostics(ctx, update, meta, lockedSnapshot{s}, workspacePackages); err != nil { -- return err -- } +- computeLoadDiagnostics(ctx, update, meta, lockedSnapshot{s}, workspacePackages) - } - s.meta = meta - s.workspacePackages = workspacePackages - s.resetActivePackagesLocked() - -- s.dumpWorkspace("load") - s.mu.Unlock() - -- // Recompute the workspace package handle for any packages we invalidated. -- // -- // This is (putatively) an optimization since handle construction prefetches -- // the content of all Go source files. +- // Opt: preLoad files in parallel. - // -- // However, one necessary side effect of this operation is that we are -- // guaranteed to visit all package files during load. This is required for -- // e.g. determining the set of directories to watch. +- // Requesting files in batch optimizes the underlying filesystem reads. +- // However, this is also currently necessary for correctness: populating all +- // files in the snapshot is necessary for certain operations that rely on the +- // completeness of the file map, e.g. computing the set of directories to +- // watch. - // - // TODO(rfindley, golang/go#57558): determine the set of directories based on -- // loaded packages, and skip this precomputation. -- for _, m := range updates { -- s.buildPackageHandle(ctx, m.ID) // ignore error -- } +- // loaded packages, so that reading files here is not necessary for +- // correctness. +- s.preloadFiles(ctx, files) - - if len(moduleErrs) > 0 { - return &moduleErrorMap{moduleErrs} @@ -16147,12 +19147,12 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - - // Apply diagnostics about the workspace configuration to relevant open - // files. -- openFiles := s.openFiles() +- openFiles := s.overlays() - - // If the snapshot does not have a valid build configuration, it may be - // that the user has opened a directory that contains multiple modules. - // Check for that an warn about it. -- if !s.ValidBuildConfiguration() { +- if !s.validBuildConfiguration() { - var msg string - if s.view.goversion >= 18 { - msg = `gopls was not able to find modules in your workspace. @@ -16171,57 +19171,10 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - return fmt.Errorf(msg), s.applyCriticalErrorToFiles(ctx, msg, openFiles) - } - -- // If the user has one active go.mod file, they may still be editing files -- // in nested modules. Check the module of each open file and add warnings -- // that the nested module must be opened as a workspace folder. -- if len(s.workspaceModFiles) == 1 { -- // Get the active root go.mod file to compare against. -- var rootMod string -- for uri := range s.workspaceModFiles { -- rootMod = uri.Filename() -- } -- rootDir := filepath.Dir(rootMod) -- nestedModules := make(map[string][]source.FileHandle) -- for _, fh := range openFiles { -- mod, err := findRootPattern(ctx, filepath.Dir(fh.URI().Filename()), "go.mod", s) -- if err != nil { -- if ctx.Err() != nil { -- return ctx.Err(), nil -- } -- continue -- } -- if mod == "" { -- continue -- } -- if mod != rootMod && source.InDir(rootDir, mod) { -- modDir := filepath.Dir(mod) -- nestedModules[modDir] = append(nestedModules[modDir], fh) -- } -- } -- var multiModuleMsg string -- if s.view.goversion >= 18 { -- multiModuleMsg = `To work on multiple modules at once, please use a go.work file. --See https://github.com/golang/tools/blob/master/gopls/doc/workspace.md for more information on using workspaces.` -- } else { -- multiModuleMsg = `To work on multiple modules at once, please upgrade to Go 1.18 and use a go.work file. --See https://github.com/golang/tools/blob/master/gopls/doc/workspace.md for more information on using workspaces.` -- } -- // Add a diagnostic to each file in a nested module to mark it as -- // "orphaned". Don't show a general diagnostic in the progress bar, -- // because the user may still want to edit a file in a nested module. -- var srcDiags []*source.Diagnostic -- for modDir, uris := range nestedModules { -- msg := fmt.Sprintf("This file is in %s, which is a nested module in the %s module.\n%s", modDir, rootMod, multiModuleMsg) -- srcDiags = append(srcDiags, s.applyCriticalErrorToFiles(ctx, msg, uris)...) -- } -- if len(srcDiags) != 0 { -- return fmt.Errorf("You have opened a nested module.\n%s", multiModuleMsg), srcDiags -- } -- } - return nil, nil -} - --func (s *snapshot) applyCriticalErrorToFiles(ctx context.Context, msg string, files []source.FileHandle) []*source.Diagnostic { +-func (s *snapshot) applyCriticalErrorToFiles(ctx context.Context, msg string, files []*Overlay) []*source.Diagnostic { - var srcDiags []*source.Diagnostic - for _, fh := range files { - // Place the diagnostics on the package or module declarations. @@ -16255,35 +19208,29 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go -// buildMetadata populates the updates map with metadata updates to -// apply, based on the given pkg. It recurs through pkg.Imports to ensure that -// metadata exists for all dependencies. --func buildMetadata(ctx context.Context, pkg *packages.Package, cfg *packages.Config, query []string, updates map[PackageID]*source.Metadata, path []PackageID) error { +-func buildMetadata(updates map[PackageID]*source.Metadata, pkg *packages.Package, loadDir string, standalone bool) { - // Allow for multiple ad-hoc packages in the workspace (see #47584). - pkgPath := PackagePath(pkg.PkgPath) - id := PackageID(pkg.ID) +- - if source.IsCommandLineArguments(id) { -- suffix := ":" + strings.Join(query, ",") +- if len(pkg.CompiledGoFiles) != 1 { +- bug.Reportf("unexpected files in command-line-arguments package: %v", pkg.CompiledGoFiles) +- return +- } +- suffix := pkg.CompiledGoFiles[0] - id = PackageID(pkg.ID + suffix) - pkgPath = PackagePath(pkg.PkgPath + suffix) - } - +- // Duplicate? - if _, ok := updates[id]; ok { -- // If we've already seen this dependency, there may be an import cycle, or -- // we may have reached the same package transitively via distinct paths. -- // Check the path to confirm. -- -- // TODO(rfindley): this doesn't look sufficient. Any single piece of new -- // metadata could theoretically introduce import cycles in the metadata -- // graph. What's the point of this limited check here (and is it even -- // possible to get an import cycle in data from go/packages)? Consider -- // simply returning, so that this function need not return an error. -- // -- // We should consider doing a more complete guard against import cycles -- // elsewhere. -- for _, prev := range path { -- if prev == id { -- return fmt.Errorf("import cycle detected: %q", id) -- } -- } -- return nil +- // A package was encountered twice due to shared +- // subgraphs (common) or cycles (rare). Although "go +- // list" usually breaks cycles, we don't rely on it. +- // breakImportCycles in metadataGraph.Clone takes care +- // of it later. +- return - } - - // Recreate the metadata rather than reusing it to avoid locking. @@ -16293,10 +19240,11 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - Name: PackageName(pkg.Name), - ForTest: PackagePath(packagesinternal.GetForTest(pkg)), - TypesSizes: pkg.TypesSizes, -- LoadDir: cfg.Dir, +- LoadDir: loadDir, - Module: pkg.Module, - Errors: pkg.Errors, - DepsErrors: packagesinternal.GetDepsErrors(pkg), +- Standalone: standalone, - } - - updates[id] = m @@ -16309,6 +19257,10 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - uri := span.URIFromPath(filename) - m.GoFiles = append(m.GoFiles, uri) - } +- for _, filename := range pkg.IgnoredFiles { +- uri := span.URIFromPath(filename) +- m.IgnoredFiles = append(m.IgnoredFiles, uri) +- } - - depsByImpPath := make(map[ImportPath]PackageID) - depsByPkgPath := make(map[PackagePath]PackageID) @@ -16386,25 +19338,42 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - continue - } - +- // Don't record self-import edges. +- // (This simplifies metadataGraph's cycle check.) +- if PackageID(imported.ID) == id { +- if len(pkg.Errors) == 0 { +- bug.Reportf("self-import without error in package %s", id) +- } +- continue +- } +- +- buildMetadata(updates, imported, loadDir, false) // only top level packages can be standalone +- +- // Don't record edges to packages with no name, as they cause trouble for +- // the importer (golang/go#60952). +- // +- // However, we do want to insert these packages into the update map +- // (buildMetadata above), so that we get type-checking diagnostics for the +- // invalid packages. +- if imported.Name == "" { +- depsByImpPath[importPath] = "" // missing +- continue +- } +- - depsByImpPath[importPath] = PackageID(imported.ID) - depsByPkgPath[PackagePath(imported.PkgPath)] = PackageID(imported.ID) -- if err := buildMetadata(ctx, imported, cfg, query, updates, append(path, id)); err != nil { -- event.Error(ctx, "error in dependency", err) -- } - } - m.DepsByImpPath = depsByImpPath - m.DepsByPkgPath = depsByPkgPath - - // m.Diagnostics is set later in the loading pass, using - // computeLoadDiagnostics. -- -- return nil -} - -// computeLoadDiagnostics computes and sets m.Diagnostics for the given metadata m. -// -// It should only be called during metadata construction in snapshot.load. --func computeLoadDiagnostics(ctx context.Context, m *source.Metadata, meta *metadataGraph, fs source.FileSource, workspacePackages map[PackageID]PackagePath) error { +-func computeLoadDiagnostics(ctx context.Context, m *source.Metadata, meta *metadataGraph, fs source.FileSource, workspacePackages map[PackageID]PackagePath) { - for _, packagesErr := range m.Errors { - // Filter out parse errors from go list. We'll get them when we - // actually parse, and buggy overlay support may generate spurious @@ -16432,10 +19401,8 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - // not normally fail. - event.Error(ctx, "unable to compute deps errors", err, tag.Package.Of(string(m.ID))) - } -- return nil - } - m.Diagnostics = append(m.Diagnostics, depsDiags...) -- return nil -} - -// containsPackageLocked reports whether p is a workspace package for the @@ -16497,7 +19464,8 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - } - - for uri := range uris { -- if s.isOpenLocked(uri) { +- fh, _ := s.files.Get(uri) +- if _, open := fh.(*Overlay); open { - return true - } - } @@ -16530,8 +19498,9 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - return false -} - --// computeWorkspacePackagesLocked computes workspace packages in the snapshot s --// for the given metadata graph. +-// computeWorkspacePackagesLocked computes workspace packages in the +-// snapshot s for the given metadata graph. The result does not +-// contain intermediate test variants. -// -// s.mu must be held while calling this function. -func computeWorkspacePackagesLocked(s *snapshot, meta *metadataGraph) map[PackageID]PackagePath { @@ -16565,6 +19534,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go - // - // Notably, this excludes intermediate test variants from workspace - // packages. +- assert(!m.IsIntermediateTestVariant(), "unexpected ITV") - workspacePackages[m.ID] = m.ForTest - } - } @@ -16613,7 +19583,7 @@ diff -urN a/gopls/internal/lsp/cache/load.go b/gopls/internal/lsp/cache/load.go diff -urN a/gopls/internal/lsp/cache/maps.go b/gopls/internal/lsp/cache/maps.go --- a/gopls/internal/lsp/cache/maps.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/maps.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,121 +0,0 @@ +@@ -1,78 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -16621,33 +19591,31 @@ diff -urN a/gopls/internal/lsp/cache/maps.go b/gopls/internal/lsp/cache/maps.go -package cache - -import ( -- "strings" -- - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" - "golang.org/x/tools/internal/persistent" -) - --// TODO(euroelessar): Use generics once support for go1.17 is dropped. -- -type filesMap struct { -- impl *persistent.Map --} -- --// uriLessInterface is the < relation for "any" values containing span.URIs. --func uriLessInterface(a, b interface{}) bool { -- return a.(span.URI) < b.(span.URI) +- impl *persistent.Map[span.URI, source.FileHandle] +- overlayMap map[span.URI]*Overlay // the subset that are overlays -} - -func newFilesMap() filesMap { - return filesMap{ -- impl: persistent.NewMap(uriLessInterface), +- impl: new(persistent.Map[span.URI, source.FileHandle]), +- overlayMap: make(map[span.URI]*Overlay), - } -} - -func (m filesMap) Clone() filesMap { +- overlays := make(map[span.URI]*Overlay, len(m.overlayMap)) +- for k, v := range m.overlayMap { +- overlays[k] = v +- } - return filesMap{ -- impl: m.impl.Clone(), +- impl: m.impl.Clone(), +- overlayMap: overlays, - } -} - @@ -16664,81 +19632,40 @@ diff -urN a/gopls/internal/lsp/cache/maps.go b/gopls/internal/lsp/cache/maps.go -} - -func (m filesMap) Range(do func(key span.URI, value source.FileHandle)) { -- m.impl.Range(func(key, value interface{}) { -- do(key.(span.URI), value.(source.FileHandle)) -- }) +- m.impl.Range(do) -} - -func (m filesMap) Set(key span.URI, value source.FileHandle) { - m.impl.Set(key, value, nil) --} - --func (m filesMap) Delete(key span.URI) { -- m.impl.Delete(key) --} -- --func packageIDLessInterface(x, y interface{}) bool { -- return x.(PackageID) < y.(PackageID) --} -- --type knownDirsSet struct { -- impl *persistent.Map --} -- --func newKnownDirsSet() knownDirsSet { -- return knownDirsSet{ -- impl: persistent.NewMap(func(a, b interface{}) bool { -- return a.(span.URI) < b.(span.URI) -- }), -- } --} -- --func (s knownDirsSet) Clone() knownDirsSet { -- return knownDirsSet{ -- impl: s.impl.Clone(), +- if o, ok := value.(*Overlay); ok { +- m.overlayMap[key] = o +- } else { +- // Setting a non-overlay must delete the corresponding overlay, to preserve +- // the accuracy of the overlay set. +- delete(m.overlayMap, key) - } -} - --func (s knownDirsSet) Destroy() { -- s.impl.Destroy() --} -- --func (s knownDirsSet) Contains(key span.URI) bool { -- _, ok := s.impl.Get(key) -- return ok --} -- --func (s knownDirsSet) Range(do func(key span.URI)) { -- s.impl.Range(func(key, value interface{}) { -- do(key.(span.URI)) -- }) --} -- --func (s knownDirsSet) SetAll(other knownDirsSet) { -- s.impl.SetAll(other.impl) --} -- --func (s knownDirsSet) Insert(key span.URI) { -- s.impl.Set(key, nil, nil) --} -- --func (s knownDirsSet) Remove(key span.URI) { -- s.impl.Delete(key) +-func (m *filesMap) Delete(key span.URI) { +- m.impl.Delete(key) +- delete(m.overlayMap, key) -} - --// analysisKeyLessInterface is the less-than relation for analysisKey --// values wrapped in an interface. --func analysisKeyLessInterface(a, b interface{}) bool { -- x, y := a.(analysisKey), b.(analysisKey) -- if cmp := strings.Compare(x.analyzerNames, y.analyzerNames); cmp != 0 { -- return cmp < 0 +-// overlays returns a new unordered array of overlay files. +-func (m filesMap) overlays() []*Overlay { +- // In practice we will always have at least one overlay, so there is no need +- // to optimize for the len=0 case by returning a nil slice. +- overlays := make([]*Overlay, 0, len(m.overlayMap)) +- for _, o := range m.overlayMap { +- overlays = append(overlays, o) - } -- return x.pkgid < y.pkgid +- return overlays -} diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go --- a/gopls/internal/lsp/cache/mod.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/mod.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,522 +0,0 @@ +@@ -1,518 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -16793,7 +19720,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - } - - // Await result. -- v, err := s.awaitPromise(ctx, entry.(*memoize.Promise)) +- v, err := s.awaitPromise(ctx, entry) - if err != nil { - return nil, err - } @@ -16807,7 +19734,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - _, done := event.Start(ctx, "cache.ParseMod", tag.URI.Of(fh.URI())) - defer done() - -- contents, err := fh.Read() +- contents, err := fh.Content() - if err != nil { - return nil, err - } @@ -16871,7 +19798,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - } - - // Await result. -- v, err := s.awaitPromise(ctx, entry.(*memoize.Promise)) +- v, err := s.awaitPromise(ctx, entry) - if err != nil { - return nil, err - } @@ -16884,12 +19811,12 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - _, done := event.Start(ctx, "cache.ParseWork", tag.URI.Of(fh.URI())) - defer done() - -- contents, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return nil, err - } -- m := protocol.NewMapper(fh.URI(), contents) -- file, parseErr := modfile.ParseWork(fh.URI().Filename(), contents, nil) +- m := protocol.NewMapper(fh.URI(), content) +- file, parseErr := modfile.ParseWork(fh.URI().Filename(), content, nil) - // Attempt to convert the error to a standardized parse error. - var parseErrors []*source.Diagnostic - if parseErr != nil { @@ -16923,7 +19850,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go -// it doesn't exist, it returns nil. -func (s *snapshot) goSum(ctx context.Context, modURI span.URI) []byte { - // Get the go.sum file, either from the snapshot or directly from the -- // cache. Avoid (*snapshot).GetFile here, as we don't want to add +- // cache. Avoid (*snapshot).ReadFile here, as we don't want to add - // nonexistent file handles to the snapshot if the file does not exist. - // - // TODO(rfindley): but that's not right. Changes to sum files should @@ -16932,12 +19859,12 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - var sumFH source.FileHandle = s.FindFile(sumURI) - if sumFH == nil { - var err error -- sumFH, err = s.view.fs.GetFile(ctx, sumURI) +- sumFH, err = s.view.fs.ReadFile(ctx, sumURI) - if err != nil { - return nil - } - } -- content, err := sumFH.Read() +- content, err := sumFH.Content() - if err != nil { - return nil - } @@ -16954,7 +19881,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go -func (s *snapshot) ModWhy(ctx context.Context, fh source.FileHandle) (map[string]string, error) { - uri := fh.URI() - -- if s.View().FileKind(fh) != source.Mod { +- if s.FileKind(fh) != source.Mod { - return nil, fmt.Errorf("%s is not a go.mod file", uri) - } - @@ -16981,7 +19908,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - } - - // Await result. -- v, err := s.awaitPromise(ctx, entry.(*memoize.Promise)) +- v, err := s.awaitPromise(ctx, entry) - if err != nil { - return nil, err - } @@ -17035,7 +19962,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - } - - type locatedErr struct { -- spn span.Span +- loc protocol.Location - msg string - } - diagLocations := map[*source.ParsedModule]locatedErr{} @@ -17048,7 +19975,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - - // Match the error against all the mod files in the workspace. - for _, uri := range s.ModFiles() { -- fh, err := s.GetFile(ctx, uri) +- fh, err := s.ReadFile(ctx, uri) - if err != nil { - event.Error(ctx, "getting modfile for Go command error", err) - continue @@ -17076,13 +20003,13 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - // file/position information, so don't even try to find it. - continue - } -- spn, found, err := s.matchErrorToModule(ctx, pm, msg) +- loc, found, err := s.matchErrorToModule(ctx, pm, msg) - if err != nil { - event.Error(ctx, "matching error to module", err) - continue - } - le := locatedErr{ -- spn: spn, +- loc: loc, - msg: msg, - } - if found { @@ -17100,7 +20027,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - - var srcErrs []*source.Diagnostic - for pm, le := range diagLocations { -- diag, err := s.goCommandDiagnostic(pm, le.spn, le.msg) +- diag, err := s.goCommandDiagnostic(pm, le.loc, le.msg) - if err != nil { - event.Error(ctx, "building go command diagnostic", err) - continue @@ -17121,7 +20048,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go -// -// It returns the location of a reference to the one of the modules and true -// if one exists. If none is found it returns a fallback location and false. --func (s *snapshot) matchErrorToModule(ctx context.Context, pm *source.ParsedModule, goCmdError string) (span.Span, bool, error) { +-func (s *snapshot) matchErrorToModule(ctx context.Context, pm *source.ParsedModule, goCmdError string) (protocol.Location, bool, error) { - var reference *modfile.Line - matches := moduleVersionInErrorRe.FindAllStringSubmatch(goCmdError, -1) - @@ -17140,25 +20067,21 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - // No match for the module path was found in the go.mod file. - // Show the error on the module declaration, if one exists, or - // just the first line of the file. -- if pm.File.Module == nil { -- return span.New(pm.URI, span.NewPoint(1, 1, 0), span.Point{}), false, nil +- var start, end int +- if pm.File.Module != nil && pm.File.Module.Syntax != nil { +- syntax := pm.File.Module.Syntax +- start, end = syntax.Start.Byte, syntax.End.Byte - } -- syntax := pm.File.Module.Syntax -- spn, err := pm.Mapper.OffsetSpan(syntax.Start.Byte, syntax.End.Byte) -- return spn, false, err +- loc, err := pm.Mapper.OffsetLocation(start, end) +- return loc, false, err - } - -- spn, err := pm.Mapper.OffsetSpan(reference.Start.Byte, reference.End.Byte) -- return spn, true, err +- loc, err := pm.Mapper.OffsetLocation(reference.Start.Byte, reference.End.Byte) +- return loc, true, err -} - -// goCommandDiagnostic creates a diagnostic for a given go command error. --func (s *snapshot) goCommandDiagnostic(pm *source.ParsedModule, spn span.Span, goCmdError string) (*source.Diagnostic, error) { -- rng, err := pm.Mapper.SpanRange(spn) -- if err != nil { -- return nil, err -- } -- +-func (s *snapshot) goCommandDiagnostic(pm *source.ParsedModule, loc protocol.Location, goCmdError string) (*source.Diagnostic, error) { - matches := moduleVersionInErrorRe.FindAllStringSubmatch(goCmdError, -1) - var innermost *module.Version - for i := len(matches) - 1; i >= 0; i-- { @@ -17178,7 +20101,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - } - return &source.Diagnostic{ - URI: pm.URI, -- Range: rng, +- Range: loc.Range, - Severity: protocol.SeverityError, - Source: source.ListError, - Message: `Inconsistent vendoring detected. Please re-run "go mod vendor". @@ -17205,7 +20128,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - } - return &source.Diagnostic{ - URI: pm.URI, -- Range: rng, +- Range: loc.Range, - Severity: protocol.SeverityError, - Source: source.ListError, - Message: msg, @@ -17226,7 +20149,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - } - return &source.Diagnostic{ - URI: pm.URI, -- Range: rng, +- Range: loc.Range, - Severity: protocol.SeverityError, - Message: fmt.Sprintf("%v@%v has not been downloaded", innermost.Path, innermost.Version), - Source: source.ListError, @@ -17235,7 +20158,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go - default: - return &source.Diagnostic{ - URI: pm.URI, -- Range: rng, +- Range: loc.Range, - Severity: protocol.SeverityError, - Source: source.ListError, - Message: goCmdError, @@ -17264,7 +20187,7 @@ diff -urN a/gopls/internal/lsp/cache/mod.go b/gopls/internal/lsp/cache/mod.go diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_tidy.go --- a/gopls/internal/lsp/cache/mod_tidy.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/mod_tidy.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,469 +0,0 @@ +@@ -1,501 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -17275,7 +20198,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - "context" - "fmt" - "go/ast" -- "io/ioutil" +- "go/token" - "os" - "path/filepath" - "strconv" @@ -17295,6 +20218,9 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ -// ModTidy returns the go.mod file that would be obtained by running -// "go mod tidy". Concurrent requests are combined into a single command. -func (s *snapshot) ModTidy(ctx context.Context, pm *source.ParsedModule) (*source.TidiedModule, error) { +- ctx, done := event.Start(ctx, "cache.snapshot.ModTidy") +- defer done() +- - uri := pm.URI - if pm.File == nil { - return nil, fmt.Errorf("cannot tidy unparseable go.mod file: %v", uri) @@ -17314,7 +20240,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - // If the file handle is an overlay, it may not be written to disk. - // The go.mod file has to be on disk for `go mod tidy` to work. - // TODO(rfindley): is this still true with Go 1.16 overlay support? -- fh, err := s.GetFile(ctx, pm.URI) +- fh, err := s.ReadFile(ctx, pm.URI) - if err != nil { - return nil, err - } @@ -17324,7 +20250,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - } - } - -- if criticalErr := s.GetCriticalError(ctx); criticalErr != nil { +- if criticalErr := s.CriticalError(ctx); criticalErr != nil { - return &source.TidiedModule{ - Diagnostics: criticalErr.Diagnostics, - }, nil @@ -17349,7 +20275,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - } - - // Await result. -- v, err := s.awaitPromise(ctx, entry.(*memoize.Promise)) +- v, err := s.awaitPromise(ctx, entry) - if err != nil { - return nil, err - } @@ -17381,7 +20307,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - - // Go directly to disk to get the temporary mod file, - // since it is always on disk. -- tempContents, err := ioutil.ReadFile(tmpURI.Filename()) +- tempContents, err := os.ReadFile(tmpURI.Filename()) - if err != nil { - return nil, err - } @@ -17432,7 +20358,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - for _, req := range wrongDirectness { - // Handle dependencies that are incorrectly labeled indirect and - // vice versa. -- srcDiag, err := directnessDiagnostic(pm.Mapper, req, snapshot.View().Options().ComputeEdits) +- srcDiag, err := directnessDiagnostic(pm.Mapper, req, snapshot.Options().ComputeEdits) - if err != nil { - // We're probably in a bad state if we can't compute a - // directnessDiagnostic, but try to keep going so as to not suppress @@ -17446,7 +20372,33 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - // go.mod file. The fixes will be for the go.mod file, but the - // diagnostics should also appear in both the go.mod file and the import - // statements in the Go files in which the dependencies are used. +- // Finally, add errors for any unused dependencies. +- if len(missing) > 0 { +- missingModuleDiagnostics, err := missingModuleDiagnostics(ctx, snapshot, pm, ideal, missing) +- if err != nil { +- return nil, err +- } +- diagnostics = append(diagnostics, missingModuleDiagnostics...) +- } +- +- // Opt: if this is the only diagnostic, we can avoid textual edits and just +- // run the Go command. +- // +- // See also the documentation for command.RemoveDependencyArgs.OnlyDiagnostic. +- onlyDiagnostic := len(diagnostics) == 0 && len(unused) == 1 +- for _, req := range unused { +- srcErr, err := unusedDiagnostic(pm.Mapper, req, onlyDiagnostic) +- if err != nil { +- return nil, err +- } +- diagnostics = append(diagnostics, srcErr) +- } +- return diagnostics, nil +-} +- +-func missingModuleDiagnostics(ctx context.Context, snapshot *snapshot, pm *source.ParsedModule, ideal *modfile.File, missing map[string]*modfile.Require) ([]*source.Diagnostic, error) { - missingModuleFixes := map[*modfile.Require][]source.SuggestedFix{} +- var diagnostics []*source.Diagnostic - for _, req := range missing { - srcDiag, err := missingModuleDiagnostic(pm, req) - if err != nil { @@ -17455,12 +20407,24 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - missingModuleFixes[req] = srcDiag.SuggestedFixes - diagnostics = append(diagnostics, srcDiag) - } +- - // Add diagnostics for missing modules anywhere they are imported in the - // workspace. +- metas, err := snapshot.WorkspaceMetadata(ctx) +- if err != nil { +- return nil, err +- } - // TODO(adonovan): opt: opportunities for parallelism abound. -- for _, m := range snapshot.workspaceMetadata() { -- // Read both lists of files of this package, in parallel. -- goFiles, compiledGoFiles, err := readGoFiles(ctx, snapshot, m) +- for _, m := range metas { +- // Read both lists of files of this package. +- // +- // Parallelism is not necessary here as the files will have already been +- // pre-read at load time. +- goFiles, err := readFiles(ctx, snapshot, m.GoFiles) +- if err != nil { +- return nil, err +- } +- compiledGoFiles, err := readFiles(ctx, snapshot, m.CompiledGoFiles) - if err != nil { - return nil, err - } @@ -17541,15 +20505,6 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ - } - } - } -- // Finally, add errors for any unused dependencies. -- onlyDiagnostic := len(diagnostics) == 0 && len(unused) == 1 -- for _, req := range unused { -- srcErr, err := unusedDiagnostic(pm.Mapper, req, onlyDiagnostic) -- if err != nil { -- return nil, err -- } -- diagnostics = append(diagnostics, srcErr) -- } - return diagnostics, nil -} - @@ -17720,7 +20675,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_tidy.go b/gopls/internal/lsp/cache/mod_ -// -// TODO(rfindley): this should key off source.ImportPath. -func parseImports(ctx context.Context, s *snapshot, files []source.FileHandle) (map[string]bool, error) { -- pgfs, _, err := s.parseCache.parseFiles(ctx, source.ParseHeader, files...) +- pgfs, err := s.view.parseCache.parseFiles(ctx, token.NewFileSet(), source.ParseHeader, false, files...) - if err != nil { // e.g. context cancellation - return nil, err - } @@ -17773,7 +20728,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_vuln.go b/gopls/internal/lsp/cache/mod_ - // The go.mod file has to be on disk for vulncheck to work. - // - // TODO(hyangah): use overlays for vulncheck. -- fh, err := s.GetFile(ctx, modURI) +- fh, err := s.ReadFile(ctx, modURI) - if err != nil { - return nil, err - } @@ -17795,7 +20750,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_vuln.go b/gopls/internal/lsp/cache/mod_ - } - - // Await result. -- v, err := s.awaitPromise(ctx, entry.(*memoize.Promise)) +- v, err := s.awaitPromise(ctx, entry) - if err != nil { - return nil, err - } @@ -17807,7 +20762,7 @@ diff -urN a/gopls/internal/lsp/cache/mod_vuln.go b/gopls/internal/lsp/cache/mod_ - if vulncheck.VulnerablePackages == nil { - return &govulncheck.Result{}, nil - } -- fh, err := s.GetFile(ctx, uri) +- fh, err := s.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -17939,7 +20894,7 @@ diff -urN a/gopls/internal/lsp/cache/os_windows.go b/gopls/internal/lsp/cache/os diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/parse_cache.go --- a/gopls/internal/lsp/cache/parse_cache.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/parse_cache.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,298 +0,0 @@ +@@ -1,418 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -17947,37 +20902,76 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/p -package cache - -import ( +- "bytes" - "container/heap" - "context" +- "fmt" +- "go/parser" - "go/token" +- "math/bits" - "runtime" -- "sort" - "sync" +- "time" - - "golang.org/x/sync/errgroup" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" - "golang.org/x/tools/internal/memoize" +- "golang.org/x/tools/internal/tokeninternal" -) - --// This file contains an implementation of a bounded-size parse cache, that --// offsets the base token.Pos value of each cached file so that they may be --// later described by a single dedicated FileSet. +-// This file contains an implementation of an LRU parse cache, that offsets the +-// base token.Pos value of each cached file so that they may be later described +-// by a single dedicated FileSet. -// -// This is achieved by tracking a monotonic offset in the token.Pos space, that -// is incremented before parsing allow room for the resulting parsed file. - --// Keep 200 recently parsed files, based on the following rationale: --// - One of the most important benefits of caching is avoiding re-parsing --// everything in a package when working on a single file. No packages in --// Kubernetes have > 200 files (only one has > 100). --// - Experience has shown that ~1000 parsed files can use noticeable space. --// 200 feels like a sweet spot between limiting cache size and optimizing --// cache hits for low-latency operations. --const parseCacheMaxFiles = 200 +-// reservedForParsing defines the room in the token.Pos space reserved for +-// cached parsed files. +-// +-// Files parsed through the parseCache are guaranteed not to have overlapping +-// spans: the parseCache tracks a monotonic base for newly parsed files. +-// +-// By offsetting the initial base of a FileSet, we can allow other operations +-// accepting the FileSet (such as the gcimporter) to add new files using the +-// normal FileSet APIs without overlapping with cached parsed files. +-// +-// Note that 1<<60 represents an exabyte of parsed data, more than any gopls +-// process can ever parse. +-// +-// On 32-bit systems we don't cache parse results (see parseFiles). +-const reservedForParsing = 1 << (bits.UintSize - 4) - --// parsePadding is additional padding allocated between entries in the parse --// cache to allow for increases in length (such as appending missing braces) --// caused by fixAST. +-// fileSetWithBase returns a new token.FileSet with Base() equal to the +-// requested base. +-// +-// If base < 1, fileSetWithBase panics. +-// (1 is the smallest permitted FileSet base). +-func fileSetWithBase(base int) *token.FileSet { +- fset := token.NewFileSet() +- if base > 1 { +- // Add a dummy file to set the base of fset. We won't ever use the +- // resulting FileSet, so it doesn't matter how we achieve this. +- // +- // FileSets leave a 1-byte padding between files, so we set the base by +- // adding a zero-length file at base-1. +- fset.AddFile("", base-1, 0) +- } +- if fset.Base() != base { +- panic("unexpected FileSet.Base") +- } +- return fset +-} +- +-const ( +- // Always keep 100 recent files, independent of their wall-clock age, to +- // optimize the case where the user resumes editing after a delay. +- parseCacheMinFiles = 100 +-) +- +-// parsePadding is additional padding allocated to allow for increases in +-// length (such as appending missing braces) caused by fixAST. -// -// This is used to mitigate a chicken and egg problem: we must know the base -// offset of the file we're about to parse, before we start parsing, and yet @@ -17991,42 +20985,65 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/p -// This value is mutable for testing, so that we can exercise the slow path. -var parsePadding = 1000 // mutable for testing - --// A parseCache holds a bounded number of recently accessed parsed Go files. As --// new files are stored, older files may be evicted from the cache. +-// A parseCache holds recently accessed parsed Go files. After new files are +-// stored, older files may be evicted from the cache via garbage collection. -// -// The parseCache.parseFiles method exposes a batch API for parsing (and -// caching) multiple files. This is necessary for type-checking, where files -// must be parsed in a common fileset. -type parseCache struct { -- mu sync.Mutex -- m map[parseKey]*parseCacheEntry -- lru queue // min-atime priority queue of *parseCacheEntry -- clock uint64 // clock time, incremented when the cache is updated -- nextOffset token.Pos // token.Pos offset for the next parsed file +- expireAfter time.Duration // interval at which to collect expired cache entries +- done chan struct{} // closed when GC is stopped +- +- mu sync.Mutex +- m map[parseKey]*parseCacheEntry +- lru queue // min-atime priority queue of *parseCacheEntry +- clock uint64 // clock time, incremented when the cache is updated +- nextBase int // base offset for the next parsed file +-} +- +-// newParseCache creates a new parse cache and starts a goroutine to garbage +-// collect entries whose age is at least expireAfter. +-// +-// Callers must call parseCache.stop when the parse cache is no longer in use. +-func newParseCache(expireAfter time.Duration) *parseCache { +- c := &parseCache{ +- expireAfter: expireAfter, +- m: make(map[parseKey]*parseCacheEntry), +- done: make(chan struct{}), +- } +- go c.gc() +- return c +-} +- +-// stop causes the GC goroutine to exit. +-func (c *parseCache) stop() { +- close(c.done) -} - -// parseKey uniquely identifies a parsed Go file. -type parseKey struct { -- file source.FileIdentity -- mode source.ParseMode +- uri span.URI +- mode parser.Mode +- purgeFuncBodies bool -} - -type parseCacheEntry struct { - key parseKey +- hash source.Hash - promise *memoize.Promise // memoize.Promise[*source.ParsedGoFile] -- atime uint64 // clock time of last access -- lruIndex int +- atime uint64 // clock time of last access, for use in LRU sorting +- walltime time.Time // actual time of last access, for use in time-based eviction; too coarse for LRU on some systems +- lruIndex int // owned by the queue implementation -} - --// startParse prepares a parsing pass, using the following steps: --// - search for cache hits --// - create new promises for cache misses --// - store as many new promises in the cache as space will allow +-// startParse prepares a parsing pass, creating new promises in the cache for +-// any cache misses. -// -// The resulting slice has an entry for every given file handle, though some -// entries may be nil if there was an error reading the file (in which case the -// resulting error will be non-nil). --func (c *parseCache) startParse(mode source.ParseMode, fhs ...source.FileHandle) ([]*memoize.Promise, error) { +-func (c *parseCache) startParse(mode parser.Mode, purgeFuncBodies bool, fhs ...source.FileHandle) ([]*memoize.Promise, error) { - c.mu.Lock() - defer c.mu.Unlock() - @@ -18035,6 +21052,7 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/p - // - // All entries parsed from a single call get the same access time. - c.clock++ +- walltime := time.Now() - - // Read file data and collect cacheable files. - var ( @@ -18043,56 +21061,83 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/p - firstReadError error // first error from fh.Read, or nil - ) - for i, fh := range fhs { -- src, err := fh.Read() +- content, err := fh.Content() - if err != nil { - if firstReadError == nil { - firstReadError = err - } - continue - } -- data[i] = src +- data[i] = content - - key := parseKey{ -- file: fh.FileIdentity(), -- mode: mode, +- uri: fh.URI(), +- mode: mode, +- purgeFuncBodies: purgeFuncBodies, - } - -- // Check for a cache hit. - if e, ok := c.m[key]; ok { -- e.atime = c.clock -- heap.Fix(&c.lru, e.lruIndex) -- promises[i] = e.promise -- continue +- if e.hash == fh.FileIdentity().Hash { // cache hit +- e.atime = c.clock +- e.walltime = walltime +- heap.Fix(&c.lru, e.lruIndex) +- promises[i] = e.promise +- continue +- } else { +- // A cache hit, for a different version. Delete it. +- delete(c.m, e.key) +- heap.Remove(&c.lru, e.lruIndex) +- } - } - -- // ...otherwise, create a new promise to parse with a non-overlapping offset -- fset := token.NewFileSet() -- if c.nextOffset > 0 { -- // Add a dummy file so that this parsed file does not overlap with others. -- fset.AddFile("", 1, int(c.nextOffset)) -- } -- c.nextOffset += token.Pos(len(src) + parsePadding + 1) // leave room for src fixes -- fh := fh -- promise := memoize.NewPromise(string(fh.URI()), func(ctx context.Context, _ interface{}) interface{} { -- return parseGoSrc(ctx, fset, fh.URI(), src, mode) +- uri := fh.URI() +- promise := memoize.NewPromise("parseCache.parse", func(ctx context.Context, _ interface{}) interface{} { +- // Allocate 2*len(content)+parsePadding to allow for re-parsing once +- // inside of parseGoSrc without exceeding the allocated space. +- base, nextBase := c.allocateSpace(2*len(content) + parsePadding) +- +- pgf, fixes1 := ParseGoSrc(ctx, fileSetWithBase(base), uri, content, mode, purgeFuncBodies) +- file := pgf.Tok +- if file.Base()+file.Size()+1 > nextBase { +- // The parsed file exceeds its allocated space, likely due to multiple +- // passes of src fixing. In this case, we have no choice but to re-do +- // the operation with the correct size. +- // +- // Even though the final successful parse requires only file.Size() +- // bytes of Pos space, we need to accommodate all the missteps to get +- // there, as parseGoSrc will repeat them. +- actual := file.Base() + file.Size() - base // actual size consumed, after re-parsing +- base2, nextBase2 := c.allocateSpace(actual) +- pgf2, fixes2 := ParseGoSrc(ctx, fileSetWithBase(base2), uri, content, mode, purgeFuncBodies) +- +- // In golang/go#59097 we observed that this panic condition was hit. +- // One bug was found and fixed, but record more information here in +- // case there is still a bug here. +- if end := pgf2.Tok.Base() + pgf2.Tok.Size(); end != nextBase2-1 { +- var errBuf bytes.Buffer +- fmt.Fprintf(&errBuf, "internal error: non-deterministic parsing result:\n") +- fmt.Fprintf(&errBuf, "\t%q (%d-%d) does not span %d-%d\n", uri, pgf2.Tok.Base(), base2, end, nextBase2-1) +- fmt.Fprintf(&errBuf, "\tfirst %q (%d-%d)\n", pgf.URI, pgf.Tok.Base(), pgf.Tok.Base()+pgf.Tok.Size()) +- fmt.Fprintf(&errBuf, "\tfirst space: (%d-%d), second space: (%d-%d)\n", base, nextBase, base2, nextBase2) +- fmt.Fprintf(&errBuf, "\tfirst mode: %v, second mode: %v", pgf.Mode, pgf2.Mode) +- fmt.Fprintf(&errBuf, "\tfirst err: %v, second err: %v", pgf.ParseErr, pgf2.ParseErr) +- fmt.Fprintf(&errBuf, "\tfirst fixes: %v, second fixes: %v", fixes1, fixes2) +- panic(errBuf.String()) +- } +- pgf = pgf2 +- } +- return pgf - }) - promises[i] = promise - -- var e *parseCacheEntry -- if len(c.lru) < parseCacheMaxFiles { -- // add new entry -- e = new(parseCacheEntry) -- if c.m == nil { -- c.m = make(map[parseKey]*parseCacheEntry) -- } -- } else { -- // evict oldest entry -- e = heap.Pop(&c.lru).(*parseCacheEntry) -- delete(c.m, e.key) +- // add new entry; entries are gc'ed asynchronously +- e := &parseCacheEntry{ +- key: key, +- hash: fh.FileIdentity().Hash, +- promise: promise, +- atime: c.clock, +- walltime: walltime, - } -- e.key = key -- e.promise = promise -- e.atime = c.clock - c.m[e.key] = e - heap.Push(&c.lru, e) - } @@ -18104,24 +21149,93 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/p - return promises, firstReadError -} - --// parseFiles returns a ParsedGoFile for the given file handles in the --// requested parse mode. --// --// If parseFiles returns an error, it still returns a slice, --// but with a nil entry for each file that could not be parsed. +-func (c *parseCache) gc() { +- const period = 10 * time.Second // gc period +- timer := time.NewTicker(period) +- defer timer.Stop() +- +- for { +- select { +- case <-c.done: +- return +- case <-timer.C: +- } +- +- c.gcOnce() +- } +-} +- +-func (c *parseCache) gcOnce() { +- now := time.Now() +- c.mu.Lock() +- defer c.mu.Unlock() +- +- for len(c.m) > parseCacheMinFiles { +- e := heap.Pop(&c.lru).(*parseCacheEntry) +- if now.Sub(e.walltime) >= c.expireAfter { +- delete(c.m, e.key) +- } else { +- heap.Push(&c.lru, e) +- break +- } +- } +-} +- +-// allocateSpace reserves the next n bytes of token.Pos space in the +-// cache. -// --// The second result is a FileSet describing all resulting parsed files. +-// It returns the resulting file base, next base, and an offset FileSet to use +-// for parsing. +-func (c *parseCache) allocateSpace(size int) (int, int) { +- c.mu.Lock() +- defer c.mu.Unlock() +- +- if c.nextBase == 0 { +- // FileSet base values must be at least 1. +- c.nextBase = 1 +- } +- base := c.nextBase +- c.nextBase += size + 1 +- return base, c.nextBase +-} +- +-// parseFiles returns a ParsedGoFile for each file handle in fhs, in the +-// requested parse mode. -// -// For parsed files that already exists in the cache, access time will be -// updated. For others, parseFiles will parse and store as many results in the -// cache as space allows. --func (c *parseCache) parseFiles(ctx context.Context, mode source.ParseMode, fhs ...source.FileHandle) ([]*source.ParsedGoFile, *token.FileSet, error) { -- promises, firstReadError := c.startParse(mode, fhs...) +-// +-// The token.File for each resulting parsed file will be added to the provided +-// FileSet, using the tokeninternal.AddExistingFiles API. Consequently, the +-// given fset should only be used in other APIs if its base is >= +-// reservedForParsing. +-// +-// If parseFiles returns an error, it still returns a slice, +-// but with a nil entry for each file that could not be parsed. +-func (c *parseCache) parseFiles(ctx context.Context, fset *token.FileSet, mode parser.Mode, purgeFuncBodies bool, fhs ...source.FileHandle) ([]*source.ParsedGoFile, error) { +- pgfs := make([]*source.ParsedGoFile, len(fhs)) +- +- // Temporary fall-back for 32-bit systems, where reservedForParsing is too +- // small to be viable. We don't actually support 32-bit systems, so this +- // workaround is only for tests and can be removed when we stop running +- // 32-bit TryBots for gopls. +- if bits.UintSize == 32 { +- for i, fh := range fhs { +- var err error +- pgfs[i], err = parseGoImpl(ctx, fset, fh, mode, purgeFuncBodies) +- if err != nil { +- return pgfs, err +- } +- } +- return pgfs, nil +- } +- +- promises, firstErr := c.startParse(mode, purgeFuncBodies, fhs...) - - // Await all parsing. - var g errgroup.Group - g.SetLimit(runtime.GOMAXPROCS(-1)) // parsing is CPU-bound. -- pgfs := make([]*source.ParsedGoFile, len(fhs)) - for i, promise := range promises { - if promise == nil { - continue @@ -18137,77 +21251,38 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/p - return nil - }) - } -- if err := g.Wait(); err != nil { -- return nil, nil, err -- } - -- // Construct a token.FileSet mapping all parsed files, and update their -- // Tok to the corresponding file in the new fileset. -- // -- // In the unlikely event that a parsed file no longer fits in its allocated -- // space in the FileSet range, it will need to be re-parsed. +- if err := g.Wait(); err != nil && firstErr == nil { +- firstErr = err +- } - +- // Augment the FileSet to map all parsed files. - var tokenFiles []*token.File -- fileIndex := make(map[*token.File]int) // to look up original indexes after sorting -- for i, pgf := range pgfs { +- for _, pgf := range pgfs { - if pgf == nil { - continue - } -- fileIndex[pgf.Tok] = i - tokenFiles = append(tokenFiles, pgf.Tok) - } +- tokeninternal.AddExistingFiles(fset, tokenFiles) - -- sort.Slice(tokenFiles, func(i, j int) bool { -- return tokenFiles[i].Base() < tokenFiles[j].Base() -- }) -- -- var needReparse []int // files requiring reparsing -- out := tokenFiles[:0] -- for i, f := range tokenFiles { -- if i < len(tokenFiles)-1 && f.Base()+f.Size() >= tokenFiles[i+1].Base() { -- if f != tokenFiles[i+1] { // no need to re-parse duplicates -- needReparse = append(needReparse, fileIndex[f]) +- const debugIssue59080 = true +- if debugIssue59080 { +- for _, f := range tokenFiles { +- pos := token.Pos(f.Base()) +- f2 := fset.File(pos) +- if f2 != f { +- panic(fmt.Sprintf("internal error: File(%d (start)) = %v, not %v", pos, f2, f)) - } -- } else { -- out = append(out, f) -- } -- } -- fset := source.FileSetFor(out...) -- -- // Re-parse any remaining files using the stitched fileSet. -- for _, i := range needReparse { -- // Start from scratch, rather than using ParsedGoFile.Src, so that source -- // fixing operates exactly the same (note that fixing stops after a limited -- // number of tries). -- fh := fhs[i] -- src, err := fh.Read() -- if err != nil { -- if firstReadError == nil { -- firstReadError = err +- pos = token.Pos(f.Base() + f.Size()) +- f2 = fset.File(pos) +- if f2 != f { +- panic(fmt.Sprintf("internal error: File(%d (end)) = %v, not %v", pos, f2, f)) - } -- continue -- } -- pgfs[i] = parseGoSrc(ctx, fset, fh.URI(), src, mode) -- } -- -- // Ensure each PGF refers to a token.File from the new FileSet. -- for i, pgf := range pgfs { -- if pgf == nil { -- continue -- } -- newTok := fset.File(token.Pos(pgf.Tok.Base())) -- if newTok == nil { -- panic("internal error: missing tok for " + pgf.URI) - } -- if newTok.Base() != pgf.Tok.Base() || newTok.Size() != pgf.Tok.Size() { -- panic("internal error: mismatching token.File in synthetic FileSet") -- } -- pgf2 := *pgf -- pgf2.Tok = newTok -- pgfs[i] = &pgf2 - } - -- return pgfs, fset, firstReadError +- return pgfs, firstErr -} - -// -- priority queue boilerplate -- @@ -18241,7 +21316,7 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache.go b/gopls/internal/lsp/cache/p diff -urN a/gopls/internal/lsp/cache/parse_cache_test.go b/gopls/internal/lsp/cache/parse_cache_test.go --- a/gopls/internal/lsp/cache/parse_cache_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/parse_cache_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,142 +0,0 @@ +@@ -1,233 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -18252,43 +21327,56 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache_test.go b/gopls/internal/lsp/ca - "context" - "fmt" - "go/token" +- "math/bits" - "testing" +- "time" - - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -) - +-func skipIfNoParseCache(t *testing.T) { +- if bits.UintSize == 32 { +- t.Skip("the parse cache is not supported on 32-bit systems") +- } +-} +- -func TestParseCache(t *testing.T) { +- skipIfNoParseCache(t) +- - ctx := context.Background() - uri := span.URI("file:///myfile") - fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) +- fset := token.NewFileSet() - -- var cache parseCache -- pgfs1, _, err := cache.parseFiles(ctx, source.ParseFull, fh) +- cache := newParseCache(0) +- pgfs1, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) - if err != nil { - t.Fatal(err) - } - pgf1 := pgfs1[0] -- pgfs2, _, err := cache.parseFiles(ctx, source.ParseFull, fh) +- pgfs2, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) - pgf2 := pgfs2[0] - if err != nil { - t.Fatal(err) - } -- if pgf1.File != pgf2.File { +- if pgf1 != pgf2 { - t.Errorf("parseFiles(%q): unexpected cache miss on repeated call", uri) - } - - // Fill up the cache with other files, but don't evict the file above. +- cache.gcOnce() - files := []source.FileHandle{fh} -- files = append(files, dummyFileHandles(parseCacheMaxFiles-1)...) -- pgfs3, fset, err := cache.parseFiles(ctx, source.ParseFull, files...) +- files = append(files, dummyFileHandles(parseCacheMinFiles-1)...) +- +- pgfs3, err := cache.parseFiles(ctx, fset, source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } - pgf3 := pgfs3[0] -- if pgf3.File != pgf1.File { +- if pgf3 != pgf1 { - t.Errorf("parseFiles(%q, ...): unexpected cache miss", uri) - } -- if pgf3.Tok == pgf1.Tok { -- t.Errorf("parseFiles(%q, ...): unexpectedly matching token file", uri) -- } - if pgf3.Tok.Base() != pgf1.Tok.Base() || pgf3.Tok.Size() != pgf1.Tok.Size() { - t.Errorf("parseFiles(%q, ...): result.Tok has base: %d, size: %d, want (%d, %d)", uri, pgf3.Tok.Base(), pgf3.Tok.Size(), pgf1.Tok.Base(), pgf1.Tok.Size()) - } @@ -18297,50 +21385,128 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache_test.go b/gopls/internal/lsp/ca - } - - // Now overwrite the cache, after which we should get new results. -- files = dummyFileHandles(parseCacheMaxFiles) -- _, _, err = cache.parseFiles(ctx, source.ParseFull, files...) +- cache.gcOnce() +- files = dummyFileHandles(parseCacheMinFiles) +- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) - if err != nil { - t.Fatal(err) - } -- pgfs4, _, err := cache.parseFiles(ctx, source.ParseFull, fh) +- // force a GC, which should collect the recently parsed files +- cache.gcOnce() +- pgfs4, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh) - if err != nil { - t.Fatal(err) - } -- if pgfs4[0].File == pgf1.File { +- if pgfs4[0] == pgf1 { - t.Errorf("parseFiles(%q): unexpected cache hit after overwriting cache", uri) - } -} - -func TestParseCache_Reparsing(t *testing.T) { +- skipIfNoParseCache(t) +- - defer func(padding int) { - parsePadding = padding - }(parsePadding) - parsePadding = 0 - -- files := dummyFileHandles(parseCacheMaxFiles) +- files := dummyFileHandles(parseCacheMinFiles) - danglingSelector := []byte("package p\nfunc _() {\n\tx.\n}") - files = append(files, makeFakeFileHandle("file:///bad1", danglingSelector)) - files = append(files, makeFakeFileHandle("file:///bad2", danglingSelector)) - - // Parsing should succeed even though we overflow the padding. -- var cache parseCache -- _, _, err := cache.parseFiles(context.Background(), source.ParseFull, files...) +- cache := newParseCache(0) +- _, err := cache.parseFiles(context.Background(), token.NewFileSet(), source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +-} +- +-// Re-parsing the first file should not panic. +-func TestParseCache_Issue59097(t *testing.T) { +- skipIfNoParseCache(t) +- +- defer func(padding int) { +- parsePadding = padding +- }(parsePadding) +- parsePadding = 0 +- +- danglingSelector := []byte("package p\nfunc _() {\n\tx.\n}") +- files := []source.FileHandle{makeFakeFileHandle("file:///bad", danglingSelector)} +- +- // Parsing should succeed even though we overflow the padding. +- cache := newParseCache(0) +- _, err := cache.parseFiles(context.Background(), token.NewFileSet(), source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +-} +- +-func TestParseCache_TimeEviction(t *testing.T) { +- skipIfNoParseCache(t) +- +- ctx := context.Background() +- fset := token.NewFileSet() +- uri := span.URI("file:///myfile") +- fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) +- +- const gcDuration = 10 * time.Millisecond +- cache := newParseCache(gcDuration) +- cache.stop() // we'll manage GC manually, for testing. +- +- pgfs0, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) +- if err != nil { +- t.Fatal(err) +- } +- +- files := dummyFileHandles(parseCacheMinFiles) +- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) +- if err != nil { +- t.Fatal(err) +- } +- +- // Even after filling up the 'min' files, we get a cache hit for our original file. +- pgfs1, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) - if err != nil { - t.Fatal(err) - } +- +- if pgfs0[0] != pgfs1[0] { +- t.Errorf("before GC, got unexpected cache miss") +- } +- +- // But after GC, we get a cache miss. +- _, err = cache.parseFiles(ctx, fset, source.ParseFull, false, files...) // mark dummy files as newer +- if err != nil { +- t.Fatal(err) +- } +- time.Sleep(gcDuration) +- cache.gcOnce() +- +- pgfs2, err := cache.parseFiles(ctx, fset, source.ParseFull, false, fh, fh) +- if err != nil { +- t.Fatal(err) +- } +- +- if pgfs0[0] == pgfs2[0] { +- t.Errorf("after GC, got unexpected cache hit for %s", pgfs0[0].URI) +- } -} - -func TestParseCache_Duplicates(t *testing.T) { +- skipIfNoParseCache(t) +- - ctx := context.Background() - uri := span.URI("file:///myfile") - fh := makeFakeFileHandle(uri, []byte("package p\n\nconst _ = \"foo\"")) - -- var cache parseCache -- pgfs, _, err := cache.parseFiles(ctx, source.ParseFull, fh, fh) +- cache := newParseCache(0) +- pgfs, err := cache.parseFiles(ctx, token.NewFileSet(), source.ParseFull, false, fh, fh) - if err != nil { - t.Fatal(err) - } -- if pgfs[0].File != pgfs[1].File { +- if pgfs[0] != pgfs[1] { - t.Errorf("parseFiles(fh, fh): = [%p, %p], want duplicate files", pgfs[0].File, pgfs[1].File) - } -} @@ -18374,7 +21540,7 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache_test.go b/gopls/internal/lsp/ca - return h.uri -} - --func (h fakeFileHandle) Read() ([]byte, error) { +-func (h fakeFileHandle) Content() ([]byte, error) { - return h.data, nil -} - @@ -18387,7 +21553,7 @@ diff -urN a/gopls/internal/lsp/cache/parse_cache_test.go b/gopls/internal/lsp/ca diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.go --- a/gopls/internal/lsp/cache/parse.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/parse.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,900 +0,0 @@ +@@ -1,969 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -18405,6 +21571,7 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - "path/filepath" - "reflect" - +- goplsastutil "golang.org/x/tools/gopls/internal/astutil" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/lsp/source" @@ -18416,8 +21583,8 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - -// ParseGo parses the file whose contents are provided by fh, using a cache. -// The resulting tree may have beeen fixed up. --func (s *snapshot) ParseGo(ctx context.Context, fh source.FileHandle, mode source.ParseMode) (*source.ParsedGoFile, error) { -- pgfs, _, err := s.parseCache.parseFiles(ctx, mode, fh) +-func (s *snapshot) ParseGo(ctx context.Context, fh source.FileHandle, mode parser.Mode) (*source.ParsedGoFile, error) { +- pgfs, err := s.view.parseCache.parseFiles(ctx, token.NewFileSet(), mode, false, fh) - if err != nil { - return nil, err - } @@ -18425,29 +21592,34 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g -} - -// parseGoImpl parses the Go source file whose content is provided by fh. --func parseGoImpl(ctx context.Context, fset *token.FileSet, fh source.FileHandle, mode source.ParseMode) (*source.ParsedGoFile, error) { -- ctx, done := event.Start(ctx, "cache.parseGo", tag.File.Of(fh.URI().Filename())) -- defer done() -- +-func parseGoImpl(ctx context.Context, fset *token.FileSet, fh source.FileHandle, mode parser.Mode, purgeFuncBodies bool) (*source.ParsedGoFile, error) { - ext := filepath.Ext(fh.URI().Filename()) - if ext != ".go" && ext != "" { // files generated by cgo have no extension - return nil, fmt.Errorf("cannot parse non-Go file %s", fh.URI()) - } -- src, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return nil, err - } -- return parseGoSrc(ctx, fset, fh.URI(), src, mode), nil +- // Check for context cancellation before actually doing the parse. +- if ctx.Err() != nil { +- return nil, ctx.Err() +- } +- pgf, _ := ParseGoSrc(ctx, fset, fh.URI(), content, mode, purgeFuncBodies) +- return pgf, nil -} - --// parseGoSrc parses a buffer of Go source, repairing the tree if necessary. --func parseGoSrc(ctx context.Context, fset *token.FileSet, uri span.URI, src []byte, mode source.ParseMode) (res *source.ParsedGoFile) { -- parserMode := parser.AllErrors | parser.ParseComments -- if mode == source.ParseHeader { -- parserMode = parser.ImportsOnly | parser.ParseComments +-// ParseGoSrc parses a buffer of Go source, repairing the tree if necessary. +-// +-// The provided ctx is used only for logging. +-func ParseGoSrc(ctx context.Context, fset *token.FileSet, uri span.URI, src []byte, mode parser.Mode, purgeFuncBodies bool) (res *source.ParsedGoFile, fixes []fixType) { +- if purgeFuncBodies { +- src = goplsastutil.PurgeFuncBodies(src) - } +- ctx, done := event.Start(ctx, "cache.ParseGoSrc", tag.File.Of(uri.Filename())) +- defer done() - -- file, err := parser.ParseFile(fset, uri.Filename(), src, parserMode) +- file, err := parser.ParseFile(fset, uri.Filename(), src, mode) - var parseErr scanner.ErrorList - if err != nil { - // We passed a byte slice, so the only possible error is a parse error. @@ -18463,15 +21635,20 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - tok.SetLinesForContent(src) - } - -- fixed := false +- fixedSrc := false +- fixedAST := false - // If there were parse errors, attempt to fix them up. - if parseErr != nil { - // Fix any badly parsed parts of the AST. -- fixed = fixAST(file, tok, src) +- astFixes := fixAST(file, tok, src) +- fixedAST = len(fixes) > 0 +- if fixedAST { +- fixes = append(fixes, astFixes...) +- } - - for i := 0; i < 10; i++ { - // Fix certain syntax errors that render the file unparseable. -- newSrc := fixSrc(file, tok, src) +- newSrc, srcFix := fixSrc(file, tok, src) - if newSrc == nil { - break - } @@ -18484,14 +21661,30 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - event.Log(ctx, fmt.Sprintf("fixSrc loop - last diff:\n%v", unified), tag.File.Of(tok.Name())) - } - -- newFile, _ := parser.ParseFile(fset, uri.Filename(), newSrc, parserMode) -- if newFile != nil { -- // Maintain the original parseError so we don't try formatting the doctored file. -- file = newFile -- src = newSrc -- tok = fset.File(file.Pos()) +- newFile, newErr := parser.ParseFile(fset, uri.Filename(), newSrc, mode) +- if newFile == nil { +- break // no progress +- } +- +- // Maintain the original parseError so we don't try formatting the +- // doctored file. +- file = newFile +- src = newSrc +- tok = fset.File(file.Pos()) - -- fixed = fixAST(file, tok, src) +- // Only now that we accept the fix do we record the src fix from above. +- fixes = append(fixes, srcFix) +- fixedSrc = true +- +- if newErr == nil { +- break // nothing to fix +- } +- +- // Note that fixedAST is reset after we fix src. +- astFixes = fixAST(file, tok, src) +- fixedAST = len(astFixes) > 0 +- if fixedAST { +- fixes = append(fixes, astFixes...) - } - } - } @@ -18500,12 +21693,13 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - URI: uri, - Mode: mode, - Src: src, -- Fixed: fixed, +- FixedSrc: fixedSrc, +- FixedAST: fixedAST, - File: file, - Tok: tok, - Mapper: protocol.NewMapper(uri, src), - ParseErr: parseErr, -- } +- }, fixes -} - -// fixAST inspects the AST and potentially modifies any *ast.BadStmts so that it can be @@ -18513,22 +21707,26 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g -// -// If fixAST returns true, the resulting AST is considered "fixed", meaning -// positions have been mangled, and type checker errors may not make sense. --func fixAST(n ast.Node, tok *token.File, src []byte) (fixed bool) { +-func fixAST(n ast.Node, tok *token.File, src []byte) (fixes []fixType) { - var err error - walkASTWithParent(n, func(n, parent ast.Node) bool { - switch n := n.(type) { - case *ast.BadStmt: -- if fixed = fixDeferOrGoStmt(n, parent, tok, src); fixed { +- if fixDeferOrGoStmt(n, parent, tok, src) { +- fixes = append(fixes, fixedDeferOrGo) - // Recursively fix in our fixed node. -- _ = fixAST(parent, tok, src) +- moreFixes := fixAST(parent, tok, src) +- fixes = append(fixes, moreFixes...) - } else { - err = fmt.Errorf("unable to parse defer or go from *ast.BadStmt: %v", err) - } - return false - case *ast.BadExpr: -- if fixed = fixArrayType(n, parent, tok, src); fixed { +- if fixArrayType(n, parent, tok, src) { +- fixes = append(fixes, fixedArrayType) - // Recursively fix in our fixed node. -- _ = fixAST(parent, tok, src) +- moreFixes := fixAST(parent, tok, src) +- fixes = append(fixes, moreFixes...) - return false - } - @@ -18538,15 +21736,18 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - // // "i := foo" is init statement, not condition. - // for i := foo - // -- fixInitStmt(n, parent, tok, src) -- +- if fixInitStmt(n, parent, tok, src) { +- fixes = append(fixes, fixedInit) +- } - return false - case *ast.SelectorExpr: - // Fix cases where a keyword prefix results in a phantom "_" selector, e.g.: - // - // foo.var<> // want to complete to "foo.variance" - // -- fixPhantomSelector(n, tok, src) +- if fixPhantomSelector(n, tok, src) { +- fixes = append(fixes, fixedPhantomSelector) +- } - return true - - case *ast.BlockStmt: @@ -18554,7 +21755,9 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - case *ast.SwitchStmt, *ast.TypeSwitchStmt, *ast.SelectStmt: - // Adjust closing curly brace of empty switch/select - // statements so we can complete inside them. -- fixEmptySwitch(n, tok, src) +- if fixEmptySwitch(n, tok, src) { +- fixes = append(fixes, fixedEmptySwitch) +- } - } - - return true @@ -18562,7 +21765,7 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - return true - } - }) -- return fixed +- return fixes -} - -// walkASTWithParent walks the AST rooted at n. The semantics are @@ -18590,9 +21793,26 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - }) -} - +-// TODO(rfindley): revert this intrumentation once we're certain the crash in +-// #59097 is fixed. +-type fixType int +- +-const ( +- noFix fixType = iota +- fixedCurlies +- fixedDanglingSelector +- fixedDeferOrGo +- fixedArrayType +- fixedInit +- fixedPhantomSelector +- fixedEmptySwitch +-) +- -// fixSrc attempts to modify the file's source code to fix certain -// syntax errors that leave the rest of the file unparsed. --func fixSrc(f *ast.File, tf *token.File, src []byte) (newSrc []byte) { +-// +-// fixSrc returns a non-nil result if and only if a fix was applied. +-func fixSrc(f *ast.File, tf *token.File, src []byte) (newSrc []byte, fix fixType) { - walkASTWithParent(f, func(n, parent ast.Node) bool { - if newSrc != nil { - return false @@ -18601,14 +21821,20 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - switch n := n.(type) { - case *ast.BlockStmt: - newSrc = fixMissingCurlies(f, n, parent, tf, src) +- if newSrc != nil { +- fix = fixedCurlies +- } - case *ast.SelectorExpr: - newSrc = fixDanglingSelector(n, tf, src) +- if newSrc != nil { +- fix = fixedDanglingSelector +- } - } - - return newSrc == nil - }) - -- return newSrc +- return newSrc, fix -} - -// fixMissingCurlies adds in curly braces for block statements that @@ -18632,7 +21858,7 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - } - } - -- parentLine := tok.Line(parent.Pos()) +- parentLine := safetoken.Line(tok, parent.Pos()) - - if parentLine >= tok.LineCount() { - // If we are the last line in the file, no need to fix anything. @@ -18727,30 +21953,33 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g -// switch { -// -// } --func fixEmptySwitch(body *ast.BlockStmt, tok *token.File, src []byte) { +-// +-// The resulting bool reports whether any fixing occurred. +-func fixEmptySwitch(body *ast.BlockStmt, tok *token.File, src []byte) bool { - // We only care about empty switch statements. - if len(body.List) > 0 || !body.Rbrace.IsValid() { -- return +- return false - } - - // If the right brace is actually in the source code at the - // specified position, don't mess with it. - braceOffset, err := safetoken.Offset(tok, body.Rbrace) - if err != nil { -- return +- return false - } - if braceOffset < len(src) && src[braceOffset] == '}' { -- return +- return false - } - -- braceLine := tok.Line(body.Rbrace) +- braceLine := safetoken.Line(tok, body.Rbrace) - if braceLine >= tok.LineCount() { - // If we are the last line in the file, no need to fix anything. -- return +- return false - } - - // Move the right brace down one line. - body.Rbrace = tok.LineStart(braceLine + 1) +- return true -} - -// fixDanglingSelector inserts real "_" selector expressions in place @@ -18801,9 +22030,11 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g -// yields a "_" selector instead of "var" since "var" is a keyword. -// -// TODO(rfindley): should this constitute an ast 'fix'? --func fixPhantomSelector(sel *ast.SelectorExpr, tf *token.File, src []byte) { +-// +-// The resulting bool reports whether any fixing occurred. +-func fixPhantomSelector(sel *ast.SelectorExpr, tf *token.File, src []byte) bool { - if !isPhantomUnderscore(sel.Sel, tf, src) { -- return +- return false - } - - // Only consider selectors directly abutting the selector ".". This @@ -18813,15 +22044,15 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - // var bar = 123 - // - if sel.Sel.Pos() != sel.X.End()+1 { -- return +- return false - } - - maybeKeyword := readKeyword(sel.Sel.Pos(), tf, src) - if maybeKeyword == "" { -- return +- return false - } - -- replaceNode(sel, sel.Sel, &ast.Ident{ +- return replaceNode(sel, sel.Sel, &ast.Ident{ - Name: maybeKeyword, - NamePos: sel.Sel.Pos(), - }) @@ -18850,21 +22081,21 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g -// parser is looking for the conditional expression. However, "i := 0" -// are not valid expressions, so we get a BadExpr. -// --// fixInitStmt returns valid AST for the original source. --func fixInitStmt(bad *ast.BadExpr, parent ast.Node, tok *token.File, src []byte) { +-// The resulting bool reports whether any fixing occurred. +-func fixInitStmt(bad *ast.BadExpr, parent ast.Node, tok *token.File, src []byte) bool { - if !bad.Pos().IsValid() || !bad.End().IsValid() { -- return +- return false - } - - // Try to extract a statement from the BadExpr. - start, end, err := safetoken.Offsets(tok, bad.Pos(), bad.End()-1) - if err != nil { -- return +- return false - } - stmtBytes := src[start : end+1] - stmt, err := parseStmt(bad.Pos(), stmtBytes) - if err != nil { -- return +- return false - } - - // If the parent statement doesn't already have an "init" statement, @@ -18873,29 +22104,33 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - switch p := parent.(type) { - case *ast.IfStmt: - if p.Init != nil { -- return +- return false - } - p.Init = stmt - p.Cond = &ast.Ident{ - Name: "_", - NamePos: stmt.End(), - } +- return true - case *ast.ForStmt: - if p.Init != nil { -- return +- return false - } - p.Init = stmt - p.Cond = &ast.Ident{ - Name: "_", - NamePos: stmt.End(), - } +- return true - case *ast.SwitchStmt: - if p.Init != nil { -- return +- return false - } - p.Init = stmt - p.Tag = nil +- return true - } +- return false -} - -// readKeyword reads the keyword starting at pos, if any. @@ -19073,7 +22308,7 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - // the period is likely a dangling selector and needs a phantom - // "_". Likewise if the current token is on a different line than - // the period, the period is likely a dangling selector. -- if lastToken == token.PERIOD && (tkn == token.RBRACE || tok.Line(to) > tok.Line(last)) { +- if lastToken == token.PERIOD && (tkn == token.RBRACE || safetoken.Line(tok, to) > safetoken.Line(tok, last)) { - // Insert phantom "_" selector after the dangling ".". - phantomSelectors = append(phantomSelectors, last+1) - // If we aren't in a block then end the expression after the ".". @@ -19288,41 +22523,10 @@ diff -urN a/gopls/internal/lsp/cache/parse.go b/gopls/internal/lsp/cache/parse.g - - return false -} -diff -urN a/gopls/internal/lsp/cache/parsemode_go116.go b/gopls/internal/lsp/cache/parsemode_go116.go ---- a/gopls/internal/lsp/cache/parsemode_go116.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/parsemode_go116.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build !go1.17 --// +build !go1.17 -- --package cache -- --// The parser.SkipObjectResolution mode flag is not supported before Go 1.17. --const skipObjectResolution = 0 -diff -urN a/gopls/internal/lsp/cache/parsemode_go117.go b/gopls/internal/lsp/cache/parsemode_go117.go ---- a/gopls/internal/lsp/cache/parsemode_go117.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/parsemode_go117.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build go1.17 --// +build go1.17 -- --package cache -- --import "go/parser" -- --const skipObjectResolution = parser.SkipObjectResolution diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go --- a/gopls/internal/lsp/cache/pkg.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/pkg.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,165 +0,0 @@ +@@ -1,177 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -19336,11 +22540,12 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go - "go/scanner" - "go/token" - "go/types" +- "sync" - - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/source/methodsets" +- "golang.org/x/tools/gopls/internal/lsp/source/xrefs" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/memoize" -) - -// Convenient local aliases for typed strings. @@ -19351,11 +22556,10 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go - ImportPath = source.ImportPath -) - --// A Package is the union of snapshot-local information (Metadata) and shared --// type-checking information (a syntaxPackage). +-// A Package is the union of package metadata and type checking results. -// -// TODO(rfindley): for now, we do not persist the post-processing of --// loadDiagnostics, because the value of the snapshot.packages map is just the +-// loadDiagnostics, because the value of the snapshot.packages map is just the -// package handle. Fix this. -type Package struct { - m *source.Metadata @@ -19365,8 +22569,7 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go -// syntaxPackage contains parse trees and type information for a package. -type syntaxPackage struct { - // -- identifiers -- -- id PackageID -- mode source.ParseMode +- id PackageID - - // -- outputs -- - fset *token.FileSet // for now, same as the snapshot's FileSet @@ -19377,11 +22580,28 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go - typeErrors []types.Error - types *types.Package - typesInfo *types.Info -- importMap map[string]*types.Package // keys are PackagePaths -- hasFixedFiles bool // if true, AST was sufficiently mangled that we should hide type errors -- analyses memoize.Store // maps analyzer.Name to Promise[actionResult] -- xrefs []byte -- methodsets *methodsets.Index +- importMap map[PackagePath]*types.Package +- hasFixedFiles bool // if true, AST was sufficiently mangled that we should hide type errors +- +- xrefsOnce sync.Once +- _xrefs []byte // only used by the xrefs method +- +- methodsetsOnce sync.Once +- _methodsets *methodsets.Index // only used by the methodsets method +-} +- +-func (p *syntaxPackage) xrefs() []byte { +- p.xrefsOnce.Do(func() { +- p._xrefs = xrefs.Index(p.compiledGoFiles, p.types, p.typesInfo) +- }) +- return p._xrefs +-} +- +-func (p *syntaxPackage) methodsets() *methodsets.Index { +- p.methodsetsOnce.Do(func() { +- p._methodsets = methodsets.NewIndex(p.fset, p.types) +- }) +- return p._methodsets -} - -func (p *Package) String() string { return string(p.m.ID) } @@ -19398,8 +22618,11 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go -type ( - fileLoadScope span.URI // load packages containing a file (including command-line-arguments) - packageLoadScope string // load a specific package (the value is its PackageID) -- moduleLoadScope string // load packages in a specific module -- viewLoadScope span.URI // load the workspace +- moduleLoadScope struct { +- dir string // dir containing the go.mod file +- modulePath string // parsed module path +- } +- viewLoadScope span.URI // load the workspace -) - -// Implement the loadScope interface. @@ -19408,10 +22631,6 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go -func (moduleLoadScope) aScope() {} -func (viewLoadScope) aScope() {} - --func (p *Package) ParseMode() source.ParseMode { -- return p.pkg.mode --} -- -func (p *Package) CompiledGoFiles() []*source.ParsedGoFile { - return p.pkg.compiledGoFiles -} @@ -19459,18 +22678,15 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go -// dependencies of p, or if no symbols from that package were -// referenced during the type-checking of p. -func (p *Package) DependencyTypes(path source.PackagePath) *types.Package { -- if path == p.m.PkgPath { -- return p.pkg.types -- } -- return p.pkg.importMap[string(path)] +- return p.pkg.importMap[path] -} - --func (p *Package) HasParseErrors() bool { -- return len(p.pkg.parseErrors) != 0 +-func (p *Package) GetParseErrors() []scanner.ErrorList { +- return p.pkg.parseErrors -} - --func (p *Package) HasTypeErrors() bool { -- return len(p.pkg.typeErrors) != 0 +-func (p *Package) GetTypeErrors() []types.Error { +- return p.pkg.typeErrors -} - -func (p *Package) DiagnosticsForFile(ctx context.Context, s source.Snapshot, uri span.URI) ([]*source.Diagnostic, error) { @@ -19491,7 +22707,7 @@ diff -urN a/gopls/internal/lsp/cache/pkg.go b/gopls/internal/lsp/cache/pkg.go diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/session.go --- a/gopls/internal/lsp/cache/session.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/session.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,730 +0,0 @@ +@@ -1,762 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -19506,13 +22722,15 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - "sync" - "sync/atomic" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/govulncheck" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/source/typerefs" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/imports" +- "golang.org/x/tools/internal/memoize" - "golang.org/x/tools/internal/persistent" - "golang.org/x/tools/internal/xcontext" -) @@ -19532,6 +22750,8 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - views []*View - viewMap map[span.URI]*View // map of URI->best view - +- parseCache *parseCache +- - *overlayFS -} - @@ -19539,6 +22759,11 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi -func (s *Session) ID() string { return s.id } -func (s *Session) String() string { return s.id } - +-// GoCommandRunner returns the gocommand Runner for this session. +-func (s *Session) GoCommandRunner() *gocommand.Runner { +- return s.gocmdRunner +-} +- -// Options returns a copy of the SessionOptions for this session. -func (s *Session) Options() *source.Options { - s.optionsMu.Lock() @@ -19564,6 +22789,7 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - for _, view := range views { - view.shutdown() - } +- s.parseCache.stop() - event.Log(ctx, "Shutdown session", KeyShutdownSession.Of(s)) -} - @@ -19597,16 +22823,18 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - -// TODO(rfindley): clarify that createView can never be cancelled (with the -// possible exception of server shutdown). +-// On success, the caller becomes responsible for calling the release function once. -func (s *Session) createView(ctx context.Context, name string, folder span.URI, options *source.Options, seqID uint64) (*View, *snapshot, func(), error) { - index := atomic.AddInt64(&viewIndex, 1) - - // Get immutable workspace information. - info, err := s.getWorkspaceInformation(ctx, folder, options) - if err != nil { -- return nil, nil, func() {}, err +- return nil, nil, nil, err - } - -- wsModFiles, wsModFilesErr := computeWorkspaceModFiles(ctx, info.gomod, info.effectiveGOWORK(), info.effectiveGO111MODULE(), s) +- gowork, _ := info.GOWORK() +- wsModFiles, wsModFilesErr := computeWorkspaceModFiles(ctx, info.gomod, gowork, info.effectiveGO111MODULE(), s) - - // We want a true background context and not a detached context here - // the spans need to be unrelated and no tag values should pollute it. @@ -19624,6 +22852,7 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - folder: folder, - moduleUpgrades: map[span.URI]map[string]string{}, - vulns: map[span.URI]*govulncheck.Result{}, +- parseCache: s.parseCache, - fs: s.overlayFS, - workspaceInformation: info, - } @@ -19651,23 +22880,22 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - backgroundCtx: backgroundCtx, - cancel: cancel, - store: s.cache.store, -- packages: persistent.NewMap(packageIDLessInterface), +- packages: new(persistent.Map[PackageID, *packageHandle]), - meta: new(metadataGraph), - files: newFilesMap(), -- parseCache: new(parseCache), -- activePackages: persistent.NewMap(packageIDLessInterface), -- symbolizeHandles: persistent.NewMap(uriLessInterface), -- analyses: persistent.NewMap(analysisKeyLessInterface), +- activePackages: new(persistent.Map[PackageID, *Package]), +- symbolizeHandles: new(persistent.Map[span.URI, *memoize.Promise]), - workspacePackages: make(map[PackageID]PackagePath), -- unloadableFiles: make(map[span.URI]struct{}), -- parseModHandles: persistent.NewMap(uriLessInterface), -- parseWorkHandles: persistent.NewMap(uriLessInterface), -- modTidyHandles: persistent.NewMap(uriLessInterface), -- modVulnHandles: persistent.NewMap(uriLessInterface), -- modWhyHandles: persistent.NewMap(uriLessInterface), -- knownSubdirs: newKnownDirsSet(), +- unloadableFiles: new(persistent.Set[span.URI]), +- parseModHandles: new(persistent.Map[span.URI, *memoize.Promise]), +- parseWorkHandles: new(persistent.Map[span.URI, *memoize.Promise]), +- modTidyHandles: new(persistent.Map[span.URI, *memoize.Promise]), +- modVulnHandles: new(persistent.Map[span.URI, *memoize.Promise]), +- modWhyHandles: new(persistent.Map[span.URI, *memoize.Promise]), +- knownSubdirs: new(persistent.Set[span.URI]), - workspaceModFiles: wsModFiles, - workspaceModFilesErr: wsModFilesErr, +- pkgIndex: typerefs.NewPackageIndex(), - } - // Save one reference in the view. - v.releaseSnapshot = v.snapshot.Acquire() @@ -19691,8 +22919,8 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - return v, snapshot, snapshot.Acquire(), nil -} - --// View returns a view with a matching name, if the session has one. --func (s *Session) View(name string) *View { +-// ViewByName returns a view with a matching name, if the session has one. +-func (s *Session) ViewByName(name string) *View { - s.viewMu.Lock() - defer s.viewMu.Unlock() - for _, view := range s.views { @@ -19703,6 +22931,18 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - return nil -} - +-// View returns the view with a matching id, if present. +-func (s *Session) View(id string) (*View, error) { +- s.viewMu.Lock() +- defer s.viewMu.Unlock() +- for _, view := range s.views { +- if view.ID() == id { +- return view, nil +- } +- } +- return nil, fmt.Errorf("no view with ID %q", id) +-} +- -// ViewOf returns a view corresponding to the given URI. -// If the file is not already associated with a view, pick one using some heuristics. -func (s *Session) ViewOf(uri span.URI) (*View, error) { @@ -19800,9 +23040,7 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - return nil, fmt.Errorf("view %q not found", view.id) - } - -- v, _, release, err := s.createView(ctx, view.name, view.folder, options, seqID) -- release() -- +- v, snapshot, release, err := s.createView(ctx, view.name, view.folder, options, seqID) - if err != nil { - // we have dropped the old view, but could not create the new one - // this should not happen and is very bad, but we still need to clean @@ -19810,6 +23048,18 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - s.views = removeElement(s.views, i) - return nil, err - } +- defer release() +- +- // The new snapshot has lost the history of the previous view. As a result, +- // it may not see open files that aren't in its build configuration (as it +- // would have done via didOpen notifications). This can lead to inconsistent +- // behavior when configuration is changed mid-session. +- // +- // Ensure the new snapshot observes all open files. +- for _, o := range v.fs.Overlays() { +- _, _ = snapshot.ReadFile(ctx, o.URI()) +- } +- - // substitute the new view into the array where the old view was - s.views[i] = v - return v, nil @@ -19983,11 +23233,11 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - if _, ok := views[view]; !ok { - views[view] = make(map[span.URI]*fileChange) - } -- fh, err := s.GetFile(ctx, c.URI) +- fh, err := s.ReadFile(ctx, c.URI) - if err != nil { - return nil, nil, err - } -- content, err := fh.Read() +- content, err := fh.Content() - if err != nil { - // Ignore the error: the file may be deleted. - content = nil @@ -20061,20 +23311,17 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - for _, c := range changes { - if !knownDirs.Contains(c.URI) { - result = append(result, c) -- continue -- } -- affectedFiles := knownFilesInDir(ctx, snapshots, c.URI) -- var fileChanges []source.FileModification -- for uri := range affectedFiles { -- fileChanges = append(fileChanges, source.FileModification{ -- URI: uri, -- Action: c.Action, -- LanguageID: "", -- OnDisk: c.OnDisk, -- // changes to directories cannot include text or versions -- }) +- } else { +- for uri := range knownFilesInDir(ctx, snapshots, c.URI) { +- result = append(result, source.FileModification{ +- URI: uri, +- Action: c.Action, +- LanguageID: "", +- OnDisk: c.OnDisk, +- // changes to directories cannot include text or versions +- }) +- } - } -- result = append(result, fileChanges...) - } - return result -} @@ -20082,15 +23329,15 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi -// knownDirectories returns all of the directories known to the given -// snapshots, including workspace directories and their subdirectories. -// It is responsibility of the caller to destroy the returned set. --func knownDirectories(ctx context.Context, snapshots []*snapshot) knownDirsSet { -- result := newKnownDirsSet() +-func knownDirectories(ctx context.Context, snapshots []*snapshot) *persistent.Set[span.URI] { +- result := new(persistent.Set[span.URI]) - for _, snapshot := range snapshots { - dirs := snapshot.dirs(ctx) - for _, dir := range dirs { -- result.Insert(dir) +- result.Add(dir) - } - knownSubdirs := snapshot.getKnownSubdirs(dirs) -- result.SetAll(knownSubdirs) +- result.AddAll(knownSubdirs) - knownSubdirs.Destroy() - } - return result @@ -20178,11 +23425,11 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - } - sameContentOnDisk = true - default: -- fh, err := fs.delegate.GetFile(ctx, c.URI) +- fh, err := fs.delegate.ReadFile(ctx, c.URI) - if err != nil { - return err - } -- _, readErr := fh.Read() +- _, readErr := fh.Content() - sameContentOnDisk = (readErr == nil && fh.FileIdentity().Hash == hash) - } - o = &Overlay{ @@ -20203,9 +23450,10 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi - return nil -} - --// FileWatchingGlobPatterns returns glob patterns to watch every directory --// known by the view. For views within a module, this is the module root, --// any directory in the module root, and any replace targets. +-// FileWatchingGlobPatterns returns a new set of glob patterns to +-// watch every directory known by the view. For views within a module, +-// this is the module root, any directory in the module root, and any +-// replace targets. -func (s *Session) FileWatchingGlobPatterns(ctx context.Context) map[string]struct{} { - s.viewMu.Lock() - defer s.viewMu.Unlock() @@ -20225,7 +23473,7 @@ diff -urN a/gopls/internal/lsp/cache/session.go b/gopls/internal/lsp/cache/sessi diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snapshot.go --- a/gopls/internal/lsp/cache/snapshot.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/snapshot.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,2214 +0,0 @@ +@@ -1,2569 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -20238,10 +23486,10 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - "errors" - "fmt" - "go/ast" +- "go/build/constraint" - "go/token" - "go/types" - "io" -- "io/ioutil" - "log" - "os" - "path/filepath" @@ -20257,12 +23505,15 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - "golang.org/x/sync/errgroup" - "golang.org/x/tools/go/packages" - "golang.org/x/tools/go/types/objectpath" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/filecache" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/source/methodsets" +- "golang.org/x/tools/gopls/internal/lsp/source/typerefs" - "golang.org/x/tools/gopls/internal/lsp/source/xrefs" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/tag" - "golang.org/x/tools/internal/gocommand" @@ -20300,14 +23551,17 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // view.initializationSema. - initialized bool - // initializedErr holds the last error resulting from initialization. If -- // initialization fails, we only retry when the the workspace modules change, +- // initialization fails, we only retry when the workspace modules change, - // to avoid too many go/packages calls. - initializedErr *source.CriticalError - - // mu guards all of the maps in the snapshot, as well as the builtin URI. - mu sync.Mutex - -- // builtin pins the AST and package for builtin.go in memory. +- // builtin is the location of builtin.go in GOROOT. +- // +- // TODO(rfindley): would it make more sense to eagerly parse builtin, and +- // instead store a *ParsedGoFile here? - builtin span.URI - - // meta holds loaded metadata. @@ -20321,12 +23575,9 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // It may invalidated when a file's content changes. - files filesMap - -- // parseCache holds an LRU cache of recently parsed files. -- parseCache *parseCache -- - // symbolizeHandles maps each file URI to a handle for the future - // result of computing the symbols declared in that file. -- symbolizeHandles *persistent.Map // from span.URI to *memoize.Promise[symbolizeResult] +- symbolizeHandles *persistent.Map[span.URI, *memoize.Promise] // *memoize.Promise[symbolizeResult] - - // packages maps a packageKey to a *packageHandle. - // It may be invalidated when a file's content changes. @@ -20335,21 +23586,16 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // - packages.Get(id).meta == meta.metadata[id] for all ids - // - if a package is in packages, then all of its dependencies should also - // be in packages, unless there is a missing import -- packages *persistent.Map // from packageID to *packageHandle +- packages *persistent.Map[PackageID, *packageHandle] - - // activePackages maps a package ID to a memoized active package, or nil if - // the package is known not to be open. - // - // IDs not contained in the map are not known to be open or not open. -- activePackages *persistent.Map // from packageID to *Package -- -- // analyses maps an analysisKey (which identifies a package -- // and a set of analyzers) to the handle for the future result -- // of loading the package and analyzing it. -- analyses *persistent.Map // from analysisKey to analysisPromise +- activePackages *persistent.Map[PackageID, *Package] - - // workspacePackages contains the workspace's packages, which are loaded -- // when the view is created. +- // when the view is created. It contains no intermediate test variants. - workspacePackages map[PackageID]PackagePath - - // shouldLoad tracks packages that need to be reloaded, mapping a PackageID @@ -20360,30 +23606,30 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - shouldLoad map[PackageID][]PackagePath - - // unloadableFiles keeps track of files that we've failed to load. -- unloadableFiles map[span.URI]struct{} +- unloadableFiles *persistent.Set[span.URI] - - // TODO(rfindley): rename the handles below to "promises". A promise is - // different from a handle (we mutate the package handle.) - - // parseModHandles keeps track of any parseModHandles for the snapshot. - // The handles need not refer to only the view's go.mod file. -- parseModHandles *persistent.Map // from span.URI to *memoize.Promise[parseModResult] +- parseModHandles *persistent.Map[span.URI, *memoize.Promise] // *memoize.Promise[parseModResult] - - // parseWorkHandles keeps track of any parseWorkHandles for the snapshot. - // The handles need not refer to only the view's go.work file. -- parseWorkHandles *persistent.Map // from span.URI to *memoize.Promise[parseWorkResult] +- parseWorkHandles *persistent.Map[span.URI, *memoize.Promise] // *memoize.Promise[parseWorkResult] - - // Preserve go.mod-related handles to avoid garbage-collecting the results - // of various calls to the go command. The handles need not refer to only - // the view's go.mod file. -- modTidyHandles *persistent.Map // from span.URI to *memoize.Promise[modTidyResult] -- modWhyHandles *persistent.Map // from span.URI to *memoize.Promise[modWhyResult] -- modVulnHandles *persistent.Map // from span.URI to *memoize.Promise[modVulnResult] -- -- // knownSubdirs is the set of subdirectories in the workspace, used to -- // create glob patterns for file watching. -- knownSubdirs knownDirsSet -- knownSubdirsPatternCache string +- modTidyHandles *persistent.Map[span.URI, *memoize.Promise] // *memoize.Promise[modTidyResult] +- modWhyHandles *persistent.Map[span.URI, *memoize.Promise] // *memoize.Promise[modWhyResult] +- modVulnHandles *persistent.Map[span.URI, *memoize.Promise] // *memoize.Promise[modVulnResult] +- +- // knownSubdirs is the set of subdirectory URIs in the workspace, +- // used to create glob patterns for file watching. +- knownSubdirs *persistent.Set[span.URI] +- knownSubdirsCache map[string]struct{} // memo of knownSubdirs as a set of filenames - // unprocessedSubdirChanges are any changes that might affect the set of - // subdirectories in the workspace. They are not reflected to knownSubdirs - // during the snapshot cloning step as it can slow down cloning. @@ -20397,6 +23643,34 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // This set is immutable inside the snapshot, and therefore is not guarded by mu. - workspaceModFiles map[span.URI]struct{} - workspaceModFilesErr error // error encountered computing workspaceModFiles +- +- // importGraph holds a shared import graph to use for type-checking. Adding +- // more packages to this import graph can speed up type checking, at the +- // expense of in-use memory. +- // +- // See getImportGraph for additional documentation. +- importGraphDone chan struct{} // closed when importGraph is set; may be nil +- importGraph *importGraph // copied from preceding snapshot and re-evaluated +- +- // pkgIndex is an index of package IDs, for efficient storage of typerefs. +- pkgIndex *typerefs.PackageIndex +- +- // Only compute module prefixes once, as they are used with high frequency to +- // detect ignored files. +- ignoreFilterOnce sync.Once +- ignoreFilter *ignoreFilter +- +- // typeCheckMu guards type checking. +- // +- // Only one type checking pass should be running at a given time, for two reasons: +- // 1. type checking batches are optimized to use all available processors. +- // Generally speaking, running two type checking batches serially is about +- // as fast as running them in parallel. +- // 2. type checking produces cached artifacts that may be re-used by the +- // next type-checking batch: the shared import graph and the set of +- // active packages. Running type checking batches in parallel after an +- // invalidation can cause redundant calculation of this shared state. +- typeCheckMu sync.Mutex -} - -var globalSnapshotID uint64 @@ -20441,7 +23715,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -// The destroyedBy argument is used for debugging. -// -// v.snapshotMu must be held while calling this function, in order to preserve --// the invariants described by the the docstring for v.snapshot. +-// the invariants described by the docstring for v.snapshot. -func (v *View) destroy(s *snapshot, destroyedBy string) { - v.snapshotWG.Add(1) - go func() { @@ -20463,7 +23737,6 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - - s.packages.Destroy() - s.activePackages.Destroy() -- s.analyses.Destroy() - s.files.Destroy() - s.knownSubdirs.Destroy() - s.symbolizeHandles.Destroy() @@ -20472,6 +23745,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - s.modTidyHandles.Destroy() - s.modVulnHandles.Destroy() - s.modWhyHandles.Destroy() +- s.unloadableFiles.Destroy() -} - -func (s *snapshot) SequenceID() uint64 { @@ -20486,6 +23760,14 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return s.view -} - +-func (s *snapshot) FileKind(h source.FileHandle) source.FileKind { +- return s.view.FileKind(h) +-} +- +-func (s *snapshot) Options() *source.Options { +- return s.view.Options() // temporarily return view options. +-} +- -func (s *snapshot) BackgroundContext() context.Context { - return s.backgroundCtx -} @@ -20499,7 +23781,8 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -} - -func (s *snapshot) WorkFile() span.URI { -- return s.view.effectiveGOWORK() +- gowork, _ := s.view.GOWORK() +- return gowork -} - -func (s *snapshot) Templates() map[span.URI]source.FileHandle { @@ -20515,53 +23798,25 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return tmpls -} - --func (s *snapshot) ValidBuildConfiguration() bool { +-func (s *snapshot) validBuildConfiguration() bool { - // Since we only really understand the `go` command, if the user has a - // different GOPACKAGESDRIVER, assume that their configuration is valid. - if s.view.hasGopackagesDriver { - return true - } +- - // Check if the user is working within a module or if we have found - // multiple modules in the workspace. - if len(s.workspaceModFiles) > 0 { - return true - } -- // The user may have a multiple directories in their GOPATH. -- // Check if the workspace is within any of them. -- // TODO(rfindley): this should probably be subject to "if GO111MODULES = off {...}". -- for _, gp := range filepath.SplitList(s.view.gopath) { -- if source.InDir(filepath.Join(gp, "src"), s.view.folder.Filename()) { -- return true -- } -- } -- return false --} - --// moduleMode reports whether the current snapshot uses Go modules. --// --// From https://go.dev/ref/mod, module mode is active if either of the --// following hold: --// - GO111MODULE=on --// - GO111MODULE=auto and we are inside a module or have a GOWORK value. --// --// Additionally, this method returns false if GOPACKAGESDRIVER is set. --// --// TODO(rfindley): use this more widely. --func (s *snapshot) moduleMode() bool { -- // Since we only really understand the `go` command, if the user has a -- // different GOPACKAGESDRIVER, assume that their configuration is valid. -- if s.view.hasGopackagesDriver { -- return false -- } -- -- switch s.view.effectiveGO111MODULE() { -- case on: +- // TODO(rfindley): this should probably be subject to "if GO111MODULES = off {...}". +- if s.view.inGOPATH { - return true -- case off: -- return false -- default: -- return len(s.workspaceModFiles) > 0 || s.view.gowork != "" - } +- +- return false -} - -// workspaceMode describes the way in which the snapshot's workspace should @@ -20573,7 +23828,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - - // If the view has an invalid configuration, don't build the workspace - // module. -- validBuildConfiguration := s.ValidBuildConfiguration() +- validBuildConfiguration := s.validBuildConfiguration() - if !validBuildConfiguration { - return mode - } @@ -20685,11 +23940,11 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return false, nil, nil, nil - } - var modBytes, sumBytes []byte -- modBytes, err = ioutil.ReadFile(tmpURI.Filename()) +- modBytes, err = os.ReadFile(tmpURI.Filename()) - if err != nil && !os.IsNotExist(err) { - return false, nil, nil, err - } -- sumBytes, err = ioutil.ReadFile(strings.TrimSuffix(tmpURI.Filename(), ".mod") + ".sum") +- sumBytes, err = os.ReadFile(strings.TrimSuffix(tmpURI.Filename(), ".mod") + ".sum") - if err != nil && !os.IsNotExist(err) { - return false, nil, nil, err - } @@ -20750,7 +24005,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // the main (workspace) module. Otherwise, we should use the module for - // the passed-in working dir. - if mode == source.LoadWorkspace { -- if s.view.effectiveGOWORK() == "" && s.view.gomod != "" { +- if gowork, _ := s.view.GOWORK(); gowork == "" && s.view.gomod != "" { - modURI = s.view.gomod - } - } else { @@ -20759,11 +24014,11 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - - var modContent []byte - if modURI != "" { -- modFH, err := s.GetFile(ctx, modURI) +- modFH, err := s.ReadFile(ctx, modURI) - if err != nil { - return "", nil, cleanup, err - } -- modContent, err = modFH.Read() +- modContent, err = modFH.Content() - if err != nil { - return "", nil, cleanup, err - } @@ -20816,7 +24071,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - if modURI == "" { - return "", nil, cleanup, fmt.Errorf("no go.mod file found in %s", inv.WorkingDir) - } -- modFH, err := s.GetFile(ctx, modURI) +- modFH, err := s.ReadFile(ctx, modURI) - if err != nil { - return "", nil, cleanup, err - } @@ -20833,24 +24088,26 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -} - -func (s *snapshot) buildOverlay() map[string][]byte { -- s.mu.Lock() -- defer s.mu.Unlock() -- - overlays := make(map[string][]byte) -- s.files.Range(func(uri span.URI, fh source.FileHandle) { -- overlay, ok := fh.(*Overlay) -- if !ok { -- return -- } +- for _, overlay := range s.overlays() { - if overlay.saved { -- return +- continue - } -- // TODO(rstambler): Make sure not to send overlays outside of the current view. -- overlays[uri.Filename()] = overlay.content -- }) +- // TODO(rfindley): previously, there was a todo here to make sure we don't +- // send overlays outside of the current view. IMO we should instead make +- // sure this doesn't matter. +- overlays[overlay.URI().Filename()] = overlay.content +- } - return overlays -} - +-func (s *snapshot) overlays() []*Overlay { +- s.mu.Lock() +- defer s.mu.Unlock() +- +- return s.files.overlays() +-} +- -// Package data kinds, identifying various package data that may be stored in -// the file cache. -const ( @@ -20858,37 +24115,59 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - methodSetsKind = "methodsets" - exportDataKind = "export" - diagnosticsKind = "diagnostics" +- typerefsKind = "typerefs" -) - -func (s *snapshot) PackageDiagnostics(ctx context.Context, ids ...PackageID) (map[span.URI][]*source.Diagnostic, error) { -- // TODO(rfindley): opt: avoid unnecessary encode->decode after type-checking. -- data, err := s.getPackageData(ctx, diagnosticsKind, ids, func(p *syntaxPackage) []byte { -- return encodeDiagnostics(p.diagnostics) -- }) +- ctx, done := event.Start(ctx, "cache.snapshot.PackageDiagnostics") +- defer done() +- +- var mu sync.Mutex - perFile := make(map[span.URI][]*source.Diagnostic) -- for _, data := range data { -- if data != nil { -- for _, diag := range data.m.Diagnostics { -- perFile[diag.URI] = append(perFile[diag.URI], diag) -- } -- diags := decodeDiagnostics(data.data) -- for _, diag := range diags { -- perFile[diag.URI] = append(perFile[diag.URI], diag) -- } +- collect := func(diags []*source.Diagnostic) { +- mu.Lock() +- defer mu.Unlock() +- for _, diag := range diags { +- perFile[diag.URI] = append(perFile[diag.URI], diag) +- } +- } +- pre := func(i int, ph *packageHandle) bool { +- data, err := filecache.Get(diagnosticsKind, ph.key) +- if err == nil { // hit +- collect(ph.m.Diagnostics) +- collect(decodeDiagnostics(data)) +- return false +- } else if err != filecache.ErrNotFound { +- event.Error(ctx, "reading diagnostics from filecache", err) - } +- return true +- } +- post := func(_ int, pkg *Package) { +- collect(pkg.m.Diagnostics) +- collect(pkg.pkg.diagnostics) - } -- return perFile, err +- return perFile, s.forEachPackage(ctx, ids, pre, post) -} - -func (s *snapshot) References(ctx context.Context, ids ...PackageID) ([]source.XrefIndex, error) { -- data, err := s.getPackageData(ctx, xrefsKind, ids, func(p *syntaxPackage) []byte { return p.xrefs }) +- ctx, done := event.Start(ctx, "cache.snapshot.References") +- defer done() +- - indexes := make([]source.XrefIndex, len(ids)) -- for i, data := range data { -- if data != nil { -- indexes[i] = XrefIndex{m: data.m, data: data.data} +- pre := func(i int, ph *packageHandle) bool { +- data, err := filecache.Get(xrefsKind, ph.key) +- if err == nil { // hit +- indexes[i] = XrefIndex{m: ph.m, data: data} +- return false +- } else if err != filecache.ErrNotFound { +- event.Error(ctx, "reading xrefs from filecache", err) - } +- return true +- } +- post := func(i int, pkg *Package) { +- indexes[i] = XrefIndex{m: pkg.m, data: pkg.pkg.xrefs()} - } -- return indexes, err +- return indexes, s.forEachPackage(ctx, ids, pre, post) -} - -// An XrefIndex is a helper for looking up a package in a given package. @@ -20902,24 +24181,39 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -} - -func (s *snapshot) MethodSets(ctx context.Context, ids ...PackageID) ([]*methodsets.Index, error) { -- // TODO(rfindley): opt: avoid unnecessary encode->decode after type-checking. -- data, err := s.getPackageData(ctx, methodSetsKind, ids, func(p *syntaxPackage) []byte { -- return p.methodsets.Encode() -- }) +- ctx, done := event.Start(ctx, "cache.snapshot.MethodSets") +- defer done() +- - indexes := make([]*methodsets.Index, len(ids)) -- for i, data := range data { -- if data != nil { -- indexes[i] = methodsets.Decode(data.data) -- } else if ids[i] == "unsafe" { -- indexes[i] = &methodsets.Index{} -- } else { -- panic(fmt.Sprintf("nil data for %s", ids[i])) +- pre := func(i int, ph *packageHandle) bool { +- data, err := filecache.Get(methodSetsKind, ph.key) +- if err == nil { // hit +- indexes[i] = methodsets.Decode(data) +- return false +- } else if err != filecache.ErrNotFound { +- event.Error(ctx, "reading methodsets from filecache", err) - } +- return true +- } +- post := func(i int, pkg *Package) { +- indexes[i] = pkg.pkg.methodsets() - } -- return indexes, err +- return indexes, s.forEachPackage(ctx, ids, pre, post) -} - -func (s *snapshot) MetadataForFile(ctx context.Context, uri span.URI) ([]*source.Metadata, error) { +- if s.view.ViewType() == AdHocView { +- // As described in golang/go#57209, in ad-hoc workspaces (where we load ./ +- // rather than ./...), preempting the directory load with file loads can +- // lead to an inconsistent outcome, where certain files are loaded with +- // command-line-arguments packages and others are loaded only in the ad-hoc +- // package. Therefore, ensure that the workspace is loaded before doing any +- // file loads. +- if err := s.awaitLoaded(ctx); err != nil { +- return nil, err +- } +- } +- - s.mu.Lock() - - // Start with the set of package associations derived from the last load. @@ -20933,7 +24227,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - } - - // Check if uri is known to be unloadable. -- _, unloadable := s.unloadableFiles[uri] +- unloadable := s.unloadableFiles.Contains(uri) - - s.mu.Unlock() - @@ -20945,12 +24239,22 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - scope := fileLoadScope(uri) - err := s.load(ctx, false, scope) - -- // Guard against failed loads due to context cancellation. - // - // Return the context error here as the current operation is no longer - // valid. -- if ctxErr := ctx.Err(); ctxErr != nil { -- return nil, ctxErr +- if err != nil { +- // Guard against failed loads due to context cancellation. We don't want +- // to mark loads as completed if they failed due to context cancellation. +- if ctx.Err() != nil { +- return nil, ctx.Err() +- } +- +- // Don't return an error here, as we may still return stale IDs. +- // Furthermore, the result of MetadataForFile should be consistent upon +- // subsequent calls, even if the file is marked as unloadable. +- if !errors.Is(err, errNoPackages) { +- event.Error(ctx, "MetadataForFile", err) +- } - } - - // We must clear scopes after loading. @@ -20959,13 +24263,6 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // packages as loaded. We could do this from snapshot.load and avoid - // raciness. - s.clearShouldLoad(scope) -- -- // Don't return an error here, as we may still return stale IDs. -- // Furthermore, the result of MetadataForFile should be consistent upon -- // subsequent calls, even if the file is marked as unloadable. -- if err != nil && !errors.Is(err, errNoPackages) { -- event.Error(ctx, "MetadataForFile", err) -- } - } - - // Retrieve the metadata. @@ -20983,17 +24280,27 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // so if we get here and still have - // no IDs, uri is unloadable. - if !unloadable && len(ids) == 0 { -- s.unloadableFiles[uri] = struct{}{} +- s.unloadableFiles.Add(uri) - } - -- // Sort packages "narrowest" to "widest" (in practice: non-tests before tests). +- // Sort packages "narrowest" to "widest" (in practice: +- // non-tests before tests), and regular packages before +- // their intermediate test variants (which have the same +- // files but different imports). - sort.Slice(metas, func(i, j int) bool { -- return len(metas[i].CompiledGoFiles) < len(metas[j].CompiledGoFiles) +- x, y := metas[i], metas[j] +- xfiles, yfiles := len(x.CompiledGoFiles), len(y.CompiledGoFiles) +- if xfiles != yfiles { +- return xfiles < yfiles +- } +- return boolLess(x.IsIntermediateTestVariant(), y.IsIntermediateTestVariant()) - }) - - return metas, nil -} - +-func boolLess(x, y bool) bool { return !x && y } // false < true +- -func (s *snapshot) ReverseDependencies(ctx context.Context, id PackageID, transitive bool) (map[PackageID]*source.Metadata, error) { - if err := s.awaitLoaded(ctx); err != nil { - return nil, err @@ -21024,21 +24331,15 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return rdeps, nil -} - --func (s *snapshot) workspaceMetadata() (meta []*source.Metadata) { -- s.mu.Lock() -- defer s.mu.Unlock() -- -- for id := range s.workspacePackages { -- meta = append(meta, s.meta.metadata[id]) -- } -- return meta --} -- -// -- Active package tracking -- -// --// We say a package is "active" if any of its files are open. After --// type-checking we keep active packages in memory. The activePackages --// peristent map does bookkeeping for the set of active packages. +-// We say a package is "active" if any of its files are open. +-// This is an optimization: the "active" concept is an +-// implementation detail of the cache and is not exposed +-// in the source or Snapshot API. +-// After type-checking we keep active packages in memory. +-// The activePackages persistent map does bookkeeping for +-// the set of active packages. - -// getActivePackage returns a the memoized active package for id, if it exists. -// If id is not active or has not yet been type-checked, it returns nil. @@ -21047,49 +24348,38 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - defer s.mu.Unlock() - - if value, ok := s.activePackages.Get(id); ok { -- return value.(*Package) // possibly nil, if we have already checked this id. +- return value - } - return nil -} - --// memoizeActivePackage checks if pkg is active, and if so either records it in +-// setActivePackage checks if pkg is active, and if so either records it in -// the active packages map or returns the existing memoized active package for id. --// --// The resulting package is non-nil if and only if the specified package is open. --func (s *snapshot) memoizeActivePackage(id PackageID, pkg *Package) (active *Package) { +-func (s *snapshot) setActivePackage(id PackageID, pkg *Package) { - s.mu.Lock() - defer s.mu.Unlock() - -- if value, ok := s.activePackages.Get(id); ok { -- return value.(*Package) // possibly nil, if we have already checked this id. +- if _, ok := s.activePackages.Get(id); ok { +- return // already memoized - } - -- defer func() { -- s.activePackages.Set(id, active, nil) // store the result either way: remember that pkg is not open -- }() -- for _, cgf := range pkg.Metadata().GoFiles { -- if s.isOpenLocked(cgf) { -- return pkg -- } -- } -- for _, cgf := range pkg.Metadata().CompiledGoFiles { -- if s.isOpenLocked(cgf) { -- return pkg -- } +- if containsOpenFileLocked(s, pkg.Metadata()) { +- s.activePackages.Set(id, pkg, nil) +- } else { +- s.activePackages.Set(id, (*Package)(nil), nil) // remember that pkg is not open - } -- return nil -} - -func (s *snapshot) resetActivePackagesLocked() { - s.activePackages.Destroy() -- s.activePackages = persistent.NewMap(packageIDLessInterface) +- s.activePackages = new(persistent.Map[PackageID, *Package]) -} - -const fileExtensions = "go,mod,sum,work" - -func (s *snapshot) fileWatchingGlobPatterns(ctx context.Context) map[string]struct{} { - extensions := fileExtensions -- for _, ext := range s.View().Options().TemplateExtensions { +- for _, ext := range s.Options().TemplateExtensions { - extensions += "," + ext - } - // Work-around microsoft/vscode#100870 by making sure that we are, @@ -21100,7 +24390,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - } - - // If GOWORK is outside the folder, ensure we are watching it. -- gowork := s.view.effectiveGOWORK() +- gowork, _ := s.view.GOWORK() - if gowork != "" && !source.InDir(s.view.folder.Filename(), gowork.Filename()) { - patterns[gowork.Filename()] = struct{}{} - } @@ -21121,19 +24411,57 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - patterns[fmt.Sprintf("%s/**/*.{%s}", dirName, extensions)] = struct{}{} - } - -- // Some clients do not send notifications for changes to directories that -- // contain Go code (golang/go#42348). To handle this, explicitly watch all -- // of the directories in the workspace. We find them by adding the -- // directories of every file in the snapshot's workspace directories. -- // There may be thousands. -- if pattern := s.getKnownSubdirsPattern(dirs); pattern != "" { -- patterns[pattern] = struct{}{} +- if s.watchSubdirs() { +- // Some clients (e.g. VS Code) do not send notifications for changes to +- // directories that contain Go code (golang/go#42348). To handle this, +- // explicitly watch all of the directories in the workspace. We find them +- // by adding the directories of every file in the snapshot's workspace +- // directories. There may be thousands of patterns, each a single +- // directory. +- // +- // (A previous iteration created a single glob pattern holding a union of +- // all the directories, but this was found to cause VS Code to get stuck +- // for several minutes after a buffer was saved twice in a workspace that +- // had >8000 watched directories.) +- // +- // Some clients (notably coc.nvim, which uses watchman for globs) perform +- // poorly with a large list of individual directories. +- s.addKnownSubdirs(patterns, dirs) - } - - return patterns -} - --func (s *snapshot) getKnownSubdirsPattern(wsDirs []span.URI) string { +-// watchSubdirs reports whether gopls should request separate file watchers for +-// each relevant subdirectory. This is necessary only for clients (namely VS +-// Code) that do not send notifications for individual files in a directory +-// when the entire directory is deleted. +-func (s *snapshot) watchSubdirs() bool { +- opts := s.view.Options() +- switch p := opts.SubdirWatchPatterns; p { +- case source.SubdirWatchPatternsOn: +- return true +- case source.SubdirWatchPatternsOff: +- return false +- case source.SubdirWatchPatternsAuto: +- // See the documentation of InternalOptions.SubdirWatchPatterns for an +- // explanation of why VS Code gets a different default value here. +- // +- // Unfortunately, there is no authoritative list of client names, nor any +- // requirements that client names do not change. We should update the VS +- // Code extension to set a default value of "subdirWatchPatterns" to "on", +- // so that this workaround is only temporary. +- if opts.ClientInfo != nil && opts.ClientInfo.Name == "Visual Studio Code" { +- return true +- } +- return false +- default: +- bug.Reportf("invalid subdirWatchPatterns: %q", p) +- return false +- } +-} +- +-func (s *snapshot) addKnownSubdirs(patterns map[string]struct{}, wsDirs []span.URI) { - s.mu.Lock() - defer s.mu.Unlock() - @@ -21142,23 +24470,18 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // It may change list of known subdirs and therefore invalidate the cache. - s.applyKnownSubdirsChangesLocked(wsDirs) - -- if s.knownSubdirsPatternCache == "" { -- var builder strings.Builder +- // TODO(adonovan): is it still necessary to memoize the Range +- // and URI.Filename operations? +- if s.knownSubdirsCache == nil { +- s.knownSubdirsCache = make(map[string]struct{}) - s.knownSubdirs.Range(func(uri span.URI) { -- if builder.Len() == 0 { -- builder.WriteString("{") -- } else { -- builder.WriteString(",") -- } -- builder.WriteString(uri.Filename()) +- s.knownSubdirsCache[uri.Filename()] = struct{}{} - }) -- if builder.Len() > 0 { -- builder.WriteString("}") -- s.knownSubdirsPatternCache = builder.String() -- } - } - -- return s.knownSubdirsPatternCache +- for pattern := range s.knownSubdirsCache { +- patterns[pattern] = struct{}{} +- } -} - -// collectAllKnownSubdirs collects all of the subdirectories within the @@ -21171,14 +24494,14 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - defer s.mu.Unlock() - - s.knownSubdirs.Destroy() -- s.knownSubdirs = newKnownDirsSet() -- s.knownSubdirsPatternCache = "" +- s.knownSubdirs = new(persistent.Set[span.URI]) +- s.knownSubdirsCache = nil - s.files.Range(func(uri span.URI, fh source.FileHandle) { - s.addKnownSubdirLocked(uri, dirs) - }) -} - --func (s *snapshot) getKnownSubdirs(wsDirs []span.URI) knownDirsSet { +-func (s *snapshot) getKnownSubdirs(wsDirs []span.URI) *persistent.Set[span.URI] { - s.mu.Lock() - defer s.mu.Unlock() - @@ -21229,9 +24552,9 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - if s.knownSubdirs.Contains(uri) { - break - } -- s.knownSubdirs.Insert(uri) +- s.knownSubdirs.Add(uri) - dir = filepath.Dir(dir) -- s.knownSubdirsPatternCache = "" +- s.knownSubdirsCache = nil - } -} - @@ -21244,7 +24567,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - } - if info, _ := os.Stat(dir); info == nil { - s.knownSubdirs.Remove(uri) -- s.knownSubdirsPatternCache = "" +- s.knownSubdirsCache = nil - } - dir = filepath.Dir(dir) - } @@ -21265,29 +24588,45 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return files -} - --func (s *snapshot) ActiveMetadata(ctx context.Context) ([]*source.Metadata, error) { +-func (s *snapshot) WorkspaceMetadata(ctx context.Context) ([]*source.Metadata, error) { - if err := s.awaitLoaded(ctx); err != nil { - return nil, err - } -- return s.workspaceMetadata(), nil +- +- s.mu.Lock() +- defer s.mu.Unlock() +- +- meta := make([]*source.Metadata, 0, len(s.workspacePackages)) +- for id := range s.workspacePackages { +- meta = append(meta, s.meta.metadata[id]) +- } +- return meta, nil -} - -// Symbols extracts and returns symbol information for every file contained in -// a loaded package. It awaits snapshot loading. -// -// TODO(rfindley): move this to the top of cache/symbols.go --func (s *snapshot) Symbols(ctx context.Context) (map[span.URI][]source.Symbol, error) { +-func (s *snapshot) Symbols(ctx context.Context, workspaceOnly bool) (map[span.URI][]source.Symbol, error) { - if err := s.awaitLoaded(ctx); err != nil { - return nil, err - } - -- // Build symbols for all loaded Go files. -- s.mu.Lock() -- meta := s.meta -- s.mu.Unlock() +- var ( +- meta []*source.Metadata +- err error +- ) +- if workspaceOnly { +- meta, err = s.WorkspaceMetadata(ctx) +- } else { +- meta, err = s.AllMetadata(ctx) +- } +- if err != nil { +- return nil, fmt.Errorf("loading metadata: %v", err) +- } - - goFiles := make(map[span.URI]struct{}) -- for _, m := range meta.metadata { +- for _, m := range meta { - for _, uri := range m.GoFiles { - goFiles[uri] = struct{}{} - } @@ -21350,7 +24689,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -func moduleForURI(modFiles map[span.URI]struct{}, uri span.URI) span.URI { - var match span.URI - for modURI := range modFiles { -- if !source.InDir(span.Dir(modURI).Filename(), uri.Filename()) { +- if !source.InDir(filepath.Dir(modURI.Filename()), uri.Filename()) { - continue - } - if len(modURI) > len(match) { @@ -21365,7 +24704,6 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -// -// The given uri must be a file, not a directory. -func nearestModFile(ctx context.Context, uri span.URI, fs source.FileSource) (span.URI, error) { -- // TODO(rfindley) - dir := filepath.Dir(uri.Filename()) - mod, err := findRootPattern(ctx, dir, "go.mod", fs) - if err != nil { @@ -21411,25 +24749,6 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - } -} - --// noValidMetadataForURILocked reports whether there is any valid metadata for --// the given URI. --func (s *snapshot) noValidMetadataForURILocked(uri span.URI) bool { -- for _, id := range s.meta.ids[uri] { -- if _, ok := s.meta.metadata[id]; ok { -- return false -- } -- } -- return true --} -- --func (s *snapshot) isWorkspacePackage(id PackageID) bool { -- s.mu.Lock() -- defer s.mu.Unlock() -- -- _, ok := s.workspacePackages[id] -- return ok --} -- -func (s *snapshot) FindFile(uri span.URI) source.FileHandle { - s.view.markKnown(uri) - @@ -21440,29 +24759,65 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return result -} - --// GetFile returns a File for the given URI. If the file is unknown it is added +-// ReadFile returns a File for the given URI. If the file is unknown it is added -// to the managed set. -// --// GetFile succeeds even if the file does not exist. A non-nil error return +-// ReadFile succeeds even if the file does not exist. A non-nil error return -// indicates some type of internal error, for example if ctx is cancelled. --func (s *snapshot) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { +-func (s *snapshot) ReadFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { - s.mu.Lock() - defer s.mu.Unlock() - -- return lockedSnapshot{s}.GetFile(ctx, uri) +- return lockedSnapshot{s}.ReadFile(ctx, uri) +-} +- +-// preloadFiles delegates to the view FileSource to read the requested uris in +-// parallel, without holding the snapshot lock. +-func (s *snapshot) preloadFiles(ctx context.Context, uris []span.URI) { +- files := make([]source.FileHandle, len(uris)) +- var wg sync.WaitGroup +- iolimit := make(chan struct{}, 20) // I/O concurrency limiting semaphore +- for i, uri := range uris { +- wg.Add(1) +- iolimit <- struct{}{} +- go func(i int, uri span.URI) { +- defer wg.Done() +- fh, err := s.view.fs.ReadFile(ctx, uri) +- <-iolimit +- if err != nil && ctx.Err() == nil { +- event.Error(ctx, fmt.Sprintf("reading %s", uri), err) +- return +- } +- files[i] = fh +- }(i, uri) +- } +- wg.Wait() +- +- s.mu.Lock() +- defer s.mu.Unlock() +- +- for i, fh := range files { +- if fh == nil { +- continue // error logged above +- } +- uri := uris[i] +- if _, ok := s.files.Get(uri); !ok { +- s.files.Set(uri, fh) +- } +- } -} - -// A lockedSnapshot implements the source.FileSource interface while holding -// the lock for the wrapped snapshot. -type lockedSnapshot struct{ wrapped *snapshot } - --func (s lockedSnapshot) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { +-func (s lockedSnapshot) ReadFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { - s.wrapped.view.markKnown(uri) - if fh, ok := s.wrapped.files.Get(uri); ok { - return fh, nil - } - -- fh, err := s.wrapped.view.fs.GetFile(ctx, uri) // read the file +- fh, err := s.wrapped.view.fs.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -21473,33 +24828,13 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -func (s *snapshot) IsOpen(uri span.URI) bool { - s.mu.Lock() - defer s.mu.Unlock() -- return s.isOpenLocked(uri) -- --} - --func (s *snapshot) openFiles() []source.FileHandle { -- s.mu.Lock() -- defer s.mu.Unlock() -- -- var open []source.FileHandle -- s.files.Range(func(uri span.URI, fh source.FileHandle) { -- if isFileOpen(fh) { -- open = append(open, fh) -- } -- }) -- return open --} -- --func (s *snapshot) isOpenLocked(uri span.URI) bool { - fh, _ := s.files.Get(uri) -- return isFileOpen(fh) --} -- --func isFileOpen(fh source.FileHandle) bool { - _, open := fh.(*Overlay) - return open -} - +-// TODO(rfindley): it would make sense for awaitLoaded to return metadata. -func (s *snapshot) awaitLoaded(ctx context.Context) error { - loadErr := s.awaitLoadedAllErrors(ctx) - @@ -21511,7 +24846,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return nil -} - --func (s *snapshot) GetCriticalError(ctx context.Context) *source.CriticalError { +-func (s *snapshot) CriticalError(ctx context.Context) *source.CriticalError { - // If we couldn't compute workspace mod files, then the load below is - // invalid. - // @@ -21528,7 +24863,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // Even if packages didn't fail to load, we still may want to show - // additional warnings. - if loadErr == nil { -- active, _ := s.ActiveMetadata(ctx) +- active, _ := s.WorkspaceMetadata(ctx) - if msg := shouldShowAdHocPackagesWarning(s, active); msg != "" { - return &source.CriticalError{ - MainError: errors.New(msg), @@ -21579,8 +24914,8 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -If you are using modules, please open your editor to a directory in your module. -If you believe this warning is incorrect, please file an issue: https://github.com/golang/go/issues/new.` - --func shouldShowAdHocPackagesWarning(snapshot source.Snapshot, active []*source.Metadata) string { -- if !snapshot.ValidBuildConfiguration() { +-func shouldShowAdHocPackagesWarning(snapshot *snapshot, active []*source.Metadata) string { +- if !snapshot.validBuildConfiguration() { - for _, m := range active { - // A blank entry in DepsByImpPath - // indicates a missing dependency. @@ -21690,7 +25025,7 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - - // If the view's build configuration is invalid, we cannot reload by - // package path. Just reload the directory instead. -- if !s.ValidBuildConfiguration() { +- if !s.validBuildConfiguration() { - scopes = []loadScope{viewLoadScope("LOAD_INVALID_VIEW")} - } - @@ -21705,86 +25040,307 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return err -} - +-// reloadOrphanedOpenFiles attempts to load a package for each open file that +-// does not yet have an associated package. If loading finishes without being +-// canceled, any files still not contained in a package are marked as unloadable. +-// +-// An error is returned if the load is canceled. -func (s *snapshot) reloadOrphanedOpenFiles(ctx context.Context) error { +- s.mu.Lock() +- meta := s.meta +- s.mu.Unlock() - // When we load ./... or a package path directly, we may not get packages - // that exist only in overlays. As a workaround, we search all of the files - // available in the snapshot and reload their metadata individually using a - // file= query if the metadata is unavailable. -- files := s.orphanedOpenFiles() -- -- // Files without a valid package declaration can't be loaded. Don't try. -- var scopes []loadScope -- for _, file := range files { -- pgf, err := s.ParseGo(ctx, file, source.ParseHeader) -- if err != nil { +- open := s.overlays() +- var files []*Overlay +- for _, o := range open { +- uri := o.URI() +- if s.IsBuiltin(uri) || s.view.FileKind(o) != source.Go { - continue - } -- if !pgf.File.Package.IsValid() { -- continue +- if len(meta.ids[uri]) == 0 { +- files = append(files, o) - } +- } - -- scopes = append(scopes, fileLoadScope(file.URI())) +- // Filter to files that are not known to be unloadable. +- s.mu.Lock() +- loadable := files[:0] +- for _, file := range files { +- if !s.unloadableFiles.Contains(file.URI()) { +- loadable = append(loadable, file) +- } - } +- files = loadable +- s.mu.Unlock() - -- if len(scopes) == 0 { +- if len(files) == 0 { - return nil - } - -- // The regtests match this exact log message, keep them in sync. -- event.Log(ctx, "reloadOrphanedFiles reloading", tag.Query.Of(scopes)) -- err := s.load(ctx, false, scopes...) +- var uris []span.URI +- for _, file := range files { +- uris = append(uris, file.URI()) +- } +- +- event.Log(ctx, "reloadOrphanedFiles reloading", tag.Files.Of(uris)) +- +- var g errgroup.Group +- +- cpulimit := runtime.GOMAXPROCS(0) +- g.SetLimit(cpulimit) +- +- // Load files one-at-a-time. go/packages can return at most one +- // command-line-arguments package per query. +- for _, file := range files { +- file := file +- g.Go(func() error { +- return s.load(ctx, false, fileLoadScope(file.URI())) +- }) +- } - - // If we failed to load some files, i.e. they have no metadata, - // mark the failures so we don't bother retrying until the file's - // content changes. - // -- // TODO(rstambler): This may be an overestimate if the load stopped -- // early for an unrelated errors. Add a fallback? -- // -- // Check for context cancellation so that we don't incorrectly mark files -- // as unloadable, but don't return before setting all workspace packages. -- if ctx.Err() == nil && err != nil { -- event.Error(ctx, "reloadOrphanedFiles: failed to load", err, tag.Query.Of(scopes)) -- s.mu.Lock() -- for _, scope := range scopes { -- uri := span.URI(scope.(fileLoadScope)) -- if s.noValidMetadataForURILocked(uri) { -- s.unloadableFiles[uri] = struct{}{} -- } +- // TODO(rfindley): is it possible that the load stopped early for an +- // unrelated errors? If so, add a fallback? +- +- if err := g.Wait(); err != nil { +- // Check for context cancellation so that we don't incorrectly mark files +- // as unloadable, but don't return before setting all workspace packages. +- if ctx.Err() != nil { +- return ctx.Err() +- } +- +- if !errors.Is(err, errNoPackages) { +- event.Error(ctx, "reloadOrphanedFiles: failed to load", err, tag.Files.Of(uris)) - } -- s.mu.Unlock() - } -- return nil --} - --func (s *snapshot) orphanedOpenFiles() []source.FileHandle { +- // If the context was not canceled, we assume that the result of loading +- // packages is deterministic (though as we saw in golang/go#59318, it may not +- // be in the presence of bugs). Marking all unloaded files as unloadable here +- // prevents us from falling into recursive reloading where we only make a bit +- // of progress each time. - s.mu.Lock() - defer s.mu.Unlock() +- for _, file := range files { +- // TODO(rfindley): instead of locking here, we should have load return the +- // metadata graph that resulted from loading. +- uri := file.URI() +- if len(s.meta.ids[uri]) == 0 { +- s.unloadableFiles.Add(uri) +- } +- } - -- var files []source.FileHandle -- s.files.Range(func(uri span.URI, fh source.FileHandle) { -- // Only consider open files, which will be represented as overlays. -- if _, isOverlay := fh.(*Overlay); !isOverlay { -- return +- return nil +-} +- +-// OrphanedFileDiagnostics reports diagnostics describing why open files have +-// no packages or have only command-line-arguments packages. +-// +-// If the resulting diagnostic is nil, the file is either not orphaned or we +-// can't produce a good diagnostic. +-// +-// TODO(rfindley): reconcile the definition of "orphaned" here with +-// reloadOrphanedFiles. The latter does not include files with +-// command-line-arguments packages. +-func (s *snapshot) OrphanedFileDiagnostics(ctx context.Context) (map[span.URI]*source.Diagnostic, error) { +- if err := s.awaitLoaded(ctx); err != nil { +- return nil, err +- } +- +- var files []*Overlay +- +-searchOverlays: +- for _, o := range s.overlays() { +- uri := o.URI() +- if s.IsBuiltin(uri) || s.view.FileKind(o) != source.Go { +- continue - } -- // Don't try to reload metadata for go.mod files. -- if s.view.FileKind(fh) != source.Go { -- return +- md, err := s.MetadataForFile(ctx, uri) +- if err != nil { +- return nil, err - } -- // If the URI doesn't belong to this view, then it's not in a workspace -- // package and should not be reloaded directly. -- if !source.InDir(s.view.folder.Filename(), uri.Filename()) { -- return +- for _, m := range md { +- if !source.IsCommandLineArguments(m.ID) || m.Standalone { +- continue searchOverlays +- } - } -- // Don't reload metadata for files we've already deemed unloadable. -- if _, ok := s.unloadableFiles[uri]; ok { -- return +- files = append(files, o) +- } +- if len(files) == 0 { +- return nil, nil +- } +- +- loadedModFiles := make(map[span.URI]struct{}) // all mod files, including dependencies +- ignoredFiles := make(map[span.URI]bool) // files reported in packages.Package.IgnoredFiles +- +- meta, err := s.AllMetadata(ctx) +- if err != nil { +- return nil, err +- } +- +- for _, meta := range meta { +- if meta.Module != nil && meta.Module.GoMod != "" { +- gomod := span.URIFromPath(meta.Module.GoMod) +- loadedModFiles[gomod] = struct{}{} - } -- if s.noValidMetadataForURILocked(uri) { -- files = append(files, fh) +- for _, ignored := range meta.IgnoredFiles { +- ignoredFiles[ignored] = true - } -- }) -- return files +- } +- +- diagnostics := make(map[span.URI]*source.Diagnostic) +- for _, fh := range files { +- // Only warn about orphaned files if the file is well-formed enough to +- // actually be part of a package. +- // +- // Use ParseGo as for open files this is likely to be a cache hit (we'll have ) +- pgf, err := s.ParseGo(ctx, fh, source.ParseHeader) +- if err != nil { +- continue +- } +- if !pgf.File.Name.Pos().IsValid() { +- continue +- } +- rng, err := pgf.PosRange(pgf.File.Name.Pos(), pgf.File.Name.End()) +- if err != nil { +- continue +- } +- +- var ( +- msg string // if non-empty, report a diagnostic with this message +- suggestedFixes []source.SuggestedFix // associated fixes, if any +- ) +- +- // If we have a relevant go.mod file, check whether the file is orphaned +- // due to its go.mod file being inactive. We could also offer a +- // prescriptive diagnostic in the case that there is no go.mod file, but it +- // is harder to be precise in that case, and less important. +- if goMod, err := nearestModFile(ctx, fh.URI(), s); err == nil && goMod != "" { +- if _, ok := loadedModFiles[goMod]; !ok { +- modDir := filepath.Dir(goMod.Filename()) +- viewDir := s.view.folder.Filename() +- +- // When the module is underneath the view dir, we offer +- // "use all modules" quick-fixes. +- inDir := source.InDir(viewDir, modDir) +- +- if rel, err := filepath.Rel(viewDir, modDir); err == nil { +- modDir = rel +- } +- +- var fix string +- if s.view.goversion >= 18 { +- if s.view.gowork != "" { +- fix = fmt.Sprintf("To fix this problem, you can add this module to your go.work file (%s)", s.view.gowork) +- if cmd, err := command.NewRunGoWorkCommandCommand("Run `go work use`", command.RunGoWorkArgs{ +- ViewID: s.view.ID(), +- Args: []string{"use", modDir}, +- }); err == nil { +- suggestedFixes = append(suggestedFixes, source.SuggestedFix{ +- Title: "Use this module in your go.work file", +- Command: &cmd, +- ActionKind: protocol.QuickFix, +- }) +- } +- +- if inDir { +- if cmd, err := command.NewRunGoWorkCommandCommand("Run `go work use -r`", command.RunGoWorkArgs{ +- ViewID: s.view.ID(), +- Args: []string{"use", "-r", "."}, +- }); err == nil { +- suggestedFixes = append(suggestedFixes, source.SuggestedFix{ +- Title: "Use all modules in your workspace", +- Command: &cmd, +- ActionKind: protocol.QuickFix, +- }) +- } +- } +- } else { +- fix = "To fix this problem, you can add a go.work file that uses this directory." +- +- if cmd, err := command.NewRunGoWorkCommandCommand("Run `go work init && go work use`", command.RunGoWorkArgs{ +- ViewID: s.view.ID(), +- InitFirst: true, +- Args: []string{"use", modDir}, +- }); err == nil { +- suggestedFixes = []source.SuggestedFix{ +- { +- Title: "Add a go.work file using this module", +- Command: &cmd, +- ActionKind: protocol.QuickFix, +- }, +- } +- } +- +- if inDir { +- if cmd, err := command.NewRunGoWorkCommandCommand("Run `go work init && go work use -r`", command.RunGoWorkArgs{ +- ViewID: s.view.ID(), +- InitFirst: true, +- Args: []string{"use", "-r", "."}, +- }); err == nil { +- suggestedFixes = append(suggestedFixes, source.SuggestedFix{ +- Title: "Add a go.work file using all modules in your workspace", +- Command: &cmd, +- ActionKind: protocol.QuickFix, +- }) +- } +- } +- } +- } else { +- fix = `To work with multiple modules simultaneously, please upgrade to Go 1.18 or +-later, reinstall gopls, and use a go.work file.` +- } +- msg = fmt.Sprintf(`This file is within module %q, which is not included in your workspace. +-%s +-See the documentation for more information on setting up your workspace: +-https://github.com/golang/tools/blob/master/gopls/doc/workspace.md.`, modDir, fix) +- } +- } +- +- if msg == "" && ignoredFiles[fh.URI()] { +- // TODO(rfindley): use the constraint package to check if the file +- // _actually_ satisfies the current build context. +- hasConstraint := false +- walkConstraints(pgf.File, func(constraint.Expr) bool { +- hasConstraint = true +- return false +- }) +- var fix string +- if hasConstraint { +- fix = `This file may be excluded due to its build tags; try adding "-tags=" to your gopls "buildFlags" configuration +-See the documentation for more information on working with build tags: +-https://github.com/golang/tools/blob/master/gopls/doc/settings.md#buildflags-string.` +- } else if strings.Contains(filepath.Base(fh.URI().Filename()), "_") { +- fix = `This file may be excluded due to its GOOS/GOARCH, or other build constraints.` +- } else { +- fix = `This file is ignored by your gopls build.` // we don't know why +- } +- msg = fmt.Sprintf("No packages found for open file %s.\n%s", fh.URI().Filename(), fix) +- } +- +- if msg != "" { +- d := &source.Diagnostic{ +- URI: fh.URI(), +- Range: rng, +- Severity: protocol.SeverityWarning, +- Source: source.ListError, +- Message: msg, +- SuggestedFixes: suggestedFixes, +- } +- if ok := source.BundleQuickFixes(d); !ok { +- bug.Reportf("failed to bundle quick fixes for %v", d) +- } +- // Only report diagnostics if we detect an actual exclusion. +- diagnostics[fh.URI()] = d +- } +- } +- return diagnostics, nil -} - -// TODO(golang/go#53756): this function needs to consider more than just the @@ -21795,41 +25351,33 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap -// Most likely, each call site of inVendor needs to be reconsidered to -// understand and correctly implement the desired behavior. -func inVendor(uri span.URI) bool { -- _, after, found := cut(string(uri), "/vendor/") +- _, after, found := strings.Cut(string(uri), "/vendor/") - // Only subdirectories of /vendor/ are considered vendored - // (/vendor/a/foo.go is vendored, /vendor/foo.go is not). - return found && strings.Contains(after, "/") -} - --// TODO(adonovan): replace with strings.Cut when we can assume go1.18. --func cut(s, sep string) (before, after string, found bool) { -- if i := strings.Index(s, sep); i >= 0 { -- return s[:i], s[i+len(sep):], true -- } -- return s, "", false --} -- -// unappliedChanges is a file source that handles an uncloned snapshot. -type unappliedChanges struct { - originalSnapshot *snapshot - changes map[span.URI]*fileChange -} - --func (ac *unappliedChanges) GetFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { +-func (ac *unappliedChanges) ReadFile(ctx context.Context, uri span.URI) (source.FileHandle, error) { - if c, ok := ac.changes[uri]; ok { - return c.fileHandle, nil - } -- return ac.originalSnapshot.GetFile(ctx, uri) +- return ac.originalSnapshot.ReadFile(ctx, uri) -} - -func (s *snapshot) clone(ctx, bgCtx context.Context, changes map[span.URI]*fileChange, forceReloadMetadata bool) (*snapshot, func()) { -- ctx, done := event.Start(ctx, "snapshot.clone") +- ctx, done := event.Start(ctx, "cache.snapshot.clone") - defer done() - - reinit := false - wsModFiles, wsModFilesErr := s.workspaceModFiles, s.workspaceModFilesErr - -- if workURI := s.view.effectiveGOWORK(); workURI != "" { +- if workURI, _ := s.view.GOWORK(); workURI != "" { - if change, ok := changes[workURI]; ok { - wsModFiles, wsModFilesErr = computeWorkspaceModFiles(ctx, s.view.gomod, workURI, s.view.effectiveGO111MODULE(), &unappliedChanges{ - originalSnapshot: s, @@ -21895,12 +25443,10 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - initializedErr: s.initializedErr, - packages: s.packages.Clone(), - activePackages: s.activePackages.Clone(), -- analyses: s.analyses.Clone(), - files: s.files.Clone(), -- parseCache: s.parseCache, - symbolizeHandles: s.symbolizeHandles.Clone(), - workspacePackages: make(map[PackageID]PackagePath, len(s.workspacePackages)), -- unloadableFiles: make(map[span.URI]struct{}, len(s.unloadableFiles)), +- unloadableFiles: s.unloadableFiles.Clone(), // see the TODO for unloadableFiles below - parseModHandles: s.parseModHandles.Clone(), - parseWorkHandles: s.parseWorkHandles.Clone(), - modTidyHandles: s.modTidyHandles.Clone(), @@ -21909,6 +25455,8 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - knownSubdirs: s.knownSubdirs.Clone(), - workspaceModFiles: wsModFiles, - workspaceModFilesErr: wsModFilesErr, +- importGraph: s.importGraph, +- pkgIndex: s.pkgIndex, - } - - // The snapshot should be initialized if either s was uninitialized, or we've @@ -21922,22 +25470,17 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // incref/decref operation that might destroy it prematurely.) - release := result.Acquire() - -- // Copy the set of unloadable files. -- // -- // TODO(rfindley): this looks wrong. Shouldn't we clear unloadableFiles on +- // TODO(rfindley): this looks wrong. Should we clear unloadableFiles on - // changes to environment or workspace layout, or more generally on any - // metadata change? - // - // Maybe not, as major configuration changes cause a new view. -- for k, v := range s.unloadableFiles { -- result.unloadableFiles[k] = v -- } - - // Add all of the known subdirectories, but don't update them for the - // changed files. We need to rebuild the workspace module to know the - // true set of known subdirectories, but we don't want to do that in clone. - result.knownSubdirs = s.knownSubdirs.Clone() -- result.knownSubdirsPatternCache = s.knownSubdirsPatternCache +- result.knownSubdirsCache = s.knownSubdirsCache - for _, c := range changes { - result.unprocessedSubdirChanges = append(result.unprocessedSubdirChanges, c) - } @@ -21996,10 +25539,36 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // Invalidate the previous modTidyHandle if any of the files have been - // saved or if any of the metadata has been invalidated. - if invalidateMetadata || fileWasSaved(originalFH, change.fileHandle) { -- // TODO(maybe): Only delete mod handles for -- // which the withoutURI is relevant. -- // Requires reverse-engineering the go command. (!) -- result.modTidyHandles.Clear() +- // Only invalidate mod tidy results for the most relevant modfile in the +- // workspace. This is a potentially lossy optimization for workspaces +- // with many modules (such as google-cloud-go, which has 145 modules as +- // of writing). +- // +- // While it is theoretically possible that a change in workspace module A +- // could affect the mod-tidiness of workspace module B (if B transitively +- // requires A), such changes are probably unlikely and not worth the +- // penalty of re-running go mod tidy for everything. Note that mod tidy +- // ignores GOWORK, so the two modules would have to be related by a chain +- // of replace directives. +- // +- // We could improve accuracy by inspecting replace directives, using +- // overlays in go mod tidy, and/or checking for metadata changes from the +- // on-disk content. +- // +- // Note that we iterate the modTidyHandles map here, rather than e.g. +- // using nearestModFile, because we don't have access to an accurate +- // FileSource at this point in the snapshot clone. +- const onlyInvalidateMostRelevant = true +- if onlyInvalidateMostRelevant { +- deleteMostRelevantModFile(result.modTidyHandles, uri) +- } else { +- result.modTidyHandles.Clear() +- } +- +- // TODO(rfindley): should we apply the above heuristic to mod vuln +- // or mod handles as well? +- // +- // TODO(rfindley): no tests fail if I delete the below line. - result.modWhyHandles.Clear() - result.modVulnHandles.Clear() - } @@ -22010,11 +25579,19 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - if !change.exists { - result.files.Delete(uri) - } else { +- // TODO(golang/go#57558): the line below is strictly necessary to ensure +- // that snapshots have each overlay, but it is problematic that we must +- // set any content in snapshot.clone: if the file has changed, let it be +- // re-read. - result.files.Set(uri, change.fileHandle) - } - - // Make sure to remove the changed file from the unloadable set. -- delete(result.unloadableFiles, uri) +- // +- // TODO(rfindley): this also looks wrong, as typing in an unloadable file +- // will result in repeated reloads. We should only delete if metadata +- // changed. +- result.unloadableFiles.Remove(uri) - } - - // Deleting an import can cause list errors due to import cycles to be @@ -22078,22 +25655,17 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - addRevDeps(id, invalidateMetadata) - } - -- // Delete invalidated package type information. -- for id := range idsToInvalidate { -- result.packages.Delete(id) -- result.activePackages.Delete(id) -- } -- -- // Delete invalidated analysis actions. -- var actionsToDelete []analysisKey -- result.analyses.Range(func(k, _ interface{}) { -- key := k.(analysisKey) -- if _, ok := idsToInvalidate[key.pkgid]; ok { -- actionsToDelete = append(actionsToDelete, key) +- // Invalidated package information. +- for id, invalidateMetadata := range idsToInvalidate { +- if _, ok := directIDs[id]; ok || invalidateMetadata { +- result.packages.Delete(id) +- } else { +- if entry, hit := result.packages.Get(id); hit { +- ph := entry.clone(false) +- result.packages.Set(id, ph, nil) +- } - } -- }) -- for _, key := range actionsToDelete { -- result.analyses.Delete(key) +- result.activePackages.Delete(id) - } - - // If a file has been deleted, we must delete metadata for all packages @@ -22180,10 +25752,33 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - if workspaceModeChanged { - result.workspacePackages = map[PackageID]PackagePath{} - } -- result.dumpWorkspace("clone") - return result, release -} - +-// deleteMostRelevantModFile deletes the mod file most likely to be the mod +-// file for the changed URI, if it exists. +-// +-// Specifically, this is the longest mod file path in a directory containing +-// changed. This might not be accurate if there is another mod file closer to +-// changed that happens not to be present in the map, but that's OK: the goal +-// of this function is to guarantee that IF the nearest mod file is present in +-// the map, it is invalidated. +-func deleteMostRelevantModFile(m *persistent.Map[span.URI, *memoize.Promise], changed span.URI) { +- var mostRelevant span.URI +- changedFile := changed.Filename() +- +- m.Range(func(modURI span.URI, _ *memoize.Promise) { +- if len(modURI) > len(mostRelevant) { +- if source.InDir(filepath.Dir(modURI.Filename()), changedFile) { +- mostRelevant = modURI +- } +- } +- }) +- if mostRelevant != "" { +- m.Delete(mostRelevant) +- } +-} +- -// invalidatedPackageIDs returns all packages invalidated by a change to uri. -// If we haven't seen this URI before, we guess based on files in the same -// directory. This is of course incorrect in build systems where packages are @@ -22287,9 +25882,10 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return false, false, false - } - +- fset := token.NewFileSet() - // Parse headers to compare package names and imports. -- oldHeads, _, oldErr := lockedSnapshot.parseCache.parseFiles(ctx, source.ParseHeader, oldFH) -- newHeads, _, newErr := lockedSnapshot.parseCache.parseFiles(ctx, source.ParseHeader, newFH) +- oldHeads, oldErr := lockedSnapshot.view.parseCache.parseFiles(ctx, fset, source.ParseHeader, false, oldFH) +- newHeads, newErr := lockedSnapshot.view.parseCache.parseFiles(ctx, fset, source.ParseHeader, false, newFH) - - if oldErr != nil || newErr != nil { - // TODO(rfindley): we can get here if newFH does not exist. There is @@ -22340,8 +25936,8 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - // Note: if this affects performance we can probably avoid parsing in the - // common case by first scanning the source for potential comments. - if !invalidate { -- origFulls, _, oldErr := lockedSnapshot.parseCache.parseFiles(ctx, source.ParseFull, oldFH) -- newFulls, _, newErr := lockedSnapshot.parseCache.parseFiles(ctx, source.ParseFull, newFH) +- origFulls, oldErr := lockedSnapshot.view.parseCache.parseFiles(ctx, fset, source.ParseFull, false, oldFH) +- newFulls, newErr := lockedSnapshot.view.parseCache.parseFiles(ctx, fset, source.ParseFull, false, newFH) - if oldErr == nil && newErr == nil { - invalidate = magicCommentsChanged(origFulls[0].File, newFulls[0].File) - } else { @@ -22419,14 +26015,21 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - return nil, fmt.Errorf("no builtin package for view %s", s.view.name) - } - -- fh, err := s.GetFile(ctx, builtin) +- fh, err := s.ReadFile(ctx, builtin) +- if err != nil { +- return nil, err +- } +- // For the builtin file only, we need syntactic object resolution +- // (since we can't type check). +- mode := source.ParseFull &^ source.SkipObjectResolution +- pgfs, err := s.view.parseCache.parseFiles(ctx, token.NewFileSet(), mode, false, fh) - if err != nil { - return nil, err - } -- return s.ParseGo(ctx, fh, source.ParseFull) +- return pgfs[0], nil -} - --func (s *snapshot) IsBuiltin(ctx context.Context, uri span.URI) bool { +-func (s *snapshot) IsBuiltin(uri span.URI) bool { - s.mu.Lock() - defer s.mu.Unlock() - // We should always get the builtin URI in a canonical form, so use simple @@ -22440,182 +26043,10 @@ diff -urN a/gopls/internal/lsp/cache/snapshot.go b/gopls/internal/lsp/cache/snap - - s.builtin = span.URIFromPath(path) -} -diff -urN a/gopls/internal/lsp/cache/standalone_go115.go b/gopls/internal/lsp/cache/standalone_go115.go ---- a/gopls/internal/lsp/cache/standalone_go115.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/standalone_go115.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build !go1.16 --// +build !go1.16 -- --package cache -- --// isStandaloneFile returns false, as the 'standaloneTags' setting is --// unsupported on Go 1.15 and earlier. --func isStandaloneFile(src []byte, standaloneTags []string) bool { -- return false --} -diff -urN a/gopls/internal/lsp/cache/standalone_go116.go b/gopls/internal/lsp/cache/standalone_go116.go ---- a/gopls/internal/lsp/cache/standalone_go116.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/standalone_go116.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,50 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build go1.16 --// +build go1.16 -- --package cache -- --import ( -- "go/build/constraint" -- "go/parser" -- "go/token" --) -- --// isStandaloneFile reports whether a file with the given contents should be --// considered a 'standalone main file', meaning a package that consists of only --// a single file. --func isStandaloneFile(src []byte, standaloneTags []string) bool { -- f, err := parser.ParseFile(token.NewFileSet(), "", src, parser.PackageClauseOnly|parser.ParseComments) -- if err != nil { -- return false -- } -- -- if f.Name == nil || f.Name.Name != "main" { -- return false -- } -- -- for _, cg := range f.Comments { -- // Even with PackageClauseOnly the parser consumes the semicolon following -- // the package clause, so we must guard against comments that come after -- // the package name. -- if cg.Pos() > f.Name.Pos() { -- continue -- } -- for _, comment := range cg.List { -- if c, err := constraint.Parse(comment.Text); err == nil { -- if tag, ok := c.(*constraint.TagExpr); ok { -- for _, t := range standaloneTags { -- if t == tag.Tag { -- return true -- } -- } -- } -- } -- } -- } -- -- return false --} -diff -urN a/gopls/internal/lsp/cache/standalone_go116_test.go b/gopls/internal/lsp/cache/standalone_go116_test.go ---- a/gopls/internal/lsp/cache/standalone_go116_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cache/standalone_go116_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,96 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build go1.16 --// +build go1.16 -- --package cache -- --import ( -- "testing" --) -- --func TestIsStandaloneFile(t *testing.T) { -- tests := []struct { -- desc string -- contents string -- standaloneTags []string -- want bool -- }{ -- { -- "new syntax", -- "//go:build ignore\n\npackage main\n", -- []string{"ignore"}, -- true, -- }, -- { -- "legacy syntax", -- "// +build ignore\n\npackage main\n", -- []string{"ignore"}, -- true, -- }, -- { -- "multiple tags", -- "//go:build ignore\n\npackage main\n", -- []string{"exclude", "ignore"}, -- true, -- }, -- { -- "invalid tag", -- "// +build ignore\n\npackage main\n", -- []string{"script"}, -- false, -- }, -- { -- "non-main package", -- "//go:build ignore\n\npackage p\n", -- []string{"ignore"}, -- false, -- }, -- { -- "alternate tag", -- "// +build script\n\npackage main\n", -- []string{"script"}, -- true, -- }, -- { -- "both syntax", -- "//go:build ignore\n// +build ignore\n\npackage main\n", -- []string{"ignore"}, -- true, -- }, -- { -- "after comments", -- "// A non-directive comment\n//go:build ignore\n\npackage main\n", -- []string{"ignore"}, -- true, -- }, -- { -- "after package decl", -- "package main //go:build ignore\n", -- []string{"ignore"}, -- false, -- }, -- { -- "on line after package decl", -- "package main\n\n//go:build ignore\n", -- []string{"ignore"}, -- false, -- }, -- { -- "combined with other expressions", -- "\n\n//go:build ignore || darwin\n\npackage main\n", -- []string{"ignore"}, -- false, -- }, -- } -- -- for _, test := range tests { -- t.Run(test.desc, func(t *testing.T) { -- if got := isStandaloneFile([]byte(test.contents), test.standaloneTags); got != test.want { -- t.Errorf("isStandaloneFile(%q, %v) = %t, want %t", test.contents, test.standaloneTags, got, test.want) -- } -- }) -- } --} diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbols.go --- a/gopls/internal/lsp/cache/symbols.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/symbols.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,213 +0,0 @@ +@@ -1,192 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -22629,10 +26060,10 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo - "go/types" - "strings" - +- "golang.org/x/tools/gopls/internal/astutil" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/memoize" -) - -// symbolize returns the result of symbolizing the file identified by uri, using a cache. @@ -22649,7 +26080,7 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo - - // Cache miss? - if !hit { -- fh, err := s.GetFile(ctx, uri) +- fh, err := s.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -22668,7 +26099,7 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo - } - - // Await result. -- v, err := s.awaitPromise(ctx, entry.(*memoize.Promise)) +- v, err := s.awaitPromise(ctx, entry) - if err != nil { - return nil, err - } @@ -22677,10 +26108,8 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo -} - -// symbolizeImpl reads and parses a file and extracts symbols from it. --// It may use a parsed file already present in the cache but --// otherwise does not populate the cache. -func symbolizeImpl(ctx context.Context, snapshot *snapshot, fh source.FileHandle) ([]source.Symbol, error) { -- pgfs, _, err := snapshot.parseCache.parseFiles(ctx, source.ParseFull, fh) +- pgfs, err := snapshot.view.parseCache.parseFiles(ctx, token.NewFileSet(), source.ParseFull, false, fh) - if err != nil { - return nil, err - } @@ -22740,7 +26169,7 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo - var recv *ast.Ident - if decl.Recv.NumFields() > 0 { - kind = protocol.Method -- recv = unpackRecv(decl.Recv.List[0].Type) +- _, recv, _ = astutil.UnpackRecv(decl.Recv.List[0].Type) - } - w.atNode(decl.Name, decl.Name.Name, kind, recv) - case *ast.GenDecl: @@ -22776,25 +26205,6 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo - return protocol.Class -} - --func unpackRecv(rtyp ast.Expr) *ast.Ident { -- // Extract the receiver identifier. Lifted from go/types/resolver.go --L: -- for { -- switch t := rtyp.(type) { -- case *ast.ParenExpr: -- rtyp = t.X -- case *ast.StarExpr: -- rtyp = t.X -- default: -- break L -- } -- } -- if name, _ := rtyp.(*ast.Ident); name != nil { -- return name -- } -- return nil --} -- -// walkType processes symbols related to a type expression. path is path of -// nested type identifiers to the type expression. -func (w *symbolWalker) walkType(typ ast.Expr, path ...*ast.Ident) { @@ -22832,7 +26242,7 @@ diff -urN a/gopls/internal/lsp/cache/symbols.go b/gopls/internal/lsp/cache/symbo diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go --- a/gopls/internal/lsp/cache/view.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/view.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1142 +0,0 @@ +@@ -1,1282 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -22846,7 +26256,6 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - "encoding/json" - "errors" - "fmt" -- "io/ioutil" - "os" - "path" - "path/filepath" @@ -22902,8 +26311,11 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - vulnsMu sync.Mutex - vulns map[span.URI]*govulncheck.Result - +- // parseCache holds an LRU cache of recently parsed files. +- parseCache *parseCache +- - // fs is the file source used to populate this view. -- fs source.FileSource +- fs *overlayFS - - // seenFiles tracks files that the view has accessed. - // TODO(golang/go#57558): this notion is fundamentally problematic, and @@ -22965,6 +26377,10 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - // GOPACKAGESDRIVER environment variable or a gopackagesdriver binary on - // their machine. - hasGopackagesDriver bool +- +- // inGOPATH reports whether the workspace directory is contained in a GOPATH +- // directory. +- inGOPATH bool -} - -// effectiveGO111MODULE reports the value of GO111MODULE effective in the go @@ -22980,13 +26396,89 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - } -} - --// effectiveGOWORK returns the effective GOWORK value for this workspace, if +-// A ViewType describes how we load package information for a view. +-// +-// This is used for constructing the go/packages.Load query, and for +-// interpreting missing packages, imports, or errors. +-// +-// Each view has a ViewType which is derived from its immutable workspace +-// information -- any environment change that would affect the view type +-// results in a new view. +-type ViewType int +- +-const ( +- // GoPackagesDriverView is a view with a non-empty GOPACKAGESDRIVER +- // environment variable. +- GoPackagesDriverView ViewType = iota +- +- // GOPATHView is a view in GOPATH mode. +- // +- // I.e. in GOPATH, with GO111MODULE=off, or GO111MODULE=auto with no +- // go.mod file. +- GOPATHView +- +- // GoModuleView is a view in module mode with a single Go module. +- GoModuleView +- +- // GoWorkView is a view in module mode with a go.work file. +- GoWorkView +- +- // An AdHocView is a collection of files in a given directory, not in GOPATH +- // or a module. +- AdHocView +-) +- +-// ViewType derives the type of the view from its workspace information. +-// +-// TODO(rfindley): this logic is overlapping and slightly inconsistent with +-// validBuildConfiguration. As part of zero-config-gopls (golang/go#57979), fix +-// this inconsistency and consolidate on the ViewType abstraction. +-func (w workspaceInformation) ViewType() ViewType { +- if w.hasGopackagesDriver { +- return GoPackagesDriverView +- } +- go111module := w.effectiveGO111MODULE() +- if w.gowork != "" && go111module != off { +- return GoWorkView +- } +- if w.gomod != "" && go111module != off { +- return GoModuleView +- } +- if w.inGOPATH && go111module != on { +- return GOPATHView +- } +- return AdHocView +-} +- +-// moduleMode reports whether the current snapshot uses Go modules. +-// +-// From https://go.dev/ref/mod, module mode is active if either of the +-// following hold: +-// - GO111MODULE=on +-// - GO111MODULE=auto and we are inside a module or have a GOWORK value. +-// +-// Additionally, this method returns false if GOPACKAGESDRIVER is set. +-// +-// TODO(rfindley): use this more widely. +-func (w workspaceInformation) moduleMode() bool { +- switch w.ViewType() { +- case GoModuleView, GoWorkView: +- return true +- default: +- return false +- } +-} +- +-// GOWORK returns the effective GOWORK value for this workspace, if -// any, in URI form. --func (w workspaceInformation) effectiveGOWORK() span.URI { +-// +-// The second result reports whether the effective GOWORK value is "" because +-// GOWORK=off. +-func (w workspaceInformation) GOWORK() (span.URI, bool) { - if w.gowork == "off" || w.gowork == "" { -- return "" +- return "", w.gowork == "off" - } -- return span.URIFromPath(w.gowork) +- return span.URIFromPath(w.gowork), false -} - -// GO111MODULE returns the value of GO111MODULE to use for running the go @@ -23103,7 +26595,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go -// longer needed. -func tempModFile(modFh source.FileHandle, gosum []byte) (tmpURI span.URI, cleanup func(), err error) { - filenameHash := source.Hashf("%s", modFh.URI().Filename()) -- tmpMod, err := ioutil.TempFile("", fmt.Sprintf("go.%s.*.mod", filenameHash)) +- tmpMod, err := os.CreateTemp("", fmt.Sprintf("go.%s.*.mod", filenameHash)) - if err != nil { - return "", nil, err - } @@ -23112,7 +26604,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - tmpURI = span.URIFromPath(tmpMod.Name()) - tmpSumName := sumFilename(tmpURI) - -- content, err := modFh.Read() +- content, err := modFh.Content() - if err != nil { - return "", nil, err - } @@ -23138,7 +26630,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - - // Create an analogous go.sum, if one exists. - if gosum != nil { -- if err := ioutil.WriteFile(tmpSumName, gosum, 0655); err != nil { +- if err := os.WriteFile(tmpSumName, gosum, 0655); err != nil { - return "", nil, err - } - } @@ -23256,7 +26748,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - v.folder.Filename(), - v.workingDir().Filename(), - strings.TrimRight(v.workspaceInformation.goversionOutput, "\n"), -- v.snapshot.ValidBuildConfiguration(), +- v.snapshot.validBuildConfiguration(), - buildFlags, - v.goEnv, - ) @@ -23271,7 +26763,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - return buf.String() -} - --func (s *snapshot) RunProcessEnvFunc(ctx context.Context, fn func(*imports.Options) error) error { +-func (s *snapshot) RunProcessEnvFunc(ctx context.Context, fn func(context.Context, *imports.Options) error) error { - return s.view.importsState.runProcessEnvFunc(ctx, s, fn) -} - @@ -23324,7 +26816,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - // - // Furthermore, this operation must ignore errors, including context - // cancellation, or risk leaving the snapshot in an undefined state. -- s.GetFile(ctx, uri) +- s.ReadFile(ctx, uri) - return nil - }) - if err != nil { @@ -23375,7 +26867,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - // - // TODO(rfindley): Make sure the go.work files are always known - // to the view. -- if c.URI == v.effectiveGOWORK() { +- if gowork, _ := v.GOWORK(); gowork == c.URI { - return true - } - @@ -23412,6 +26904,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - - v.snapshotMu.Lock() - if v.snapshot != nil { +- v.snapshot.cancel() - v.releaseSnapshot() - v.destroy(v.snapshot, "View.shutdown") - v.snapshot = nil @@ -23422,22 +26915,57 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - v.snapshotWG.Wait() -} - +-// While go list ./... skips directories starting with '.', '_', or 'testdata', +-// gopls may still load them via file queries. Explicitly filter them out. -func (s *snapshot) IgnoredFile(uri span.URI) bool { -- filename := uri.Filename() -- var prefixes []string -- if len(s.workspaceModFiles) == 0 { -- for _, entry := range filepath.SplitList(s.view.gopath) { -- prefixes = append(prefixes, filepath.Join(entry, "src")) +- // Fast path: if uri doesn't contain '.', '_', or 'testdata', it is not +- // possible that it is ignored. +- { +- uriStr := string(uri) +- if !strings.Contains(uriStr, ".") && !strings.Contains(uriStr, "_") && !strings.Contains(uriStr, "testdata") { +- return false - } -- } else { -- prefixes = append(prefixes, s.view.gomodcache) -- for m := range s.workspaceModFiles { -- prefixes = append(prefixes, span.Dir(m).Filename()) +- } +- +- s.ignoreFilterOnce.Do(func() { +- var dirs []string +- if len(s.workspaceModFiles) == 0 { +- for _, entry := range filepath.SplitList(s.view.gopath) { +- dirs = append(dirs, filepath.Join(entry, "src")) +- } +- } else { +- dirs = append(dirs, s.view.gomodcache) +- for m := range s.workspaceModFiles { +- dirs = append(dirs, filepath.Dir(m.Filename())) +- } - } +- s.ignoreFilter = newIgnoreFilter(dirs) +- }) +- +- return s.ignoreFilter.ignored(uri.Filename()) +-} +- +-// An ignoreFilter implements go list's exclusion rules via its 'ignored' method. +-type ignoreFilter struct { +- prefixes []string // root dirs, ending in filepath.Separator +-} +- +-// newIgnoreFilter returns a new ignoreFilter implementing exclusion rules +-// relative to the provided directories. +-func newIgnoreFilter(dirs []string) *ignoreFilter { +- f := new(ignoreFilter) +- for _, d := range dirs { +- f.prefixes = append(f.prefixes, filepath.Clean(d)+string(filepath.Separator)) - } -- for _, prefix := range prefixes { -- if strings.HasPrefix(filename, prefix) { -- return checkIgnored(filename[len(prefix):]) +- return f +-} +- +-func (f *ignoreFilter) ignored(filename string) bool { +- for _, prefix := range f.prefixes { +- if suffix := strings.TrimPrefix(filename, prefix); suffix != filename { +- if checkIgnored(suffix) { +- return true +- } - } - } - return false @@ -23449,6 +26977,8 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go -// Directory and file names that begin with "." or "_" are ignored -// by the go tool, as are directories named "testdata". -func checkIgnored(suffix string) bool { +- // Note: this could be further optimized by writing a HasSegment helper, a +- // segment-boundary respecting variant of strings.Contains. - for _, component := range strings.Split(suffix, string(filepath.Separator)) { - if len(component) == 0 { - continue @@ -23534,30 +27064,43 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - }) - } - +- // TODO(rfindley): this should be predicated on the s.view.moduleMode(). +- // There is no point loading ./... if we have an empty go.work. - if len(s.workspaceModFiles) > 0 { - for modURI := range s.workspaceModFiles { +- // Verify that the modfile is valid before trying to load it. +- // +- // TODO(rfindley): now that we no longer need to parse the modfile in +- // order to load scope, we could move these diagnostics to a more general +- // location where we diagnose problems with modfiles or the workspace. +- // - // Be careful not to add context cancellation errors as critical module - // errors. -- fh, err := s.GetFile(ctx, modURI) +- fh, err := s.ReadFile(ctx, modURI) - if err != nil { -- if ctx.Err() == nil { -- addError(modURI, err) +- if ctx.Err() != nil { +- return ctx.Err() - } +- addError(modURI, err) - continue - } - parsed, err := s.ParseMod(ctx, fh) - if err != nil { -- if ctx.Err() == nil { -- addError(modURI, err) +- if ctx.Err() != nil { +- return ctx.Err() - } +- addError(modURI, err) - continue - } - if parsed.File == nil || parsed.File.Module == nil { - addError(modURI, fmt.Errorf("no module path for %s", modURI)) - continue - } -- path := parsed.File.Module.Mod.Path -- scopes = append(scopes, moduleLoadScope(path)) +- moduleDir := filepath.Dir(modURI.Filename()) +- // Previously, we loaded /... for each module path, but that +- // is actually incorrect when the pattern may match packages in more than +- // one module. See golang/go#59458 for more details. +- scopes = append(scopes, moduleLoadScope{dir: moduleDir, modulePath: parsed.File.Module.Mod.Path}) - } - } else { - scopes = append(scopes, viewLoadScope("LOAD_VIEW")) @@ -23662,7 +27205,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - if err != nil { - return info, err - } -- if err := info.goEnv.load(ctx, folder.Filename(), options.EnvSlice(), s.gocmdRunner); err != nil { +- if err := info.load(ctx, folder.Filename(), options.EnvSlice(), s.gocmdRunner); err != nil { - return info, err - } - // The value of GOPACKAGESDRIVER is not returned through the go command. @@ -23680,6 +27223,13 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - return info, err - } - +- // Check if the workspace is within any GOPATH directory. +- for _, gp := range filepath.SplitList(info.gopath) { +- if source.InDir(filepath.Join(gp, "src"), folder.Filename()) { +- info.inGOPATH = true +- break +- } +- } - return info, nil -} - @@ -23734,7 +27284,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go - // TODO(golang/go#57514): eliminate the expandWorkspaceToModule setting - // entirely. - if v.Options().ExpandWorkspaceToModule && v.gomod != "" { -- return span.Dir(v.gomod) +- return span.URIFromPath(filepath.Dir(v.gomod.Filename())) - } - return v.folder -} @@ -23978,7 +27528,7 @@ diff -urN a/gopls/internal/lsp/cache/view.go b/gopls/internal/lsp/cache/view.go diff -urN a/gopls/internal/lsp/cache/view_test.go b/gopls/internal/lsp/cache/view_test.go --- a/gopls/internal/lsp/cache/view_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/view_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,278 +0,0 @@ +@@ -1,303 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -23987,7 +27537,6 @@ diff -urN a/gopls/internal/lsp/cache/view_test.go b/gopls/internal/lsp/cache/vie -import ( - "context" - "encoding/json" -- "io/ioutil" - "os" - "path/filepath" - "testing" @@ -24001,17 +27550,14 @@ diff -urN a/gopls/internal/lsp/cache/view_test.go b/gopls/internal/lsp/cache/vie -) - -func TestCaseInsensitiveFilesystem(t *testing.T) { -- base, err := ioutil.TempDir("", t.Name()) -- if err != nil { -- t.Fatal(err) -- } +- base := t.TempDir() - - inner := filepath.Join(base, "a/B/c/DEFgh") - if err := os.MkdirAll(inner, 0777); err != nil { - t.Fatal(err) - } - file := filepath.Join(inner, "f.go") -- if err := ioutil.WriteFile(file, []byte("hi"), 0777); err != nil { +- if err := os.WriteFile(file, []byte("hi"), 0777); err != nil { - t.Fatal(err) - } - if _, err := os.Stat(filepath.Join(inner, "F.go")); err != nil { @@ -24257,10 +27803,39 @@ diff -urN a/gopls/internal/lsp/cache/view_test.go b/gopls/internal/lsp/cache/vie - b, _ := json.MarshalIndent(x, "", " ") - return string(b) -} +- +-func TestIgnoreFilter(t *testing.T) { +- tests := []struct { +- dirs []string +- path string +- want bool +- }{ +- {[]string{"a"}, "a/testdata/foo", true}, +- {[]string{"a"}, "a/_ignore/foo", true}, +- {[]string{"a"}, "a/.ignore/foo", true}, +- {[]string{"a"}, "b/testdata/foo", false}, +- {[]string{"a"}, "testdata/foo", false}, +- {[]string{"a", "b"}, "b/testdata/foo", true}, +- {[]string{"a"}, "atestdata/foo", false}, +- } +- +- for _, test := range tests { +- // convert to filepaths, for convenience +- for i, dir := range test.dirs { +- test.dirs[i] = filepath.FromSlash(dir) +- } +- test.path = filepath.FromSlash(test.path) +- +- f := newIgnoreFilter(test.dirs) +- if got := f.ignored(test.path); got != test.want { +- t.Errorf("newIgnoreFilter(%q).ignore(%q) = %t, want %t", test.dirs, test.path, got, test.want) +- } +- } +-} diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/workspace.go --- a/gopls/internal/lsp/cache/workspace.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cache/workspace.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,177 +0,0 @@ +@@ -1,181 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -24271,6 +27846,7 @@ diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/wor - "context" - "errors" - "fmt" +- "io/fs" - "os" - "path/filepath" - "sort" @@ -24291,11 +27867,11 @@ diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/wor - return nil, nil - } - if gowork != "" { -- fh, err := fs.GetFile(ctx, gowork) +- fh, err := fs.ReadFile(ctx, gowork) - if err != nil { - return nil, err - } -- content, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return nil, err - } @@ -24366,16 +27942,16 @@ diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/wor - -// fileExists reports if the file uri exists within source. -func fileExists(ctx context.Context, uri span.URI, source source.FileSource) (bool, error) { -- fh, err := source.GetFile(ctx, uri) +- fh, err := source.ReadFile(ctx, uri) - if err != nil { - return false, err - } - return fileHandleExists(fh) -} - --// fileHandleExists reports if the file underlying fh actually exits. +-// fileHandleExists reports if the file underlying fh actually exists. -func fileHandleExists(fh source.FileHandle) (bool, error) { -- _, err := fh.Read() +- _, err := fh.Content() - if err == nil { - return true, nil - } @@ -24390,7 +27966,10 @@ diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/wor - -// Limit go.mod search to 1 million files. As a point of reference, -// Kubernetes has 22K files (as of 2020-11-24). --const fileLimit = 1000000 +-// +-// Note: per golang/go#56496, the previous limit of 1M files was too slow, at +-// which point this limit was decreased to 100K. +-const fileLimit = 100_000 - -// findModules recursively walks the root directory looking for go.mod files, -// returning the set of modules it discovers. If modLimit is non-zero, @@ -24402,7 +27981,7 @@ diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/wor - modFiles := make(map[span.URI]struct{}) - searched := 0 - errDone := errors.New("done") -- err := filepath.Walk(root.Filename(), func(path string, info os.FileInfo, err error) error { +- err := filepath.WalkDir(root.Filename(), func(path string, info fs.DirEntry, err error) error { - if err != nil { - // Probably a permission error. Keep looking. - return filepath.SkipDir @@ -24441,7 +28020,7 @@ diff -urN a/gopls/internal/lsp/cache/workspace.go b/gopls/internal/lsp/cache/wor diff -urN a/gopls/internal/lsp/call_hierarchy.go b/gopls/internal/lsp/call_hierarchy.go --- a/gopls/internal/lsp/call_hierarchy.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/call_hierarchy.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,42 +0,0 @@ +@@ -1,52 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -24453,9 +28032,13 @@ diff -urN a/gopls/internal/lsp/call_hierarchy.go b/gopls/internal/lsp/call_hiera - - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" -) - -func (s *Server) prepareCallHierarchy(ctx context.Context, params *protocol.CallHierarchyPrepareParams) ([]protocol.CallHierarchyItem, error) { +- ctx, done := event.Start(ctx, "lsp.Server.prepareCallHierarchy") +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { @@ -24466,6 +28049,9 @@ diff -urN a/gopls/internal/lsp/call_hierarchy.go b/gopls/internal/lsp/call_hiera -} - -func (s *Server) incomingCalls(ctx context.Context, params *protocol.CallHierarchyIncomingCallsParams) ([]protocol.CallHierarchyIncomingCall, error) { +- ctx, done := event.Start(ctx, "lsp.Server.incomingCalls") +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.Item.URI, source.Go) - defer release() - if !ok { @@ -24476,6 +28062,9 @@ diff -urN a/gopls/internal/lsp/call_hierarchy.go b/gopls/internal/lsp/call_hiera -} - -func (s *Server) outgoingCalls(ctx context.Context, params *protocol.CallHierarchyOutgoingCallsParams) ([]protocol.CallHierarchyOutgoingCall, error) { +- ctx, done := event.Start(ctx, "lsp.Server.outgoingCalls") +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.Item.URI, source.Go) - defer release() - if !ok { @@ -24487,7 +28076,7 @@ diff -urN a/gopls/internal/lsp/call_hierarchy.go b/gopls/internal/lsp/call_hiera diff -urN a/gopls/internal/lsp/cmd/call_hierarchy.go b/gopls/internal/lsp/cmd/call_hierarchy.go --- a/gopls/internal/lsp/cmd/call_hierarchy.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/call_hierarchy.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,142 +0,0 @@ +@@ -1,144 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -24530,16 +28119,16 @@ diff -urN a/gopls/internal/lsp/cmd/call_hierarchy.go b/gopls/internal/lsp/cmd/ca - return tool.CommandLineErrorf("call_hierarchy expects 1 argument (position)") - } - -- conn, err := c.app.connect(ctx) +- conn, err := c.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - - loc, err := file.mapper.SpanLocation(from) @@ -24601,27 +28190,29 @@ diff -urN a/gopls/internal/lsp/cmd/call_hierarchy.go b/gopls/internal/lsp/cmd/ca -// callItemPrintString returns a protocol.CallHierarchyItem object represented as a string. -// item and call ranges (protocol.Range) are converted to user friendly spans (1-indexed). -func callItemPrintString(ctx context.Context, conn *connection, item protocol.CallHierarchyItem, callsURI protocol.DocumentURI, calls []protocol.Range) (string, error) { -- itemFile := conn.openFile(ctx, item.URI.SpanURI()) -- if itemFile.err != nil { -- return "", itemFile.err +- itemFile, err := conn.openFile(ctx, item.URI.SpanURI()) +- if err != nil { +- return "", err - } -- itemSpan, err := itemFile.mapper.LocationSpan(protocol.Location{URI: item.URI, Range: item.Range}) +- itemSpan, err := itemFile.mapper.RangeSpan(item.Range) - if err != nil { - return "", err - } - -- callsFile := conn.openFile(ctx, callsURI.SpanURI()) -- if callsURI != "" && callsFile.err != nil { -- return "", callsFile.err -- } - var callRanges []string -- for _, rng := range calls { -- call, err := callsFile.mapper.RangeSpan(rng) +- if callsURI != "" { +- callsFile, err := conn.openFile(ctx, callsURI.SpanURI()) - if err != nil { - return "", err - } -- callRange := fmt.Sprintf("%d:%d-%d", call.Start().Line(), call.Start().Column(), call.End().Column()) -- callRanges = append(callRanges, callRange) +- for _, rng := range calls { +- call, err := callsFile.mapper.RangeSpan(rng) +- if err != nil { +- return "", err +- } +- callRange := fmt.Sprintf("%d:%d-%d", call.Start().Line(), call.Start().Column(), call.End().Column()) +- callRanges = append(callRanges, callRange) +- } - } - - printString := fmt.Sprintf("function %s in %v", item.Name, itemSpan) @@ -24633,7 +28224,7 @@ diff -urN a/gopls/internal/lsp/cmd/call_hierarchy.go b/gopls/internal/lsp/cmd/ca diff -urN a/gopls/internal/lsp/cmd/capabilities_test.go b/gopls/internal/lsp/cmd/capabilities_test.go --- a/gopls/internal/lsp/cmd/capabilities_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/capabilities_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,166 +0,0 @@ +@@ -1,175 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -24651,11 +28242,18 @@ diff -urN a/gopls/internal/lsp/cmd/capabilities_test.go b/gopls/internal/lsp/cmd - "golang.org/x/tools/gopls/internal/lsp" - "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/internal/testenv" -) - -// TestCapabilities does some minimal validation of the server's adherence to the LSP. -// The checks in the test are added as changes are made and errors noticed. -func TestCapabilities(t *testing.T) { +- // TODO(bcmills): This test fails on js/wasm, which is not unexpected, but the +- // failure mode is that the DidOpen call below reports "no views in session", +- // which seems a little too cryptic. +- // Is there some missing error reporting somewhere? +- testenv.NeedsTool(t, "go") +- - tmpDir, err := ioutil.TempDir("", "fake") - if err != nil { - t.Fatal(err) @@ -24670,17 +28268,16 @@ diff -urN a/gopls/internal/lsp/cmd/capabilities_test.go b/gopls/internal/lsp/cmd - defer os.RemoveAll(tmpDir) - - app := New("gopls-test", tmpDir, os.Environ(), nil) -- c := newConnection(app) -- ctx := context.Background() -- defer c.terminate(ctx) - - params := &protocol.ParamInitialize{} -- params.RootURI = protocol.URIFromPath(c.Client.app.wd) +- params.RootURI = protocol.URIFromPath(app.wd) - params.Capabilities.Workspace.Configuration = true - - // Send an initialize request to the server. -- c.Server = lsp.NewServer(cache.NewSession(ctx, cache.New(nil), app.options), c.Client) -- result, err := c.Server.Initialize(ctx, params) +- ctx := context.Background() +- client := newClient(app, nil) +- server := lsp.NewServer(cache.NewSession(ctx, cache.New(nil), app.options), client) +- result, err := server.Initialize(ctx, params) - if err != nil { - t.Fatal(err) - } @@ -24689,10 +28286,13 @@ diff -urN a/gopls/internal/lsp/cmd/capabilities_test.go b/gopls/internal/lsp/cmd - t.Error(err) - } - // Complete initialization of server. -- if err := c.Server.Initialized(ctx, &protocol.InitializedParams{}); err != nil { +- if err := server.Initialized(ctx, &protocol.InitializedParams{}); err != nil { - t.Fatal(err) - } - +- c := newConnection(server, client) +- defer c.terminate(ctx) +- - // Open the file on the server side. - uri := protocol.URIFromPath(tmpFile) - if err := c.Server.DidOpen(ctx, &protocol.DidOpenTextDocumentParams{ @@ -24846,7 +28446,7 @@ diff -urN a/gopls/internal/lsp/cmd/check.go b/gopls/internal/lsp/cmd/check.go - checking := map[span.URI]*cmdFile{} - var uris []span.URI - // now we ready to kick things off -- conn, err := c.app.connect(ctx) +- conn, err := c.app.connect(ctx, nil) - if err != nil { - return err - } @@ -24854,17 +28454,17 @@ diff -urN a/gopls/internal/lsp/cmd/check.go b/gopls/internal/lsp/cmd/check.go - for _, arg := range args { - uri := span.URIFromPath(arg) - uris = append(uris, uri) -- file := conn.openFile(ctx, uri) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, uri) +- if err != nil { +- return err - } - checking[uri] = file - } - if err := conn.diagnoseFiles(ctx, uris); err != nil { - return err - } -- conn.Client.filesMu.Lock() -- defer conn.Client.filesMu.Unlock() +- conn.client.filesMu.Lock() +- defer conn.client.filesMu.Unlock() - - for _, file := range checking { - for _, d := range file.diagnostics { @@ -24880,7 +28480,7 @@ diff -urN a/gopls/internal/lsp/cmd/check.go b/gopls/internal/lsp/cmd/check.go diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go --- a/gopls/internal/lsp/cmd/cmd.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/cmd.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,640 +0,0 @@ +@@ -1,794 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -24905,12 +28505,15 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - "time" - - "golang.org/x/tools/gopls/internal/lsp" +- "golang.org/x/tools/gopls/internal/lsp/browser" - "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/debug" +- "golang.org/x/tools/gopls/internal/lsp/filecache" - "golang.org/x/tools/gopls/internal/lsp/lsprpc" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/diff" - "golang.org/x/tools/internal/jsonrpc2" - "golang.org/x/tools/internal/tool" - "golang.org/x/tools/internal/xcontext" @@ -24956,6 +28559,26 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - // PrepareOptions is called to update the options when a new view is built. - // It is primarily to allow the behavior of gopls to be modified by hooks. - PrepareOptions func(*source.Options) +- +- // editFlags holds flags that control how file edit operations +- // are applied, in particular when the server makes an ApplyEdits +- // downcall to the client. Present only for commands that apply edits. +- editFlags *EditFlags +-} +- +-// EditFlags defines flags common to {fix,format,imports,rename} +-// that control how edits are applied to the client's files. +-// +-// The type is exported for flag reflection. +-// +-// The -write, -diff, and -list flags are orthogonal but any +-// of them suppresses the default behavior, which is to print +-// the edited file contents. +-type EditFlags struct { +- Write bool `flag:"w,write" help:"write edited content to source files"` +- Preserve bool `flag:"preserve" help:"with -write, make copies of original files"` +- Diff bool `flag:"d,diff" help:"display diffs instead of edited file content"` +- List bool `flag:"l,list" help:"display names of edited files"` -} - -func (app *Application) verbose() bool { @@ -25097,6 +28720,11 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go -// If no arguments are passed it will invoke the server sub command, as a -// temporary measure for compatibility. -func (app *Application) Run(ctx context.Context, args ...string) error { +- // In the category of "things we can do while waiting for the Go command": +- // Pre-initialize the filecache, which takes ~50ms to hash the gopls +- // executable, and immediately runs a gc. +- filecache.Start() +- - ctx = debug.WithInstance(ctx, app.wd, app.OCAgent) - if len(args) == 0 { - s := flag.NewFlagSet(app.Name(), flag.ExitOnError) @@ -25151,6 +28779,7 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - &rename{app: app}, - &semtok{app: app}, - &signature{app: app}, +- &stats{app: app}, - &suggestedFix{app: app}, - &symbols{app: app}, - &workspaceSymbol{app: app}, @@ -25163,13 +28792,20 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - internalConnections = make(map[string]*connection) -) - --func (app *Application) connect(ctx context.Context) (*connection, error) { +-// connect creates and initializes a new in-process gopls session. +-// +-// If onProgress is set, it is called for each new progress notification. +-func (app *Application) connect(ctx context.Context, onProgress func(*protocol.ProgressParams)) (*connection, error) { - switch { - case app.Remote == "": -- connection := newConnection(app) -- connection.Server = lsp.NewServer(cache.NewSession(ctx, cache.New(nil), app.options), connection.Client) -- ctx = protocol.WithClient(ctx, connection.Client) -- return connection, connection.initialize(ctx, app.options) +- client := newClient(app, onProgress) +- server := lsp.NewServer(cache.NewSession(ctx, cache.New(nil), app.options), client) +- conn := newConnection(server, client) +- if err := conn.initialize(protocol.WithClient(ctx, client), app.options); err != nil { +- return nil, err +- } +- return conn, nil +- - case strings.HasPrefix(app.Remote, "internal@"): - internalMu.Lock() - defer internalMu.Unlock() @@ -25194,29 +28830,20 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - } -} - --// CloseTestConnections terminates shared connections used in command tests. It --// should only be called from tests. --func CloseTestConnections(ctx context.Context) { -- for _, c := range internalConnections { -- c.Shutdown(ctx) -- c.Exit(ctx) -- } --} -- -func (app *Application) connectRemote(ctx context.Context, remote string) (*connection, error) { -- connection := newConnection(app) - conn, err := lsprpc.ConnectToRemote(ctx, remote) - if err != nil { - return nil, err - } - stream := jsonrpc2.NewHeaderStream(conn) - cc := jsonrpc2.NewConn(stream) -- connection.Server = protocol.ServerDispatcher(cc) -- ctx = protocol.WithClient(ctx, connection.Client) +- server := protocol.ServerDispatcher(cc) +- client := newClient(app, nil) +- connection := newConnection(server, client) +- ctx = protocol.WithClient(ctx, connection.client) - cc.Go(ctx, - protocol.Handlers( -- protocol.ClientHandler(connection.Client, -- jsonrpc2.MethodNotFound))) +- protocol.ClientHandler(client, jsonrpc2.MethodNotFound))) - return connection, connection.initialize(ctx, app.options) -} - @@ -25228,7 +28855,7 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - -func (c *connection) initialize(ctx context.Context, options func(*source.Options)) error { - params := &protocol.ParamInitialize{} -- params.RootURI = protocol.URIFromPath(c.Client.app.wd) +- params.RootURI = protocol.URIFromPath(c.client.app.wd) - params.Capabilities.Workspace.Configuration = true - - // Make sure to respect configured options when sending initialize request. @@ -25247,6 +28874,13 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - params.Capabilities.TextDocument.SemanticTokens.Requests.Full.Value = true - params.Capabilities.TextDocument.SemanticTokens.TokenTypes = lsp.SemanticTypes() - params.Capabilities.TextDocument.SemanticTokens.TokenModifiers = lsp.SemanticModifiers() +- +- // If the subcommand has registered a progress handler, report the progress +- // capability. +- if c.client.onProgress != nil { +- params.Capabilities.Window.WorkDoneProgress = true +- } +- - params.InitializationOptions = map[string]interface{}{ - "symbolMatcher": matcherString[opts.SymbolMatcher], - } @@ -25261,17 +28895,18 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - -type connection struct { - protocol.Server -- Client *cmdClient +- client *cmdClient -} - +-// cmdClient defines the protocol.Client interface behavior of the gopls CLI tool. -type cmdClient struct { -- protocol.Server -- app *Application +- app *Application +- onProgress func(*protocol.ProgressParams) - - diagnosticsMu sync.Mutex - diagnosticsDone chan struct{} - -- filesMu sync.Mutex +- filesMu sync.Mutex // guards files map and each cmdFile.diagnostics - files map[span.URI]*cmdFile -} - @@ -25279,16 +28914,21 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - uri span.URI - mapper *protocol.Mapper - err error -- open bool - diagnostics []protocol.Diagnostic -} - --func newConnection(app *Application) *connection { +-func newClient(app *Application, onProgress func(*protocol.ProgressParams)) *cmdClient { +- return &cmdClient{ +- app: app, +- onProgress: onProgress, +- files: make(map[span.URI]*cmdFile), +- } +-} +- +-func newConnection(server protocol.Server, client *cmdClient) *connection { - return &connection{ -- Client: &cmdClient{ -- app: app, -- files: make(map[span.URI]*cmdFile), -- }, +- Server: server, +- client: client, - } -} - @@ -25379,7 +29019,87 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go -} - -func (c *cmdClient) ApplyEdit(ctx context.Context, p *protocol.ApplyWorkspaceEditParams) (*protocol.ApplyWorkspaceEditResult, error) { -- return &protocol.ApplyWorkspaceEditResult{Applied: false, FailureReason: "not implemented"}, nil +- if err := c.applyWorkspaceEdit(&p.Edit); err != nil { +- return &protocol.ApplyWorkspaceEditResult{FailureReason: err.Error()}, nil +- } +- return &protocol.ApplyWorkspaceEditResult{Applied: true}, nil +-} +- +-// applyWorkspaceEdit applies a complete WorkspaceEdit to the client's +-// files, honoring the preferred edit mode specified by cli.app.editMode. +-// (Used by rename and by ApplyEdit downcalls.) +-func (cli *cmdClient) applyWorkspaceEdit(edit *protocol.WorkspaceEdit) error { +- var orderedURIs []string +- edits := map[span.URI][]protocol.TextEdit{} +- for _, c := range edit.DocumentChanges { +- if c.TextDocumentEdit != nil { +- uri := fileURI(c.TextDocumentEdit.TextDocument.URI) +- edits[uri] = append(edits[uri], c.TextDocumentEdit.Edits...) +- orderedURIs = append(orderedURIs, string(uri)) +- } +- if c.RenameFile != nil { +- return fmt.Errorf("client does not support file renaming (%s -> %s)", +- c.RenameFile.OldURI, +- c.RenameFile.NewURI) +- } +- } +- sort.Strings(orderedURIs) +- for _, u := range orderedURIs { +- uri := span.URIFromURI(u) +- f := cli.openFile(uri) +- if f.err != nil { +- return f.err +- } +- if err := applyTextEdits(f.mapper, edits[uri], cli.app.editFlags); err != nil { +- return err +- } +- } +- return nil +-} +- +-// applyTextEdits applies a list of edits to the mapper file content, +-// using the preferred edit mode. It is a no-op if there are no edits. +-func applyTextEdits(mapper *protocol.Mapper, edits []protocol.TextEdit, flags *EditFlags) error { +- if len(edits) == 0 { +- return nil +- } +- newContent, renameEdits, err := source.ApplyProtocolEdits(mapper, edits) +- if err != nil { +- return err +- } +- +- filename := mapper.URI.Filename() +- +- if flags.List { +- fmt.Println(filename) +- } +- +- if flags.Write { +- if flags.Preserve { +- if err := os.Rename(filename, filename+".orig"); err != nil { +- return err +- } +- } +- if err := os.WriteFile(filename, newContent, 0644); err != nil { +- return err +- } +- } +- +- if flags.Diff { +- unified, err := diff.ToUnified(filename+".orig", filename, string(mapper.Content), renameEdits) +- if err != nil { +- return err +- } +- fmt.Print(unified) +- } +- +- // No flags: just print edited file content. +- // TODO(adonovan): how is this ever useful with multiple files? +- if !(flags.List || flags.Write || flags.Diff) { +- os.Stdout.Write(newContent) +- } +- +- return nil -} - -func (c *cmdClient) PublishDiagnostics(ctx context.Context, p *protocol.PublishDiagnosticsParams) error { @@ -25394,17 +29114,52 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - c.filesMu.Lock() - defer c.filesMu.Unlock() - -- file := c.getFile(ctx, fileURI(p.URI)) -- file.diagnostics = p.Diagnostics +- file := c.getFile(fileURI(p.URI)) +- file.diagnostics = append(file.diagnostics, p.Diagnostics...) +- +- // Perform a crude in-place deduplication. +- // TODO(golang/go#60122): replace the ad-hoc gopls/diagnoseFiles +- // non-standard request with support for textDocument/diagnostic, +- // so that we don't need to do this de-duplication. +- type key [6]interface{} +- seen := make(map[key]bool) +- out := file.diagnostics[:0] +- for _, d := range file.diagnostics { +- var codeHref string +- if desc := d.CodeDescription; desc != nil { +- codeHref = desc.Href +- } +- k := key{d.Range, d.Severity, d.Code, codeHref, d.Source, d.Message} +- if !seen[k] { +- seen[k] = true +- out = append(out, d) +- } +- } +- file.diagnostics = out +- - return nil -} - --func (c *cmdClient) Progress(context.Context, *protocol.ProgressParams) error { +-func (c *cmdClient) Progress(_ context.Context, params *protocol.ProgressParams) error { +- if c.onProgress != nil { +- c.onProgress(params) +- } - return nil -} - --func (c *cmdClient) ShowDocument(context.Context, *protocol.ShowDocumentParams) (*protocol.ShowDocumentResult, error) { -- return nil, nil +-func (c *cmdClient) ShowDocument(ctx context.Context, params *protocol.ShowDocumentParams) (*protocol.ShowDocumentResult, error) { +- var success bool +- if params.External { +- // Open URI in external browser. +- success = browser.Open(string(params.URI)) +- } else { +- // Open file in editor, optionally taking focus and selecting a range. +- // (cmdClient has no editor. Should it fork+exec $EDITOR?) +- log.Printf("Server requested that client editor open %q (takeFocus=%t, selection=%+v)", +- params.URI, params.TakeFocus, params.Selection) +- success = true +- } +- return &protocol.ShowDocumentResult{Success: success}, nil -} - -func (c *cmdClient) WorkDoneProgressCreate(context.Context, *protocol.WorkDoneProgressCreateParams) error { @@ -25427,7 +29182,7 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - return nil -} - --func (c *cmdClient) getFile(ctx context.Context, uri span.URI) *cmdFile { +-func (c *cmdClient) getFile(uri span.URI) *cmdFile { - file, found := c.files[uri] - if !found || file.err != nil { - file = &cmdFile{ @@ -25446,22 +29201,19 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - return file -} - --func (c *cmdClient) openFile(ctx context.Context, uri span.URI) *cmdFile { +-func (c *cmdClient) openFile(uri span.URI) *cmdFile { - c.filesMu.Lock() - defer c.filesMu.Unlock() -- -- file := c.getFile(ctx, uri) -- if file.err != nil || file.open { -- return file -- } -- file.open = true -- return file +- return c.getFile(uri) -} - --func (c *connection) openFile(ctx context.Context, uri span.URI) *cmdFile { -- file := c.Client.openFile(ctx, uri) +-// TODO(adonovan): provide convenience helpers to: +-// - map a (URI, protocol.Range) to a MappedRange; +-// - parse a command-line argument to a MappedRange. +-func (c *connection) openFile(ctx context.Context, uri span.URI) (*cmdFile, error) { +- file := c.client.openFile(uri) - if file.err != nil { -- return file +- return nil, file.err - } - - p := &protocol.DidOpenTextDocumentParams{ @@ -25473,9 +29225,11 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - }, - } - if err := c.Server.DidOpen(ctx, p); err != nil { +- // TODO(adonovan): is this assignment concurrency safe? - file.err = fmt.Errorf("%v: %v", uri, err) +- return nil, file.err - } -- return file +- return file, nil -} - -func (c *connection) semanticTokens(ctx context.Context, p *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) { @@ -25492,22 +29246,22 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go - for _, file := range files { - untypedFiles = append(untypedFiles, string(file)) - } -- c.Client.diagnosticsMu.Lock() -- defer c.Client.diagnosticsMu.Unlock() +- c.client.diagnosticsMu.Lock() +- defer c.client.diagnosticsMu.Unlock() - -- c.Client.diagnosticsDone = make(chan struct{}) +- c.client.diagnosticsDone = make(chan struct{}) - _, err := c.Server.NonstandardRequest(ctx, "gopls/diagnoseFiles", map[string]interface{}{"files": untypedFiles}) - if err != nil { -- close(c.Client.diagnosticsDone) +- close(c.client.diagnosticsDone) - return err - } - -- <-c.Client.diagnosticsDone +- <-c.client.diagnosticsDone - return nil -} - -func (c *connection) terminate(ctx context.Context) { -- if strings.HasPrefix(c.Client.app.Remote, "internal@") { +- if strings.HasPrefix(c.client.app.Remote, "internal@") { - // internal connections need to be left alive for the next test - return - } @@ -25524,7 +29278,7 @@ diff -urN a/gopls/internal/lsp/cmd/cmd.go b/gopls/internal/lsp/cmd/cmd.go diff -urN a/gopls/internal/lsp/cmd/definition.go b/gopls/internal/lsp/cmd/definition.go --- a/gopls/internal/lsp/cmd/definition.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/definition.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,132 +0,0 @@ +@@ -1,138 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -25601,15 +29355,15 @@ diff -urN a/gopls/internal/lsp/cmd/definition.go b/gopls/internal/lsp/cmd/defini - o.PreferredContentFormat = protocol.Markdown - } - } -- conn, err := d.app.connect(ctx) +- conn, err := d.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - loc, err := file.mapper.SpanLocation(from) - if err != nil { @@ -25626,25 +29380,27 @@ diff -urN a/gopls/internal/lsp/cmd/definition.go b/gopls/internal/lsp/cmd/defini - if len(locs) == 0 { - return fmt.Errorf("%v: not an identifier", from) - } -- q := protocol.HoverParams{ -- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), -- } -- hover, err := conn.Hover(ctx, &q) +- file, err = conn.openFile(ctx, fileURI(locs[0].URI)) - if err != nil { - return fmt.Errorf("%v: %v", from, err) - } -- if hover == nil { -- return fmt.Errorf("%v: not an identifier", from) +- definition, err := file.mapper.LocationSpan(locs[0]) +- if err != nil { +- return fmt.Errorf("%v: %v", from, err) - } -- file = conn.openFile(ctx, fileURI(locs[0].URI)) -- if file.err != nil { -- return fmt.Errorf("%v: %v", from, file.err) +- +- q := protocol.HoverParams{ +- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), - } -- definition, err := file.mapper.LocationSpan(locs[0]) +- hover, err := conn.Hover(ctx, &q) - if err != nil { - return fmt.Errorf("%v: %v", from, err) - } -- description := strings.TrimSpace(hover.Contents.Value) +- var description string +- if hover != nil { +- description = strings.TrimSpace(hover.Contents.Value) +- } +- - result := &Definition{ - Span: definition, - Description: description, @@ -25654,13 +29410,17 @@ diff -urN a/gopls/internal/lsp/cmd/definition.go b/gopls/internal/lsp/cmd/defini - enc.SetIndent("", "\t") - return enc.Encode(result) - } -- fmt.Printf("%v: defined here as %s", result.Span, result.Description) +- fmt.Printf("%v", result.Span) +- if len(result.Description) > 0 { +- fmt.Printf(": defined here as %s", result.Description) +- } +- fmt.Printf("\n") - return nil -} diff -urN a/gopls/internal/lsp/cmd/folding_range.go b/gopls/internal/lsp/cmd/folding_range.go --- a/gopls/internal/lsp/cmd/folding_range.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/folding_range.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,73 +0,0 @@ +@@ -1,72 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -25700,16 +29460,15 @@ diff -urN a/gopls/internal/lsp/cmd/folding_range.go b/gopls/internal/lsp/cmd/fol - return tool.CommandLineErrorf("folding_ranges expects 1 argument (file)") - } - -- conn, err := r.app.connect(ctx) +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- if _, err := conn.openFile(ctx, from.URI()); err != nil { +- return err - } - - p := protocol.FoldingRangeParams{ @@ -25737,7 +29496,7 @@ diff -urN a/gopls/internal/lsp/cmd/folding_range.go b/gopls/internal/lsp/cmd/fol diff -urN a/gopls/internal/lsp/cmd/format.go b/gopls/internal/lsp/cmd/format.go --- a/gopls/internal/lsp/cmd/format.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/format.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,110 +0,0 @@ +@@ -1,76 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -25748,21 +29507,14 @@ diff -urN a/gopls/internal/lsp/cmd/format.go b/gopls/internal/lsp/cmd/format.go - "context" - "flag" - "fmt" -- "io/ioutil" -- "os" - - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/diff" -) - -// format implements the format verb for gopls. -type format struct { -- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"` -- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"` -- List bool `flag:"l,list" help:"list files whose formatting differs from gofmt's"` -- +- EditFlags - app *Application -} - @@ -25787,22 +29539,20 @@ diff -urN a/gopls/internal/lsp/cmd/format.go b/gopls/internal/lsp/cmd/format.go -// results to stdout. -func (c *format) Run(ctx context.Context, args ...string) error { - if len(args) == 0 { -- // no files, so no results - return nil - } -- // now we ready to kick things off -- conn, err := c.app.connect(ctx) +- c.app.editFlags = &c.EditFlags +- conn, err := c.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - for _, arg := range args { - spn := span.Parse(arg) -- file := conn.openFile(ctx, spn.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, spn.URI()) +- if err != nil { +- return err - } -- filename := spn.URI().Filename() - loc, err := file.mapper.SpanLocation(spn) - if err != nil { - return err @@ -25817,33 +29567,8 @@ diff -urN a/gopls/internal/lsp/cmd/format.go b/gopls/internal/lsp/cmd/format.go - if err != nil { - return fmt.Errorf("%v: %v", spn, err) - } -- formatted, sedits, err := source.ApplyProtocolEdits(file.mapper, edits) -- if err != nil { -- return fmt.Errorf("%v: %v", spn, err) -- } -- printIt := true -- if c.List { -- printIt = false -- if len(edits) > 0 { -- fmt.Println(filename) -- } -- } -- if c.Write { -- printIt = false -- if len(edits) > 0 { -- ioutil.WriteFile(filename, formatted, 0644) -- } -- } -- if c.Diff { -- printIt = false -- unified, err := diff.ToUnified(filename+".orig", filename, string(file.mapper.Content), sedits) -- if err != nil { -- return err -- } -- fmt.Print(unified) -- } -- if printIt { -- os.Stdout.Write(formatted) +- if err := applyTextEdits(file.mapper, edits, c.app.editFlags); err != nil { +- return err - } - } - return nil @@ -25955,16 +29680,16 @@ diff -urN a/gopls/internal/lsp/cmd/highlight.go b/gopls/internal/lsp/cmd/highlig - return tool.CommandLineErrorf("highlight expects 1 argument (position)") - } - -- conn, err := r.app.connect(ctx) +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - - loc, err := file.mapper.SpanLocation(from) @@ -25999,7 +29724,7 @@ diff -urN a/gopls/internal/lsp/cmd/highlight.go b/gopls/internal/lsp/cmd/highlig diff -urN a/gopls/internal/lsp/cmd/implementation.go b/gopls/internal/lsp/cmd/implementation.go --- a/gopls/internal/lsp/cmd/implementation.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/implementation.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,84 +0,0 @@ +@@ -1,87 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -26042,16 +29767,16 @@ diff -urN a/gopls/internal/lsp/cmd/implementation.go b/gopls/internal/lsp/cmd/im - return tool.CommandLineErrorf("implementation expects 1 argument (position)") - } - -- conn, err := i.app.connect(ctx) +- conn, err := i.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - - loc, err := file.mapper.SpanLocation(from) @@ -26069,7 +29794,10 @@ diff -urN a/gopls/internal/lsp/cmd/implementation.go b/gopls/internal/lsp/cmd/im - - var spans []string - for _, impl := range implementations { -- f := conn.openFile(ctx, fileURI(impl.URI)) +- f, err := conn.openFile(ctx, fileURI(impl.URI)) +- if err != nil { +- return err +- } - span, err := f.mapper.LocationSpan(impl) - if err != nil { - return err @@ -26087,7 +29815,7 @@ diff -urN a/gopls/internal/lsp/cmd/implementation.go b/gopls/internal/lsp/cmd/im diff -urN a/gopls/internal/lsp/cmd/imports.go b/gopls/internal/lsp/cmd/imports.go --- a/gopls/internal/lsp/cmd/imports.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/imports.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,105 +0,0 @@ +@@ -1,81 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -26098,21 +29826,15 @@ diff -urN a/gopls/internal/lsp/cmd/imports.go b/gopls/internal/lsp/cmd/imports.g - "context" - "flag" - "fmt" -- "io/ioutil" -- "os" - - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/diff" - "golang.org/x/tools/internal/tool" -) - -// imports implements the import verb for gopls. -type imports struct { -- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"` -- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"` -- +- EditFlags - app *Application -} - @@ -26139,7 +29861,8 @@ diff -urN a/gopls/internal/lsp/cmd/imports.go b/gopls/internal/lsp/cmd/imports.g - if len(args) != 1 { - return tool.CommandLineErrorf("imports expects 1 argument") - } -- conn, err := t.app.connect(ctx) +- t.app.editFlags = &t.EditFlags +- conn, err := t.app.connect(ctx, nil) - if err != nil { - return err - } @@ -26147,9 +29870,9 @@ diff -urN a/gopls/internal/lsp/cmd/imports.go b/gopls/internal/lsp/cmd/imports.g - - from := span.Parse(args[0]) - uri := from.URI() -- file := conn.openFile(ctx, uri) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, uri) +- if err != nil { +- return err - } - actions, err := conn.CodeAction(ctx, &protocol.CodeActionParams{ - TextDocument: protocol.TextDocumentIdentifier{ @@ -26172,31 +29895,12 @@ diff -urN a/gopls/internal/lsp/cmd/imports.go b/gopls/internal/lsp/cmd/imports.g - } - } - } -- newContent, sedits, err := source.ApplyProtocolEdits(file.mapper, edits) -- if err != nil { -- return fmt.Errorf("%v: %v", edits, err) -- } -- filename := file.uri.Filename() -- switch { -- case t.Write: -- if len(edits) > 0 { -- ioutil.WriteFile(filename, newContent, 0644) -- } -- case t.Diff: -- unified, err := diff.ToUnified(filename+".orig", filename, string(file.mapper.Content), sedits) -- if err != nil { -- return err -- } -- fmt.Print(unified) -- default: -- os.Stdout.Write(newContent) -- } -- return nil +- return applyTextEdits(file.mapper, edits, t.app.editFlags) -} diff -urN a/gopls/internal/lsp/cmd/info.go b/gopls/internal/lsp/cmd/info.go --- a/gopls/internal/lsp/cmd/info.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/info.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,246 +0,0 @@ +@@ -1,312 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -26211,10 +29915,13 @@ diff -urN a/gopls/internal/lsp/cmd/info.go b/gopls/internal/lsp/cmd/info.go - "fmt" - "net/url" - "os" +- "sort" - "strings" - +- goplsbug "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/browser" - "golang.org/x/tools/gopls/internal/lsp/debug" +- "golang.org/x/tools/gopls/internal/lsp/filecache" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/internal/tool" -) @@ -26327,10 +30034,50 @@ diff -urN a/gopls/internal/lsp/cmd/info.go b/gopls/internal/lsp/cmd/info.go -// Run collects some basic information and then prepares an issue ready to -// be reported. -func (b *bug) Run(ctx context.Context, args ...string) error { -- buf := &bytes.Buffer{} -- fmt.Fprint(buf, goplsBugHeader) -- debug.PrintVersionInfo(ctx, buf, true, debug.Markdown) -- body := buf.String() +- // This undocumented environment variable allows +- // the cmd integration test (and maintainers) to +- // trigger a call to bug.Report. +- if msg := os.Getenv("TEST_GOPLS_BUG"); msg != "" { +- filecache.Start() // register bug handler +- goplsbug.Report(msg) +- return nil +- } +- +- // Enumerate bug reports, grouped and sorted. +- _, reports := filecache.BugReports() +- sort.Slice(reports, func(i, j int) bool { +- x, y := reports[i], reports[i] +- if x.Key != y.Key { +- return x.Key < y.Key // ascending key order +- } +- return y.AtTime.Before(x.AtTime) // most recent first +- }) +- keyDenom := make(map[string]int) // key is "file:line" +- for _, report := range reports { +- keyDenom[report.Key]++ +- } +- +- // Privacy: the content of 'public' will be posted to GitHub +- // to populate an issue textarea. Even though the user must +- // submit the form to share the information with the world, +- // merely populating the form causes us to share the +- // information with GitHub itself. +- // +- // For that reason, we cannot write private information to +- // public, such as bug reports, which may quote source code. +- public := &bytes.Buffer{} +- fmt.Fprint(public, goplsBugHeader) +- if len(reports) > 0 { +- fmt.Fprintf(public, "#### Internal errors\n\n") +- fmt.Fprintf(public, "Gopls detected %d internal errors, %d distinct:\n", +- len(reports), len(keyDenom)) +- for key, denom := range keyDenom { +- fmt.Fprintf(public, "- %s (%d)\n", key, denom) +- } +- fmt.Fprintf(public, "\nPlease copy the full information printed by `gopls bug` here, if you are comfortable sharing it.\n\n") +- } +- debug.PrintVersionInfo(ctx, public, true, debug.Markdown) +- body := public.String() - title := strings.Join(args, " ") - if !strings.HasPrefix(title, goplsBugPrefix) { - title = goplsBugPrefix + title @@ -26339,6 +30086,29 @@ diff -urN a/gopls/internal/lsp/cmd/info.go b/gopls/internal/lsp/cmd/info.go - fmt.Print("Please file a new issue at golang.org/issue/new using this template:\n\n") - fmt.Print(body) - } +- +- // Print bug reports to stdout (not GitHub). +- keyNum := make(map[string]int) +- for _, report := range reports { +- fmt.Printf("-- %v -- \n", report.AtTime) +- +- // Append seq number (e.g. " (1/2)") for repeated keys. +- var seq string +- if denom := keyDenom[report.Key]; denom > 1 { +- keyNum[report.Key]++ +- seq = fmt.Sprintf(" (%d/%d)", keyNum[report.Key], denom) +- } +- +- // Privacy: +- // - File and Stack may contain the name of the user that built gopls. +- // - Description may contain names of the user's packages/files/symbols. +- fmt.Printf("%s:%d: %s%s\n\n", report.File, report.Line, report.Description, seq) +- fmt.Printf("%s\n\n", report.Stack) +- } +- if len(reports) > 0 { +- fmt.Printf("Please copy the above information into the GitHub issue, if you are comfortable sharing it.\n") +- } +- - return nil -} - @@ -26494,7 +30264,7 @@ diff -urN a/gopls/internal/lsp/cmd/links.go b/gopls/internal/lsp/cmd/links.go - if len(args) != 1 { - return tool.CommandLineErrorf("links expects 1 argument") - } -- conn, err := l.app.connect(ctx) +- conn, err := l.app.connect(ctx, nil) - if err != nil { - return err - } @@ -26502,9 +30272,9 @@ diff -urN a/gopls/internal/lsp/cmd/links.go b/gopls/internal/lsp/cmd/links.go - - from := span.Parse(args[0]) - uri := from.URI() -- file := conn.openFile(ctx, uri) -- if file.err != nil { -- return file.err +- +- if _, err := conn.openFile(ctx, uri); err != nil { +- return err - } - results, err := conn.DocumentLink(ctx, &protocol.DocumentLinkParams{ - TextDocument: protocol.TextDocumentIdentifier{ @@ -26520,7 +30290,7 @@ diff -urN a/gopls/internal/lsp/cmd/links.go b/gopls/internal/lsp/cmd/links.go - return enc.Encode(results) - } - for _, v := range results { -- fmt.Println(v.Target) +- fmt.Println(*v.Target) - } - return nil -} @@ -26574,16 +30344,16 @@ diff -urN a/gopls/internal/lsp/cmd/prepare_rename.go b/gopls/internal/lsp/cmd/pr - return tool.CommandLineErrorf("prepare_rename expects 1 argument (file)") - } - -- conn, err := r.app.connect(ctx) +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - loc, err := file.mapper.SpanLocation(from) - if err != nil { @@ -26611,7 +30381,7 @@ diff -urN a/gopls/internal/lsp/cmd/prepare_rename.go b/gopls/internal/lsp/cmd/pr diff -urN a/gopls/internal/lsp/cmd/references.go b/gopls/internal/lsp/cmd/references.go --- a/gopls/internal/lsp/cmd/references.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/references.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,89 +0,0 @@ +@@ -1,92 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -26658,16 +30428,16 @@ diff -urN a/gopls/internal/lsp/cmd/references.go b/gopls/internal/lsp/cmd/refere - return tool.CommandLineErrorf("references expects 1 argument (position)") - } - -- conn, err := r.app.connect(ctx) +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - loc, err := file.mapper.SpanLocation(from) - if err != nil { @@ -26685,7 +30455,10 @@ diff -urN a/gopls/internal/lsp/cmd/references.go b/gopls/internal/lsp/cmd/refere - } - var spans []string - for _, l := range locations { -- f := conn.openFile(ctx, fileURI(l.URI)) +- f, err := conn.openFile(ctx, fileURI(l.URI)) +- if err != nil { +- return err +- } - // convert location to span for user-friendly 1-indexed line - // and column numbers - span, err := f.mapper.LocationSpan(l) @@ -26872,7 +30645,7 @@ diff -urN a/gopls/internal/lsp/cmd/remote.go b/gopls/internal/lsp/cmd/remote.go diff -urN a/gopls/internal/lsp/cmd/rename.go b/gopls/internal/lsp/cmd/rename.go --- a/gopls/internal/lsp/cmd/rename.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/rename.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,130 +0,0 @@ +@@ -1,74 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -26883,24 +30656,15 @@ diff -urN a/gopls/internal/lsp/cmd/rename.go b/gopls/internal/lsp/cmd/rename.go - "context" - "flag" - "fmt" -- "io/ioutil" -- "os" -- "path/filepath" -- "sort" - - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/diff" - "golang.org/x/tools/internal/tool" -) - -// rename implements the rename verb for gopls. -type rename struct { -- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"` -- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"` -- Preserve bool `flag:"preserve" help:"preserve original files"` -- +- EditFlags - app *Application -} - @@ -26929,16 +30693,17 @@ diff -urN a/gopls/internal/lsp/cmd/rename.go b/gopls/internal/lsp/cmd/rename.go - if len(args) != 2 { - return tool.CommandLineErrorf("definition expects 2 arguments (position, new name)") - } -- conn, err := r.app.connect(ctx) +- r.app.editFlags = &r.EditFlags +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - loc, err := file.mapper.SpanLocation(from) - if err != nil { @@ -26953,55 +30718,7 @@ diff -urN a/gopls/internal/lsp/cmd/rename.go b/gopls/internal/lsp/cmd/rename.go - if err != nil { - return err - } -- var orderedURIs []string -- edits := map[span.URI][]protocol.TextEdit{} -- for _, c := range edit.DocumentChanges { -- if c.TextDocumentEdit != nil { -- uri := fileURI(c.TextDocumentEdit.TextDocument.URI) -- edits[uri] = append(edits[uri], c.TextDocumentEdit.Edits...) -- orderedURIs = append(orderedURIs, string(uri)) -- } -- } -- sort.Strings(orderedURIs) -- changeCount := len(orderedURIs) -- -- for _, u := range orderedURIs { -- uri := span.URIFromURI(u) -- cmdFile := conn.openFile(ctx, uri) -- filename := cmdFile.uri.Filename() -- -- newContent, renameEdits, err := source.ApplyProtocolEdits(cmdFile.mapper, edits[uri]) -- if err != nil { -- return fmt.Errorf("%v: %v", edits, err) -- } -- -- switch { -- case r.Write: -- fmt.Fprintln(os.Stderr, filename) -- if r.Preserve { -- if err := os.Rename(filename, filename+".orig"); err != nil { -- return fmt.Errorf("%v: %v", edits, err) -- } -- } -- ioutil.WriteFile(filename, newContent, 0644) -- case r.Diff: -- unified, err := diff.ToUnified(filename+".orig", filename, string(cmdFile.mapper.Content), renameEdits) -- if err != nil { -- return err -- } -- fmt.Print(unified) -- default: -- if len(orderedURIs) > 1 { -- fmt.Printf("%s:\n", filepath.Base(filename)) -- } -- os.Stdout.Write(newContent) -- if changeCount > 1 { // if this wasn't last change, print newline -- fmt.Println() -- } -- changeCount -= 1 -- } -- } -- return nil +- return conn.client.applyWorkspaceEdit(edit) -} diff -urN a/gopls/internal/lsp/cmd/semantictokens.go b/gopls/internal/lsp/cmd/semantictokens.go --- a/gopls/internal/lsp/cmd/semantictokens.go 2000-01-01 00:00:00.000000000 -0000 @@ -27085,15 +30802,15 @@ diff -urN a/gopls/internal/lsp/cmd/semantictokens.go b/gopls/internal/lsp/cmd/se - origOptions(opts) - opts.SemanticTokens = true - } -- conn, err := c.app.connect(ctx) +- conn, err := c.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - uri := span.URIFromPath(args[0]) -- file := conn.openFile(ctx, uri) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, uri) +- if err != nil { +- return err - } - - buf, err := ioutil.ReadFile(args[0]) @@ -27235,7 +30952,7 @@ diff -urN a/gopls/internal/lsp/cmd/semantictokens.go b/gopls/internal/lsp/cmd/se diff -urN a/gopls/internal/lsp/cmd/serve.go b/gopls/internal/lsp/cmd/serve.go --- a/gopls/internal/lsp/cmd/serve.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/serve.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,130 +0,0 @@ +@@ -1,146 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -27328,7 +31045,6 @@ diff -urN a/gopls/internal/lsp/cmd/serve.go b/gopls/internal/lsp/cmd/serve.go - } - defer closeLog() - di.ServerAddress = s.Address -- di.MonitorMemory(ctx) - di.Serve(ctx, s.Debug) - } - var ss jsonrpc2.StreamServer @@ -27348,6 +31064,23 @@ diff -urN a/gopls/internal/lsp/cmd/serve.go b/gopls/internal/lsp/cmd/serve.go - } - if s.Port != 0 { - network = "tcp" +- // TODO(adonovan): should gopls ever be listening on network +- // sockets, or only local ones? +- // +- // Ian says this was added in anticipation of +- // something related to "VS Code remote" that turned +- // out to be unnecessary. So I propose we limit it to +- // localhost, if only so that we avoid the macOS +- // firewall prompt. +- // +- // Hana says: "s.Address is for the remote access (LSP) +- // and s.Port is for debugging purpose (according to +- // the Server type documentation). I am not sure why the +- // existing code here is mixing up and overwriting addr. +- // For debugging endpoint, I think localhost makes perfect sense." +- // +- // TODO(adonovan): disentangle Address and Port, +- // and use only localhost for the latter. - addr = fmt.Sprintf(":%v", s.Port) - } - if addr != "" { @@ -27411,16 +31144,16 @@ diff -urN a/gopls/internal/lsp/cmd/signature.go b/gopls/internal/lsp/cmd/signatu - return tool.CommandLineErrorf("signature expects 1 argument (position)") - } - -- conn, err := r.app.connect(ctx) +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } - defer conn.terminate(ctx) - - from := span.Parse(args[0]) -- file := conn.openFile(ctx, from.URI()) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, from.URI()) +- if err != nil { +- return err - } - - loc, err := file.mapper.SpanLocation(from) @@ -27458,6 +31191,281 @@ diff -urN a/gopls/internal/lsp/cmd/signature.go b/gopls/internal/lsp/cmd/signatu - - return nil -} +diff -urN a/gopls/internal/lsp/cmd/stats.go b/gopls/internal/lsp/cmd/stats.go +--- a/gopls/internal/lsp/cmd/stats.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cmd/stats.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,271 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package cmd +- +-import ( +- "context" +- "encoding/json" +- "flag" +- "fmt" +- "go/token" +- "io/fs" +- "os" +- "path/filepath" +- "reflect" +- "runtime" +- "strings" +- "sync" +- "time" +- +- goplsbug "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/debug" +- "golang.org/x/tools/gopls/internal/lsp/filecache" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +-) +- +-type stats struct { +- app *Application +- +- Anon bool `flag:"anon" help:"hide any fields that may contain user names, file names, or source code"` +-} +- +-func (s *stats) Name() string { return "stats" } +-func (r *stats) Parent() string { return r.app.Name() } +-func (s *stats) Usage() string { return "" } +-func (s *stats) ShortHelp() string { return "print workspace statistics" } +- +-func (s *stats) DetailedHelp(f *flag.FlagSet) { +- fmt.Fprint(f.Output(), ` +-Load the workspace for the current directory, and output a JSON summary of +-workspace information relevant to performance. As a side effect, this command +-populates the gopls file cache for the current workspace. +- +-By default, this command may include output that refers to the location or +-content of user code. When the -anon flag is set, fields that may refer to user +-code are hidden. +- +-Example: +- $ gopls stats -anon +-`) +- printFlagDefaults(f) +-} +- +-func (s *stats) Run(ctx context.Context, args ...string) error { +- if s.app.Remote != "" { +- // stats does not work with -remote. +- // Other sessions on the daemon may interfere with results. +- // Additionally, the type assertions in below only work if progress +- // notifications bypass jsonrpc2 serialization. +- return fmt.Errorf("the stats subcommand does not work with -remote") +- } +- +- if !s.app.Verbose { +- event.SetExporter(nil) // don't log errors to stderr +- } +- +- stats := GoplsStats{ +- GOOS: runtime.GOOS, +- GOARCH: runtime.GOARCH, +- GOPLSCACHE: os.Getenv("GOPLSCACHE"), +- GoVersion: runtime.Version(), +- GoplsVersion: debug.Version(), +- } +- +- opts := s.app.options +- s.app.options = func(o *source.Options) { +- if opts != nil { +- opts(o) +- } +- o.VerboseWorkDoneProgress = true +- } +- var ( +- iwlMu sync.Mutex +- iwlToken protocol.ProgressToken +- iwlDone = make(chan struct{}) +- ) +- +- onProgress := func(p *protocol.ProgressParams) { +- switch v := p.Value.(type) { +- case *protocol.WorkDoneProgressBegin: +- if v.Title == lsp.DiagnosticWorkTitle(lsp.FromInitialWorkspaceLoad) { +- iwlMu.Lock() +- iwlToken = p.Token +- iwlMu.Unlock() +- } +- case *protocol.WorkDoneProgressEnd: +- iwlMu.Lock() +- tok := iwlToken +- iwlMu.Unlock() +- +- if p.Token == tok { +- close(iwlDone) +- } +- } +- } +- +- // do executes a timed section of the stats command. +- do := func(name string, f func() error) (time.Duration, error) { +- start := time.Now() +- fmt.Fprintf(os.Stderr, "%-30s", name+"...") +- if err := f(); err != nil { +- return time.Since(start), err +- } +- d := time.Since(start) +- fmt.Fprintf(os.Stderr, "done (%v)\n", d) +- return d, nil +- } +- +- var conn *connection +- iwlDuration, err := do("Initializing workspace", func() error { +- var err error +- conn, err = s.app.connect(ctx, onProgress) +- if err != nil { +- return err +- } +- select { +- case <-iwlDone: +- case <-ctx.Done(): +- return ctx.Err() +- } +- return nil +- }) +- stats.InitialWorkspaceLoadDuration = fmt.Sprint(iwlDuration) +- if err != nil { +- return err +- } +- defer conn.terminate(ctx) +- +- // Gather bug reports produced by any process using +- // this executable and persisted in the cache. +- do("Gathering bug reports", func() error { +- stats.CacheDir, stats.BugReports = filecache.BugReports() +- if stats.BugReports == nil { +- stats.BugReports = []goplsbug.Bug{} // non-nil for JSON +- } +- return nil +- }) +- +- if _, err := do("Querying memstats", func() error { +- memStats, err := conn.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ +- Command: command.MemStats.ID(), +- }) +- if err != nil { +- return err +- } +- stats.MemStats = memStats.(command.MemStatsResult) +- return nil +- }); err != nil { +- return err +- } +- +- if _, err := do("Querying workspace stats", func() error { +- wsStats, err := conn.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ +- Command: command.WorkspaceStats.ID(), +- }) +- if err != nil { +- return err +- } +- stats.WorkspaceStats = wsStats.(command.WorkspaceStatsResult) +- return nil +- }); err != nil { +- return err +- } +- +- if _, err := do("Collecting directory info", func() error { +- var err error +- stats.DirStats, err = findDirStats(ctx) +- if err != nil { +- return err +- } +- return nil +- }); err != nil { +- return err +- } +- +- // Filter JSON output to fields that are consistent with s.Anon. +- okFields := make(map[string]interface{}) +- { +- v := reflect.ValueOf(stats) +- t := v.Type() +- for i := 0; i < t.NumField(); i++ { +- f := t.Field(i) +- if !token.IsExported(f.Name) { +- continue +- } +- if s.Anon && f.Tag.Get("anon") != "ok" { +- // Fields that can be served with -anon must be explicitly marked as OK. +- continue +- } +- vf := v.FieldByName(f.Name) +- okFields[f.Name] = vf.Interface() +- } +- } +- data, err := json.MarshalIndent(okFields, "", " ") +- if err != nil { +- return err +- } +- +- os.Stdout.Write(data) +- fmt.Println() +- return nil +-} +- +-// GoplsStats holds information extracted from a gopls session in the current +-// workspace. +-// +-// Fields that should be printed with the -anon flag should be explicitly +-// marked as `anon:"ok"`. Only fields that cannot refer to user files or code +-// should be marked as such. +-type GoplsStats struct { +- GOOS, GOARCH string `anon:"ok"` +- GOPLSCACHE string +- GoVersion string `anon:"ok"` +- GoplsVersion string `anon:"ok"` +- InitialWorkspaceLoadDuration string `anon:"ok"` // in time.Duration string form +- CacheDir string +- BugReports []goplsbug.Bug +- MemStats command.MemStatsResult `anon:"ok"` +- WorkspaceStats command.WorkspaceStatsResult `anon:"ok"` +- DirStats dirStats `anon:"ok"` +-} +- +-type dirStats struct { +- Files int +- TestdataFiles int +- GoFiles int +- ModFiles int +- Dirs int +-} +- +-// findDirStats collects information about the current directory and its +-// subdirectories. +-func findDirStats(ctx context.Context) (dirStats, error) { +- var ds dirStats +- filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error { +- if err != nil { +- return err +- } +- if d.IsDir() { +- ds.Dirs++ +- } else { +- ds.Files++ +- slashed := filepath.ToSlash(path) +- switch { +- case strings.Contains(slashed, "/testdata/") || strings.HasPrefix(slashed, "testdata/"): +- ds.TestdataFiles++ +- case strings.HasSuffix(path, ".go"): +- ds.GoFiles++ +- case strings.HasSuffix(path, ".mod"): +- ds.ModFiles++ +- } +- } +- return nil +- }) +- return ds, nil +-} diff -urN a/gopls/internal/lsp/cmd/subcommands.go b/gopls/internal/lsp/cmd/subcommands.go --- a/gopls/internal/lsp/cmd/subcommands.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/subcommands.go 1970-01-01 00:00:00.000000000 +0000 @@ -27524,7 +31532,7 @@ diff -urN a/gopls/internal/lsp/cmd/subcommands.go b/gopls/internal/lsp/cmd/subco diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/suggested_fix.go --- a/gopls/internal/lsp/cmd/suggested_fix.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/suggested_fix.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,167 +0,0 @@ +@@ -1,193 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -27535,21 +31543,21 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug - "context" - "flag" - "fmt" -- "io/ioutil" -- "os" - - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/diff" - "golang.org/x/tools/internal/tool" -) - +-// TODO(adonovan): this command has a very poor user interface. It +-// should have a way to query the available fixes for a file (without +-// a span), enumerate the valid fix kinds, enable all fixes, and not +-// require the pointless -all flag. See issue #60290. +- -// suggestedFix implements the fix verb for gopls. -type suggestedFix struct { -- Diff bool `flag:"d,diff" help:"display diffs instead of rewriting files"` -- Write bool `flag:"w,write" help:"write result to (source) file instead of stdout"` -- All bool `flag:"a,all" help:"apply all fixes, not just preferred fixes"` +- EditFlags +- All bool `flag:"a,all" help:"apply all fixes, not just preferred fixes"` - - app *Application -} @@ -27560,8 +31568,33 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug -func (s *suggestedFix) ShortHelp() string { return "apply suggested fixes" } -func (s *suggestedFix) DetailedHelp(f *flag.FlagSet) { - fmt.Fprintf(f.Output(), ` --Example: apply suggested fixes for this file -- $ gopls fix -w internal/lsp/cmd/check.go +-Example: apply fixes to this file, rewriting it: +- +- $ gopls fix -a -w internal/lsp/cmd/check.go +- +-The -a (-all) flag causes all fixes, not just preferred ones, to be +-applied, but since no fixes are currently preferred, this flag is +-essentially mandatory. +- +-Arguments after the filename are interpreted as LSP CodeAction kinds +-to be applied; the default set is {"quickfix"}, but valid kinds include: +- +- quickfix +- refactor +- refactor.extract +- refactor.inline +- refactor.rewrite +- source.organizeImports +- source.fixAll +- +-CodeAction kinds are hierarchical, so "refactor" includes +-"refactor.inline". There is currently no way to enable or even +-enumerate all kinds. +- +-Example: apply any "refactor.rewrite" fixes at the specific byte +-offset within this file: +- +- $ gopls fix -a internal/lsp/cmd/check.go:#43 refactor.rewrite - -fix-flags: -`) @@ -27576,7 +31609,8 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug - if len(args) < 1 { - return tool.CommandLineErrorf("fix expects at least 1 argument") - } -- conn, err := s.app.connect(ctx) +- s.app.editFlags = &s.EditFlags +- conn, err := s.app.connect(ctx, nil) - if err != nil { - return err - } @@ -27584,17 +31618,25 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug - - from := span.Parse(args[0]) - uri := from.URI() -- file := conn.openFile(ctx, uri) -- if file.err != nil { -- return file.err +- file, err := conn.openFile(ctx, uri) +- if err != nil { +- return err +- } +- rng, err := file.mapper.SpanRange(from) +- if err != nil { +- return err - } - +- // Get diagnostics. - if err := conn.diagnoseFiles(ctx, []span.URI{uri}); err != nil { - return err - } -- conn.Client.filesMu.Lock() -- defer conn.Client.filesMu.Unlock() +- diagnostics := []protocol.Diagnostic{} // LSP wants non-nil slice +- conn.client.filesMu.Lock() +- diagnostics = append(diagnostics, file.diagnostics...) +- conn.client.filesMu.Unlock() - +- // Request code actions - codeActionKinds := []protocol.CodeActionKind{protocol.QuickFix} - if len(args) > 1 { - codeActionKinds = []protocol.CodeActionKind{} @@ -27602,18 +31644,13 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug - codeActionKinds = append(codeActionKinds, protocol.CodeActionKind(k)) - } - } -- -- rng, err := file.mapper.SpanRange(from) -- if err != nil { -- return err -- } - p := protocol.CodeActionParams{ - TextDocument: protocol.TextDocumentIdentifier{ - URI: protocol.URIFromSpanURI(uri), - }, - Context: protocol.CodeActionContext{ - Only: codeActionKinds, -- Diagnostics: file.diagnostics, +- Diagnostics: diagnostics, - }, - Range: rng, - } @@ -27621,14 +31658,34 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug - if err != nil { - return fmt.Errorf("%v: %v", from, err) - } +- +- // Gather edits from matching code actions. - var edits []protocol.TextEdit - for _, a := range actions { -- if a.Command != nil { -- return fmt.Errorf("ExecuteCommand is not yet supported on the command line") -- } +- // Without -all, apply only "preferred" fixes. - if !a.IsPreferred && !s.All { - continue - } +- +- // Execute any command. +- // This may cause the server to make +- // an ApplyEdit downcall to the client. +- if a.Command != nil { +- if _, err := conn.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ +- Command: a.Command.Command, +- Arguments: a.Command.Arguments, +- }); err != nil { +- return err +- } +- // The specification says that commands should +- // be executed _after_ edits are applied, not +- // instead of them, but we don't want to +- // duplicate edits. +- continue +- } +- +- // Partially apply CodeAction.Edit, a WorkspaceEdit. +- // (See also conn.Client.applyWorkspaceEdit(a.Edit)). - if !from.HasPosition() { - for _, c := range a.Edit.DocumentChanges { - if c.TextDocumentEdit != nil { @@ -27639,14 +31696,11 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug - } - continue - } -- // If the span passed in has a position, then we need to find -- // the codeaction that has the same range as the passed in span. +- +- // The provided span has a position (not just offsets). +- // Find the code action that has the same range as it. - for _, diag := range a.Diagnostics { -- spn, err := file.mapper.RangeSpan(diag.Range) -- if err != nil { -- continue -- } -- if span.ComparePoint(from.Start(), spn.Start()) == 0 { +- if diag.Range.Start == rng.Start { - for _, c := range a.Edit.DocumentChanges { - if c.TextDocumentEdit != nil { - if fileURI(c.TextDocumentEdit.TextDocument.URI) == uri { @@ -27670,27 +31724,7 @@ diff -urN a/gopls/internal/lsp/cmd/suggested_fix.go b/gopls/internal/lsp/cmd/sug - } - } - -- newContent, sedits, err := source.ApplyProtocolEdits(file.mapper, edits) -- if err != nil { -- return fmt.Errorf("%v: %v", edits, err) -- } -- -- filename := file.uri.Filename() -- switch { -- case s.Write: -- if len(edits) > 0 { -- ioutil.WriteFile(filename, newContent, 0644) -- } -- case s.Diff: -- diffs, err := diff.ToUnified(filename+".orig", filename, string(file.mapper.Content), sedits) -- if err != nil { -- return err -- } -- fmt.Print(diffs) -- default: -- os.Stdout.Write(newContent) -- } -- return nil +- return applyTextEdits(file.mapper, edits, s.app.editFlags) -} diff -urN a/gopls/internal/lsp/cmd/symbols.go b/gopls/internal/lsp/cmd/symbols.go --- a/gopls/internal/lsp/cmd/symbols.go 2000-01-01 00:00:00.000000000 -0000 @@ -27735,7 +31769,7 @@ diff -urN a/gopls/internal/lsp/cmd/symbols.go b/gopls/internal/lsp/cmd/symbols.g - return tool.CommandLineErrorf("symbols expects 1 argument (position)") - } - -- conn, err := r.app.connect(ctx) +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } @@ -27812,23 +31846,15 @@ diff -urN a/gopls/internal/lsp/cmd/symbols.go b/gopls/internal/lsp/cmd/symbols.g - r.End.Character+1, - ) -} -diff -urN a/gopls/internal/lsp/cmd/test/cmdtest.go b/gopls/internal/lsp/cmd/test/cmdtest.go ---- a/gopls/internal/lsp/cmd/test/cmdtest.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/cmd/test/cmdtest.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --// Package cmdtest contains the test suite for the command line behavior of gopls. --package cmdtest diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp/cmd/test/integration_test.go --- a/gopls/internal/lsp/cmd/test/integration_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/test/integration_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,898 +0,0 @@ +@@ -1,1024 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. +- +-// Package cmdtest contains the test suite for the command line behavior of gopls. -package cmdtest - -// This file defines integration tests of each gopls subcommand that @@ -27845,9 +31871,9 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp -// -// TODO(adonovan): -// - Use markers to represent positions in the input and in assertions. --// - Coverage of cross-cutting things like cwd, enviro, span parsing, etc. --// - Subcommands that accept -write and -diff flags should implement --// them consistently wrt the default behavior; factor their tests. +-// - Coverage of cross-cutting things like cwd, environ, span parsing, etc. +-// - Subcommands that accept -write and -diff flags implement them +-// consistently; factor their tests. -// - Add missing test for 'vulncheck' subcommand. -// - Add tests for client-only commands: serve, bug, help, api-json, licenses. - @@ -27856,6 +31882,7 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - "context" - "encoding/json" - "fmt" +- "math/rand" - "os" - "path/filepath" - "regexp" @@ -27863,11 +31890,11 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - "testing" - - exec "golang.org/x/sys/execabs" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/lsp/cmd" - "golang.org/x/tools/gopls/internal/lsp/debug" - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/testenv" - "golang.org/x/tools/internal/tool" - "golang.org/x/tools/txtar" @@ -27880,7 +31907,7 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - tree := writeTree(t, "") - - // There's not much we can robustly assert about the actual version. -- const want = debug.Version // e.g. "master" +- want := debug.Version() // e.g. "master" - - // basic - { @@ -28221,7 +32248,7 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - res := gopls(t, tree, "imports", "a.go") - res.checkExit(true) - if res.stdout != want { -- t.Errorf("format: got <<%s>>, want <<%s>>", res.stdout, want) +- t.Errorf("imports: got <<%s>>, want <<%s>>", res.stdout, want) - } - } - // -diff: show a unified diff @@ -28506,6 +32533,95 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - } -} - +-func TestStats(t *testing.T) { +- t.Parallel() +- +- tree := writeTree(t, ` +--- go.mod -- +-module example.com +-go 1.18 +- +--- a.go -- +-package a +--- b/b.go -- +-package b +--- testdata/foo.go -- +-package foo +-`) +- +- // Trigger a bug report with a distinctive string +- // and check that it was durably recorded. +- oops := fmt.Sprintf("oops-%d", rand.Int()) +- { +- env := []string{"TEST_GOPLS_BUG=" + oops} +- res := goplsWithEnv(t, tree, env, "bug") +- res.checkExit(true) +- } +- +- res := gopls(t, tree, "stats") +- res.checkExit(true) +- +- var stats cmd.GoplsStats +- if err := json.Unmarshal([]byte(res.stdout), &stats); err != nil { +- t.Fatalf("failed to unmarshal JSON output of stats command: %v", err) +- } +- +- // a few sanity checks +- checks := []struct { +- field string +- got int +- want int +- }{ +- { +- "WorkspaceStats.Views[0].WorkspaceModules", +- stats.WorkspaceStats.Views[0].WorkspacePackages.Modules, +- 1, +- }, +- { +- "WorkspaceStats.Views[0].WorkspacePackages", +- stats.WorkspaceStats.Views[0].WorkspacePackages.Packages, +- 2, +- }, +- {"DirStats.Files", stats.DirStats.Files, 4}, +- {"DirStats.GoFiles", stats.DirStats.GoFiles, 2}, +- {"DirStats.ModFiles", stats.DirStats.ModFiles, 1}, +- {"DirStats.TestdataFiles", stats.DirStats.TestdataFiles, 1}, +- } +- for _, check := range checks { +- if check.got != check.want { +- t.Errorf("stats.%s = %d, want %d", check.field, check.got, check.want) +- } +- } +- +- // Check that we got a BugReport with the expected message. +- { +- got := fmt.Sprint(stats.BugReports) +- wants := []string{ +- "cmd/info.go", // File containing call to bug.Report +- oops, // Description +- } +- for _, want := range wants { +- if !strings.Contains(got, want) { +- t.Errorf("BugReports does not contain %q. Got:<<%s>>", want, got) +- break +- } +- } +- } +- +- // Check that -anon suppresses fields containing user information. +- { +- res2 := gopls(t, tree, "stats", "-anon") +- res2.checkExit(true) +- var stats2 cmd.GoplsStats +- if err := json.Unmarshal([]byte(res2.stdout), &stats2); err != nil { +- t.Fatalf("failed to unmarshal JSON output of stats command: %v", err) +- } +- if got := len(stats2.BugReports); got > 0 { +- t.Errorf("Got %d bug reports with -anon, want 0. Reports:%+v", got, stats2.BugReports) +- } +- } +-} +- -// TestFix tests the 'fix' subcommand (../suggested_fix.go). -func TestFix(t *testing.T) { - t.Parallel() @@ -28517,16 +32633,15 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - --- a.go -- -package a --var _ error = T(0) -type T int -func f() (int, string) { return } --`) -- want := ` +- +--- b.go -- -package a --var _ error = T(0) --type T int --func f() (int, string) { return 0, "" } --`[1:] +-import "io" +-var _ io.Reader = C{} +-type C struct{} +-`) - - // no arguments - { @@ -28534,20 +32649,45 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - res.checkExit(false) - res.checkStderr("expects at least 1 argument") - } -- // success (-a enables fillreturns) +- // success with default kinds, {quickfix}. +- // -a is always required because no fix is currently "preferred" (!) - { - res := gopls(t, tree, "fix", "-a", "a.go") - res.checkExit(true) - got := res.stdout +- want := ` +-package a +-type T int +-func f() (int, string) { return 0, "" } +- +-`[1:] - if got != want { -- t.Errorf("fix: got <<%s>>, want <<%s>>", got, want) +- t.Errorf("fix: got <<%s>>, want <<%s>>\nstderr:\n%s", got, want, res.stderr) +- } +- } +- // success, with explicit CodeAction kind and diagnostics span. +- { +- res := gopls(t, tree, "fix", "-a", "b.go:#40", "quickfix") +- res.checkExit(true) +- got := res.stdout +- want := ` +-package a +- +-import "io" +- +-var _ io.Reader = C{} +- +-type C struct{} +- +-// Read implements io.Reader. +-func (C) Read(p []byte) (n int, err error) { +- panic("unimplemented") +-} +-`[1:] +- if got != want { +- t.Errorf("fix: got <<%s>>, want <<%s>>\nstderr:\n%s", got, want, res.stderr) - } - } -- // TODO(adonovan): more tests: -- // - -write, -diff: factor with imports, format, rename. -- // - without -all flag -- // - args[2:] is an optional list of protocol.CodeActionKind enum values. -- // - a span argument with a range causes filtering. -} - -// TestWorkspaceSymbol tests the 'workspace_symbol' subcommand (../workspace_symbol.go). @@ -28590,7 +32730,12 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - -// This function is a stand-in for gopls.main in ../../../../main.go. -func goplsMain() { -- bug.PanicOnBugs = true // (not in the production command) +- // Panic on bugs (unlike the production gopls command), +- // except in tests that inject calls to bug.Report. +- if os.Getenv("TEST_GOPLS_BUG") == "" { +- bug.PanicOnBugs = true +- } +- - tool.Main(context.Background(), cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) -} - @@ -28620,6 +32765,10 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - -// gopls executes gopls in a child process. -func gopls(t *testing.T, dir string, args ...string) *result { +- return goplsWithEnv(t, dir, nil, args...) +-} +- +-func goplsWithEnv(t *testing.T, dir string, env []string, args ...string) *result { - testenv.NeedsTool(t, "go") - - // Catch inadvertent use of dir=".", which would make @@ -28628,16 +32777,17 @@ diff -urN a/gopls/internal/lsp/cmd/test/integration_test.go b/gopls/internal/lsp - t.Fatalf("dir is not absolute: %s", dir) - } - -- cmd := exec.Command(os.Args[0], args...) -- cmd.Env = append(os.Environ(), "ENTRYPOINT=goplsMain") -- cmd.Dir = dir -- cmd.Stdout = new(bytes.Buffer) -- cmd.Stderr = new(bytes.Buffer) +- goplsCmd := exec.Command(os.Args[0], args...) +- goplsCmd.Env = append(os.Environ(), "ENTRYPOINT=goplsMain") +- goplsCmd.Env = append(goplsCmd.Env, env...) +- goplsCmd.Dir = dir +- goplsCmd.Stdout = new(bytes.Buffer) +- goplsCmd.Stderr = new(bytes.Buffer) - -- cmdErr := cmd.Run() +- cmdErr := goplsCmd.Run() - -- stdout := strings.ReplaceAll(fmt.Sprint(cmd.Stdout), dir, ".") -- stderr := strings.ReplaceAll(fmt.Sprint(cmd.Stderr), dir, ".") +- stdout := strings.ReplaceAll(fmt.Sprint(goplsCmd.Stdout), dir, ".") +- stderr := strings.ReplaceAll(fmt.Sprint(goplsCmd.Stderr), dir, ".") - exitcode := 0 - if cmdErr != nil { - if exitErr, ok := cmdErr.(*exec.ExitError); ok { @@ -28788,22 +32938,51 @@ diff -urN a/gopls/internal/lsp/cmd/usage/definition.hlp b/gopls/internal/lsp/cmd diff -urN a/gopls/internal/lsp/cmd/usage/fix.hlp b/gopls/internal/lsp/cmd/usage/fix.hlp --- a/gopls/internal/lsp/cmd/usage/fix.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/fix.hlp 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ +@@ -1,44 +0,0 @@ -apply suggested fixes - -Usage: - gopls [flags] fix [fix-flags] - --Example: apply suggested fixes for this file -- $ gopls fix -w internal/lsp/cmd/check.go +-Example: apply fixes to this file, rewriting it: +- +- $ gopls fix -a -w internal/lsp/cmd/check.go +- +-The -a (-all) flag causes all fixes, not just preferred ones, to be +-applied, but since no fixes are currently preferred, this flag is +-essentially mandatory. +- +-Arguments after the filename are interpreted as LSP CodeAction kinds +-to be applied; the default set is {"quickfix"}, but valid kinds include: +- +- quickfix +- refactor +- refactor.extract +- refactor.inline +- refactor.rewrite +- source.organizeImports +- source.fixAll +- +-CodeAction kinds are hierarchical, so "refactor" includes +-"refactor.inline". There is currently no way to enable or even +-enumerate all kinds. +- +-Example: apply any "refactor.rewrite" fixes at the specific byte +-offset within this file: +- +- $ gopls fix -a internal/lsp/cmd/check.go:#43 refactor.rewrite - -fix-flags: - -a,-all - apply all fixes, not just preferred fixes - -d,-diff -- display diffs instead of rewriting files +- display diffs instead of edited file content +- -l,-list +- display names of edited files +- -preserve +- with -write, make copies of original files - -w,-write -- write result to (source) file instead of stdout +- write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/folding_ranges.hlp b/gopls/internal/lsp/cmd/usage/folding_ranges.hlp --- a/gopls/internal/lsp/cmd/usage/folding_ranges.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/folding_ranges.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -28819,7 +32998,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/folding_ranges.hlp b/gopls/internal/lsp diff -urN a/gopls/internal/lsp/cmd/usage/format.hlp b/gopls/internal/lsp/cmd/usage/format.hlp --- a/gopls/internal/lsp/cmd/usage/format.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/format.hlp 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ +@@ -1,20 +0,0 @@ -format the code according to the go standard - -Usage: @@ -28833,11 +33012,13 @@ diff -urN a/gopls/internal/lsp/cmd/usage/format.hlp b/gopls/internal/lsp/cmd/usa - -format-flags: - -d,-diff -- display diffs instead of rewriting files +- display diffs instead of edited file content - -l,-list -- list files whose formatting differs from gofmt's +- display names of edited files +- -preserve +- with -write, make copies of original files - -w,-write -- write result to (source) file instead of stdout +- write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/help.hlp b/gopls/internal/lsp/cmd/usage/help.hlp --- a/gopls/internal/lsp/cmd/usage/help.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/help.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -28883,7 +33064,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/implementation.hlp b/gopls/internal/lsp diff -urN a/gopls/internal/lsp/cmd/usage/imports.hlp b/gopls/internal/lsp/cmd/usage/imports.hlp --- a/gopls/internal/lsp/cmd/usage/imports.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/imports.hlp 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ +@@ -1,18 +0,0 @@ -updates import statements - -Usage: @@ -28895,9 +33076,13 @@ diff -urN a/gopls/internal/lsp/cmd/usage/imports.hlp b/gopls/internal/lsp/cmd/us - -imports-flags: - -d,-diff -- display diffs instead of rewriting files +- display diffs instead of edited file content +- -l,-list +- display names of edited files +- -preserve +- with -write, make copies of original files - -w,-write -- write result to (source) file instead of stdout +- write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/inspect.hlp b/gopls/internal/lsp/cmd/usage/inspect.hlp --- a/gopls/internal/lsp/cmd/usage/inspect.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/inspect.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -28981,7 +33166,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/remote.hlp b/gopls/internal/lsp/cmd/usa diff -urN a/gopls/internal/lsp/cmd/usage/rename.hlp b/gopls/internal/lsp/cmd/usage/rename.hlp --- a/gopls/internal/lsp/cmd/usage/rename.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/rename.hlp 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ +@@ -1,20 +0,0 @@ -rename selected identifier - -Usage: @@ -28995,11 +33180,13 @@ diff -urN a/gopls/internal/lsp/cmd/usage/rename.hlp b/gopls/internal/lsp/cmd/usa - -rename-flags: - -d,-diff -- display diffs instead of rewriting files +- display diffs instead of edited file content +- -l,-list +- display names of edited files - -preserve -- preserve original files +- with -write, make copies of original files - -w,-write -- write result to (source) file instead of stdout +- write edited content to source files diff -urN a/gopls/internal/lsp/cmd/usage/semtok.hlp b/gopls/internal/lsp/cmd/usage/semtok.hlp --- a/gopls/internal/lsp/cmd/usage/semtok.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/semtok.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -29060,6 +33247,27 @@ diff -urN a/gopls/internal/lsp/cmd/usage/signature.hlp b/gopls/internal/lsp/cmd/ - $ # 1-indexed location (:line:column or :#offset) of the target identifier - $ gopls signature helper/helper.go:8:6 - $ gopls signature helper/helper.go:#53 +diff -urN a/gopls/internal/lsp/cmd/usage/stats.hlp b/gopls/internal/lsp/cmd/usage/stats.hlp +--- a/gopls/internal/lsp/cmd/usage/stats.hlp 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/cmd/usage/stats.hlp 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +-print workspace statistics +- +-Usage: +- gopls [flags] stats +- +-Load the workspace for the current directory, and output a JSON summary of +-workspace information relevant to performance. As a side effect, this command +-populates the gopls file cache for the current workspace. +- +-By default, this command may include output that refers to the location or +-content of user code. When the -anon flag is set, fields that may refer to user +-code are hidden. +- +-Example: +- $ gopls stats -anon +- -anon +- hide any fields that may contain user names, file names, or source code diff -urN a/gopls/internal/lsp/cmd/usage/symbols.hlp b/gopls/internal/lsp/cmd/usage/symbols.hlp --- a/gopls/internal/lsp/cmd/usage/symbols.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/symbols.hlp 1970-01-01 00:00:00.000000000 +0000 @@ -29074,7 +33282,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/symbols.hlp b/gopls/internal/lsp/cmd/us diff -urN a/gopls/internal/lsp/cmd/usage/usage.hlp b/gopls/internal/lsp/cmd/usage/usage.hlp --- a/gopls/internal/lsp/cmd/usage/usage.hlp 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/usage/usage.hlp 1970-01-01 00:00:00.000000000 +0000 -@@ -1,77 +0,0 @@ +@@ -1,80 +0,0 @@ - -gopls is a Go language server. - @@ -29112,6 +33320,7 @@ diff -urN a/gopls/internal/lsp/cmd/usage/usage.hlp b/gopls/internal/lsp/cmd/usag - rename rename selected identifier - semtok show semantic tokens for the specified file - signature display selected identifier's signature +- stats print workspace statistics - fix apply suggested fixes - symbols display selected file's symbols - workspace_symbol search symbols in workspace @@ -29132,6 +33341,8 @@ diff -urN a/gopls/internal/lsp/cmd/usage/usage.hlp b/gopls/internal/lsp/cmd/usag - the address of the ocagent (e.g. http://localhost:55678), or off (default "off") - -port=int - port on which to run gopls for debugging purposes +- -profile.alloc=string +- write alloc profile to this file - -profile.cpu=string - write CPU profile to this file - -profile.mem=string @@ -29198,8 +33409,8 @@ diff -urN a/gopls/internal/lsp/cmd/usage/workspace_symbol.hlp b/gopls/internal/l - -workspace_symbol-flags: - -matcher=string -- specifies the type of matcher: fuzzy, caseSensitive, or caseInsensitive. -- The default is caseInsensitive. +- specifies the type of matcher: fuzzy, fastfuzzy, casesensitive, or caseinsensitive. +- The default is caseinsensitive. diff -urN a/gopls/internal/lsp/cmd/vulncheck.go b/gopls/internal/lsp/cmd/vulncheck.go --- a/gopls/internal/lsp/cmd/vulncheck.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/vulncheck.go 1970-01-01 00:00:00.000000000 +0000 @@ -29291,7 +33502,7 @@ diff -urN a/gopls/internal/lsp/cmd/vulncheck.go b/gopls/internal/lsp/cmd/vulnche diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/workspace_symbol.go --- a/gopls/internal/lsp/cmd/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/cmd/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,85 +0,0 @@ +@@ -1,89 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -29302,6 +33513,7 @@ diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/ - "context" - "flag" - "fmt" +- "strings" - - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" @@ -29310,7 +33522,7 @@ diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/ - -// workspaceSymbol implements the workspace_symbol verb for gopls. -type workspaceSymbol struct { -- Matcher string `flag:"matcher" help:"specifies the type of matcher: fuzzy, caseSensitive, or caseInsensitive.\nThe default is caseInsensitive."` +- Matcher string `flag:"matcher" help:"specifies the type of matcher: fuzzy, fastfuzzy, casesensitive, or caseinsensitive.\nThe default is caseinsensitive."` - - app *Application -} @@ -29340,10 +33552,10 @@ diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/ - if opts != nil { - opts(o) - } -- switch r.Matcher { +- switch strings.ToLower(r.Matcher) { - case "fuzzy": - o.SymbolMatcher = source.SymbolFuzzy -- case "caseSensitive": +- case "casesensitive": - o.SymbolMatcher = source.SymbolCaseSensitive - case "fastfuzzy": - o.SymbolMatcher = source.SymbolFastFuzzy @@ -29352,7 +33564,7 @@ diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/ - } - } - -- conn, err := r.app.connect(ctx) +- conn, err := r.app.connect(ctx, nil) - if err != nil { - return err - } @@ -29367,7 +33579,10 @@ diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/ - return err - } - for _, s := range symbols { -- f := conn.openFile(ctx, fileURI(s.Location.URI)) +- f, err := conn.openFile(ctx, fileURI(s.Location.URI)) +- if err != nil { +- return err +- } - span, err := f.mapper.LocationSpan(s.Location) - if err != nil { - return err @@ -29380,7 +33595,7 @@ diff -urN a/gopls/internal/lsp/cmd/workspace_symbol.go b/gopls/internal/lsp/cmd/ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.go --- a/gopls/internal/lsp/code_action.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/code_action.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,481 +0,0 @@ +@@ -1,655 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -29390,9 +33605,15 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g -import ( - "context" - "fmt" +- "go/ast" - "sort" - "strings" - +- "golang.org/x/tools/go/ast/inspector" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/analysis/fillstruct" +- "golang.org/x/tools/gopls/internal/lsp/analysis/infertypeargs" +- "golang.org/x/tools/gopls/internal/lsp/analysis/stubmethods" - "golang.org/x/tools/gopls/internal/lsp/command" - "golang.org/x/tools/gopls/internal/lsp/mod" - "golang.org/x/tools/gopls/internal/lsp/protocol" @@ -29404,6 +33625,9 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g -) - -func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) { +- ctx, done := event.Start(ctx, "lsp.Server.codeAction") +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { @@ -29412,219 +33636,263 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - uri := fh.URI() - - // Determine the supported actions for this file kind. -- kind := snapshot.View().FileKind(fh) -- supportedCodeActions, ok := snapshot.View().Options().SupportedCodeActions[kind] +- kind := snapshot.FileKind(fh) +- supportedCodeActions, ok := snapshot.Options().SupportedCodeActions[kind] - if !ok { - return nil, fmt.Errorf("no supported code actions for %v file kind", kind) - } +- if len(supportedCodeActions) == 0 { +- return nil, nil // not an error if there are none supported +- } - - // The Only field of the context specifies which code actions the client wants. - // If Only is empty, assume that the client wants all of the non-explicit code actions. -- var wanted map[protocol.CodeActionKind]bool -- -- // Explicit Code Actions are opt-in and shouldn't be returned to the client unless -- // requested using Only. -- // TODO: Add other CodeLenses such as GoGenerate, RegenerateCgo, etc.. -- explicit := map[protocol.CodeActionKind]bool{ -- protocol.GoTest: true, -- } +- var want map[protocol.CodeActionKind]bool +- { +- // Explicit Code Actions are opt-in and shouldn't be returned to the client unless +- // requested using Only. +- // TODO: Add other CodeLenses such as GoGenerate, RegenerateCgo, etc.. +- explicit := map[protocol.CodeActionKind]bool{ +- protocol.GoTest: true, +- } - -- if len(params.Context.Only) == 0 { -- wanted = supportedCodeActions -- } else { -- wanted = make(map[protocol.CodeActionKind]bool) -- for _, only := range params.Context.Only { -- for k, v := range supportedCodeActions { -- if only == k || strings.HasPrefix(string(k), string(only)+".") { -- wanted[k] = wanted[k] || v +- if len(params.Context.Only) == 0 { +- want = supportedCodeActions +- } else { +- want = make(map[protocol.CodeActionKind]bool) +- for _, only := range params.Context.Only { +- for k, v := range supportedCodeActions { +- if only == k || strings.HasPrefix(string(k), string(only)+".") { +- want[k] = want[k] || v +- } - } +- want[only] = want[only] || explicit[only] - } -- wanted[only] = wanted[only] || explicit[only] - } - } -- if len(supportedCodeActions) == 0 { -- return nil, nil // not an error if there are none supported -- } -- if len(wanted) == 0 { +- if len(want) == 0 { - return nil, fmt.Errorf("no supported code action to execute for %s, wanted %v", uri, params.Context.Only) - } - -- var codeActions []protocol.CodeAction - switch kind { - case source.Mod: -- if diagnostics := params.Context.Diagnostics; len(diagnostics) > 0 { -- diags, err := mod.ModDiagnostics(ctx, snapshot, fh) -- if source.IsNonFatalGoModError(err) { -- return nil, nil -- } -- if err != nil { -- return nil, err -- } -- udiags, err := mod.ModUpgradeDiagnostics(ctx, snapshot, fh) -- if err != nil { -- return nil, err -- } -- quickFixes, err := codeActionsMatchingDiagnostics(ctx, snapshot, diagnostics, append(diags, udiags...)) -- if err != nil { -- return nil, err -- } -- codeActions = append(codeActions, quickFixes...) +- var actions []protocol.CodeAction - -- vdiags, err := mod.ModVulnerabilityDiagnostics(ctx, snapshot, fh) -- if err != nil { -- return nil, err -- } -- // Group vulnerabilities by location and then limit which code actions we return -- // for each location. -- m := make(map[protocol.Range][]*source.Diagnostic) -- for _, v := range vdiags { -- m[v.Range] = append(m[v.Range], v) -- } -- for _, sdiags := range m { -- quickFixes, err = codeActionsMatchingDiagnostics(ctx, snapshot, diagnostics, sdiags) -- if err != nil { -- return nil, err +- fixes, err := s.codeActionsMatchingDiagnostics(ctx, fh.URI(), snapshot, params.Context.Diagnostics, want) +- if err != nil { +- return nil, err +- } +- +- // Group vulnerability fixes by their range, and select only the most +- // appropriate upgrades. +- // +- // TODO(rfindley): can this instead be accomplished on the diagnosis side, +- // so that code action handling remains uniform? +- vulnFixes := make(map[protocol.Range][]protocol.CodeAction) +- searchFixes: +- for _, fix := range fixes { +- for _, diag := range fix.Diagnostics { +- if diag.Source == string(source.Govulncheck) || diag.Source == string(source.Vulncheck) { +- vulnFixes[diag.Range] = append(vulnFixes[diag.Range], fix) +- continue searchFixes - } -- quickFixes = mod.SelectUpgradeCodeActions(quickFixes) -- codeActions = append(codeActions, quickFixes...) - } +- actions = append(actions, fix) - } +- +- for _, fixes := range vulnFixes { +- fixes = mod.SelectUpgradeCodeActions(fixes) +- actions = append(actions, fixes...) +- } +- +- return actions, nil +- - case source.Go: +- diagnostics := params.Context.Diagnostics +- - // Don't suggest fixes for generated files, since they are generally - // not useful and some editors may apply them automatically on save. - if source.IsGenerated(ctx, snapshot, uri) { - return nil, nil - } -- diagnostics := params.Context.Diagnostics - -- // First, process any missing imports and pair them with the -- // diagnostics they fix. -- if wantQuickFixes := wanted[protocol.QuickFix] && len(diagnostics) > 0; wantQuickFixes || wanted[protocol.SourceOrganizeImports] { -- importEdits, importEditsPerFix, err := source.AllImportsFixes(ctx, snapshot, fh) +- actions, err := s.codeActionsMatchingDiagnostics(ctx, uri, snapshot, diagnostics, want) +- if err != nil { +- return nil, err +- } +- +- // Only compute quick fixes if there are any diagnostics to fix. +- wantQuickFixes := want[protocol.QuickFix] && len(diagnostics) > 0 +- +- // Code actions requiring syntax information alone. +- if wantQuickFixes || want[protocol.SourceOrganizeImports] || want[protocol.RefactorExtract] { +- pgf, err := snapshot.ParseGo(ctx, fh, source.ParseFull) - if err != nil { -- event.Error(ctx, "imports fixes", err, tag.File.Of(fh.URI().Filename())) -- } -- // Separate this into a set of codeActions per diagnostic, where -- // each action is the addition, removal, or renaming of one import. -- if wantQuickFixes { -- for _, importFix := range importEditsPerFix { -- fixes := importDiagnostics(importFix.Fix, diagnostics) -- if len(fixes) == 0 { -- continue +- return nil, err +- } +- +- // Process any missing imports and pair them with the diagnostics they +- // fix. +- if wantQuickFixes || want[protocol.SourceOrganizeImports] { +- importEdits, importEditsPerFix, err := source.AllImportsFixes(ctx, snapshot, pgf) +- if err != nil { +- event.Error(ctx, "imports fixes", err, tag.File.Of(fh.URI().Filename())) +- importEdits = nil +- importEditsPerFix = nil +- } +- +- // Separate this into a set of codeActions per diagnostic, where +- // each action is the addition, removal, or renaming of one import. +- if wantQuickFixes { +- for _, importFix := range importEditsPerFix { +- fixed := fixedByImportFix(importFix.Fix, diagnostics) +- if len(fixed) == 0 { +- continue +- } +- actions = append(actions, protocol.CodeAction{ +- Title: importFixTitle(importFix.Fix), +- Kind: protocol.QuickFix, +- Edit: &protocol.WorkspaceEdit{ +- DocumentChanges: documentChanges(fh, importFix.Edits), +- }, +- Diagnostics: fixed, +- }) - } -- codeActions = append(codeActions, protocol.CodeAction{ -- Title: importFixTitle(importFix.Fix), -- Kind: protocol.QuickFix, +- } +- +- // Send all of the import edits as one code action if the file is +- // being organized. +- if want[protocol.SourceOrganizeImports] && len(importEdits) > 0 { +- actions = append(actions, protocol.CodeAction{ +- Title: "Organize Imports", +- Kind: protocol.SourceOrganizeImports, - Edit: &protocol.WorkspaceEdit{ -- DocumentChanges: documentChanges(fh, importFix.Edits), +- DocumentChanges: documentChanges(fh, importEdits), - }, -- Diagnostics: fixes, - }) - } - } - -- // Send all of the import edits as one code action if the file is -- // being organized. -- if wanted[protocol.SourceOrganizeImports] && len(importEdits) > 0 { -- codeActions = append(codeActions, protocol.CodeAction{ -- Title: "Organize Imports", -- Kind: protocol.SourceOrganizeImports, -- Edit: &protocol.WorkspaceEdit{ -- DocumentChanges: documentChanges(fh, importEdits), -- }, -- }) +- if want[protocol.RefactorExtract] { +- extractions, err := refactorExtract(ctx, snapshot, pgf, params.Range) +- if err != nil { +- return nil, err +- } +- actions = append(actions, extractions...) - } - } -- if ctx.Err() != nil { -- return nil, ctx.Err() -- } - -- // Type-check the package and also run analysis, -- // then combine their diagnostics. -- pkg, _, err := source.PackageForFile(ctx, snapshot, fh.URI(), source.NarrowestPackage) -- if err != nil { -- return nil, err -- } -- pkgDiags, err := pkg.DiagnosticsForFile(ctx, snapshot, uri) -- if err != nil { -- return nil, err -- } -- analysisDiags, err := source.Analyze(ctx, snapshot, pkg.Metadata().ID, true) -- if err != nil { -- return nil, err -- } -- var fileDiags []*source.Diagnostic -- source.CombineDiagnostics(pkgDiags, analysisDiags[uri], &fileDiags, &fileDiags) -- -- // Split diagnostics into fixes, which must match incoming diagnostics, -- // and non-fixes, which must match the requested range. Build actions -- // for all of them. -- var fixDiags, nonFixDiags []*source.Diagnostic -- for _, d := range fileDiags { -- if len(d.SuggestedFixes) == 0 { -- continue -- } -- var isFix bool -- for _, fix := range d.SuggestedFixes { -- if fix.ActionKind == protocol.QuickFix || fix.ActionKind == protocol.SourceFixAll { -- isFix = true -- break +- var stubMethodsDiagnostics []protocol.Diagnostic +- if wantQuickFixes && snapshot.Options().IsAnalyzerEnabled(stubmethods.Analyzer.Name) { +- for _, pd := range diagnostics { +- if stubmethods.MatchesMessage(pd.Message) { +- stubMethodsDiagnostics = append(stubMethodsDiagnostics, pd) - } - } -- if isFix { -- fixDiags = append(fixDiags, d) -- } else { -- nonFixDiags = append(nonFixDiags, d) -- } -- } -- -- fixActions, err := codeActionsMatchingDiagnostics(ctx, snapshot, diagnostics, fixDiags) -- if err != nil { -- return nil, err - } -- codeActions = append(codeActions, fixActions...) - -- for _, nonfix := range nonFixDiags { -- // For now, only show diagnostics for matching lines. Maybe we should -- // alter this behavior in the future, depending on the user experience. -- if !protocol.Intersect(nonfix.Range, params.Range) { -- continue -- } -- actions, err := codeActionsForDiagnostic(ctx, snapshot, nonfix, nil) +- // Code actions requiring type information. +- if len(stubMethodsDiagnostics) > 0 || +- want[protocol.RefactorRewrite] || +- want[protocol.RefactorInline] || +- want[protocol.GoTest] { +- pkg, pgf, err := source.NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err - } -- codeActions = append(codeActions, actions...) -- } +- for _, pd := range stubMethodsDiagnostics { +- start, end, err := pgf.RangePos(pd.Range) +- if err != nil { +- return nil, err +- } +- action, ok, err := func() (_ protocol.CodeAction, _ bool, rerr error) { +- // golang/go#61693: code actions were refactored to run outside of the +- // analysis framework, but as a result they lost their panic recovery. +- // +- // Stubmethods "should never fail"", but put back the panic recovery as a +- // defensive measure. +- defer func() { +- if r := recover(); r != nil { +- rerr = bug.Errorf("stubmethods panicked: %v", r) +- } +- }() +- d, ok := stubmethods.DiagnosticForError(pkg.FileSet(), pgf.File, start, end, pd.Message, pkg.GetTypesInfo()) +- if !ok { +- return protocol.CodeAction{}, false, nil +- } +- cmd, err := command.NewApplyFixCommand(d.Message, command.ApplyFixArgs{ +- URI: protocol.URIFromSpanURI(pgf.URI), +- Fix: source.StubMethods, +- Range: pd.Range, +- }) +- if err != nil { +- return protocol.CodeAction{}, false, err +- } +- return protocol.CodeAction{ +- Title: d.Message, +- Kind: protocol.QuickFix, +- Command: &cmd, +- Diagnostics: []protocol.Diagnostic{pd}, +- }, true, nil +- }() +- if err != nil { +- return nil, err +- } +- if ok { +- actions = append(actions, action) +- } +- } - -- if wanted[protocol.RefactorExtract] { -- fixes, err := extractionFixes(ctx, snapshot, uri, params.Range) -- if err != nil { -- return nil, err +- if want[protocol.RefactorRewrite] { +- rewrites, err := refactorRewrite(ctx, snapshot, pkg, pgf, fh, params.Range) +- if err != nil { +- return nil, err +- } +- actions = append(actions, rewrites...) - } -- codeActions = append(codeActions, fixes...) -- } - -- if wanted[protocol.GoTest] { -- fixes, err := goTest(ctx, snapshot, uri, params.Range) -- if err != nil { -- return nil, err +- if want[protocol.RefactorInline] { +- rewrites, err := refactorInline(ctx, snapshot, pkg, pgf, fh, params.Range) +- if err != nil { +- return nil, err +- } +- actions = append(actions, rewrites...) +- } +- +- if want[protocol.GoTest] { +- fixes, err := goTest(ctx, snapshot, pkg, pgf, params.Range) +- if err != nil { +- return nil, err +- } +- actions = append(actions, fixes...) - } -- codeActions = append(codeActions, fixes...) - } - +- return actions, nil +- - default: - // Unsupported file kind for a code action. - return nil, nil - } +-} +- +-func (s *Server) findMatchingDiagnostics(uri span.URI, pd protocol.Diagnostic) []*source.Diagnostic { +- s.diagnosticsMu.Lock() +- defer s.diagnosticsMu.Unlock() - -- var filtered []protocol.CodeAction -- for _, action := range codeActions { -- if wanted[action.Kind] { -- filtered = append(filtered, action) +- var sds []*source.Diagnostic +- for _, report := range s.diagnostics[uri].reports { +- for _, sd := range report.diags { +- sameDiagnostic := (pd.Message == strings.TrimSpace(sd.Message) && // extra space may have been trimmed when converting to protocol.Diagnostic +- protocol.CompareRange(pd.Range, sd.Range) == 0 && +- pd.Source == string(sd.Source)) +- +- if sameDiagnostic { +- sds = append(sds, sd) +- } - } - } -- return filtered, nil +- return sds -} - -func (s *Server) getSupportedCodeActions() []protocol.CodeActionKind { @@ -29657,7 +33925,10 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - return str -} - --func importDiagnostics(fix *imports.ImportFix, diagnostics []protocol.Diagnostic) (results []protocol.Diagnostic) { +-// fixedByImportFix filters the provided slice of diagnostics to those that +-// would be fixed by the provided imports fix. +-func fixedByImportFix(fix *imports.ImportFix, diagnostics []protocol.Diagnostic) []protocol.Diagnostic { +- var results []protocol.Diagnostic - for _, diagnostic := range diagnostics { - switch { - // "undeclared name: X" may be an unresolved import. @@ -29691,23 +33962,16 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - return results -} - --func extractionFixes(ctx context.Context, snapshot source.Snapshot, uri span.URI, rng protocol.Range) ([]protocol.CodeAction, error) { +-func refactorExtract(ctx context.Context, snapshot source.Snapshot, pgf *source.ParsedGoFile, rng protocol.Range) ([]protocol.CodeAction, error) { - if rng.Start == rng.End { - return nil, nil - } -- fh, err := snapshot.GetFile(ctx, uri) -- if err != nil { -- return nil, err -- } -- pgf, err := snapshot.ParseGo(ctx, fh, source.ParseFull) -- if err != nil { -- return nil, fmt.Errorf("getting file for Identifier: %w", err) -- } +- - start, end, err := pgf.RangePos(rng) - if err != nil { - return nil, err - } -- puri := protocol.URIFromSpanURI(uri) +- puri := protocol.URIFromSpanURI(pgf.URI) - var commands []protocol.Command - if _, ok, methodOk, _ := source.CanExtractFunction(pgf.Tok, start, end, pgf.Src, pgf.File); ok { - cmd, err := command.NewApplyFixCommand("Extract function", command.ApplyFixArgs{ @@ -29753,6 +34017,126 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - return actions, nil -} - +-func refactorRewrite(ctx context.Context, snapshot source.Snapshot, pkg source.Package, pgf *source.ParsedGoFile, fh source.FileHandle, rng protocol.Range) (_ []protocol.CodeAction, rerr error) { +- // golang/go#61693: code actions were refactored to run outside of the +- // analysis framework, but as a result they lost their panic recovery. +- // +- // These code actions should never fail, but put back the panic recovery as a +- // defensive measure. +- defer func() { +- if r := recover(); r != nil { +- rerr = bug.Errorf("refactor.rewrite code actions panicked: %v", r) +- } +- }() +- start, end, err := pgf.RangePos(rng) +- if err != nil { +- return nil, err +- } +- +- var commands []protocol.Command +- if _, ok, _ := source.CanInvertIfCondition(pgf.File, start, end); ok { +- cmd, err := command.NewApplyFixCommand("Invert if condition", command.ApplyFixArgs{ +- URI: protocol.URIFromSpanURI(pgf.URI), +- Fix: source.InvertIfCondition, +- Range: rng, +- }) +- if err != nil { +- return nil, err +- } +- commands = append(commands, cmd) +- } +- +- // N.B.: an inspector only pays for itself after ~5 passes, which means we're +- // currently not getting a good deal on this inspection. +- // +- // TODO: Consider removing the inspection after convenienceAnalyzers are removed. +- inspect := inspector.New([]*ast.File{pgf.File}) +- if snapshot.Options().IsAnalyzerEnabled(fillstruct.Analyzer.Name) { +- for _, d := range fillstruct.DiagnoseFillableStructs(inspect, start, end, pkg.GetTypes(), pkg.GetTypesInfo()) { +- rng, err := pgf.Mapper.PosRange(pgf.Tok, d.Pos, d.End) +- if err != nil { +- return nil, err +- } +- cmd, err := command.NewApplyFixCommand(d.Message, command.ApplyFixArgs{ +- URI: protocol.URIFromSpanURI(pgf.URI), +- Fix: source.FillStruct, +- Range: rng, +- }) +- if err != nil { +- return nil, err +- } +- commands = append(commands, cmd) +- } +- } +- +- var actions []protocol.CodeAction +- for i := range commands { +- actions = append(actions, protocol.CodeAction{ +- Title: commands[i].Title, +- Kind: protocol.RefactorRewrite, +- Command: &commands[i], +- }) +- } +- +- if snapshot.Options().IsAnalyzerEnabled(infertypeargs.Analyzer.Name) { +- for _, d := range infertypeargs.DiagnoseInferableTypeArgs(pkg.FileSet(), inspect, start, end, pkg.GetTypes(), pkg.GetTypesInfo()) { +- if len(d.SuggestedFixes) != 1 { +- panic(fmt.Sprintf("unexpected number of suggested fixes from infertypeargs: %v", len(d.SuggestedFixes))) +- } +- fix := d.SuggestedFixes[0] +- var edits []protocol.TextEdit +- for _, analysisEdit := range fix.TextEdits { +- rng, err := pgf.Mapper.PosRange(pgf.Tok, analysisEdit.Pos, analysisEdit.End) +- if err != nil { +- return nil, err +- } +- edits = append(edits, protocol.TextEdit{ +- Range: rng, +- NewText: string(analysisEdit.NewText), +- }) +- } +- actions = append(actions, protocol.CodeAction{ +- Title: "Simplify type arguments", +- Kind: protocol.RefactorRewrite, +- Edit: &protocol.WorkspaceEdit{ +- DocumentChanges: documentChanges(fh, edits), +- }, +- }) +- } +- } +- +- return actions, nil +-} +- +-// refactorInline returns inline actions available at the specified range. +-func refactorInline(ctx context.Context, snapshot source.Snapshot, pkg source.Package, pgf *source.ParsedGoFile, fh source.FileHandle, rng protocol.Range) ([]protocol.CodeAction, error) { +- var commands []protocol.Command +- +- // If range is within call expression, offer inline action. +- if _, fn, err := source.EnclosingStaticCall(pkg, pgf, rng); err == nil { +- cmd, err := command.NewApplyFixCommand(fmt.Sprintf("Inline call to %s", fn.Name()), command.ApplyFixArgs{ +- URI: protocol.URIFromSpanURI(pgf.URI), +- Fix: source.InlineCall, +- Range: rng, +- }) +- if err != nil { +- return nil, err +- } +- commands = append(commands, cmd) +- } +- +- // Convert commands to actions. +- var actions []protocol.CodeAction +- for i := range commands { +- actions = append(actions, protocol.CodeAction{ +- Title: commands[i].Title, +- Kind: protocol.RefactorInline, +- Command: &commands[i], +- }) +- } +- return actions, nil +-} +- -func documentChanges(fh source.FileHandle, edits []protocol.TextEdit) []protocol.DocumentChanges { - return []protocol.DocumentChanges{ - { @@ -29763,41 +34147,55 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - URI: protocol.URIFromSpanURI(fh.URI()), - }, - }, -- Edits: edits, +- Edits: nonNilSliceTextEdit(edits), - }, - }, - } -} - --func codeActionsMatchingDiagnostics(ctx context.Context, snapshot source.Snapshot, pdiags []protocol.Diagnostic, sdiags []*source.Diagnostic) ([]protocol.CodeAction, error) { +-// codeActionsMatchingDiagnostics fetches code actions for the provided +-// diagnostics, by first attempting to unmarshal code actions directly from the +-// bundled protocol.Diagnostic.Data field, and failing that by falling back on +-// fetching a matching source.Diagnostic from the set of stored diagnostics for +-// this file. +-func (s *Server) codeActionsMatchingDiagnostics(ctx context.Context, uri span.URI, snapshot source.Snapshot, pds []protocol.Diagnostic, want map[protocol.CodeActionKind]bool) ([]protocol.CodeAction, error) { - var actions []protocol.CodeAction -- for _, sd := range sdiags { -- var diag *protocol.Diagnostic -- for _, pd := range pdiags { -- if sameDiagnostic(pd, sd) { -- diag = &pd -- break +- var unbundled []protocol.Diagnostic // diagnostics without bundled code actions in their Data field +- for _, pd := range pds { +- bundled := source.BundledQuickFixes(pd) +- if len(bundled) > 0 { +- for _, fix := range bundled { +- if want[fix.Kind] { +- actions = append(actions, fix) +- } - } +- } else { +- // No bundled actions: keep searching for a match. +- unbundled = append(unbundled, pd) - } -- if diag == nil { -- continue -- } -- diagActions, err := codeActionsForDiagnostic(ctx, snapshot, sd, diag) -- if err != nil { -- return nil, err -- } -- actions = append(actions, diagActions...) +- } - +- for _, pd := range unbundled { +- for _, sd := range s.findMatchingDiagnostics(uri, pd) { +- diagActions, err := codeActionsForDiagnostic(ctx, snapshot, sd, &pd, want) +- if err != nil { +- return nil, err +- } +- actions = append(actions, diagActions...) +- } - } - return actions, nil -} - --func codeActionsForDiagnostic(ctx context.Context, snapshot source.Snapshot, sd *source.Diagnostic, pd *protocol.Diagnostic) ([]protocol.CodeAction, error) { +-func codeActionsForDiagnostic(ctx context.Context, snapshot source.Snapshot, sd *source.Diagnostic, pd *protocol.Diagnostic, want map[protocol.CodeActionKind]bool) ([]protocol.CodeAction, error) { - var actions []protocol.CodeAction - for _, fix := range sd.SuggestedFixes { -- var changes []protocol.DocumentChanges +- if !want[fix.ActionKind] { +- continue +- } +- changes := []protocol.DocumentChanges{} // must be a slice - for uri, edits := range fix.Edits { -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -29811,25 +34209,14 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - }, - Command: fix.Command, - } -- if pd != nil { -- action.Diagnostics = []protocol.Diagnostic{*pd} -- } +- action.Diagnostics = []protocol.Diagnostic{*pd} - actions = append(actions, action) - } - return actions, nil -} - --func sameDiagnostic(pd protocol.Diagnostic, sd *source.Diagnostic) bool { -- return pd.Message == strings.TrimSpace(sd.Message) && // extra space may have been trimmed when converting to protocol.Diagnostic -- protocol.CompareRange(pd.Range, sd.Range) == 0 && pd.Source == string(sd.Source) --} -- --func goTest(ctx context.Context, snapshot source.Snapshot, uri span.URI, rng protocol.Range) ([]protocol.CodeAction, error) { -- fh, err := snapshot.GetFile(ctx, uri) -- if err != nil { -- return nil, err -- } -- fns, err := source.TestsAndBenchmarks(ctx, snapshot, fh) +-func goTest(ctx context.Context, snapshot source.Snapshot, pkg source.Package, pgf *source.ParsedGoFile, rng protocol.Range) ([]protocol.CodeAction, error) { +- fns, err := source.TestsAndBenchmarks(ctx, snapshot, pkg, pgf) - if err != nil { - return nil, err - } @@ -29852,7 +34239,7 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - return nil, nil - } - -- cmd, err := command.NewTestCommand("Run tests and benchmarks", protocol.URIFromSpanURI(uri), tests, benchmarks) +- cmd, err := command.NewTestCommand("Run tests and benchmarks", protocol.URIFromSpanURI(pgf.URI), tests, benchmarks) - if err != nil { - return nil, err - } @@ -29862,10 +34249,12 @@ diff -urN a/gopls/internal/lsp/code_action.go b/gopls/internal/lsp/code_action.g - Command: &cmd, - }}, nil -} +- +-type unit = struct{} diff -urN a/gopls/internal/lsp/code_lens.go b/gopls/internal/lsp/code_lens.go --- a/gopls/internal/lsp/code_lens.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/code_lens.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,57 +0,0 @@ +@@ -1,61 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -29882,16 +34271,20 @@ diff -urN a/gopls/internal/lsp/code_lens.go b/gopls/internal/lsp/code_lens.go - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) codeLens(ctx context.Context, params *protocol.CodeLensParams) ([]protocol.CodeLens, error) { +- ctx, done := event.Start(ctx, "lsp.Server.codeLens", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { - return nil, err - } - var lenses map[command.Command]source.LensFunc -- switch snapshot.View().FileKind(fh) { +- switch snapshot.FileKind(fh) { - case source.Mod: - lenses = mod.LensFuncs() - case source.Go: @@ -29902,7 +34295,7 @@ diff -urN a/gopls/internal/lsp/code_lens.go b/gopls/internal/lsp/code_lens.go - } - var result []protocol.CodeLens - for cmd, lf := range lenses { -- if !snapshot.View().Options().Codelenses[string(cmd)] { +- if !snapshot.Options().Codelenses[string(cmd)] { - continue - } - added, err := lf(ctx, snapshot, fh) @@ -29926,7 +34319,7 @@ diff -urN a/gopls/internal/lsp/code_lens.go b/gopls/internal/lsp/code_lens.go diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/command/command_gen.go --- a/gopls/internal/lsp/command/command_gen.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/command/command_gen.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,509 +0,0 @@ +@@ -1,585 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -29936,10 +34329,10 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma -//go:build !generate -// +build !generate - --package command -- -// Code generated by generate.go. DO NOT EDIT. - +-package command +- -import ( - "context" - "fmt" @@ -29963,15 +34356,19 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - RegenerateCgo Command = "regenerate_cgo" - RemoveDependency Command = "remove_dependency" - ResetGoModDiagnostics Command = "reset_go_mod_diagnostics" +- RunGoWorkCommand Command = "run_go_work_command" - RunGovulncheck Command = "run_govulncheck" - RunTests Command = "run_tests" - StartDebugging Command = "start_debugging" +- StartProfile Command = "start_profile" +- StopProfile Command = "stop_profile" - Test Command = "test" - Tidy Command = "tidy" - ToggleGCDetails Command = "toggle_gc_details" - UpdateGoSum Command = "update_go_sum" - UpgradeDependency Command = "upgrade_dependency" - Vendor Command = "vendor" +- WorkspaceStats Command = "workspace_stats" -) - -var Commands = []Command{ @@ -29990,15 +34387,19 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - RegenerateCgo, - RemoveDependency, - ResetGoModDiagnostics, +- RunGoWorkCommand, - RunGovulncheck, - RunTests, - StartDebugging, +- StartProfile, +- StopProfile, - Test, - Tidy, - ToggleGCDetails, - UpdateGoSum, - UpgradeDependency, - Vendor, +- WorkspaceStats, -} - -func Dispatch(ctx context.Context, params *protocol.ExecuteCommandParams, s Interface) (interface{}, error) { @@ -30089,6 +34490,12 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - return nil, err - } - return nil, s.ResetGoModDiagnostics(ctx, a0) +- case "gopls.run_go_work_command": +- var a0 RunGoWorkArgs +- if err := UnmarshalArgs(params.Arguments, &a0); err != nil { +- return nil, err +- } +- return nil, s.RunGoWorkCommand(ctx, a0) - case "gopls.run_govulncheck": - var a0 VulncheckArgs - if err := UnmarshalArgs(params.Arguments, &a0); err != nil { @@ -30107,6 +34514,18 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - return nil, err - } - return s.StartDebugging(ctx, a0) +- case "gopls.start_profile": +- var a0 StartProfileArgs +- if err := UnmarshalArgs(params.Arguments, &a0); err != nil { +- return nil, err +- } +- return s.StartProfile(ctx, a0) +- case "gopls.stop_profile": +- var a0 StopProfileArgs +- if err := UnmarshalArgs(params.Arguments, &a0); err != nil { +- return nil, err +- } +- return s.StopProfile(ctx, a0) - case "gopls.test": - var a0 protocol.DocumentURI - var a1 []string @@ -30145,6 +34564,8 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - return nil, err - } - return nil, s.Vendor(ctx, a0) +- case "gopls.workspace_stats": +- return s.WorkspaceStats(ctx) - } - return nil, fmt.Errorf("unsupported command %q", params.Command) -} @@ -30329,6 +34750,18 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - }, nil -} - +-func NewRunGoWorkCommandCommand(title string, a0 RunGoWorkArgs) (protocol.Command, error) { +- args, err := MarshalArgs(a0) +- if err != nil { +- return protocol.Command{}, err +- } +- return protocol.Command{ +- Title: title, +- Command: "gopls.run_go_work_command", +- Arguments: args, +- }, nil +-} +- -func NewRunGovulncheckCommand(title string, a0 VulncheckArgs) (protocol.Command, error) { - args, err := MarshalArgs(a0) - if err != nil { @@ -30365,6 +34798,30 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - }, nil -} - +-func NewStartProfileCommand(title string, a0 StartProfileArgs) (protocol.Command, error) { +- args, err := MarshalArgs(a0) +- if err != nil { +- return protocol.Command{}, err +- } +- return protocol.Command{ +- Title: title, +- Command: "gopls.start_profile", +- Arguments: args, +- }, nil +-} +- +-func NewStopProfileCommand(title string, a0 StopProfileArgs) (protocol.Command, error) { +- args, err := MarshalArgs(a0) +- if err != nil { +- return protocol.Command{}, err +- } +- return protocol.Command{ +- Title: title, +- Command: "gopls.stop_profile", +- Arguments: args, +- }, nil +-} +- -func NewTestCommand(title string, a0 protocol.DocumentURI, a1 []string, a2 []string) (protocol.Command, error) { - args, err := MarshalArgs(a0, a1, a2) - if err != nil { @@ -30436,6 +34893,18 @@ diff -urN a/gopls/internal/lsp/command/command_gen.go b/gopls/internal/lsp/comma - Arguments: args, - }, nil -} +- +-func NewWorkspaceStatsCommand(title string) (protocol.Command, error) { +- args, err := MarshalArgs() +- if err != nil { +- return protocol.Command{}, err +- } +- return protocol.Command{ +- Title: title, +- Command: "gopls.workspace_stats", +- Arguments: args, +- }, nil +-} diff -urN a/gopls/internal/lsp/command/commandmeta/meta.go b/gopls/internal/lsp/command/commandmeta/meta.go --- a/gopls/internal/lsp/command/commandmeta/meta.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/command/commandmeta/meta.go 1970-01-01 00:00:00.000000000 +0000 @@ -30717,8 +35186,8 @@ diff -urN a/gopls/internal/lsp/command/gen/gen.go b/gopls/internal/lsp/command/g - "go/types" - "text/template" - -- "golang.org/x/tools/internal/imports" - "golang.org/x/tools/gopls/internal/lsp/command/commandmeta" +- "golang.org/x/tools/internal/imports" -) - -const src = `// Copyright 2021 The Go Authors. All rights reserved. @@ -30730,10 +35199,10 @@ diff -urN a/gopls/internal/lsp/command/gen/gen.go b/gopls/internal/lsp/command/g -//go:build !generate -// +build !generate - --package command -- -// Code generated by generate.go. DO NOT EDIT. - +-package command +- -import ( - {{range $k, $v := .Imports -}} - "{{$k}}" @@ -30890,7 +35359,7 @@ diff -urN a/gopls/internal/lsp/command/generate.go b/gopls/internal/lsp/command/ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command/interface.go --- a/gopls/internal/lsp/command/interface.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/command/interface.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,410 +0,0 @@ +@@ -1,501 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -31038,6 +35507,21 @@ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command - // address. - StartDebugging(context.Context, DebuggingArgs) (DebuggingResult, error) - +- // StartProfile: start capturing a profile of gopls' execution. +- // +- // Start a new pprof profile. Before using the resulting file, profiling must +- // be stopped with a corresponding call to StopProfile. +- // +- // This command is intended for internal use only, by the gopls benchmark +- // runner. +- StartProfile(context.Context, StartProfileArgs) (StartProfileResult, error) +- +- // StopProfile: stop an ongoing profile. +- // +- // This command is intended for internal use only, by the gopls benchmark +- // runner. +- StopProfile(context.Context, StopProfileArgs) (StopProfileResult, error) +- - // RunGovulncheck: Run govulncheck. - // - // Run vulnerability check (`govulncheck`). @@ -31055,6 +35539,18 @@ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command - // - // This command is used for benchmarking, and may change in the future. - MemStats(context.Context) (MemStatsResult, error) +- +- // WorkspaceStats: fetch workspace statistics +- // +- // Query statistics about workspace builds, modules, packages, and files. +- // +- // This command is intended for internal use only, by the gopls stats +- // command. +- WorkspaceStats(context.Context) (WorkspaceStatsResult, error) +- +- // RunGoWorkCommand: run `go work [args...]`, and apply the resulting go.work +- // edits to the current go.work file. +- RunGoWorkCommand(context.Context, RunGoWorkArgs) error -} - -type RunTestsArgs struct { @@ -31117,7 +35613,10 @@ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command - // The go.mod file URI. - URI protocol.DocumentURI - // The module path to remove. -- ModulePath string +- ModulePath string +- // If the module is tidied apart from the one unused diagnostic, we can +- // run `go get module@none`, and then run `go mod tidy`. Otherwise, we +- // must make textual edits. - OnlyDiagnostic bool -} - @@ -31205,6 +35704,30 @@ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command - URLs []string -} - +-// StartProfileArgs holds the arguments to the StartProfile command. +-// +-// It is a placeholder for future compatibility. +-type StartProfileArgs struct { +-} +- +-// StartProfileResult holds the result of the StartProfile command. +-// +-// It is a placeholder for future compatibility. +-type StartProfileResult struct { +-} +- +-// StopProfileArgs holds the arguments to the StopProfile command. +-// +-// It is a placeholder for future compatibility. +-type StopProfileArgs struct { +-} +- +-// StopProfileResult holds the result to the StopProfile command. +-type StopProfileResult struct { +- // File is the profile file name. +- File string +-} +- -type ResetGoModDiagnosticsArgs struct { - URIArg - @@ -31298,13 +35821,50 @@ diff -urN a/gopls/internal/lsp/command/interface.go b/gopls/internal/lsp/command - -// MemStatsResult holds selected fields from runtime.MemStats. -type MemStatsResult struct { -- HeapAlloc uint64 -- HeapInUse uint64 +- HeapAlloc uint64 +- HeapInUse uint64 +- TotalAlloc uint64 +-} +- +-// WorkspaceStatsResult returns information about the size and shape of the +-// workspace. +-type WorkspaceStatsResult struct { +- Files FileStats // file stats for the cache +- Views []ViewStats // stats for each view in the session +-} +- +-// FileStats holds information about a set of files. +-type FileStats struct { +- Total int // total number of files +- Largest int // number of bytes in the largest file +- Errs int // number of files that could not be read +-} +- +-// ViewStats holds information about a single View in the session. +-type ViewStats struct { +- GoCommandVersion string // version of the Go command resolved for this view +- AllPackages PackageStats // package info for all packages (incl. dependencies) +- WorkspacePackages PackageStats // package info for workspace packages +- Diagnostics int // total number of diagnostics in the workspace +-} +- +-// PackageStats holds information about a collection of packages. +-type PackageStats struct { +- Packages int // total number of packages +- LargestPackage int // number of files in the largest package +- CompiledGoFiles int // total number of compiled Go files across all packages +- Modules int // total number of unique modules +-} +- +-type RunGoWorkArgs struct { +- ViewID string // ID of the view to run the command from +- InitFirst bool // Whether to run `go work init` first +- Args []string // Args to pass to `go work` -} diff -urN a/gopls/internal/lsp/command/interface_test.go b/gopls/internal/lsp/command/interface_test.go --- a/gopls/internal/lsp/command/interface_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/command/interface_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ +@@ -1,32 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -31321,7 +35881,8 @@ diff -urN a/gopls/internal/lsp/command/interface_test.go b/gopls/internal/lsp/co -) - -func TestGenerated(t *testing.T) { -- testenv.NeedsGoBuild(t) // This is a lie. We actually need the source code. +- testenv.NeedsGoPackages(t) +- testenv.NeedsLocalXTools(t) - - onDisk, err := ioutil.ReadFile("command_gen.go") - if err != nil { @@ -31339,7 +35900,7 @@ diff -urN a/gopls/internal/lsp/command/interface_test.go b/gopls/internal/lsp/co diff -urN a/gopls/internal/lsp/command/util.go b/gopls/internal/lsp/command/util.go --- a/gopls/internal/lsp/command/util.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/command/util.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,63 +0,0 @@ +@@ -1,64 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -31358,6 +35919,7 @@ diff -urN a/gopls/internal/lsp/command/util.go b/gopls/internal/lsp/command/util - -type Command string - +-// ID returns the command identifier to use in the executeCommand request. -func (c Command) ID() string { - return ID(string(c)) -} @@ -31406,7 +35968,7 @@ diff -urN a/gopls/internal/lsp/command/util.go b/gopls/internal/lsp/command/util diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go --- a/gopls/internal/lsp/command.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/command.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,964 +0,0 @@ +@@ -1,1232 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -31420,18 +35982,20 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - "errors" - "fmt" - "io" -- "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" +- "runtime/pprof" - "sort" - "strings" - "time" - - "golang.org/x/mod/modfile" - "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/govulncheck" +- "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/command" - "golang.org/x/tools/gopls/internal/lsp/debug" - "golang.org/x/tools/gopls/internal/lsp/progress" @@ -31441,10 +36005,14 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - "golang.org/x/tools/gopls/internal/vulncheck" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/gocommand" +- "golang.org/x/tools/internal/tokeninternal" - "golang.org/x/tools/internal/xcontext" -) - -func (s *Server) executeCommand(ctx context.Context, params *protocol.ExecuteCommandParams) (interface{}, error) { +- ctx, done := event.Start(ctx, "lsp.Server.executeCommand") +- defer done() +- - var found bool - for _, name := range s.session.Options().SupportedCommands { - if name == params.Command { @@ -31473,6 +36041,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - async bool // whether to run the command asynchronously. Async commands can only return errors. - requireSave bool // whether all files must be saved for the command to work - progress string // title to use for progress reporting. If empty, no progress will be reported. +- forView string // view to resolve to a snapshot; incompatible with forURI - forURI protocol.DocumentURI // URI to resolve to a snapshot. If unset, snapshot will be nil. -} - @@ -31507,6 +36076,9 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - } - } - var deps commandDeps +- if cfg.forURI != "" && cfg.forView != "" { +- return bug.Errorf("internal error: forURI=%q, forView=%q", cfg.forURI, cfg.forView) +- } - if cfg.forURI != "" { - var ok bool - var release func() @@ -31518,6 +36090,17 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - } - return fmt.Errorf("invalid file URL: %v", cfg.forURI) - } +- } else if cfg.forView != "" { +- view, err := c.s.session.View(cfg.forView) +- if err != nil { +- return err +- } +- var release func() +- deps.snapshot, release, err = view.Snapshot() +- if err != nil { +- return err +- } +- defer release() - } - ctx, cancel := context.WithCancel(xcontext.Detach(ctx)) - if cfg.progress != "" { @@ -31564,7 +36147,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - if err != nil { - return err - } -- var changes []protocol.DocumentChanges +- changes := []protocol.DocumentChanges{} // must be a slice - for _, edit := range edits { - edit := edit - changes = append(changes, protocol.DocumentChanges{ @@ -31609,7 +36192,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - } - deps.snapshot.View().RegisterModuleUpgrades(args.URI.SpanURI(), upgrades) - // Re-diagnose the snapshot to publish the new module diagnostics. -- c.s.diagnoseSnapshot(deps.snapshot, nil, false) +- c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0) - return nil - }) -} @@ -31640,7 +36223,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - } - - // Re-diagnose the snapshot to remove the diagnostics. -- c.s.diagnoseSnapshot(deps.snapshot, nil, false) +- c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0) - return nil - }) -} @@ -31748,10 +36331,9 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - progress: "Removing dependency", - forURI: args.URI, - }, func(ctx context.Context, deps commandDeps) error { -- // If the module is tidied apart from the one unused diagnostic, we can -- // run `go get module@none`, and then run `go mod tidy`. Otherwise, we -- // must make textual edits. -- // TODO(rstambler): In Go 1.17+, we will be able to use the go command +- // See the documentation for OnlyDiagnostic. +- // +- // TODO(rfindley): In Go 1.17+, we will be able to use the go command - // without checking if the module is tidy. - if args.OnlyDiagnostic { - return c.s.runGoModUpdateCommands(ctx, deps.snapshot, args.URI.SpanURI(), func(invoke func(...string) (*bytes.Buffer, error)) error { @@ -31781,7 +36363,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - URI: protocol.URIFromSpanURI(deps.fh.URI()), - }, - }, -- Edits: edits, +- Edits: nonNilSliceTextEdit(edits), - }, - }, - }, @@ -31815,7 +36397,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - return nil, err - } - // Calculate the edits to be made due to the change. -- diff := snapshot.View().Options().ComputeEdits(string(pm.Mapper.Content), string(newContent)) +- diff := snapshot.Options().ComputeEdits(string(pm.Mapper.Content), string(newContent)) - return source.ToProtocolEdits(pm.Mapper, diff) -} - @@ -31843,15 +36425,11 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - -func (c *commandHandler) runTests(ctx context.Context, snapshot source.Snapshot, work *progress.WorkDone, uri protocol.DocumentURI, tests, benchmarks []string) error { - // TODO: fix the error reporting when this runs async. -- metas, err := snapshot.MetadataForFile(ctx, uri.SpanURI()) +- meta, err := source.NarrowestMetadataForFile(ctx, snapshot, uri.SpanURI()) - if err != nil { - return err - } -- metas = source.RemoveIntermediateTestVariants(metas) -- if len(metas) == 0 { -- return fmt.Errorf("package could not be found for file: %s", uri.SpanURI().Filename()) -- } -- pkgPath := string(metas[0].ForTest) +- pkgPath := string(meta.ForTest) - - // create output - buf := &bytes.Buffer{} @@ -31984,48 +36562,35 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - } - modURI := snapshot.GoModForFile(uri) - sumURI := span.URIFromPath(strings.TrimSuffix(modURI.Filename(), ".mod") + ".sum") -- modEdits, err := applyFileEdits(ctx, snapshot, modURI, newModBytes) +- modEdits, err := collectFileEdits(ctx, snapshot, modURI, newModBytes) - if err != nil { - return err - } -- sumEdits, err := applyFileEdits(ctx, snapshot, sumURI, newSumBytes) +- sumEdits, err := collectFileEdits(ctx, snapshot, sumURI, newSumBytes) - if err != nil { - return err - } -- changes := append(sumEdits, modEdits...) -- if len(changes) == 0 { -- return nil -- } -- var documentChanges []protocol.DocumentChanges -- for _, change := range changes { -- change := change -- documentChanges = append(documentChanges, protocol.DocumentChanges{ -- TextDocumentEdit: &change, -- }) -- } -- response, err := s.client.ApplyEdit(ctx, &protocol.ApplyWorkspaceEditParams{ -- Edit: protocol.WorkspaceEdit{ -- DocumentChanges: documentChanges, -- }, -- }) -- if err != nil { -- return err -- } -- if !response.Applied { -- return fmt.Errorf("edits not applied because of %s", response.FailureReason) -- } -- return nil +- return applyFileEdits(ctx, s.client, append(sumEdits, modEdits...)) -} - --func applyFileEdits(ctx context.Context, snapshot source.Snapshot, uri span.URI, newContent []byte) ([]protocol.TextDocumentEdit, error) { -- fh, err := snapshot.GetFile(ctx, uri) +-// collectFileEdits collects any file edits required to transform the snapshot +-// file specified by uri to the provided new content. +-// +-// If the file is not open, collectFileEdits simply writes the new content to +-// disk. +-// +-// TODO(rfindley): fix this API asymmetry. It should be up to the caller to +-// write the file or apply the edits. +-func collectFileEdits(ctx context.Context, snapshot source.Snapshot, uri span.URI, newContent []byte) ([]protocol.TextDocumentEdit, error) { +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return nil, err - } -- oldContent, err := fh.Read() +- oldContent, err := fh.Content() - if err != nil && !os.IsNotExist(err) { - return nil, err - } +- - if bytes.Equal(oldContent, newContent) { - return nil, nil - } @@ -32034,12 +36599,12 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - // file and leave it unsaved. We would rather apply the changes directly, - // especially to go.sum, which should be mostly invisible to the user. - if !snapshot.IsOpen(uri) { -- err := ioutil.WriteFile(uri.Filename(), newContent, 0666) +- err := os.WriteFile(uri.Filename(), newContent, 0666) - return nil, err - } - - m := protocol.NewMapper(fh.URI(), oldContent) -- diff := snapshot.View().Options().ComputeEdits(string(oldContent), string(newContent)) +- diff := snapshot.Options().ComputeEdits(string(oldContent), string(newContent)) - edits, err := source.ToProtocolEdits(m, diff) - if err != nil { - return nil, err @@ -32055,6 +36620,31 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - }}, nil -} - +-func applyFileEdits(ctx context.Context, cli protocol.Client, edits []protocol.TextDocumentEdit) error { +- if len(edits) == 0 { +- return nil +- } +- documentChanges := []protocol.DocumentChanges{} // must be a slice +- for _, change := range edits { +- change := change +- documentChanges = append(documentChanges, protocol.DocumentChanges{ +- TextDocumentEdit: &change, +- }) +- } +- response, err := cli.ApplyEdit(ctx, &protocol.ApplyWorkspaceEditParams{ +- Edit: protocol.WorkspaceEdit{ +- DocumentChanges: documentChanges, +- }, +- }) +- if err != nil { +- return err +- } +- if !response.Applied { +- return fmt.Errorf("edits not applied because of %s", response.FailureReason) +- } +- return nil +-} +- -func runGoGetModule(invoke func(...string) (*bytes.Buffer, error), addRequire bool, args []string) error { - if addRequire { - if err := addModuleRequire(invoke, args); err != nil { @@ -32109,20 +36699,19 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - progress: "Toggling GC Details", - forURI: args.URI, - }, func(ctx context.Context, deps commandDeps) error { -- metas, err := deps.snapshot.MetadataForFile(ctx, deps.fh.URI()) +- meta, err := source.NarrowestMetadataForFile(ctx, deps.snapshot, deps.fh.URI()) - if err != nil { - return err - } -- id := metas[0].ID // 0 => narrowest package - c.s.gcOptimizationDetailsMu.Lock() -- if _, ok := c.s.gcOptimizationDetails[id]; ok { -- delete(c.s.gcOptimizationDetails, id) +- if _, ok := c.s.gcOptimizationDetails[meta.ID]; ok { +- delete(c.s.gcOptimizationDetails, meta.ID) - c.s.clearDiagnosticSource(gcDetailsSource) - } else { -- c.s.gcOptimizationDetails[id] = struct{}{} +- c.s.gcOptimizationDetails[meta.ID] = struct{}{} - } - c.s.gcOptimizationDetailsMu.Unlock() -- c.s.diagnoseSnapshot(deps.snapshot, nil, false) +- c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0) - return nil - }) -} @@ -32147,7 +36736,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - err := c.run(ctx, commandConfig{ - forURI: args.URI, - }, func(ctx context.Context, deps commandDeps) error { -- fh, err := deps.snapshot.GetFile(ctx, args.URI.SpanURI()) +- fh, err := deps.snapshot.ReadFile(ctx, args.URI.SpanURI()) - if err != nil { - return err - } @@ -32155,7 +36744,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - if err != nil { - return err - } -- fset := source.FileSetFor(pgf.Tok) +- fset := tokeninternal.FileSetFor(pgf.Tok) - for _, group := range astutil.Imports(fset, pgf.File) { - for _, imp := range group { - if imp.Path == nil { @@ -32171,14 +36760,11 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - }) - } - } -- metas, err := deps.snapshot.MetadataForFile(ctx, args.URI.SpanURI()) +- meta, err := source.NarrowestMetadataForFile(ctx, deps.snapshot, args.URI.SpanURI()) - if err != nil { - return err // e.g. cancelled - } -- if len(metas) == 0 { -- return fmt.Errorf("no package containing %v", args.URI.SpanURI()) -- } -- for pkgPath := range metas[0].DepsByPkgPath { // 0 => narrowest package +- for pkgPath := range meta.DepsByPkgPath { - result.PackageImports = append(result.PackageImports, - command.PackageImport{Path: string(pkgPath)}) - } @@ -32224,6 +36810,49 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - return result, fmt.Errorf("starting debug server: %w", err) - } - result.URLs = []string{"http://" + listenedAddr} +- openClientBrowser(ctx, c.s.client, result.URLs[0]) +- return result, nil +-} +- +-func (c *commandHandler) StartProfile(ctx context.Context, args command.StartProfileArgs) (result command.StartProfileResult, _ error) { +- file, err := os.CreateTemp("", "gopls-profile-*") +- if err != nil { +- return result, fmt.Errorf("creating temp profile file: %v", err) +- } +- +- c.s.ongoingProfileMu.Lock() +- defer c.s.ongoingProfileMu.Unlock() +- +- if c.s.ongoingProfile != nil { +- file.Close() // ignore error +- return result, fmt.Errorf("profile already started (for %q)", c.s.ongoingProfile.Name()) +- } +- +- if err := pprof.StartCPUProfile(file); err != nil { +- file.Close() // ignore error +- return result, fmt.Errorf("starting profile: %v", err) +- } +- +- c.s.ongoingProfile = file +- return result, nil +-} +- +-func (c *commandHandler) StopProfile(ctx context.Context, args command.StopProfileArgs) (result command.StopProfileResult, _ error) { +- c.s.ongoingProfileMu.Lock() +- defer c.s.ongoingProfileMu.Unlock() +- +- prof := c.s.ongoingProfile +- c.s.ongoingProfile = nil +- +- if prof == nil { +- return result, fmt.Errorf("no ongoing profile") +- } +- +- pprof.StopCPUProfile() +- if err := prof.Close(); err != nil { +- return result, fmt.Errorf("closing profile file: %v", err) +- } +- result.File = prof.Name() - return result, nil -} - @@ -32241,7 +36870,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go -func (c *commandHandler) FetchVulncheckResult(ctx context.Context, arg command.URIArg) (map[protocol.DocumentURI]*govulncheck.Result, error) { - ret := map[protocol.DocumentURI]*govulncheck.Result{} - err := c.run(ctx, commandConfig{forURI: arg.URI}, func(ctx context.Context, deps commandDeps) error { -- if deps.snapshot.View().Options().Vulncheck == source.ModeVulncheckImports { +- if deps.snapshot.Options().Vulncheck == source.ModeVulncheckImports { - for _, modfile := range deps.snapshot.ModFiles() { - res, err := deps.snapshot.ModVuln(ctx, modfile) - if err != nil { @@ -32278,8 +36907,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - }, func(ctx context.Context, deps commandDeps) error { - tokenChan <- deps.work.Token() - -- view := deps.snapshot.View() -- opts := view.Options() +- opts := deps.snapshot.Options() - // quickly test if gopls is compiled to support govulncheck - // by checking vulncheck.Main. Alternatively, we can continue and - // let the `gopls vulncheck` command fail. This is lighter-weight. @@ -32326,7 +36954,7 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - result.AsOf = time.Now() - deps.snapshot.View().SetVulnerabilities(args.URI.SpanURI(), &result) - -- c.s.diagnoseSnapshot(deps.snapshot, nil, false) +- c.s.diagnoseSnapshot(deps.snapshot, nil, false, 0) - vulns := result.Vulns - affecting := make([]string, 0, len(vulns)) - for _, v := range vulns { @@ -32367,14 +36995,216 @@ diff -urN a/gopls/internal/lsp/command.go b/gopls/internal/lsp/command.go - var m runtime.MemStats - runtime.ReadMemStats(&m) - return command.MemStatsResult{ -- HeapAlloc: m.HeapAlloc, -- HeapInUse: m.HeapInuse, +- HeapAlloc: m.HeapAlloc, +- HeapInUse: m.HeapInuse, +- TotalAlloc: m.TotalAlloc, - }, nil -} +- +-// WorkspaceStats implements the WorkspaceStats command, reporting information +-// about the current state of the loaded workspace for the current session. +-func (c *commandHandler) WorkspaceStats(ctx context.Context) (command.WorkspaceStatsResult, error) { +- var res command.WorkspaceStatsResult +- res.Files.Total, res.Files.Largest, res.Files.Errs = c.s.session.Cache().FileStats() +- +- for _, view := range c.s.session.Views() { +- vs, err := collectViewStats(ctx, view) +- if err != nil { +- return res, err +- } +- res.Views = append(res.Views, vs) +- } +- return res, nil +-} +- +-func collectViewStats(ctx context.Context, view *cache.View) (command.ViewStats, error) { +- s, release, err := view.Snapshot() +- if err != nil { +- return command.ViewStats{}, err +- } +- defer release() +- +- allMD, err := s.AllMetadata(ctx) +- if err != nil { +- return command.ViewStats{}, err +- } +- allPackages := collectPackageStats(allMD) +- +- wsMD, err := s.WorkspaceMetadata(ctx) +- if err != nil { +- return command.ViewStats{}, err +- } +- workspacePackages := collectPackageStats(wsMD) +- +- var ids []source.PackageID +- for _, m := range wsMD { +- ids = append(ids, m.ID) +- } +- +- diags, err := s.PackageDiagnostics(ctx, ids...) +- if err != nil { +- return command.ViewStats{}, err +- } +- +- ndiags := 0 +- for _, d := range diags { +- ndiags += len(d) +- } +- +- return command.ViewStats{ +- GoCommandVersion: view.GoVersionString(), +- AllPackages: allPackages, +- WorkspacePackages: workspacePackages, +- Diagnostics: ndiags, +- }, nil +-} +- +-func collectPackageStats(md []*source.Metadata) command.PackageStats { +- var stats command.PackageStats +- stats.Packages = len(md) +- modules := make(map[string]bool) +- +- for _, m := range md { +- n := len(m.CompiledGoFiles) +- stats.CompiledGoFiles += n +- if n > stats.LargestPackage { +- stats.LargestPackage = n +- } +- if m.Module != nil { +- modules[m.Module.Path] = true +- } +- } +- stats.Modules = len(modules) +- +- return stats +-} +- +-// RunGoWorkCommand invokes `go work ` with the provided arguments. +-// +-// args.InitFirst controls whether to first run `go work init`. This allows a +-// single command to both create and recursively populate a go.work file -- as +-// of writing there is no `go work init -r`. +-// +-// Some thought went into implementing this command. Unlike the go.mod commands +-// above, this command simply invokes the go command and relies on the client +-// to notify gopls of file changes via didChangeWatchedFile notifications. +-// We could instead run these commands with GOWORK set to a temp file, but that +-// poses the following problems: +-// - directory locations in the resulting temp go.work file will be computed +-// relative to the directory containing that go.work. If the go.work is in a +-// tempdir, the directories will need to be translated to/from that dir. +-// - it would be simpler to use a temp go.work file in the workspace +-// directory, or whichever directory contains the real go.work file, but +-// that sets a bad precedent of writing to a user-owned directory. We +-// shouldn't start doing that. +-// - Sending workspace edits to create a go.work file would require using +-// the CreateFile resource operation, which would need to be tested in every +-// client as we haven't used it before. We don't have time for that right +-// now. +-// +-// Therefore, we simply require that the current go.work file is saved (if it +-// exists), and delegate to the go command. +-func (c *commandHandler) RunGoWorkCommand(ctx context.Context, args command.RunGoWorkArgs) error { +- return c.run(ctx, commandConfig{ +- progress: "Running go work command", +- forView: args.ViewID, +- }, func(ctx context.Context, deps commandDeps) (runErr error) { +- snapshot := deps.snapshot +- view := snapshot.View().(*cache.View) +- viewDir := view.Folder().Filename() +- +- // If the user has explicitly set GOWORK=off, we should warn them +- // explicitly and avoid potentially misleading errors below. +- goworkURI, off := view.GOWORK() +- if off { +- return fmt.Errorf("cannot modify go.work files when GOWORK=off") +- } +- gowork := goworkURI.Filename() +- +- if goworkURI != "" { +- fh, err := snapshot.ReadFile(ctx, goworkURI) +- if err != nil { +- return fmt.Errorf("reading current go.work file: %v", err) +- } +- if !fh.Saved() { +- return fmt.Errorf("must save workspace file %s before running go work commands", goworkURI) +- } +- } else { +- if !args.InitFirst { +- // If go.work does not exist, we should have detected that and asked +- // for InitFirst. +- return bug.Errorf("internal error: cannot run go work command: required go.work file not found") +- } +- gowork = filepath.Join(viewDir, "go.work") +- if err := c.invokeGoWork(ctx, viewDir, gowork, []string{"init"}); err != nil { +- return fmt.Errorf("running `go work init`: %v", err) +- } +- } +- +- return c.invokeGoWork(ctx, viewDir, gowork, args.Args) +- }) +-} +- +-func (c *commandHandler) invokeGoWork(ctx context.Context, viewDir, gowork string, args []string) error { +- inv := gocommand.Invocation{ +- Verb: "work", +- Args: args, +- WorkingDir: viewDir, +- Env: append(os.Environ(), fmt.Sprintf("GOWORK=%s", gowork)), +- } +- if _, err := c.s.session.GoCommandRunner().Run(ctx, inv); err != nil { +- return fmt.Errorf("running go work command: %v", err) +- } +- return nil +-} +- +-// openClientBrowser causes the LSP client to open the specified URL +-// in an external browser. +-func openClientBrowser(ctx context.Context, cli protocol.Client, url protocol.URI) { +- showDocumentImpl(ctx, cli, url, nil) +-} +- +-// openClientEditor causes the LSP client to open the specified document +-// and select the indicated range. +-func openClientEditor(ctx context.Context, cli protocol.Client, loc protocol.Location) { +- showDocumentImpl(ctx, cli, protocol.URI(loc.URI), &loc.Range) +-} +- +-func showDocumentImpl(ctx context.Context, cli protocol.Client, url protocol.URI, rangeOpt *protocol.Range) { +- // In principle we shouldn't send a showDocument request to a +- // client that doesn't support it, as reported by +- // ShowDocumentClientCapabilities. But even clients that do +- // support it may defer the real work of opening the document +- // asynchronously, to avoid deadlocks due to rentrancy. +- // +- // For example: client sends request to server; server sends +- // showDocument to client; client opens editor; editor causes +- // new RPC to be sent to server, which is still busy with +- // previous request. (This happens in eglot.) +- // +- // So we can't rely on the success/failure information. +- // That's the reason this function doesn't return an error. +- +- // "External" means run the system-wide handler (e.g. open(1) +- // on macOS or xdg-open(1) on Linux) for this URL, ignoring +- // TakeFocus and Selection. Note that this may still end up +- // opening the same editor (e.g. VSCode) for a file: URL. +- res, err := cli.ShowDocument(ctx, &protocol.ShowDocumentParams{ +- URI: url, +- External: rangeOpt == nil, +- TakeFocus: true, +- Selection: rangeOpt, // optional +- }) +- if err != nil { +- event.Error(ctx, "client.showDocument: %v", err) +- } else if res != nil && !res.Success { +- event.Log(ctx, fmt.Sprintf("client declined to open document %v", url)) +- } +-} diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go --- a/gopls/internal/lsp/completion.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/completion.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,140 +0,0 @@ +@@ -1,143 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -32396,6 +37226,9 @@ diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go -) - -func (s *Server) completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) { +- ctx, done := event.Start(ctx, "lsp.Server.completion", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { @@ -32403,7 +37236,7 @@ diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go - } - var candidates []completion.CompletionItem - var surrounding *completion.Selection -- switch snapshot.View().FileKind(fh) { +- switch snapshot.FileKind(fh) { - case source.Go: - candidates, surrounding, err = completion.Completion(ctx, snapshot, fh, params.Position, params.Context) - case source.Mod: @@ -32439,7 +37272,7 @@ diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go - - // When using deep completions/fuzzy matching, report results as incomplete so - // client fetches updated completions after every key stroke. -- options := snapshot.View().Options() +- options := snapshot.Options() - incompleteResults := options.DeepCompletion || options.Matcher == source.Fuzzy - - items := toProtocolCompletionItems(candidates, rng, options) @@ -32508,7 +37341,7 @@ diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go - - Preselect: i == 0, - Documentation: doc, -- Tags: candidate.Tags, +- Tags: nonNilSliceCompletionItemTag(candidate.Tags), - Deprecated: candidate.Deprecated, - } - items = append(items, item) @@ -32518,7 +37351,7 @@ diff -urN a/gopls/internal/lsp/completion.go b/gopls/internal/lsp/completion.go diff -urN a/gopls/internal/lsp/completion_test.go b/gopls/internal/lsp/completion_test.go --- a/gopls/internal/lsp/completion_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/completion_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,176 +0,0 @@ +@@ -1,177 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -32639,6 +37472,7 @@ diff -urN a/gopls/internal/lsp/completion_test.go b/gopls/internal/lsp/completio - Label: item.Label, - Kind: item.Kind, - Detail: item.Detail, +- Tags: []protocol.CompletionItemTag{}, // must be a slice - Documentation: &protocol.Or_CompletionItem_documentation{ - Value: item.Documentation, - }, @@ -32695,226 +37529,10 @@ diff -urN a/gopls/internal/lsp/completion_test.go b/gopls/internal/lsp/completio - } - return list.Items -} -diff -urN a/gopls/internal/lsp/debounce.go b/gopls/internal/lsp/debounce.go ---- a/gopls/internal/lsp/debounce.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debounce.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,71 +0,0 @@ --// Copyright 2020 The Go Authors. 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 -- --import ( -- "sync" -- "time" --) -- --type debounceEvent struct { -- order uint64 -- done chan struct{} --} -- --type debouncer struct { -- mu sync.Mutex -- events map[string]*debounceEvent --} -- --func newDebouncer() *debouncer { -- return &debouncer{ -- events: make(map[string]*debounceEvent), -- } --} -- --// debounce returns a channel that receives a boolean reporting whether, --// by the time the delay channel receives a value, this call is (or will be) --// the most recent call with the highest order number for its key. --func (d *debouncer) debounce(key string, order uint64, delay <-chan time.Time) <-chan bool { -- okc := make(chan bool, 1) -- -- d.mu.Lock() -- if prev, ok := d.events[key]; ok { -- if prev.order > order { -- // If we have a logical ordering of events (as is the case for snapshots), -- // don't overwrite a later event with an earlier event. -- d.mu.Unlock() -- okc <- false -- return okc -- } -- close(prev.done) -- } -- done := make(chan struct{}) -- next := &debounceEvent{ -- order: order, -- done: done, -- } -- d.events[key] = next -- d.mu.Unlock() -- -- go func() { -- ok := false -- select { -- case <-delay: -- d.mu.Lock() -- if d.events[key] == next { -- ok = true -- delete(d.events, key) -- } else { -- // The event was superseded before we acquired d.mu. -- } -- d.mu.Unlock() -- case <-done: -- } -- okc <- ok -- }() -- -- return okc --} -diff -urN a/gopls/internal/lsp/debounce_test.go b/gopls/internal/lsp/debounce_test.go ---- a/gopls/internal/lsp/debounce_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debounce_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,81 +0,0 @@ --// Copyright 2020 The Go Authors. 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 -- --import ( -- "testing" -- "time" --) -- --func TestDebouncer(t *testing.T) { -- t.Parallel() -- -- type event struct { -- key string -- order uint64 -- wantFired bool -- } -- tests := []struct { -- label string -- events []*event -- }{ -- { -- label: "overridden", -- events: []*event{ -- {key: "a", order: 1, wantFired: false}, -- {key: "a", order: 2, wantFired: true}, -- }, -- }, -- { -- label: "distinct labels", -- events: []*event{ -- {key: "a", order: 1, wantFired: true}, -- {key: "b", order: 2, wantFired: true}, -- }, -- }, -- { -- label: "reverse order", -- events: []*event{ -- {key: "a", order: 2, wantFired: true}, -- {key: "a", order: 1, wantFired: false}, -- }, -- }, -- { -- label: "multiple overrides", -- events: []*event{ -- {key: "a", order: 1, wantFired: false}, -- {key: "a", order: 2, wantFired: false}, -- {key: "a", order: 3, wantFired: false}, -- {key: "a", order: 4, wantFired: false}, -- {key: "a", order: 5, wantFired: true}, -- }, -- }, -- } -- for _, test := range tests { -- test := test -- t.Run(test.label, func(t *testing.T) { -- d := newDebouncer() -- -- delays := make([]chan time.Time, len(test.events)) -- okcs := make([]<-chan bool, len(test.events)) -- -- // Register the events in deterministic order, synchronously. -- for i, e := range test.events { -- delays[i] = make(chan time.Time, 1) -- okcs[i] = d.debounce(e.key, e.order, delays[i]) -- } -- -- // Now see which event fired. -- for i, okc := range okcs { -- event := test.events[i] -- delays[i] <- time.Now() -- fired := <-okc -- if fired != event.wantFired { -- t.Errorf("[key: %q, order: %d]: fired = %t, want %t", event.key, event.order, fired, event.wantFired) -- } -- } -- }) -- } --} -diff -urN a/gopls/internal/lsp/debug/buildinfo_go1.12.go b/gopls/internal/lsp/debug/buildinfo_go1.12.go ---- a/gopls/internal/lsp/debug/buildinfo_go1.12.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/buildinfo_go1.12.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build !go1.18 --// +build !go1.18 -- --package debug -- --import ( -- "runtime" -- "runtime/debug" --) -- --type BuildInfo struct { -- debug.BuildInfo -- GoVersion string // Version of Go that produced this binary --} -- --func readBuildInfo() (*BuildInfo, bool) { -- rinfo, ok := debug.ReadBuildInfo() -- if !ok { -- return nil, false -- } -- return &BuildInfo{ -- GoVersion: runtime.Version(), -- BuildInfo: *rinfo, -- }, true --} -diff -urN a/gopls/internal/lsp/debug/buildinfo_go1.18.go b/gopls/internal/lsp/debug/buildinfo_go1.18.go ---- a/gopls/internal/lsp/debug/buildinfo_go1.18.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/debug/buildinfo_go1.18.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build go1.18 --// +build go1.18 -- --package debug -- --import ( -- "runtime/debug" --) -- --type BuildInfo debug.BuildInfo -- --func readBuildInfo() (*BuildInfo, bool) { -- info, ok := debug.ReadBuildInfo() -- return (*BuildInfo)(info), ok --} diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go --- a/gopls/internal/lsp/debug/info.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/debug/info.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,254 +0,0 @@ +@@ -1,258 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -32927,6 +37545,7 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go - "encoding/json" - "fmt" - "io" +- "os" - "reflect" - "runtime" - "runtime/debug" @@ -32946,12 +37565,19 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go -) - -// Version is a manually-updated mechanism for tracking versions. --const Version = "master" +-func Version() string { +- if info, ok := debug.ReadBuildInfo(); ok { +- if info.Main.Version != "" { +- return info.Main.Version +- } +- } +- return "(unknown)" +-} - -// ServerVersion is the format used by gopls to report its version to the -// client. This format is structured so that the client can parse it easily. -type ServerVersion struct { -- *BuildInfo +- *debug.BuildInfo - Version string -} - @@ -32959,23 +37585,18 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go -// built in module mode, we return a GOPATH-specific message with the -// hardcoded version. -func VersionInfo() *ServerVersion { -- if info, ok := readBuildInfo(); ok { -- return getVersion(info) -- } -- buildInfo := &BuildInfo{} -- // go1.17 or earlier, part of s.BuildInfo are embedded fields. -- buildInfo.Path = "gopls, built in GOPATH mode" -- buildInfo.GoVersion = runtime.Version() -- return &ServerVersion{ -- Version: Version, -- BuildInfo: buildInfo, +- if info, ok := debug.ReadBuildInfo(); ok { +- return &ServerVersion{ +- Version: Version(), +- BuildInfo: info, +- } - } --} -- --func getVersion(info *BuildInfo) *ServerVersion { - return &ServerVersion{ -- Version: Version, -- BuildInfo: info, +- Version: Version(), +- BuildInfo: &debug.BuildInfo{ +- Path: "gopls, built in GOPATH mode", +- GoVersion: runtime.Version(), +- }, - } -} - @@ -32984,6 +37605,7 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go - section(w, HTML, "Server Instance", func() { - fmt.Fprintf(w, "Start time: %v\n", i.StartTime) - fmt.Fprintf(w, "LogFile: %s\n", i.Logfile) +- fmt.Fprintf(w, "pid: %d\n", os.Getpid()) - fmt.Fprintf(w, "Working directory: %s\n", i.Workdir) - fmt.Fprintf(w, "Address: %s\n", i.ServerAddress) - fmt.Fprintf(w, "Debug address: %s\n", i.DebugAddress()) @@ -33040,7 +37662,7 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go -} - -func printBuildInfo(w io.Writer, info *ServerVersion, verbose bool, mode PrintMode) { -- fmt.Fprintf(w, "%v %v\n", info.Path, Version) +- fmt.Fprintf(w, "%v %v\n", info.Path, Version()) - printModuleInfo(w, info.Main, mode) - if !verbose { - return @@ -33172,7 +37794,7 @@ diff -urN a/gopls/internal/lsp/debug/info.go b/gopls/internal/lsp/debug/info.go diff -urN a/gopls/internal/lsp/debug/info_test.go b/gopls/internal/lsp/debug/info_test.go --- a/gopls/internal/lsp/debug/info_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/debug/info_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,47 +0,0 @@ +@@ -1,48 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -33202,7 +37824,7 @@ diff -urN a/gopls/internal/lsp/debug/info_test.go b/gopls/internal/lsp/debug/inf - if g, w := got.GoVersion, runtime.Version(); g != w { - t.Errorf("go version = %v, want %v", g, w) - } -- if g, w := got.Version, Version; g != w { +- if g, w := got.Version, Version(); g != w { - t.Errorf("gopls version = %v, want %v", g, w) - } - // Other fields of BuildInfo may not be available during test. @@ -33216,8 +37838,9 @@ diff -urN a/gopls/internal/lsp/debug/info_test.go b/gopls/internal/lsp/debug/inf - res := buf.Bytes() - - // Other fields of BuildInfo may not be available during test. -- if !bytes.Contains(res, []byte(Version)) || !bytes.Contains(res, []byte(runtime.Version())) { -- t.Errorf("plaintext output = %q,\nwant (version: %v, go: %v)", res, Version, runtime.Version()) +- wantGoplsVersion, wantGoVersion := Version(), runtime.Version() +- if !bytes.Contains(res, []byte(wantGoplsVersion)) || !bytes.Contains(res, []byte(wantGoVersion)) { +- t.Errorf("plaintext output = %q,\nwant (version: %v, go: %v)", res, wantGoplsVersion, wantGoVersion) - } -} diff -urN a/gopls/internal/lsp/debug/log/log.go b/gopls/internal/lsp/debug/log/log.go @@ -33575,7 +38198,7 @@ diff -urN a/gopls/internal/lsp/debug/rpc.go b/gopls/internal/lsp/debug/rpc.go diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.go --- a/gopls/internal/lsp/debug/serve.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/debug/serve.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,909 +0,0 @@ +@@ -1,871 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -33583,7 +38206,6 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g -package debug - -import ( -- "archive/zip" - "bytes" - "context" - "errors" @@ -33598,16 +38220,15 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g - "path" - "path/filepath" - "runtime" -- rpprof "runtime/pprof" - "strconv" - "strings" - "sync" - "time" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/debug/log" - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/core" - "golang.org/x/tools/internal/event/export" @@ -33685,6 +38306,13 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g - return nil -} - +-// Analysis returns the global Analysis template value. +-func (st *State) Analysis() (_ analysisTmpl) { return } +- +-type analysisTmpl struct{} +- +-func (analysisTmpl) AnalyzerRunTimes() []cache.LabelDuration { return cache.AnalyzerRunTimes() } +- -// Sessions returns the set of Session objects currently being served. -func (st *State) Sessions() []*cache.Session { - var sessions []*cache.Session @@ -33858,6 +38486,10 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g - return i.State.Cache(path.Base(r.URL.Path)) -} - +-func (i *Instance) getAnalysis(r *http.Request) interface{} { +- return i.State.Analysis() +-} +- -func (i *Instance) getSession(r *http.Request) interface{} { - return i.State.Session(path.Base(r.URL.Path)) -} @@ -34030,6 +38662,7 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g - if i.traces != nil { - mux.HandleFunc("/trace/", render(TraceTmpl, i.traces.getData)) - } +- mux.HandleFunc("/analysis/", render(AnalysisTmpl, i.getAnalysis)) - mux.HandleFunc("/cache/", render(CacheTmpl, i.getCache)) - mux.HandleFunc("/session/", render(SessionTmpl, i.getSession)) - mux.HandleFunc("/view/", render(ViewTmpl, i.getView)) @@ -34040,14 +38673,14 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g - mux.HandleFunc("/memory", render(MemoryTmpl, getMemory)) - - // Internal debugging helpers. -- mux.HandleFunc("/_dogc", func(w http.ResponseWriter, r *http.Request) { +- mux.HandleFunc("/gc", func(w http.ResponseWriter, r *http.Request) { - runtime.GC() - runtime.GC() - runtime.GC() -- http.Error(w, "OK", 200) +- http.Redirect(w, r, "/memory", http.StatusTemporaryRedirect) - }) - mux.HandleFunc("/_makeabug", func(w http.ResponseWriter, r *http.Request) { -- bug.Report("bug here", nil) +- bug.Report("bug here") - http.Error(w, "made a bug", http.StatusOK) - }) - @@ -34072,65 +38705,6 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g - return i.listenedDebugAddress -} - --// MonitorMemory starts recording memory statistics each second. --func (i *Instance) MonitorMemory(ctx context.Context) { -- tick := time.NewTicker(time.Second) -- nextThresholdGiB := uint64(1) -- go func() { -- for { -- <-tick.C -- var mem runtime.MemStats -- runtime.ReadMemStats(&mem) -- if mem.HeapAlloc < nextThresholdGiB*1<<30 { -- continue -- } -- if err := i.writeMemoryDebug(nextThresholdGiB, true); err != nil { -- event.Error(ctx, "writing memory debug info", err) -- } -- if err := i.writeMemoryDebug(nextThresholdGiB, false); err != nil { -- event.Error(ctx, "writing memory debug info", err) -- } -- event.Log(ctx, fmt.Sprintf("Wrote memory usage debug info to %v", os.TempDir())) -- nextThresholdGiB++ -- } -- }() --} -- --func (i *Instance) writeMemoryDebug(threshold uint64, withNames bool) error { -- suffix := "withnames" -- if !withNames { -- suffix = "nonames" -- } -- -- filename := fmt.Sprintf("gopls.%d-%dGiB-%s.zip", os.Getpid(), threshold, suffix) -- zipf, err := os.OpenFile(filepath.Join(os.TempDir(), filename), os.O_CREATE|os.O_RDWR, 0644) -- if err != nil { -- return err -- } -- zipw := zip.NewWriter(zipf) -- -- f, err := zipw.Create("heap.pb.gz") -- if err != nil { -- return err -- } -- if err := rpprof.Lookup("heap").WriteTo(f, 0); err != nil { -- return err -- } -- -- f, err = zipw.Create("goroutines.txt") -- if err != nil { -- return err -- } -- if err := rpprof.Lookup("goroutine").WriteTo(f, 1); err != nil { -- return err -- } -- -- if err := zipw.Close(); err != nil { -- return err -- } -- return zipf.Close() --} -- -func makeGlobalExporter(stderr io.Writer) event.Exporter { - p := export.Printer{} - var pMu sync.Mutex @@ -34275,10 +38849,10 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g -td.value { - text-align: right; -} --ul.events { -- list-style-type: none; +-ul.spans { +- font-family: monospace; +- font-size: 85%; -} -- - -{{block "head" .}}{{end}} - @@ -34286,9 +38860,11 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g -Main -Info -Memory +-Profiling -Metrics -RPC -Trace +-Analysis -
-

{{template "title" .}}

-{{block "body" .}} @@ -34355,9 +38931,10 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g -`)) - -var MemoryTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(` --{{define "title"}}GoPls memory usage{{end}} +-{{define "title"}}Gopls memory usage{{end}} -{{define "head"}}{{end}} -{{define "body"}} +-
-

Stats

- - @@ -34399,6 +38976,14 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g -{{end}} -`)) - +-var AnalysisTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(` +-{{define "title"}}Analysis{{end}} +-{{define "body"}} +-

Analyzer.Run times

+-
    {{range .AnalyzerRunTimes}}
  • {{.Duration}} {{.Label}}
  • {{end}}
+-{{end}} +-`)) +- -var ClientTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(` -{{define "title"}}Client {{.Session.ID}}{{end}} -{{define "body"}} @@ -34482,13 +39067,13 @@ diff -urN a/gopls/internal/lsp/debug/serve.go b/gopls/internal/lsp/debug/serve.g - Kind: {{.Kind}}
-{{end}} -

Contents

--
{{fcontent .Read}}
+-
{{fcontent .Content}}
-{{end}} -`)) diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.go --- a/gopls/internal/lsp/debug/trace.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/debug/trace.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,233 +0,0 @@ +@@ -1,320 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -34513,60 +39098,117 @@ diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.g - "golang.org/x/tools/internal/event/label" -) - +-// TraceTmpl extends BaseTemplate and renders a TraceResults, e.g. from getData(). -var TraceTmpl = template.Must(template.Must(BaseTemplate.Clone()).Parse(` -{{define "title"}}Trace Information{{end}} -{{define "body"}} - {{range .Traces}}{{.Name}} last: {{.Last.Duration}}, longest: {{.Longest.Duration}}
{{end}} - {{if .Selected}} -

{{.Selected.Name}}

-- {{if .Selected.Last}}

Last

    {{template "details" .Selected.Last}}
{{end}} -- {{if .Selected.Longest}}

Longest

    {{template "details" .Selected.Longest}}
{{end}} +- {{if .Selected.Last}}

Last

    {{template "completeSpan" .Selected.Last}}
{{end}} +- {{if .Selected.Longest}}

Longest

    {{template "completeSpan" .Selected.Longest}}
{{end}} - {{end}} +- +-

Recent spans (oldest first)

+-

+- A finite number of recent span start/end times are shown below. +- The nesting represents the children of a parent span (and the log events within a span). +- A span may appear twice: chronologically at toplevel, and nested within its parent. +-

+-
    {{range .Recent}}{{template "spanStartEnd" .}}{{end}}
-{{end}} --{{define "details"}} --
  • {{.Offset}} {{.Name}} {{.Duration}} {{.Tags}}
  • -- {{if .Events}}
      {{range .Events}}
    • {{.Offset}} {{.Tags}}
    • {{end}}
    {{end}} -- {{if .Children}}
      {{range .Children}}{{template "details" .}}{{end}}
    {{end}} +-{{define "spanStartEnd"}} +- {{if .Start}} +-
  • {{.Span.Header .Start}}
  • +- {{else}} +- {{template "completeSpan" .Span}} +- {{end}} +-{{end}} +-{{define "completeSpan"}} +-
  • {{.Header false}}
  • +- {{if .Events}}
      {{range .Events}}
    • {{.Header}}
    • {{end}}
    {{end}} +- {{if .ChildStartEnd}}
      {{range .ChildStartEnd}}{{template "spanStartEnd" .}}{{end}}
    {{end}} -{{end}} -`)) - -type traces struct { -- mu sync.Mutex -- sets map[string]*traceSet -- unfinished map[export.SpanContext]*traceData +- mu sync.Mutex +- sets map[string]*traceSet +- unfinished map[export.SpanContext]*traceSpan +- recent []spanStartEnd +- recentEvictions int +-} +- +-// A spanStartEnd records the start or end of a span. +-// If Start, the span may be unfinished, so some fields (e.g. Finish) +-// may be unset and others (e.g. Events) may be being actively populated. +-type spanStartEnd struct { +- Start bool +- Span *traceSpan +-} +- +-func (ev spanStartEnd) Time() time.Time { +- if ev.Start { +- return ev.Span.Start +- } else { +- return ev.Span.Finish +- } -} - +-// A TraceResults is the subject for the /trace HTML template. -type TraceResults struct { // exported for testing - Traces []*traceSet - Selected *traceSet +- Recent []spanStartEnd -} - +-// A traceSet holds two representative spans of a given span name. -type traceSet struct { - Name string -- Last *traceData -- Longest *traceData --} -- --type traceData struct { -- TraceID export.TraceID -- SpanID export.SpanID -- ParentID export.SpanID -- Name string -- Start time.Time -- Finish time.Time -- Offset time.Duration -- Duration time.Duration -- Tags string -- Events []traceEvent -- Children []*traceData +- Last *traceSpan +- Longest *traceSpan +-} +- +-// A traceSpan holds information about a single span. +-type traceSpan struct { +- TraceID export.TraceID +- SpanID export.SpanID +- ParentID export.SpanID +- Name string +- Start time.Time +- Finish time.Time // set at end +- Duration time.Duration // set at end +- Tags string +- Events []traceEvent // set at end +- ChildStartEnd []spanStartEnd // populated while active +- +- parent *traceSpan +-} +- +-const timeFormat = "15:04:05.000" +- +-// Header renders the time, name, tags, and (if !start), +-// duration of a span start or end event. +-func (span *traceSpan) Header(start bool) string { +- if start { +- return fmt.Sprintf("%s start %s %s", +- span.Start.Format(timeFormat), span.Name, span.Tags) +- } else { +- return fmt.Sprintf("%s end %s (+%s) %s", +- span.Finish.Format(timeFormat), span.Name, span.Duration, span.Tags) +- } -} - -type traceEvent struct { - Time time.Time -- Offset time.Duration +- Offset time.Duration // relative to start of span - Tags string -} - +-func (ev traceEvent) Header() string { +- return fmt.Sprintf("%s event (+%s) %s", ev.Time.Format(timeFormat), ev.Offset, ev.Tags) +-} +- -func StdTrace(exporter event.Exporter) event.Exporter { - return func(ctx context.Context, ev core.Event, lm label.Map) context.Context { - span := export.GetSpan(ctx) @@ -34619,7 +39261,7 @@ diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.g - case event.IsStart(ev): - // Just starting: add it to the unfinished map. - // Allocate before the critical section. -- td := &traceData{ +- td := &traceSpan{ - TraceID: span.ID.TraceID, - SpanID: span.ID.SpanID, - ParentID: span.ParentID, @@ -34630,22 +39272,23 @@ diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.g - - t.mu.Lock() - defer t.mu.Unlock() +- +- t.addRecentLocked(td, true) // add start event +- - if t.sets == nil { - t.sets = make(map[string]*traceSet) -- t.unfinished = make(map[export.SpanContext]*traceData) +- t.unfinished = make(map[export.SpanContext]*traceSpan) - } - t.unfinished[span.ID] = td -- // and wire up parents if we have them -- if !span.ParentID.IsValid() { -- return ctx -- } -- parentID := export.SpanContext{TraceID: span.ID.TraceID, SpanID: span.ParentID} -- parent, found := t.unfinished[parentID] -- if !found { -- // trace had an invalid parent, so it cannot itself be valid -- return ctx +- +- // Wire up parents if we have them. +- if span.ParentID.IsValid() { +- parentID := export.SpanContext{TraceID: span.ID.TraceID, SpanID: span.ParentID} +- if parent, ok := t.unfinished[parentID]; ok { +- td.parent = parent +- parent.ChildStartEnd = append(parent.ChildStartEnd, spanStartEnd{true, td}) +- } - } -- parent.Children = append(parent.Children, td) - - case event.IsEnd(ev): - // Finishing: must be already in the map. @@ -34666,10 +39309,10 @@ diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.g - return ctx // if this happens we are in a bad place - } - delete(t.unfinished, span.ID) -- - td.Finish = span.Finish().At() - td.Duration = span.Finish().At().Sub(span.Start().At()) - td.Events = tdEvents +- t.addRecentLocked(td, false) // add end event - - set, ok := t.sets[span.Name] - if !ok { @@ -34680,43 +39323,72 @@ diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.g - if set.Longest == nil || set.Last.Duration > set.Longest.Duration { - set.Longest = set.Last - } -- if !td.ParentID.IsValid() { +- if td.parent != nil { +- td.parent.ChildStartEnd = append(td.parent.ChildStartEnd, spanStartEnd{false, td}) +- } else { - fillOffsets(td, td.Start) - } - } - return ctx -} - --func (t *traces) getData(req *http.Request) interface{} { -- if len(t.sets) == 0 { -- return nil +-// addRecentLocked appends a start or end event to the "recent" log, +-// evicting an old entry if necessary. +-func (t *traces) addRecentLocked(span *traceSpan, start bool) { +- t.recent = append(t.recent, spanStartEnd{Start: start, Span: span}) +- +- const maxRecent = 100 // number of log entries before eviction +- for len(t.recent) > maxRecent { +- t.recent[0] = spanStartEnd{} // aid GC +- t.recent = t.recent[1:] +- t.recentEvictions++ +- +- // Using a slice as a FIFO queue leads to unbounded growth +- // as Go's GC cannot collect the ever-growing unused prefix. +- // So, compact it periodically. +- if t.recentEvictions%maxRecent == 0 { +- t.recent = append([]spanStartEnd(nil), t.recent...) +- } - } -- data := TraceResults{} -- data.Traces = make([]*traceSet, 0, len(t.sets)) +-} +- +-// getData returns the TraceResults rendered by TraceTmpl for the /trace[/name] endpoint. +-func (t *traces) getData(req *http.Request) interface{} { +- // TODO(adonovan): the HTTP request doesn't acquire the mutex +- // for t or for each span! Audit and fix. +- +- // Sort last/longest sets by name. +- traces := make([]*traceSet, 0, len(t.sets)) - for _, set := range t.sets { -- data.Traces = append(data.Traces, set) +- traces = append(traces, set) - } -- sort.Slice(data.Traces, func(i, j int) bool { return data.Traces[i].Name < data.Traces[j].Name }) -- if bits := strings.SplitN(req.URL.Path, "/trace/", 2); len(bits) > 1 { -- data.Selected = t.sets[bits[1]] +- sort.Slice(traces, func(i, j int) bool { +- return traces[i].Name < traces[j].Name +- }) +- +- return TraceResults{ +- Traces: traces, +- Selected: t.sets[strings.TrimPrefix(req.URL.Path, "/trace/")], // may be nil +- Recent: t.recent, - } -- return data -} - --func fillOffsets(td *traceData, start time.Time) { -- td.Offset = td.Start.Sub(start) +-func fillOffsets(td *traceSpan, start time.Time) { - for i := range td.Events { - td.Events[i].Offset = td.Events[i].Time.Sub(start) - } -- for _, child := range td.Children { -- fillOffsets(child, start) +- for _, child := range td.ChildStartEnd { +- if !child.Start { +- fillOffsets(child.Span, start) +- } - } -} - -func renderLabels(labels label.List) string { - buf := &bytes.Buffer{} - for index := 0; labels.Valid(index); index++ { -- if l := labels.Label(index); l.Valid() { +- // The 'start' label duplicates the span name, so discard it. +- if l := labels.Label(index); l.Valid() && l.Key().Name() != "start" { - fmt.Fprintf(buf, "%v ", l) - } - } @@ -34725,7 +39397,7 @@ diff -urN a/gopls/internal/lsp/debug/trace.go b/gopls/internal/lsp/debug/trace.g diff -urN a/gopls/internal/lsp/definition.go b/gopls/internal/lsp/definition.go --- a/gopls/internal/lsp/definition.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/definition.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,52 +0,0 @@ +@@ -1,60 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -34740,16 +39412,21 @@ diff -urN a/gopls/internal/lsp/definition.go b/gopls/internal/lsp/definition.go - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/template" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) definition(ctx context.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) { +- ctx, done := event.Start(ctx, "lsp.Server.definition", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - // TODO(rfindley): definition requests should be multiplexed across all views. - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { - return nil, err - } -- switch kind := snapshot.View().FileKind(fh); kind { +- switch kind := snapshot.FileKind(fh); kind { - case source.Tmpl: - return template.Definition(snapshot, fh, params.Position) - case source.Go: @@ -34765,13 +39442,16 @@ diff -urN a/gopls/internal/lsp/definition.go b/gopls/internal/lsp/definition.go -} - -func (s *Server) typeDefinition(ctx context.Context, params *protocol.TypeDefinitionParams) ([]protocol.Location, error) { +- ctx, done := event.Start(ctx, "lsp.Server.typeDefinition", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - // TODO(rfindley): type definition requests should be multiplexed across all views. - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { - return nil, err - } -- switch kind := snapshot.View().FileKind(fh); kind { +- switch kind := snapshot.FileKind(fh); kind { - case source.Go: - return source.TypeDefinition(ctx, snapshot, fh, params.Position) - default: @@ -34781,7 +39461,7 @@ diff -urN a/gopls/internal/lsp/definition.go b/gopls/internal/lsp/definition.go diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.go --- a/gopls/internal/lsp/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,764 +0,0 @@ +@@ -1,862 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -34795,12 +39475,12 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - "fmt" - "os" - "path/filepath" +- "sort" - "strings" - "sync" - "time" - -- "golang.org/x/sync/errgroup" -- "golang.org/x/tools/gopls/internal/lsp/debug/log" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/mod" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" @@ -34809,14 +39489,23 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - "golang.org/x/tools/gopls/internal/span" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/tag" -- "golang.org/x/tools/internal/xcontext" -) - +-// TODO(rfindley): simplify this very complicated logic for publishing +-// diagnostics. While doing so, ensure that we can test subtle logic such as +-// for multi-pass diagnostics. +- -// diagnosticSource differentiates different sources of diagnostics. +-// +-// Diagnostics from the same source overwrite each other, whereas diagnostics +-// from different sources do not. Conceptually, the server state is a mapping +-// from diagnostics source to a set of diagnostics, and each storeDiagnostics +-// operation updates one entry of that mapping. -type diagnosticSource int - -const ( -- modSource diagnosticSource = iota +- modParseSource diagnosticSource = iota +- modTidySource - gcDetailsSource - analysisSource - typeCheckSource @@ -34863,13 +39552,15 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - mustPublish bool - - // The last stored diagnostics for each diagnostic source. -- reports map[diagnosticSource]diagnosticReport +- reports map[diagnosticSource]*diagnosticReport -} - -func (d diagnosticSource) String() string { - switch d { -- case modSource: -- return "FromSource" +- case modParseSource: +- return "FromModParse" +- case modTidySource: +- return "FromModTidy" - case gcDetailsSource: - return "FromGCDetails" - case analysisSource: @@ -34890,46 +39581,69 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g -} - -// hashDiagnostics computes a hash to identify diags. +-// +-// hashDiagnostics mutates its argument (via sorting). -func hashDiagnostics(diags ...*source.Diagnostic) string { +- if len(diags) == 0 { +- return emptyDiagnosticsHash +- } +- return computeDiagnosticHash(diags...) +-} +- +-// opt: pre-computed hash for empty diagnostics +-var emptyDiagnosticsHash = computeDiagnosticHash() +- +-// computeDiagnosticHash should only be called from hashDiagnostics. +-// +-// TODO(rfindley): this should use source.Hash. +-func computeDiagnosticHash(diags ...*source.Diagnostic) string { - source.SortDiagnostics(diags) - h := sha256.New() - for _, d := range diags { - for _, t := range d.Tags { -- fmt.Fprintf(h, "%s", t) +- fmt.Fprintf(h, "tag: %s\n", t) - } - for _, r := range d.Related { -- fmt.Fprintf(h, "%s%s%s", r.Location.URI.SpanURI(), r.Message, r.Location.Range) +- fmt.Fprintf(h, "related: %s %s %s\n", r.Location.URI.SpanURI(), r.Message, r.Location.Range) +- } +- fmt.Fprintf(h, "code: %s\n", d.Code) +- fmt.Fprintf(h, "codeHref: %s\n", d.CodeHref) +- fmt.Fprintf(h, "message: %s\n", d.Message) +- fmt.Fprintf(h, "range: %s\n", d.Range) +- fmt.Fprintf(h, "severity: %s\n", d.Severity) +- fmt.Fprintf(h, "source: %s\n", d.Source) +- if d.BundledFixes != nil { +- fmt.Fprintf(h, "fixes: %s\n", *d.BundledFixes) - } -- fmt.Fprintf(h, "%s%s%s%s", d.Message, d.Range, d.Severity, d.Source) - } - return fmt.Sprintf("%x", h.Sum(nil)) -} - --func (s *Server) diagnoseDetached(snapshot source.Snapshot) { -- ctx := snapshot.BackgroundContext() -- ctx = xcontext.Detach(ctx) -- s.diagnose(ctx, snapshot, false) -- s.publishDiagnostics(ctx, true, snapshot) --} -- -func (s *Server) diagnoseSnapshots(snapshots map[source.Snapshot][]span.URI, onDisk bool) { - var diagnosticWG sync.WaitGroup - for snapshot, uris := range snapshots { - diagnosticWG.Add(1) - go func(snapshot source.Snapshot, uris []span.URI) { - defer diagnosticWG.Done() -- s.diagnoseSnapshot(snapshot, uris, onDisk) +- s.diagnoseSnapshot(snapshot, uris, onDisk, snapshot.Options().DiagnosticsDelay) - }(snapshot, uris) - } - diagnosticWG.Wait() -} - --func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, changedURIs []span.URI, onDisk bool) { +-// diagnoseSnapshot computes and publishes diagnostics for the given snapshot. +-// +-// If delay is non-zero, computing diagnostics does not start until after this +-// delay has expired, to allow work to be cancelled by subsequent changes. +-// +-// If changedURIs is non-empty, it is a set of recently changed files that +-// should be diagnosed immediately, and onDisk reports whether these file +-// changes came from a change to on-disk files. +-func (s *Server) diagnoseSnapshot(snapshot source.Snapshot, changedURIs []span.URI, onDisk bool, delay time.Duration) { - ctx := snapshot.BackgroundContext() - ctx, done := event.Start(ctx, "Server.diagnoseSnapshot", source.SnapshotLabels(snapshot)...) - defer done() - -- delay := snapshot.View().Options().DiagnosticsDelay - if delay > 0 { - // 2-phase diagnostics. - // @@ -34937,25 +39651,36 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - // does not analyze) packages directly affected by - // file modifications. - // -- // The second phase runs analysis on the entire snapshot, -- // and is debounced by the configured delay. +- // The second phase runs after the delay, and does everything. +- // +- // We wait a brief delay before the first phase, to allow higher priority +- // work such as autocompletion to acquire the type checking mutex (though +- // typically both diagnosing changed files and performing autocompletion +- // will be doing the same work: recomputing active packages). +- const minDelay = 20 * time.Millisecond +- select { +- case <-time.After(minDelay): +- case <-ctx.Done(): +- return +- } +- - s.diagnoseChangedFiles(ctx, snapshot, changedURIs, onDisk) - s.publishDiagnostics(ctx, false, snapshot) - -- // We debounce diagnostics separately for each view, using the snapshot -- // local ID as logical ordering. -- // -- // TODO(rfindley): it would be cleaner to simply put the diagnostic -- // debouncer on the view, and remove the "key" argument to debouncing. -- if ok := <-s.diagDebouncer.debounce(snapshot.View().Name(), snapshot.SequenceID(), time.After(delay)); ok { -- s.diagnose(ctx, snapshot, false) -- s.publishDiagnostics(ctx, true, snapshot) +- if delay < minDelay { +- delay = 0 +- } else { +- delay -= minDelay +- } +- +- select { +- case <-time.After(delay): +- case <-ctx.Done(): +- return - } -- return - } - -- // Ignore possible workspace configuration warnings in the normal flow. -- s.diagnose(ctx, snapshot, false) +- s.diagnose(ctx, snapshot, analyzeOpenPackages) - s.publishDiagnostics(ctx, true, snapshot) -} - @@ -34963,11 +39688,7 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - ctx, done := event.Start(ctx, "Server.diagnoseChangedFiles", source.SnapshotLabels(snapshot)...) - defer done() - -- // TODO(adonovan): safety: refactor so that group.Go is called -- // in a second loop, so that if we should later add an early -- // return to the first loop, we don't leak goroutines. -- var group errgroup.Group -- seen := make(map[*source.Metadata]bool) +- toDiagnose := make(map[source.PackageID]*source.Metadata) - for _, uri := range uris { - // If the change is only on-disk and the file is not open, don't - // directly request its package. It may not be a workspace package. @@ -34981,45 +39702,50 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - } - - // Don't request type-checking for builtin.go: it's not a real package. -- if snapshot.IsBuiltin(ctx, uri) { +- if snapshot.IsBuiltin(uri) { +- continue +- } +- +- // Don't diagnose files that are ignored by `go list` (e.g. testdata). +- if snapshot.IgnoredFile(uri) { - continue - } - - // Find all packages that include this file and diagnose them in parallel. -- metas, err := snapshot.MetadataForFile(ctx, uri) +- meta, err := source.NarrowestMetadataForFile(ctx, snapshot, uri) - if err != nil { +- if ctx.Err() != nil { +- return +- } - // TODO(findleyr): we should probably do something with the error here, - // but as of now this can fail repeatedly if load fails, so can be too - // noisy to log (and we'll handle things later in the slow pass). - continue - } -- for _, m := range metas { -- if m.IsIntermediateTestVariant() { -- continue -- } -- if !seen[m] { -- seen[m] = true -- m := m -- group.Go(func() error { -- s.diagnosePkg(ctx, snapshot, m, false) -- return nil // error result is ignored -- }) -- } -- } +- toDiagnose[meta.ID] = meta - } -- group.Wait() // ignore error +- s.diagnosePkgs(ctx, snapshot, toDiagnose, nil) -} - +-// analysisMode parameterizes analysis behavior of a call to diagnosePkgs. +-type analysisMode int +- +-const ( +- analyzeNothing analysisMode = iota // don't run any analysis +- analyzeOpenPackages // run analysis on packages with open files +- analyzeEverything // run analysis on all packages +-) +- -// diagnose is a helper function for running diagnostics with a given context. -// Do not call it directly. forceAnalysis is only true for testing purposes. --func (s *Server) diagnose(ctx context.Context, snapshot source.Snapshot, forceAnalysis bool) { +-func (s *Server) diagnose(ctx context.Context, snapshot source.Snapshot, analyze analysisMode) { - ctx, done := event.Start(ctx, "Server.diagnose", source.SnapshotLabels(snapshot)...) - defer done() - - // Wait for a free diagnostics slot. - // TODO(adonovan): opt: shouldn't it be the analysis implementation's - // job to de-dup and limit resource consumption? In any case this -- // this function spends most its time waiting for awaitLoaded, at +- // function spends most its time waiting for awaitLoaded, at - // least initially. - select { - case <-ctx.Done(): @@ -35044,45 +39770,42 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - } - } - -- // Diagnose go.mod upgrades. -- upgradeReports, upgradeErr := mod.UpgradeDiagnostics(ctx, snapshot) -- if ctx.Err() != nil { -- log.Trace.Log(ctx, "diagnose cancelled") -- return -- } -- store(modCheckUpgradesSource, "diagnosing go.mod upgrades", upgradeReports, upgradeErr, true) +- // Diagnostics below are organized by increasing specificity: +- // go.work > mod > mod upgrade > mod vuln > package, etc. - - // Diagnose go.work file. - workReports, workErr := work.Diagnostics(ctx, snapshot) - if ctx.Err() != nil { -- log.Trace.Log(ctx, "diagnose cancelled") - return - } - store(workSource, "diagnosing go.work file", workReports, workErr, true) - - // Diagnose go.mod file. -- // (This step demands type checking of all active packages: -- // the bottleneck in the startup sequence for a big workspace.) - modReports, modErr := mod.Diagnostics(ctx, snapshot) - if ctx.Err() != nil { -- log.Trace.Log(ctx, "diagnose cancelled") - return - } -- store(modSource, "diagnosing go.mod file", modReports, modErr, true) +- store(modParseSource, "diagnosing go.mod file", modReports, modErr, true) +- +- // Diagnose go.mod upgrades. +- upgradeReports, upgradeErr := mod.UpgradeDiagnostics(ctx, snapshot) +- if ctx.Err() != nil { +- return +- } +- store(modCheckUpgradesSource, "diagnosing go.mod upgrades", upgradeReports, upgradeErr, true) - - // Diagnose vulnerabilities. - vulnReports, vulnErr := mod.VulnerabilityDiagnostics(ctx, snapshot) - if ctx.Err() != nil { -- log.Trace.Log(ctx, "diagnose cancelled") - return - } - store(modVulncheckSource, "diagnosing vulnerabilities", vulnReports, vulnErr, false) - -- activeMetas, activeErr := snapshot.ActiveMetadata(ctx) -- if s.shouldIgnoreError(ctx, snapshot, activeErr) { +- workspace, err := snapshot.WorkspaceMetadata(ctx) +- if s.shouldIgnoreError(ctx, snapshot, err) { - return - } -- criticalErr := snapshot.GetCriticalError(ctx) +- criticalErr := snapshot.CriticalError(ctx) - if ctx.Err() != nil { // must check ctx after GetCriticalError - return - } @@ -35101,103 +39824,200 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - - // If there are no workspace packages, there is nothing to diagnose and - // there are no orphaned files. -- if len(activeMetas) == 0 { +- if len(workspace) == 0 { - return - } - -- // Run go/analysis diagnosis of packages in parallel. -- // TODO(adonovan): opt: it may be more efficient to -- // have diagnosePkg take a set of packages. +- var wg sync.WaitGroup // for potentially slow operations below +- +- // Maybe run go mod tidy (if it has been invalidated). - // -- // TODO(adonovan): opt: since the new analysis driver does its -- // own type checking, we could strength-reduce pkg to -- // PackageID and get this step started as soon as the set of -- // active package IDs are known, without waiting for them to load. +- // Since go mod tidy can be slow, we run it concurrently to diagnostics. +- wg.Add(1) +- go func() { +- defer wg.Done() +- modTidyReports, err := mod.TidyDiagnostics(ctx, snapshot) +- store(modTidySource, "running go mod tidy", modTidyReports, err, true) +- }() +- +- // Run type checking and go/analysis diagnosis of packages in parallel. - var ( -- wg sync.WaitGroup -- seen = map[span.URI]struct{}{} +- seen = map[span.URI]struct{}{} +- toDiagnose = make(map[source.PackageID]*source.Metadata) +- toAnalyze = make(map[source.PackageID]unit) - ) -- for _, m := range activeMetas { +- for _, m := range workspace { +- var hasNonIgnored, hasOpenFile bool - for _, uri := range m.CompiledGoFiles { - seen[uri] = struct{}{} +- if !hasNonIgnored && !snapshot.IgnoredFile(uri) { +- hasNonIgnored = true +- } +- if !hasOpenFile && snapshot.IsOpen(uri) { +- hasOpenFile = true +- } +- } +- if hasNonIgnored { +- toDiagnose[m.ID] = m +- if analyze == analyzeEverything || analyze == analyzeOpenPackages && hasOpenFile { +- toAnalyze[m.ID] = unit{} +- } - } -- -- wg.Add(1) -- go func(m *source.Metadata) { -- defer wg.Done() -- s.diagnosePkg(ctx, snapshot, m, forceAnalysis) -- }(m) - } +- +- wg.Add(1) +- go func() { +- s.diagnosePkgs(ctx, snapshot, toDiagnose, toAnalyze) +- wg.Done() +- }() +- - wg.Wait() - - // Orphaned files. - // Confirm that every opened file belongs to a package (if any exist in - // the workspace). Otherwise, add a diagnostic to the file. -- for _, o := range s.session.Overlays() { -- if _, ok := seen[o.URI()]; ok { -- continue +- if diags, err := snapshot.OrphanedFileDiagnostics(ctx); err == nil { +- for uri, diag := range diags { +- s.storeDiagnostics(snapshot, uri, orphanedSource, []*source.Diagnostic{diag}, true) - } -- diagnostic := s.checkForOrphanedFile(ctx, snapshot, o) -- if diagnostic == nil { -- continue +- } else { +- if ctx.Err() == nil { +- event.Error(ctx, "computing orphaned file diagnostics", err, source.SnapshotLabels(snapshot)...) - } -- s.storeDiagnostics(snapshot, o.URI(), orphanedSource, []*source.Diagnostic{diagnostic}, true) - } -} - --func (s *Server) diagnosePkg(ctx context.Context, snapshot source.Snapshot, m *source.Metadata, alwaysAnalyze bool) { -- ctx, done := event.Start(ctx, "Server.diagnosePkg", append(source.SnapshotLabels(snapshot), tag.Package.Of(string(m.ID)))...) +-// diagnosePkgs type checks packages in toDiagnose, and analyzes packages in +-// toAnalyze, merging their diagnostics. Packages in toAnalyze must be a subset +-// of the packages in toDiagnose. +-// +-// It also implements gc_details diagnostics. +-// +-// TODO(rfindley): revisit handling of analysis gc_details. It may be possible +-// to merge this function with Server.diagnose, thereby avoiding the two layers +-// of concurrent dispatch: as of writing we concurrently run TidyDiagnostics +-// and diagnosePkgs, and diagnosePkgs concurrently runs PackageDiagnostics and +-// analysis. +-func (s *Server) diagnosePkgs(ctx context.Context, snapshot source.Snapshot, toDiagnose map[source.PackageID]*source.Metadata, toAnalyze map[source.PackageID]unit) { +- ctx, done := event.Start(ctx, "Server.diagnosePkgs", source.SnapshotLabels(snapshot)...) - defer done() -- enableDiagnostics := false -- includeAnalysis := alwaysAnalyze // only run analyses for packages with open files -- for _, uri := range m.CompiledGoFiles { -- enableDiagnostics = enableDiagnostics || !snapshot.IgnoredFile(uri) -- includeAnalysis = includeAnalysis || snapshot.IsOpen(uri) -- } -- // Don't show any diagnostics on ignored files. -- if !enableDiagnostics { -- return -- } - -- diags, err := snapshot.PackageDiagnostics(ctx, m.ID) -- if err != nil { -- event.Error(ctx, "warning: diagnostics failed", err, append(source.SnapshotLabels(snapshot), tag.Package.Of(string(m.ID)))...) -- return -- } +- // Analyze and type-check concurrently, since they are independent +- // operations. +- var ( +- wg sync.WaitGroup +- pkgDiags map[span.URI][]*source.Diagnostic +- analysisDiags = make(map[span.URI][]*source.Diagnostic) +- ) +- +- // Collect package diagnostics. +- wg.Add(1) +- go func() { +- defer wg.Done() +- var ids []source.PackageID +- for id := range toDiagnose { +- ids = append(ids, id) +- } +- var err error +- pkgDiags, err = snapshot.PackageDiagnostics(ctx, ids...) +- if err != nil { +- event.Error(ctx, "warning: diagnostics failed", err, source.SnapshotLabels(snapshot)...) +- } +- }() - - // Get diagnostics from analysis framework. - // This includes type-error analyzers, which suggest fixes to compiler errors. -- var analysisDiags map[span.URI][]*source.Diagnostic -- if includeAnalysis { -- diags, err := source.Analyze(ctx, snapshot, m.ID, false) +- wg.Add(1) +- go func() { +- defer wg.Done() +- diags, err := source.Analyze(ctx, snapshot, toAnalyze, s.progress) - if err != nil { -- event.Error(ctx, "warning: analyzing package", err, append(source.SnapshotLabels(snapshot), tag.Package.Of(string(m.ID)))...) +- var tagStr string // sorted comma-separated list of package IDs +- { +- // TODO(adonovan): replace with a generic map[S]any -> string +- // function in the tag package, and use maps.Keys + slices.Sort. +- keys := make([]string, 0, len(toDiagnose)) +- for id := range toDiagnose { +- keys = append(keys, string(id)) +- } +- sort.Strings(keys) +- tagStr = strings.Join(keys, ",") +- } +- event.Error(ctx, "warning: analyzing package", err, append(source.SnapshotLabels(snapshot), tag.Package.Of(tagStr))...) - return - } -- analysisDiags = diags -- } +- for uri, diags := range diags { +- analysisDiags[uri] = append(analysisDiags[uri], diags...) +- } +- }() - -- // For each file, update the server's diagnostics state. -- for _, uri := range m.CompiledGoFiles { -- // builtin.go exists only for documentation purposes and -- // is not valid Go code. Don't report distracting errors. -- if snapshot.IsBuiltin(ctx, uri) { +- wg.Wait() +- +- // TODO(rfindley): remove the guards against snapshot.IsBuiltin, after the +- // gopls@v0.12.0 release. Packages should not be producing diagnostics for +- // the builtin file: I do not know why this logic existed previously. +- +- // Merge analysis diagnostics with package diagnostics, and store the +- // resulting analysis diagnostics. +- for uri, adiags := range analysisDiags { +- if snapshot.IsBuiltin(uri) { +- bug.Reportf("go/analysis reported diagnostics for the builtin file: %v", adiags) - continue - } +- tdiags := pkgDiags[uri] +- var tdiags2, adiags2 []*source.Diagnostic +- source.CombineDiagnostics(tdiags, adiags, &tdiags2, &adiags2) +- pkgDiags[uri] = tdiags2 +- s.storeDiagnostics(snapshot, uri, analysisSource, adiags2, true) +- } - -- pkgDiags := diags[uri] -- var tdiags, adiags []*source.Diagnostic -- source.CombineDiagnostics(pkgDiags, analysisDiags[uri], &tdiags, &adiags) -- s.storeDiagnostics(snapshot, uri, typeCheckSource, tdiags, true) -- s.storeDiagnostics(snapshot, uri, analysisSource, adiags, true) +- // golang/go#59587: guarantee that we store type-checking diagnostics for every compiled +- // package file. +- // +- // Without explicitly storing empty diagnostics, the eager diagnostics +- // publication for changed files will not publish anything for files with +- // empty diagnostics. +- storedPkgDiags := make(map[span.URI]bool) +- for _, m := range toDiagnose { +- for _, uri := range m.CompiledGoFiles { +- s.storeDiagnostics(snapshot, uri, typeCheckSource, pkgDiags[uri], true) +- storedPkgDiags[uri] = true +- } +- } +- // Store the package diagnostics. +- for uri, diags := range pkgDiags { +- if storedPkgDiags[uri] { +- continue +- } +- // builtin.go exists only for documentation purposes, and is not valid Go code. +- // Don't report distracting errors +- if snapshot.IsBuiltin(uri) { +- bug.Reportf("type checking reported diagnostics for the builtin file: %v", diags) +- continue +- } +- s.storeDiagnostics(snapshot, uri, typeCheckSource, diags, true) - } - -- // If gc optimization details are requested, add them to the -- // diagnostic reports. +- // Process requested gc_details diagnostics. +- // +- // TODO(rfindley): this could be improved: +- // 1. This should memoize its results if the package has not changed. +- // 2. This should not even run gc_details if the package contains unsaved +- // files. +- // 3. See note below about using FindFile. +- var toGCDetail map[source.PackageID]*source.Metadata - s.gcOptimizationDetailsMu.Lock() -- _, enableGCDetails := s.gcOptimizationDetails[m.ID] +- for id := range s.gcOptimizationDetails { +- if m, ok := toDiagnose[id]; ok { +- if toGCDetail == nil { +- toGCDetail = make(map[source.PackageID]*source.Metadata) +- } +- toGCDetail[id] = m +- } +- } - s.gcOptimizationDetailsMu.Unlock() -- if enableGCDetails { +- +- for _, m := range toGCDetail { - gcReports, err := source.GCOptimizationDetails(ctx, snapshot, m) - if err != nil { - event.Error(ctx, "warning: gc details", err, append(source.SnapshotLabels(snapshot), tag.Package.Of(string(m.ID)))...) @@ -35211,6 +40031,9 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - // diagnostics does not race with storing the results here. - if enableGCDetails { - for uri, diags := range gcReports { +- // TODO(rfindley): remove the use of FindFile here, and use ReadFile +- // instead. Isn't it enough to know that the package came from the +- // snapshot? Any reports should apply to the snapshot. - fh := snapshot.FindFile(uri) - // Don't publish gc details for unsaved buffers, since the underlying - // logic operates on the file on disk. @@ -35236,7 +40059,7 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - if s.diagnostics[uri] == nil { - s.diagnostics[uri] = &fileReports{ - publishedHash: hashDiagnostics(), // Hash for 0 diagnostics. -- reports: map[diagnosticSource]diagnosticReport{}, +- reports: map[diagnosticSource]*diagnosticReport{}, - } - } - s.diagnostics[uri].mustPublish = true @@ -35245,6 +40068,8 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g -// storeDiagnostics stores results from a single diagnostic source. If merge is -// true, it merges results into any existing results for this snapshot. -// +-// Mutates (sorts) diags. +-// -// TODO(hyangah): investigate whether we can unconditionally overwrite previous report.diags -// with the new diags and eliminate the need for the `merge` flag. -func (s *Server) storeDiagnostics(snapshot source.Snapshot, uri span.URI, dsource diagnosticSource, diags []*source.Diagnostic, merge bool) { @@ -35260,10 +40085,14 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - if s.diagnostics[uri] == nil { - s.diagnostics[uri] = &fileReports{ - publishedHash: hashDiagnostics(), // Hash for 0 diagnostics. -- reports: map[diagnosticSource]diagnosticReport{}, +- reports: map[diagnosticSource]*diagnosticReport{}, - } - } - report := s.diagnostics[uri].reports[dsource] +- if report == nil { +- report = new(diagnosticReport) +- s.diagnostics[uri].reports[dsource] = report +- } - // Don't set obsolete diagnostics. - if report.snapshotID > snapshot.GlobalID() { - return @@ -35275,7 +40104,6 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - for _, d := range diags { - report.diags[hashDiagnostics(d)] = d - } -- s.diagnostics[uri].reports[dsource] = report -} - -// clearDiagnosticSource clears all diagnostics for a given source type. It is @@ -35303,7 +40131,7 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - if err != nil { - event.Error(ctx, "errors loading workspace", err.MainError, source.SnapshotLabels(snapshot)...) - for _, d := range err.Diagnostics { -- s.storeDiagnostics(snapshot, d.URI, modSource, []*source.Diagnostic{d}, true) +- s.storeDiagnostics(snapshot, d.URI, modParseSource, []*source.Diagnostic{d}, true) - } - errMsg = strings.ReplaceAll(err.MainError.Error(), "\n", " ") - } @@ -35325,66 +40153,6 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - } -} - --// checkForOrphanedFile checks that the given URIs can be mapped to packages. --// If they cannot and the workspace is not otherwise unloaded, it also surfaces --// a warning, suggesting that the user check the file for build tags. --func (s *Server) checkForOrphanedFile(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) *source.Diagnostic { -- // TODO(rfindley): this function may fail to produce a diagnostic for a -- // variety of reasons, some of which should probably not be ignored. For -- // example, should this function be tolerant of the case where fh does not -- // exist, or does not have a package name? -- // -- // It would be better to panic or report a bug in several of the cases below, -- // so that we can move toward guaranteeing we show the user a meaningful -- // error whenever it makes sense. -- if snapshot.View().FileKind(fh) != source.Go { -- return nil -- } -- // builtin files won't have a package, but they are never orphaned. -- if snapshot.IsBuiltin(ctx, fh.URI()) { -- return nil -- } -- -- // This call has the effect of inserting fh into snapshot.files, -- // where for better or worse (actually: just worse) it influences -- // the sets of open, known, and orphaned files. -- snapshot.GetFile(ctx, fh.URI()) -- -- metas, _ := snapshot.MetadataForFile(ctx, fh.URI()) -- if len(metas) > 0 || ctx.Err() != nil { -- return nil // no package, or cancelled -- } -- // Inv: file does not belong to a package we know about. -- pgf, err := snapshot.ParseGo(ctx, fh, source.ParseHeader) -- if err != nil { -- return nil -- } -- if !pgf.File.Name.Pos().IsValid() { -- return nil -- } -- rng, err := pgf.NodeRange(pgf.File.Name) -- if err != nil { -- return nil -- } -- // If the file no longer has a name ending in .go, this diagnostic is wrong -- if filepath.Ext(fh.URI().Filename()) != ".go" { -- return nil -- } -- // TODO(rstambler): We should be able to parse the build tags in the -- // file and show a more specific error message. For now, put the diagnostic -- // on the package declaration. -- return &source.Diagnostic{ -- URI: fh.URI(), -- Range: rng, -- Severity: protocol.SeverityWarning, -- Source: source.ListError, -- Message: fmt.Sprintf(`No packages found for open file %s: %v. --If this file contains build tags, try adding "-tags=" to your gopls "buildFlags" configuration (see (https://github.com/golang/tools/blob/master/gopls/doc/settings.md#buildflags-string). --Otherwise, see the troubleshooting guidelines for help investigating (https://github.com/golang/tools/blob/master/gopls/doc/troubleshooting.md). --`, fh.URI().Filename(), err), -- } --} -- -// publishDiagnostics collects and publishes any unpublished diagnostic reports. -func (s *Server) publishDiagnostics(ctx context.Context, final bool, snapshot source.Snapshot) { - ctx, done := event.Start(ctx, "Server.publishDiagnostics", source.SnapshotLabels(snapshot)...) @@ -35422,6 +40190,7 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - diags = append(diags, d) - reportDiags = append(reportDiags, d) - } +- - hash := hashDiagnostics(reportDiags...) - if hash != report.publishedHash { - anyReportsChanged = true @@ -35435,7 +40204,6 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - continue - } - -- source.SortDiagnostics(diags) - hash := hashDiagnostics(diags...) - if hash == r.publishedHash && !r.mustPublish { - // Update snapshotID to be the latest snapshot for which this diagnostic @@ -35455,15 +40223,22 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - r.publishedHash = hash - r.mustPublish = false // diagnostics have been successfully published - r.publishedSnapshotID = snapshot.GlobalID() -- for dsource, hash := range reportHashes { -- report := r.reports[dsource] -- report.publishedHash = hash -- r.reports[dsource] = report +- // When we publish diagnostics for a file, we must update the +- // publishedHash for every report, not just the reports that were +- // published. Eliding a report is equivalent to publishing empty +- // diagnostics. +- for dsource, report := range r.reports { +- if hash, ok := reportHashes[dsource]; ok { +- report.publishedHash = hash +- } else { +- // The report was not (yet) stored for this snapshot. Record that we +- // published no diagnostics from this source. +- report.publishedHash = hashDiagnostics() +- } - } - } else { - if ctx.Err() != nil { - // Publish may have failed due to a cancelled context. -- log.Trace.Log(ctx, "publish cancelled") - return - } - event.Error(ctx, "publishReports: failed to deliver diagnostic", err, tag.URI.Of(uri)) @@ -35480,8 +40255,9 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - Range: diag.Range, - Severity: diag.Severity, - Source: string(diag.Source), -- Tags: diag.Tags, +- Tags: emptySliceDiagnosticTag(diag.Tags), - RelatedInformation: diag.Related, +- Data: diag.BundledFixes, - } - if diag.Code != "" { - pdiag.Code = diag.Code @@ -35502,6 +40278,8 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - return true - } - // If the folder has no Go code in it, we shouldn't spam the user with a warning. +- // TODO(rfindley): surely it is not correct to walk the folder here just to +- // suppress diagnostics, every time we compute diagnostics. - var hasGo bool - _ = filepath.Walk(snapshot.View().Folder().Filename(), func(path string, info os.FileInfo, err error) error { - if err != nil { @@ -35537,7 +40315,7 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g - return ans -} - --func auxStr(v *source.Diagnostic, d diagnosticReport, typ diagnosticSource) string { +-func auxStr(v *source.Diagnostic, d *diagnosticReport, typ diagnosticSource) string { - // Tags? RelatedInformation? - msg := fmt.Sprintf("(%s)%q(source:%q,code:%q,severity:%s,snapshot:%d,type:%s)", - v.Range, v.Message, v.Source, v.Code, v.Severity, d.snapshotID, typ) @@ -35549,7 +40327,7 @@ diff -urN a/gopls/internal/lsp/diagnostics.go b/gopls/internal/lsp/diagnostics.g diff -urN a/gopls/internal/lsp/fake/client.go b/gopls/internal/lsp/fake/client.go --- a/gopls/internal/lsp/fake/client.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/fake/client.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,187 +0,0 @@ +@@ -1,193 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -35566,7 +40344,7 @@ diff -urN a/gopls/internal/lsp/fake/client.go b/gopls/internal/lsp/fake/client.g -) - -// ClientHooks are a set of optional hooks called during handling of --// the corresponding client method (see protocol.Client for the the +-// the corresponding client method (see protocol.Client for the -// LSP server-to-client RPCs) in order to make test expectations -// awaitable. -type ClientHooks struct { @@ -35574,6 +40352,7 @@ diff -urN a/gopls/internal/lsp/fake/client.go b/gopls/internal/lsp/fake/client.g - OnDiagnostics func(context.Context, *protocol.PublishDiagnosticsParams) error - OnWorkDoneProgressCreate func(context.Context, *protocol.WorkDoneProgressCreateParams) error - OnProgress func(context.Context, *protocol.ProgressParams) error +- OnShowDocument func(context.Context, *protocol.ShowDocumentParams) error - OnShowMessage func(context.Context, *protocol.ShowMessageParams) error - OnShowMessageRequest func(context.Context, *protocol.ShowMessageRequestParams) error - OnRegisterCapability func(context.Context, *protocol.RegistrationParams) error @@ -35646,9 +40425,8 @@ diff -urN a/gopls/internal/lsp/fake/client.go b/gopls/internal/lsp/fake/client.g - results := make([]interface{}, len(p.Items)) - for i, item := range p.Items { - if item.Section == "gopls" { -- c.editor.mu.Lock() -- results[i] = c.editor.settingsLocked() -- c.editor.mu.Unlock() +- config := c.editor.Config() +- results[i] = makeSettings(c.editor.sandbox, config) - } - } - return results, nil @@ -35715,7 +40493,13 @@ diff -urN a/gopls/internal/lsp/fake/client.go b/gopls/internal/lsp/fake/client.g - return nil -} - --func (c *Client) ShowDocument(context.Context, *protocol.ShowDocumentParams) (*protocol.ShowDocumentResult, error) { +-func (c *Client) ShowDocument(ctx context.Context, params *protocol.ShowDocumentParams) (*protocol.ShowDocumentResult, error) { +- if c.hooks.OnShowDocument != nil { +- if err := c.hooks.OnShowDocument(ctx, params); err != nil { +- return nil, err +- } +- return &protocol.ShowDocumentResult{Success: true}, nil +- } - return nil, nil -} - @@ -35818,7 +40602,7 @@ diff -urN a/gopls/internal/lsp/fake/edit.go b/gopls/internal/lsp/fake/edit.go diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.go --- a/gopls/internal/lsp/fake/editor.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/fake/editor.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1464 +0,0 @@ +@@ -1,1481 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -35858,7 +40642,6 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - serverConn jsonrpc2.Conn - client *Client - sandbox *Sandbox -- defaultEnv map[string]string - - // TODO(adonovan): buffers should be keyed by protocol.DocumentURI. - mu sync.Mutex @@ -35896,8 +40679,14 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g -// source.UserOptions, but we use a separate type here so that we expose only -// that configuration which we support. -// --// The zero value for EditorConfig should correspond to its defaults. +-// The zero value for EditorConfig is the default configuration. -type EditorConfig struct { +- // ClientName sets the clientInfo.name for the LSP session (in the initialize request). +- // +- // Since this can only be set during initialization, changing this field via +- // Editor.ChangeConfiguration has no effect. +- ClientName string +- - // Env holds environment variables to apply on top of the default editor - // environment. When applying these variables, the special string - // $SANDBOX_WORKDIR is replaced by the absolute path to the sandbox working @@ -35930,10 +40719,9 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g -// NewEditor creates a new Editor. -func NewEditor(sandbox *Sandbox, config EditorConfig) *Editor { - return &Editor{ -- buffers: make(map[string]buffer), -- sandbox: sandbox, -- defaultEnv: sandbox.GoEnv(), -- config: config, +- buffers: make(map[string]buffer), +- sandbox: sandbox, +- config: config, - } -} - @@ -36019,19 +40807,17 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - return e.client -} - --// settingsLocked builds the settings map for use in LSP settings RPCs. --// --// e.mu must be held while calling this function. --func (e *Editor) settingsLocked() map[string]interface{} { +-// makeSettings builds the settings map for use in LSP settings RPCs. +-func makeSettings(sandbox *Sandbox, config EditorConfig) map[string]interface{} { - env := make(map[string]string) -- for k, v := range e.defaultEnv { +- for k, v := range sandbox.GoEnv() { - env[k] = v - } -- for k, v := range e.config.Env { +- for k, v := range config.Env { - env[k] = v - } - for k, v := range env { -- v = strings.ReplaceAll(v, "$SANDBOX_WORKDIR", e.sandbox.Workdir.RootURI().SpanURI().Filename()) +- v = strings.ReplaceAll(v, "$SANDBOX_WORKDIR", sandbox.Workdir.RootURI().SpanURI().Filename()) - env[k] = v - } - @@ -36045,13 +40831,9 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - // Set a generous completion budget, so that tests don't flake because - // completions are too slow. - "completionBudget": "10s", -- -- // Shorten the diagnostic delay to speed up test execution (else we'd add -- // the default delay to each assertion about diagnostics) -- "diagnosticsDelay": "10ms", - } - -- for k, v := range e.config.Settings { +- for k, v := range config.Settings { - if k == "env" { - panic("must not provide env via the EditorConfig.Settings field: use the EditorConfig.Env field instead") - } @@ -36062,20 +40844,22 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g -} - -func (e *Editor) initialize(ctx context.Context) error { +- config := e.Config() +- - params := &protocol.ParamInitialize{} -- params.ClientInfo = &protocol.Msg_XInitializeParams_clientInfo{} -- params.ClientInfo.Name = "fakeclient" -- params.ClientInfo.Version = "v1.0.0" -- e.mu.Lock() -- params.WorkspaceFolders = e.makeWorkspaceFoldersLocked() -- params.InitializationOptions = e.settingsLocked() -- e.mu.Unlock() -- params.Capabilities.Workspace.Configuration = true -- params.Capabilities.Window.WorkDoneProgress = true +- if e.config.ClientName != "" { +- params.ClientInfo = &protocol.Msg_XInitializeParams_clientInfo{} +- params.ClientInfo.Name = e.config.ClientName +- params.ClientInfo.Version = "v1.0.0" +- } +- params.InitializationOptions = makeSettings(e.sandbox, config) +- params.WorkspaceFolders = makeWorkspaceFolders(e.sandbox, config.WorkspaceFolders) +- params.Capabilities.Workspace.Configuration = true // support workspace/configuration +- params.Capabilities.Window.WorkDoneProgress = true // support window/workDoneProgress - -- // TODO: set client capabilities -- params.Capabilities.TextDocument.Completion.CompletionItem.TagSupport.ValueSet = []protocol.CompletionItemTag{protocol.ComplDeprecated} +- // TODO(rfindley): set client capabilities (note from the future: why?) - +- params.Capabilities.TextDocument.Completion.CompletionItem.TagSupport.ValueSet = []protocol.CompletionItemTag{protocol.ComplDeprecated} - params.Capabilities.TextDocument.Completion.CompletionItem.SnippetSupport = true - params.Capabilities.TextDocument.SemanticTokens.Requests.Full.Value = true - // copied from lsp/semantic.go to avoid import cycle in tests @@ -36090,11 +40874,16 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - "deprecated", "abstract", "async", "modification", "documentation", "defaultLibrary", - } - -- // This is a bit of a hack, since the fake editor doesn't actually support -- // watching changed files that match a specific glob pattern. However, the -- // editor does send didChangeWatchedFiles notifications, so set this to -- // true. +- // The LSP tests have historically enabled this flag, +- // but really we should test both ways for older editors. +- params.Capabilities.TextDocument.DocumentSymbol.HierarchicalDocumentSymbolSupport = true +- +- // Glob pattern watching is enabled. - params.Capabilities.Workspace.DidChangeWatchedFiles.DynamicRegistration = true +- +- // "rename" operations are used for package renaming. +- // +- // TODO(rfindley): add support for other resource operations (create, delete, ...) - params.Capabilities.Workspace.WorkspaceEdit = &protocol.WorkspaceEditClientCapabilities{ - ResourceOperations: []protocol.ResourceOperationKind{ - "rename", @@ -36121,18 +40910,25 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - return nil -} - --// makeWorkspaceFoldersLocked creates a slice of workspace folders to use for +-// HasCommand reports whether the connected server supports the command with the given ID. +-func (e *Editor) HasCommand(id string) bool { +- for _, command := range e.serverCapabilities.ExecuteCommandProvider.Commands { +- if command == id { +- return true +- } +- } +- return false +-} +- +-// makeWorkspaceFolders creates a slice of workspace folders to use for -// this editing session, based on the editor configuration. --// --// e.mu must be held while calling this function. --func (e *Editor) makeWorkspaceFoldersLocked() (folders []protocol.WorkspaceFolder) { -- paths := e.config.WorkspaceFolders +-func makeWorkspaceFolders(sandbox *Sandbox, paths []string) (folders []protocol.WorkspaceFolder) { - if len(paths) == 0 { -- paths = append(paths, string(e.sandbox.Workdir.RelativeTo)) +- paths = []string{string(sandbox.Workdir.RelativeTo)} - } - - for _, path := range paths { -- uri := string(e.sandbox.Workdir.URI(path)) +- uri := string(sandbox.Workdir.URI(path)) - folders = append(folders, protocol.WorkspaceFolder{ - URI: uri, - Name: filepath.Base(uri), @@ -37150,14 +41946,18 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g - return e.config -} - +-func (e *Editor) SetConfig(cfg EditorConfig) { +- e.mu.Lock() +- e.config = cfg +- e.mu.Unlock() +-} +- -// ChangeConfiguration sets the new editor configuration, and if applicable -// sends a didChangeConfiguration notification. -// -// An error is returned if the change notification failed to send. -func (e *Editor) ChangeConfiguration(ctx context.Context, newConfig EditorConfig) error { -- e.mu.Lock() -- e.config = newConfig -- e.mu.Unlock() // don't hold e.mu during server calls +- e.SetConfig(newConfig) - if e.Server != nil { - var params protocol.DidChangeConfigurationParams // empty: gopls ignores the Settings field - if err := e.Server.DidChangeConfiguration(ctx, ¶ms); err != nil { @@ -37172,12 +41972,13 @@ diff -urN a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.g -// -// The given folders must all be unique. -func (e *Editor) ChangeWorkspaceFolders(ctx context.Context, folders []string) error { +- config := e.Config() +- - // capture existing folders so that we can compute the change. -- e.mu.Lock() -- oldFolders := e.makeWorkspaceFoldersLocked() -- e.config.WorkspaceFolders = folders -- newFolders := e.makeWorkspaceFoldersLocked() -- e.mu.Unlock() +- oldFolders := makeWorkspaceFolders(e.sandbox, config.WorkspaceFolders) +- newFolders := makeWorkspaceFolders(e.sandbox, folders) +- config.WorkspaceFolders = folders +- e.SetConfig(config) - - if e.Server == nil { - return nil @@ -37490,7 +42291,7 @@ diff -urN a/gopls/internal/lsp/fake/proxy.go b/gopls/internal/lsp/fake/proxy.go diff -urN a/gopls/internal/lsp/fake/sandbox.go b/gopls/internal/lsp/fake/sandbox.go --- a/gopls/internal/lsp/fake/sandbox.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/fake/sandbox.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,299 +0,0 @@ +@@ -1,300 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -37747,10 +42548,11 @@ diff -urN a/gopls/internal/lsp/fake/sandbox.go b/gopls/internal/lsp/fake/sandbox -// RunGoCommand executes a go command in the sandbox. If checkForFileChanges is -// true, the sandbox scans the working directory and emits file change events -// for any file changes it finds. --func (sb *Sandbox) RunGoCommand(ctx context.Context, dir, verb string, args []string, checkForFileChanges bool) error { +-func (sb *Sandbox) RunGoCommand(ctx context.Context, dir, verb string, args, env []string, checkForFileChanges bool) error { - inv := sb.goCommandInvocation() - inv.Verb = verb - inv.Args = args +- inv.Env = append(inv.Env, env...) - if dir != "" { - inv.WorkingDir = sb.Workdir.AbsPath(dir) - } @@ -37759,7 +42561,7 @@ diff -urN a/gopls/internal/lsp/fake/sandbox.go b/gopls/internal/lsp/fake/sandbox - return fmt.Errorf("go command failed (stdout: %s) (stderr: %s): %v", stdout.String(), stderr.String(), err) - } - // Since running a go command may result in changes to workspace files, -- // check if we need to send any any "watched" file events. +- // check if we need to send any "watched" file events. - // - // TODO(rFindley): this side-effect can impact the usability of the sandbox - // for benchmarks. Consider refactoring. @@ -37782,7 +42584,7 @@ diff -urN a/gopls/internal/lsp/fake/sandbox.go b/gopls/internal/lsp/fake/sandbox -func (sb *Sandbox) Close() error { - var goCleanErr error - if sb.gopath != "" { -- goCleanErr = sb.RunGoCommand(context.Background(), "", "clean", []string{"-modcache"}, false) +- goCleanErr = sb.RunGoCommand(context.Background(), "", "clean", []string{"-modcache"}, nil, false) - } - err := robustio.RemoveAll(sb.rootdir) - if err != nil || goCleanErr != nil { @@ -37793,7 +42595,7 @@ diff -urN a/gopls/internal/lsp/fake/sandbox.go b/gopls/internal/lsp/fake/sandbox diff -urN a/gopls/internal/lsp/fake/workdir.go b/gopls/internal/lsp/fake/workdir.go --- a/gopls/internal/lsp/fake/workdir.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/fake/workdir.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,438 +0,0 @@ +@@ -1,431 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -37916,7 +42718,7 @@ diff -urN a/gopls/internal/lsp/fake/workdir.go b/gopls/internal/lsp/fake/workdir -// fileID identifies a file version on disk. -type fileID struct { - mtime time.Time -- hash string // empty if mtime is old enough to be reliabe; otherwise a file digest +- hash string // empty if mtime is old enough to be reliable; otherwise a file digest -} - -func hashFile(data []byte) string { @@ -38015,13 +42817,6 @@ diff -urN a/gopls/internal/lsp/fake/workdir.go b/gopls/internal/lsp/fake/workdir - return w.WriteFiles(ctx, map[string]string{path: content}) -} - --func (w *Workdir) fileEvent(path string, changeType protocol.FileChangeType) protocol.FileEvent { -- return protocol.FileEvent{ -- URI: w.URI(path), -- Type: changeType, -- } --} -- -// RenameFile performs an on disk-renaming of the workdir-relative oldPath to -// workdir-relative newPath, and notifies watchers of the changes. -// @@ -38166,7 +42961,7 @@ diff -urN a/gopls/internal/lsp/fake/workdir.go b/gopls/internal/lsp/fake/workdir - return nil - } - -- // Opt: avoid reading the file if mtime is sufficently old to be reliable. +- // Opt: avoid reading the file if mtime is sufficiently old to be reliable. - // - // If mtime is recent, it may not sufficiently identify the file contents: - // a subsequent write could result in the same mtime. For these cases, we @@ -38484,7 +43279,7 @@ diff -urN a/gopls/internal/lsp/fake/workdir_windows.go b/gopls/internal/lsp/fake diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filecache/filecache.go --- a/gopls/internal/lsp/filecache/filecache.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/filecache/filecache.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,369 +0,0 @@ +@@ -1,608 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -38510,60 +43305,114 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec -import ( - "bytes" - "crypto/sha256" -- "encoding/binary" +- "encoding/hex" +- "encoding/json" - "errors" - "fmt" - "io" +- "io/fs" - "log" - "os" - "path/filepath" - "sort" +- "strings" - "sync" - "sync/atomic" - "time" - -- "golang.org/x/tools/internal/lockedfile" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/lru" -) - --// Get retrieves from the cache and returns a newly allocated --// copy of the value most recently supplied to Set(kind, key), --// possibly by another process. +-// Start causes the filecache to initialize and start garbage gollection. +-// +-// Start is automatically called by the first call to Get, but may be called +-// explicitly to pre-initialize the cache. +-func Start() { +- go getCacheDir() +-} +- +-// As an optimization, use a 100MB in-memory LRU cache in front of filecache +-// operations. This reduces I/O for operations such as diagnostics or +-// implementations that repeatedly access the same cache entries. +-var memCache = lru.New(100 * 1e6) +- +-type memKey struct { +- kind string +- key [32]byte +-} +- +-// Get retrieves from the cache and returns the value most recently +-// supplied to Set(kind, key), possibly by another process. -// Get returns ErrNotFound if the value was not found. +-// +-// Callers should not modify the returned array. -func Get(kind string, key [32]byte) ([]byte, error) { -- name := filename(kind, key) -- data, err := lockedfile.Read(name) +- // First consult the read-through memory cache. +- // Note that memory cache hits do not update the times +- // used for LRU eviction of the file-based cache. +- if value := memCache.Get(memKey{kind, key}); value != nil { +- return value.([]byte), nil +- } +- +- iolimit <- struct{}{} // acquire a token +- defer func() { <-iolimit }() // release a token +- +- // Read the index file, which provides the name of the CAS file. +- indexName, err := filename(kind, key) +- if err != nil { +- return nil, err +- } +- indexData, err := os.ReadFile(indexName) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return nil, ErrNotFound - } - return nil, err - } +- var valueHash [32]byte +- if copy(valueHash[:], indexData) != len(valueHash) { +- return nil, ErrNotFound // index entry has wrong length +- } - -- // Verify that the Write was complete -- // by checking the recorded length. -- if len(data) < 8 { -- return nil, ErrNotFound // cache entry is incomplete +- // Read the CAS file and check its contents match. +- // +- // This ensures integrity in all cases (corrupt or truncated +- // file, short read, I/O error, wrong length, etc) except an +- // engineered hash collision, which is infeasible. +- casName, err := filename(casKind, valueHash) +- if err != nil { +- return nil, err - } -- if length := binary.LittleEndian.Uint64(data); int(length) != len(data)-8 { -- return nil, ErrNotFound // cache entry is incomplete (or too long!) +- value, _ := os.ReadFile(casName) // ignore error +- if sha256.Sum256(value) != valueHash { +- return nil, ErrNotFound // CAS file is missing or has wrong contents - } -- data = data[8:] - -- // Update file time for use by LRU eviction. -- // (This turns every read into a write operation. -- // If this is a performance problem, we should -- // touch the files aynchronously.) +- // Update file times used by LRU eviction. +- // +- // Because this turns a read into a write operation, +- // we follow the approach used in the go command's +- // cache and update the access time only if the +- // existing timestamp is older than one hour. - // - // (Traditionally the access time would be updated - // automatically, but for efficiency most POSIX systems have - // for many years set the noatime mount option to avoid every - // open or read operation entailing a metadata write.) - now := time.Now() -- if err := os.Chtimes(name, now, now); err != nil { -- return nil, fmt.Errorf("failed to update access time: %w", err) +- touch := func(filename string) { +- st, err := os.Stat(filename) +- if err == nil && now.Sub(st.ModTime()) > time.Hour { +- os.Chtimes(filename, now, now) // ignore error +- } - } +- touch(indexName) +- touch(casName) - -- return data, nil +- memCache.Set(memKey{kind, key}, value, len(value)) +- +- return value, nil -} - -// ErrNotFound is the distinguished error @@ -38572,37 +43421,97 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - -// Set updates the value in the cache. -func Set(kind string, key [32]byte, value []byte) error { -- name := filename(kind, key) -- if err := os.MkdirAll(filepath.Dir(name), 0700); err != nil { +- memCache.Set(memKey{kind, key}, value, len(value)) +- +- // Set the active event to wake up the GC. +- select { +- case active <- struct{}{}: +- default: +- } +- +- iolimit <- struct{}{} // acquire a token +- defer func() { <-iolimit }() // release a token +- +- // First, add the value to the content- +- // addressable store (CAS), if not present. +- hash := sha256.Sum256(value) +- casName, err := filename(casKind, hash) +- if err != nil { +- return err +- } +- // Does CAS file exist and have correct (complete) content? +- // TODO(adonovan): opt: use mmap for this check. +- if prev, _ := os.ReadFile(casName); !bytes.Equal(prev, value) { +- if err := os.MkdirAll(filepath.Dir(casName), 0700); err != nil { +- return err +- } +- // Avoiding O_TRUNC here is merely an optimization to avoid +- // cache misses when two threads race to write the same file. +- if err := writeFileNoTrunc(casName, value, 0600); err != nil { +- os.Remove(casName) // ignore error +- return err // e.g. disk full +- } +- } +- +- // Now write an index entry that refers to the CAS file. +- indexName, err := filename(kind, key) +- if err != nil { +- return err +- } +- if err := os.MkdirAll(filepath.Dir(indexName), 0700); err != nil { - return err - } +- if err := writeFileNoTrunc(indexName, hash[:], 0600); err != nil { +- os.Remove(indexName) // ignore error +- return err // e.g. disk full +- } - -- // In the unlikely event of a short write (e.g. ENOSPC) -- // followed by process termination (e.g. a power cut), we -- // don't want a reader to see a short file, so we record -- // the expected length first and verify it in Get. -- var length [8]byte -- binary.LittleEndian.PutUint64(length[:], uint64(len(value))) -- header := bytes.NewReader(length[:]) -- payload := bytes.NewReader(value) +- return nil +-} - -- // Windows doesn't support atomic rename--we tried MoveFile, -- // MoveFileEx, ReplaceFileEx, and SetFileInformationByHandle -- // of RenameFileInfo, all to no avail--so instead we use -- // advisory file locking, which is only about 2x slower even -- // on POSIX platforms with atomic rename. -- return lockedfile.Write(name, io.MultiReader(header, payload), 0600) +-// The active 1-channel is a selectable resettable event +-// indicating recent cache activity. +-var active = make(chan struct{}, 1) +- +-// writeFileNoTrunc is like os.WriteFile but doesn't truncate until +-// after the write, so that racing writes of the same data are idempotent. +-func writeFileNoTrunc(filename string, data []byte, perm os.FileMode) error { +- f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, perm) +- if err != nil { +- return err +- } +- _, err = f.Write(data) +- if err == nil { +- err = f.Truncate(int64(len(data))) +- } +- if closeErr := f.Close(); err == nil { +- err = closeErr +- } +- return err -} - +-// reserved kind strings +-const ( +- casKind = "cas" // content-addressable store files +- bugKind = "bug" // gopls bug reports +-) +- +-var iolimit = make(chan struct{}, 128) // counting semaphore to limit I/O concurrency in Set. +- -var budget int64 = 1e9 // 1GB - --// SetBudget sets a soft limit on disk usage of the cache (in bytes) --// and returns the previous value. Supplying a negative value queries --// the current value without changing it. +-// SetBudget sets a soft limit on disk usage of regular files in the +-// cache (in bytes) and returns the previous value. Supplying a +-// negative value queries the current value without changing it. -// -// If two gopls processes have different budgets, the one with the -// lower budget will collect garbage more actively, but both will -// observe the effect. +-// +-// Even in the steady state, the storage usage reported by the 'du' +-// command may exceed the budget by as much as a factor of 3 due to +-// the overheads of directories and the effects of block quantization, +-// which are especially pronounced for the small index files. -func SetBudget(new int64) (old int64) { - if new < 0 { - return atomic.LoadInt64(&budget) @@ -38612,22 +43521,62 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - -// --- implementation ---- - --// filename returns the cache entry of the specified kind and key. +-// filename returns the name of the cache file of the specified kind and key. -// --// A typical cache entry is a file name such as: +-// A typical cache file has a name such as: -// --// $HOME/Library/Caches / gopls / VVVVVVVV / kind / KK / KKKK...KKKK +-// $HOME/Library/Caches / gopls / VVVVVVVV / KK / KKKK...KKKK - kind -// -// The portions separated by spaces are as follows: -// - The user's preferred cache directory; the default value varies by OS. -// - The constant "gopls". -// - The "version", 32 bits of the digest of the gopls executable. --// - The kind or purpose of this cache subtree (e.g. "analysis"). -// - The first 8 bits of the key, to avoid huge directories. -// - The full 256 bits of the key. --// --// Once a file is written its contents are never modified, though it --// may be atomically replaced or removed. +-// - The kind or purpose of this cache file (e.g. "analysis"). +-// +-// The kind establishes a namespace for the keys. It is represented as +-// a suffix, not a segment, as this significantly reduces the number +-// of directories created, and thus the storage overhead. +-// +-// Previous iterations of the design aimed for the invariant that once +-// a file is written, its contents are never modified, though it may +-// be atomically replaced or removed. However, not all platforms have +-// an atomic rename operation (our first approach), and file locking +-// (our second) is a notoriously fickle mechanism. +-// +-// The current design instead exploits a trick from the cache +-// implementation used by the go command: writes of small files are in +-// practice atomic (all or nothing) on all platforms. +-// (See GOROOT/src/cmd/go/internal/cache/cache.go.) +-// +-// Russ Cox notes: "all file systems use an rwlock around every file +-// system block, including data blocks, so any writes or reads within +-// the same block are going to be handled atomically by the FS +-// implementation without any need to request file locking explicitly. +-// And since the files are so small, there's only one block. (A block +-// is at minimum 512 bytes, usually much more.)" And: "all modern file +-// systems protect against [partial writes due to power loss] with +-// journals." +-// +-// We use a two-level scheme consisting of an index and a +-// content-addressable store (CAS). A single cache entry consists of +-// two files. The value of a cache entry is written into the file at +-// filename("cas", sha256(value)). Since the value may be arbitrarily +-// large, this write is not atomic. That means we must check the +-// integrity of the contents read back from the CAS to make sure they +-// hash to the expected key. If the CAS file is incomplete or +-// inconsistent, we proceed as if it were missing. +-// +-// Once the CAS file has been written, we write a small fixed-size +-// index file at filename(kind, key), using the values supplied by the +-// caller. The index file contains the hash that identifies the value +-// file in the CAS. (We could add extra metadata to this file, up to +-// 512B, the minimum size of a disk block, if later desired, so long +-// as the total size remains fixed.) Because the index file is small, +-// concurrent writes to it are atomic in practice, even though this is +-// not guaranteed by any OS. The fixed size ensures that readers can't +-// see a palimpsest when a short new file overwrites a longer old one. -// -// New versions of gopls are free to reorganize the contents of the -// version directory as needs evolve. But all versions of gopls must @@ -38636,10 +43585,15 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec -// In particular, each gopls process attempts to garbage collect -// the entire gopls directory so that newer binaries can clean up -// after older ones: in the development cycle especially, new --// new versions may be created frequently. --func filename(kind string, key [32]byte) string { -- hex := fmt.Sprintf("%x", key) -- return filepath.Join(getCacheDir(), kind, hex[:2], hex) +-// versions may be created frequently. +-func filename(kind string, key [32]byte) (string, error) { +- base := fmt.Sprintf("%x-%s", key, kind) +- dir, err := getCacheDir() +- if err != nil { +- return "", err +- } +- // Keep the BugReports function consistent with this one. +- return filepath.Join(dir, base[:2], base), nil -} - -// getCacheDir returns the persistent cache directory of all processes @@ -38648,7 +43602,7 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec -// It must incorporate the hash of the executable so that we needn't -// worry about incompatible changes to the file format or changes to -// the algorithm that produced the index. --func getCacheDir() string { +-func getCacheDir() (string, error) { - cacheDirOnce.Do(func() { - // Use user's preferred cache directory. - userDir := os.Getenv("GOPLSCACHE") @@ -38681,21 +43635,22 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - // Compute the hash of this executable (~20ms) and create a subdirectory. - hash, err := hashExecutable() - if err != nil { -- log.Fatalf("can't hash gopls executable: %v", err) +- cacheDirErr = fmt.Errorf("can't hash gopls executable: %v", err) - } - // Use only 32 bits of the digest to avoid unwieldy filenames. - // It's not an adversarial situation. - cacheDir = filepath.Join(goplsDir, fmt.Sprintf("%x", hash[:4])) - if err := os.MkdirAll(cacheDir, 0700); err != nil { -- log.Fatalf("can't create cache: %v", err) +- cacheDirErr = fmt.Errorf("can't create cache: %v", err) - } - }) -- return cacheDir +- return cacheDir, cacheDirErr -} - -var ( - cacheDirOnce sync.Once -- cacheDir string // only accessed by getCacheDir +- cacheDir string +- cacheDirErr error -) - -func hashExecutable() (hash [32]byte, err error) { @@ -38724,13 +43679,25 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec -// process, possibly running a different version of gopls, possibly -// running concurrently. -func gc(goplsDir string) { -- const period = 1 * time.Minute // period between collections +- // period between collections +- // +- // Originally the period was always 1 minute, but this +- // consumed 15% of a CPU core when idle (#61049). +- // +- // The reason for running collections even when idle is so +- // that long lived gopls sessions eventually clean up the +- // caches created by defunct executables. +- const ( +- minPeriod = 5 * time.Minute // when active +- maxPeriod = 6 * time.Hour // when idle +- ) +- - // Sleep statDelay*batchSize between stats to smooth out I/O. - // - // The constants below were chosen using the following heuristics: - // - 1GB of filecache is on the order of ~100-200k files, in which case -- // 100μs delay per file introduces 10-20s of additional walk time, less -- // than the 1m gc period. +- // 100μs delay per file introduces 10-20s of additional walk time, +- // less than the minPeriod. - // - Processing batches of stats at once is much more efficient than - // sleeping after every stat (due to OS optimizations). - const statDelay = 100 * time.Microsecond // average delay between stats, to smooth out I/O @@ -38756,8 +43723,9 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - for { - // Enumerate all files in the cache. - type item struct { -- path string -- stat os.FileInfo +- path string +- mtime time.Time +- size int64 - } - var files []item - start := time.Now() @@ -38783,7 +43751,7 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - } - os.Remove(path) // ignore error - } else { -- files = append(files, item{path, stat}) +- files = append(files, item{path, stat.ModTime(), stat.Size()}) - total += stat.Size() - if debug && len(files)%1000 == 0 { - log.Printf("filecache: checked %d files in %v", len(files), time.Since(start)) @@ -38798,7 +43766,7 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - - // Sort oldest files first. - sort.Slice(files, func(i, j int) bool { -- return files[i].stat.ModTime().Before(files[j].stat.ModTime()) +- return files[i].mtime.Before(files[j].mtime) - }) - - // Delete oldest files until we're under budget. @@ -38808,15 +43776,17 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - break - } - if debug { -- age := time.Since(file.stat.ModTime()) +- age := time.Since(file.mtime) - log.Printf("budget: deleting stale file %s (%dB, age %v)", -- file.path, file.stat.Size(), age) +- file.path, file.size, age) - } - os.Remove(file.path) // ignore error -- total -= file.stat.Size() +- total -= file.size - } +- files = nil // release memory before sleep - -- time.Sleep(period) +- // Wait unconditionally for the minimum period. +- time.Sleep(minPeriod) - - // Once only, delete all directories. - // This will succeed only for the empty ones, @@ -38852,12 +43822,76 @@ diff -urN a/gopls/internal/lsp/filecache/filecache.go b/gopls/internal/lsp/filec - log.Printf("deleted %d empty directories", deleted) - } - } +- +- // Wait up to the max period, +- // or for Set activity in this process. +- select { +- case <-active: +- case <-time.After(maxPeriod): +- } - } -} +- +-func init() { +- // Register a handler to durably record this process's first +- // assertion failure in the cache so that we can ask users to +- // share this information via the stats command. +- bug.Handle(func(bug bug.Bug) { +- // Wait for cache init (bugs in tests happen early). +- _, _ = getCacheDir() +- +- data, err := json.Marshal(bug) +- if err != nil { +- panic(fmt.Sprintf("error marshalling bug %+v: %v", bug, err)) +- } +- +- key := sha256.Sum256(data) +- _ = Set(bugKind, key, data) +- }) +-} +- +-// BugReports returns a new unordered array of the contents +-// of all cached bug reports produced by this executable. +-// It also returns the location of the cache directory +-// used by this process (or "" on initialization error). +-func BugReports() (string, []bug.Bug) { +- // To test this logic, run: +- // $ TEST_GOPLS_BUG=oops gopls bug # trigger a bug +- // $ gopls stats # list the bugs +- +- dir, err := getCacheDir() +- if err != nil { +- return "", nil // ignore initialization errors +- } +- var result []bug.Bug +- _ = filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { +- if err != nil { +- return nil // ignore readdir/stat errors +- } +- // Parse the key from each "XXXX-bug" cache file name. +- if !info.IsDir() && strings.HasSuffix(path, bugKind) { +- var key [32]byte +- n, err := hex.Decode(key[:], []byte(filepath.Base(path)[:len(key)*2])) +- if err != nil || n != len(key) { +- return nil // ignore malformed file names +- } +- content, err := Get(bugKind, key) +- if err == nil { // ignore read errors +- var b bug.Bug +- if err := json.Unmarshal(content, &b); err != nil { +- log.Printf("error marshalling bug %q: %v", string(content), err) +- } +- result = append(result, b) +- } +- } +- return nil +- }) +- return dir, result +-} diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/filecache/filecache_test.go --- a/gopls/internal/lsp/filecache/filecache_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/filecache/filecache_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,215 +0,0 @@ +@@ -1,265 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -38878,10 +43912,12 @@ diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/ - "os" - "os/exec" - "strconv" +- "strings" - "testing" - - "golang.org/x/sync/errgroup" - "golang.org/x/tools/gopls/internal/lsp/filecache" +- "golang.org/x/tools/internal/testenv" -) - -func TestBasics(t *testing.T) { @@ -38891,6 +43927,10 @@ diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/ - - // Get of a never-seen key returns not found. - if _, err := filecache.Get(kind, key); err != filecache.ErrNotFound { +- if strings.Contains(err.Error(), "operation not supported") || +- strings.Contains(err.Error(), "not implemented") { +- t.Skipf("skipping: %v", err) +- } - t.Errorf("Get of random key returned err=%q, want not found", err) - } - @@ -38914,6 +43954,9 @@ diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/ - -// TestConcurrency exercises concurrent access to the same entry. -func TestConcurrency(t *testing.T) { +- if os.Getenv("GO_BUILDER_NAME") == "plan9-arm" { +- t.Skip(`skipping on plan9-arm builder due to golang/go#58748: failing with 'mount rpc error'`) +- } - const kind = "TestConcurrency" - key := uniqueKey() - const N = 100 // concurrency level @@ -38956,6 +43999,10 @@ diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/ - group.Go(func() error { return get(false) }) - } - if err := group.Wait(); err != nil { +- if strings.Contains(err.Error(), "operation not supported") || +- strings.Contains(err.Error(), "not implemented") { +- t.Skipf("skipping: %v", err) +- } - t.Fatal(err) - } - @@ -38975,12 +44022,17 @@ diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/ -// It calls Set(A) in the parent, { Get(A); Set(B) } in the child -// process, then Get(B) in the parent. -func TestIPC(t *testing.T) { +- testenv.NeedsExec(t) +- - keyA := uniqueKey() - keyB := uniqueKey() - value := []byte(testIPCValueA) - - // Set keyA. - if err := filecache.Set(testIPCKind, keyA, value); err != nil { +- if strings.Contains(err.Error(), "operation not supported") { +- t.Skipf("skipping: %v", err) +- } - t.Fatalf("Set: %v", err) - } - @@ -39060,6 +44112,7 @@ diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/ - b.Fatal(err) - } - b.ResetTimer() +- b.SetBytes(int64(len(value))) - - var group errgroup.Group - group.SetLimit(50) @@ -39073,10 +44126,41 @@ diff -urN a/gopls/internal/lsp/filecache/filecache_test.go b/gopls/internal/lsp/ - b.Fatal(err) - } -} +- +-// These two benchmarks are asymmetric: the one for Get imposes a +-// modest bound on concurrency (50) whereas the one for Set imposes a +-// much higher concurrency (1000) to test the implementation's +-// self-imposed bound. +- +-func BenchmarkUncontendedSet(b *testing.B) { +- const kind = "BenchmarkUncontendedSet" +- key := uniqueKey() +- var value [8192]byte +- +- const P = 1000 // parallelism +- b.SetBytes(P * int64(len(value))) +- +- for i := 0; i < b.N; i++ { +- // Perform P concurrent calls to Set. All must succeed. +- var group errgroup.Group +- for range [P]bool{} { +- group.Go(func() error { +- return filecache.Set(kind, key, value[:]) +- }) +- } +- if err := group.Wait(); err != nil { +- if strings.Contains(err.Error(), "operation not supported") || +- strings.Contains(err.Error(), "not implemented") { +- b.Skipf("skipping: %v", err) +- } +- b.Fatal(err) +- } +- } +-} diff -urN a/gopls/internal/lsp/folding_range.go b/gopls/internal/lsp/folding_range.go --- a/gopls/internal/lsp/folding_range.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/folding_range.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,41 +0,0 @@ +@@ -1,46 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -39088,16 +44172,21 @@ diff -urN a/gopls/internal/lsp/folding_range.go b/gopls/internal/lsp/folding_ran - - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) foldingRange(ctx context.Context, params *protocol.FoldingRangeParams) ([]protocol.FoldingRange, error) { +- ctx, done := event.Start(ctx, "lsp.Server.foldingRange", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { - return nil, err - } - -- ranges, err := source.FoldingRange(ctx, snapshot, fh, snapshot.View().Options().LineFoldingOnly) +- ranges, err := source.FoldingRange(ctx, snapshot, fh, snapshot.Options().LineFoldingOnly) - if err != nil { - return nil, err - } @@ -39121,7 +44210,7 @@ diff -urN a/gopls/internal/lsp/folding_range.go b/gopls/internal/lsp/folding_ran diff -urN a/gopls/internal/lsp/format.go b/gopls/internal/lsp/format.go --- a/gopls/internal/lsp/format.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/format.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ +@@ -1,36 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -39135,15 +44224,20 @@ diff -urN a/gopls/internal/lsp/format.go b/gopls/internal/lsp/format.go - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/work" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormattingParams) ([]protocol.TextEdit, error) { +- ctx, done := event.Start(ctx, "lsp.Server.formatting", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { - return nil, err - } -- switch snapshot.View().FileKind(fh) { +- switch snapshot.FileKind(fh) { - case source.Mod: - return mod.Format(ctx, snapshot, fh) - case source.Go: @@ -39153,10 +44247,576 @@ diff -urN a/gopls/internal/lsp/format.go b/gopls/internal/lsp/format.go - } - return nil, nil -} +diff -urN a/gopls/internal/lsp/frob/frob.go b/gopls/internal/lsp/frob/frob.go +--- a/gopls/internal/lsp/frob/frob.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/frob/frob.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,439 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-// Package frob is a fast restricted object encoder/decoder in the +-// spirit of encoding/gob. +-// +-// As with gob, types that recursively contain functions, channels, +-// and unsafe.Pointers cannot be encoded, but frob has these +-// additional restrictions: +-// +-// - Interface values are not supported; this avoids the need for +-// the encoding to describe types. +-// +-// - Types that recursively contain private struct fields are not +-// permitted. +-// +-// - The encoding is unspecified and subject to change, so the encoder +-// and decoder must exactly agree on their implementation and on the +-// definitions of the target types. +-// +-// - Lengths (of arrays, slices, and maps) are currently assumed to +-// fit in 32 bits. +-// +-// - There is no error handling. All errors are reported by panicking. +-// +-// - Values are serialized as trees, not graphs, so shared subgraphs +-// are encoded repeatedly. +-// +-// - No attempt is made to detect cyclic data structures. +-package frob +- +-import ( +- "encoding/binary" +- "fmt" +- "math" +- "reflect" +- "sync" +-) +- +-// A Codec[T] is an immutable encoder and decoder for values of type T. +-type Codec[T any] struct{ frob *frob } +- +-// CodecFor[T] returns a codec for values of type T. +-// It panics if type T is unsuitable. +-func CodecFor[T any]() Codec[T] { +- frobsMu.Lock() +- defer frobsMu.Unlock() +- return Codec[T]{frobFor(reflect.TypeOf((*T)(nil)).Elem())} +-} +- +-func (codec Codec[T]) Encode(v T) []byte { return codec.frob.Encode(v) } +-func (codec Codec[T]) Decode(data []byte, ptr *T) { codec.frob.Decode(data, ptr) } +- +-var ( +- frobsMu sync.Mutex +- frobs = make(map[reflect.Type]*frob) +-) +- +-// A frob is an encoder/decoder for a specific type. +-type frob struct { +- t reflect.Type +- kind reflect.Kind +- elems []*frob // elem (array/slice/ptr), key+value (map), fields (struct) +-} +- +-// frobFor returns the frob for a particular type. +-// Precondition: caller holds frobsMu. +-func frobFor(t reflect.Type) *frob { +- fr, ok := frobs[t] +- if !ok { +- fr = &frob{t: t, kind: t.Kind()} +- frobs[t] = fr +- +- switch fr.kind { +- case reflect.Bool, +- reflect.Int, +- reflect.Int8, +- reflect.Int16, +- reflect.Int32, +- reflect.Int64, +- reflect.Uint, +- reflect.Uint8, +- reflect.Uint16, +- reflect.Uint32, +- reflect.Uint64, +- reflect.Uintptr, +- reflect.Float32, +- reflect.Float64, +- reflect.Complex64, +- reflect.Complex128, +- reflect.String: +- +- case reflect.Array, +- reflect.Slice, +- reflect.Ptr: // TODO(adonovan): after go1.18, use Pointer +- fr.addElem(fr.t.Elem()) +- +- case reflect.Map: +- fr.addElem(fr.t.Key()) +- fr.addElem(fr.t.Elem()) +- +- case reflect.Struct: +- for i := 0; i < fr.t.NumField(); i++ { +- field := fr.t.Field(i) +- if field.PkgPath != "" { +- panic(fmt.Sprintf("unexported field %v", field)) +- } +- fr.addElem(field.Type) +- } +- +- default: +- // chan, func, interface, unsafe.Pointer +- panic(fmt.Sprintf("type %v is not supported by frob", fr.t)) +- } +- } +- return fr +-} +- +-func (fr *frob) addElem(t reflect.Type) { +- fr.elems = append(fr.elems, frobFor(t)) +-} +- +-const magic = "frob" +- +-func (fr *frob) Encode(v any) []byte { +- rv := reflect.ValueOf(v) +- if rv.Type() != fr.t { +- panic(fmt.Sprintf("got %v, want %v", rv.Type(), fr.t)) +- } +- w := &writer{} +- w.bytes([]byte(magic)) +- fr.encode(w, rv) +- if uint64(len(w.data))>>32 != 0 { +- panic("too large") // includes all cases where len doesn't fit in 32 bits +- } +- return w.data +-} +- +-// encode appends the encoding of value v, whose type must be fr.t. +-func (fr *frob) encode(out *writer, v reflect.Value) { +- switch fr.kind { +- case reflect.Bool: +- var b byte +- if v.Bool() { +- b = 1 +- } +- out.uint8(b) +- case reflect.Int: +- out.uint64(uint64(v.Int())) +- case reflect.Int8: +- out.uint8(uint8(v.Int())) +- case reflect.Int16: +- out.uint16(uint16(v.Int())) +- case reflect.Int32: +- out.uint32(uint32(v.Int())) +- case reflect.Int64: +- out.uint64(uint64(v.Int())) +- case reflect.Uint: +- out.uint64(v.Uint()) +- case reflect.Uint8: +- out.uint8(uint8(v.Uint())) +- case reflect.Uint16: +- out.uint16(uint16(v.Uint())) +- case reflect.Uint32: +- out.uint32(uint32(v.Uint())) +- case reflect.Uint64: +- out.uint64(v.Uint()) +- case reflect.Uintptr: +- out.uint64(uint64(v.Uint())) +- case reflect.Float32: +- out.uint32(math.Float32bits(float32(v.Float()))) +- case reflect.Float64: +- out.uint64(math.Float64bits(v.Float())) +- case reflect.Complex64: +- z := complex64(v.Complex()) +- out.uint32(uint32(math.Float32bits(real(z)))) +- out.uint32(uint32(math.Float32bits(imag(z)))) +- case reflect.Complex128: +- z := v.Complex() +- out.uint64(math.Float64bits(real(z))) +- out.uint64(math.Float64bits(imag(z))) +- +- case reflect.Array: +- len := v.Type().Len() +- elem := fr.elems[0] +- for i := 0; i < len; i++ { +- elem.encode(out, v.Index(i)) +- } +- +- case reflect.Slice: +- len := v.Len() +- out.uint32(uint32(len)) +- if len > 0 { +- elem := fr.elems[0] +- if elem.kind == reflect.Uint8 { +- // []byte fast path +- out.bytes(v.Bytes()) +- } else { +- for i := 0; i < len; i++ { +- elem.encode(out, v.Index(i)) +- } +- } +- } +- +- case reflect.Map: +- len := v.Len() +- out.uint32(uint32(len)) +- if len > 0 { +- kfrob, vfrob := fr.elems[0], fr.elems[1] +- for iter := v.MapRange(); iter.Next(); { +- kfrob.encode(out, iter.Key()) +- vfrob.encode(out, iter.Value()) +- } +- } +- +- case reflect.Ptr: // TODO(adonovan): after go1.18, use Pointer +- if v.IsNil() { +- out.uint8(0) +- } else { +- out.uint8(1) +- fr.elems[0].encode(out, v.Elem()) +- } +- +- case reflect.String: +- len := v.Len() +- out.uint32(uint32(len)) +- if len > 0 { +- out.data = append(out.data, v.String()...) +- } +- +- case reflect.Struct: +- for i, elem := range fr.elems { +- elem.encode(out, v.Field(i)) +- } +- +- default: +- panic(fr.t) +- } +-} +- +-func (fr *frob) Decode(data []byte, ptr any) { +- rv := reflect.ValueOf(ptr).Elem() +- if rv.Type() != fr.t { +- panic(fmt.Sprintf("got %v, want %v", rv.Type(), fr.t)) +- } +- rd := &reader{data} +- if string(rd.bytes(4)) != magic { +- panic("not a frob-encoded message") +- } +- fr.decode(rd, rv) +- if len(rd.data) > 0 { +- panic("surplus bytes") +- } +-} +- +-// decode reads from in, decodes a value, and sets addr to it. +-// addr must be a zero-initialized addressable variable of type fr.t. +-func (fr *frob) decode(in *reader, addr reflect.Value) { +- switch fr.kind { +- case reflect.Bool: +- addr.SetBool(in.uint8() != 0) +- case reflect.Int: +- addr.SetInt(int64(in.uint64())) +- case reflect.Int8: +- addr.SetInt(int64(in.uint8())) +- case reflect.Int16: +- addr.SetInt(int64(in.uint16())) +- case reflect.Int32: +- addr.SetInt(int64(in.uint32())) +- case reflect.Int64: +- addr.SetInt(int64(in.uint64())) +- case reflect.Uint: +- addr.SetUint(in.uint64()) +- case reflect.Uint8: +- addr.SetUint(uint64(in.uint8())) +- case reflect.Uint16: +- addr.SetUint(uint64(in.uint16())) +- case reflect.Uint32: +- addr.SetUint(uint64(in.uint32())) +- case reflect.Uint64: +- addr.SetUint(in.uint64()) +- case reflect.Uintptr: +- addr.SetUint(in.uint64()) +- case reflect.Float32: +- addr.SetFloat(float64(math.Float32frombits(in.uint32()))) +- case reflect.Float64: +- addr.SetFloat(math.Float64frombits(in.uint64())) +- case reflect.Complex64: +- addr.SetComplex(complex128(complex( +- math.Float32frombits(in.uint32()), +- math.Float32frombits(in.uint32()), +- ))) +- case reflect.Complex128: +- addr.SetComplex(complex( +- math.Float64frombits(in.uint64()), +- math.Float64frombits(in.uint64()), +- )) +- +- case reflect.Array: +- len := fr.t.Len() +- for i := 0; i < len; i++ { +- fr.elems[0].decode(in, addr.Index(i)) +- } +- +- case reflect.Slice: +- len := int(in.uint32()) +- if len > 0 { +- elem := fr.elems[0] +- if elem.kind == reflect.Uint8 { +- // []byte fast path +- // (Not addr.SetBytes: we must make a copy.) +- addr.Set(reflect.AppendSlice(addr, reflect.ValueOf(in.bytes(len)))) +- } else { +- addr.Set(reflect.MakeSlice(fr.t, len, len)) +- for i := 0; i < len; i++ { +- elem.decode(in, addr.Index(i)) +- } +- } +- } +- +- case reflect.Map: +- len := int(in.uint32()) +- if len > 0 { +- m := reflect.MakeMapWithSize(fr.t, len) +- addr.Set(m) +- kfrob, vfrob := fr.elems[0], fr.elems[1] +- k := reflect.New(kfrob.t).Elem() +- v := reflect.New(vfrob.t).Elem() +- kzero := reflect.Zero(kfrob.t) +- vzero := reflect.Zero(vfrob.t) +- for i := 0; i < len; i++ { +- // TODO(adonovan): use SetZero from go1.20. +- // k.SetZero() +- // v.SetZero() +- k.Set(kzero) +- v.Set(vzero) +- kfrob.decode(in, k) +- vfrob.decode(in, v) +- m.SetMapIndex(k, v) +- } +- } +- +- case reflect.Ptr: // TODO(adonovan): after go1.18, use Pointer +- isNil := in.uint8() == 0 +- if !isNil { +- ptr := reflect.New(fr.elems[0].t) +- addr.Set(ptr) +- fr.elems[0].decode(in, ptr.Elem()) +- } +- +- case reflect.String: +- len := int(in.uint32()) +- if len > 0 { +- addr.SetString(string(in.bytes(len))) +- } +- +- case reflect.Struct: +- for i, elem := range fr.elems { +- elem.decode(in, addr.Field(i)) +- } +- +- default: +- panic(fr.t) +- } +-} +- +-var le = binary.LittleEndian +- +-type reader struct{ data []byte } +- +-func (r *reader) uint8() uint8 { +- v := r.data[0] +- r.data = r.data[1:] +- return v +-} +- +-func (r *reader) uint16() uint16 { +- v := le.Uint16(r.data) +- r.data = r.data[2:] +- return v +-} +- +-func (r *reader) uint32() uint32 { +- v := le.Uint32(r.data) +- r.data = r.data[4:] +- return v +-} +- +-func (r *reader) uint64() uint64 { +- v := le.Uint64(r.data) +- r.data = r.data[8:] +- return v +-} +- +-func (r *reader) bytes(n int) []byte { +- v := r.data[:n] +- r.data = r.data[n:] +- return v +-} +- +-type writer struct{ data []byte } +- +-func (w *writer) uint8(v uint8) { w.data = append(w.data, v) } +-func (w *writer) uint16(v uint16) { w.data = appendUint16(w.data, v) } +-func (w *writer) uint32(v uint32) { w.data = appendUint32(w.data, v) } +-func (w *writer) uint64(v uint64) { w.data = appendUint64(w.data, v) } +-func (w *writer) bytes(v []byte) { w.data = append(w.data, v...) } +- +-// TODO(adonovan): delete these as in go1.19 they are methods on LittleEndian: +- +-func appendUint16(b []byte, v uint16) []byte { +- return append(b, +- byte(v), +- byte(v>>8), +- ) +-} +- +-func appendUint32(b []byte, v uint32) []byte { +- return append(b, +- byte(v), +- byte(v>>8), +- byte(v>>16), +- byte(v>>24), +- ) +-} +- +-func appendUint64(b []byte, v uint64) []byte { +- return append(b, +- byte(v), +- byte(v>>8), +- byte(v>>16), +- byte(v>>24), +- byte(v>>32), +- byte(v>>40), +- byte(v>>48), +- byte(v>>56), +- ) +-} +diff -urN a/gopls/internal/lsp/frob/frob_test.go b/gopls/internal/lsp/frob/frob_test.go +--- a/gopls/internal/lsp/frob/frob_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/frob/frob_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,119 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package frob_test +- +-import ( +- "math" +- "reflect" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/frob" +-) +- +-func TestBasics(t *testing.T) { +- type Basics struct { +- A []*string +- B [2]int +- C *Basics +- D map[string]int +- E []byte +- F []string +- } +- codec := frob.CodecFor[Basics]() +- +- s1, s2 := "hello", "world" +- x := Basics{ +- A: []*string{&s1, nil, &s2}, +- B: [...]int{1, 2}, +- C: &Basics{ +- B: [...]int{3, 4}, +- D: map[string]int{"one": 1}, +- }, +- E: []byte("hello"), +- F: []string{s1, s2}, +- } +- var y Basics +- codec.Decode(codec.Encode(x), &y) +- if !reflect.DeepEqual(x, y) { +- t.Fatalf("bad roundtrip: got %#v, want %#v", y, x) +- } +-} +- +-func TestInts(t *testing.T) { +- type Ints struct { +- U uint +- U8 uint8 +- U16 uint16 +- U32 uint32 +- U64 uint64 +- UP uintptr +- I int +- I8 int8 +- I16 int16 +- I32 int32 +- I64 int64 +- F32 float32 +- F64 float64 +- C64 complex64 +- C128 complex128 +- } +- codec := frob.CodecFor[Ints]() +- +- // maxima +- max1 := Ints{ +- U: math.MaxUint, +- U8: math.MaxUint8, +- U16: math.MaxUint16, +- U32: math.MaxUint32, +- U64: math.MaxUint64, +- UP: math.MaxUint, +- I: math.MaxInt, +- I8: math.MaxInt8, +- I16: math.MaxInt16, +- I32: math.MaxInt32, +- I64: math.MaxInt64, +- F32: math.MaxFloat32, +- F64: math.MaxFloat64, +- C64: complex(math.MaxFloat32, math.MaxFloat32), +- C128: complex(math.MaxFloat64, math.MaxFloat64), +- } +- var max2 Ints +- codec.Decode(codec.Encode(max1), &max2) +- if !reflect.DeepEqual(max1, max2) { +- t.Fatalf("max: bad roundtrip: got %#v, want %#v", max2, max1) +- } +- +- // minima +- min1 := Ints{ +- I: math.MinInt, +- I8: math.MinInt8, +- I16: math.MinInt16, +- I32: math.MinInt32, +- I64: math.MinInt64, +- F32: -math.MaxFloat32, +- F64: -math.MaxFloat32, +- C64: complex(-math.MaxFloat32, -math.MaxFloat32), +- C128: complex(-math.MaxFloat64, -math.MaxFloat64), +- } +- var min2 Ints +- codec.Decode(codec.Encode(min1), &min2) +- if !reflect.DeepEqual(min1, min2) { +- t.Fatalf("min: bad roundtrip: got %#v, want %#v", min2, min1) +- } +- +- // negatives (other than MinInt), to exercise conversions +- neg1 := Ints{ +- I: -1, +- I8: -1, +- I16: -1, +- I32: -1, +- I64: -1, +- } +- var neg2 Ints +- codec.Decode(codec.Encode(neg1), &neg2) +- if !reflect.DeepEqual(neg1, neg2) { +- t.Fatalf("neg: bad roundtrip: got %#v, want %#v", neg2, neg1) +- } +-} diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go --- a/gopls/internal/lsp/general.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/general.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,619 +0,0 @@ +@@ -1,682 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -39167,6 +44827,7 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - "context" - "encoding/json" - "fmt" +- "go/build" - "log" - "os" - "path" @@ -39175,16 +44836,22 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - "strings" - "sync" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/debug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" +- "golang.org/x/tools/gopls/internal/telemetry" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/jsonrpc2" -) - -func (s *Server) initialize(ctx context.Context, params *protocol.ParamInitialize) (*protocol.InitializeResult, error) { +- ctx, done := event.Start(ctx, "lsp.Server.initialize") +- defer done() +- +- telemetry.RecordClientInfo(params) +- - s.stateMu.Lock() - if s.state >= serverInitializing { - defer s.stateMu.Unlock() @@ -39215,21 +44882,21 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - if err := s.handleOptionResults(ctx, source.SetOptions(options, params.InitializationOptions)); err != nil { - return nil, err - } -- options.ForClientCapabilities(params.Capabilities) +- options.ForClientCapabilities(params.ClientInfo, params.Capabilities) - - if options.ShowBugReports { - // Report the next bug that occurs on the server. -- bugCh := bug.Notify() -- go func() { -- b := <-bugCh +- bug.Handle(func(b bug.Bug) { - msg := &protocol.ShowMessageParams{ - Type: protocol.Error, - Message: fmt.Sprintf("A bug occurred on the server: %s\nLocation:%s", b.Description, b.Key), - } -- if err := s.eventuallyShowMessage(context.Background(), msg); err != nil { -- log.Printf("error showing bug: %v", err) -- } -- }() +- go func() { +- if err := s.eventuallyShowMessage(context.Background(), msg); err != nil { +- log.Printf("error showing bug: %v", err) +- } +- }() +- }) - } - - folders := params.WorkspaceFolders @@ -39308,7 +44975,7 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - DocumentSymbolProvider: &protocol.Or_ServerCapabilities_documentSymbolProvider{Value: true}, - WorkspaceSymbolProvider: &protocol.Or_ServerCapabilities_workspaceSymbolProvider{Value: true}, - ExecuteCommandProvider: &protocol.ExecuteCommandOptions{ -- Commands: options.SupportedCommands, +- Commands: nonNilSliceString(options.SupportedCommands), - }, - FoldingRangeProvider: &protocol.Or_ServerCapabilities_foldingRangeProvider{Value: true}, - HoverProvider: &protocol.Or_ServerCapabilities_hoverProvider{Value: true}, @@ -39322,8 +44989,8 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - Range: &protocol.Or_SemanticTokensOptions_range{Value: true}, - Full: &protocol.Or_SemanticTokensOptions_full{Value: true}, - Legend: protocol.SemanticTokensLegend{ -- TokenTypes: s.session.Options().SemanticTypes, -- TokenModifiers: s.session.Options().SemanticMods, +- TokenTypes: nonNilSliceString(s.session.Options().SemanticTypes), +- TokenModifiers: nonNilSliceString(s.session.Options().SemanticMods), - }, - }, - SignatureHelpProvider: &protocol.SignatureHelpOptions{ @@ -39351,6 +45018,9 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go -} - -func (s *Server) initialized(ctx context.Context, params *protocol.InitializedParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.initialized") +- defer done() +- - s.stateMu.Lock() - if s.state >= serverInitialized { - defer s.stateMu.Unlock() @@ -39392,14 +45062,16 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - -// GoVersionTable maps Go versions to the gopls version in which support will -// be deprecated, and the final gopls version supporting them without warnings. --// Keep this in sync with gopls/README.md +-// Keep this in sync with gopls/README.md. -// -// Must be sorted in ascending order of Go version. -// -// Mutable for testing. -var GoVersionTable = []GoVersionSupport{ - {12, "", "v0.7.5"}, -- {15, "v0.11.0", "v0.9.5"}, +- {15, "", "v0.9.5"}, +- {16, "v0.13.0", "v0.11.0"}, +- {17, "v0.13.0", "v0.11.0"}, -} - -// GoVersionSupport holds information about end-of-life Go version support. @@ -39415,11 +45087,13 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - return GoVersionTable[len(GoVersionTable)-1].GoVersion + 1 -} - --// versionMessage returns the warning/error message to display if the user is --// on the given Go version, if any. The goVersion variable is the X in Go 1.X. +-// versionMessage returns the warning/error message to display if the user has +-// the given Go version, if any. The goVersion variable is the X in Go 1.X. If +-// fromBuild is set, the Go version is the version used to build gopls. +-// Otherwise, it is the go command version. -// -// If goVersion is invalid (< 0), it returns "", 0. --func versionMessage(goVersion int) (string, protocol.MessageType) { +-func versionMessage(goVersion int, fromBuild bool) (string, protocol.MessageType) { - if goVersion < 0 { - return "", 0 - } @@ -39429,7 +45103,11 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - var msgBuilder strings.Builder - - mType := protocol.Error -- fmt.Fprintf(&msgBuilder, "Found Go version 1.%d", goVersion) +- if fromBuild { +- fmt.Fprintf(&msgBuilder, "Gopls was built with Go version 1.%d", goVersion) +- } else { +- fmt.Fprintf(&msgBuilder, "Found Go version 1.%d", goVersion) +- } - if v.DeprecatedVersion != "" { - // not deprecated yet, just a warning - fmt.Fprintf(&msgBuilder, ", which will be unsupported by gopls %s. ", v.DeprecatedVersion) @@ -39452,15 +45130,16 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go -// -// It should be called after views change. -func (s *Server) checkViewGoVersions() { -- oldestVersion := -1 +- oldestVersion, fromBuild := go1Point(), true - for _, view := range s.session.Views() { - viewVersion := view.GoVersion() - if oldestVersion == -1 || viewVersion < oldestVersion { -- oldestVersion = viewVersion +- oldestVersion, fromBuild = viewVersion, false - } +- telemetry.RecordViewGoVersion(viewVersion) - } - -- if msg, mType := versionMessage(oldestVersion); msg != "" { +- if msg, mType := versionMessage(oldestVersion, fromBuild); msg != "" { - s.eventuallyShowMessage(context.Background(), &protocol.ShowMessageParams{ - Type: mType, - Message: msg, @@ -39468,6 +45147,21 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - } -} - +-// go1Point returns the x in Go 1.x. If an error occurs extracting the go +-// version, it returns -1. +-// +-// Copied from the testenv package. +-func go1Point() int { +- for i := len(build.Default.ReleaseTags) - 1; i >= 0; i-- { +- var version int +- if _, err := fmt.Sscanf(build.Default.ReleaseTags[i], "go1.%d", &version); err != nil { +- continue +- } +- return version +- } +- return -1 +-} +- -func (s *Server) addFolders(ctx context.Context, folders []protocol.WorkspaceFolder) error { - originalViews := len(s.session.Views()) - viewErrors := make(map[span.URI]error) @@ -39515,7 +45209,7 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - // Diagnose the newly created view asynchronously. - ndiagnose.Add(1) - go func() { -- s.diagnoseDetached(snapshot) +- s.diagnoseSnapshot(snapshot, nil, false, 0) - <-initialized - release() - ndiagnose.Done() @@ -39598,14 +45292,13 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - -// registerWatchedDirectoriesLocked sends the workspace/didChangeWatchedFiles -// registrations to the client and updates s.watchedDirectories. +-// The caller must not subsequently mutate patterns. -func (s *Server) registerWatchedDirectoriesLocked(ctx context.Context, patterns map[string]struct{}) error { - if !s.session.Options().DynamicWatchedFilesSupported { - return nil - } -- for k := range s.watchedGlobPatterns { -- delete(s.watchedGlobPatterns, k) -- } -- var watchers []protocol.FileSystemWatcher +- s.watchedGlobPatterns = patterns +- watchers := make([]protocol.FileSystemWatcher, 0, len(patterns)) // must be a slice - val := protocol.WatchChange | protocol.WatchDelete | protocol.WatchCreate - for pattern := range patterns { - watchers = append(watchers, protocol.FileSystemWatcher{ @@ -39626,10 +45319,6 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - return err - } - s.watchRegistrationCount++ -- -- for k, v := range patterns { -- s.watchedGlobPatterns[k] = v -- } - return nil -} - @@ -39728,7 +45417,7 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - if err != nil { - return nil, nil, false, func() {}, err - } -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - release() - return nil, nil, false, func() {}, err @@ -39744,6 +45433,9 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go -// shutdown implements the 'shutdown' LSP handler. It releases resources -// associated with the server and waits for all ongoing work to complete. -func (s *Server) shutdown(ctx context.Context) error { +- ctx, done := event.Start(ctx, "lsp.Server.shutdown") +- defer done() +- - s.stateMu.Lock() - defer s.stateMu.Unlock() - if s.state < serverInitialized { @@ -39763,6 +45455,9 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go -} - -func (s *Server) exit(ctx context.Context) error { +- ctx, done := event.Start(ctx, "lsp.Server.exit") +- defer done() +- - s.stateMu.Lock() - defer s.stateMu.Unlock() - @@ -39772,14 +45467,42 @@ diff -urN a/gopls/internal/lsp/general.go b/gopls/internal/lsp/general.go - // TODO: We should be able to do better than this. - os.Exit(1) - } -- // we don't terminate the process on a normal exit, we just allow it to +- // We don't terminate the process on a normal exit, we just allow it to - // close naturally if needed after the connection is closed. - return nil -} +- +-// TODO: when we can assume go1.18, replace with generic +-// (after retiring support for go1.17) +-func nonNilSliceString(x []string) []string { +- if x == nil { +- return []string{} +- } +- return x +-} +-func nonNilSliceTextEdit(x []protocol.TextEdit) []protocol.TextEdit { +- if x == nil { +- return []protocol.TextEdit{} +- } +- +- return x +-} +-func nonNilSliceCompletionItemTag(x []protocol.CompletionItemTag) []protocol.CompletionItemTag { +- if x == nil { +- return []protocol.CompletionItemTag{} +- } +- return x +-} +-func emptySliceDiagnosticTag(x []protocol.DiagnosticTag) []protocol.DiagnosticTag { +- if x == nil { +- return []protocol.DiagnosticTag{} +- } +- return x +-} diff -urN a/gopls/internal/lsp/general_test.go b/gopls/internal/lsp/general_test.go --- a/gopls/internal/lsp/general_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/general_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,44 +0,0 @@ +@@ -1,48 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -39796,18 +45519,22 @@ diff -urN a/gopls/internal/lsp/general_test.go b/gopls/internal/lsp/general_test -func TestVersionMessage(t *testing.T) { - tests := []struct { - goVersion int +- fromBuild bool - wantContains []string // string fragments that we expect to see - wantType protocol.MessageType - }{ -- {-1, nil, 0}, -- {12, []string{"1.12", "not supported", "upgrade to Go 1.16", "install gopls v0.7.5"}, protocol.Error}, -- {13, []string{"1.13", "will be unsupported by gopls v0.11.0", "upgrade to Go 1.16", "install gopls v0.9.5"}, protocol.Warning}, -- {15, []string{"1.15", "will be unsupported by gopls v0.11.0", "upgrade to Go 1.16", "install gopls v0.9.5"}, protocol.Warning}, -- {16, nil, 0}, +- {-1, false, nil, 0}, +- {12, false, []string{"1.12", "not supported", "upgrade to Go 1.18", "install gopls v0.7.5"}, protocol.Error}, +- {13, false, []string{"1.13", "not supported", "upgrade to Go 1.18", "install gopls v0.9.5"}, protocol.Error}, +- {15, false, []string{"1.15", "not supported", "upgrade to Go 1.18", "install gopls v0.9.5"}, protocol.Error}, +- {15, true, []string{"Gopls was built with Go version 1.15", "not supported", "upgrade to Go 1.18", "install gopls v0.9.5"}, protocol.Error}, +- {16, false, []string{"1.16", "will be unsupported by gopls v0.13.0", "upgrade to Go 1.18", "install gopls v0.11.0"}, protocol.Warning}, +- {17, false, []string{"1.17", "will be unsupported by gopls v0.13.0", "upgrade to Go 1.18", "install gopls v0.11.0"}, protocol.Warning}, +- {17, true, []string{"Gopls was built with Go version 1.17", "will be unsupported by gopls v0.13.0", "upgrade to Go 1.18", "install gopls v0.11.0"}, protocol.Warning}, - } - - for _, test := range tests { -- gotMsg, gotType := versionMessage(test.goVersion) +- gotMsg, gotType := versionMessage(test.goVersion, test.fromBuild) - - if len(test.wantContains) == 0 && gotMsg != "" { - t.Errorf("versionMessage(%d) = %q, want \"\"", test.goVersion, gotMsg) @@ -40609,7 +46336,7 @@ diff -urN a/gopls/internal/lsp/helper/README.md b/gopls/internal/lsp/helper/READ diff -urN a/gopls/internal/lsp/highlight.go b/gopls/internal/lsp/highlight.go --- a/gopls/internal/lsp/highlight.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/highlight.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,45 +0,0 @@ +@@ -1,48 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -40619,27 +46346,30 @@ diff -urN a/gopls/internal/lsp/highlight.go b/gopls/internal/lsp/highlight.go -import ( - "context" - -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/event/tag" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/template" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) documentHighlight(ctx context.Context, params *protocol.DocumentHighlightParams) ([]protocol.DocumentHighlight, error) { +- ctx, done := event.Start(ctx, "lsp.Server.documentHighlight", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { - return nil, err - } - -- if snapshot.View().FileKind(fh) == source.Tmpl { +- if snapshot.FileKind(fh) == source.Tmpl { - return template.Highlight(ctx, snapshot, fh, params.Position) - } - - rngs, err := source.Highlight(ctx, snapshot, fh, params.Position) - if err != nil { -- event.Error(ctx, "no highlight", err, tag.URI.Of(params.TextDocument.URI)) +- event.Error(ctx, "no highlight", err) - } - return toProtocolHighlight(rngs), nil -} @@ -40658,7 +46388,7 @@ diff -urN a/gopls/internal/lsp/highlight.go b/gopls/internal/lsp/highlight.go diff -urN a/gopls/internal/lsp/hover.go b/gopls/internal/lsp/hover.go --- a/gopls/internal/lsp/hover.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/hover.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,34 +0,0 @@ +@@ -1,39 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -40673,15 +46403,20 @@ diff -urN a/gopls/internal/lsp/hover.go b/gopls/internal/lsp/hover.go - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/template" - "golang.org/x/tools/gopls/internal/lsp/work" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*protocol.Hover, error) { +- ctx, done := event.Start(ctx, "lsp.Server.hover", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { - return nil, err - } -- switch snapshot.View().FileKind(fh) { +- switch snapshot.FileKind(fh) { - case source.Mod: - return mod.Hover(ctx, snapshot, fh, params.Position) - case source.Go: @@ -40696,7 +46431,7 @@ diff -urN a/gopls/internal/lsp/hover.go b/gopls/internal/lsp/hover.go diff -urN a/gopls/internal/lsp/implementation.go b/gopls/internal/lsp/implementation.go --- a/gopls/internal/lsp/implementation.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/implementation.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ +@@ -1,26 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -40708,9 +46443,14 @@ diff -urN a/gopls/internal/lsp/implementation.go b/gopls/internal/lsp/implementa - - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) implementation(ctx context.Context, params *protocol.ImplementationParams) ([]protocol.Location, error) { +- ctx, done := event.Start(ctx, "lsp.Server.implementation", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { @@ -40721,7 +46461,7 @@ diff -urN a/gopls/internal/lsp/implementation.go b/gopls/internal/lsp/implementa diff -urN a/gopls/internal/lsp/inlay_hint.go b/gopls/internal/lsp/inlay_hint.go --- a/gopls/internal/lsp/inlay_hint.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/inlay_hint.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ +@@ -1,33 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -40731,22 +46471,34 @@ diff -urN a/gopls/internal/lsp/inlay_hint.go b/gopls/internal/lsp/inlay_hint.go -import ( - "context" - +- "golang.org/x/tools/gopls/internal/lsp/mod" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) inlayHint(ctx context.Context, params *protocol.InlayHintParams) ([]protocol.InlayHint, error) { -- snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) +- ctx, done := event.Start(ctx, "lsp.Server.inlayHint", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- +- snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { - return nil, err - } -- return source.InlayHint(ctx, snapshot, fh, params.Range) +- switch snapshot.FileKind(fh) { +- case source.Mod: +- return mod.InlayHint(ctx, snapshot, fh, params.Range) +- case source.Go: +- return source.InlayHint(ctx, snapshot, fh, params.Range) +- } +- return nil, nil -} diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go --- a/gopls/internal/lsp/link.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/link.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,278 +0,0 @@ +@@ -1,280 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -40773,12 +46525,15 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go -) - -func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLinkParams) (links []protocol.DocumentLink, err error) { +- ctx, done := event.Start(ctx, "lsp.Server.documentLink") +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { - return nil, err - } -- switch snapshot.View().FileKind(fh) { +- switch snapshot.FileKind(fh) { - case source.Mod: - links, err = modLinks(ctx, snapshot, fh) - case source.Go: @@ -40815,7 +46570,7 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - } - // Shift the start position to the location of the - // dependency within the require statement. -- target := source.BuildLink(snapshot.View().Options().LinkTarget, "mod/"+req.Mod.String(), "") +- target := source.BuildLink(snapshot.Options().LinkTarget, "mod/"+req.Mod.String(), "") - l, err := toProtocolLink(pm.Mapper, target, start+i, start+i+len(dep)) - if err != nil { - return nil, err @@ -40828,7 +46583,7 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - } - - // Get all the links that are contained in the comments of the file. -- urlRegexp := snapshot.View().Options().URLRegexp +- urlRegexp := snapshot.Options().URLRegexp - for _, expr := range pm.File.Syntax.Stmt { - comments := expr.Comment() - if comments == nil { @@ -40849,7 +46604,6 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - -// goLinks returns the set of hyperlink annotations for the specified Go file. -func goLinks(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.DocumentLink, error) { -- view := snapshot.View() - - pgf, err := snapshot.ParseGo(ctx, fh, source.ParseFull) - if err != nil { @@ -40859,14 +46613,14 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - var links []protocol.DocumentLink - - // Create links for import specs. -- if view.Options().ImportShortcut.ShowLinks() { +- if snapshot.Options().ImportShortcut.ShowLinks() { - - // If links are to pkg.go.dev, append module version suffixes. - // This requires the import map from the package metadata. Ignore errors. - var depsByImpPath map[source.ImportPath]source.PackageID -- if strings.ToLower(view.Options().LinkTarget) == "pkg.go.dev" { -- if metas, _ := snapshot.MetadataForFile(ctx, fh.URI()); len(metas) > 0 { -- depsByImpPath = metas[0].DepsByImpPath // 0 => narrowest package +- if strings.ToLower(snapshot.Options().LinkTarget) == "pkg.go.dev" { +- if meta, err := source.NarrowestMetadataForFile(ctx, snapshot, fh.URI()); err == nil { +- depsByImpPath = meta.DepsByImpPath - } - } - @@ -40876,7 +46630,7 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - continue // bad import - } - // See golang/go#36998: don't link to modules matching GOPRIVATE. -- if view.IsGoPrivatePath(string(importPath)) { +- if snapshot.View().IsGoPrivatePath(string(importPath)) { - continue - } - @@ -40891,7 +46645,7 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - if err != nil { - return nil, err - } -- targetURL := source.BuildLink(view.Options().LinkTarget, urlPath, "") +- targetURL := source.BuildLink(snapshot.Options().LinkTarget, urlPath, "") - // Account for the quotation marks in the positions. - l, err := toProtocolLink(pgf.Mapper, targetURL, start+len(`"`), end-len(`"`)) - if err != nil { @@ -40901,7 +46655,7 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - } - } - -- urlRegexp := snapshot.View().Options().URLRegexp +- urlRegexp := snapshot.Options().URLRegexp - - // Gather links found in string literals. - var str []*ast.BasicLit @@ -41022,9 +46776,367 @@ diff -urN a/gopls/internal/lsp/link.go b/gopls/internal/lsp/link.go - } - return protocol.DocumentLink{ - Range: rng, -- Target: targetURL, +- Target: &targetURL, - }, nil -} +diff -urN a/gopls/internal/lsp/lru/lru_fuzz_test.go b/gopls/internal/lsp/lru/lru_fuzz_test.go +--- a/gopls/internal/lsp/lru/lru_fuzz_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/lru/lru_fuzz_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,41 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.18 +-// +build go1.18 +- +-package lru_test +- +-import ( +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/lru" +-) +- +-// Simple fuzzing test for consistency. +-func FuzzCache(f *testing.F) { +- type op struct { +- set bool +- key, value byte +- } +- f.Fuzz(func(t *testing.T, data []byte) { +- var ops []op +- for len(data) >= 3 { +- ops = append(ops, op{data[0]%2 == 0, data[1], data[2]}) +- data = data[3:] +- } +- cache := lru.New(100) +- var reference [256]byte +- for _, op := range ops { +- if op.set { +- reference[op.key] = op.value +- cache.Set(op.key, op.value, 1) +- } else { +- if v := cache.Get(op.key); v != nil && v != reference[op.key] { +- t.Fatalf("cache.Get(%d) = %d, want %d", op.key, v, reference[op.key]) +- } +- } +- } +- }) +-} +diff -urN a/gopls/internal/lsp/lru/lru.go b/gopls/internal/lsp/lru/lru.go +--- a/gopls/internal/lsp/lru/lru.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/lru/lru.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,151 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-// The lru package implements a fixed-size in-memory LRU cache. +-package lru +- +-import ( +- "container/heap" +- "fmt" +- "sync" +-) +- +-// A Cache is a fixed-size in-memory LRU cache. +-type Cache struct { +- capacity int +- +- mu sync.Mutex +- used int // used capacity, in user-specified units +- m map[any]*entry // k/v lookup +- lru queue // min-atime priority queue of *entry +- clock int64 // clock time, incremented whenever the cache is updated +-} +- +-type entry struct { +- key any +- value any +- size int // caller-specified size +- atime int64 // last access / set time +- index int // index of entry in the heap slice +-} +- +-// New creates a new Cache with the given capacity, which must be positive. +-// +-// The cache capacity uses arbitrary units, which are specified during the Set +-// operation. +-func New(capacity int) *Cache { +- if capacity == 0 { +- panic("zero capacity") +- } +- +- return &Cache{ +- capacity: capacity, +- m: make(map[any]*entry), +- } +-} +- +-// Get retrieves the value for the specified key, or nil if the key is not +-// found. +-// +-// If the key is found, its access time is updated. +-func (c *Cache) Get(key any) any { +- c.mu.Lock() +- defer c.mu.Unlock() +- +- c.clock++ // every access updates the clock +- +- if e, ok := c.m[key]; ok { // cache hit +- e.atime = c.clock +- heap.Fix(&c.lru, e.index) +- return e.value +- } +- +- return nil +-} +- +-// Set stores a value for the specified key, using its given size to update the +-// current cache size, evicting old entries as necessary to fit in the cache +-// capacity. +-// +-// Size must be a non-negative value. If size is larger than the cache +-// capacity, the value is not stored and the cache is not modified. +-func (c *Cache) Set(key, value any, size int) { +- if size < 0 { +- panic(fmt.Sprintf("size must be non-negative, got %d", size)) +- } +- if size > c.capacity { +- return // uncacheable +- } +- +- c.mu.Lock() +- defer c.mu.Unlock() +- +- c.clock++ +- +- // Remove the existing cache entry for key, if it exists. +- e, ok := c.m[key] +- if ok { +- c.used -= e.size +- heap.Remove(&c.lru, e.index) +- delete(c.m, key) +- } +- +- // Evict entries until the new value will fit. +- newUsed := c.used + size +- if newUsed < 0 { +- return // integer overflow; return silently +- } +- c.used = newUsed +- for c.used > c.capacity { +- // evict oldest entry +- e = heap.Pop(&c.lru).(*entry) +- c.used -= e.size +- delete(c.m, e.key) +- } +- +- // Store the new value. +- // Opt: e is evicted, so it can be reused to reduce allocation. +- if e == nil { +- e = new(entry) +- } +- e.key = key +- e.value = value +- e.size = size +- e.atime = c.clock +- c.m[e.key] = e +- heap.Push(&c.lru, e) +- +- if len(c.m) != len(c.lru) { +- panic("map and LRU are inconsistent") +- } +-} +- +-// -- priority queue boilerplate -- +- +-// queue is a min-atime priority queue of cache entries. +-type queue []*entry +- +-func (q queue) Len() int { return len(q) } +- +-func (q queue) Less(i, j int) bool { return q[i].atime < q[j].atime } +- +-func (q queue) Swap(i, j int) { +- q[i], q[j] = q[j], q[i] +- q[i].index = i +- q[j].index = j +-} +- +-func (q *queue) Push(x any) { +- e := x.(*entry) +- e.index = len(*q) +- *q = append(*q, e) +-} +- +-func (q *queue) Pop() any { +- last := len(*q) - 1 +- e := (*q)[last] +- (*q)[last] = nil // aid GC +- *q = (*q)[:last] +- return e +-} +diff -urN a/gopls/internal/lsp/lru/lru_test.go b/gopls/internal/lsp/lru/lru_test.go +--- a/gopls/internal/lsp/lru/lru_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/lru/lru_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,154 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package lru_test +- +-import ( +- "bytes" +- cryptorand "crypto/rand" +- "fmt" +- "log" +- mathrand "math/rand" +- "strings" +- "testing" +- +- "golang.org/x/sync/errgroup" +- "golang.org/x/tools/gopls/internal/lsp/lru" +-) +- +-func TestCache(t *testing.T) { +- type get struct { +- key string +- want any +- } +- type set struct { +- key, value string +- } +- +- tests := []struct { +- label string +- steps []any +- }{ +- {"empty cache", []any{ +- get{"a", nil}, +- get{"b", nil}, +- }}, +- {"zero-length string", []any{ +- set{"a", ""}, +- get{"a", ""}, +- }}, +- {"under capacity", []any{ +- set{"a", "123"}, +- set{"b", "456"}, +- get{"a", "123"}, +- get{"b", "456"}, +- }}, +- {"over capacity", []any{ +- set{"a", "123"}, +- set{"b", "456"}, +- set{"c", "78901"}, +- get{"a", nil}, +- get{"b", "456"}, +- get{"c", "78901"}, +- }}, +- {"access ordering", []any{ +- set{"a", "123"}, +- set{"b", "456"}, +- get{"a", "123"}, +- set{"c", "78901"}, +- get{"a", "123"}, +- get{"b", nil}, +- get{"c", "78901"}, +- }}, +- } +- +- for _, test := range tests { +- t.Run(test.label, func(t *testing.T) { +- c := lru.New(10) +- for i, step := range test.steps { +- switch step := step.(type) { +- case get: +- if got := c.Get(step.key); got != step.want { +- t.Errorf("#%d: c.Get(%q) = %q, want %q", i, step.key, got, step.want) +- } +- case set: +- c.Set(step.key, step.value, len(step.value)) +- } +- } +- }) +- } +-} +- +-// TestConcurrency exercises concurrent access to the same entry. +-// +-// It is a copy of TestConcurrency from the filecache package. +-func TestConcurrency(t *testing.T) { +- key := uniqueKey() +- const N = 100 // concurrency level +- +- // Construct N distinct values, each larger +- // than a typical 4KB OS file buffer page. +- var values [N][8192]byte +- for i := range values { +- if _, err := mathrand.Read(values[i][:]); err != nil { +- t.Fatalf("rand: %v", err) +- } +- } +- +- cache := lru.New(100 * 1e6) // 100MB cache +- +- // get calls Get and verifies that the cache entry +- // matches one of the values passed to Set. +- get := func(mustBeFound bool) error { +- got := cache.Get(key) +- if got == nil { +- if !mustBeFound { +- return nil +- } +- return fmt.Errorf("Get did not return a value") +- } +- gotBytes := got.([]byte) +- for _, want := range values { +- if bytes.Equal(want[:], gotBytes) { +- return nil // a match +- } +- } +- return fmt.Errorf("Get returned a value that was never Set") +- } +- +- // Perform N concurrent calls to Set and Get. +- // All sets must succeed. +- // All gets must return nothing, or one of the Set values; +- // there is no third possibility. +- var group errgroup.Group +- for i := range values { +- i := i +- v := values[i][:] +- group.Go(func() error { +- cache.Set(key, v, len(v)) +- return nil +- }) +- group.Go(func() error { return get(false) }) +- } +- if err := group.Wait(); err != nil { +- if strings.Contains(err.Error(), "operation not supported") || +- strings.Contains(err.Error(), "not implemented") { +- t.Skipf("skipping: %v", err) +- } +- t.Fatal(err) +- } +- +- // A final Get must report one of the values that was Set. +- if err := get(true); err != nil { +- t.Fatalf("final Get failed: %v", err) +- } +-} +- +-// uniqueKey returns a key that has never been used before. +-func uniqueKey() (key [32]byte) { +- if _, err := cryptorand.Read(key[:]); err != nil { +- log.Fatalf("rand: %v", err) +- } +- return +-} diff -urN a/gopls/internal/lsp/lsprpc/autostart_default.go b/gopls/internal/lsp/lsprpc/autostart_default.go --- a/gopls/internal/lsp/lsprpc/autostart_default.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/lsprpc/autostart_default.go 1970-01-01 00:00:00.000000000 +0000 @@ -41700,10 +47812,10 @@ diff -urN a/gopls/internal/lsp/lsprpc/goenv.go b/gopls/internal/lsp/lsprpc/goenv - "fmt" - "os" - +- "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/gocommand" - jsonrpc2_v2 "golang.org/x/tools/internal/jsonrpc2_v2" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -) - -func GoEnvMiddleware() (Middleware, error) { @@ -41787,7 +47899,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/goenv.go b/gopls/internal/lsp/lsprpc/goenv diff -urN a/gopls/internal/lsp/lsprpc/goenv_test.go b/gopls/internal/lsp/lsprpc/goenv_test.go --- a/gopls/internal/lsp/lsprpc/goenv_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/lsprpc/goenv_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,65 +0,0 @@ +@@ -1,68 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -41799,6 +47911,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/goenv_test.go b/gopls/internal/lsp/lsprpc/ - "testing" - - "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/internal/testenv" - - . "golang.org/x/tools/gopls/internal/lsp/lsprpc" -) @@ -41815,6 +47928,8 @@ diff -urN a/gopls/internal/lsp/lsprpc/goenv_test.go b/gopls/internal/lsp/lsprpc/ -} - -func TestGoEnvMiddleware(t *testing.T) { +- testenv.NeedsTool(t, "go") +- - ctx := context.Background() - - server := &initServer{} @@ -42403,7 +48518,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/lsprpc.go b/gopls/internal/lsp/lsprpc/lspr diff -urN a/gopls/internal/lsp/lsprpc/lsprpc_test.go b/gopls/internal/lsp/lsprpc/lsprpc_test.go --- a/gopls/internal/lsp/lsprpc/lsprpc_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/lsprpc/lsprpc_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,345 +0,0 @@ +@@ -1,376 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -42412,6 +48527,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/lsprpc_test.go b/gopls/internal/lsp/lsprpc - -import ( - "context" +- "encoding/json" - "errors" - "regexp" - "strings" @@ -42425,6 +48541,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/lsprpc_test.go b/gopls/internal/lsp/lsprpc - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/jsonrpc2" - "golang.org/x/tools/internal/jsonrpc2/servertest" +- "golang.org/x/tools/internal/testenv" -) - -type FakeClient struct { @@ -42695,6 +48812,8 @@ diff -urN a/gopls/internal/lsp/lsprpc/lsprpc_test.go b/gopls/internal/lsp/lsprpc -} - -func TestEnvForwarding(t *testing.T) { +- testenv.NeedsTool(t, "go") +- - ctx := context.Background() - - server := &initServer{} @@ -42749,6 +48868,33 @@ diff -urN a/gopls/internal/lsp/lsprpc/lsprpc_test.go b/gopls/internal/lsp/lsprpc - } - } -} +- +-// For #59479, verify that empty slices are serialized as []. +-func TestEmptySlices(t *testing.T) { +- // The LSP would prefer that empty slices be sent as [] rather than null. +- const bad = `{"a":null}` +- const good = `{"a":[]}` +- var x struct { +- A []string `json:"a"` +- } +- buf, _ := json.Marshal(x) +- if string(buf) != bad { +- // uninitialized is ezpected to give null +- t.Errorf("unexpectedly got %s, want %s", buf, bad) +- } +- x.A = make([]string, 0) +- buf, _ = json.Marshal(x) +- if string(buf) != good { +- // expect [] +- t.Errorf("unexpectedly got %s, want %s", buf, good) +- } +- x.A = []string{} +- buf, _ = json.Marshal(x) +- if string(buf) != good { +- // expect [] +- t.Errorf("unexpectedly got %s, want %s", buf, good) +- } +-} diff -urN a/gopls/internal/lsp/lsprpc/middleware.go b/gopls/internal/lsp/lsprpc/middleware.go --- a/gopls/internal/lsp/lsprpc/middleware.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/lsprpc/middleware.go 1970-01-01 00:00:00.000000000 +0000 @@ -42995,7 +49141,7 @@ diff -urN a/gopls/internal/lsp/lsprpc/middleware_test.go b/gopls/internal/lsp/ls diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go --- a/gopls/internal/lsp/lsp_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/lsp_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1360 +0,0 @@ +@@ -1,1057 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -43007,24 +49153,21 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - "context" - "fmt" - "os" -- "os/exec" - "path/filepath" - "sort" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" -- "github.com/google/go-cmp/cmp/cmpopts" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/debug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/tests" - "golang.org/x/tools/gopls/internal/lsp/tests/compare" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" -- "golang.org/x/tools/internal/diff" -- "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/testenv" -) - @@ -43032,13 +49175,6 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - bug.PanicOnBugs = true - testenv.ExitIfSmallMachine() - -- // Set the global exporter to nil so that we don't log to stderr. This avoids -- // a lot of misleading noise in test output. -- // -- // TODO(rfindley): investigate whether we can/should capture logs scoped to -- // individual tests by passing in a context with a local exporter. -- event.SetExporter(nil) -- - os.Exit(m.Run()) -} - @@ -43052,6 +49188,13 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go -func testLSP(t *testing.T, datum *tests.Data) { - ctx := tests.Context(t) - +- // Setting a debug instance suppresses logging to stderr, but ensures that we +- // still e.g. convert events into runtime/trace/instrumentation. +- // +- // Previously, we called event.SetExporter(nil), which turns off all +- // instrumentation. +- ctx = debug.WithInstance(ctx, "", "off") +- - session := cache.NewSession(ctx, cache.New(nil), nil) - options := source.DefaultOptions().Clone() - tests.DefaultOptions(options) @@ -43076,8 +49219,8 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - datum.ModfileFlagAvailable = len(snapshot.ModFiles()) > 0 && testenv.Go1Point() >= 14 - release() - -- // Open all files for performance reasons. This is done because gopls only -- // keeps active packages in memory for open files. +- // Open all files for performance reasons, because gopls only +- // keeps active packages (those with open files) in memory. - // - // In practice clients will only send document-oriented requests for open - // files. @@ -43117,10 +49260,9 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - t.Fatal(err) - } - r := &runner{ -- data: datum, -- ctx: ctx, -- normalizers: tests.CollectNormalizers(datum.Exported), -- editRecv: make(chan map[span.URI][]byte, 1), +- data: datum, +- ctx: ctx, +- editRecv: make(chan map[span.URI][]byte, 1), - } - - r.server = NewServer(session, testClient{runner: r}) @@ -43133,7 +49275,6 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - data *tests.Data - diagnostics map[span.URI][]*source.Diagnostic - ctx context.Context -- normalizers []tests.Normalizer - editRecv chan map[span.URI][]byte -} - @@ -43206,7 +49347,7 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - } - msg := tests.DiffCallHierarchyItems(incomingCallItems, expectedCalls.IncomingCalls) - if msg != "" { -- t.Error(fmt.Sprintf("incoming calls: %s", msg)) +- t.Errorf("incoming calls: %s", msg) - } - - outgoingCalls, err := r.server.OutgoingCalls(r.ctx, &protocol.CallHierarchyOutgoingCallsParams{Item: items[0]}) @@ -43219,7 +49360,7 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - } - msg = tests.DiffCallHierarchyItems(outgoingCallItems, expectedCalls.OutgoingCalls) - if msg != "" { -- t.Error(fmt.Sprintf("outgoing calls: %s", msg)) +- t.Errorf("outgoing calls: %s", msg) - } -} - @@ -43242,7 +49383,7 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - -func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []*source.Diagnostic) { - // Get the diagnostics for this view if we have not done it before. -- v := r.server.session.View(r.data.Config.Dir) +- v := r.server.session.ViewByName(r.data.Config.Dir) - r.collectDiagnostics(v) - tests.CompareDiagnostics(t, uri, want, r.diagnostics[uri]) -} @@ -43374,52 +49515,18 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - // TODO(adonovan): factor to use diff.ApplyEdits, which validates the input. - for i := len(ranges) - 1; i >= 0; i-- { - r := ranges[i] -- start, err := m.PositionPoint(protocol.Position{Line: r.StartLine, Character: r.StartCharacter}) -- if err != nil { -- return "", err -- } -- end, err := m.PositionPoint(protocol.Position{Line: r.EndLine, Character: r.EndCharacter}) +- start, end, err := m.RangeOffsets(protocol.Range{ +- Start: protocol.Position{Line: r.StartLine, Character: r.StartCharacter}, +- End: protocol.Position{Line: r.EndLine, Character: r.EndCharacter}, +- }) - if err != nil { - return "", err - } -- res = res[:start.Offset()] + foldedText + res[end.Offset():] +- res = res[:start] + foldedText + res[end:] - } - return res, nil -} - --func (r *runner) Format(t *testing.T, spn span.Span) { -- uri := spn.URI() -- filename := uri.Filename() -- gofmted := r.data.Golden(t, "gofmt", filename, func() ([]byte, error) { -- cmd := exec.Command("gofmt", filename) -- out, _ := cmd.Output() // ignore error, sometimes we have intentionally ungofmt-able files -- return out, nil -- }) -- -- edits, err := r.server.Formatting(r.ctx, &protocol.DocumentFormattingParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- }) -- if err != nil { -- if len(gofmted) > 0 { -- t.Error(err) -- } -- return -- } -- m, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- got, _, err := source.ApplyProtocolEdits(m, edits) -- if err != nil { -- t.Error(err) -- } -- if diff := compare.Bytes(gofmted, got); diff != "" { -- t.Errorf("format failed for %s (-want +got):\n%s", filename, diff) -- } --} -- -func (r *runner) SemanticTokens(t *testing.T, spn span.Span) { - uri := spn.URI() - filename := uri.Filename() @@ -43453,39 +49560,6 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - } -} - --func (r *runner) Import(t *testing.T, spn span.Span) { -- // Invokes textDocument/codeAction and applies all the "goimports" edits. -- -- uri := spn.URI() -- filename := uri.Filename() -- actions, err := r.server.CodeAction(r.ctx, &protocol.CodeActionParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- }) -- if err != nil { -- t.Fatal(err) -- } -- m, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- got := m.Content -- if len(actions) > 0 { -- res, err := applyTextDocumentEdits(r, actions[0].Edit.DocumentChanges) -- if err != nil { -- t.Fatal(err) -- } -- got = res[uri] -- } -- want := r.data.Golden(t, "goimports", filename, func() ([]byte, error) { -- return got, nil -- }) -- if diff := compare.Bytes(want, got); diff != "" { -- t.Errorf("import failed for %s:\n%s", filename, diff) -- } --} -- -func (r *runner) SuggestedFix(t *testing.T, spn span.Span, actionKinds []tests.SuggestedFix, expectedActions int) { - uri := spn.URI() - view, err := r.server.session.ViewOf(uri) @@ -43584,58 +49658,6 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - } -} - --func (r *runner) FunctionExtraction(t *testing.T, start span.Span, end span.Span) { -- uri := start.URI() -- m, err := r.data.Mapper(uri) -- if err != nil { -- t.Fatal(err) -- } -- spn := span.New(start.URI(), start.Start(), end.End()) -- rng, err := m.SpanRange(spn) -- if err != nil { -- t.Fatal(err) -- } -- actionsRaw, err := r.server.CodeAction(r.ctx, &protocol.CodeActionParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- Range: rng, -- Context: protocol.CodeActionContext{ -- Only: []protocol.CodeActionKind{"refactor.extract"}, -- }, -- }) -- if err != nil { -- t.Fatal(err) -- } -- var actions []protocol.CodeAction -- for _, action := range actionsRaw { -- if action.Command.Title == "Extract function" { -- actions = append(actions, action) -- } -- } -- // Hack: We assume that we only get one code action per range. -- // TODO(rstambler): Support multiple code actions per test. -- if len(actions) == 0 || len(actions) > 1 { -- t.Fatalf("unexpected number of code actions, want 1, got %v", len(actions)) -- } -- _, err = r.server.ExecuteCommand(r.ctx, &protocol.ExecuteCommandParams{ -- Command: actions[0].Command.Command, -- Arguments: actions[0].Command.Arguments, -- }) -- if err != nil { -- t.Fatal(err) -- } -- res := <-r.editRecv -- for u, got := range res { -- want := r.data.Golden(t, "functionextraction_"+tests.SpanName(spn), u.Filename(), func() ([]byte, error) { -- return got, nil -- }) -- if diff := compare.Bytes(want, got); diff != "" { -- t.Errorf("function extraction failed for %s:\n%s", u.Filename(), diff) -- } -- } --} -- -func (r *runner) MethodExtraction(t *testing.T, start span.Span, end span.Span) { - uri := start.URI() - m, err := r.data.Mapper(uri) @@ -43767,35 +49789,6 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - } -} - --func (r *runner) Implementation(t *testing.T, spn span.Span, wantSpans []span.Span) { -- sm, err := r.data.Mapper(spn.URI()) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := sm.SpanLocation(spn) -- if err != nil { -- t.Fatal(err) -- } -- gotImpls, err := r.server.Implementation(r.ctx, &protocol.ImplementationParams{ -- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), -- }) -- if err != nil { -- t.Fatalf("Server.Implementation(%s): %v", spn, err) -- } -- gotLocs, err := tests.LocationsToSpans(r.data, gotImpls) -- if err != nil { -- t.Fatal(err) -- } -- sanitize := func(s string) string { -- return strings.ReplaceAll(s, r.data.Config.Dir, "gopls/internal/lsp/testdata") -- } -- want := sanitize(tests.SortAndFormatSpans(wantSpans)) -- got := sanitize(tests.SortAndFormatSpans(gotLocs)) -- if got != want { -- t.Errorf("implementations(%s):\n%s", sanitize(fmt.Sprint(spn)), diff.Unified("want", "got", want, got)) -- } --} -- -func (r *runner) Highlight(t *testing.T, src span.Span, spans []span.Span) { - m, err := r.data.Mapper(src.URI()) - if err != nil { @@ -43840,90 +49833,6 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - } -} - --func (r *runner) References(t *testing.T, src span.Span, itemList []span.Span) { -- // This test is substantially the same as (*runner).References in source/source_test.go. -- // TODO(adonovan): Factor (and remove fluff). Where should the common code live? -- -- sm, err := r.data.Mapper(src.URI()) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := sm.SpanLocation(src) -- if err != nil { -- t.Fatalf("failed for %v: %v", src, err) -- } -- for _, includeDeclaration := range []bool{true, false} { -- t.Run(fmt.Sprintf("refs-declaration-%v", includeDeclaration), func(t *testing.T) { -- want := make(map[protocol.Location]bool) -- for i, pos := range itemList { -- // We don't want the first result if we aren't including the declaration. -- // TODO(adonovan): don't assume a single declaration: -- // there may be >1 if corresponding methods are considered. -- if i == 0 && !includeDeclaration { -- continue -- } -- m, err := r.data.Mapper(pos.URI()) -- if err != nil { -- t.Fatal(err) -- } -- loc, err := m.SpanLocation(pos) -- if err != nil { -- t.Fatalf("failed for %v: %v", src, err) -- } -- want[loc] = true -- } -- params := &protocol.ReferenceParams{ -- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(loc), -- Context: protocol.ReferenceContext{ -- IncludeDeclaration: includeDeclaration, -- }, -- } -- got, err := r.server.References(r.ctx, params) -- if err != nil { -- t.Fatalf("failed for %v: %v", src, err) -- } -- -- sanitize := func(s string) string { -- // In practice, CONFIGDIR means "gopls/internal/lsp/testdata". -- return strings.ReplaceAll(s, r.data.Config.Dir, "CONFIGDIR") -- } -- formatLocation := func(loc protocol.Location) string { -- return fmt.Sprintf("%s:%d.%d-%d.%d", -- sanitize(string(loc.URI)), -- loc.Range.Start.Line+1, -- loc.Range.Start.Character+1, -- loc.Range.End.Line+1, -- loc.Range.End.Character+1) -- } -- toSlice := func(set map[protocol.Location]bool) []protocol.Location { -- // TODO(adonovan): use generic maps.Keys(), someday. -- list := make([]protocol.Location, 0, len(set)) -- for key := range set { -- list = append(list, key) -- } -- return list -- } -- toString := func(locs []protocol.Location) string { -- // TODO(adonovan): use generic JoinValues(locs, formatLocation). -- strs := make([]string, len(locs)) -- for i, loc := range locs { -- strs[i] = formatLocation(loc) -- } -- sort.Strings(strs) -- return strings.Join(strs, "\n") -- } -- gotStr := toString(got) -- wantStr := toString(toSlice(want)) -- if gotStr != wantStr { -- t.Errorf("incorrect references (got %d, want %d) at %s:\n%s", -- len(got), len(want), -- formatLocation(loc), -- diff.Unified("want", "got", wantStr, gotStr)) -- } -- }) -- } --} -- -func (r *runner) InlayHints(t *testing.T, spn span.Span) { - uri := spn.URI() - filename := uri.Filename() @@ -44104,72 +50013,6 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - return res, nil -} - --func (r *runner) Symbols(t *testing.T, uri span.URI, expectedSymbols []protocol.DocumentSymbol) { -- params := &protocol.DocumentSymbolParams{ -- TextDocument: protocol.TextDocumentIdentifier{ -- URI: protocol.URIFromSpanURI(uri), -- }, -- } -- got, err := r.server.DocumentSymbol(r.ctx, params) -- if err != nil { -- t.Fatal(err) -- } -- -- symbols := make([]protocol.DocumentSymbol, len(got)) -- for i, s := range got { -- s, ok := s.(protocol.DocumentSymbol) -- if !ok { -- t.Fatalf("%v: wanted []DocumentSymbols but got %v", uri, got) -- } -- symbols[i] = s -- } -- -- // Sort by position to make it easier to find errors. -- sortSymbols := func(s []protocol.DocumentSymbol) { -- sort.Slice(s, func(i, j int) bool { -- return protocol.CompareRange(s[i].SelectionRange, s[j].SelectionRange) < 0 -- }) -- } -- sortSymbols(expectedSymbols) -- sortSymbols(symbols) -- -- // Ignore 'Range' here as it is difficult (impossible?) to express -- // multi-line ranges in the packagestest framework. -- ignoreRange := cmpopts.IgnoreFields(protocol.DocumentSymbol{}, "Range") -- if diff := cmp.Diff(expectedSymbols, symbols, ignoreRange); diff != "" { -- t.Errorf("mismatching symbols (-want +got)\n%s", diff) -- } --} -- --func (r *runner) WorkspaceSymbols(t *testing.T, uri span.URI, query string, typ tests.WorkspaceSymbolsTestType) { -- matcher := tests.WorkspaceSymbolsTestTypeToMatcher(typ) -- -- original := r.server.session.Options() -- modified := original -- modified.SymbolMatcher = matcher -- r.server.session.SetOptions(modified) -- defer r.server.session.SetOptions(original) -- -- params := &protocol.WorkspaceSymbolParams{ -- Query: query, -- } -- gotSymbols, err := r.server.Symbol(r.ctx, params) -- if err != nil { -- t.Fatal(err) -- } -- got, err := tests.WorkspaceSymbolsString(r.ctx, r.data, uri, gotSymbols) -- if err != nil { -- t.Fatal(err) -- } -- got = filepath.ToSlash(tests.Normalize(got, r.normalizers)) -- want := string(r.data.Golden(t, fmt.Sprintf("workspace_symbol-%s-%s", strings.ToLower(string(matcher)), query), uri.Filename(), func() ([]byte, error) { -- return []byte(got), nil -- })) -- if diff := compare.Text(want, got); diff != "" { -- t.Error(diff) -- } --} -- -func (r *runner) SignatureHelp(t *testing.T, spn span.Span, want *protocol.SignatureHelp) { - m, err := r.data.Mapper(spn.URI()) - if err != nil { @@ -44347,7 +50190,7 @@ diff -urN a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go - defer release() - - // Always run diagnostics with analysis. -- r.server.diagnose(r.ctx, snapshot, true) +- r.server.diagnose(r.ctx, snapshot, analyzeEverything) - for uri, reports := range r.server.diagnostics { - for _, report := range reports.reports { - for _, d := range report.diags { @@ -44554,7 +50397,7 @@ diff -urN a/gopls/internal/lsp/mod/code_lens.go b/gopls/internal/lsp/mod/code_le diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagnostics.go --- a/gopls/internal/lsp/mod/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/mod/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,561 +0,0 @@ +@@ -1,571 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -44566,11 +50409,14 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn -import ( - "context" - "fmt" +- "runtime" - "sort" - "strings" +- "sync" - - "golang.org/x/mod/modfile" - "golang.org/x/mod/semver" +- "golang.org/x/sync/errgroup" - "golang.org/x/tools/gopls/internal/govulncheck" - "golang.org/x/tools/gopls/internal/lsp/command" - "golang.org/x/tools/gopls/internal/lsp/protocol" @@ -44580,14 +50426,20 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn - "golang.org/x/vuln/osv" -) - --// Diagnostics returns diagnostics for the modules in the workspace. --// --// It waits for completion of type-checking of all active packages. +-// Diagnostics returns diagnostics from parsing the modules in the workspace. -func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[span.URI][]*source.Diagnostic, error) { - ctx, done := event.Start(ctx, "mod.Diagnostics", source.SnapshotLabels(snapshot)...) - defer done() - -- return collectDiagnostics(ctx, snapshot, ModDiagnostics) +- return collectDiagnostics(ctx, snapshot, ModParseDiagnostics) +-} +- +-// Diagnostics returns diagnostics from running go mod tidy. +-func TidyDiagnostics(ctx context.Context, snapshot source.Snapshot) (map[span.URI][]*source.Diagnostic, error) { +- ctx, done := event.Start(ctx, "mod.Diagnostics", source.SnapshotLabels(snapshot)...) +- defer done() +- +- return collectDiagnostics(ctx, snapshot, ModTidyDiagnostics) -} - -// UpgradeDiagnostics returns upgrade diagnostics for the modules in the @@ -44609,32 +50461,42 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn -} - -func collectDiagnostics(ctx context.Context, snapshot source.Snapshot, diagFn func(context.Context, source.Snapshot, source.FileHandle) ([]*source.Diagnostic, error)) (map[span.URI][]*source.Diagnostic, error) { +- +- g, ctx := errgroup.WithContext(ctx) +- cpulimit := runtime.GOMAXPROCS(0) +- g.SetLimit(cpulimit) +- +- var mu sync.Mutex - reports := make(map[span.URI][]*source.Diagnostic) +- - for _, uri := range snapshot.ModFiles() { -- fh, err := snapshot.GetFile(ctx, uri) -- if err != nil { -- return nil, err -- } -- reports[fh.URI()] = []*source.Diagnostic{} -- diagnostics, err := diagFn(ctx, snapshot, fh) -- if err != nil { -- return nil, err -- } -- for _, d := range diagnostics { -- fh, err := snapshot.GetFile(ctx, d.URI) +- uri := uri +- g.Go(func() error { +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { -- return nil, err +- return err - } -- reports[fh.URI()] = append(reports[fh.URI()], d) -- } +- diagnostics, err := diagFn(ctx, snapshot, fh) +- if err != nil { +- return err +- } +- for _, d := range diagnostics { +- mu.Lock() +- reports[d.URI] = append(reports[fh.URI()], d) +- mu.Unlock() +- } +- return nil +- }) +- } +- +- if err := g.Wait(); err != nil { +- return nil, err - } - return reports, nil -} - --// ModDiagnostics waits for completion of type-checking of all active --// packages, then returns diagnostics from diagnosing the packages in --// the workspace and from tidying the go.mod file. --func ModDiagnostics(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) (diagnostics []*source.Diagnostic, err error) { +-// ModParseDiagnostics reports diagnostics from parsing the mod file. +-func ModParseDiagnostics(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) (diagnostics []*source.Diagnostic, err error) { - pm, err := snapshot.ParseMod(ctx, fh) - if err != nil { - if pm == nil || len(pm.ParseErrors) == 0 { @@ -44642,28 +50504,14 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn - } - return pm.ParseErrors, nil - } +- return nil, nil +-} - -- // Packages in the workspace can contribute diagnostics to go.mod files. -- // TODO(rfindley): Try to avoid type checking all packages in the workspace here, -- // for every go.mod file. If gc_details is enabled, it looks like this could lead to extra -- // go command invocations (as gc details is not memoized). -- active, err := snapshot.ActiveMetadata(ctx) -- if err != nil && !source.IsNonFatalGoModError(err) { -- event.Error(ctx, fmt.Sprintf("workspace packages: diagnosing %s", pm.URI), err) -- } -- if err == nil { -- // Note: the call to PackageDiagnostics below may be the first operation -- // after the initial metadata load, and therefore result in type-checking -- // or loading many packages. -- ids := make([]source.PackageID, len(active)) -- for i, meta := range active { -- ids[i] = meta.ID -- } -- diags, err := snapshot.PackageDiagnostics(ctx, ids...) -- if err != nil { -- return nil, err -- } -- diagnostics = append(diagnostics, diags[fh.URI()]...) +-// ModTidyDiagnostics reports diagnostics from running go mod tidy. +-func ModTidyDiagnostics(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) (diagnostics []*source.Diagnostic, err error) { +- pm, err := snapshot.ParseMod(ctx, fh) // memoized +- if err != nil { +- return nil, nil // errors reported by ModDiagnostics above - } - - tidied, err := snapshot.ModTidy(ctx, pm) @@ -44744,7 +50592,7 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn - - diagSource := source.Govulncheck - vs := snapshot.View().Vulnerabilities(fh.URI())[fh.URI()] -- if vs == nil && snapshot.View().Options().Vulncheck == source.ModeVulncheckImports { +- if vs == nil && snapshot.Options().Vulncheck == source.ModeVulncheckImports { - vs, err = snapshot.ModVuln(ctx, fh.URI()) - if err != nil { - return nil, err @@ -44876,7 +50724,6 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn - Source: diagSource, - Message: getVulnMessage(req.Mod.Path, info, false, diagSource == source.Govulncheck), - SuggestedFixes: infoFixes, -- Related: relatedInfo, - }) - } - } @@ -44884,7 +50731,13 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn - // TODO(hyangah): place this diagnostic on the `go` directive or `toolchain` directive - // after https://go.dev/issue/57001. - const diagnoseStdLib = false -- if diagnoseStdLib { +- +- // If diagnosing the stdlib, add standard library vulnerability diagnostics +- // on the module declaration. +- // +- // Only proceed if we have a valid module declaration on which to position +- // the diagnostics. +- if diagnoseStdLib && pm.File.Module != nil && pm.File.Module.Syntax != nil { - // Add standard library vulnerabilities. - stdlibVulns := vulnsByModule["stdlib"] - if len(stdlibVulns) == 0 { @@ -45084,7 +50937,7 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn - var chosenVersionedUpgrade string - var selected []protocol.CodeAction - -- seen := make(map[string]bool) +- seenTitles := make(map[string]bool) - - for _, action := range actions { - if strings.HasPrefix(action.Title, upgradeCodeActionPrefix) { @@ -45096,8 +50949,8 @@ diff -urN a/gopls/internal/lsp/mod/diagnostics.go b/gopls/internal/lsp/mod/diagn - } - } else if strings.HasPrefix(action.Title, "Reset govulncheck") { - resetAction = action -- } else if !seen[action.Command.Title] { -- seen[action.Command.Title] = true +- } else if !seenTitles[action.Command.Title] { +- seenTitles[action.Command.Title] = true - selected = append(selected, action) - } - } @@ -45147,7 +51000,7 @@ diff -urN a/gopls/internal/lsp/mod/format.go b/gopls/internal/lsp/mod/format.go - return nil, err - } - // Calculate the edits to be made due to the change. -- diffs := snapshot.View().Options().ComputeEdits(string(pm.Mapper.Content), string(formatted)) +- diffs := snapshot.Options().ComputeEdits(string(pm.Mapper.Content), string(formatted)) - return source.ToProtocolEdits(pm.Mapper, diffs) -} diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go @@ -45238,7 +51091,7 @@ diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go - // Get the vulnerability info. - fromGovulncheck := true - vs := snapshot.View().Vulnerabilities(fh.URI())[fh.URI()] -- if vs == nil && snapshot.View().Options().Vulncheck == source.ModeVulncheckImports { +- if vs == nil && snapshot.Options().Vulncheck == source.ModeVulncheckImports { - var err error - vs, err = snapshot.ModVuln(ctx, fh.URI()) - if err != nil { @@ -45265,7 +51118,7 @@ diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go - if err != nil { - return nil, err - } -- options := snapshot.View().Options() +- options := snapshot.Options() - isPrivate := snapshot.View().IsGoPrivatePath(req.Mod.Path) - header := formatHeader(req.Mod.Path, options) - explanation = formatExplanation(explanation, req, options, isPrivate) @@ -45296,7 +51149,7 @@ diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go - fromGovulncheck := true - vs := snapshot.View().Vulnerabilities(fh.URI())[fh.URI()] - -- if vs == nil && snapshot.View().Options().Vulncheck == source.ModeVulncheckImports { +- if vs == nil && snapshot.Options().Vulncheck == source.ModeVulncheckImports { - vs, err = snapshot.ModVuln(ctx, fh.URI()) - if err != nil { - return nil, false @@ -45306,7 +51159,7 @@ diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go - modpath := "stdlib" - goVersion := snapshot.View().GoVersionString() - affecting, nonaffecting := lookupVulns(vs, modpath, goVersion) -- options := snapshot.View().Options() +- options := snapshot.Options() - vulns := formatVulnerabilities(modpath, affecting, nonaffecting, options, fromGovulncheck) - - return &protocol.Hover{ @@ -45512,86 +51365,114 @@ diff -urN a/gopls/internal/lsp/mod/hover.go b/gopls/internal/lsp/mod/hover.go - b.WriteString("\n```") - return b.String() -} -diff -urN a/gopls/internal/lsp/mod/mod_test.go b/gopls/internal/lsp/mod/mod_test.go ---- a/gopls/internal/lsp/mod/mod_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/mod_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,57 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/lsp/mod/inlayhint.go b/gopls/internal/lsp/mod/inlayhint.go +--- a/gopls/internal/lsp/mod/inlayhint.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/mod/inlayhint.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,100 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. -- -package mod - -import ( -- "io/ioutil" -- "os" -- "path/filepath" -- "testing" +- "context" +- "fmt" - -- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/tests" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/testenv" -) - --func TestMain(m *testing.M) { -- testenv.ExitIfSmallMachine() -- os.Exit(m.Run()) --} +-func InlayHint(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, rng protocol.Range) ([]protocol.InlayHint, error) { +- // Inlay hints are enabled if the client supports them. +- pm, err := snapshot.ParseMod(ctx, fh) +- if err != nil { +- return nil, err +- } - --func TestModfileRemainsUnchanged(t *testing.T) { -- ctx := tests.Context(t) -- session := cache.NewSession(ctx, cache.New(nil), nil) -- options := source.DefaultOptions().Clone() -- tests.DefaultOptions(options) -- options.TempModfile = true -- options.Env = map[string]string{"GOPACKAGESDRIVER": "off", "GOROOT": ""} +- // Compare the version of the module used in the snapshot's metadata with the +- // version requested by the module, in both cases, taking replaces into account. +- // Produce an InlayHint when the version is the module is not the one used. - -- // Make sure to copy the test directory to a temporary directory so we do not -- // modify the test code or add go.sum files when we run the tests. -- folder, err := tests.CopyFolderToTempDir(filepath.Join("testdata", "unchanged")) -- if err != nil { -- t.Fatal(err) +- replaces := make(map[string]*modfile.Replace) +- for _, x := range pm.File.Replace { +- replaces[x.Old.Path] = x +- } +- +- requires := make(map[string]*modfile.Require) +- for _, x := range pm.File.Require { +- requires[x.Mod.Path] = x - } -- defer os.RemoveAll(folder) - -- before, err := ioutil.ReadFile(filepath.Join(folder, "go.mod")) +- am, err := snapshot.AllMetadata(ctx) - if err != nil { -- t.Fatal(err) +- return nil, err +- } +- +- var ans []protocol.InlayHint +- seen := make(map[string]bool) +- for _, meta := range am { +- if meta.Module == nil || seen[meta.Module.Path] { +- continue +- } +- seen[meta.Module.Path] = true +- metaVersion := meta.Module.Version +- if meta.Module.Replace != nil { +- metaVersion = meta.Module.Replace.Version +- } +- // These versions can be blank, as in gopls/go.mod's local replace +- if oldrepl, ok := replaces[meta.Module.Path]; ok && oldrepl.New.Version != metaVersion { +- ih := genHint(oldrepl.Syntax, oldrepl.New.Version, metaVersion, pm.Mapper) +- if ih != nil { +- ans = append(ans, *ih) +- } +- } else if oldreq, ok := requires[meta.Module.Path]; ok && oldreq.Mod.Version != metaVersion { +- // maybe it was replaced: +- if _, ok := replaces[meta.Module.Path]; ok { +- continue +- } +- ih := genHint(oldreq.Syntax, oldreq.Mod.Version, metaVersion, pm.Mapper) +- if ih != nil { +- ans = append(ans, *ih) +- } +- } - } -- _, _, release, err := session.NewView(ctx, "diagnostics_test", span.URIFromPath(folder), options) +- return ans, nil +-} +- +-func genHint(mline *modfile.Line, oldVersion, newVersion string, m *protocol.Mapper) *protocol.InlayHint { +- x := mline.End.Byte // the parser has removed trailing whitespace and comments (see modfile_test.go) +- x -= len(mline.Token[len(mline.Token)-1]) +- line, err := m.OffsetPosition(x) - if err != nil { -- t.Fatal(err) +- return nil - } -- release() -- after, err := ioutil.ReadFile(filepath.Join(folder, "go.mod")) +- part := protocol.InlayHintLabelPart{ +- Value: newVersion, +- Tooltip: &protocol.OrPTooltipPLabel{ +- Value: fmt.Sprintf("used metadata's version %s rather than go.mod's version %s", newVersion, oldVersion), +- }, +- } +- rng, err := m.OffsetRange(x, mline.End.Byte) - if err != nil { -- t.Fatal(err) +- return nil - } -- if string(before) != string(after) { -- t.Errorf("the real go.mod file was changed even when tempModfile=true") +- te := protocol.TextEdit{ +- Range: rng, +- NewText: newVersion, +- } +- return &protocol.InlayHint{ +- Position: line, +- Label: []protocol.InlayHintLabelPart{part}, +- Kind: protocol.Parameter, +- PaddingRight: true, +- TextEdits: []protocol.TextEdit{te}, - } --} -diff -urN a/gopls/internal/lsp/mod/testdata/unchanged/go.mod b/gopls/internal/lsp/mod/testdata/unchanged/go.mod ---- a/gopls/internal/lsp/mod/testdata/unchanged/go.mod 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/testdata/unchanged/go.mod 1970-01-01 00:00:00.000000000 +0000 -@@ -1 +0,0 @@ --module unchanged -diff -urN a/gopls/internal/lsp/mod/testdata/unchanged/main.go b/gopls/internal/lsp/mod/testdata/unchanged/main.go ---- a/gopls/internal/lsp/mod/testdata/unchanged/main.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/mod/testdata/unchanged/main.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --// Package unchanged does something --package unchanged -- --func Yo() { -- println("yo") -} diff -urN a/gopls/internal/lsp/progress/progress.go b/gopls/internal/lsp/progress/progress.go --- a/gopls/internal/lsp/progress/progress.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/progress/progress.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,271 +0,0 @@ +@@ -1,283 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -45627,10 +51508,22 @@ diff -urN a/gopls/internal/lsp/progress/progress.go b/gopls/internal/lsp/progres - } -} - +-// SetSupportsWorkDoneProgress sets whether the client supports work done +-// progress reporting. It must be set before using the tracker. +-// +-// TODO(rfindley): fix this broken initialization pattern. +-// Also: do we actually need the fall-back progress behavior using ShowMessage? +-// Surely ShowMessage notifications are too noisy to be worthwhile. -func (tracker *Tracker) SetSupportsWorkDoneProgress(b bool) { - tracker.supportsWorkDoneProgress = b -} - +-// SupportsWorkDoneProgress reports whether the tracker supports work done +-// progress reporting. +-func (tracker *Tracker) SupportsWorkDoneProgress() bool { +- return tracker.supportsWorkDoneProgress +-} +- -// Start notifies the client of work being done on the server. It uses either -// ShowMessage RPCs or $/progress messages, depending on the capabilities of -// the client. The returned WorkDone handle may be used to report incremental @@ -46046,7 +51939,7 @@ diff -urN a/gopls/internal/lsp/protocol/codeactionkind.go b/gopls/internal/lsp/p diff -urN a/gopls/internal/lsp/protocol/context.go b/gopls/internal/lsp/protocol/context.go --- a/gopls/internal/lsp/protocol/context.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/context.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,43 +0,0 @@ +@@ -1,45 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -46087,6 +51980,8 @@ diff -urN a/gopls/internal/lsp/protocol/context.go b/gopls/internal/lsp/protocol - if event.IsError(ev) { - msg.Type = Error - } +- // TODO(adonovan): the goroutine here could cause log +- // messages to be delivered out of order! Use a queue. - go client.LogMessage(xcontext.Detach(ctx), msg) - return ctx -} @@ -46475,7 +52370,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/generate.go b/gopls/internal/ls diff -urN a/gopls/internal/lsp/protocol/generate/main.go b/gopls/internal/lsp/protocol/generate/main.go --- a/gopls/internal/lsp/protocol/generate/main.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/generate/main.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,387 +0,0 @@ +@@ -1,390 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -46489,6 +52384,8 @@ diff -urN a/gopls/internal/lsp/protocol/generate/main.go b/gopls/internal/lsp/pr -// To run it, type 'go generate' in the parent (protocol) directory. -package main - +-// see https://github.com/golang/go/issues/61217 for discussion of an issue +- -import ( - "bytes" - "encoding/json" @@ -46509,14 +52406,15 @@ diff -urN a/gopls/internal/lsp/protocol/generate/main.go b/gopls/internal/lsp/pr -// For example, tag release/protocol/3.17.3 of the repo defines protocol version 3.17.0. -// (Point releases are reflected in the git tag version even when they are cosmetic -// and don't change the protocol.) --var lspGitRef = "release/protocol/3.17.3-next.6" +-var lspGitRef = "release/protocol/3.17.4-next.2" - -var ( - repodir = flag.String("d", "", "directory containing clone of "+vscodeRepo) - outputdir = flag.String("o", ".", "output directory") - // PJW: not for real code -- cmpdir = flag.String("c", "", "directory of earlier code") -- doboth = flag.String("b", "", "generate and compare") +- cmpdir = flag.String("c", "", "directory of earlier code") +- doboth = flag.String("b", "", "generate and compare") +- lineNumbers = flag.Bool("l", false, "add line numbers to generated output") -) - -func main() { @@ -46866,7 +52764,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/main.go b/gopls/internal/lsp/pr diff -urN a/gopls/internal/lsp/protocol/generate/main_test.go b/gopls/internal/lsp/protocol/generate/main_test.go --- a/gopls/internal/lsp/protocol/generate/main_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/generate/main_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,118 +0,0 @@ +@@ -1,119 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -46891,6 +52789,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/main_test.go b/gopls/internal/l -// (in vscode, just run the test with "go.coverOnSingleTest": true) -func TestAll(t *testing.T) { - t.Skip("needs vscode-languageserver-node repository") +- *lineNumbers = true - log.SetFlags(log.Lshortfile) - main() -} @@ -46988,7 +52887,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/main_test.go b/gopls/internal/l diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/protocol/generate/output.go --- a/gopls/internal/lsp/protocol/generate/output.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/generate/output.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,420 +0,0 @@ +@@ -1,427 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -47044,7 +52943,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ -} - -func genDecl(method string, param, result *Type, dir string) { -- fname := methodNames[method] +- fname := methodName(method) - p := "" - if notNil(param) { - p = ", *" + goplsName(param) @@ -47083,7 +52982,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - out := new(bytes.Buffer) - fmt.Fprintf(out, "\tcase %q:\n", method) - var p string -- fname := methodNames[method] +- fname := methodName(method) - if notNil(param) { - nm := goplsName(param) - if method == "workspace/configuration" { // gopls compatibility @@ -47145,7 +53044,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - r = "([]LSPAny, error)" - goResult = "[]LSPAny" - } -- fname := methodNames[method] +- fname := methodName(method) - fmt.Fprintf(out, "func (s *%%sDispatcher) %s(ctx context.Context%s) %s {\n", - fname, p, r) - @@ -47208,7 +53107,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - // a weird case, and needed only so the generated code contains the old gopls code - nm = "DocumentDiagnosticParams" - } -- fmt.Fprintf(out, "type %s struct { // line %d\n", nm, s.Line) +- fmt.Fprintf(out, "type %s struct {%s\n", nm, linex(s.Line)) - // for gpls compatibilitye, embed most extensions, but expand the rest some day - props := append([]NameType{}, s.Properties...) - if s.Name == "SymbolInformation" { // but expand this one @@ -47278,7 +53177,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - switch nt.kind { - case "literal": - fmt.Fprintf(out, "// created for Literal (%s)\n", nt.name) -- fmt.Fprintf(out, "type %s struct { // line %d\n", nm, nt.line+1) +- fmt.Fprintf(out, "type %s struct {%s\n", nm, linex(nt.line+1)) - genProps(out, nt.properties, nt.name) // systematic name, not gopls name; is this a good choice? - case "or": - if !strings.HasPrefix(nm, "Or") { @@ -47293,18 +53192,18 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - } - sort.Strings(names) - fmt.Fprintf(out, "// created for Or %v\n", names) -- fmt.Fprintf(out, "type %s struct { // line %d\n", nm, nt.line+1) +- fmt.Fprintf(out, "type %s struct {%s\n", nm, linex(nt.line+1)) - fmt.Fprintf(out, "\tValue interface{} `json:\"value\"`\n") - case "and": - fmt.Fprintf(out, "// created for And\n") -- fmt.Fprintf(out, "type %s struct { // line %d\n", nm, nt.line+1) +- fmt.Fprintf(out, "type %s struct {%s\n", nm, linex(nt.line+1)) - for _, x := range nt.items { - nm := goplsName(x) - fmt.Fprintf(out, "\t%s\n", nm) - } - case "tuple": // there's only this one - nt.name = "UIntCommaUInt" -- fmt.Fprintf(out, "//created for Tuple\ntype %s struct { // line %d\n", nm, nt.line+1) +- fmt.Fprintf(out, "//created for Tuple\ntype %s struct {%s\n", nm, linex(nt.line+1)) - fmt.Fprintf(out, "\tFld0 uint32 `json:\"fld0\"`\n") - fmt.Fprintf(out, "\tFld1 uint32 `json:\"fld1\"`\n") - default: @@ -47320,7 +53219,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - generateDoc(out, e.Documentation) - tp := goplsName(e.Type) - nm := goName(e.Name) -- fmt.Fprintf(out, "type %s %s // line %d\n", nm, tp, e.Line) +- fmt.Fprintf(out, "type %s %s%s\n", nm, tp, linex(e.Line)) - types[nm] = out.String() - vals := new(bytes.Buffer) - generateDoc(vals, e.Documentation) @@ -47342,7 +53241,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - default: - log.Fatalf("impossible type %T", v) - } -- fmt.Fprintf(vals, "\t%s %s = %s // line %d\n", nm, e.Name, val, v.Line) +- fmt.Fprintf(vals, "\t%s %s = %s%s\n", nm, e.Name, val, linex(v.Line)) - } - consts[nm] = vals.String() - } @@ -47384,6 +53283,13 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ - } -} - +-func linex(n int) string { +- if *lineNumbers { +- return fmt.Sprintf(" // line %d", n) +- } +- return "" +-} +- -func goplsName(t *Type) string { - nm := typeNames[t] - // translate systematic name to gopls name @@ -47412,7 +53318,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/output.go b/gopls/internal/lsp/ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/protocol/generate/README.md --- a/gopls/internal/lsp/protocol/generate/README.md 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/generate/README.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,136 +0,0 @@ +@@ -1,144 +0,0 @@ -# LSP Support for gopls - -## The protocol @@ -47428,6 +53334,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -exact version can be tied to a githash. By default, the command will download the `github.com/microsoft/vscode-languageserver-node` repository to a temporary directory. - -The specification has five sections +- -1. Requests, which describe the Request and Response types for request methods (e.g., *textDocument/didChange*), -2. Notifications, which describe the Request types for notification methods, -3. Structures, which describe named struct-like types, @@ -47443,6 +53350,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -Finally, the specified types are Typescript types, which are quite different from Go types. - -### Optionality +- -The specification can mark fields in structs as Optional. The client distinguishes between missing -fields and `null` fields in some cases. The Go translation for an optional type -should be making sure the field's value @@ -47450,6 +53358,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -adding `*` to the field's type if the type is not a reference type. - -### Types +- -The specification uses a number of different types, only a few of which correspond directly to Go types. -The specification's types are "base", "reference", "map", "literal", "stringLiteral", "tuple", "and", "or". -The "base" types correspond directly to Go types, although some Go types needs to be chosen for `URI` and `DocumentUri`. (The "base" types`RegExp`, `BooleanLiteral`, `NumericLiteral` never occur.) @@ -47485,6 +53394,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -have a single non-null component, and these are converted to the component type. - -## Processing +- -The code parses the json specification file, and scans all the types. It assigns names, as described -above, to the types that are unnamed in the specification, and constructs Go equivalents as required. -(Most of this code is in typenames.go.) @@ -47495,6 +53405,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -And tsprotocol.go contains the type and const definitions. - -### Accommodating gopls +- -As the code generates output, mostly in generateoutput.go and main.go, -it makes adjustments so that no changes are required to the existing Go code. -(Organizing the computation this way makes the code's structure simpler, but results in @@ -47522,6 +53433,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -whose type is an "or" of 3 stringLiterals, which just becomes a `string`. - -### Checking +- -`TestAll(t *testing.T)` checks that there are no unexpected fields in the json specification. - -While the code is executing, it checks that all the entries in the maps in tables.go are used. @@ -47534,6 +53446,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -slightly between the new and the old, and is not worth fixing.) - -### Some history +- -The original stub code was written by hand, but with the protocol under active development, that -couldn't last. The web page existed before the json specification, but it lagged the implementation -and was hard to process by machine. So the earlier version of the generating code was written in Typescript, and @@ -47543,16 +53456,17 @@ diff -urN a/gopls/internal/lsp/protocol/generate/README.md b/gopls/internal/lsp/ -The output was functional, but idiosyncratic, and the code was fragile and barely maintainable. - -### The future +- -Most of the adjustments using the maps in tables.go could be removed by making changes, mostly to names, -in the gopls code. Using more "or" types in gopls requires more elaborate, but stereotyped, changes. -But even without all the adjustments, making this its own module would face problems; a number of -dependencies would have to be factored out. And, it is fragile. The custom unmarshaling code knows what -types it expects. A design that return an 'any' on unexpected types would match the json --'ignore unexpected values' philosophy better, but the the Go code would need extra checking. +-'ignore unexpected values' philosophy better, but the Go code would need extra checking. diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/protocol/generate/tables.go --- a/gopls/internal/lsp/protocol/generate/tables.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/generate/tables.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,327 +0,0 @@ +@@ -1,341 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -47562,6 +53476,8 @@ diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/ - -package main - +-import "log" +- -// prop combines the name of a property with the name of the structure it is in. -type prop [2]string - @@ -47623,6 +53539,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/ - {"Command", "arguments"}: "[]json.RawMessage", - {"CompletionItem", "textEdit"}: "TextEdit", - {"Diagnostic", "code"}: "interface{}", +- {"Diagnostic", "data"}: "json.RawMessage", // delay unmarshalling quickfixes - - {"DocumentDiagnosticReportPartialResult", "relatedDocuments"}: "map[DocumentURI]interface{}", - @@ -47665,6 +53582,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/ - "DiagnosticSeverity": {"Severity", ""}, - "DocumentDiagnosticReportKind": {"Diagnostic", ""}, - "FileOperationPatternKind": {"", "Pattern"}, +- "InlineCompletionTriggerKind": {"Inline", ""}, - "InsertTextFormat": {"", "TextFormat"}, - "SemanticTokenModifiers": {"Mod", ""}, - "SemanticTokenTypes": {"", "Type"}, @@ -47831,6 +53749,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/ - "textDocument/hover": "Hover", - "textDocument/implementation": "Implementation", - "textDocument/inlayHint": "InlayHint", +- "textDocument/inlineCompletion": "InlineCompletion", - "textDocument/inlineValue": "InlineValue", - "textDocument/linkedEditingRange": "LinkedEditingRange", - "textDocument/moniker": "Moniker", @@ -47840,6 +53759,7 @@ diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/ - "textDocument/prepareTypeHierarchy": "PrepareTypeHierarchy", - "textDocument/publishDiagnostics": "PublishDiagnostics", - "textDocument/rangeFormatting": "RangeFormatting", +- "textDocument/rangesFormatting": "RangesFormatting", - "textDocument/references": "References", - "textDocument/rename": "Rename", - "textDocument/selectionRange": "SelectionRange", @@ -47880,6 +53800,14 @@ diff -urN a/gopls/internal/lsp/protocol/generate/tables.go b/gopls/internal/lsp/ - "workspace/workspaceFolders": "WorkspaceFolders", - "workspaceSymbol/resolve": "ResolveWorkspaceSymbol", -} +- +-func methodName(method string) string { +- ans := methodNames[method] +- if ans == "" { +- log.Fatalf("unknown method %q", method) +- } +- return ans +-} diff -urN a/gopls/internal/lsp/protocol/generate/typenames.go b/gopls/internal/lsp/protocol/generate/typenames.go --- a/gopls/internal/lsp/protocol/generate/typenames.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/generate/typenames.go 1970-01-01 00:00:00.000000000 +0000 @@ -48460,9 +54388,9 @@ diff -urN a/gopls/internal/lsp/protocol/mapper.go b/gopls/internal/lsp/protocol/ - "sync" - "unicode/utf8" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" -) - -// A Mapper wraps the content of a file and provides mapping @@ -48918,7 +54846,7 @@ diff -urN a/gopls/internal/lsp/protocol/mapper.go b/gopls/internal/lsp/protocol/ diff -urN a/gopls/internal/lsp/protocol/mapper_test.go b/gopls/internal/lsp/protocol/mapper_test.go --- a/gopls/internal/lsp/protocol/mapper_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/mapper_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,441 +0,0 @@ +@@ -1,439 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -49358,8 +55286,6 @@ diff -urN a/gopls/internal/lsp/protocol/mapper_test.go b/gopls/internal/lsp/prot - } - } -} -- --// -- end -- diff -urN a/gopls/internal/lsp/protocol/protocol.go b/gopls/internal/lsp/protocol/protocol.go --- a/gopls/internal/lsp/protocol/protocol.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/protocol.go 1970-01-01 00:00:00.000000000 +0000 @@ -49782,8 +55708,8 @@ diff -urN a/gopls/internal/lsp/protocol/tsclient.go b/gopls/internal/lsp/protoco - -package protocol - --// Code generated from protocol/metaModel.json at ref release/protocol/3.17.3-next.6 (hash 56c23c557e3568a9f56f42435fd5a80f9458957f). --// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.3-next.6/protocol/metaModel.json +-// Code generated from protocol/metaModel.json at ref release/protocol/3.17.4-next.2 (hash 184c8a7f010d335582f24337fe182baa6f2fccdd). +-// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.4-next.2/protocol/metaModel.json -// LSP metaData.version = 3.17.0. - -import ( @@ -50072,7 +55998,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsdocument_changes.go b/gopls/internal/l diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/tsjson.go --- a/gopls/internal/lsp/protocol/tsjson.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/tsjson.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1997 +0,0 @@ +@@ -1,2090 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -50081,8 +56007,8 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - -package protocol - --// Code generated from protocol/metaModel.json at ref release/protocol/3.17.3-next.6 (hash 56c23c557e3568a9f56f42435fd5a80f9458957f). --// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.3-next.6/protocol/metaModel.json +-// Code generated from protocol/metaModel.json at ref release/protocol/3.17.4-next.2 (hash 184c8a7f010d335582f24337fe182baa6f2fccdd). +-// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.4-next.2/protocol/metaModel.json -// LSP metaData.version = 3.17.0. - -import "encoding/json" @@ -50099,7 +56025,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return e.msg -} - --// from line 4769 +-// from line 4964 -func (t OrFEditRangePItemDefaults) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case FEditRangePItemDefaults: @@ -50130,7 +56056,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [FEditRangePItemDefaults Range]"} -} - --// from line 9811 +-// from line 10165 -func (t OrFNotebookPNotebookSelector) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case NotebookDocumentFilter: @@ -50161,7 +56087,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [NotebookDocumentFilter string]"} -} - --// from line 5520 +-// from line 5715 -func (t OrPLocation_workspace_symbol) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case Location: @@ -50192,7 +56118,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [Location PLocationMsg_workspace_symbol]"} -} - --// from line 4163 +-// from line 4358 -func (t OrPSection_workspace_didChangeConfiguration) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case []string: @@ -50223,7 +56149,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [[]string string]"} -} - --// from line 7075 +-// from line 7311 -func (t OrPTooltipPLabel) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case MarkupContent: @@ -50254,7 +56180,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [MarkupContent string]"} -} - --// from line 3699 +-// from line 3772 -func (t OrPTooltip_textDocument_inlayHint) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case MarkupContent: @@ -50285,7 +56211,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [MarkupContent string]"} -} - --// from line 6184 +-// from line 6420 -func (t Or_CancelParams_id) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case int32: @@ -50316,7 +56242,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [int32 string]"} -} - --// from line 4582 +-// from line 4777 -func (t Or_CompletionItem_documentation) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case MarkupContent: @@ -50347,7 +56273,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [MarkupContent string]"} -} - --// from line 4665 +-// from line 4860 -func (t Or_CompletionItem_textEdit) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case InsertReplaceEdit: @@ -50378,7 +56304,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [InsertReplaceEdit TextEdit]"} -} - --// from line 13753 +-// from line 14168 -func (t Or_Definition) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case Location: @@ -50409,7 +56335,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [Location []Location]"} -} - --// from line 8547 +-// from line 8865 -func (t Or_Diagnostic_code) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case int32: @@ -50440,7 +56366,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [int32 string]"} -} - --// from line 13885 +-// from line 14300 -func (t Or_DocumentDiagnosticReport) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case RelatedFullDocumentDiagnosticReport: @@ -50471,7 +56397,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [RelatedFullDocumentDiagnosticReport RelatedUnchangedDocumentDiagnosticReport]"} -} - --// from line 3822 +-// from line 3895 -func (t Or_DocumentDiagnosticReportPartialResult_relatedDocuments_Value) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case FullDocumentDiagnosticReport: @@ -50502,7 +56428,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [FullDocumentDiagnosticReport UnchangedDocumentDiagnosticReport]"} -} - --// from line 14095 +-// from line 14510 -func (t Or_DocumentFilter) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case NotebookCellTextDocumentFilter: @@ -50533,7 +56459,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [NotebookCellTextDocumentFilter TextDocumentFilter]"} -} - --// from line 4891 +-// from line 5086 -func (t Or_Hover_contents) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case MarkedString: @@ -50571,7 +56497,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [MarkedString MarkupContent []MarkedString]"} -} - --// from line 3658 +-// from line 3731 -func (t Or_InlayHint_label) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case []InlayHintLabelPart: @@ -50602,7 +56528,38 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [[]InlayHintLabelPart string]"} -} - --// from line 13863 +-// from line 4163 +-func (t Or_InlineCompletionItem_insertText) MarshalJSON() ([]byte, error) { +- switch x := t.Value.(type) { +- case StringValue: +- return json.Marshal(x) +- case string: +- return json.Marshal(x) +- case nil: +- return []byte("null"), nil +- } +- return nil, fmt.Errorf("type %T not one of [StringValue string]", t) +-} +- +-func (t *Or_InlineCompletionItem_insertText) UnmarshalJSON(x []byte) error { +- if string(x) == "null" { +- t.Value = nil +- return nil +- } +- var h0 StringValue +- if err := json.Unmarshal(x, &h0); err == nil { +- t.Value = h0 +- return nil +- } +- var h1 string +- if err := json.Unmarshal(x, &h1); err == nil { +- t.Value = h1 +- return nil +- } +- return &UnmarshalError{"unmarshal failed to match one of [StringValue string]"} +-} +- +-// from line 14278 -func (t Or_InlineValue) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case InlineValueEvaluatableExpression: @@ -50640,7 +56597,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [InlineValueEvaluatableExpression InlineValueText InlineValueVariableLookup]"} -} - --// from line 14060 +-// from line 14475 -func (t Or_MarkedString) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case Msg_MarkedString: @@ -50671,7 +56628,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [Msg_MarkedString string]"} -} - --// from line 10118 +-// from line 10472 -func (t Or_NotebookCellTextDocumentFilter_notebook) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case NotebookDocumentFilter: @@ -50702,7 +56659,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [NotebookDocumentFilter string]"} -} - --// from line 9857 +-// from line 10211 -func (t Or_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1_notebook) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case NotebookDocumentFilter: @@ -50733,7 +56690,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [NotebookDocumentFilter string]"} -} - --// from line 7168 +-// from line 7404 -func (t Or_RelatedFullDocumentDiagnosticReport_relatedDocuments_Value) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case FullDocumentDiagnosticReport: @@ -50764,7 +56721,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [FullDocumentDiagnosticReport UnchangedDocumentDiagnosticReport]"} -} - --// from line 7207 +-// from line 7443 -func (t Or_RelatedUnchangedDocumentDiagnosticReport_relatedDocuments_Value) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case FullDocumentDiagnosticReport: @@ -50795,7 +56752,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [FullDocumentDiagnosticReport UnchangedDocumentDiagnosticReport]"} -} - --// from line 10741 +-// from line 11106 -func (t Or_RelativePattern_baseUri) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case URI: @@ -50826,7 +56783,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [URI WorkspaceFolder]"} -} - --// from line 1371 +-// from line 1413 -func (t Or_Result_textDocument_codeAction_Item0_Elem) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case CodeAction: @@ -50857,7 +56814,38 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [CodeAction Command]"} -} - --// from line 12197 +-// from line 980 +-func (t Or_Result_textDocument_inlineCompletion) MarshalJSON() ([]byte, error) { +- switch x := t.Value.(type) { +- case InlineCompletionList: +- return json.Marshal(x) +- case []InlineCompletionItem: +- return json.Marshal(x) +- case nil: +- return []byte("null"), nil +- } +- return nil, fmt.Errorf("type %T not one of [InlineCompletionList []InlineCompletionItem]", t) +-} +- +-func (t *Or_Result_textDocument_inlineCompletion) UnmarshalJSON(x []byte) error { +- if string(x) == "null" { +- t.Value = nil +- return nil +- } +- var h0 InlineCompletionList +- if err := json.Unmarshal(x, &h0); err == nil { +- t.Value = h0 +- return nil +- } +- var h1 []InlineCompletionItem +- if err := json.Unmarshal(x, &h1); err == nil { +- t.Value = h1 +- return nil +- } +- return &UnmarshalError{"unmarshal failed to match one of [InlineCompletionList []InlineCompletionItem]"} +-} +- +-// from line 12573 -func (t Or_SemanticTokensClientCapabilities_requests_full) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case FFullPRequests: @@ -50888,7 +56876,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [FFullPRequests bool]"} -} - --// from line 12177 +-// from line 12553 -func (t Or_SemanticTokensClientCapabilities_requests_range) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case FRangePRequests: @@ -50919,7 +56907,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [FRangePRequests bool]"} -} - --// from line 6579 +-// from line 6815 -func (t Or_SemanticTokensOptions_full) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case PFullESemanticTokensOptions: @@ -50950,7 +56938,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [PFullESemanticTokensOptions bool]"} -} - --// from line 6559 +-// from line 6795 -func (t Or_SemanticTokensOptions_range) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case PRangeESemanticTokensOptions: @@ -50981,7 +56969,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [PRangeESemanticTokensOptions bool]"} -} - --// from line 8227 +-// from line 8525 -func (t Or_ServerCapabilities_callHierarchyProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case CallHierarchyOptions: @@ -51019,7 +57007,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [CallHierarchyOptions CallHierarchyRegistrationOptions bool]"} -} - --// from line 8035 +-// from line 8333 -func (t Or_ServerCapabilities_codeActionProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case CodeActionOptions: @@ -51050,7 +57038,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [CodeActionOptions bool]"} -} - --// from line 8071 +-// from line 8369 -func (t Or_ServerCapabilities_colorProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DocumentColorOptions: @@ -51088,7 +57076,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DocumentColorOptions DocumentColorRegistrationOptions bool]"} -} - --// from line 7897 +-// from line 8195 -func (t Or_ServerCapabilities_declarationProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DeclarationOptions: @@ -51126,7 +57114,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DeclarationOptions DeclarationRegistrationOptions bool]"} -} - --// from line 7919 +-// from line 8217 -func (t Or_ServerCapabilities_definitionProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DefinitionOptions: @@ -51157,7 +57145,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DefinitionOptions bool]"} -} - --// from line 8384 +-// from line 8682 -func (t Or_ServerCapabilities_diagnosticProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DiagnosticOptions: @@ -51188,7 +57176,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DiagnosticOptions DiagnosticRegistrationOptions]"} -} - --// from line 8111 +-// from line 8409 -func (t Or_ServerCapabilities_documentFormattingProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DocumentFormattingOptions: @@ -51219,7 +57207,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DocumentFormattingOptions bool]"} -} - --// from line 7999 +-// from line 8297 -func (t Or_ServerCapabilities_documentHighlightProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DocumentHighlightOptions: @@ -51250,7 +57238,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DocumentHighlightOptions bool]"} -} - --// from line 8129 +-// from line 8427 -func (t Or_ServerCapabilities_documentRangeFormattingProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DocumentRangeFormattingOptions: @@ -51281,7 +57269,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DocumentRangeFormattingOptions bool]"} -} - --// from line 8017 +-// from line 8315 -func (t Or_ServerCapabilities_documentSymbolProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case DocumentSymbolOptions: @@ -51312,7 +57300,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [DocumentSymbolOptions bool]"} -} - --// from line 8174 +-// from line 8472 -func (t Or_ServerCapabilities_foldingRangeProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case FoldingRangeOptions: @@ -51350,7 +57338,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [FoldingRangeOptions FoldingRangeRegistrationOptions bool]"} -} - --// from line 7870 +-// from line 8168 -func (t Or_ServerCapabilities_hoverProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case HoverOptions: @@ -51381,7 +57369,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [HoverOptions bool]"} -} - --// from line 7959 +-// from line 8257 -func (t Or_ServerCapabilities_implementationProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case ImplementationOptions: @@ -51419,7 +57407,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [ImplementationOptions ImplementationRegistrationOptions bool]"} -} - --// from line 8361 +-// from line 8659 -func (t Or_ServerCapabilities_inlayHintProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case InlayHintOptions: @@ -51457,7 +57445,38 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [InlayHintOptions InlayHintRegistrationOptions bool]"} -} - --// from line 8338 +-// from line 8701 +-func (t Or_ServerCapabilities_inlineCompletionProvider) MarshalJSON() ([]byte, error) { +- switch x := t.Value.(type) { +- case InlineCompletionOptions: +- return json.Marshal(x) +- case bool: +- return json.Marshal(x) +- case nil: +- return []byte("null"), nil +- } +- return nil, fmt.Errorf("type %T not one of [InlineCompletionOptions bool]", t) +-} +- +-func (t *Or_ServerCapabilities_inlineCompletionProvider) UnmarshalJSON(x []byte) error { +- if string(x) == "null" { +- t.Value = nil +- return nil +- } +- var h0 InlineCompletionOptions +- if err := json.Unmarshal(x, &h0); err == nil { +- t.Value = h0 +- return nil +- } +- var h1 bool +- if err := json.Unmarshal(x, &h1); err == nil { +- t.Value = h1 +- return nil +- } +- return &UnmarshalError{"unmarshal failed to match one of [InlineCompletionOptions bool]"} +-} +- +-// from line 8636 -func (t Or_ServerCapabilities_inlineValueProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case InlineValueOptions: @@ -51495,7 +57514,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [InlineValueOptions InlineValueRegistrationOptions bool]"} -} - --// from line 8250 +-// from line 8548 -func (t Or_ServerCapabilities_linkedEditingRangeProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case LinkedEditingRangeOptions: @@ -51533,7 +57552,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [LinkedEditingRangeOptions LinkedEditingRangeRegistrationOptions bool]"} -} - --// from line 8292 +-// from line 8590 -func (t Or_ServerCapabilities_monikerProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case MonikerOptions: @@ -51571,7 +57590,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [MonikerOptions MonikerRegistrationOptions bool]"} -} - --// from line 7842 +-// from line 8140 -func (t Or_ServerCapabilities_notebookDocumentSync) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case NotebookDocumentSyncOptions: @@ -51602,7 +57621,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [NotebookDocumentSyncOptions NotebookDocumentSyncRegistrationOptions]"} -} - --// from line 7981 +-// from line 8279 -func (t Or_ServerCapabilities_referencesProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case ReferenceOptions: @@ -51633,7 +57652,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [ReferenceOptions bool]"} -} - --// from line 8156 +-// from line 8454 -func (t Or_ServerCapabilities_renameProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case RenameOptions: @@ -51664,7 +57683,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [RenameOptions bool]"} -} - --// from line 8196 +-// from line 8494 -func (t Or_ServerCapabilities_selectionRangeProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case SelectionRangeOptions: @@ -51702,7 +57721,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [SelectionRangeOptions SelectionRangeRegistrationOptions bool]"} -} - --// from line 8273 +-// from line 8571 -func (t Or_ServerCapabilities_semanticTokensProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case SemanticTokensOptions: @@ -51733,7 +57752,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [SemanticTokensOptions SemanticTokensRegistrationOptions]"} -} - --// from line 7824 +-// from line 8122 -func (t Or_ServerCapabilities_textDocumentSync) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case TextDocumentSyncKind: @@ -51764,7 +57783,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [TextDocumentSyncKind TextDocumentSyncOptions]"} -} - --// from line 7937 +-// from line 8235 -func (t Or_ServerCapabilities_typeDefinitionProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case TypeDefinitionOptions: @@ -51802,7 +57821,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [TypeDefinitionOptions TypeDefinitionRegistrationOptions bool]"} -} - --// from line 8315 +-// from line 8613 -func (t Or_ServerCapabilities_typeHierarchyProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case TypeHierarchyOptions: @@ -51840,7 +57859,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [TypeHierarchyOptions TypeHierarchyRegistrationOptions bool]"} -} - --// from line 8093 +-// from line 8391 -func (t Or_ServerCapabilities_workspaceSymbolProvider) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case WorkspaceSymbolOptions: @@ -51871,7 +57890,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [WorkspaceSymbolOptions bool]"} -} - --// from line 8841 +-// from line 9159 -func (t Or_SignatureInformation_documentation) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case MarkupContent: @@ -51902,7 +57921,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [MarkupContent string]"} -} - --// from line 6692 +-// from line 6928 -func (t Or_TextDocumentEdit_edits_Elem) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case AnnotatedTextEdit: @@ -51933,7 +57952,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [AnnotatedTextEdit TextEdit]"} -} - --// from line 9777 +-// from line 10131 -func (t Or_TextDocumentSyncOptions_save) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case SaveOptions: @@ -51964,7 +57983,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [SaveOptions bool]"} -} - --// from line 13986 +-// from line 14401 -func (t Or_WorkspaceDocumentDiagnosticReport) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case WorkspaceFullDocumentDiagnosticReport: @@ -51995,7 +58014,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ - return &UnmarshalError{"unmarshal failed to match one of [WorkspaceFullDocumentDiagnosticReport WorkspaceUnchangedDocumentDiagnosticReport]"} -} - --// from line 3219 +-// from line 3292 -func (t Or_WorkspaceEdit_documentChanges_Elem) MarshalJSON() ([]byte, error) { - switch x := t.Value.(type) { - case CreateFile: @@ -52073,7 +58092,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsjson.go b/gopls/internal/lsp/protocol/ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/protocol/tsprotocol.go --- a/gopls/internal/lsp/protocol/tsprotocol.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/tsprotocol.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5450 +0,0 @@ +@@ -1,5642 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -52082,8 +58101,8 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -package protocol - --// Code generated from protocol/metaModel.json at ref release/protocol/3.17.3-next.6 (hash 56c23c557e3568a9f56f42435fd5a80f9458957f). --// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.3-next.6/protocol/metaModel.json +-// Code generated from protocol/metaModel.json at ref release/protocol/3.17.4-next.2 (hash 184c8a7f010d335582f24337fe182baa6f2fccdd). +-// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.4-next.2/protocol/metaModel.json -// LSP metaData.version = 3.17.0. - -import "encoding/json" @@ -52091,14 +58110,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A special text edit with an additional change annotation. -// -// @since 3.16.0. --type AnnotatedTextEdit struct { // line 9372 +-type AnnotatedTextEdit struct { - // The actual identifier of the change annotation - AnnotationID ChangeAnnotationIdentifier `json:"annotationId"` - TextEdit -} - --// The parameters passed via a apply workspace edit request. --type ApplyWorkspaceEditParams struct { // line 5984 +-// The parameters passed via an apply workspace edit request. +-type ApplyWorkspaceEditParams struct { - // An optional label of the workspace edit. This label is - // presented in the user interface for example on an undo - // stack to undo the workspace edit. @@ -52110,7 +58129,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The result returned from the apply workspace edit request. -// -// @since 3.17 renamed from ApplyWorkspaceEditResponse --type ApplyWorkspaceEditResult struct { // line 6007 +-type ApplyWorkspaceEditResult struct { - // Indicates whether the edit was applied or not. - Applied bool `json:"applied"` - // An optional textual description for why the edit was not applied. @@ -52124,7 +58143,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// A base for all symbol information. --type BaseSymbolInformation struct { // line 8966 +-type BaseSymbolInformation struct { - // The name of this symbol. - Name string `json:"name"` - // The kind of this symbol. @@ -52141,7 +58160,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type CallHierarchyClientCapabilities struct { // line 12141 +-type CallHierarchyClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` - // return value for the corresponding server capability as well. @@ -52151,7 +58170,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Represents an incoming call, e.g. a caller of a method or constructor. -// -// @since 3.16.0 --type CallHierarchyIncomingCall struct { // line 2779 +-type CallHierarchyIncomingCall struct { - // The item that makes the call. - From CallHierarchyItem `json:"from"` - // The ranges at which the calls appear. This is relative to the caller @@ -52162,7 +58181,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The parameter of a `callHierarchy/incomingCalls` request. -// -// @since 3.16.0 --type CallHierarchyIncomingCallsParams struct { // line 2755 +-type CallHierarchyIncomingCallsParams struct { - Item CallHierarchyItem `json:"item"` - WorkDoneProgressParams - PartialResultParams @@ -52172,7 +58191,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// of call hierarchy. -// -// @since 3.16.0 --type CallHierarchyItem struct { // line 2656 +-type CallHierarchyItem struct { - // The name of this item. - Name string `json:"name"` - // The kind of this item. @@ -52196,14 +58215,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Call hierarchy options used during static registration. -// -// @since 3.16.0 --type CallHierarchyOptions struct { // line 6534 +-type CallHierarchyOptions struct { - WorkDoneProgressOptions -} - -// Represents an outgoing call, e.g. calling a getter from a method or a method from a constructor etc. -// -// @since 3.16.0 --type CallHierarchyOutgoingCall struct { // line 2829 +-type CallHierarchyOutgoingCall struct { - // The item that is called. - To CallHierarchyItem `json:"to"` - // The range at which this item is called. This is the range relative to the caller, e.g the item @@ -52215,7 +58234,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The parameter of a `callHierarchy/outgoingCalls` request. -// -// @since 3.16.0 --type CallHierarchyOutgoingCallsParams struct { // line 2805 +-type CallHierarchyOutgoingCallsParams struct { - Item CallHierarchyItem `json:"item"` - WorkDoneProgressParams - PartialResultParams @@ -52224,7 +58243,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The parameter of a `textDocument/prepareCallHierarchy` request. -// -// @since 3.16.0 --type CallHierarchyPrepareParams struct { // line 2638 +-type CallHierarchyPrepareParams struct { - TextDocumentPositionParams - WorkDoneProgressParams -} @@ -52232,12 +58251,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Call hierarchy options used during static or dynamic registration. -// -// @since 3.16.0 --type CallHierarchyRegistrationOptions struct { // line 2733 +-type CallHierarchyRegistrationOptions struct { - TextDocumentRegistrationOptions - CallHierarchyOptions - StaticRegistrationOptions -} --type CancelParams struct { // line 6179 +-type CancelParams struct { - // The request id to cancel. - ID interface{} `json:"id"` -} @@ -52245,7 +58264,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Additional information that describes document changes. -// -// @since 3.16.0 --type ChangeAnnotation struct { // line 6831 +-type ChangeAnnotation struct { - // A human-readable string describing the actual change. The string - // is rendered prominent in the user interface. - Label string `json:"label"` @@ -52258,9 +58277,9 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// An identifier to refer to a change annotation stored with a workspace edit. --type ChangeAnnotationIdentifier = string // (alias) line 13976 +-type ChangeAnnotationIdentifier = string // (alias) line 14391 -// Defines the capabilities provided by the client. --type ClientCapabilities struct { // line 9674 +-type ClientCapabilities struct { - // Workspace specific client capabilities. - Workspace WorkspaceClientCapabilities `json:"workspace,omitempty"` - // Text document specific client capabilities. @@ -52283,7 +58302,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// to refactor code. -// -// A CodeAction must set either `edit` and/or a `command`. If both are supplied, the `edit` is applied first, then the `command` is executed. --type CodeAction struct { // line 5382 +-type CodeAction struct { - // A short, human-readable, title for this code action. - Title string `json:"title"` - // The kind of the code action. @@ -52330,7 +58349,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The Client Capabilities of a {@link CodeActionRequest}. --type CodeActionClientCapabilities struct { // line 11721 +-type CodeActionClientCapabilities struct { - // Whether code action supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // The client support code action literals of type `CodeAction` as a valid @@ -52370,7 +58389,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// Contains additional diagnostic information about the context in which -// a {@link CodeActionProvider.provideCodeActions code action} is run. --type CodeActionContext struct { // line 9032 +-type CodeActionContext struct { - // An array of diagnostics known on the client side overlapping the range provided to the - // `textDocument/codeAction` request. They are provided so that the server knows which - // errors are currently presented to the user for the given range. There is no guarantee @@ -52389,9 +58408,10 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// A set of predefined code action kinds --type CodeActionKind string // line 13326 +-type CodeActionKind string +- -// Provider options for a {@link CodeActionRequest}. --type CodeActionOptions struct { // line 9071 +-type CodeActionOptions struct { - // CodeActionKinds that this server may return. - // - // The list of kinds may be generic, such as `CodeActionKind.Refactor`, or the server @@ -52406,7 +58426,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The parameters of a {@link CodeActionRequest}. --type CodeActionParams struct { // line 5308 +-type CodeActionParams struct { - // The document in which the command was invoked. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The range for which the command was invoked. @@ -52418,7 +58438,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link CodeActionRequest}. --type CodeActionRegistrationOptions struct { // line 5476 +-type CodeActionRegistrationOptions struct { - TextDocumentRegistrationOptions - CodeActionOptions -} @@ -52426,11 +58446,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The reason why code actions were requested. -// -// @since 3.17.0 --type CodeActionTriggerKind uint32 // line 13606 +-type CodeActionTriggerKind uint32 +- -// Structure to capture a description for an error code. -// -// @since 3.16.0 --type CodeDescription struct { // line 10026 +-type CodeDescription struct { - // An URI to open with more information about the diagnostic error. - Href URI `json:"href"` -} @@ -52440,7 +58461,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// -// A code lens is _unresolved_ when no command is associated to it. For performance -// reasons the creation of a code lens and resolving should be done in two stages. --type CodeLens struct { // line 5599 +-type CodeLens struct { - // The range in which this code lens is valid. Should only span a single line. - Range Range `json:"range"` - // The command this code lens represents. @@ -52452,20 +58473,20 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The client capabilities of a {@link CodeLensRequest}. --type CodeLensClientCapabilities struct { // line 11835 +-type CodeLensClientCapabilities struct { - // Whether code lens supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// Code Lens provider options of a {@link CodeLensRequest}. --type CodeLensOptions struct { // line 9127 +-type CodeLensOptions struct { - // Code lens has a resolve provider as well. - ResolveProvider bool `json:"resolveProvider,omitempty"` - WorkDoneProgressOptions -} - -// The parameters of a {@link CodeLensRequest}. --type CodeLensParams struct { // line 5575 +-type CodeLensParams struct { - // The document to request code lens for. - TextDocument TextDocumentIdentifier `json:"textDocument"` - WorkDoneProgressParams @@ -52473,13 +58494,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link CodeLensRequest}. --type CodeLensRegistrationOptions struct { // line 5631 +-type CodeLensRegistrationOptions struct { - TextDocumentRegistrationOptions - CodeLensOptions -} - -// @since 3.16.0 --type CodeLensWorkspaceClientCapabilities struct { // line 10993 +-type CodeLensWorkspaceClientCapabilities struct { - // Whether the client implementation supports a refresh request sent from the - // server to the client. - // @@ -52491,7 +58512,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Represents a color in RGBA space. --type Color struct { // line 6433 +-type Color struct { - // The red component of this color in the range [0-1]. - Red float64 `json:"red"` - // The green component of this color in the range [0-1]. @@ -52503,13 +58524,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Represents a color range from a document. --type ColorInformation struct { // line 2239 +-type ColorInformation struct { - // The range in the document where this color appears. - Range Range `json:"range"` - // The actual color value for this color range. - Color Color `json:"color"` -} --type ColorPresentation struct { // line 2321 +-type ColorPresentation struct { - // The label of this color presentation. It will be shown on the color - // picker header. By default this is also the text that is inserted when selecting - // this color presentation. @@ -52524,7 +58545,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Parameters for a {@link ColorPresentationRequest}. --type ColorPresentationParams struct { // line 2281 +-type ColorPresentationParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The color to request presentations for. @@ -52539,7 +58560,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// will be used to represent a command in the UI and, optionally, -// an array of arguments which will be passed to the command handler -// function when invoked. --type Command struct { // line 5348 +-type Command struct { - // Title of the command, like `save`. - Title string `json:"title"` - // The identifier of the actual command handler. @@ -52550,7 +58571,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Completion client capabilities --type CompletionClientCapabilities struct { // line 11168 +-type CompletionClientCapabilities struct { - // Whether completion supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // The client supports the following `CompletionItem` specific @@ -52574,7 +58595,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Contains additional information about the context in which a completion request is triggered. --type CompletionContext struct { // line 8628 +-type CompletionContext struct { - // How the completion was triggered. - TriggerKind CompletionTriggerKind `json:"triggerKind"` - // The trigger character (a single character) that has trigger code complete. @@ -52584,7 +58605,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// A completion item represents a text snippet that is -// proposed to complete text that is being typed. --type CompletionItem struct { // line 4528 +-type CompletionItem struct { - // The label of this completion item. - // - // The label property is also by default the text that @@ -52705,11 +58726,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The kind of a completion entry. --type CompletionItemKind uint32 // line 13134 +-type CompletionItemKind uint32 +- -// Additional details for a completion item label. -// -// @since 3.17.0 --type CompletionItemLabelDetails struct { // line 8651 +-type CompletionItemLabelDetails struct { - // An optional string which is rendered less prominently directly after {@link CompletionItem.label label}, - // without any spacing. Should be used for function signatures and type annotations. - Detail string `json:"detail,omitempty"` @@ -52722,10 +58744,11 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// item. -// -// @since 3.15.0 --type CompletionItemTag uint32 // line 13244 +-type CompletionItemTag uint32 +- -// Represents a collection of {@link CompletionItem completion items} to be presented -// in the editor. --type CompletionList struct { // line 4737 +-type CompletionList struct { - // This list it not complete. Further typing results in recomputing this list. - // - // Recomputed lists have all their items replaced (not appended) in the @@ -52750,7 +58773,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Completion options. --type CompletionOptions struct { // line 8707 +-type CompletionOptions struct { - // Most tools trigger completion request automatically without explicitly requesting - // it using a keyboard shortcut (e.g. Ctrl+Space). Typically they do so when the user - // starts to type an identifier. For example if the user types `c` in a JavaScript file @@ -52781,7 +58804,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Completion parameters --type CompletionParams struct { // line 4497 +-type CompletionParams struct { - // The completion context. This is only available it the client specifies - // to send this using the client capability `textDocument.completion.contextSupport === true` - Context CompletionContext `json:"context,omitempty"` @@ -52791,14 +58814,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link CompletionRequest}. --type CompletionRegistrationOptions struct { // line 4854 +-type CompletionRegistrationOptions struct { - TextDocumentRegistrationOptions - CompletionOptions -} - -// How a completion was triggered --type CompletionTriggerKind uint32 // line 13555 --type ConfigurationItem struct { // line 6396 +-type CompletionTriggerKind uint32 +-type ConfigurationItem struct { - // The scope to get the configuration section for. - ScopeURI string `json:"scopeUri,omitempty"` - // The configuration section asked for. @@ -52806,12 +58829,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The parameters of a configuration request. --type ConfigurationParams struct { // line 2199 +-type ConfigurationParams struct { - Items []ConfigurationItem `json:"items"` -} - -// Create file operation. --type CreateFile struct { // line 6712 +-type CreateFile struct { - // A create - Kind string `json:"kind"` - // The resource to create. @@ -52822,7 +58845,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Options to create a file. --type CreateFileOptions struct { // line 9417 +-type CreateFileOptions struct { - // Overwrite existing file. Overwrite wins over `ignoreIfExists` - Overwrite bool `json:"overwrite,omitempty"` - // Ignore if exists. @@ -52833,15 +58856,15 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// files. -// -// @since 3.16.0 --type CreateFilesParams struct { // line 3175 +-type CreateFilesParams struct { - // An array of all files/folders created in this operation. - Files []FileCreate `json:"files"` -} - -// The declaration of a symbol representation as one or many {@link Location locations}. --type Declaration = []Location // (alias) line 13833 +-type Declaration = []Location // (alias) line 14248 -// @since 3.14.0 --type DeclarationClientCapabilities struct { // line 11509 +-type DeclarationClientCapabilities struct { - // Whether declaration supports dynamic registration. If this is set to `true` - // the client supports the new `DeclarationRegistrationOptions` return value - // for the corresponding server capability as well. @@ -52857,16 +58880,16 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// -// Servers should prefer returning `DeclarationLink` over `Declaration` if supported -// by the client. --type DeclarationLink = LocationLink // (alias) line 13853 --type DeclarationOptions struct { // line 6491 +-type DeclarationLink = LocationLink // (alias) line 14268 +-type DeclarationOptions struct { - WorkDoneProgressOptions -} --type DeclarationParams struct { // line 2494 +-type DeclarationParams struct { - TextDocumentPositionParams - WorkDoneProgressParams - PartialResultParams -} --type DeclarationRegistrationOptions struct { // line 2514 +-type DeclarationRegistrationOptions struct { - DeclarationOptions - TextDocumentRegistrationOptions - StaticRegistrationOptions @@ -52878,9 +58901,9 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// -// Servers should prefer returning `DefinitionLink` over `Definition` if supported -// by the client. --type Definition = Or_Definition // (alias) line 13751 +-type Definition = Or_Definition // (alias) line 14166 -// Client Capabilities for a {@link DefinitionRequest}. --type DefinitionClientCapabilities struct { // line 11534 +-type DefinitionClientCapabilities struct { - // Whether definition supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // The client supports additional metadata in the form of definition links. @@ -52893,27 +58916,27 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// -// Provides additional metadata over normal {@link Location location} definitions, including the range of -// the defining symbol --type DefinitionLink = LocationLink // (alias) line 13771 +-type DefinitionLink = LocationLink // (alias) line 14186 -// Server Capabilities for a {@link DefinitionRequest}. --type DefinitionOptions struct { // line 8919 +-type DefinitionOptions struct { - WorkDoneProgressOptions -} - -// Parameters for a {@link DefinitionRequest}. --type DefinitionParams struct { // line 5018 +-type DefinitionParams struct { - TextDocumentPositionParams - WorkDoneProgressParams - PartialResultParams -} - -// Registration options for a {@link DefinitionRequest}. --type DefinitionRegistrationOptions struct { // line 5039 +-type DefinitionRegistrationOptions struct { - TextDocumentRegistrationOptions - DefinitionOptions -} - -// Delete file operation --type DeleteFile struct { // line 6794 +-type DeleteFile struct { - // A delete - Kind string `json:"kind"` - // The file to delete. @@ -52924,7 +58947,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Delete file options --type DeleteFileOptions struct { // line 9465 +-type DeleteFileOptions struct { - // Delete the content recursively if a folder is denoted. - Recursive bool `json:"recursive,omitempty"` - // Ignore the operation if the file doesn't exist. @@ -52935,14 +58958,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// files. -// -// @since 3.16.0 --type DeleteFilesParams struct { // line 3300 +-type DeleteFilesParams struct { - // An array of all files/folders deleted in this operation. - Files []FileDelete `json:"files"` -} - -// Represents a diagnostic, such as a compiler error or warning. Diagnostic objects -// are only valid in the scope of a resource. --type Diagnostic struct { // line 8525 +-type Diagnostic struct { - // The range at which the message applies - Range Range `json:"range"` - // The diagnostic's severity. Can be omitted. If omitted it is up to the @@ -52972,13 +58995,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // notification and `textDocument/codeAction` request. - // - // @since 3.16.0 -- Data interface{} `json:"data,omitempty"` +- Data *json.RawMessage `json:"data,omitempty"` -} - -// Client capabilities specific to diagnostic pull requests. -// -// @since 3.17.0 --type DiagnosticClientCapabilities struct { // line 12408 +-type DiagnosticClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` - // return value for the corresponding server capability as well. @@ -52990,7 +59013,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Diagnostic options. -// -// @since 3.17.0 --type DiagnosticOptions struct { // line 7293 +-type DiagnosticOptions struct { - // An optional identifier under which the diagnostics are - // managed by the client. - Identifier string `json:"identifier,omitempty"` @@ -53007,7 +59030,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Diagnostic registration options. -// -// @since 3.17.0 --type DiagnosticRegistrationOptions struct { // line 3855 +-type DiagnosticRegistrationOptions struct { - TextDocumentRegistrationOptions - DiagnosticOptions - StaticRegistrationOptions @@ -53016,7 +59039,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Represents a related message and source code location for a diagnostic. This should be -// used to point to code locations that cause or related to a diagnostics, e.g when duplicating -// a symbol in a scope. --type DiagnosticRelatedInformation struct { // line 10041 +-type DiagnosticRelatedInformation struct { - // The location of this related diagnostic information. - Location Location `json:"location"` - // The message of this related diagnostic information. @@ -53026,20 +59049,22 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Cancellation data returned from a diagnostic request. -// -// @since 3.17.0 --type DiagnosticServerCancellationData struct { // line 3841 +-type DiagnosticServerCancellationData struct { - RetriggerRequest bool `json:"retriggerRequest"` -} - -// The diagnostic's severity. --type DiagnosticSeverity uint32 // line 13504 +-type DiagnosticSeverity uint32 +- -// The diagnostic tags. -// -// @since 3.15.0 --type DiagnosticTag uint32 // line 13534 +-type DiagnosticTag uint32 +- -// Workspace client capabilities specific to diagnostic pull requests. -// -// @since 3.17.0 --type DiagnosticWorkspaceClientCapabilities struct { // line 11111 +-type DiagnosticWorkspaceClientCapabilities struct { - // Whether the client implementation supports a refresh request sent from - // the server to the client. - // @@ -53049,24 +59074,24 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // change that requires such a calculation. - RefreshSupport bool `json:"refreshSupport,omitempty"` -} --type DidChangeConfigurationClientCapabilities struct { // line 10837 +-type DidChangeConfigurationClientCapabilities struct { - // Did change configuration notification supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// The parameters of a change configuration notification. --type DidChangeConfigurationParams struct { // line 4144 +-type DidChangeConfigurationParams struct { - // The actual changed settings - Settings interface{} `json:"settings"` -} --type DidChangeConfigurationRegistrationOptions struct { // line 4158 +-type DidChangeConfigurationRegistrationOptions struct { - Section *OrPSection_workspace_didChangeConfiguration `json:"section,omitempty"` -} - -// The params sent in a change notebook document notification. -// -// @since 3.17.0 --type DidChangeNotebookDocumentParams struct { // line 3974 +-type DidChangeNotebookDocumentParams struct { - // The notebook document that did change. The version number points - // to the version after all provided changes have been applied. If - // only the text document content of a cell changes the notebook version @@ -53090,7 +59115,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The change text document notification's parameters. --type DidChangeTextDocumentParams struct { // line 4287 +-type DidChangeTextDocumentParams struct { - // The document that did change. The version number points - // to the version after all provided content changes have - // been applied. @@ -53109,7 +59134,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // you receive them. - ContentChanges []TextDocumentContentChangeEvent `json:"contentChanges"` -} --type DidChangeWatchedFilesClientCapabilities struct { // line 10851 +-type DidChangeWatchedFilesClientCapabilities struct { - // Did change watched files notification supports dynamic registration. Please note - // that the current protocol doesn't support static configuration for file changes - // from the server side. @@ -53122,19 +59147,19 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The watched files change notification's parameters. --type DidChangeWatchedFilesParams struct { // line 4428 +-type DidChangeWatchedFilesParams struct { - // The actual file events. - Changes []FileEvent `json:"changes"` -} - -// Describe options to be used when registered for text document change events. --type DidChangeWatchedFilesRegistrationOptions struct { // line 4445 +-type DidChangeWatchedFilesRegistrationOptions struct { - // The watchers to register. - Watchers []FileSystemWatcher `json:"watchers"` -} - -// The parameters of a `workspace/didChangeWorkspaceFolders` notification. --type DidChangeWorkspaceFoldersParams struct { // line 2185 +-type DidChangeWorkspaceFoldersParams struct { - // The actual workspace folder change event. - Event WorkspaceFoldersChangeEvent `json:"event"` -} @@ -53142,7 +59167,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The params sent in a close notebook document notification. -// -// @since 3.17.0 --type DidCloseNotebookDocumentParams struct { // line 4012 +-type DidCloseNotebookDocumentParams struct { - // The notebook document that got closed. - NotebookDocument NotebookDocumentIdentifier `json:"notebookDocument"` - // The text documents that represent the content @@ -53151,7 +59176,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The parameters sent in a close text document notification --type DidCloseTextDocumentParams struct { // line 4332 +-type DidCloseTextDocumentParams struct { - // The document that was closed. - TextDocument TextDocumentIdentifier `json:"textDocument"` -} @@ -53159,7 +59184,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The params sent in an open notebook document notification. -// -// @since 3.17.0 --type DidOpenNotebookDocumentParams struct { // line 3948 +-type DidOpenNotebookDocumentParams struct { - // The notebook document that got opened. - NotebookDocument NotebookDocument `json:"notebookDocument"` - // The text documents that represent the content @@ -53168,7 +59193,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The parameters sent in an open text document notification --type DidOpenTextDocumentParams struct { // line 4273 +-type DidOpenTextDocumentParams struct { - // The document that was opened. - TextDocument TextDocumentItem `json:"textDocument"` -} @@ -53176,37 +59201,37 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The params sent in a save notebook document notification. -// -// @since 3.17.0 --type DidSaveNotebookDocumentParams struct { // line 3997 +-type DidSaveNotebookDocumentParams struct { - // The notebook document that got saved. - NotebookDocument NotebookDocumentIdentifier `json:"notebookDocument"` -} - -// The parameters sent in a save text document notification --type DidSaveTextDocumentParams struct { // line 4346 +-type DidSaveTextDocumentParams struct { - // The document that was saved. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // Optional the content when saved. Depends on the includeText value - // when the save notification was requested. - Text *string `json:"text,omitempty"` -} --type DocumentColorClientCapabilities struct { // line 11875 +-type DocumentColorClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `DocumentColorRegistrationOptions` return value - // for the corresponding server capability as well. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} --type DocumentColorOptions struct { // line 6471 +-type DocumentColorOptions struct { - WorkDoneProgressOptions -} - -// Parameters for a {@link DocumentColorRequest}. --type DocumentColorParams struct { // line 2215 +-type DocumentColorParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - WorkDoneProgressParams - PartialResultParams -} --type DocumentColorRegistrationOptions struct { // line 2261 +-type DocumentColorRegistrationOptions struct { - TextDocumentRegistrationOptions - DocumentColorOptions - StaticRegistrationOptions @@ -53215,7 +59240,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Parameters of the document diagnostic request. -// -// @since 3.17.0 --type DocumentDiagnosticParams struct { // line 3768 +-type DocumentDiagnosticParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The additional identifier provided during registration. @@ -53229,11 +59254,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The document diagnostic report kinds. -// -// @since 3.17.0 --type DocumentDiagnosticReportKind string // line 12722 +-type DocumentDiagnosticReportKind string +- -// A partial result for a document diagnostic report. -// -// @since 3.17.0 --type DocumentDiagnosticReportPartialResult struct { // line 3811 +-type DocumentDiagnosticReportPartialResult struct { - RelatedDocuments map[DocumentURI]interface{} `json:"relatedDocuments"` -} - @@ -53241,20 +59267,20 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// a notebook cell document. -// -// @since 3.17.0 - proposed support for NotebookCellTextDocumentFilter. --type DocumentFilter = Or_DocumentFilter // (alias) line 14093 +-type DocumentFilter = Or_DocumentFilter // (alias) line 14508 -// Client capabilities of a {@link DocumentFormattingRequest}. --type DocumentFormattingClientCapabilities struct { // line 11889 +-type DocumentFormattingClientCapabilities struct { - // Whether formatting supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// Provider options for a {@link DocumentFormattingRequest}. --type DocumentFormattingOptions struct { // line 9221 +-type DocumentFormattingOptions struct { - WorkDoneProgressOptions -} - -// The parameters of a {@link DocumentFormattingRequest}. --type DocumentFormattingParams struct { // line 5727 +-type DocumentFormattingParams struct { - // The document to format. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The format options. @@ -53263,7 +59289,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link DocumentFormattingRequest}. --type DocumentFormattingRegistrationOptions struct { // line 5755 +-type DocumentFormattingRegistrationOptions struct { - TextDocumentRegistrationOptions - DocumentFormattingOptions -} @@ -53271,7 +59297,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A document highlight is a range inside a text document which deserves -// special attention. Usually a document highlight is visualized by changing -// the background color of its range. --type DocumentHighlight struct { // line 5119 +-type DocumentHighlight struct { - // The range this highlight applies to. - Range Range `json:"range"` - // The highlight kind, default is {@link DocumentHighlightKind.Text text}. @@ -53279,38 +59305,39 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Client Capabilities for a {@link DocumentHighlightRequest}. --type DocumentHighlightClientCapabilities struct { // line 11624 +-type DocumentHighlightClientCapabilities struct { - // Whether document highlight supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// A document highlight kind. --type DocumentHighlightKind uint32 // line 13301 +-type DocumentHighlightKind uint32 +- -// Provider options for a {@link DocumentHighlightRequest}. --type DocumentHighlightOptions struct { // line 8955 +-type DocumentHighlightOptions struct { - WorkDoneProgressOptions -} - -// Parameters for a {@link DocumentHighlightRequest}. --type DocumentHighlightParams struct { // line 5098 +-type DocumentHighlightParams struct { - TextDocumentPositionParams - WorkDoneProgressParams - PartialResultParams -} - -// Registration options for a {@link DocumentHighlightRequest}. --type DocumentHighlightRegistrationOptions struct { // line 5142 +-type DocumentHighlightRegistrationOptions struct { - TextDocumentRegistrationOptions - DocumentHighlightOptions -} - -// A document link is a range in a text document that links to an internal or external resource, like another -// text document or a web site. --type DocumentLink struct { // line 5670 +-type DocumentLink struct { - // The range this link applies to. - Range Range `json:"range"` - // The uri this link points to. If missing a resolve request is sent later. -- Target string `json:"target,omitempty"` +- Target *URI `json:"target,omitempty"` - // The tooltip text when you hover over this link. - // - // If a tooltip is provided, is will be displayed in a string that includes instructions on how to @@ -53325,7 +59352,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The client capabilities of a {@link DocumentLinkRequest}. --type DocumentLinkClientCapabilities struct { // line 11850 +-type DocumentLinkClientCapabilities struct { - // Whether document link supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // Whether the client supports the `tooltip` property on `DocumentLink`. @@ -53335,14 +59362,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Provider options for a {@link DocumentLinkRequest}. --type DocumentLinkOptions struct { // line 9148 +-type DocumentLinkOptions struct { - // Document links have a resolve provider as well. - ResolveProvider bool `json:"resolveProvider,omitempty"` - WorkDoneProgressOptions -} - -// The parameters of a {@link DocumentLinkRequest}. --type DocumentLinkParams struct { // line 5646 +-type DocumentLinkParams struct { - // The document to provide document links for. - TextDocument TextDocumentIdentifier `json:"textDocument"` - WorkDoneProgressParams @@ -53350,19 +59377,19 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link DocumentLinkRequest}. --type DocumentLinkRegistrationOptions struct { // line 5712 +-type DocumentLinkRegistrationOptions struct { - TextDocumentRegistrationOptions - DocumentLinkOptions -} - -// Client capabilities of a {@link DocumentOnTypeFormattingRequest}. --type DocumentOnTypeFormattingClientCapabilities struct { // line 11919 +-type DocumentOnTypeFormattingClientCapabilities struct { - // Whether on type formatting supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// Provider options for a {@link DocumentOnTypeFormattingRequest}. --type DocumentOnTypeFormattingOptions struct { // line 9243 +-type DocumentOnTypeFormattingOptions struct { - // A character on which formatting should be triggered, like `{`. - FirstTriggerCharacter string `json:"firstTriggerCharacter"` - // More trigger characters. @@ -53370,7 +59397,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The parameters of a {@link DocumentOnTypeFormattingRequest}. --type DocumentOnTypeFormattingParams struct { // line 5821 +-type DocumentOnTypeFormattingParams struct { - // The document to format. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The position around which the on type formatting should happen. @@ -53387,24 +59414,34 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link DocumentOnTypeFormattingRequest}. --type DocumentOnTypeFormattingRegistrationOptions struct { // line 5859 +-type DocumentOnTypeFormattingRegistrationOptions struct { - TextDocumentRegistrationOptions - DocumentOnTypeFormattingOptions -} - -// Client capabilities of a {@link DocumentRangeFormattingRequest}. --type DocumentRangeFormattingClientCapabilities struct { // line 11904 +-type DocumentRangeFormattingClientCapabilities struct { - // Whether range formatting supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +- // Whether the client supports formatting multiple ranges at once. +- // +- // @since 3.18.0 +- // @proposed +- RangesSupport bool `json:"rangesSupport,omitempty"` -} - -// Provider options for a {@link DocumentRangeFormattingRequest}. --type DocumentRangeFormattingOptions struct { // line 9232 +-type DocumentRangeFormattingOptions struct { +- // Whether the server supports formatting multiple ranges at once. +- // +- // @since 3.18.0 +- // @proposed +- RangesSupport bool `json:"rangesSupport,omitempty"` - WorkDoneProgressOptions -} - -// The parameters of a {@link DocumentRangeFormattingRequest}. --type DocumentRangeFormattingParams struct { // line 5770 +-type DocumentRangeFormattingParams struct { - // The document to format. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The range to format @@ -53415,22 +59452,36 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link DocumentRangeFormattingRequest}. --type DocumentRangeFormattingRegistrationOptions struct { // line 5806 +-type DocumentRangeFormattingRegistrationOptions struct { - TextDocumentRegistrationOptions - DocumentRangeFormattingOptions -} - +-// The parameters of a {@link DocumentRangesFormattingRequest}. +-// +-// @since 3.18.0 +-// @proposed +-type DocumentRangesFormattingParams struct { +- // The document to format. +- TextDocument TextDocumentIdentifier `json:"textDocument"` +- // The ranges to format +- Ranges []Range `json:"ranges"` +- // The format options +- Options FormattingOptions `json:"options"` +- WorkDoneProgressParams +-} +- -// A document selector is the combination of one or many document filters. -// -// @sample `let sel:DocumentSelector = [{ language: 'typescript' }, { language: 'json', pattern: '**∕tsconfig.json' }]`; -// -// The use of a string as a document filter is deprecated @since 3.16.0. --type DocumentSelector = []DocumentFilter // (alias) line 13948 +-type DocumentSelector = []DocumentFilter // (alias) line 14363 -// Represents programming constructs like variables, classes, interfaces etc. -// that appear in a document. Document symbols can be hierarchical and they -// have two ranges: one that encloses its definition and one that points to -// its most interesting range, e.g. the range of an identifier. --type DocumentSymbol struct { // line 5211 +-type DocumentSymbol struct { - // The name of this symbol. Will be displayed in the user interface and therefore must not be - // an empty string or a string only consisting of white spaces. - Name string `json:"name"` @@ -53458,7 +59509,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Client Capabilities for a {@link DocumentSymbolRequest}. --type DocumentSymbolClientCapabilities struct { // line 11639 +-type DocumentSymbolClientCapabilities struct { - // Whether document symbol supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // Specific capabilities for the `SymbolKind` in the @@ -53480,7 +59531,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Provider options for a {@link DocumentSymbolRequest}. --type DocumentSymbolOptions struct { // line 9010 +-type DocumentSymbolOptions struct { - // A human-readable string that is shown when multiple outlines trees - // are shown for the same document. - // @@ -53490,7 +59541,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Parameters for a {@link DocumentSymbolRequest}. --type DocumentSymbolParams struct { // line 5157 +-type DocumentSymbolParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - WorkDoneProgressParams @@ -53498,29 +59549,30 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link DocumentSymbolRequest}. --type DocumentSymbolRegistrationOptions struct { // line 5293 +-type DocumentSymbolRegistrationOptions struct { - TextDocumentRegistrationOptions - DocumentSymbolOptions -} -type DocumentURI string - -// Predefined error codes. --type ErrorCodes int32 // line 12743 +-type ErrorCodes int32 +- -// The client capabilities of a {@link ExecuteCommandRequest}. --type ExecuteCommandClientCapabilities struct { // line 10962 +-type ExecuteCommandClientCapabilities struct { - // Execute command supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// The server capabilities of a {@link ExecuteCommandRequest}. --type ExecuteCommandOptions struct { // line 9291 +-type ExecuteCommandOptions struct { - // The commands to be executed on the server - Commands []string `json:"commands"` - WorkDoneProgressOptions -} - -// The parameters of a {@link ExecuteCommandRequest}. --type ExecuteCommandParams struct { // line 5941 +-type ExecuteCommandParams struct { - // The identifier of the actual command handler. - Command string `json:"command"` - // Arguments that the command should be invoked with. @@ -53529,10 +59581,10 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link ExecuteCommandRequest}. --type ExecuteCommandRegistrationOptions struct { // line 5973 +-type ExecuteCommandRegistrationOptions struct { - ExecuteCommandOptions -} --type ExecutionSummary struct { // line 10162 +-type ExecutionSummary struct { - // A strict monotonically increasing value - // indicating the execution order of a cell - // inside a notebook. @@ -53543,7 +59595,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CodeActionClientCapabilities_codeActionLiteralSupport_codeActionKind) --type FCodeActionKindPCodeActionLiteralSupport struct { // line 11742 +-type FCodeActionKindPCodeActionLiteralSupport struct { - // The code action kind values the client supports. When this - // property exists the client also guarantees that it will - // handle values outside its set gracefully and falls back @@ -53552,25 +59604,25 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CompletionList_itemDefaults_editRange_Item1) --type FEditRangePItemDefaults struct { // line 4777 +-type FEditRangePItemDefaults struct { - Insert Range `json:"insert"` - Replace Range `json:"replace"` -} - -// created for Literal (Lit_SemanticTokensClientCapabilities_requests_full_Item1) --type FFullPRequests struct { // line 12205 +-type FFullPRequests struct { - // The client will send the `textDocument/semanticTokens/full/delta` request if - // the server provides a corresponding handler. - Delta bool `json:"delta"` -} - -// created for Literal (Lit_CompletionClientCapabilities_completionItem_insertTextModeSupport) --type FInsertTextModeSupportPCompletionItem struct { // line 11295 +-type FInsertTextModeSupportPCompletionItem struct { - ValueSet []InsertTextMode `json:"valueSet"` -} - -// created for Literal (Lit_SignatureHelpClientCapabilities_signatureInformation_parameterInformation) --type FParameterInformationPSignatureInformation struct { // line 11461 +-type FParameterInformationPSignatureInformation struct { - // The client supports processing label offsets instead of a - // simple label string. - // @@ -53579,17 +59631,17 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_SemanticTokensClientCapabilities_requests_range_Item1) --type FRangePRequests struct { // line 12185 +-type FRangePRequests struct { -} - -// created for Literal (Lit_CompletionClientCapabilities_completionItem_resolveSupport) --type FResolveSupportPCompletionItem struct { // line 11271 +-type FResolveSupportPCompletionItem struct { - // The properties that a client can resolve lazily. - Properties []string `json:"properties"` -} - -// created for Literal (Lit_NotebookDocumentChangeEvent_cells_structure) --type FStructurePCells struct { // line 7487 +-type FStructurePCells struct { - // The change to the cell array. - Array NotebookCellArrayChange `json:"array"` - // Additional opened cell text documents. @@ -53599,17 +59651,19 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CompletionClientCapabilities_completionItem_tagSupport) --type FTagSupportPCompletionItem struct { // line 11237 +-type FTagSupportPCompletionItem struct { - // The tags supported by the client. - ValueSet []CompletionItemTag `json:"valueSet"` -} --type FailureHandlingKind string // line 13693 +-type FailureHandlingKind string +- -// The file event type --type FileChangeType uint32 // line 13454 +-type FileChangeType uint32 +- -// Represents information on a file/folder create. -// -// @since 3.16.0 --type FileCreate struct { // line 6662 +-type FileCreate struct { - // A file:// URI for the location of the file/folder being created. - URI string `json:"uri"` -} @@ -53617,13 +59671,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Represents information on a file/folder delete. -// -// @since 3.16.0 --type FileDelete struct { // line 6911 +-type FileDelete struct { - // A file:// URI for the location of the file/folder being deleted. - URI string `json:"uri"` -} - -// An event describing a file change. --type FileEvent struct { // line 8480 +-type FileEvent struct { - // The file's uri. - URI DocumentURI `json:"uri"` - // The change type. @@ -53636,7 +59690,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// like renaming a file in the UI. -// -// @since 3.16.0 --type FileOperationClientCapabilities struct { // line 11009 +-type FileOperationClientCapabilities struct { - // Whether the client supports dynamic registration for file requests/notifications. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // The client has support for sending didCreateFiles notifications. @@ -53657,7 +59711,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// the server is interested in receiving. -// -// @since 3.16.0 --type FileOperationFilter struct { // line 6864 +-type FileOperationFilter struct { - // A Uri scheme like `file` or `untitled`. - Scheme string `json:"scheme,omitempty"` - // The actual file operation pattern. @@ -53667,7 +59721,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Options for notifications/requests for user operations on files. -// -// @since 3.16.0 --type FileOperationOptions struct { // line 9965 +-type FileOperationOptions struct { - // The server is interested in receiving didCreateFiles notifications. - DidCreate *FileOperationRegistrationOptions `json:"didCreate,omitempty"` - // The server is interested in receiving willCreateFiles requests. @@ -53686,7 +59740,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// the server is interested in receiving. -// -// @since 3.16.0 --type FileOperationPattern struct { // line 9489 +-type FileOperationPattern struct { - // The glob pattern to match. Glob patterns can have the following syntax: - // - // - `*` to match one or more characters in a path segment @@ -53708,11 +59762,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// both. -// -// @since 3.16.0 --type FileOperationPatternKind string // line 13627 +-type FileOperationPatternKind string +- -// Matching options for the file operation pattern. -// -// @since 3.16.0 --type FileOperationPatternOptions struct { // line 10146 +-type FileOperationPatternOptions struct { - // The pattern should be matched ignoring casing. - IgnoreCase bool `json:"ignoreCase,omitempty"` -} @@ -53720,7 +59775,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The options to register for file operations. -// -// @since 3.16.0 --type FileOperationRegistrationOptions struct { // line 3264 +-type FileOperationRegistrationOptions struct { - // The actual filters. - Filters []FileOperationFilter `json:"filters"` -} @@ -53728,13 +59783,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Represents information on a file/folder rename. -// -// @since 3.16.0 --type FileRename struct { // line 6888 +-type FileRename struct { - // A file:// URI for the original location of the file/folder being renamed. - OldURI string `json:"oldUri"` - // A file:// URI for the new location of the file/folder being renamed. - NewURI string `json:"newUri"` -} --type FileSystemWatcher struct { // line 8502 +-type FileSystemWatcher struct { - // The glob pattern to watch. See {@link GlobPattern glob pattern} for more detail. - // - // @since 3.17.0 support for relative patterns. @@ -53747,7 +59802,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// Represents a folding range. To be valid, start and end line must be bigger than zero and smaller -// than the number of lines in the document. Clients are free to ignore invalid ranges. --type FoldingRange struct { // line 2415 +-type FoldingRange struct { - // The zero-based start line of the range to fold. The folded area starts after the line's last character. - // To be valid, the end must be zero or larger and smaller than the number of lines in the document. - StartLine uint32 `json:"startLine"` @@ -53769,7 +59824,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // @since 3.17.0 - CollapsedText string `json:"collapsedText,omitempty"` -} --type FoldingRangeClientCapabilities struct { // line 11978 +-type FoldingRangeClientCapabilities struct { - // Whether implementation supports dynamic registration for folding range - // providers. If this is set to `true` the client supports the new - // `FoldingRangeRegistrationOptions` return value for the corresponding @@ -53794,26 +59849,26 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// A set of predefined range kinds. --type FoldingRangeKind string // line 12815 --type FoldingRangeOptions struct { // line 6481 +-type FoldingRangeKind string +-type FoldingRangeOptions struct { - WorkDoneProgressOptions -} - -// Parameters for a {@link FoldingRangeRequest}. --type FoldingRangeParams struct { // line 2391 +-type FoldingRangeParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - WorkDoneProgressParams - PartialResultParams -} --type FoldingRangeRegistrationOptions struct { // line 2474 +-type FoldingRangeRegistrationOptions struct { - TextDocumentRegistrationOptions - FoldingRangeOptions - StaticRegistrationOptions -} - -// Value-object describing what options formatting should use. --type FormattingOptions struct { // line 9169 +-type FormattingOptions struct { - // Size of a tab in spaces. - TabSize uint32 `json:"tabSize"` - // Prefer spaces over tabs. @@ -53835,7 +59890,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A diagnostic report with a full set of problems. -// -// @since 3.17.0 --type FullDocumentDiagnosticReport struct { // line 7235 +-type FullDocumentDiagnosticReport struct { - // A full document diagnostic report. - Kind string `json:"kind"` - // An optional result id. If provided it will @@ -53849,7 +59904,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// General client capabilities. -// -// @since 3.16.0 --type GeneralClientCapabilities struct { // line 10664 +-type GeneralClientCapabilities struct { - // Client capability that signals how the client - // handles stale requests (e.g. a request - // for which the client will not process the response @@ -53889,16 +59944,16 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The glob pattern. Either a string pattern or a relative pattern. -// -// @since 3.17.0 --type GlobPattern = string // (alias) line 14127 +-type GlobPattern = string // (alias) line 14542 -// The result of a hover request. --type Hover struct { // line 4886 +-type Hover struct { - // The hover's content - Contents MarkupContent `json:"contents"` - // An optional range inside the text document that is used to - // visualize the hover, e.g. by changing the background color. - Range Range `json:"range,omitempty"` -} --type HoverClientCapabilities struct { // line 11402 +-type HoverClientCapabilities struct { - // Whether hover supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // Client supports the following content formats for the content @@ -53907,24 +59962,24 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Hover options. --type HoverOptions struct { // line 8776 +-type HoverOptions struct { - WorkDoneProgressOptions -} - -// Parameters for a {@link HoverRequest}. --type HoverParams struct { // line 4869 +-type HoverParams struct { - TextDocumentPositionParams - WorkDoneProgressParams -} - -// Registration options for a {@link HoverRequest}. --type HoverRegistrationOptions struct { // line 4925 +-type HoverRegistrationOptions struct { - TextDocumentRegistrationOptions - HoverOptions -} - -// @since 3.6.0 --type ImplementationClientCapabilities struct { // line 11583 +-type ImplementationClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `ImplementationRegistrationOptions` return value - // for the corresponding server capability as well. @@ -53934,15 +59989,15 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // @since 3.14.0 - LinkSupport bool `json:"linkSupport,omitempty"` -} --type ImplementationOptions struct { // line 6333 +-type ImplementationOptions struct { - WorkDoneProgressOptions -} --type ImplementationParams struct { // line 2063 +-type ImplementationParams struct { - TextDocumentPositionParams - WorkDoneProgressParams - PartialResultParams -} --type ImplementationRegistrationOptions struct { // line 2103 +-type ImplementationRegistrationOptions struct { - TextDocumentRegistrationOptions - ImplementationOptions - StaticRegistrationOptions @@ -53950,20 +60005,20 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// The data type of the ResponseError if the -// initialize request fails. --type InitializeError struct { // line 4126 +-type InitializeError struct { - // Indicates whether the client execute the following retry logic: - // (1) show the message provided by the ResponseError to the user - // (2) user selects retry or cancel - // (3) if user selected retry the initialize method is sent again. - Retry bool `json:"retry"` -} --type InitializeParams struct { // line 4068 +-type InitializeParams struct { - XInitializeParams - WorkspaceFoldersInitializeParams -} - -// The result returned from an initialize request. --type InitializeResult struct { // line 4082 +-type InitializeResult struct { - // The capabilities the language server provides. - Capabilities ServerCapabilities `json:"capabilities"` - // Information about the server. @@ -53971,13 +60026,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // @since 3.15.0 - ServerInfo *PServerInfoMsg_initialize `json:"serverInfo,omitempty"` -} --type InitializedParams struct { // line 4140 +-type InitializedParams struct { -} - -// Inlay hint information. -// -// @since 3.17.0 --type InlayHint struct { // line 3645 +-type InlayHint struct { - // The position of this hint. - Position Position `json:"position"` - // The label of this hint. A human readable string or an array of @@ -54016,7 +60071,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Inlay hint client capabilities. -// -// @since 3.17.0 --type InlayHintClientCapabilities struct { // line 12369 +-type InlayHintClientCapabilities struct { - // Whether inlay hints support dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // Indicates which properties a client can resolve lazily on an inlay @@ -54027,12 +60082,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Inlay hint kinds. -// -// @since 3.17.0 --type InlayHintKind uint32 // line 13033 +-type InlayHintKind uint32 +- -// An inlay hint label part allows for interactive and composite labels -// of inlay hints. -// -// @since 3.17.0 --type InlayHintLabelPart struct { // line 7062 +-type InlayHintLabelPart struct { - // The value of this label part. - Value string `json:"value"` - // The tooltip text when you hover over this label part. Depending on @@ -54061,7 +60117,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Inlay hint options used during static registration. -// -// @since 3.17.0 --type InlayHintOptions struct { // line 7135 +-type InlayHintOptions struct { - // The server provides support to resolve additional - // information for an inlay hint item. - ResolveProvider bool `json:"resolveProvider,omitempty"` @@ -54071,7 +60127,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A parameter literal used in inlay hint requests. -// -// @since 3.17.0 --type InlayHintParams struct { // line 3616 +-type InlayHintParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The document range for which inlay hints should be computed. @@ -54082,7 +60138,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Inlay hint options used during static or dynamic registration. -// -// @since 3.17.0 --type InlayHintRegistrationOptions struct { // line 3746 +-type InlayHintRegistrationOptions struct { - InlayHintOptions - TextDocumentRegistrationOptions - StaticRegistrationOptions @@ -54091,7 +60147,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Client workspace capabilities specific to inlay hints. -// -// @since 3.17.0 --type InlayHintWorkspaceClientCapabilities struct { // line 11095 +-type InlayHintWorkspaceClientCapabilities struct { - // Whether the client implementation supports a refresh request sent from - // the server to the client. - // @@ -54102,6 +60158,86 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - RefreshSupport bool `json:"refreshSupport,omitempty"` -} - +-// Client capabilities specific to inline completions. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionClientCapabilities struct { +- // Whether implementation supports dynamic registration for inline completion providers. +- DynamicRegistration bool `json:"dynamicRegistration,omitempty"` +-} +- +-// Provides information about the context in which an inline completion was requested. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionContext struct { +- // Describes how the inline completion was triggered. +- TriggerKind InlineCompletionTriggerKind `json:"triggerKind"` +- // Provides information about the currently selected item in the autocomplete widget if it is visible. +- SelectedCompletionInfo *SelectedCompletionInfo `json:"selectedCompletionInfo,omitempty"` +-} +- +-// An inline completion item represents a text snippet that is proposed inline to complete text that is being typed. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionItem struct { +- // The text to replace the range with. Must be set. +- InsertText Or_InlineCompletionItem_insertText `json:"insertText"` +- // A text that is used to decide if this inline completion should be shown. When `falsy` the {@link InlineCompletionItem.insertText} is used. +- FilterText string `json:"filterText,omitempty"` +- // The range to replace. Must begin and end on the same line. +- Range *Range `json:"range,omitempty"` +- // An optional {@link Command} that is executed *after* inserting this completion. +- Command *Command `json:"command,omitempty"` +-} +- +-// Represents a collection of {@link InlineCompletionItem inline completion items} to be presented in the editor. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionList struct { +- // The inline completion items +- Items []InlineCompletionItem `json:"items"` +-} +- +-// Inline completion options used during static registration. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionOptions struct { +- WorkDoneProgressOptions +-} +- +-// A parameter literal used in inline completion requests. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionParams struct { +- // Additional information about the context in which inline completions were +- // requested. +- Context InlineCompletionContext `json:"context"` +- TextDocumentPositionParams +- WorkDoneProgressParams +-} +- +-// Inline completion options used during static or dynamic registration. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionRegistrationOptions struct { +- InlineCompletionOptions +- TextDocumentRegistrationOptions +- StaticRegistrationOptions +-} +- +-// Describes how an {@link InlineCompletionItemProvider inline completion provider} was triggered. +-// +-// @since 3.18.0 +-// @proposed +-type InlineCompletionTriggerKind uint32 +- -// Inline value information can be provided by different means: -// -// - directly as a text value (class InlineValueText). @@ -54111,17 +60247,17 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The InlineValue types combines all inline value types into one type. -// -// @since 3.17.0 --type InlineValue = Or_InlineValue // (alias) line 13861 +-type InlineValue = Or_InlineValue // (alias) line 14276 -// Client capabilities specific to inline values. -// -// @since 3.17.0 --type InlineValueClientCapabilities struct { // line 12353 +-type InlineValueClientCapabilities struct { - // Whether implementation supports dynamic registration for inline value providers. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// @since 3.17.0 --type InlineValueContext struct { // line 6948 +-type InlineValueContext struct { - // The stack frame (as a DAP Id) where the execution has stopped. - FrameID int32 `json:"frameId"` - // The document range where execution has stopped. @@ -54134,7 +60270,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// An optional expression can be used to override the extracted expression. -// -// @since 3.17.0 --type InlineValueEvaluatableExpression struct { // line 7026 +-type InlineValueEvaluatableExpression struct { - // The document range for which the inline value applies. - // The range is used to extract the evaluatable expression from the underlying document. - Range Range `json:"range"` @@ -54145,14 +60281,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Inline value options used during static registration. -// -// @since 3.17.0 --type InlineValueOptions struct { // line 7050 +-type InlineValueOptions struct { - WorkDoneProgressOptions -} - -// A parameter literal used in inline value requests. -// -// @since 3.17.0 --type InlineValueParams struct { // line 3557 +-type InlineValueParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The document range for which inline values should be computed. @@ -54166,7 +60302,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Inline value options used during static or dynamic registration. -// -// @since 3.17.0 --type InlineValueRegistrationOptions struct { // line 3594 +-type InlineValueRegistrationOptions struct { - InlineValueOptions - TextDocumentRegistrationOptions - StaticRegistrationOptions @@ -54175,7 +60311,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Provide inline value as text. -// -// @since 3.17.0 --type InlineValueText struct { // line 6971 +-type InlineValueText struct { - // The document range for which the inline value applies. - Range Range `json:"range"` - // The text of the inline value. @@ -54187,7 +60323,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// An optional variable name can be used to override the extracted name. -// -// @since 3.17.0 --type InlineValueVariableLookup struct { // line 6994 +-type InlineValueVariableLookup struct { - // The document range for which the inline value applies. - // The range is used to extract the variable name from the underlying document. - Range Range `json:"range"` @@ -54200,7 +60336,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Client workspace capabilities specific to inline values. -// -// @since 3.17.0 --type InlineValueWorkspaceClientCapabilities struct { // line 11079 +-type InlineValueWorkspaceClientCapabilities struct { - // Whether the client implementation supports a refresh request sent from the - // server to the client. - // @@ -54214,7 +60350,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A special text edit to provide an insert and a replace operation. -// -// @since 3.16.0 --type InsertReplaceEdit struct { // line 8676 +-type InsertReplaceEdit struct { - // The string to be inserted. - NewText string `json:"newText"` - // The range if the insert is requested @@ -54225,38 +60361,40 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// Defines whether the insert text in a completion item should be interpreted as -// plain text or a snippet. --type InsertTextFormat uint32 // line 13260 +-type InsertTextFormat uint32 +- -// How whitespace and indentation is handled during completion -// item insertion. -// -// @since 3.16.0 --type InsertTextMode uint32 // line 13280 +-type InsertTextMode uint32 -type LSPAny = interface{} - -// LSP arrays. -// @since 3.17.0 --type LSPArray = []interface{} // (alias) line 13779 --type LSPErrorCodes int32 // line 12783 +-type LSPArray = []interface{} // (alias) line 14194 +-type LSPErrorCodes int32 +- -// LSP object definition. -// @since 3.17.0 --type LSPObject = map[string]LSPAny // (alias) line 14111 +-type LSPObject = map[string]LSPAny // (alias) line 14526 -// Client capabilities for the linked editing range request. -// -// @since 3.16.0 --type LinkedEditingRangeClientCapabilities struct { // line 12305 +-type LinkedEditingRangeClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` - // return value for the corresponding server capability as well. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} --type LinkedEditingRangeOptions struct { // line 6652 +-type LinkedEditingRangeOptions struct { - WorkDoneProgressOptions -} --type LinkedEditingRangeParams struct { // line 3112 +-type LinkedEditingRangeParams struct { - TextDocumentPositionParams - WorkDoneProgressParams -} --type LinkedEditingRangeRegistrationOptions struct { // line 3155 +-type LinkedEditingRangeRegistrationOptions struct { - TextDocumentRegistrationOptions - LinkedEditingRangeOptions - StaticRegistrationOptions @@ -54265,7 +60403,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The result of a linked editing range request. -// -// @since 3.16.0 --type LinkedEditingRanges struct { // line 3128 +-type LinkedEditingRanges struct { - // A list of ranges that can be edited together. The ranges must have - // identical length and contain identical text content. The ranges cannot overlap. - Ranges []Range `json:"ranges"` @@ -54276,13 +60414,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_NotebookDocumentChangeEvent_cells_textContent_Elem) --type Lit_NotebookDocumentChangeEvent_cells_textContent_Elem struct { // line 7545 +-type Lit_NotebookDocumentChangeEvent_cells_textContent_Elem struct { - Document VersionedTextDocumentIdentifier `json:"document"` - Changes []TextDocumentContentChangeEvent `json:"changes"` -} - -// created for Literal (Lit_NotebookDocumentFilter_Item1) --type Lit_NotebookDocumentFilter_Item1 struct { // line 14293 +-type Lit_NotebookDocumentFilter_Item1 struct { - // The type of the enclosing notebook. - NotebookType string `json:"notebookType,omitempty"` - // A Uri {@link Uri.scheme scheme}, like `file` or `untitled`. @@ -54292,7 +60430,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_NotebookDocumentFilter_Item2) --type Lit_NotebookDocumentFilter_Item2 struct { // line 14326 +-type Lit_NotebookDocumentFilter_Item2 struct { - // The type of the enclosing notebook. - NotebookType string `json:"notebookType,omitempty"` - // A Uri {@link Uri.scheme scheme}, like `file` or `untitled`. @@ -54302,12 +60440,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item0_cells_Elem) --type Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item0_cells_Elem struct { // line 9831 +-type Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item0_cells_Elem struct { - Language string `json:"language"` -} - -// created for Literal (Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1) --type Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1 struct { // line 9852 +-type Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1 struct { - // The notebook to be synced If a string - // value is provided it matches against the - // notebook type. '*' matches every notebook. @@ -54317,23 +60455,23 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1_cells_Elem) --type Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1_cells_Elem struct { // line 9878 +-type Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1_cells_Elem struct { - Language string `json:"language"` -} - -// created for Literal (Lit_PrepareRenameResult_Item2) --type Lit_PrepareRenameResult_Item2 struct { // line 13932 +-type Lit_PrepareRenameResult_Item2 struct { - DefaultBehavior bool `json:"defaultBehavior"` -} - -// created for Literal (Lit_TextDocumentContentChangeEvent_Item1) --type Lit_TextDocumentContentChangeEvent_Item1 struct { // line 14040 +-type Lit_TextDocumentContentChangeEvent_Item1 struct { - // The new text of the whole document. - Text string `json:"text"` -} - -// created for Literal (Lit_TextDocumentFilter_Item2) --type Lit_TextDocumentFilter_Item2 struct { // line 14217 +-type Lit_TextDocumentFilter_Item2 struct { - // A language id, like `typescript`. - Language string `json:"language,omitempty"` - // A Uri {@link Uri.scheme scheme}, like `file` or `untitled`. @@ -54344,14 +60482,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// Represents a location inside a resource, such as a line -// inside a text file. --type Location struct { // line 2083 +-type Location struct { - URI DocumentURI `json:"uri"` - Range Range `json:"range"` -} - -// Represents the connection of two locations. Provides additional metadata over normal {@link Location locations}, -// including an origin range. --type LocationLink struct { // line 6272 +-type LocationLink struct { - // Span of the origin of this link. - // - // Used as the underlined span for mouse interaction. Defaults to the word range at @@ -54369,13 +60507,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The log message parameters. --type LogMessageParams struct { // line 4251 +-type LogMessageParams struct { - // The message type. See {@link MessageType} - Type MessageType `json:"type"` - // The actual message. - Message string `json:"message"` -} --type LogTraceParams struct { // line 6159 +-type LogTraceParams struct { - Message string `json:"message"` - Verbose string `json:"verbose,omitempty"` -} @@ -54383,7 +60521,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Client capabilities specific to the used markdown parser. -// -// @since 3.16.0 --type MarkdownClientCapabilities struct { // line 12524 +-type MarkdownClientCapabilities struct { - // The name of the parser. - Parser string `json:"parser"` - // The version of the parser. @@ -54407,7 +60545,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// -// Note that markdown strings will be sanitized - that means html will be escaped. -// @deprecated use MarkupContent instead. --type MarkedString = Or_MarkedString // (alias) line 14058 +-type MarkedString = Or_MarkedString // (alias) line 14473 -// A `MarkupContent` literal represents a string value which content is interpreted base on its -// kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds. -// @@ -54432,7 +60570,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// -// *Please Note* that clients might sanitize the return markdown. A client could decide to -// remove HTML from the markdown to avoid script execution. --type MarkupContent struct { // line 7113 +-type MarkupContent struct { - // The type of the Markup - Kind MarkupKind `json:"kind"` - // The content itself @@ -54444,18 +60582,19 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// -// Please note that `MarkupKinds` must not start with a `$`. This kinds -// are reserved for internal usage. --type MarkupKind string // line 13407 --type MessageActionItem struct { // line 4238 +-type MarkupKind string +-type MessageActionItem struct { - // A short title like 'Retry', 'Open Log' etc. - Title string `json:"title"` -} - -// The message type --type MessageType uint32 // line 13054 +-type MessageType uint32 +- -// Moniker definition to match LSIF 0.5 moniker definition. -// -// @since 3.16.0 --type Moniker struct { // line 3338 +-type Moniker struct { - // The scheme of the moniker. For example tsc or .Net - Scheme string `json:"scheme"` - // The identifier of the moniker. The value is opaque in LSIF however @@ -54470,7 +60609,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Client capabilities specific to the moniker request. -// -// @since 3.16.0 --type MonikerClientCapabilities struct { // line 12321 +-type MonikerClientCapabilities struct { - // Whether moniker supports dynamic registration. If this is set to `true` - // the client supports the new `MonikerRegistrationOptions` return value - // for the corresponding server capability as well. @@ -54480,28 +60619,28 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The moniker kind. -// -// @since 3.16.0 --type MonikerKind string // line 13007 --type MonikerOptions struct { // line 6926 +-type MonikerKind string +-type MonikerOptions struct { - WorkDoneProgressOptions -} --type MonikerParams struct { // line 3318 +-type MonikerParams struct { - TextDocumentPositionParams - WorkDoneProgressParams - PartialResultParams -} --type MonikerRegistrationOptions struct { // line 3378 +-type MonikerRegistrationOptions struct { - TextDocumentRegistrationOptions - MonikerOptions -} - -// created for Literal (Lit_MarkedString_Item1) --type Msg_MarkedString struct { // line 14068 +-type Msg_MarkedString struct { - Language string `json:"language"` - Value string `json:"value"` -} - -// created for Literal (Lit_NotebookDocumentFilter_Item0) --type Msg_NotebookDocumentFilter struct { // line 14260 +-type Msg_NotebookDocumentFilter struct { - // The type of the enclosing notebook. - NotebookType string `json:"notebookType"` - // A Uri {@link Uri.scheme scheme}, like `file` or `untitled`. @@ -54511,13 +60650,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_PrepareRenameResult_Item1) --type Msg_PrepareRename2Gn struct { // line 13911 +-type Msg_PrepareRename2Gn struct { - Range Range `json:"range"` - Placeholder string `json:"placeholder"` -} - -// created for Literal (Lit_TextDocumentContentChangeEvent_Item0) --type Msg_TextDocumentContentChangeEvent struct { // line 14008 +-type Msg_TextDocumentContentChangeEvent struct { - // The range of the document that changed. - Range *Range `json:"range"` - // The optional length of the range that got replaced. @@ -54529,7 +60668,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_TextDocumentFilter_Item1) --type Msg_TextDocumentFilter struct { // line 14184 +-type Msg_TextDocumentFilter struct { - // A language id, like `typescript`. - Language string `json:"language,omitempty"` - // A Uri {@link Uri.scheme scheme}, like `file` or `untitled`. @@ -54539,7 +60678,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit__InitializeParams_clientInfo) --type Msg_XInitializeParams_clientInfo struct { // line 7673 +-type Msg_XInitializeParams_clientInfo struct { - // The name of the client as defined by the client. - Name string `json:"name"` - // The client's version as defined by the client. @@ -54553,7 +60692,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// notebook cell or the cell's text document. -// -// @since 3.17.0 --type NotebookCell struct { // line 9598 +-type NotebookCell struct { - // The cell's kind - Kind NotebookCellKind `json:"kind"` - // The URI of the cell's text document @@ -54572,7 +60711,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// array from state S to S'. -// -// @since 3.17.0 --type NotebookCellArrayChange struct { // line 9639 +-type NotebookCellArrayChange struct { - // The start oftest of the cell that changed. - Start uint32 `json:"start"` - // The deleted cells @@ -54584,12 +60723,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A notebook cell kind. -// -// @since 3.17.0 --type NotebookCellKind uint32 // line 13648 +-type NotebookCellKind uint32 +- -// A notebook cell text document filter denotes a cell text -// document by different properties. -// -// @since 3.17.0 --type NotebookCellTextDocumentFilter struct { // line 10113 +-type NotebookCellTextDocumentFilter struct { - // A filter that matches against the notebook - // containing the notebook cell. If a string - // value is provided it matches against the @@ -54605,7 +60745,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A notebook document. -// -// @since 3.17.0 --type NotebookDocument struct { // line 7354 +-type NotebookDocument struct { - // The notebook document's uri. - URI URI `json:"uri"` - // The type of the notebook. @@ -54625,7 +60765,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A change event for a notebook document. -// -// @since 3.17.0 --type NotebookDocumentChangeEvent struct { // line 7466 +-type NotebookDocumentChangeEvent struct { - // The changed meta data if any. - // - // Note: should always be an object literal (e.g. LSPObject) @@ -54637,7 +60777,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Capabilities specific to the notebook document support. -// -// @since 3.17.0 --type NotebookDocumentClientCapabilities struct { // line 10613 +-type NotebookDocumentClientCapabilities struct { - // Capabilities specific to notebook document synchronization - // - // @since 3.17.0 @@ -54649,11 +60789,11 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// against the notebook's URI (same as with documents) -// -// @since 3.17.0 --type NotebookDocumentFilter = Msg_NotebookDocumentFilter // (alias) line 14254 +-type NotebookDocumentFilter = Msg_NotebookDocumentFilter // (alias) line 14669 -// A literal to identify a notebook document in the client. -// -// @since 3.17.0 --type NotebookDocumentIdentifier struct { // line 7582 +-type NotebookDocumentIdentifier struct { - // The notebook document's uri. - URI URI `json:"uri"` -} @@ -54661,7 +60801,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Notebook specific client capabilities. -// -// @since 3.17.0 --type NotebookDocumentSyncClientCapabilities struct { // line 12433 +-type NotebookDocumentSyncClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is - // set to `true` the client supports the new - // `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` @@ -54684,7 +60824,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// cell will be synced. -// -// @since 3.17.0 --type NotebookDocumentSyncOptions struct { // line 9795 +-type NotebookDocumentSyncOptions struct { - // The notebooks to be synced - NotebookSelector []PNotebookSelectorPNotebookDocumentSync `json:"notebookSelector"` - // Whether save notification should be forwarded to @@ -54695,13 +60835,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Registration options specific to a notebook. -// -// @since 3.17.0 --type NotebookDocumentSyncRegistrationOptions struct { // line 9915 +-type NotebookDocumentSyncRegistrationOptions struct { - NotebookDocumentSyncOptions - StaticRegistrationOptions -} - -// A text document identifier to optionally denote a specific version of a text document. --type OptionalVersionedTextDocumentIdentifier struct { // line 9343 +-type OptionalVersionedTextDocumentIdentifier struct { - // The version number of this document. If a versioned text document identifier - // is sent from the server to the client and the file is not open in the editor - // (the server has not received an open notification before) the server can send @@ -54712,307 +60852,322 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Or [FEditRangePItemDefaults Range] --type OrFEditRangePItemDefaults struct { // line 4770 +-type OrFEditRangePItemDefaults struct { - Value interface{} `json:"value"` -} - -// created for Or [NotebookDocumentFilter string] --type OrFNotebookPNotebookSelector struct { // line 9812 +-type OrFNotebookPNotebookSelector struct { - Value interface{} `json:"value"` -} - -// created for Or [Location PLocationMsg_workspace_symbol] --type OrPLocation_workspace_symbol struct { // line 5521 +-type OrPLocation_workspace_symbol struct { - Value interface{} `json:"value"` -} - -// created for Or [[]string string] --type OrPSection_workspace_didChangeConfiguration struct { // line 4164 +-type OrPSection_workspace_didChangeConfiguration struct { - Value interface{} `json:"value"` -} - -// created for Or [MarkupContent string] --type OrPTooltipPLabel struct { // line 7076 +-type OrPTooltipPLabel struct { - Value interface{} `json:"value"` -} - -// created for Or [MarkupContent string] --type OrPTooltip_textDocument_inlayHint struct { // line 3700 +-type OrPTooltip_textDocument_inlayHint struct { - Value interface{} `json:"value"` -} - -// created for Or [int32 string] --type Or_CancelParams_id struct { // line 6185 +-type Or_CancelParams_id struct { - Value interface{} `json:"value"` -} - -// created for Or [MarkupContent string] --type Or_CompletionItem_documentation struct { // line 4583 +-type Or_CompletionItem_documentation struct { - Value interface{} `json:"value"` -} - -// created for Or [InsertReplaceEdit TextEdit] --type Or_CompletionItem_textEdit struct { // line 4666 +-type Or_CompletionItem_textEdit struct { - Value interface{} `json:"value"` -} - -// created for Or [Location []Location] --type Or_Definition struct { // line 13754 +-type Or_Definition struct { - Value interface{} `json:"value"` -} - -// created for Or [int32 string] --type Or_Diagnostic_code struct { // line 8548 +-type Or_Diagnostic_code struct { - Value interface{} `json:"value"` -} - -// created for Or [RelatedFullDocumentDiagnosticReport RelatedUnchangedDocumentDiagnosticReport] --type Or_DocumentDiagnosticReport struct { // line 13886 +-type Or_DocumentDiagnosticReport struct { - Value interface{} `json:"value"` -} - -// created for Or [FullDocumentDiagnosticReport UnchangedDocumentDiagnosticReport] --type Or_DocumentDiagnosticReportPartialResult_relatedDocuments_Value struct { // line 3823 +-type Or_DocumentDiagnosticReportPartialResult_relatedDocuments_Value struct { - Value interface{} `json:"value"` -} - -// created for Or [NotebookCellTextDocumentFilter TextDocumentFilter] --type Or_DocumentFilter struct { // line 14096 +-type Or_DocumentFilter struct { - Value interface{} `json:"value"` -} - -// created for Or [MarkedString MarkupContent []MarkedString] --type Or_Hover_contents struct { // line 4892 +-type Or_Hover_contents struct { - Value interface{} `json:"value"` -} - -// created for Or [[]InlayHintLabelPart string] --type Or_InlayHint_label struct { // line 3659 +-type Or_InlayHint_label struct { +- Value interface{} `json:"value"` +-} +- +-// created for Or [StringValue string] +-type Or_InlineCompletionItem_insertText struct { - Value interface{} `json:"value"` -} - -// created for Or [InlineValueEvaluatableExpression InlineValueText InlineValueVariableLookup] --type Or_InlineValue struct { // line 13864 +-type Or_InlineValue struct { - Value interface{} `json:"value"` -} - -// created for Or [Msg_MarkedString string] --type Or_MarkedString struct { // line 14061 +-type Or_MarkedString struct { - Value interface{} `json:"value"` -} - -// created for Or [NotebookDocumentFilter string] --type Or_NotebookCellTextDocumentFilter_notebook struct { // line 10119 +-type Or_NotebookCellTextDocumentFilter_notebook struct { - Value interface{} `json:"value"` -} - -// created for Or [NotebookDocumentFilter string] --type Or_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1_notebook struct { // line 9858 +-type Or_NotebookDocumentSyncOptions_notebookSelector_Elem_Item1_notebook struct { - Value interface{} `json:"value"` -} - -// created for Or [FullDocumentDiagnosticReport UnchangedDocumentDiagnosticReport] --type Or_RelatedFullDocumentDiagnosticReport_relatedDocuments_Value struct { // line 7169 +-type Or_RelatedFullDocumentDiagnosticReport_relatedDocuments_Value struct { - Value interface{} `json:"value"` -} - -// created for Or [FullDocumentDiagnosticReport UnchangedDocumentDiagnosticReport] --type Or_RelatedUnchangedDocumentDiagnosticReport_relatedDocuments_Value struct { // line 7208 +-type Or_RelatedUnchangedDocumentDiagnosticReport_relatedDocuments_Value struct { - Value interface{} `json:"value"` -} - -// created for Or [URI WorkspaceFolder] --type Or_RelativePattern_baseUri struct { // line 10742 +-type Or_RelativePattern_baseUri struct { - Value interface{} `json:"value"` -} - -// created for Or [CodeAction Command] --type Or_Result_textDocument_codeAction_Item0_Elem struct { // line 1372 +-type Or_Result_textDocument_codeAction_Item0_Elem struct { +- Value interface{} `json:"value"` +-} +- +-// created for Or [InlineCompletionList []InlineCompletionItem] +-type Or_Result_textDocument_inlineCompletion struct { - Value interface{} `json:"value"` -} - -// created for Or [FFullPRequests bool] --type Or_SemanticTokensClientCapabilities_requests_full struct { // line 12198 +-type Or_SemanticTokensClientCapabilities_requests_full struct { - Value interface{} `json:"value"` -} - -// created for Or [FRangePRequests bool] --type Or_SemanticTokensClientCapabilities_requests_range struct { // line 12178 +-type Or_SemanticTokensClientCapabilities_requests_range struct { - Value interface{} `json:"value"` -} - -// created for Or [PFullESemanticTokensOptions bool] --type Or_SemanticTokensOptions_full struct { // line 6580 +-type Or_SemanticTokensOptions_full struct { - Value interface{} `json:"value"` -} - -// created for Or [PRangeESemanticTokensOptions bool] --type Or_SemanticTokensOptions_range struct { // line 6560 +-type Or_SemanticTokensOptions_range struct { - Value interface{} `json:"value"` -} - -// created for Or [CallHierarchyOptions CallHierarchyRegistrationOptions bool] --type Or_ServerCapabilities_callHierarchyProvider struct { // line 8228 +-type Or_ServerCapabilities_callHierarchyProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [CodeActionOptions bool] --type Or_ServerCapabilities_codeActionProvider struct { // line 8036 +-type Or_ServerCapabilities_codeActionProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DocumentColorOptions DocumentColorRegistrationOptions bool] --type Or_ServerCapabilities_colorProvider struct { // line 8072 +-type Or_ServerCapabilities_colorProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DeclarationOptions DeclarationRegistrationOptions bool] --type Or_ServerCapabilities_declarationProvider struct { // line 7898 +-type Or_ServerCapabilities_declarationProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DefinitionOptions bool] --type Or_ServerCapabilities_definitionProvider struct { // line 7920 +-type Or_ServerCapabilities_definitionProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DiagnosticOptions DiagnosticRegistrationOptions] --type Or_ServerCapabilities_diagnosticProvider struct { // line 8385 +-type Or_ServerCapabilities_diagnosticProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DocumentFormattingOptions bool] --type Or_ServerCapabilities_documentFormattingProvider struct { // line 8112 +-type Or_ServerCapabilities_documentFormattingProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DocumentHighlightOptions bool] --type Or_ServerCapabilities_documentHighlightProvider struct { // line 8000 +-type Or_ServerCapabilities_documentHighlightProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DocumentRangeFormattingOptions bool] --type Or_ServerCapabilities_documentRangeFormattingProvider struct { // line 8130 +-type Or_ServerCapabilities_documentRangeFormattingProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [DocumentSymbolOptions bool] --type Or_ServerCapabilities_documentSymbolProvider struct { // line 8018 +-type Or_ServerCapabilities_documentSymbolProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [FoldingRangeOptions FoldingRangeRegistrationOptions bool] --type Or_ServerCapabilities_foldingRangeProvider struct { // line 8175 +-type Or_ServerCapabilities_foldingRangeProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [HoverOptions bool] --type Or_ServerCapabilities_hoverProvider struct { // line 7871 +-type Or_ServerCapabilities_hoverProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [ImplementationOptions ImplementationRegistrationOptions bool] --type Or_ServerCapabilities_implementationProvider struct { // line 7960 +-type Or_ServerCapabilities_implementationProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [InlayHintOptions InlayHintRegistrationOptions bool] --type Or_ServerCapabilities_inlayHintProvider struct { // line 8362 +-type Or_ServerCapabilities_inlayHintProvider struct { +- Value interface{} `json:"value"` +-} +- +-// created for Or [InlineCompletionOptions bool] +-type Or_ServerCapabilities_inlineCompletionProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [InlineValueOptions InlineValueRegistrationOptions bool] --type Or_ServerCapabilities_inlineValueProvider struct { // line 8339 +-type Or_ServerCapabilities_inlineValueProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [LinkedEditingRangeOptions LinkedEditingRangeRegistrationOptions bool] --type Or_ServerCapabilities_linkedEditingRangeProvider struct { // line 8251 +-type Or_ServerCapabilities_linkedEditingRangeProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [MonikerOptions MonikerRegistrationOptions bool] --type Or_ServerCapabilities_monikerProvider struct { // line 8293 +-type Or_ServerCapabilities_monikerProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [NotebookDocumentSyncOptions NotebookDocumentSyncRegistrationOptions] --type Or_ServerCapabilities_notebookDocumentSync struct { // line 7843 +-type Or_ServerCapabilities_notebookDocumentSync struct { - Value interface{} `json:"value"` -} - -// created for Or [ReferenceOptions bool] --type Or_ServerCapabilities_referencesProvider struct { // line 7982 +-type Or_ServerCapabilities_referencesProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [RenameOptions bool] --type Or_ServerCapabilities_renameProvider struct { // line 8157 +-type Or_ServerCapabilities_renameProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [SelectionRangeOptions SelectionRangeRegistrationOptions bool] --type Or_ServerCapabilities_selectionRangeProvider struct { // line 8197 +-type Or_ServerCapabilities_selectionRangeProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [SemanticTokensOptions SemanticTokensRegistrationOptions] --type Or_ServerCapabilities_semanticTokensProvider struct { // line 8274 +-type Or_ServerCapabilities_semanticTokensProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [TextDocumentSyncKind TextDocumentSyncOptions] --type Or_ServerCapabilities_textDocumentSync struct { // line 7825 +-type Or_ServerCapabilities_textDocumentSync struct { - Value interface{} `json:"value"` -} - -// created for Or [TypeDefinitionOptions TypeDefinitionRegistrationOptions bool] --type Or_ServerCapabilities_typeDefinitionProvider struct { // line 7938 +-type Or_ServerCapabilities_typeDefinitionProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [TypeHierarchyOptions TypeHierarchyRegistrationOptions bool] --type Or_ServerCapabilities_typeHierarchyProvider struct { // line 8316 +-type Or_ServerCapabilities_typeHierarchyProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [WorkspaceSymbolOptions bool] --type Or_ServerCapabilities_workspaceSymbolProvider struct { // line 8094 +-type Or_ServerCapabilities_workspaceSymbolProvider struct { - Value interface{} `json:"value"` -} - -// created for Or [MarkupContent string] --type Or_SignatureInformation_documentation struct { // line 8842 +-type Or_SignatureInformation_documentation struct { - Value interface{} `json:"value"` -} - -// created for Or [AnnotatedTextEdit TextEdit] --type Or_TextDocumentEdit_edits_Elem struct { // line 6693 +-type Or_TextDocumentEdit_edits_Elem struct { - Value interface{} `json:"value"` -} - -// created for Or [SaveOptions bool] --type Or_TextDocumentSyncOptions_save struct { // line 9778 +-type Or_TextDocumentSyncOptions_save struct { - Value interface{} `json:"value"` -} - -// created for Or [WorkspaceFullDocumentDiagnosticReport WorkspaceUnchangedDocumentDiagnosticReport] --type Or_WorkspaceDocumentDiagnosticReport struct { // line 13987 +-type Or_WorkspaceDocumentDiagnosticReport struct { - Value interface{} `json:"value"` -} - -// created for Or [CreateFile DeleteFile RenameFile TextDocumentEdit] --type Or_WorkspaceEdit_documentChanges_Elem struct { // line 3220 +-type Or_WorkspaceEdit_documentChanges_Elem struct { - Value interface{} `json:"value"` -} - -// created for Or [Declaration []DeclarationLink] --type Or_textDocument_declaration struct { // line 249 +-type Or_textDocument_declaration struct { - Value interface{} `json:"value"` -} - -// created for Literal (Lit_NotebookDocumentChangeEvent_cells) --type PCellsPChange struct { // line 7481 +-type PCellsPChange struct { - // Changes to the cell structure to add or - // remove cells. - Structure *FStructurePCells `json:"structure,omitempty"` @@ -55024,7 +61179,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_WorkspaceEditClientCapabilities_changeAnnotationSupport) --type PChangeAnnotationSupportPWorkspaceEdit struct { // line 10816 +-type PChangeAnnotationSupportPWorkspaceEdit struct { - // Whether the client groups edits with equal labels into tree nodes, - // for instance all edits labelled with "Changes in Strings" would - // be a tree node. @@ -55032,14 +61187,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CodeActionClientCapabilities_codeActionLiteralSupport) --type PCodeActionLiteralSupportPCodeAction struct { // line 11736 +-type PCodeActionLiteralSupportPCodeAction struct { - // The code action kind is support with the following value - // set. - CodeActionKind FCodeActionKindPCodeActionLiteralSupport `json:"codeActionKind"` -} - -// created for Literal (Lit_CompletionClientCapabilities_completionItemKind) --type PCompletionItemKindPCompletion struct { // line 11334 +-type PCompletionItemKindPCompletion struct { - // The completion item kind values the client supports. When this - // property exists the client also guarantees that it will - // handle values outside its set gracefully and falls back @@ -55052,7 +61207,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CompletionClientCapabilities_completionItem) --type PCompletionItemPCompletion struct { // line 11183 +-type PCompletionItemPCompletion struct { - // Client supports snippets as insert text. - // - // A snippet can define tab stops and placeholders with `$1`, `$2` @@ -55101,7 +61256,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CompletionOptions_completionItem) --type PCompletionItemPCompletionProvider struct { // line 8747 +-type PCompletionItemPCompletionProvider struct { - // The server has support for completion item label - // details (see also `CompletionItemLabelDetails`) when - // receiving a completion item in a resolve call. @@ -55111,7 +61266,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CompletionClientCapabilities_completionList) --type PCompletionListPCompletion struct { // line 11376 +-type PCompletionListPCompletion struct { - // The client supports the following itemDefaults on - // a completion list. - // @@ -55124,7 +61279,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CodeAction_disabled) --type PDisabledMsg_textDocument_codeAction struct { // line 5427 +-type PDisabledMsg_textDocument_codeAction struct { - // Human readable description of why the code action is currently disabled. - // - // This is displayed in the code actions UI. @@ -55132,7 +61287,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_FoldingRangeClientCapabilities_foldingRangeKind) --type PFoldingRangeKindPFoldingRange struct { // line 12011 +-type PFoldingRangeKindPFoldingRange struct { - // The folding range kind values the client supports. When this - // property exists the client also guarantees that it will - // handle values outside its set gracefully and falls back @@ -55141,7 +61296,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_FoldingRangeClientCapabilities_foldingRange) --type PFoldingRangePFoldingRange struct { // line 12036 +-type PFoldingRangePFoldingRange struct { - // If set, the client signals that it supports setting collapsedText on - // folding ranges to display custom labels instead of the default text. - // @@ -55150,13 +61305,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_SemanticTokensOptions_full_Item1) --type PFullESemanticTokensOptions struct { // line 6587 +-type PFullESemanticTokensOptions struct { - // The server supports deltas for full documents. - Delta bool `json:"delta"` -} - -// created for Literal (Lit_CompletionList_itemDefaults) --type PItemDefaultsMsg_textDocument_completion struct { // line 4751 +-type PItemDefaultsMsg_textDocument_completion struct { - // A default commit character set. - // - // @since 3.17.0 @@ -55180,12 +61335,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_WorkspaceSymbol_location_Item1) --type PLocationMsg_workspace_symbol struct { // line 5528 +-type PLocationMsg_workspace_symbol struct { - URI DocumentURI `json:"uri"` -} - -// created for Literal (Lit_ShowMessageRequestClientCapabilities_messageActionItem) --type PMessageActionItemPShowMessage struct { // line 12464 +-type PMessageActionItemPShowMessage struct { - // Whether the client supports additional attributes which - // are preserved and send back to the server in the - // request's response. @@ -55193,7 +61348,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_NotebookDocumentSyncOptions_notebookSelector_Elem_Item0) --type PNotebookSelectorPNotebookDocumentSync struct { // line 9806 +-type PNotebookSelectorPNotebookDocumentSync struct { - // The notebook to be synced If a string - // value is provided it matches against the - // notebook type. '*' matches every notebook. @@ -55203,11 +61358,11 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_SemanticTokensOptions_range_Item1) --type PRangeESemanticTokensOptions struct { // line 6567 +-type PRangeESemanticTokensOptions struct { -} - -// created for Literal (Lit_SemanticTokensClientCapabilities_requests) --type PRequestsPSemanticTokens struct { // line 12172 +-type PRequestsPSemanticTokens struct { - // The client will send the `textDocument/semanticTokens/range` request if - // the server provides a corresponding handler. - Range Or_SemanticTokensClientCapabilities_requests_range `json:"range"` @@ -55217,26 +61372,26 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_CodeActionClientCapabilities_resolveSupport) --type PResolveSupportPCodeAction struct { // line 11801 +-type PResolveSupportPCodeAction struct { - // The properties that a client can resolve lazily. - Properties []string `json:"properties"` -} - -// created for Literal (Lit_InlayHintClientCapabilities_resolveSupport) --type PResolveSupportPInlayHint struct { // line 12384 +-type PResolveSupportPInlayHint struct { - // The properties that a client can resolve lazily. - Properties []string `json:"properties"` -} - -// created for Literal (Lit_WorkspaceSymbolClientCapabilities_resolveSupport) --type PResolveSupportPSymbol struct { // line 10938 +-type PResolveSupportPSymbol struct { - // The properties that a client can resolve lazily. Usually - // `location.range` - Properties []string `json:"properties"` -} - -// created for Literal (Lit_InitializeResult_serverInfo) --type PServerInfoMsg_initialize struct { // line 4096 +-type PServerInfoMsg_initialize struct { - // The name of the server as defined by the server. - Name string `json:"name"` - // The server's version as defined by the server. @@ -55244,7 +61399,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_SignatureHelpClientCapabilities_signatureInformation) --type PSignatureInformationPSignatureHelp struct { // line 11443 +-type PSignatureInformationPSignatureHelp struct { - // Client supports the following content formats for the documentation - // property. The order describes the preferred format of the client. - DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"` @@ -55258,7 +61413,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_GeneralClientCapabilities_staleRequestSupport) --type PStaleRequestSupportPGeneral struct { // line 10670 +-type PStaleRequestSupportPGeneral struct { - // The client will actively cancel the request. - Cancel bool `json:"cancel"` - // The list of requests for which the client @@ -55268,7 +61423,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_DocumentSymbolClientCapabilities_symbolKind) --type PSymbolKindPDocumentSymbol struct { // line 11654 +-type PSymbolKindPDocumentSymbol struct { - // The symbol kind values the client supports. When this - // property exists the client also guarantees that it will - // handle values outside its set gracefully and falls back @@ -55281,7 +61436,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_WorkspaceSymbolClientCapabilities_symbolKind) --type PSymbolKindPSymbol struct { // line 10890 +-type PSymbolKindPSymbol struct { - // The symbol kind values the client supports. When this - // property exists the client also guarantees that it will - // handle values outside its set gracefully and falls back @@ -55294,35 +61449,35 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_DocumentSymbolClientCapabilities_tagSupport) --type PTagSupportPDocumentSymbol struct { // line 11687 +-type PTagSupportPDocumentSymbol struct { - // The tags supported by the client. - ValueSet []SymbolTag `json:"valueSet"` -} - -// created for Literal (Lit_PublishDiagnosticsClientCapabilities_tagSupport) --type PTagSupportPPublishDiagnostics struct { // line 12087 +-type PTagSupportPPublishDiagnostics struct { - // The tags supported by the client. - ValueSet []DiagnosticTag `json:"valueSet"` -} - -// created for Literal (Lit_WorkspaceSymbolClientCapabilities_tagSupport) --type PTagSupportPSymbol struct { // line 10914 +-type PTagSupportPSymbol struct { - // The tags supported by the client. - ValueSet []SymbolTag `json:"valueSet"` -} - -// The parameters of a configuration request. --type ParamConfiguration struct { // line 2199 +-type ParamConfiguration struct { - Items []ConfigurationItem `json:"items"` -} --type ParamInitialize struct { // line 4068 +-type ParamInitialize struct { - XInitializeParams - WorkspaceFoldersInitializeParams -} - -// Represents a parameter of a callable-signature. A parameter can -// have a label and a doc-comment. --type ParameterInformation struct { // line 10063 +-type ParameterInformation struct { - // The label of this parameter information. - // - // Either a string or an inclusive start and exclusive end offsets within its containing @@ -55336,7 +61491,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // in the UI but can be omitted. - Documentation string `json:"documentation,omitempty"` -} --type PartialResultParams struct { // line 6258 +-type PartialResultParams struct { - // An optional token that a server can use to report partial results (e.g. streaming) to - // the client. - PartialResultToken *ProgressToken `json:"partialResultToken,omitempty"` @@ -55352,7 +61507,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`) -// -// @since 3.17.0 --type Pattern = string // (alias) line 14363 +-type Pattern = string // (alias) line 14778 -// Position in a text document expressed as zero-based line and character -// offset. Prior to 3.17 the offsets were always based on a UTF-16 string -// representation. So a string of the form `a𐐀b` the character offset of the @@ -55380,7 +61535,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// that denotes `\r|\n` or `\n|` where `|` represents the character offset. -// -// @since 3.17.0 - support for negotiated position encoding. --type Position struct { // line 6501 +-type Position struct { - // Line position in a document (zero-based). - // - // If a line number is greater than the number of lines in a document, it defaults back to the number of lines in the document. @@ -55399,18 +61554,19 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A set of predefined position encoding kinds. -// -// @since 3.17.0 --type PositionEncodingKind string // line 13427 +-type PositionEncodingKind string -type PrepareRename2Gn = Msg_PrepareRename2Gn // (alias) line 13927 --type PrepareRenameParams struct { // line 5925 +-type PrepareRenameParams struct { - TextDocumentPositionParams - WorkDoneProgressParams -} -type PrepareRenameResult = Msg_PrepareRename2Gn // (alias) line 13927 --type PrepareSupportDefaultBehavior uint32 // line 13722 +-type PrepareSupportDefaultBehavior uint32 +- -// A previous result id in a workspace pull request. -// -// @since 3.17.0 --type PreviousResultID struct { // line 7331 +-type PreviousResultID struct { - // The URI for which the client knowns a - // result id. - URI DocumentURI `json:"uri"` @@ -55421,22 +61577,22 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A previous result id in a workspace pull request. -// -// @since 3.17.0 --type PreviousResultId struct { // line 7331 +-type PreviousResultId struct { - // The URI for which the client knowns a - // result id. - URI DocumentURI `json:"uri"` - // The value of the previous result id. - Value string `json:"value"` -} --type ProgressParams struct { // line 6201 +-type ProgressParams struct { - // The progress token provided by the client or server. - Token ProgressToken `json:"token"` - // The progress data. - Value interface{} `json:"value"` -} --type ProgressToken = interface{} // (alias) line 13960 +-type ProgressToken = interface{} // (alias) line 14375 -// The publish diagnostic client capabilities. --type PublishDiagnosticsClientCapabilities struct { // line 12072 +-type PublishDiagnosticsClientCapabilities struct { - // Whether the clients accepts diagnostics with related information. - RelatedInformation bool `json:"relatedInformation,omitempty"` - // Client supports the tag property to provide meta data about a diagnostic. @@ -55462,7 +61618,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The publish diagnostic notification's parameters. --type PublishDiagnosticsParams struct { // line 4462 +-type PublishDiagnosticsParams struct { - // The URI for which diagnostic information is reported. - URI DocumentURI `json:"uri"` - // Optional the version number of the document the diagnostics are published for. @@ -55486,7 +61642,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// } -// -// ``` --type Range struct { // line 6311 +-type Range struct { - // The range's start position. - Start Position `json:"start"` - // The range's end position. @@ -55494,25 +61650,25 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Client Capabilities for a {@link ReferencesRequest}. --type ReferenceClientCapabilities struct { // line 11609 +-type ReferenceClientCapabilities struct { - // Whether references supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} - -// Value-object that contains additional information when -// requesting references. --type ReferenceContext struct { // line 8930 +-type ReferenceContext struct { - // Include the declaration of the current symbol. - IncludeDeclaration bool `json:"includeDeclaration"` -} - -// Reference options. --type ReferenceOptions struct { // line 8944 +-type ReferenceOptions struct { - WorkDoneProgressOptions -} - -// Parameters for a {@link ReferencesRequest}. --type ReferenceParams struct { // line 5054 +-type ReferenceParams struct { - Context ReferenceContext `json:"context"` - TextDocumentPositionParams - WorkDoneProgressParams @@ -55520,13 +61676,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link ReferencesRequest}. --type ReferenceRegistrationOptions struct { // line 5083 +-type ReferenceRegistrationOptions struct { - TextDocumentRegistrationOptions - ReferenceOptions -} - --// General parameters to to register for an notification or to register a provider. --type Registration struct { // line 7597 +-// General parameters to register for a notification or to register a provider. +-type Registration struct { - // The id used to register the request. The id can be used to deregister - // the request again. - ID string `json:"id"` @@ -55535,14 +61691,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // Options necessary for the registration. - RegisterOptions interface{} `json:"registerOptions,omitempty"` -} --type RegistrationParams struct { // line 4038 +-type RegistrationParams struct { - Registrations []Registration `json:"registrations"` -} - -// Client capabilities specific to regular expressions. -// -// @since 3.16.0 --type RegularExpressionsClientCapabilities struct { // line 12500 +-type RegularExpressionsClientCapabilities struct { - // The engine's name. - Engine string `json:"engine"` - // The engine's version. @@ -55552,7 +61708,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A full diagnostic report with a set of related documents. -// -// @since 3.17.0 --type RelatedFullDocumentDiagnosticReport struct { // line 7157 +-type RelatedFullDocumentDiagnosticReport struct { - // Diagnostics of related documents. This information is useful - // in programming languages where code in a file A can generate - // diagnostics in a file B which A depends on. An example of @@ -55567,7 +61723,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// An unchanged diagnostic report with a set of related documents. -// -// @since 3.17.0 --type RelatedUnchangedDocumentDiagnosticReport struct { // line 7196 +-type RelatedUnchangedDocumentDiagnosticReport struct { - // Diagnostics of related documents. This information is useful - // in programming languages where code in a file A can generate - // diagnostics in a file B which A depends on. An example of @@ -55584,14 +61740,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// folder root, but it can be another absolute URI as well. -// -// @since 3.17.0 --type RelativePattern struct { // line 10736 +-type RelativePattern struct { - // A workspace folder or a base URI to which this pattern will be matched - // against relatively. - BaseURI Or_RelativePattern_baseUri `json:"baseUri"` - // The actual glob pattern; - Pattern Pattern `json:"pattern"` -} --type RenameClientCapabilities struct { // line 11934 +-type RenameClientCapabilities struct { - // Whether rename supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // Client supports testing for validity of rename operations @@ -55617,7 +61773,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Rename file operation --type RenameFile struct { // line 6749 +-type RenameFile struct { - // A rename - Kind string `json:"kind"` - // The old (existing) location. @@ -55630,7 +61786,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Rename file options --type RenameFileOptions struct { // line 9441 +-type RenameFileOptions struct { - // Overwrite target if existing. Overwrite wins over `ignoreIfExists` - Overwrite bool `json:"overwrite,omitempty"` - // Ignores if target exists. @@ -55641,14 +61797,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// files. -// -// @since 3.16.0 --type RenameFilesParams struct { // line 3282 +-type RenameFilesParams struct { - // An array of all files/folders renamed in this operation. When a folder is renamed, only - // the folder will be included, and not its children. - Files []FileRename `json:"files"` -} - -// Provider options for a {@link RenameRequest}. --type RenameOptions struct { // line 9269 +-type RenameOptions struct { - // Renames should be checked and tested before being executed. - // - // @since version 3.12.0 @@ -55657,7 +61813,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The parameters of a {@link RenameRequest}. --type RenameParams struct { // line 5874 +-type RenameParams struct { - // The document to rename. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The position at which this request was sent. @@ -55670,13 +61826,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link RenameRequest}. --type RenameRegistrationOptions struct { // line 5910 +-type RenameRegistrationOptions struct { - TextDocumentRegistrationOptions - RenameOptions -} - -// A generic resource operation. --type ResourceOperation struct { // line 9393 +-type ResourceOperation struct { - // The resource operation kind. - Kind string `json:"kind"` - // An optional annotation identifier describing the operation. @@ -55684,33 +61840,45 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // @since 3.16.0 - AnnotationID *ChangeAnnotationIdentifier `json:"annotationId,omitempty"` -} --type ResourceOperationKind string // line 13669 +-type ResourceOperationKind string +- -// Save options. --type SaveOptions struct { // line 8465 +-type SaveOptions struct { - // The client is supposed to include the content on save. - IncludeText bool `json:"includeText,omitempty"` -} - +-// Describes the currently selected completion item. +-// +-// @since 3.18.0 +-// @proposed +-type SelectedCompletionInfo struct { +- // The range that will be replaced if this completion item is accepted. +- Range Range `json:"range"` +- // The text the range will be replaced with if this completion is accepted. +- Text string `json:"text"` +-} +- -// A selection range represents a part of a selection hierarchy. A selection range -// may have a parent selection range that contains it. --type SelectionRange struct { // line 2569 +-type SelectionRange struct { - // The {@link Range range} of this selection range. - Range Range `json:"range"` - // The parent selection range containing this range. Therefore `parent.range` must contain `this.range`. - Parent *SelectionRange `json:"parent,omitempty"` -} --type SelectionRangeClientCapabilities struct { // line 12058 +-type SelectionRangeClientCapabilities struct { - // Whether implementation supports dynamic registration for selection range providers. If this is set to `true` - // the client supports the new `SelectionRangeRegistrationOptions` return value for the corresponding server - // capability as well. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` -} --type SelectionRangeOptions struct { // line 6524 +-type SelectionRangeOptions struct { - WorkDoneProgressOptions -} - -// A parameter literal used in selection range requests. --type SelectionRangeParams struct { // line 2534 +-type SelectionRangeParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The positions inside the text document. @@ -55718,7 +61886,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - WorkDoneProgressParams - PartialResultParams -} --type SelectionRangeRegistrationOptions struct { // line 2592 +-type SelectionRangeRegistrationOptions struct { - SelectionRangeOptions - TextDocumentRegistrationOptions - StaticRegistrationOptions @@ -55729,15 +61897,17 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// corresponding client capabilities. -// -// @since 3.16.0 --type SemanticTokenModifiers string // line 12670 +-type SemanticTokenModifiers string +- -// A set of predefined token types. This set is not fixed -// an clients can specify additional token types via the -// corresponding client capabilities. -// -// @since 3.16.0 --type SemanticTokenTypes string // line 12563 +-type SemanticTokenTypes string +- -// @since 3.16.0 --type SemanticTokens struct { // line 2880 +-type SemanticTokens struct { - // An optional result id. If provided and clients support delta updating - // the client will include the result id in the next semantic token request. - // A server can then instead of computing all semantic tokens again simply @@ -55748,7 +61918,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensClientCapabilities struct { // line 12157 +-type SemanticTokensClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` - // return value for the corresponding server capability as well. @@ -55793,14 +61963,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensDelta struct { // line 2979 +-type SemanticTokensDelta struct { - ResultID string `json:"resultId,omitempty"` - // The semantic token edits to transform a previous result into a new result. - Edits []SemanticTokensEdit `json:"edits"` -} - -// @since 3.16.0 --type SemanticTokensDeltaParams struct { // line 2946 +-type SemanticTokensDeltaParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The result id of a previous response. The result Id can either point to a full response @@ -55811,12 +61981,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensDeltaPartialResult struct { // line 3005 +-type SemanticTokensDeltaPartialResult struct { - Edits []SemanticTokensEdit `json:"edits"` -} - -// @since 3.16.0 --type SemanticTokensEdit struct { // line 6617 +-type SemanticTokensEdit struct { - // The start offset of the edit. - Start uint32 `json:"start"` - // The count of elements to remove. @@ -55826,7 +61996,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensLegend struct { // line 9314 +-type SemanticTokensLegend struct { - // The token types a server uses. - TokenTypes []string `json:"tokenTypes"` - // The token modifiers a server uses. @@ -55834,7 +62004,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensOptions struct { // line 6546 +-type SemanticTokensOptions struct { - // The legend used by the server - Legend SemanticTokensLegend `json:"legend"` - // Server supports providing semantic tokens for a specific range @@ -55846,7 +62016,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensParams struct { // line 2855 +-type SemanticTokensParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - WorkDoneProgressParams @@ -55854,12 +62024,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensPartialResult struct { // line 2907 +-type SemanticTokensPartialResult struct { - Data []uint32 `json:"data"` -} - -// @since 3.16.0 --type SemanticTokensRangeParams struct { // line 3022 +-type SemanticTokensRangeParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The range the semantic tokens are requested for. @@ -55869,14 +62039,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.16.0 --type SemanticTokensRegistrationOptions struct { // line 2924 +-type SemanticTokensRegistrationOptions struct { - TextDocumentRegistrationOptions - SemanticTokensOptions - StaticRegistrationOptions -} - -// @since 3.16.0 --type SemanticTokensWorkspaceClientCapabilities struct { // line 10977 +-type SemanticTokensWorkspaceClientCapabilities struct { - // Whether the client implementation supports a refresh request sent from - // the server to the client. - // @@ -55889,7 +62059,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// Defines the capabilities provided by a language -// server. --type ServerCapabilities struct { // line 7809 +-type ServerCapabilities struct { - // The position encoding the server picked from the encodings offered - // by the client via the client capability `general.positionEncodings`. - // @@ -55988,32 +62158,37 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // - // @since 3.17.0 - DiagnosticProvider *Or_ServerCapabilities_diagnosticProvider `json:"diagnosticProvider,omitempty"` +- // Inline completion options used during static registration. +- // +- // @since 3.18.0 +- // @proposed +- InlineCompletionProvider *Or_ServerCapabilities_inlineCompletionProvider `json:"inlineCompletionProvider,omitempty"` - // Workspace specific server capabilities. - Workspace *Workspace6Gn `json:"workspace,omitempty"` - // Experimental server capabilities. - Experimental interface{} `json:"experimental,omitempty"` -} --type SetTraceParams struct { // line 6147 +-type SetTraceParams struct { - Value TraceValues `json:"value"` -} - -// Client capabilities for the showDocument request. -// -// @since 3.16.0 --type ShowDocumentClientCapabilities struct { // line 12485 +-type ShowDocumentClientCapabilities struct { - // The client has support for the showDocument - // request. - Support bool `json:"support"` -} - --// Params to show a document. +-// Params to show a resource in the UI. -// -// @since 3.16.0 --type ShowDocumentParams struct { // line 3055 -- // The document uri to show. +-type ShowDocumentParams struct { +- // The uri to show. - URI URI `json:"uri"` - // Indicates to show the resource in an external program. -- // To show for example `https://code.visualstudio.com/` +- // To show, for example, `https://code.visualstudio.com/` - // in the default WEB browser set `external` to `true`. - External bool `json:"external,omitempty"` - // An optional property to indicate whether the editor @@ -56031,13 +62206,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The result of a showDocument request. -// -// @since 3.16.0 --type ShowDocumentResult struct { // line 3097 +-type ShowDocumentResult struct { - // A boolean indicating if the show was successful. - Success bool `json:"success"` -} - -// The parameters of a notification message. --type ShowMessageParams struct { // line 4183 +-type ShowMessageParams struct { - // The message type. See {@link MessageType} - Type MessageType `json:"type"` - // The actual message. @@ -56045,11 +62220,11 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Show message request client capabilities --type ShowMessageRequestClientCapabilities struct { // line 12458 +-type ShowMessageRequestClientCapabilities struct { - // Capabilities specific to the `MessageActionItem` type. - MessageActionItem *PMessageActionItemPShowMessage `json:"messageActionItem,omitempty"` -} --type ShowMessageRequestParams struct { // line 4205 +-type ShowMessageRequestParams struct { - // The message type. See {@link MessageType} - Type MessageType `json:"type"` - // The actual message. @@ -56061,7 +62236,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Signature help represents the signature of something -// callable. There can be multiple signature but only one -// active and only one active parameter. --type SignatureHelp struct { // line 4968 +-type SignatureHelp struct { - // One or more signatures. - Signatures []SignatureInformation `json:"signatures"` - // The active signature. If omitted or the value lies outside the @@ -56085,7 +62260,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Client Capabilities for a {@link SignatureHelpRequest}. --type SignatureHelpClientCapabilities struct { // line 11428 +-type SignatureHelpClientCapabilities struct { - // Whether signature help supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // The client supports the following `SignatureInformation` @@ -56103,7 +62278,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Additional information about the context in which a signature help request was triggered. -// -// @since 3.15.0 --type SignatureHelpContext struct { // line 8787 +-type SignatureHelpContext struct { - // Action that caused signature help to be triggered. - TriggerKind SignatureHelpTriggerKind `json:"triggerKind"` - // Character that caused signature help to be triggered. @@ -56123,7 +62298,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Server Capabilities for a {@link SignatureHelpRequest}. --type SignatureHelpOptions struct { // line 8882 +-type SignatureHelpOptions struct { - // List of characters that trigger signature help automatically. - TriggerCharacters []string `json:"triggerCharacters,omitempty"` - // List of characters that re-trigger signature help. @@ -56137,7 +62312,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Parameters for a {@link SignatureHelpRequest}. --type SignatureHelpParams struct { // line 4940 +-type SignatureHelpParams struct { - // The signature help context. This is only available if the client specifies - // to send this using the client capability `textDocument.signatureHelp.contextSupport === true` - // @@ -56148,7 +62323,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link SignatureHelpRequest}. --type SignatureHelpRegistrationOptions struct { // line 5003 +-type SignatureHelpRegistrationOptions struct { - TextDocumentRegistrationOptions - SignatureHelpOptions -} @@ -56156,11 +62331,12 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// How a signature help was triggered. -// -// @since 3.15.0 --type SignatureHelpTriggerKind uint32 // line 13580 +-type SignatureHelpTriggerKind uint32 +- -// Represents the signature of something callable. A signature -// can have a label, like a function-name, a doc-comment, and -// a set of parameters. --type SignatureInformation struct { // line 8828 +-type SignatureInformation struct { - // The label of this signature. Will be shown in - // the UI. - Label string `json:"label"` @@ -56179,15 +62355,32 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// Static registration options to be returned in the initialize -// request. --type StaticRegistrationOptions struct { // line 6343 +-type StaticRegistrationOptions struct { - // The id used to register the request. The id can be used to deregister - // the request again. See also Registration#id. - ID string `json:"id,omitempty"` -} - +-// A string value used as a snippet is a template which allows to insert text +-// and to control the editor cursor when insertion happens. +-// +-// A snippet can define tab stops and placeholders with `$1`, `$2` +-// and `${3:foo}`. `$0` defines the final tab stop, it defaults to +-// the end of the snippet. Variables are defined with `$name` and +-// `${name:default value}`. +-// +-// @since 3.18.0 +-// @proposed +-type StringValue struct { +- // The kind of string value. +- Kind string `json:"kind"` +- // The snippet string. +- Value string `json:"value"` +-} +- -// Represents information about programming constructs like variables, classes, -// interfaces etc. --type SymbolInformation struct { // line 5181 +-type SymbolInformation struct { - // extends BaseSymbolInformation - // Indicates if this symbol is deprecated. - // @@ -56219,20 +62412,22 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// A symbol kind. --type SymbolKind uint32 // line 12841 +-type SymbolKind uint32 +- -// Symbol tags are extra annotations that tweak the rendering of a symbol. -// -// @since 3.16 --type SymbolTag uint32 // line 12955 +-type SymbolTag uint32 +- -// Describe options to be used when registered for text document change events. --type TextDocumentChangeRegistrationOptions struct { // line 4312 +-type TextDocumentChangeRegistrationOptions struct { - // How documents are synced to the server. - SyncKind TextDocumentSyncKind `json:"syncKind"` - TextDocumentRegistrationOptions -} - -// Text document specific client capabilities. --type TextDocumentClientCapabilities struct { // line 10323 +-type TextDocumentClientCapabilities struct { - // Defines which synchronization capabilities the client supports. - Synchronization *TextDocumentSyncClientCapabilities `json:"synchronization,omitempty"` - // Capabilities specific to the `textDocument/completion` request. @@ -56322,16 +62517,21 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // - // @since 3.17.0 - Diagnostic *DiagnosticClientCapabilities `json:"diagnostic,omitempty"` +- // Client capabilities specific to inline completions. +- // +- // @since 3.18.0 +- // @proposed +- InlineCompletion *InlineCompletionClientCapabilities `json:"inlineCompletion,omitempty"` -} - -// An event describing a change to a text document. If only a text is provided -// it is considered to be the full content of the document. --type TextDocumentContentChangeEvent = Msg_TextDocumentContentChangeEvent // (alias) line 14002 +-type TextDocumentContentChangeEvent = Msg_TextDocumentContentChangeEvent // (alias) line 14417 -// Describes textual changes on a text document. A TextDocumentEdit describes all changes -// on a document version Si and after they are applied move the document to version Si+1. -// So the creator of a TextDocumentEdit doesn't need to sort the array of edits or do any -// kind of ordering. However the edits must be non overlapping. --type TextDocumentEdit struct { // line 6677 +-type TextDocumentEdit struct { - // The text document to change. - TextDocument OptionalVersionedTextDocumentIdentifier `json:"textDocument"` - // The edits to be applied. @@ -56358,16 +62558,16 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// @sample A language filter that applies to all package.json paths: `{ language: 'json', pattern: '**package.json' }` -// -// @since 3.17.0 --type TextDocumentFilter = Msg_TextDocumentFilter // (alias) line 14145 +-type TextDocumentFilter = Msg_TextDocumentFilter // (alias) line 14560 -// A literal to identify a text document in the client. --type TextDocumentIdentifier struct { // line 6419 +-type TextDocumentIdentifier struct { - // The text document's uri. - URI DocumentURI `json:"uri"` -} - -// An item to transfer a text document from the client to the -// server. --type TextDocumentItem struct { // line 7405 +-type TextDocumentItem struct { - // The text document's uri. - URI DocumentURI `json:"uri"` - // The text document's language identifier. @@ -56381,7 +62581,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// A parameter literal used in requests to pass a text document and a position inside that -// document. --type TextDocumentPositionParams struct { // line 6222 +-type TextDocumentPositionParams struct { - // The text document. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The position inside the text document. @@ -56389,20 +62589,21 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// General text document registration options. --type TextDocumentRegistrationOptions struct { // line 2368 +-type TextDocumentRegistrationOptions struct { - // A document selector to identify the scope of the registration. If set to null - // the document selector provided on the client side will be used. - DocumentSelector DocumentSelector `json:"documentSelector"` -} - -// Represents reasons why a text document is saved. --type TextDocumentSaveReason uint32 // line 13109 +-type TextDocumentSaveReason uint32 +- -// Save registration options. --type TextDocumentSaveRegistrationOptions struct { // line 4369 +-type TextDocumentSaveRegistrationOptions struct { - TextDocumentRegistrationOptions - SaveOptions -} --type TextDocumentSyncClientCapabilities struct { // line 11127 +-type TextDocumentSyncClientCapabilities struct { - // Whether text document synchronization supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // The client supports sending will save notifications. @@ -56417,8 +62618,8 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - -// Defines how the host (editor) should sync -// document changes to the language server. --type TextDocumentSyncKind uint32 // line 13084 --type TextDocumentSyncOptions struct { // line 9736 +-type TextDocumentSyncKind uint32 +-type TextDocumentSyncOptions struct { - // Open and close notifications are sent to the server. If omitted open close notification should not - // be sent. - OpenClose bool `json:"openClose,omitempty"` @@ -56437,7 +62638,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// A text edit applicable to a text document. --type TextEdit struct { // line 4406 +-type TextEdit struct { - // The range of the text document to be manipulated. To insert - // text into a document create a range where start === end. - Range Range `json:"range"` @@ -56445,10 +62646,11 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // empty string. - NewText string `json:"newText"` -} --type TokenFormat string // line 13736 --type TraceValues string // line 13383 +-type TokenFormat string +-type TraceValues string +- -// Since 3.6.0 --type TypeDefinitionClientCapabilities struct { // line 11559 +-type TypeDefinitionClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `TypeDefinitionRegistrationOptions` return value - // for the corresponding server capability as well. @@ -56458,22 +62660,22 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // Since 3.14.0 - LinkSupport bool `json:"linkSupport,omitempty"` -} --type TypeDefinitionOptions struct { // line 6358 +-type TypeDefinitionOptions struct { - WorkDoneProgressOptions -} --type TypeDefinitionParams struct { // line 2123 +-type TypeDefinitionParams struct { - TextDocumentPositionParams - WorkDoneProgressParams - PartialResultParams -} --type TypeDefinitionRegistrationOptions struct { // line 2143 +-type TypeDefinitionRegistrationOptions struct { - TextDocumentRegistrationOptions - TypeDefinitionOptions - StaticRegistrationOptions -} - -// @since 3.17.0 --type TypeHierarchyClientCapabilities struct { // line 12337 +-type TypeHierarchyClientCapabilities struct { - // Whether implementation supports dynamic registration. If this is set to `true` - // the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)` - // return value for the corresponding server capability as well. @@ -56481,7 +62683,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// @since 3.17.0 --type TypeHierarchyItem struct { // line 3410 +-type TypeHierarchyItem struct { - // The name of this item. - Name string `json:"name"` - // The kind of this item. @@ -56509,14 +62711,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Type hierarchy options used during static registration. -// -// @since 3.17.0 --type TypeHierarchyOptions struct { // line 6936 +-type TypeHierarchyOptions struct { - WorkDoneProgressOptions -} - -// The parameter of a `textDocument/prepareTypeHierarchy` request. -// -// @since 3.17.0 --type TypeHierarchyPrepareParams struct { // line 3392 +-type TypeHierarchyPrepareParams struct { - TextDocumentPositionParams - WorkDoneProgressParams -} @@ -56524,7 +62726,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Type hierarchy options used during static or dynamic registration. -// -// @since 3.17.0 --type TypeHierarchyRegistrationOptions struct { // line 3487 +-type TypeHierarchyRegistrationOptions struct { - TextDocumentRegistrationOptions - TypeHierarchyOptions - StaticRegistrationOptions @@ -56533,7 +62735,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The parameter of a `typeHierarchy/subtypes` request. -// -// @since 3.17.0 --type TypeHierarchySubtypesParams struct { // line 3533 +-type TypeHierarchySubtypesParams struct { - Item TypeHierarchyItem `json:"item"` - WorkDoneProgressParams - PartialResultParams @@ -56542,14 +62744,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// The parameter of a `typeHierarchy/supertypes` request. -// -// @since 3.17.0 --type TypeHierarchySupertypesParams struct { // line 3509 +-type TypeHierarchySupertypesParams struct { - Item TypeHierarchyItem `json:"item"` - WorkDoneProgressParams - PartialResultParams -} - -// created for Tuple --type UIntCommaUInt struct { // line 10076 +-type UIntCommaUInt struct { - Fld0 uint32 `json:"fld0"` - Fld1 uint32 `json:"fld1"` -} @@ -56559,7 +62761,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// report is still accurate. -// -// @since 3.17.0 --type UnchangedDocumentDiagnosticReport struct { // line 7270 +-type UnchangedDocumentDiagnosticReport struct { - // A document diagnostic report indicating - // no changes to the last result. A server can - // only return `unchanged` if result ids are @@ -56573,23 +62775,24 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Moniker uniqueness level to define scope of the moniker. -// -// @since 3.16.0 --type UniquenessLevel string // line 12971 +-type UniquenessLevel string +- -// General parameters to unregister a request or notification. --type Unregistration struct { // line 7628 +-type Unregistration struct { - // The id used to unregister the request or notification. Usually an id - // provided during the register request. - ID string `json:"id"` - // The method to unregister for. - Method string `json:"method"` -} --type UnregistrationParams struct { // line 4053 +-type UnregistrationParams struct { - Unregisterations []Unregistration `json:"unregisterations"` -} - -// A versioned notebook document identifier. -// -// @since 3.17.0 --type VersionedNotebookDocumentIdentifier struct { // line 7443 +-type VersionedNotebookDocumentIdentifier struct { - // The version number of this notebook document. - Version int32 `json:"version"` - // The notebook document's uri. @@ -56597,19 +62800,19 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// A text document identifier to denote a specific version of a text document. --type VersionedTextDocumentIdentifier struct { // line 8445 +-type VersionedTextDocumentIdentifier struct { - // The version number of this document. - Version int32 `json:"version"` - TextDocumentIdentifier -} --type WatchKind = uint32 // line 13505// The parameters sent in a will save text document notification. --type WillSaveTextDocumentParams struct { // line 4384 +-type WatchKind = uint32 // line 13505// The parameters sent in a will save text document notification. +-type WillSaveTextDocumentParams struct { - // The document that will be saved. - TextDocument TextDocumentIdentifier `json:"textDocument"` - // The 'TextDocumentSaveReason'. - Reason TextDocumentSaveReason `json:"reason"` -} --type WindowClientCapabilities struct { // line 10629 +-type WindowClientCapabilities struct { - // It indicates whether the client supports server initiated - // progress using the `window/workDoneProgress/create` request. - // @@ -56629,7 +62832,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // @since 3.16.0 - ShowDocument *ShowDocumentClientCapabilities `json:"showDocument,omitempty"` -} --type WorkDoneProgressBegin struct { // line 6040 +-type WorkDoneProgressBegin struct { - Kind string `json:"kind"` - // Mandatory title of the progress operation. Used to briefly inform about - // the kind of operation being performed. @@ -56654,34 +62857,34 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // that are not following this rule. The value range is [0, 100]. - Percentage uint32 `json:"percentage,omitempty"` -} --type WorkDoneProgressCancelParams struct { // line 2625 +-type WorkDoneProgressCancelParams struct { - // The token to be used to report progress. - Token ProgressToken `json:"token"` -} --type WorkDoneProgressCreateParams struct { // line 2612 +-type WorkDoneProgressCreateParams struct { - // The token to be used to report progress. - Token ProgressToken `json:"token"` -} --type WorkDoneProgressEnd struct { // line 6126 +-type WorkDoneProgressEnd struct { - Kind string `json:"kind"` - // Optional, a final message indicating to for example indicate the outcome - // of the operation. - Message string `json:"message,omitempty"` -} --type WorkDoneProgressOptions struct { // line 2355 +-type WorkDoneProgressOptions struct { - WorkDoneProgress bool `json:"workDoneProgress,omitempty"` -} - -// created for And --type WorkDoneProgressOptionsAndTextDocumentRegistrationOptions struct { // line 196 +-type WorkDoneProgressOptionsAndTextDocumentRegistrationOptions struct { - WorkDoneProgressOptions - TextDocumentRegistrationOptions -} --type WorkDoneProgressParams struct { // line 6244 +-type WorkDoneProgressParams struct { - // An optional token that a server can use to report work done progress. - WorkDoneToken ProgressToken `json:"workDoneToken,omitempty"` -} --type WorkDoneProgressReport struct { // line 6087 +-type WorkDoneProgressReport struct { - Kind string `json:"kind"` - // Controls enablement state of a cancel button. - // @@ -56704,7 +62907,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// created for Literal (Lit_ServerCapabilities_workspace) --type Workspace6Gn struct { // line 8404 +-type Workspace6Gn struct { - // The server supports workspace folder. - // - // @since 3.6.0 @@ -56716,7 +62919,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Workspace specific client capabilities. --type WorkspaceClientCapabilities struct { // line 10184 +-type WorkspaceClientCapabilities struct { - // The client supports applying batch edits - // to the workspace by supporting the request - // 'workspace/applyEdit' @@ -56773,7 +62976,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// Parameters of the workspace diagnostic request. -// -// @since 3.17.0 --type WorkspaceDiagnosticParams struct { // line 3877 +-type WorkspaceDiagnosticParams struct { - // The additional identifier provided during registration. - Identifier string `json:"identifier,omitempty"` - // The currently known diagnostic reports with their @@ -56786,21 +62989,21 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A workspace diagnostic report. -// -// @since 3.17.0 --type WorkspaceDiagnosticReport struct { // line 3914 +-type WorkspaceDiagnosticReport struct { - Items []WorkspaceDocumentDiagnosticReport `json:"items"` -} - -// A partial result for a workspace diagnostic report. -// -// @since 3.17.0 --type WorkspaceDiagnosticReportPartialResult struct { // line 3931 +-type WorkspaceDiagnosticReportPartialResult struct { - Items []WorkspaceDocumentDiagnosticReport `json:"items"` -} - -// A workspace diagnostic document report. -// -// @since 3.17.0 --type WorkspaceDocumentDiagnosticReport = Or_WorkspaceDocumentDiagnosticReport // (alias) line 13984 +-type WorkspaceDocumentDiagnosticReport = Or_WorkspaceDocumentDiagnosticReport // (alias) line 14399 -// A workspace edit represents changes to many resources managed in the workspace. The edit -// should either provide `changes` or `documentChanges`. If documentChanges are present -// they are preferred over `changes` if the client can handle versioned document edits. @@ -56813,7 +63016,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// An invalid sequence (e.g. (1) delete file a.txt and (2) insert text into file a.txt) will -// cause failure of the operation. How the client recovers from the failure is described by -// the client capability: `workspace.workspaceEdit.failureHandling` --type WorkspaceEdit struct { // line 3193 +-type WorkspaceEdit struct { - // Holds changes to existing resources. - Changes map[DocumentURI][]TextEdit `json:"changes,omitempty"` - // Depending on the client capability `workspace.workspaceEdit.resourceOperations` document changes @@ -56835,7 +63038,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // @since 3.16.0 - ChangeAnnotations map[ChangeAnnotationIdentifier]ChangeAnnotation `json:"changeAnnotations,omitempty"` -} --type WorkspaceEditClientCapabilities struct { // line 10768 +-type WorkspaceEditClientCapabilities struct { - // The client supports versioned document changes in `WorkspaceEdit`s - DocumentChanges bool `json:"documentChanges,omitempty"` - // The resource operations the client supports. Clients should at least @@ -56864,14 +63067,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// A workspace folder inside a client. --type WorkspaceFolder struct { // line 2163 +-type WorkspaceFolder struct { - // The associated URI for this workspace folder. - URI URI `json:"uri"` - // The name of the workspace folder. Used to refer to this - // workspace folder in the user interface. - Name string `json:"name"` -} --type WorkspaceFolders5Gn struct { // line 9933 +-type WorkspaceFolders5Gn struct { - // The server has support for workspace folders - Supported bool `json:"supported,omitempty"` - // Whether the server wants to receive workspace folder @@ -56885,13 +63088,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The workspace folder change event. --type WorkspaceFoldersChangeEvent struct { // line 6368 +-type WorkspaceFoldersChangeEvent struct { - // The array of added workspace folders - Added []WorkspaceFolder `json:"added"` - // The array of the removed workspace folders - Removed []WorkspaceFolder `json:"removed"` -} --type WorkspaceFoldersInitializeParams struct { // line 7782 +-type WorkspaceFoldersInitializeParams struct { - // The workspace folders configured in the client when the server starts. - // - // This property is only available if the client supports workspace folders. @@ -56901,7 +63104,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // @since 3.6.0 - WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders,omitempty"` -} --type WorkspaceFoldersServerCapabilities struct { // line 9933 +-type WorkspaceFoldersServerCapabilities struct { - // The server has support for workspace folders - Supported bool `json:"supported,omitempty"` - // Whether the server wants to receive workspace folder @@ -56917,7 +63120,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// A full document diagnostic report for a workspace diagnostic result. -// -// @since 3.17.0 --type WorkspaceFullDocumentDiagnosticReport struct { // line 9522 +-type WorkspaceFullDocumentDiagnosticReport struct { - // The URI for which diagnostic information is reported. - URI DocumentURI `json:"uri"` - // The version number for which the diagnostics are reported. @@ -56931,7 +63134,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -// See also SymbolInformation. -// -// @since 3.17.0 --type WorkspaceSymbol struct { // line 5515 +-type WorkspaceSymbol struct { - // The location of the symbol. Whether a server is allowed to - // return a location without a range depends on the client - // capability `workspace.symbol.resolveSupport`. @@ -56945,7 +63148,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Client capabilities for a {@link WorkspaceSymbolRequest}. --type WorkspaceSymbolClientCapabilities struct { // line 10875 +-type WorkspaceSymbolClientCapabilities struct { - // Symbol request supports dynamic registration. - DynamicRegistration bool `json:"dynamicRegistration,omitempty"` - // Specific capabilities for the `SymbolKind` in the `workspace/symbol` request. @@ -56964,7 +63167,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Server capabilities for a {@link WorkspaceSymbolRequest}. --type WorkspaceSymbolOptions struct { // line 9105 +-type WorkspaceSymbolOptions struct { - // The server provides support to resolve additional - // information for a workspace symbol. - // @@ -56974,7 +63177,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The parameters of a {@link WorkspaceSymbolRequest}. --type WorkspaceSymbolParams struct { // line 5491 +-type WorkspaceSymbolParams struct { - // A query string to filter symbols by. Clients may send an empty - // string here to request all symbols. - Query string `json:"query"` @@ -56983,14 +63186,14 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// Registration options for a {@link WorkspaceSymbolRequest}. --type WorkspaceSymbolRegistrationOptions struct { // line 5564 +-type WorkspaceSymbolRegistrationOptions struct { - WorkspaceSymbolOptions -} - -// An unchanged document diagnostic report for a workspace diagnostic result. -// -// @since 3.17.0 --type WorkspaceUnchangedDocumentDiagnosticReport struct { // line 9560 +-type WorkspaceUnchangedDocumentDiagnosticReport struct { - // The URI for which diagnostic information is reported. - URI DocumentURI `json:"uri"` - // The version number for which the diagnostics are reported. @@ -57000,7 +63203,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The initialize parameters --type XInitializeParams struct { // line 7650 +-type XInitializeParams struct { - // The process Id of the parent process that started - // the server. - // @@ -57041,7 +63244,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -} - -// The initialize parameters --type _InitializeParams struct { // line 7650 +-type _InitializeParams struct { - // The process Id of the parent process that started - // the server. - // @@ -57084,11 +63287,11 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto -const ( - // A set of predefined code action kinds - // Empty kind. -- Empty CodeActionKind = "" // line 13333 +- Empty CodeActionKind = "" - // Base kind for quickfix actions: 'quickfix' -- QuickFix CodeActionKind = "quickfix" // line 13338 +- QuickFix CodeActionKind = "quickfix" - // Base kind for refactoring actions: 'refactor' -- Refactor CodeActionKind = "refactor" // line 13343 +- Refactor CodeActionKind = "refactor" - // Base kind for refactoring extraction actions: 'refactor.extract' - // - // Example extract actions: @@ -57099,7 +63302,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // - Extract variable - // - Extract interface from class - // - ... -- RefactorExtract CodeActionKind = "refactor.extract" // line 13348 +- RefactorExtract CodeActionKind = "refactor.extract" - // Base kind for refactoring inline actions: 'refactor.inline' - // - // Example inline actions: @@ -57109,7 +63312,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // - Inline variable - // - Inline constant - // - ... -- RefactorInline CodeActionKind = "refactor.inline" // line 13353 +- RefactorInline CodeActionKind = "refactor.inline" - // Base kind for refactoring rewrite actions: 'refactor.rewrite' - // - // Example rewrite actions: @@ -57121,80 +63324,80 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // - Make method static - // - Move method to base class - // - ... -- RefactorRewrite CodeActionKind = "refactor.rewrite" // line 13358 +- RefactorRewrite CodeActionKind = "refactor.rewrite" - // Base kind for source actions: `source` - // - // Source code actions apply to the entire file. -- Source CodeActionKind = "source" // line 13363 +- Source CodeActionKind = "source" - // Base kind for an organize imports source action: `source.organizeImports` -- SourceOrganizeImports CodeActionKind = "source.organizeImports" // line 13368 +- SourceOrganizeImports CodeActionKind = "source.organizeImports" - // Base kind for auto-fix source actions: `source.fixAll`. - // - // Fix all actions automatically fix errors that have a clear fix that do not require user input. - // They should not suppress errors or perform unsafe fixes such as generating new types or classes. - // - // @since 3.15.0 -- SourceFixAll CodeActionKind = "source.fixAll" // line 13373 +- SourceFixAll CodeActionKind = "source.fixAll" - // The reason why code actions were requested. - // - // @since 3.17.0 - // Code actions were explicitly requested by the user or by an extension. -- CodeActionInvoked CodeActionTriggerKind = 1 // line 13613 +- CodeActionInvoked CodeActionTriggerKind = 1 - // Code actions were requested automatically. - // - // This typically happens when current selection in a file changes, but can - // also be triggered when file content changes. -- CodeActionAutomatic CodeActionTriggerKind = 2 // line 13618 +- CodeActionAutomatic CodeActionTriggerKind = 2 - // The kind of a completion entry. -- TextCompletion CompletionItemKind = 1 // line 13141 -- MethodCompletion CompletionItemKind = 2 // line 13145 -- FunctionCompletion CompletionItemKind = 3 // line 13149 -- ConstructorCompletion CompletionItemKind = 4 // line 13153 -- FieldCompletion CompletionItemKind = 5 // line 13157 -- VariableCompletion CompletionItemKind = 6 // line 13161 -- ClassCompletion CompletionItemKind = 7 // line 13165 -- InterfaceCompletion CompletionItemKind = 8 // line 13169 -- ModuleCompletion CompletionItemKind = 9 // line 13173 -- PropertyCompletion CompletionItemKind = 10 // line 13177 -- UnitCompletion CompletionItemKind = 11 // line 13181 -- ValueCompletion CompletionItemKind = 12 // line 13185 -- EnumCompletion CompletionItemKind = 13 // line 13189 -- KeywordCompletion CompletionItemKind = 14 // line 13193 -- SnippetCompletion CompletionItemKind = 15 // line 13197 -- ColorCompletion CompletionItemKind = 16 // line 13201 -- FileCompletion CompletionItemKind = 17 // line 13205 -- ReferenceCompletion CompletionItemKind = 18 // line 13209 -- FolderCompletion CompletionItemKind = 19 // line 13213 -- EnumMemberCompletion CompletionItemKind = 20 // line 13217 -- ConstantCompletion CompletionItemKind = 21 // line 13221 -- StructCompletion CompletionItemKind = 22 // line 13225 -- EventCompletion CompletionItemKind = 23 // line 13229 -- OperatorCompletion CompletionItemKind = 24 // line 13233 -- TypeParameterCompletion CompletionItemKind = 25 // line 13237 +- TextCompletion CompletionItemKind = 1 +- MethodCompletion CompletionItemKind = 2 +- FunctionCompletion CompletionItemKind = 3 +- ConstructorCompletion CompletionItemKind = 4 +- FieldCompletion CompletionItemKind = 5 +- VariableCompletion CompletionItemKind = 6 +- ClassCompletion CompletionItemKind = 7 +- InterfaceCompletion CompletionItemKind = 8 +- ModuleCompletion CompletionItemKind = 9 +- PropertyCompletion CompletionItemKind = 10 +- UnitCompletion CompletionItemKind = 11 +- ValueCompletion CompletionItemKind = 12 +- EnumCompletion CompletionItemKind = 13 +- KeywordCompletion CompletionItemKind = 14 +- SnippetCompletion CompletionItemKind = 15 +- ColorCompletion CompletionItemKind = 16 +- FileCompletion CompletionItemKind = 17 +- ReferenceCompletion CompletionItemKind = 18 +- FolderCompletion CompletionItemKind = 19 +- EnumMemberCompletion CompletionItemKind = 20 +- ConstantCompletion CompletionItemKind = 21 +- StructCompletion CompletionItemKind = 22 +- EventCompletion CompletionItemKind = 23 +- OperatorCompletion CompletionItemKind = 24 +- TypeParameterCompletion CompletionItemKind = 25 - // Completion item tags are extra annotations that tweak the rendering of a completion - // item. - // - // @since 3.15.0 - // Render a completion as obsolete, usually using a strike-out. -- ComplDeprecated CompletionItemTag = 1 // line 13251 +- ComplDeprecated CompletionItemTag = 1 - // How a completion was triggered - // Completion was triggered by typing an identifier (24x7 code - // complete), manual invocation (e.g Ctrl+Space) or via API. -- Invoked CompletionTriggerKind = 1 // line 13562 +- Invoked CompletionTriggerKind = 1 - // Completion was triggered by a trigger character specified by - // the `triggerCharacters` properties of the `CompletionRegistrationOptions`. -- TriggerCharacter CompletionTriggerKind = 2 // line 13567 +- TriggerCharacter CompletionTriggerKind = 2 - // Completion was re-triggered as current completion list is incomplete -- TriggerForIncompleteCompletions CompletionTriggerKind = 3 // line 13572 +- TriggerForIncompleteCompletions CompletionTriggerKind = 3 - // The diagnostic's severity. - // Reports an error. -- SeverityError DiagnosticSeverity = 1 // line 13511 +- SeverityError DiagnosticSeverity = 1 - // Reports a warning. -- SeverityWarning DiagnosticSeverity = 2 // line 13516 +- SeverityWarning DiagnosticSeverity = 2 - // Reports an information. -- SeverityInformation DiagnosticSeverity = 3 // line 13521 +- SeverityInformation DiagnosticSeverity = 3 - // Reports a hint. -- SeverityHint DiagnosticSeverity = 4 // line 13526 +- SeverityHint DiagnosticSeverity = 4 - // The diagnostic tags. - // - // @since 3.15.0 @@ -57202,83 +63405,91 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // - // Clients are allowed to render diagnostics with this tag faded out instead of having - // an error squiggle. -- Unnecessary DiagnosticTag = 1 // line 13541 +- Unnecessary DiagnosticTag = 1 - // Deprecated or obsolete code. - // - // Clients are allowed to rendered diagnostics with this tag strike through. -- Deprecated DiagnosticTag = 2 // line 13546 +- Deprecated DiagnosticTag = 2 - // The document diagnostic report kinds. - // - // @since 3.17.0 - // A diagnostic report with a full - // set of problems. -- DiagnosticFull DocumentDiagnosticReportKind = "full" // line 12729 +- DiagnosticFull DocumentDiagnosticReportKind = "full" - // A report indicating that the last - // returned report is still accurate. -- DiagnosticUnchanged DocumentDiagnosticReportKind = "unchanged" // line 12734 +- DiagnosticUnchanged DocumentDiagnosticReportKind = "unchanged" - // A document highlight kind. - // A textual occurrence. -- Text DocumentHighlightKind = 1 // line 13308 +- Text DocumentHighlightKind = 1 - // Read-access of a symbol, like reading a variable. -- Read DocumentHighlightKind = 2 // line 13313 +- Read DocumentHighlightKind = 2 - // Write-access of a symbol, like writing to a variable. -- Write DocumentHighlightKind = 3 // line 13318 +- Write DocumentHighlightKind = 3 - // Predefined error codes. -- ParseError ErrorCodes = -32700 // line 12750 -- InvalidRequest ErrorCodes = -32600 // line 12754 -- MethodNotFound ErrorCodes = -32601 // line 12758 -- InvalidParams ErrorCodes = -32602 // line 12762 -- InternalError ErrorCodes = -32603 // line 12766 +- ParseError ErrorCodes = -32700 +- InvalidRequest ErrorCodes = -32600 +- MethodNotFound ErrorCodes = -32601 +- InvalidParams ErrorCodes = -32602 +- InternalError ErrorCodes = -32603 - // Error code indicating that a server received a notification or - // request before the server has received the `initialize` request. -- ServerNotInitialized ErrorCodes = -32002 // line 12770 -- UnknownErrorCode ErrorCodes = -32001 // line 12775 +- ServerNotInitialized ErrorCodes = -32002 +- UnknownErrorCode ErrorCodes = -32001 - // Applying the workspace change is simply aborted if one of the changes provided - // fails. All operations executed before the failing operation stay executed. -- Abort FailureHandlingKind = "abort" // line 13700 +- Abort FailureHandlingKind = "abort" - // All operations are executed transactional. That means they either all - // succeed or no changes at all are applied to the workspace. -- Transactional FailureHandlingKind = "transactional" // line 13705 +- Transactional FailureHandlingKind = "transactional" - // If the workspace edit contains only textual file changes they are executed transactional. - // If resource changes (create, rename or delete file) are part of the change the failure - // handling strategy is abort. -- TextOnlyTransactional FailureHandlingKind = "textOnlyTransactional" // line 13710 +- TextOnlyTransactional FailureHandlingKind = "textOnlyTransactional" - // The client tries to undo the operations already executed. But there is no - // guarantee that this is succeeding. -- Undo FailureHandlingKind = "undo" // line 13715 +- Undo FailureHandlingKind = "undo" - // The file event type - // The file got created. -- Created FileChangeType = 1 // line 13461 +- Created FileChangeType = 1 - // The file got changed. -- Changed FileChangeType = 2 // line 13466 +- Changed FileChangeType = 2 - // The file got deleted. -- Deleted FileChangeType = 3 // line 13471 +- Deleted FileChangeType = 3 - // A pattern kind describing if a glob pattern matches a file a folder or - // both. - // - // @since 3.16.0 - // The pattern matches a file only. -- FilePattern FileOperationPatternKind = "file" // line 13634 +- FilePattern FileOperationPatternKind = "file" - // The pattern matches a folder only. -- FolderPattern FileOperationPatternKind = "folder" // line 13639 +- FolderPattern FileOperationPatternKind = "folder" - // A set of predefined range kinds. - // Folding range for a comment -- Comment FoldingRangeKind = "comment" // line 12822 +- Comment FoldingRangeKind = "comment" - // Folding range for an import or include -- Imports FoldingRangeKind = "imports" // line 12827 +- Imports FoldingRangeKind = "imports" - // Folding range for a region (e.g. `#region`) -- Region FoldingRangeKind = "region" // line 12832 +- Region FoldingRangeKind = "region" - // Inlay hint kinds. - // - // @since 3.17.0 - // An inlay hint that for a type annotation. -- Type InlayHintKind = 1 // line 13040 +- Type InlayHintKind = 1 - // An inlay hint that is for a parameter. -- Parameter InlayHintKind = 2 // line 13045 +- Parameter InlayHintKind = 2 +- // Describes how an {@link InlineCompletionItemProvider inline completion provider} was triggered. +- // +- // @since 3.18.0 +- // @proposed +- // Completion was triggered explicitly by a user gesture. +- InlineInvoked InlineCompletionTriggerKind = 0 +- // Completion was triggered automatically while editing. +- InlineAutomatic InlineCompletionTriggerKind = 1 - // Defines whether the insert text in a completion item should be interpreted as - // plain text or a snippet. - // The primary text to be inserted is treated as a plain string. -- PlainTextTextFormat InsertTextFormat = 1 // line 13267 +- PlainTextTextFormat InsertTextFormat = 1 - // The primary text to be inserted is treated as a snippet. - // - // A snippet can define tab stops and placeholders with `$1`, `$2` @@ -57287,7 +63498,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // that is typing in one will update others too. - // - // See also: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax -- SnippetTextFormat InsertTextFormat = 2 // line 13272 +- SnippetTextFormat InsertTextFormat = 2 - // How whitespace and indentation is handled during completion - // item insertion. - // @@ -57297,7 +63508,7 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // inserted using the indentation defined in the string value. - // The client will not apply any kind of adjustments to the - // string. -- AsIs InsertTextMode = 1 // line 13287 +- AsIs InsertTextMode = 1 - // The editor adjusts leading whitespace of new lines so that - // they match the indentation up to the cursor of the line for - // which the item is accepted. @@ -57305,20 +63516,20 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // Consider a line like this: <2tabs><3tabs>foo. Accepting a - // multi line completion item is indented using 2 tabs and all - // following lines inserted will be indented using 2 tabs as well. -- AdjustIndentation InsertTextMode = 2 // line 13292 +- AdjustIndentation InsertTextMode = 2 - // A request failed but it was syntactically correct, e.g the - // method name was known and the parameters were valid. The error - // message should contain human readable information about why - // the request failed. - // - // @since 3.17.0 -- RequestFailed LSPErrorCodes = -32803 // line 12790 +- RequestFailed LSPErrorCodes = -32803 - // The server cancelled the request. This error code should - // only be used for requests that explicitly support being - // server cancellable. - // - // @since 3.17.0 -- ServerCancelled LSPErrorCodes = -32802 // line 12796 +- ServerCancelled LSPErrorCodes = -32802 - // The server detected that the content of a document got - // modified outside normal conditions. A server should - // NOT send this error code if it detects a content change @@ -57327,207 +63538,207 @@ diff -urN a/gopls/internal/lsp/protocol/tsprotocol.go b/gopls/internal/lsp/proto - // - // If a client decides that a result is not of any use anymore - // the client should cancel the request. -- ContentModified LSPErrorCodes = -32801 // line 12802 +- ContentModified LSPErrorCodes = -32801 - // The client has canceled a request and a server as detected - // the cancel. -- RequestCancelled LSPErrorCodes = -32800 // line 12807 +- RequestCancelled LSPErrorCodes = -32800 - // Describes the content type that a client supports in various - // result literals like `Hover`, `ParameterInfo` or `CompletionItem`. - // - // Please note that `MarkupKinds` must not start with a `$`. This kinds - // are reserved for internal usage. - // Plain text is supported as a content format -- PlainText MarkupKind = "plaintext" // line 13414 +- PlainText MarkupKind = "plaintext" - // Markdown is supported as a content format -- Markdown MarkupKind = "markdown" // line 13419 +- Markdown MarkupKind = "markdown" - // The message type - // An error message. -- Error MessageType = 1 // line 13061 +- Error MessageType = 1 - // A warning message. -- Warning MessageType = 2 // line 13066 +- Warning MessageType = 2 - // An information message. -- Info MessageType = 3 // line 13071 +- Info MessageType = 3 - // A log message. -- Log MessageType = 4 // line 13076 +- Log MessageType = 4 - // The moniker kind. - // - // @since 3.16.0 - // The moniker represent a symbol that is imported into a project -- Import MonikerKind = "import" // line 13014 +- Import MonikerKind = "import" - // The moniker represents a symbol that is exported from a project -- Export MonikerKind = "export" // line 13019 +- Export MonikerKind = "export" - // The moniker represents a symbol that is local to a project (e.g. a local - // variable of a function, a class not visible outside the project, ...) -- Local MonikerKind = "local" // line 13024 +- Local MonikerKind = "local" - // A notebook cell kind. - // - // @since 3.17.0 - // A markup-cell is formatted source that is used for display. -- Markup NotebookCellKind = 1 // line 13655 +- Markup NotebookCellKind = 1 - // A code-cell is source code. -- Code NotebookCellKind = 2 // line 13660 +- Code NotebookCellKind = 2 - // A set of predefined position encoding kinds. - // - // @since 3.17.0 -- // Character offsets count UTF-8 code units. -- UTF8 PositionEncodingKind = "utf-8" // line 13434 +- // Character offsets count UTF-8 code units (e.g. bytes). +- UTF8 PositionEncodingKind = "utf-8" - // Character offsets count UTF-16 code units. - // - // This is the default and must always be supported - // by servers -- UTF16 PositionEncodingKind = "utf-16" // line 13439 +- UTF16 PositionEncodingKind = "utf-16" - // Character offsets count UTF-32 code units. - // -- // Implementation note: these are the same as Unicode code points, +- // Implementation note: these are the same as Unicode codepoints, - // so this `PositionEncodingKind` may also be used for an - // encoding-agnostic representation of character offsets. -- UTF32 PositionEncodingKind = "utf-32" // line 13444 +- UTF32 PositionEncodingKind = "utf-32" - // The client's default behavior is to select the identifier - // according the to language's syntax rule. -- Identifier PrepareSupportDefaultBehavior = 1 // line 13729 +- Identifier PrepareSupportDefaultBehavior = 1 - // Supports creating new files and folders. -- Create ResourceOperationKind = "create" // line 13676 +- Create ResourceOperationKind = "create" - // Supports renaming existing files and folders. -- Rename ResourceOperationKind = "rename" // line 13681 +- Rename ResourceOperationKind = "rename" - // Supports deleting existing files and folders. -- Delete ResourceOperationKind = "delete" // line 13686 +- Delete ResourceOperationKind = "delete" - // A set of predefined token modifiers. This set is not fixed - // an clients can specify additional token types via the - // corresponding client capabilities. - // - // @since 3.16.0 -- ModDeclaration SemanticTokenModifiers = "declaration" // line 12677 -- ModDefinition SemanticTokenModifiers = "definition" // line 12681 -- ModReadonly SemanticTokenModifiers = "readonly" // line 12685 -- ModStatic SemanticTokenModifiers = "static" // line 12689 -- ModDeprecated SemanticTokenModifiers = "deprecated" // line 12693 -- ModAbstract SemanticTokenModifiers = "abstract" // line 12697 -- ModAsync SemanticTokenModifiers = "async" // line 12701 -- ModModification SemanticTokenModifiers = "modification" // line 12705 -- ModDocumentation SemanticTokenModifiers = "documentation" // line 12709 -- ModDefaultLibrary SemanticTokenModifiers = "defaultLibrary" // line 12713 +- ModDeclaration SemanticTokenModifiers = "declaration" +- ModDefinition SemanticTokenModifiers = "definition" +- ModReadonly SemanticTokenModifiers = "readonly" +- ModStatic SemanticTokenModifiers = "static" +- ModDeprecated SemanticTokenModifiers = "deprecated" +- ModAbstract SemanticTokenModifiers = "abstract" +- ModAsync SemanticTokenModifiers = "async" +- ModModification SemanticTokenModifiers = "modification" +- ModDocumentation SemanticTokenModifiers = "documentation" +- ModDefaultLibrary SemanticTokenModifiers = "defaultLibrary" - // A set of predefined token types. This set is not fixed - // an clients can specify additional token types via the - // corresponding client capabilities. - // - // @since 3.16.0 -- NamespaceType SemanticTokenTypes = "namespace" // line 12570 +- NamespaceType SemanticTokenTypes = "namespace" - // Represents a generic type. Acts as a fallback for types which can't be mapped to - // a specific type like class or enum. -- TypeType SemanticTokenTypes = "type" // line 12574 -- ClassType SemanticTokenTypes = "class" // line 12579 -- EnumType SemanticTokenTypes = "enum" // line 12583 -- InterfaceType SemanticTokenTypes = "interface" // line 12587 -- StructType SemanticTokenTypes = "struct" // line 12591 -- TypeParameterType SemanticTokenTypes = "typeParameter" // line 12595 -- ParameterType SemanticTokenTypes = "parameter" // line 12599 -- VariableType SemanticTokenTypes = "variable" // line 12603 -- PropertyType SemanticTokenTypes = "property" // line 12607 -- EnumMemberType SemanticTokenTypes = "enumMember" // line 12611 -- EventType SemanticTokenTypes = "event" // line 12615 -- FunctionType SemanticTokenTypes = "function" // line 12619 -- MethodType SemanticTokenTypes = "method" // line 12623 -- MacroType SemanticTokenTypes = "macro" // line 12627 -- KeywordType SemanticTokenTypes = "keyword" // line 12631 -- ModifierType SemanticTokenTypes = "modifier" // line 12635 -- CommentType SemanticTokenTypes = "comment" // line 12639 -- StringType SemanticTokenTypes = "string" // line 12643 -- NumberType SemanticTokenTypes = "number" // line 12647 -- RegexpType SemanticTokenTypes = "regexp" // line 12651 -- OperatorType SemanticTokenTypes = "operator" // line 12655 +- TypeType SemanticTokenTypes = "type" +- ClassType SemanticTokenTypes = "class" +- EnumType SemanticTokenTypes = "enum" +- InterfaceType SemanticTokenTypes = "interface" +- StructType SemanticTokenTypes = "struct" +- TypeParameterType SemanticTokenTypes = "typeParameter" +- ParameterType SemanticTokenTypes = "parameter" +- VariableType SemanticTokenTypes = "variable" +- PropertyType SemanticTokenTypes = "property" +- EnumMemberType SemanticTokenTypes = "enumMember" +- EventType SemanticTokenTypes = "event" +- FunctionType SemanticTokenTypes = "function" +- MethodType SemanticTokenTypes = "method" +- MacroType SemanticTokenTypes = "macro" +- KeywordType SemanticTokenTypes = "keyword" +- ModifierType SemanticTokenTypes = "modifier" +- CommentType SemanticTokenTypes = "comment" +- StringType SemanticTokenTypes = "string" +- NumberType SemanticTokenTypes = "number" +- RegexpType SemanticTokenTypes = "regexp" +- OperatorType SemanticTokenTypes = "operator" - // @since 3.17.0 -- DecoratorType SemanticTokenTypes = "decorator" // line 12659 +- DecoratorType SemanticTokenTypes = "decorator" - // How a signature help was triggered. - // - // @since 3.15.0 - // Signature help was invoked manually by the user or by a command. -- SigInvoked SignatureHelpTriggerKind = 1 // line 13587 +- SigInvoked SignatureHelpTriggerKind = 1 - // Signature help was triggered by a trigger character. -- SigTriggerCharacter SignatureHelpTriggerKind = 2 // line 13592 +- SigTriggerCharacter SignatureHelpTriggerKind = 2 - // Signature help was triggered by the cursor moving or by the document content changing. -- SigContentChange SignatureHelpTriggerKind = 3 // line 13597 +- SigContentChange SignatureHelpTriggerKind = 3 - // A symbol kind. -- File SymbolKind = 1 // line 12848 -- Module SymbolKind = 2 // line 12852 -- Namespace SymbolKind = 3 // line 12856 -- Package SymbolKind = 4 // line 12860 -- Class SymbolKind = 5 // line 12864 -- Method SymbolKind = 6 // line 12868 -- Property SymbolKind = 7 // line 12872 -- Field SymbolKind = 8 // line 12876 -- Constructor SymbolKind = 9 // line 12880 -- Enum SymbolKind = 10 // line 12884 -- Interface SymbolKind = 11 // line 12888 -- Function SymbolKind = 12 // line 12892 -- Variable SymbolKind = 13 // line 12896 -- Constant SymbolKind = 14 // line 12900 -- String SymbolKind = 15 // line 12904 -- Number SymbolKind = 16 // line 12908 -- Boolean SymbolKind = 17 // line 12912 -- Array SymbolKind = 18 // line 12916 -- Object SymbolKind = 19 // line 12920 -- Key SymbolKind = 20 // line 12924 -- Null SymbolKind = 21 // line 12928 -- EnumMember SymbolKind = 22 // line 12932 -- Struct SymbolKind = 23 // line 12936 -- Event SymbolKind = 24 // line 12940 -- Operator SymbolKind = 25 // line 12944 -- TypeParameter SymbolKind = 26 // line 12948 +- File SymbolKind = 1 +- Module SymbolKind = 2 +- Namespace SymbolKind = 3 +- Package SymbolKind = 4 +- Class SymbolKind = 5 +- Method SymbolKind = 6 +- Property SymbolKind = 7 +- Field SymbolKind = 8 +- Constructor SymbolKind = 9 +- Enum SymbolKind = 10 +- Interface SymbolKind = 11 +- Function SymbolKind = 12 +- Variable SymbolKind = 13 +- Constant SymbolKind = 14 +- String SymbolKind = 15 +- Number SymbolKind = 16 +- Boolean SymbolKind = 17 +- Array SymbolKind = 18 +- Object SymbolKind = 19 +- Key SymbolKind = 20 +- Null SymbolKind = 21 +- EnumMember SymbolKind = 22 +- Struct SymbolKind = 23 +- Event SymbolKind = 24 +- Operator SymbolKind = 25 +- TypeParameter SymbolKind = 26 - // Symbol tags are extra annotations that tweak the rendering of a symbol. - // - // @since 3.16 - // Render a symbol as obsolete, usually using a strike-out. -- DeprecatedSymbol SymbolTag = 1 // line 12962 +- DeprecatedSymbol SymbolTag = 1 - // Represents reasons why a text document is saved. - // Manually triggered, e.g. by the user pressing save, by starting debugging, - // or by an API call. -- Manual TextDocumentSaveReason = 1 // line 13116 +- Manual TextDocumentSaveReason = 1 - // Automatic after a delay. -- AfterDelay TextDocumentSaveReason = 2 // line 13121 +- AfterDelay TextDocumentSaveReason = 2 - // When the editor lost focus. -- FocusOut TextDocumentSaveReason = 3 // line 13126 +- FocusOut TextDocumentSaveReason = 3 - // Defines how the host (editor) should sync - // document changes to the language server. - // Documents should not be synced at all. -- None TextDocumentSyncKind = 0 // line 13091 +- None TextDocumentSyncKind = 0 - // Documents are synced by always sending the full content - // of the document. -- Full TextDocumentSyncKind = 1 // line 13096 +- Full TextDocumentSyncKind = 1 - // Documents are synced by sending the full content on open. - // After that only incremental updates to the document are - // send. -- Incremental TextDocumentSyncKind = 2 // line 13101 -- Relative TokenFormat = "relative" // line 13743 +- Incremental TextDocumentSyncKind = 2 +- Relative TokenFormat = "relative" - // Turn tracing off. -- Off TraceValues = "off" // line 13390 +- Off TraceValues = "off" - // Trace messages only. -- Messages TraceValues = "messages" // line 13395 +- Messages TraceValues = "messages" - // Verbose message tracing. -- Verbose TraceValues = "verbose" // line 13400 +- Verbose TraceValues = "verbose" - // Moniker uniqueness level to define scope of the moniker. - // - // @since 3.16.0 - // The moniker is only unique inside a document -- Document UniquenessLevel = "document" // line 12978 +- Document UniquenessLevel = "document" - // The moniker is unique inside a project for which a dump got created -- Project UniquenessLevel = "project" // line 12983 +- Project UniquenessLevel = "project" - // The moniker is unique inside the group to which a project belongs -- Group UniquenessLevel = "group" // line 12988 +- Group UniquenessLevel = "group" - // The moniker is unique inside the moniker scheme. -- Scheme UniquenessLevel = "scheme" // line 12993 +- Scheme UniquenessLevel = "scheme" - // The moniker is globally unique -- Global UniquenessLevel = "global" // line 12998 +- Global UniquenessLevel = "global" - // Interested in create events. -- WatchCreate WatchKind = 1 // line 13486 +- WatchCreate WatchKind = 1 - // Interested in change events -- WatchChange WatchKind = 2 // line 13491 +- WatchChange WatchKind = 2 - // Interested in delete events -- WatchDelete WatchKind = 4 // line 13496 +- WatchDelete WatchKind = 4 -) diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protocol/tsserver.go --- a/gopls/internal/lsp/protocol/tsserver.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/protocol/tsserver.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1160 +0,0 @@ +@@ -1,1196 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -57536,8 +63747,8 @@ diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protoco - -package protocol - --// Code generated from protocol/metaModel.json at ref release/protocol/3.17.3-next.6 (hash 56c23c557e3568a9f56f42435fd5a80f9458957f). --// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.3-next.6/protocol/metaModel.json +-// Code generated from protocol/metaModel.json at ref release/protocol/3.17.4-next.2 (hash 184c8a7f010d335582f24337fe182baa6f2fccdd). +-// https://github.com/microsoft/vscode-languageserver-node/blob/release/protocol/3.17.4-next.2/protocol/metaModel.json -// LSP metaData.version = 3.17.0. - -import ( @@ -57548,77 +63759,79 @@ diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protoco -) - -type Server interface { -- Progress(context.Context, *ProgressParams) error // $/progress -- SetTrace(context.Context, *SetTraceParams) error // $/setTrace -- IncomingCalls(context.Context, *CallHierarchyIncomingCallsParams) ([]CallHierarchyIncomingCall, error) // callHierarchy/incomingCalls -- OutgoingCalls(context.Context, *CallHierarchyOutgoingCallsParams) ([]CallHierarchyOutgoingCall, error) // callHierarchy/outgoingCalls -- ResolveCodeAction(context.Context, *CodeAction) (*CodeAction, error) // codeAction/resolve -- ResolveCodeLens(context.Context, *CodeLens) (*CodeLens, error) // codeLens/resolve -- ResolveCompletionItem(context.Context, *CompletionItem) (*CompletionItem, error) // completionItem/resolve -- ResolveDocumentLink(context.Context, *DocumentLink) (*DocumentLink, error) // documentLink/resolve -- Exit(context.Context) error // exit -- Initialize(context.Context, *ParamInitialize) (*InitializeResult, error) // initialize -- Initialized(context.Context, *InitializedParams) error // initialized -- Resolve(context.Context, *InlayHint) (*InlayHint, error) // inlayHint/resolve -- DidChangeNotebookDocument(context.Context, *DidChangeNotebookDocumentParams) error // notebookDocument/didChange -- DidCloseNotebookDocument(context.Context, *DidCloseNotebookDocumentParams) error // notebookDocument/didClose -- DidOpenNotebookDocument(context.Context, *DidOpenNotebookDocumentParams) error // notebookDocument/didOpen -- DidSaveNotebookDocument(context.Context, *DidSaveNotebookDocumentParams) error // notebookDocument/didSave -- Shutdown(context.Context) error // shutdown -- CodeAction(context.Context, *CodeActionParams) ([]CodeAction, error) // textDocument/codeAction -- CodeLens(context.Context, *CodeLensParams) ([]CodeLens, error) // textDocument/codeLens -- ColorPresentation(context.Context, *ColorPresentationParams) ([]ColorPresentation, error) // textDocument/colorPresentation -- Completion(context.Context, *CompletionParams) (*CompletionList, error) // textDocument/completion -- Declaration(context.Context, *DeclarationParams) (*Or_textDocument_declaration, error) // textDocument/declaration -- Definition(context.Context, *DefinitionParams) ([]Location, error) // textDocument/definition -- Diagnostic(context.Context, *string) (*string, error) // textDocument/diagnostic -- DidChange(context.Context, *DidChangeTextDocumentParams) error // textDocument/didChange -- DidClose(context.Context, *DidCloseTextDocumentParams) error // textDocument/didClose -- DidOpen(context.Context, *DidOpenTextDocumentParams) error // textDocument/didOpen -- DidSave(context.Context, *DidSaveTextDocumentParams) error // textDocument/didSave -- DocumentColor(context.Context, *DocumentColorParams) ([]ColorInformation, error) // textDocument/documentColor -- DocumentHighlight(context.Context, *DocumentHighlightParams) ([]DocumentHighlight, error) // textDocument/documentHighlight -- DocumentLink(context.Context, *DocumentLinkParams) ([]DocumentLink, error) // textDocument/documentLink -- DocumentSymbol(context.Context, *DocumentSymbolParams) ([]interface{}, error) // textDocument/documentSymbol -- FoldingRange(context.Context, *FoldingRangeParams) ([]FoldingRange, error) // textDocument/foldingRange -- Formatting(context.Context, *DocumentFormattingParams) ([]TextEdit, error) // textDocument/formatting -- Hover(context.Context, *HoverParams) (*Hover, error) // textDocument/hover -- Implementation(context.Context, *ImplementationParams) ([]Location, error) // textDocument/implementation -- InlayHint(context.Context, *InlayHintParams) ([]InlayHint, error) // textDocument/inlayHint -- InlineValue(context.Context, *InlineValueParams) ([]InlineValue, error) // textDocument/inlineValue -- LinkedEditingRange(context.Context, *LinkedEditingRangeParams) (*LinkedEditingRanges, error) // textDocument/linkedEditingRange -- Moniker(context.Context, *MonikerParams) ([]Moniker, error) // textDocument/moniker -- OnTypeFormatting(context.Context, *DocumentOnTypeFormattingParams) ([]TextEdit, error) // textDocument/onTypeFormatting -- PrepareCallHierarchy(context.Context, *CallHierarchyPrepareParams) ([]CallHierarchyItem, error) // textDocument/prepareCallHierarchy -- PrepareRename(context.Context, *PrepareRenameParams) (*PrepareRename2Gn, error) // textDocument/prepareRename -- PrepareTypeHierarchy(context.Context, *TypeHierarchyPrepareParams) ([]TypeHierarchyItem, error) // textDocument/prepareTypeHierarchy -- RangeFormatting(context.Context, *DocumentRangeFormattingParams) ([]TextEdit, error) // textDocument/rangeFormatting -- References(context.Context, *ReferenceParams) ([]Location, error) // textDocument/references -- Rename(context.Context, *RenameParams) (*WorkspaceEdit, error) // textDocument/rename -- SelectionRange(context.Context, *SelectionRangeParams) ([]SelectionRange, error) // textDocument/selectionRange -- SemanticTokensFull(context.Context, *SemanticTokensParams) (*SemanticTokens, error) // textDocument/semanticTokens/full -- SemanticTokensFullDelta(context.Context, *SemanticTokensDeltaParams) (interface{}, error) // textDocument/semanticTokens/full/delta -- SemanticTokensRange(context.Context, *SemanticTokensRangeParams) (*SemanticTokens, error) // textDocument/semanticTokens/range -- SignatureHelp(context.Context, *SignatureHelpParams) (*SignatureHelp, error) // textDocument/signatureHelp -- TypeDefinition(context.Context, *TypeDefinitionParams) ([]Location, error) // textDocument/typeDefinition -- WillSave(context.Context, *WillSaveTextDocumentParams) error // textDocument/willSave -- WillSaveWaitUntil(context.Context, *WillSaveTextDocumentParams) ([]TextEdit, error) // textDocument/willSaveWaitUntil -- Subtypes(context.Context, *TypeHierarchySubtypesParams) ([]TypeHierarchyItem, error) // typeHierarchy/subtypes -- Supertypes(context.Context, *TypeHierarchySupertypesParams) ([]TypeHierarchyItem, error) // typeHierarchy/supertypes -- WorkDoneProgressCancel(context.Context, *WorkDoneProgressCancelParams) error // window/workDoneProgress/cancel -- DiagnosticWorkspace(context.Context, *WorkspaceDiagnosticParams) (*WorkspaceDiagnosticReport, error) // workspace/diagnostic -- DidChangeConfiguration(context.Context, *DidChangeConfigurationParams) error // workspace/didChangeConfiguration -- DidChangeWatchedFiles(context.Context, *DidChangeWatchedFilesParams) error // workspace/didChangeWatchedFiles -- DidChangeWorkspaceFolders(context.Context, *DidChangeWorkspaceFoldersParams) error // workspace/didChangeWorkspaceFolders -- DidCreateFiles(context.Context, *CreateFilesParams) error // workspace/didCreateFiles -- DidDeleteFiles(context.Context, *DeleteFilesParams) error // workspace/didDeleteFiles -- DidRenameFiles(context.Context, *RenameFilesParams) error // workspace/didRenameFiles -- ExecuteCommand(context.Context, *ExecuteCommandParams) (interface{}, error) // workspace/executeCommand -- Symbol(context.Context, *WorkspaceSymbolParams) ([]SymbolInformation, error) // workspace/symbol -- WillCreateFiles(context.Context, *CreateFilesParams) (*WorkspaceEdit, error) // workspace/willCreateFiles -- WillDeleteFiles(context.Context, *DeleteFilesParams) (*WorkspaceEdit, error) // workspace/willDeleteFiles -- WillRenameFiles(context.Context, *RenameFilesParams) (*WorkspaceEdit, error) // workspace/willRenameFiles -- ResolveWorkspaceSymbol(context.Context, *WorkspaceSymbol) (*WorkspaceSymbol, error) // workspaceSymbol/resolve +- Progress(context.Context, *ProgressParams) error // $/progress +- SetTrace(context.Context, *SetTraceParams) error // $/setTrace +- IncomingCalls(context.Context, *CallHierarchyIncomingCallsParams) ([]CallHierarchyIncomingCall, error) // callHierarchy/incomingCalls +- OutgoingCalls(context.Context, *CallHierarchyOutgoingCallsParams) ([]CallHierarchyOutgoingCall, error) // callHierarchy/outgoingCalls +- ResolveCodeAction(context.Context, *CodeAction) (*CodeAction, error) // codeAction/resolve +- ResolveCodeLens(context.Context, *CodeLens) (*CodeLens, error) // codeLens/resolve +- ResolveCompletionItem(context.Context, *CompletionItem) (*CompletionItem, error) // completionItem/resolve +- ResolveDocumentLink(context.Context, *DocumentLink) (*DocumentLink, error) // documentLink/resolve +- Exit(context.Context) error // exit +- Initialize(context.Context, *ParamInitialize) (*InitializeResult, error) // initialize +- Initialized(context.Context, *InitializedParams) error // initialized +- Resolve(context.Context, *InlayHint) (*InlayHint, error) // inlayHint/resolve +- DidChangeNotebookDocument(context.Context, *DidChangeNotebookDocumentParams) error // notebookDocument/didChange +- DidCloseNotebookDocument(context.Context, *DidCloseNotebookDocumentParams) error // notebookDocument/didClose +- DidOpenNotebookDocument(context.Context, *DidOpenNotebookDocumentParams) error // notebookDocument/didOpen +- DidSaveNotebookDocument(context.Context, *DidSaveNotebookDocumentParams) error // notebookDocument/didSave +- Shutdown(context.Context) error // shutdown +- CodeAction(context.Context, *CodeActionParams) ([]CodeAction, error) // textDocument/codeAction +- CodeLens(context.Context, *CodeLensParams) ([]CodeLens, error) // textDocument/codeLens +- ColorPresentation(context.Context, *ColorPresentationParams) ([]ColorPresentation, error) // textDocument/colorPresentation +- Completion(context.Context, *CompletionParams) (*CompletionList, error) // textDocument/completion +- Declaration(context.Context, *DeclarationParams) (*Or_textDocument_declaration, error) // textDocument/declaration +- Definition(context.Context, *DefinitionParams) ([]Location, error) // textDocument/definition +- Diagnostic(context.Context, *string) (*string, error) // textDocument/diagnostic +- DidChange(context.Context, *DidChangeTextDocumentParams) error // textDocument/didChange +- DidClose(context.Context, *DidCloseTextDocumentParams) error // textDocument/didClose +- DidOpen(context.Context, *DidOpenTextDocumentParams) error // textDocument/didOpen +- DidSave(context.Context, *DidSaveTextDocumentParams) error // textDocument/didSave +- DocumentColor(context.Context, *DocumentColorParams) ([]ColorInformation, error) // textDocument/documentColor +- DocumentHighlight(context.Context, *DocumentHighlightParams) ([]DocumentHighlight, error) // textDocument/documentHighlight +- DocumentLink(context.Context, *DocumentLinkParams) ([]DocumentLink, error) // textDocument/documentLink +- DocumentSymbol(context.Context, *DocumentSymbolParams) ([]interface{}, error) // textDocument/documentSymbol +- FoldingRange(context.Context, *FoldingRangeParams) ([]FoldingRange, error) // textDocument/foldingRange +- Formatting(context.Context, *DocumentFormattingParams) ([]TextEdit, error) // textDocument/formatting +- Hover(context.Context, *HoverParams) (*Hover, error) // textDocument/hover +- Implementation(context.Context, *ImplementationParams) ([]Location, error) // textDocument/implementation +- InlayHint(context.Context, *InlayHintParams) ([]InlayHint, error) // textDocument/inlayHint +- InlineCompletion(context.Context, *InlineCompletionParams) (*Or_Result_textDocument_inlineCompletion, error) // textDocument/inlineCompletion +- InlineValue(context.Context, *InlineValueParams) ([]InlineValue, error) // textDocument/inlineValue +- LinkedEditingRange(context.Context, *LinkedEditingRangeParams) (*LinkedEditingRanges, error) // textDocument/linkedEditingRange +- Moniker(context.Context, *MonikerParams) ([]Moniker, error) // textDocument/moniker +- OnTypeFormatting(context.Context, *DocumentOnTypeFormattingParams) ([]TextEdit, error) // textDocument/onTypeFormatting +- PrepareCallHierarchy(context.Context, *CallHierarchyPrepareParams) ([]CallHierarchyItem, error) // textDocument/prepareCallHierarchy +- PrepareRename(context.Context, *PrepareRenameParams) (*PrepareRename2Gn, error) // textDocument/prepareRename +- PrepareTypeHierarchy(context.Context, *TypeHierarchyPrepareParams) ([]TypeHierarchyItem, error) // textDocument/prepareTypeHierarchy +- RangeFormatting(context.Context, *DocumentRangeFormattingParams) ([]TextEdit, error) // textDocument/rangeFormatting +- RangesFormatting(context.Context, *DocumentRangesFormattingParams) ([]TextEdit, error) // textDocument/rangesFormatting +- References(context.Context, *ReferenceParams) ([]Location, error) // textDocument/references +- Rename(context.Context, *RenameParams) (*WorkspaceEdit, error) // textDocument/rename +- SelectionRange(context.Context, *SelectionRangeParams) ([]SelectionRange, error) // textDocument/selectionRange +- SemanticTokensFull(context.Context, *SemanticTokensParams) (*SemanticTokens, error) // textDocument/semanticTokens/full +- SemanticTokensFullDelta(context.Context, *SemanticTokensDeltaParams) (interface{}, error) // textDocument/semanticTokens/full/delta +- SemanticTokensRange(context.Context, *SemanticTokensRangeParams) (*SemanticTokens, error) // textDocument/semanticTokens/range +- SignatureHelp(context.Context, *SignatureHelpParams) (*SignatureHelp, error) // textDocument/signatureHelp +- TypeDefinition(context.Context, *TypeDefinitionParams) ([]Location, error) // textDocument/typeDefinition +- WillSave(context.Context, *WillSaveTextDocumentParams) error // textDocument/willSave +- WillSaveWaitUntil(context.Context, *WillSaveTextDocumentParams) ([]TextEdit, error) // textDocument/willSaveWaitUntil +- Subtypes(context.Context, *TypeHierarchySubtypesParams) ([]TypeHierarchyItem, error) // typeHierarchy/subtypes +- Supertypes(context.Context, *TypeHierarchySupertypesParams) ([]TypeHierarchyItem, error) // typeHierarchy/supertypes +- WorkDoneProgressCancel(context.Context, *WorkDoneProgressCancelParams) error // window/workDoneProgress/cancel +- DiagnosticWorkspace(context.Context, *WorkspaceDiagnosticParams) (*WorkspaceDiagnosticReport, error) // workspace/diagnostic +- DidChangeConfiguration(context.Context, *DidChangeConfigurationParams) error // workspace/didChangeConfiguration +- DidChangeWatchedFiles(context.Context, *DidChangeWatchedFilesParams) error // workspace/didChangeWatchedFiles +- DidChangeWorkspaceFolders(context.Context, *DidChangeWorkspaceFoldersParams) error // workspace/didChangeWorkspaceFolders +- DidCreateFiles(context.Context, *CreateFilesParams) error // workspace/didCreateFiles +- DidDeleteFiles(context.Context, *DeleteFilesParams) error // workspace/didDeleteFiles +- DidRenameFiles(context.Context, *RenameFilesParams) error // workspace/didRenameFiles +- ExecuteCommand(context.Context, *ExecuteCommandParams) (interface{}, error) // workspace/executeCommand +- Symbol(context.Context, *WorkspaceSymbolParams) ([]SymbolInformation, error) // workspace/symbol +- WillCreateFiles(context.Context, *CreateFilesParams) (*WorkspaceEdit, error) // workspace/willCreateFiles +- WillDeleteFiles(context.Context, *DeleteFilesParams) (*WorkspaceEdit, error) // workspace/willDeleteFiles +- WillRenameFiles(context.Context, *RenameFilesParams) (*WorkspaceEdit, error) // workspace/willRenameFiles +- ResolveWorkspaceSymbol(context.Context, *WorkspaceSymbol) (*WorkspaceSymbol, error) // workspaceSymbol/resolve - NonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) -} - @@ -57947,6 +64160,16 @@ diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protoco - return true, reply(ctx, nil, err) - } - return true, reply(ctx, resp, nil) +- case "textDocument/inlineCompletion": +- var params InlineCompletionParams +- if err := json.Unmarshal(r.Params(), ¶ms); err != nil { +- return true, sendParseError(ctx, reply, err) +- } +- resp, err := server.InlineCompletion(ctx, ¶ms) +- if err != nil { +- return true, reply(ctx, nil, err) +- } +- return true, reply(ctx, resp, nil) - case "textDocument/inlineValue": - var params InlineValueParams - if err := json.Unmarshal(r.Params(), ¶ms); err != nil { @@ -58027,6 +64250,16 @@ diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protoco - return true, reply(ctx, nil, err) - } - return true, reply(ctx, resp, nil) +- case "textDocument/rangesFormatting": +- var params DocumentRangesFormattingParams +- if err := json.Unmarshal(r.Params(), ¶ms); err != nil { +- return true, sendParseError(ctx, reply, err) +- } +- resp, err := server.RangesFormatting(ctx, ¶ms) +- if err != nil { +- return true, reply(ctx, nil, err) +- } +- return true, reply(ctx, resp, nil) - case "textDocument/references": - var params ReferenceParams - if err := json.Unmarshal(r.Params(), ¶ms); err != nil { @@ -58475,6 +64708,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protoco - } - return result, nil -} +-func (s *serverDispatcher) InlineCompletion(ctx context.Context, params *InlineCompletionParams) (*Or_Result_textDocument_inlineCompletion, error) { +- var result *Or_Result_textDocument_inlineCompletion +- if err := s.sender.Call(ctx, "textDocument/inlineCompletion", params, &result); err != nil { +- return nil, err +- } +- return result, nil +-} -func (s *serverDispatcher) InlineValue(ctx context.Context, params *InlineValueParams) ([]InlineValue, error) { - var result []InlineValue - if err := s.sender.Call(ctx, "textDocument/inlineValue", params, &result); err != nil { @@ -58531,6 +64771,13 @@ diff -urN a/gopls/internal/lsp/protocol/tsserver.go b/gopls/internal/lsp/protoco - } - return result, nil -} +-func (s *serverDispatcher) RangesFormatting(ctx context.Context, params *DocumentRangesFormattingParams) ([]TextEdit, error) { +- var result []TextEdit +- if err := s.sender.Call(ctx, "textDocument/rangesFormatting", params, &result); err != nil { +- return nil, err +- } +- return result, nil +-} -func (s *serverDispatcher) References(ctx context.Context, params *ReferenceParams) ([]Location, error) { - var result []Location - if err := s.sender.Call(ctx, "textDocument/references", params, &result); err != nil { @@ -58702,7 +64949,7 @@ diff -urN a/gopls/internal/lsp/README.md b/gopls/internal/lsp/README.md diff -urN a/gopls/internal/lsp/references.go b/gopls/internal/lsp/references.go --- a/gopls/internal/lsp/references.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/references.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,25 +0,0 @@ +@@ -1,30 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -58715,15 +64962,20 @@ diff -urN a/gopls/internal/lsp/references.go b/gopls/internal/lsp/references.go - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/template" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) references(ctx context.Context, params *protocol.ReferenceParams) ([]protocol.Location, error) { +- ctx, done := event.Start(ctx, "lsp.Server.references", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) - defer release() - if !ok { - return nil, err - } -- if snapshot.View().FileKind(fh) == source.Tmpl { +- if snapshot.FileKind(fh) == source.Tmpl { - return template.References(ctx, snapshot, fh, params) - } - return source.References(ctx, snapshot, fh, params.Position, params.Context.IncludeDeclaration) @@ -58892,7 +65144,7 @@ diff -urN a/gopls/internal/lsp/regtest/doc.go b/gopls/internal/lsp/regtest/doc.g diff -urN a/gopls/internal/lsp/regtest/env.go b/gopls/internal/lsp/regtest/env.go --- a/gopls/internal/lsp/regtest/env.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/regtest/env.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,391 +0,0 @@ +@@ -1,403 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -58964,6 +65216,7 @@ diff -urN a/gopls/internal/lsp/regtest/env.go b/gopls/internal/lsp/regtest/env.g - OnLogMessage: a.onLogMessage, - OnWorkDoneProgressCreate: a.onWorkDoneProgressCreate, - OnProgress: a.onProgress, +- OnShowDocument: a.onShowDocument, - OnShowMessage: a.onShowMessage, - OnShowMessageRequest: a.onShowMessageRequest, - OnRegisterCapability: a.onRegisterCapability, @@ -58977,6 +65230,7 @@ diff -urN a/gopls/internal/lsp/regtest/env.go b/gopls/internal/lsp/regtest/env.g - // diagnostics are a map of relative path->diagnostics params - diagnostics map[string]*protocol.PublishDiagnosticsParams - logs []*protocol.LogMessageParams +- showDocument []*protocol.ShowDocumentParams - showMessage []*protocol.ShowMessageParams - showMessageRequest []*protocol.ShowMessageRequestParams - @@ -59096,6 +65350,15 @@ diff -urN a/gopls/internal/lsp/regtest/env.go b/gopls/internal/lsp/regtest/env.g - return nil -} - +-func (a *Awaiter) onShowDocument(_ context.Context, params *protocol.ShowDocumentParams) error { +- a.mu.Lock() +- defer a.mu.Unlock() +- +- a.state.showDocument = append(a.state.showDocument, params) +- a.checkConditionsLocked() +- return nil +-} +- -func (a *Awaiter) onShowMessage(_ context.Context, m *protocol.ShowMessageParams) error { - a.mu.Lock() - defer a.mu.Unlock() @@ -59237,6 +65500,7 @@ diff -urN a/gopls/internal/lsp/regtest/env.go b/gopls/internal/lsp/regtest/env.g -// unmeetable. If it was met, OnceMet checks that the state meets all -// expectations in mustMeets. -func (e *Env) OnceMet(precondition Expectation, mustMeets ...Expectation) { +- e.T.Helper() - e.Await(OnceMet(precondition, mustMeets...)) -} - @@ -59357,7 +65621,7 @@ diff -urN a/gopls/internal/lsp/regtest/env_test.go b/gopls/internal/lsp/regtest/ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regtest/expectation.go --- a/gopls/internal/lsp/regtest/expectation.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/regtest/expectation.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,769 +0,0 @@ +@@ -1,783 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -59370,6 +65634,7 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte - "sort" - "strings" - +- "github.com/google/go-cmp/cmp" - "golang.org/x/tools/gopls/internal/lsp" - "golang.org/x/tools/gopls/internal/lsp/protocol" -) @@ -59465,6 +65730,26 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte - return strings.Join(descriptions, "\n") -} - +-// Not inverts the sense of an expectation: a met expectation is unmet, and an +-// unmet expectation is met. +-func Not(e Expectation) Expectation { +- check := func(s State) Verdict { +- switch v := e.Check(s); v { +- case Met: +- return Unmet +- case Unmet, Unmeetable: +- return Met +- default: +- panic(fmt.Sprintf("unexpected verdict %v", v)) +- } +- } +- description := describeExpectations(e) +- return Expectation{ +- Check: check, +- Description: fmt.Sprintf("not: %s", description), +- } +-} +- -// AnyOf returns an expectation that is satisfied when any of the given -// expectations is met. -func AnyOf(anyOf ...Expectation) Expectation { @@ -59566,6 +65851,23 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte - } -} - +-// ShownDocument asserts that the client has received a +-// ShowDocumentRequest for the given URI. +-func ShownDocument(uri protocol.URI) Expectation { +- check := func(s State) Verdict { +- for _, params := range s.showDocument { +- if params.URI == uri { +- return Met +- } +- } +- return Unmet +- } +- return Expectation{ +- Check: check, +- Description: fmt.Sprintf("received window/showDocument for URI %s", uri), +- } +-} +- -// NoShownMessage asserts that the editor has not received a ShowMessage. -func NoShownMessage(subString string) Expectation { - check := func(s State) Verdict { @@ -59595,7 +65897,7 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte - } - return Expectation{ - Check: check, -- Description: "received ShowMessage", +- Description: fmt.Sprintf("received window/showMessage containing %q", containing), - } -} - @@ -59829,6 +66131,10 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte -// The count argument specifies the expected number of matching logs. If -// atLeast is set, this is a lower bound, otherwise there must be exactly count -// matching logs. +-// +-// Logs are asynchronous to other LSP messages, so this expectation should not +-// be used with combinators such as OnceMet or AfterChange that assert on +-// ordering with respect to other operations. -func LogMatching(typ protocol.MessageType, re string, count int, atLeast bool) Expectation { - rec, err := regexp.Compile(re) - if err != nil { @@ -59845,6 +66151,11 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte - if found == count || (found >= count && atLeast) { - return Met - } +- // If we require an exact count, and have received more than expected, the +- // expectation can never be met. +- if found > count && !atLeast { +- return Unmeetable +- } - return Unmet - } - desc := fmt.Sprintf("log message matching %q expected %v times", re, count) @@ -59936,50 +66247,6 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte - return jsonProperty(m[path[0]], path[1:]...) -} - --// RegistrationMatching asserts that the client has received a capability --// registration matching the given regexp. --// --// TODO(rfindley): remove this once TestWatchReplaceTargets has been revisited. --// --// Deprecated: use (No)FileWatchMatching --func RegistrationMatching(re string) Expectation { -- rec := regexp.MustCompile(re) -- check := func(s State) Verdict { -- for _, p := range s.registrations { -- for _, r := range p.Registrations { -- if rec.Match([]byte(r.Method)) { -- return Met -- } -- } -- } -- return Unmet -- } -- return Expectation{ -- Check: check, -- Description: fmt.Sprintf("registration matching %q", re), -- } --} -- --// UnregistrationMatching asserts that the client has received an --// unregistration whose ID matches the given regexp. --func UnregistrationMatching(re string) Expectation { -- rec := regexp.MustCompile(re) -- check := func(s State) Verdict { -- for _, p := range s.unregistrations { -- for _, r := range p.Unregisterations { -- if rec.Match([]byte(r.Method)) { -- return Met -- } -- } -- } -- return Unmet -- } -- return Expectation{ -- Check: check, -- Description: fmt.Sprintf("unregistration matching %q", re), -- } --} -- -// Diagnostics asserts that there is at least one diagnostic matching the given -// filters. -func Diagnostics(filters ...DiagnosticFilter) Expectation { @@ -60127,10 +66394,21 @@ diff -urN a/gopls/internal/lsp/regtest/expectation.go b/gopls/internal/lsp/regte - }, - } -} +- +-// WithSeverityTags filters to diagnostics whose severity and tags match +-// the given expectation. +-func WithSeverityTags(diagName string, severity protocol.DiagnosticSeverity, tags []protocol.DiagnosticTag) DiagnosticFilter { +- return DiagnosticFilter{ +- desc: fmt.Sprintf("with diagnostic %q with severity %q and tag %#q", diagName, severity, tags), +- check: func(_ string, d protocol.Diagnostic) bool { +- return d.Source == diagName && d.Severity == severity && cmp.Equal(d.Tags, tags) +- }, +- } +-} diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/marker.go --- a/gopls/internal/lsp/regtest/marker.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/regtest/marker.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1273 +0,0 @@ +@@ -1,1828 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -60145,15 +66423,18 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - "fmt" - "go/token" - "io/fs" +- "log" - "os" - "path" - "path/filepath" - "reflect" - "regexp" +- "runtime" - "sort" - "strings" - "testing" - +- "github.com/google/go-cmp/cmp" - "golang.org/x/tools/go/expect" - "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/lsp/cache" @@ -60174,6 +66455,11 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -var update = flag.Bool("update", false, "if set, update test data during marker tests") - -// RunMarkerTests runs "marker" tests in the given test data directory. +-// (In practice: ../../regtest/marker/testdata) +-// +-// Use this command to run the tests: +-// +-// $ go test ./gopls/internal/regtest/marker [-update] -// -// A marker test uses the '//@' marker syntax of the x/tools/go/expect package -// to annotate source code with various information such as locations and @@ -60223,11 +66509,20 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// -// # Special files -// --// There are three types of file within the test archive that are given special +-// There are several types of file within the test archive that are given special -// treatment by the test runner: +-// - "skip": the presence of this file causes the test to be skipped, with +-// the file content used as the skip message. -// - "flags": this file is treated as a whitespace-separated list of flags --// that configure the MarkerTest instance. For example, -min_go=go1.18 sets --// the minimum required Go version for the test. +-// that configure the MarkerTest instance. Supported flags: +-// -min_go=go1.18 sets the minimum Go version for the test; +-// -cgo requires that CGO_ENABLED is set and the cgo tool is available +-// -write_sumfile=a,b,c instructs the test runner to generate go.sum files +-// in these directories before running the test. +-// -skip_goos=a,b,c instructs the test runner to skip the test for the +-// listed GOOS values. +-// TODO(rfindley): using build constraint expressions for -skip_goos would +-// be clearer. -// TODO(rfindley): support flag values containing whitespace. -// - "settings.json": this file is parsed as JSON, and used as the -// session configuration (see gopls/doc/settings.md) @@ -60240,22 +66535,57 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// Foo were of type *Golden, the test runner would convert the identifier a -// in the call @foo(a, "b", 3) into a *Golden by collecting golden file -// data starting with "@a/". +-// - proxy files: any file starting with proxy/ is treated as a Go proxy +-// file. If present, these files are written to a separate temporary +-// directory and GOPROXY is set to file://. -// -// # Marker types -// -// The following markers are supported within marker tests: -// +-// - acceptcompletion(location, label, golden): specifies that accepting the +-// completion candidate produced at the given location with provided label +-// results in the given golden state. +-// +-// - codeaction(kind, start, end, golden): specifies a codeaction to request +-// for the given range. To support multi-line ranges, the range is defined +-// to be between start.Start and end.End. The golden directory contains +-// changed file content after the code action is applied. +-// +-// - codeactionerr(kind, start, end, wantError): specifies a codeaction that +-// fails with an error that matches the expectation. +-// +-// - complete(location, ...labels): specifies expected completion results at +-// the given location. +-// -// - diag(location, regexp): specifies an expected diagnostic matching the -// given regexp at the given location. The test runner requires --// a 1:1 correspondence between observed diagnostics and diag annotations +-// a 1:1 correspondence between observed diagnostics and diag annotations. +-// The diagnostics source and kind fields are ignored, to reduce fuss. +-// +-// The specified location must match the start position of the diagnostic, +-// but end positions are ignored. +-// +-// TODO(adonovan): in the older marker framework, the annotation asserted +-// two additional fields (source="compiler", kind="error"). Restore them? -// -// - def(src, dst location): perform a textDocument/definition request at --// the src location, and check the the result points to the dst location. +-// the src location, and check the result points to the dst location. +-// +-// - format(golden): perform a textDocument/format request for the enclosing +-// file, and compare against the named golden file. If the formatting +-// request succeeds, the golden file must contain the resulting formatted +-// source. If the formatting request fails, the golden file must contain +-// the error message. -// -// - hover(src, dst location, g Golden): perform a textDocument/hover at the -// src location, and checks that the result is the dst location, with hover -// content matching "hover.md" in the golden data g. -// +-// - implementations(src location, want ...location): makes a +-// textDocument/implementation query at the src location and +-// checks that the resulting set of locations matches want. +-// -// - loc(name, location): specifies the name for a location in the source. These -// locations may be referenced by other markers. -// @@ -60272,6 +66602,30 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// This action is executed for its editing effects on the source files. -// Like rename, the golden directory contains the expected transformed files. -// +-// - refs(location, want ...location): executes a 'references' query at the +-// first location and asserts that the result is the set of 'want' locations. +-// The first want location must be the declaration (assumedly unique). +-// +-// - symbol(golden): makes a textDocument/documentSymbol request +-// for the enclosing file, formats the response with one symbol +-// per line, sorts it, and compares against the named golden file. +-// Each line is of the form: +-// +-// dotted.symbol.name kind "detail" +n lines +-// +-// where the "+n lines" part indicates that the declaration spans +-// several lines. The test otherwise makes no attempt to check +-// location information. There is no point to using more than one +-// @symbol marker in a given file. +-// +-// - workspacesymbol(query, golden): makes a workspace/symbol request for the +-// given query, formats the response with one symbol per line, and compares +-// against the named golden file. As workspace symbols are by definition a +-// workspace-wide request, the location of the workspace symbol marker does +-// not matter. Each line is of the form: +-// +-// location name kind +-// -// # Argument conversion -// -// Marker arguments are first parsed by the go/expect package, which accepts @@ -60360,8 +66714,11 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// - parallelize/optimize test execution -// - reorganize regtest packages (and rename to just 'test'?) -// - Rename the files .txtar. +-// - Provide some means by which locations in the standard library +-// (or builtin.go) can be named, so that, for example, we can we +-// can assert that MyError implements the built-in error type. -// --// Existing marker tests to port: +-// Existing marker tests (in ../testdata) to port: -// - CallHierarchy -// - CodeLens -// - Diagnostics @@ -60377,16 +66734,11 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// - Formats -// - Imports -// - SemanticTokens --// - SuggestedFixes -// - FunctionExtractions -// - MethodExtractions --// - Definitions --// - Implementations -// - Highlights --// - References -// - Renames -// - PrepareRenames --// - Symbols -// - InlayHints -// - WorkspaceSymbols -// - Signatures @@ -60408,6 +66760,15 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { +- if test.skipReason != "" { +- t.Skip(test.skipReason) +- } +- for _, goos := range test.skipGOOS { +- if runtime.GOOS == goos { +- t.Skipf("skipping on %s due to -skip_goos", runtime.GOOS) +- } +- } +- - // TODO(rfindley): it may be more useful to have full support for build - // constraints. - if test.minGoVersion != "" { @@ -60415,16 +66776,25 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - if _, err := fmt.Sscanf(test.minGoVersion, "go1.%d", &go1point); err != nil { - t.Fatalf("parsing -min_go version: %v", err) - } -- testenv.NeedsGo1Point(t, 18) +- testenv.NeedsGo1Point(t, go1point) +- } +- if test.cgo { +- testenv.NeedsTool(t, "cgo") - } - config := fake.EditorConfig{ - Settings: test.settings, - Env: test.env, - } -- run := &markerTestRun{ -- test: test, -- env: newEnv(t, cache, test.files, config), +- if _, ok := config.Settings["diagnosticsDelay"]; !ok { +- if config.Settings == nil { +- config.Settings = make(map[string]interface{}) +- } +- config.Settings["diagnosticsDelay"] = "10ms" +- } - +- run := &markerTestRun{ +- test: test, +- env: newEnv(t, cache, test.files, test.proxyFiles, test.writeGoSum, config), - locations: make(map[expect.Identifier]protocol.Location), - diags: make(map[protocol.Location][]protocol.Diagnostic), - } @@ -60461,8 +66831,11 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - uri := run.env.Sandbox.Workdir.URI(path) - for _, diag := range params.Diagnostics { - loc := protocol.Location{ -- URI: uri, -- Range: diag.Range, +- URI: uri, +- Range: protocol.Range{ +- Start: diag.Range.Start, +- End: diag.Range.Start, // ignore end positions +- }, - } - run.diags[loc] = append(run.diags[loc], diag) - } @@ -60505,6 +66878,10 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - }) - } +- +- if abs, err := filepath.Abs(dir); err == nil && t.Failed() { +- t.Logf("(Filenames are relative to %s.)", abs) +- } -} - -// A marker holds state for the execution of a single @marker @@ -60514,9 +66891,16 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - note *expect.Note -} - +-// server returns the LSP server for the marker test run. +-func (m marker) server() protocol.Server { +- return m.run.env.Editor.Server +-} +- -// errorf reports an error with a prefix indicating the position of the marker note. +-// +-// It formats the error message using mark.sprintf. -func (mark marker) errorf(format string, args ...interface{}) { -- msg := fmt.Sprintf(format, args...) +- msg := mark.sprintf(format, args...) - // TODO(adonovan): consider using fmt.Fprintf(os.Stderr)+t.Fail instead of - // t.Errorf to avoid reporting uninteresting positions in the Go source of - // the driver. However, this loses the order of stderr wrt "FAIL: TestFoo" @@ -60534,29 +66918,39 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - - // The first converter corresponds to the *Env argument. - // All others must be converted from the marker syntax. -- if got, want := len(mark.note.Args), len(fn.converters); got != want { -- mark.errorf("got %d arguments to %s, expect %d", got, mark.note.Name, want) -- return -- } -- - args := []reflect.Value{reflect.ValueOf(mark)} +- var convert converter - for i, in := range mark.note.Args { -- // Special handling for the blank identifier: treat it as the zero -- // value. +- if i < len(fn.converters) { +- convert = fn.converters[i] +- } else if !fn.variadic { +- goto arity // too many args +- } +- +- // Special handling for the blank identifier: treat it as the zero value. - if ident, ok := in.(expect.Identifier); ok && ident == "_" { - zero := reflect.Zero(fn.paramTypes[i]) - args = append(args, zero) - continue - } -- out, err := fn.converters[i](mark, in) +- +- out, err := convert(mark, in) - if err != nil { - mark.errorf("converting argument #%d of %s (%v): %v", i, mark.note.Name, in, err) - return - } - args = append(args, reflect.ValueOf(out)) - } +- if len(args) < len(fn.converters) { +- goto arity // too few args +- } - - fn.fn.Call(args) +- return +- +-arity: +- mark.errorf("got %d arguments to %s, want %d", +- len(mark.note.Args), mark.note.Name, len(fn.converters)) -} - -// Supported marker functions. @@ -60567,13 +66961,22 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// Marker funcs should not mutate the test environment (e.g. via opening files -// or applying edits in the editor). -var markerFuncs = map[string]markerFunc{ -- "def": makeMarkerFunc(defMarker), -- "diag": makeMarkerFunc(diagMarker), -- "hover": makeMarkerFunc(hoverMarker), -- "loc": makeMarkerFunc(locMarker), -- "rename": makeMarkerFunc(renameMarker), -- "renameerr": makeMarkerFunc(renameErrMarker), -- "suggestedfix": makeMarkerFunc(suggestedfixMarker), +- "acceptcompletion": makeMarkerFunc(acceptCompletionMarker), +- "codeaction": makeMarkerFunc(codeActionMarker), +- "codeactionerr": makeMarkerFunc(codeActionErrMarker), +- "complete": makeMarkerFunc(completeMarker), +- "def": makeMarkerFunc(defMarker), +- "diag": makeMarkerFunc(diagMarker), +- "hover": makeMarkerFunc(hoverMarker), +- "format": makeMarkerFunc(formatMarker), +- "implementation": makeMarkerFunc(implementationMarker), +- "loc": makeMarkerFunc(locMarker), +- "rename": makeMarkerFunc(renameMarker), +- "renameerr": makeMarkerFunc(renameErrMarker), +- "suggestedfix": makeMarkerFunc(suggestedfixMarker), +- "symbol": makeMarkerFunc(symbolMarker), +- "refs": makeMarkerFunc(refsMarker), +- "workspacesymbol": makeMarkerFunc(workspaceSymbolMarker), -} - -// markerTest holds all the test data extracted from a test txtar archive. @@ -60581,20 +66984,25 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// See the documentation for RunMarkerTests for more information on the archive -// format. -type markerTest struct { -- name string // relative path to the txtar file in the testdata dir -- fset *token.FileSet // fileset used for parsing notes -- content []byte // raw test content -- archive *txtar.Archive // original test archive -- settings map[string]interface{} // gopls settings -- env map[string]string // editor environment -- files map[string][]byte // data files from the archive (excluding special files) -- notes []*expect.Note // extracted notes from data files -- golden map[string]*Golden // extracted golden content, by identifier name -- -- // flags holds flags extracted from the special "flags" archive file. -- flags []string +- name string // relative path to the txtar file in the testdata dir +- fset *token.FileSet // fileset used for parsing notes +- content []byte // raw test content +- archive *txtar.Archive // original test archive +- settings map[string]interface{} // gopls settings +- env map[string]string // editor environment +- proxyFiles map[string][]byte // proxy content +- files map[string][]byte // data files from the archive (excluding special files) +- notes []*expect.Note // extracted notes from data files +- golden map[string]*Golden // extracted golden content, by identifier name +- +- skipReason string // the skip reason extracted from the "skip" archive file +- flags []string // flags extracted from the special "flags" archive file. +- - // Parsed flags values. - minGoVersion string +- cgo bool +- writeGoSum []string // comma separated dirs to write go sum for +- skipGOOS []string // comma separated GOOS values to skip -} - -// flagSet returns the flagset used for parsing the special "flags" file in the @@ -60602,9 +67010,28 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -func (t *markerTest) flagSet() *flag.FlagSet { - flags := flag.NewFlagSet(t.name, flag.ContinueOnError) - flags.StringVar(&t.minGoVersion, "min_go", "", "if set, the minimum go1.X version required for this test") +- flags.BoolVar(&t.cgo, "cgo", false, "if set, requires cgo (both the cgo tool and CGO_ENABLED=1)") +- flags.Var((*stringListValue)(&t.writeGoSum), "write_sumfile", "if set, write the sumfile for these directories") +- flags.Var((*stringListValue)(&t.skipGOOS), "skip_goos", "if set, skip this test on these GOOS values") - return flags -} - +-// stringListValue implements flag.Value. +-type stringListValue []string +- +-func (l *stringListValue) Set(s string) error { +- if s != "" { +- for _, d := range strings.Split(s, ",") { +- *l = append(*l, strings.TrimSpace(d)) +- } +- } +- return nil +-} +- +-func (l stringListValue) String() string { +- return strings.Join([]string(l), ",") +-} +- -func (t *markerTest) getGolden(id string) *Golden { - golden, ok := t.golden[id] - // If there was no golden content for this identifier, we must create one @@ -60670,9 +67097,6 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// -// See the documentation for RunMarkerTests for more details on the test data -// archive. --// --// TODO(rfindley): this test could sanity check the results. For example, it is --// too easy to write "// @" instead of "//@", which we will happy skip silently. -func loadMarkerTests(dir string) ([]*markerTest, error) { - var tests []*markerTest - err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error { @@ -60681,6 +67105,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - if err != nil { - return err - } +- - name := strings.TrimPrefix(path, dir+string(filepath.Separator)) - test, err := loadMarkerTest(name, content) - if err != nil { @@ -60695,6 +67120,13 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - -func loadMarkerTest(name string, content []byte) (*markerTest, error) { - archive := txtar.Parse(content) +- if len(archive.Files) == 0 { +- return nil, fmt.Errorf("txtar file has no '-- filename --' sections") +- } +- if bytes.Contains(archive.Comment, []byte("\n-- ")) { +- // This check is conservative, but the comment is only a comment. +- return nil, fmt.Errorf("ill-formed '-- filename --' header in comment") +- } - test := &markerTest{ - name: name, - fset: token.NewFileSet(), @@ -60705,6 +67137,11 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - for _, file := range archive.Files { - switch { +- case file.Name == "skip": +- reason := strings.ReplaceAll(string(file.Data), "\n", " ") +- reason = strings.TrimSpace(reason) +- test.skipReason = reason +- - case file.Name == "flags": - test.flags = strings.Fields(string(file.Data)) - if err := test.flagSet().Parse(test.flags); err != nil { @@ -60720,8 +67157,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - test.env = make(map[string]string) - fields := strings.Fields(string(file.Data)) - for _, field := range fields { -- // TODO: use strings.Cut once we are on 1.18+. -- key, value, ok := cut(field, "=") +- key, value, ok := strings.Cut(field, "=") - if !ok { - return nil, fmt.Errorf("env vars must be formatted as var=value, got %q", field) - } @@ -60729,7 +67165,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - - case strings.HasPrefix(file.Name, "@"): // golden content -- id, name, _ := cut(file.Name[len("@"):], "/") +- id, name, _ := strings.Cut(file.Name[len("@"):], "/") - // Note that a file.Name of just "@id" gives (id, name) = ("id", ""). - if _, ok := test.golden[id]; !ok { - test.golden[id] = &Golden{ @@ -60739,29 +67175,41 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - test.golden[id].data[name] = file.Data - +- case strings.HasPrefix(file.Name, "proxy/"): +- name := file.Name[len("proxy/"):] +- if test.proxyFiles == nil { +- test.proxyFiles = make(map[string][]byte) +- } +- test.proxyFiles[name] = file.Data +- - default: // ordinary file content - notes, err := expect.Parse(test.fset, file.Name, file.Data) - if err != nil { - return nil, fmt.Errorf("parsing notes in %q: %v", file.Name, err) - } +- +- // Reject common misspelling: "// @mark". +- // TODO(adonovan): permit "// @" within a string. Detect multiple spaces. +- if i := bytes.Index(file.Data, []byte("// @")); i >= 0 { +- line := 1 + bytes.Count(file.Data[:i], []byte("\n")) +- return nil, fmt.Errorf("%s:%d: unwanted space before marker (// @)", file.Name, line) +- } +- - test.notes = append(test.notes, notes...) - test.files[file.Name] = file.Data - } +- +- // Print a warning if we see what looks like "-- filename --" +- // without the second "--". It's not necessarily wrong, +- // but it should almost never appear in our test inputs. +- if bytes.Contains(file.Data, []byte("\n-- ")) { +- log.Printf("ill-formed '-- filename --' header in %s?", file.Name) +- } - } - - return test, nil -} - --// cut is a copy of strings.Cut. --// --// TODO: once we only support Go 1.18+, just use strings.Cut. --func cut(s, sep string) (before, after string, found bool) { -- if i := strings.Index(s, sep); i >= 0 { -- return s[:i], s[i+len(sep):], true -- } -- return s, "", false --} -- -// formatTest formats the test as a txtar archive. -func formatTest(test *markerTest) ([]byte, error) { - arch := &txtar.Archive{ @@ -60781,11 +67229,13 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - switch file.Name { - // Preserve configuration files exactly as they were. They must have parsed - // if we got this far. -- case "flags", "settings.json", "env": +- case "skip", "flags", "settings.json", "env": - arch.Files = append(arch.Files, file) - default: - if _, ok := test.files[file.Name]; ok { // ordinary file - arch.Files = append(arch.Files, file) +- } else if strings.HasPrefix(file.Name, "proxy/") { // proxy file +- arch.Files = append(arch.Files, file) - } else if data, ok := updatedGolden[file.Name]; ok { // golden file - arch.Files = append(arch.Files, txtar.File{Name: file.Name, Data: data}) - delete(updatedGolden, file.Name) @@ -60811,16 +67261,22 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// -// TODO(rfindley): simplify and refactor the construction of testing -// environments across regtests, marker tests, and benchmarks. --func newEnv(t *testing.T, cache *cache.Cache, files map[string][]byte, config fake.EditorConfig) *Env { +-func newEnv(t *testing.T, cache *cache.Cache, files, proxyFiles map[string][]byte, writeGoSum []string, config fake.EditorConfig) *Env { - sandbox, err := fake.NewSandbox(&fake.SandboxConfig{ -- RootDir: t.TempDir(), -- GOPROXY: "https://proxy.golang.org", -- Files: files, +- RootDir: t.TempDir(), +- Files: files, +- ProxyFiles: proxyFiles, - }) - if err != nil { - t.Fatal(err) - } - +- for _, dir := range writeGoSum { +- if err := sandbox.RunGoCommand(context.Background(), dir, "list", []string{"-mod=mod", "..."}, []string{"GOWORK=off"}, true); err != nil { +- t.Fatal(err) +- } +- } +- - // Put a debug instance in the context to prevent logging to stderr. - // See associated TODO in runner.go: we should revisit this pattern. - ctx := context.Background() @@ -60853,6 +67309,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - fn reflect.Value // the func to invoke - paramTypes []reflect.Type // parameter types, for zero values - converters []converter // to convert non-blank arguments +- variadic bool -} - -// A markerTestRun holds the state of one run of a marker test archive. @@ -60863,7 +67320,34 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - // Collected information. - // Each @diag/@suggestedfix marker eliminates an entry from diags. - locations map[expect.Identifier]protocol.Location -- diags map[protocol.Location][]protocol.Diagnostic +- diags map[protocol.Location][]protocol.Diagnostic // diagnostics by position; location end == start +-} +- +-// sprintf returns a formatted string after applying pre-processing to +-// arguments of the following types: +-// - token.Pos: formatted using (*markerTestRun).fmtPos +-// - protocol.Location: formatted using (*markerTestRun).fmtLoc +-func (c *marker) sprintf(format string, args ...interface{}) string { +- if false { +- _ = fmt.Sprintf(format, args...) // enable vet printf checker +- } +- var args2 []interface{} +- for _, arg := range args { +- switch arg := arg.(type) { +- case token.Pos: +- args2 = append(args2, c.run.fmtPos(arg)) +- case protocol.Location: +- args2 = append(args2, c.run.fmtLoc(arg)) +- default: +- args2 = append(args2, arg) +- } +- } +- return fmt.Sprintf(format, args2...) +-} +- +-// uri returns the URI of the file containing the marker. +-func (mark marker) uri() protocol.DocumentURI { +- return mark.run.env.Sandbox.Workdir.URI(mark.run.test.fset.File(mark.note.Pos).Name()) -} - -// fmtLoc formats the given pos in the context of the test, using @@ -60891,8 +67375,21 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// archive-relative paths for files and including the line number in the full -// archive file. -func (run *markerTestRun) fmtLoc(loc protocol.Location) string { +- formatted := run.fmtLocDetails(loc, true) +- if formatted == "" { +- run.env.T.Errorf("unable to find %s in test archive", loc) +- return "" +- } +- return formatted +-} +- +-// See fmtLoc. If includeTxtPos is not set, the position in the full archive +-// file is omitted. +-// +-// If the location cannot be found within the archive, fmtLocDetails returns "". +-func (run *markerTestRun) fmtLocDetails(loc protocol.Location, includeTxtPos bool) string { - if loc == (protocol.Location{}) { -- return "" +- return "" - } - lines := bytes.Count(run.test.archive.Comment, []byte("\n")) - var name string @@ -60906,8 +67403,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - lines += bytes.Count(f.Data, []byte("\n")) - } - if name == "" { -- run.env.T.Errorf("unable to find %s in test archive", loc) -- return "" +- return "" - } - m, err := run.env.Editor.Mapper(name) - if err != nil { @@ -60932,7 +67428,11 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - } - -- return fmt.Sprintf("%s:%s (%s:%s)", name, innerSpan, run.test.name, outerSpan) +- if includeTxtPos { +- return fmt.Sprintf("%s:%s (%s:%s)", name, innerSpan, run.test.name, outerSpan) +- } else { +- return fmt.Sprintf("%s:%s", name, innerSpan) +- } -} - -// makeMarkerFunc uses reflection to create a markerFunc for the given func value. @@ -60941,6 +67441,7 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - fn: reflect.ValueOf(fn), - } - mtyp := mi.fn.Type() +- mi.variadic = mtyp.IsVariadic() - if mtyp.NumIn() == 0 || mtyp.In(0) != markerType { - panic(fmt.Sprintf("marker function %#v must accept marker as its first argument", mi.fn)) - } @@ -60949,6 +67450,9 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - for a := 1; a < mtyp.NumIn(); a++ { - in := mtyp.In(a) +- if mi.variadic && a == mtyp.NumIn()-1 { +- in = in.Elem() // for ...T, convert to T +- } - mi.paramTypes = append(mi.paramTypes, in) - c := makeConverter(in) - mi.converters = append(mi.converters, c) @@ -61175,7 +67679,64 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - -// ---- marker functions ---- - --// defMarker implements the @godef marker, running textDocument/definition at +-// completeMarker implements the @complete marker, running +-// textDocument/completion at the given src location and asserting that the +-// results match the expected results. +-// +-// TODO(rfindley): for now, this is just a quick check against the expected +-// completion labels. We could do more by assembling richer completion items, +-// as is done in the old marker tests. Does that add value? If so, perhaps we +-// should support a variant form of the argument, labelOrItem, which allows the +-// string form or item form. +-func completeMarker(mark marker, src protocol.Location, want ...string) { +- list := mark.run.env.Completion(src) +- var got []string +- for _, item := range list.Items { +- got = append(got, item.Label) +- } +- if diff := cmp.Diff(want, got); diff != "" { +- mark.errorf("Completion(...) returned unexpect results (-want +got):\n%s", diff) +- } +-} +- +-// acceptCompletionMarker implements the @acceptCompletion marker, running +-// textDocument/completion at the given src location and accepting the +-// candidate with the given label. The resulting source must match the provided +-// golden content. +-func acceptCompletionMarker(mark marker, src protocol.Location, label string, golden *Golden) { +- list := mark.run.env.Completion(src) +- var selected *protocol.CompletionItem +- for _, item := range list.Items { +- if item.Label == label { +- selected = &item +- break +- } +- } +- if selected == nil { +- mark.errorf("Completion(...) did not return an item labeled %q", label) +- return +- } +- filename := mark.run.env.Sandbox.Workdir.URIToPath(mark.uri()) +- mapper, err := mark.run.env.Editor.Mapper(filename) +- if err != nil { +- mark.errorf("Editor.Mapper(%s) failed: %v", filename, err) +- return +- } +- +- patched, _, err := source.ApplyProtocolEdits(mapper, append([]protocol.TextEdit{ +- *selected.TextEdit, +- }, selected.AdditionalTextEdits...)) +- +- if err != nil { +- mark.errorf("ApplyProtocolEdits failed: %v", err) +- return +- } +- changes := map[string][]byte{filename: patched} +- // Check the file state. +- checkChangedFiles(mark, changes, golden) +-} +- +-// defMarker implements the @def marker, running textDocument/definition at -// the given src location and asserting that there is exactly one resulting -// location, matching dst. -// @@ -61188,6 +67749,40 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } -} - +-// formatMarker implements the @format marker. +-func formatMarker(mark marker, golden *Golden) { +- edits, err := mark.server().Formatting(mark.run.env.Ctx, &protocol.DocumentFormattingParams{ +- TextDocument: protocol.TextDocumentIdentifier{URI: mark.uri()}, +- }) +- var got []byte +- if err != nil { +- got = []byte(err.Error() + "\n") // all golden content is newline terminated +- } else { +- env := mark.run.env +- filename := env.Sandbox.Workdir.URIToPath(mark.uri()) +- mapper, err := env.Editor.Mapper(filename) +- if err != nil { +- mark.errorf("Editor.Mapper(%s) failed: %v", filename, err) +- } +- +- got, _, err = source.ApplyProtocolEdits(mapper, edits) +- if err != nil { +- mark.errorf("ApplyProtocolEdits failed: %v", err) +- return +- } +- } +- +- want, ok := golden.Get(mark.run.env.T, "", got) +- if !ok { +- mark.errorf("missing golden file @%s", golden.id) +- return +- } +- +- if diff := compare.Bytes(want, got); diff != "" { +- mark.errorf("golden file @%s does not match format results:\n%s", golden.id, diff) +- } +-} +- -// hoverMarker implements the @hover marker, running textDocument/hover at the -// given src location and asserting that the resulting hover is over the dst -// location (typically a span surrounding src), and that the markdown content @@ -61219,26 +67814,38 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// locMarker implements the @loc marker. It is executed before other -// markers, so that locations are available. -func locMarker(mark marker, name expect.Identifier, loc protocol.Location) { +- if prev, dup := mark.run.locations[name]; dup { +- mark.errorf("location %q already declared at %s", +- name, mark.run.fmtLoc(prev)) +- return +- } - mark.run.locations[name] = loc -} - -// diagMarker implements the @diag marker. It eliminates diagnostics from -// the observed set in mark.test. -func diagMarker(mark marker, loc protocol.Location, re *regexp.Regexp) { -- if _, err := removeDiagnostic(mark, loc, re); err != nil { -- mark.errorf("%v", err) +- if _, ok := removeDiagnostic(mark, loc, re); !ok { +- mark.errorf("no diagnostic at %v matches %q", loc, re) - } -} - --func removeDiagnostic(mark marker, loc protocol.Location, re *regexp.Regexp) (protocol.Diagnostic, error) { +-// removeDiagnostic looks for a diagnostic matching loc at the given position. +-// +-// If found, it returns (diag, true), and eliminates the matched diagnostic +-// from the unmatched set. +-// +-// If not found, it returns (protocol.Diagnostic{}, false). +-func removeDiagnostic(mark marker, loc protocol.Location, re *regexp.Regexp) (protocol.Diagnostic, bool) { +- loc.Range.End = loc.Range.Start // diagnostics ignore end position. - diags := mark.run.diags[loc] - for i, diag := range diags { - if re.MatchString(diag.Message) { - mark.run.diags[loc] = append(diags[:i], diags[i+1:]...) -- return diag, nil +- return diag, true - } - } -- return protocol.Diagnostic{}, fmt.Errorf("no diagnostic matches %q", re) +- return protocol.Diagnostic{}, false -} - -// renameMarker implements the @rename(location, new, golden) marker. @@ -61275,41 +67882,74 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - return nil, err - } - -- return applyDocumentChanges(env, editMap.DocumentChanges) +- fileChanges := make(map[string][]byte) +- if err := applyDocumentChanges(env, editMap.DocumentChanges, fileChanges); err != nil { +- return nil, fmt.Errorf("applying document changes: %v", err) +- } +- return fileChanges, nil -} - --// applyDocumentChanges returns the effect of applying the document --// changes to the contents of the Editor buffers. The actual editor --// buffers are unchanged. --func applyDocumentChanges(env *Env, changes []protocol.DocumentChanges) (map[string][]byte, error) { -- result := make(map[string][]byte) +-// applyDocumentChanges applies the given document changes to the editor buffer +-// content, recording the resulting contents in the fileChanges map. It is an +-// error for a change to an edit a file that is already present in the +-// fileChanges map. +-func applyDocumentChanges(env *Env, changes []protocol.DocumentChanges, fileChanges map[string][]byte) error { +- getMapper := func(path string) (*protocol.Mapper, error) { +- if _, ok := fileChanges[path]; ok { +- return nil, fmt.Errorf("internal error: %s is already edited", path) +- } +- return env.Editor.Mapper(path) +- } +- - for _, change := range changes { - if change.RenameFile != nil { - // rename - oldFile := env.Sandbox.Workdir.URIToPath(change.RenameFile.OldURI) -- newFile := env.Sandbox.Workdir.URIToPath(change.RenameFile.NewURI) -- mapper, err := env.Editor.Mapper(oldFile) +- mapper, err := getMapper(oldFile) - if err != nil { -- return nil, err +- return err - } -- result[newFile] = mapper.Content -- +- newFile := env.Sandbox.Workdir.URIToPath(change.RenameFile.NewURI) +- fileChanges[newFile] = mapper.Content - } else { - // edit - filename := env.Sandbox.Workdir.URIToPath(change.TextDocumentEdit.TextDocument.URI) -- mapper, err := env.Editor.Mapper(filename) +- mapper, err := getMapper(filename) - if err != nil { -- return nil, err +- return err - } - patched, _, err := source.ApplyProtocolEdits(mapper, change.TextDocumentEdit.Edits) - if err != nil { -- return nil, err +- return err - } -- result[filename] = patched +- fileChanges[filename] = patched - } - } - -- return result, nil +- return nil +-} +- +-func codeActionMarker(mark marker, actionKind string, start, end protocol.Location, golden *Golden) { +- // Request the range from start.Start to end.End. +- loc := start +- loc.Range.End = end.Range.End +- +- // Apply the fix it suggests. +- changed, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil) +- if err != nil { +- mark.errorf("codeAction failed: %v", err) +- return +- } +- +- // Check the file state. +- checkChangedFiles(mark, changed, golden) +-} +- +-func codeActionErrMarker(mark marker, actionKind string, start, end protocol.Location, wantErr wantError) { +- loc := start +- loc.Range.End = end.Range.End +- _, err := codeAction(mark.run.env, loc.URI, loc.Range, actionKind, nil) +- wantErr.check(mark, err) -} - -// suggestedfixMarker implements the @suggestedfix(location, regexp, @@ -61317,15 +67957,16 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma -// the expectation of a diagnostic, but then it applies the first code -// action of the specified kind suggested by the matched diagnostic. -func suggestedfixMarker(mark marker, loc protocol.Location, re *regexp.Regexp, actionKind string, golden *Golden) { +- loc.Range.End = loc.Range.Start // diagnostics ignore end position. - // Find and remove the matching diagnostic. -- diag, err := removeDiagnostic(mark, loc, re) -- if err != nil { -- mark.errorf("%v", err) +- diag, ok := removeDiagnostic(mark, loc, re) +- if !ok { +- mark.errorf("no diagnostic at %v matches %q", loc, re) - return - } - - // Apply the fix it suggests. -- changed, err := suggestedfix(mark.run.env, loc, diag, actionKind) +- changed, err := codeAction(mark.run.env, loc.URI, diag.Range, actionKind, &diag) - if err != nil { - mark.errorf("suggestedfix failed: %v. (Use @suggestedfixerr for expected errors.)", err) - return @@ -61335,19 +67976,29 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - checkChangedFiles(mark, changed, golden) -} - --func suggestedfix(env *Env, loc protocol.Location, diag protocol.Diagnostic, actionKind string) (map[string][]byte, error) { -- +-// codeAction executes a textDocument/codeAction request for the specified +-// location and kind. If diag is non-nil, it is used as the code action +-// context. +-// +-// The resulting map contains resulting file contents after the code action is +-// applied. Currently, this function does not support code actions that return +-// edits directly; it only supports code action commands. +-func codeAction(env *Env, uri protocol.DocumentURI, rng protocol.Range, actionKind string, diag *protocol.Diagnostic) (map[string][]byte, error) { - // Request all code actions that apply to the diagnostic. - // (The protocol supports filtering using Context.Only={actionKind} - // but we can give a better error if we don't filter.) -- actions, err := env.Editor.Server.CodeAction(env.Ctx, &protocol.CodeActionParams{ -- TextDocument: protocol.TextDocumentIdentifier{URI: loc.URI}, -- Range: diag.Range, +- params := &protocol.CodeActionParams{ +- TextDocument: protocol.TextDocumentIdentifier{URI: uri}, +- Range: rng, - Context: protocol.CodeActionContext{ -- Only: nil, // => all kinds -- Diagnostics: []protocol.Diagnostic{diag}, +- Only: nil, // => all kinds - }, -- }) +- } +- if diag != nil { +- params.Context.Diagnostics = []protocol.Diagnostic{*diag} +- } +- +- actions, err := env.Editor.Server.CodeAction(env.Ctx, params) - if err != nil { - return nil, err - } @@ -61367,47 +68018,229 @@ diff -urN a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/ma - } - action := candidates[0] - +- // Apply the codeAction. +- // +- // Spec: +- // "If a code action provides an edit and a command, first the edit is +- // executed and then the command." +- fileChanges := make(map[string][]byte) - // An action may specify an edit and/or a command, to be - // applied in that order. But since applyDocumentChanges(env, - // action.Edit.DocumentChanges) doesn't compose, for now we - // assert that all commands used in the @suggestedfix tests - // return only a command. -- if action.Edit.DocumentChanges != nil { -- env.T.Errorf("internal error: discarding unexpected CodeAction{Kind=%s, Title=%q}.Edit.DocumentChanges", action.Kind, action.Title) -- } -- if action.Command == nil { -- return nil, fmt.Errorf("missing CodeAction{Kind=%s, Title=%q}.Command", action.Kind, action.Title) +- if action.Edit != nil { +- if action.Edit.Changes != nil { +- env.T.Errorf("internal error: discarding unexpected CodeAction{Kind=%s, Title=%q}.Edit.Changes", action.Kind, action.Title) +- } +- if action.Edit.DocumentChanges != nil { +- if err := applyDocumentChanges(env, action.Edit.DocumentChanges, fileChanges); err != nil { +- return nil, fmt.Errorf("applying document changes: %v", err) +- } +- } - } - -- // This is a typical CodeAction command: -- // -- // Title: "Implement error" -- // Command: gopls.apply_fix -- // Arguments: [{"Fix":"stub_methods","URI":".../a.go","Range":...}}] -- // -- // The client makes an ExecuteCommand RPC to the server, -- // which dispatches it to the ApplyFix handler. -- // ApplyFix dispatches to the "stub_methods" suggestedfix hook (the meat). -- // The server then makes an ApplyEdit RPC to the client, -- // whose Awaiter hook gathers the edits instead of applying them. +- if action.Command != nil { +- // This is a typical CodeAction command: +- // +- // Title: "Implement error" +- // Command: gopls.apply_fix +- // Arguments: [{"Fix":"stub_methods","URI":".../a.go","Range":...}}] +- // +- // The client makes an ExecuteCommand RPC to the server, +- // which dispatches it to the ApplyFix handler. +- // ApplyFix dispatches to the "stub_methods" suggestedfix hook (the meat). +- // The server then makes an ApplyEdit RPC to the client, +- // whose Awaiter hook gathers the edits instead of applying them. - -- _ = env.Awaiter.takeDocumentChanges() // reset (assuming Env is confined to this thread) +- _ = env.Awaiter.takeDocumentChanges() // reset (assuming Env is confined to this thread) - -- if _, err := env.Editor.Server.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{ -- Command: action.Command.Command, -- Arguments: action.Command.Arguments, -- }); err != nil { -- env.T.Fatalf("error converting command %q to edits: %v", action.Command.Command, err) +- if _, err := env.Editor.Server.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{ +- Command: action.Command.Command, +- Arguments: action.Command.Arguments, +- }); err != nil { +- env.T.Fatalf("error converting command %q to edits: %v", action.Command.Command, err) +- } +- +- if err := applyDocumentChanges(env, env.Awaiter.takeDocumentChanges(), fileChanges); err != nil { +- return nil, fmt.Errorf("applying document changes from command: %v", err) +- } - } - -- return applyDocumentChanges(env, env.Awaiter.takeDocumentChanges()) +- return fileChanges, nil -} - -// TODO(adonovan): suggestedfixerr +- +-// refsMarker implements the @refs marker. +-func refsMarker(mark marker, src protocol.Location, want ...protocol.Location) { +- refs := func(includeDeclaration bool, want []protocol.Location) error { +- got, err := mark.server().References(mark.run.env.Ctx, &protocol.ReferenceParams{ +- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src), +- Context: protocol.ReferenceContext{ +- IncludeDeclaration: includeDeclaration, +- }, +- }) +- if err != nil { +- return err +- } +- +- return compareLocations(mark, got, want) +- } +- +- for _, includeDeclaration := range []bool{false, true} { +- // Ignore first 'want' location if we didn't request the declaration. +- // TODO(adonovan): don't assume a single declaration: +- // there may be >1 if corresponding methods are considered. +- want := want +- if !includeDeclaration && len(want) > 0 { +- want = want[1:] +- } +- if err := refs(includeDeclaration, want); err != nil { +- mark.errorf("refs(includeDeclaration=%t) failed: %v", +- includeDeclaration, err) +- } +- } +-} +- +-// implementationMarker implements the @implementation marker. +-func implementationMarker(mark marker, src protocol.Location, want ...protocol.Location) { +- got, err := mark.server().Implementation(mark.run.env.Ctx, &protocol.ImplementationParams{ +- TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src), +- }) +- if err != nil { +- mark.errorf("implementation at %s failed: %v", src, err) +- return +- } +- if err := compareLocations(mark, got, want); err != nil { +- mark.errorf("implementation: %v", err) +- } +-} +- +-// symbolMarker implements the @symbol marker. +-func symbolMarker(mark marker, golden *Golden) { +- // Retrieve information about all symbols in this file. +- symbols, err := mark.server().DocumentSymbol(mark.run.env.Ctx, &protocol.DocumentSymbolParams{ +- TextDocument: protocol.TextDocumentIdentifier{URI: mark.uri()}, +- }) +- if err != nil { +- mark.errorf("DocumentSymbol request failed: %v", err) +- return +- } +- +- // Format symbols one per line, sorted (in effect) by first column, a dotted name. +- var lines []string +- for _, symbol := range symbols { +- // Each result element is a union of (legacy) +- // SymbolInformation and (new) DocumentSymbol, +- // so we ascertain which one and then transcode. +- data, err := json.Marshal(symbol) +- if err != nil { +- mark.run.env.T.Fatal(err) +- } +- if _, ok := symbol.(map[string]interface{})["location"]; ok { +- // This case is not reached because Editor initialization +- // enables HierarchicalDocumentSymbolSupport. +- // TODO(adonovan): test this too. +- var sym protocol.SymbolInformation +- if err := json.Unmarshal(data, &sym); err != nil { +- mark.run.env.T.Fatal(err) +- } +- mark.errorf("fake Editor doesn't support SymbolInformation") +- +- } else { +- var sym protocol.DocumentSymbol // new hierarchical hotness +- if err := json.Unmarshal(data, &sym); err != nil { +- mark.run.env.T.Fatal(err) +- } +- +- // Print each symbol in the response tree. +- var visit func(sym protocol.DocumentSymbol, prefix []string) +- visit = func(sym protocol.DocumentSymbol, prefix []string) { +- var out strings.Builder +- out.WriteString(strings.Join(prefix, ".")) +- fmt.Fprintf(&out, " %q", sym.Detail) +- if delta := sym.Range.End.Line - sym.Range.Start.Line; delta > 0 { +- fmt.Fprintf(&out, " +%d lines", delta) +- } +- lines = append(lines, out.String()) +- +- for _, child := range sym.Children { +- visit(child, append(prefix, child.Name)) +- } +- } +- visit(sym, []string{sym.Name}) +- } +- } +- sort.Strings(lines) +- lines = append(lines, "") // match trailing newline in .txtar file +- got := []byte(strings.Join(lines, "\n")) +- +- // Compare with golden. +- want, ok := golden.Get(mark.run.env.T, "", got) +- if !ok { +- mark.errorf("%s: missing golden file @%s", mark.note.Name, golden.id) +- } else if diff := cmp.Diff(string(got), string(want)); diff != "" { +- mark.errorf("%s: unexpected output: got:\n%s\nwant:\n%s\ndiff:\n%s", +- mark.note.Name, got, want, diff) +- } +-} +- +-// compareLocations returns an error message if got and want are not +-// the same set of locations. The marker is used only for fmtLoc. +-func compareLocations(mark marker, got, want []protocol.Location) error { +- toStrings := func(locs []protocol.Location) []string { +- strs := make([]string, len(locs)) +- for i, loc := range locs { +- strs[i] = mark.run.fmtLoc(loc) +- } +- sort.Strings(strs) +- return strs +- } +- if diff := cmp.Diff(toStrings(want), toStrings(got)); diff != "" { +- return fmt.Errorf("incorrect result locations: (got %d, want %d):\n%s", +- len(got), len(want), diff) +- } +- return nil +-} +- +-func workspaceSymbolMarker(mark marker, query string, golden *Golden) { +- params := &protocol.WorkspaceSymbolParams{ +- Query: query, +- } +- +- gotSymbols, err := mark.server().Symbol(mark.run.env.Ctx, params) +- if err != nil { +- mark.errorf("Symbol(%q) failed: %v", query, err) +- return +- } +- var got bytes.Buffer +- for _, s := range gotSymbols { +- // Omit the txtar position of the symbol location; otherwise edits to the +- // txtar archive lead to unexpected failures. +- loc := mark.run.fmtLocDetails(s.Location, false) +- // TODO(rfindley): can we do better here, by detecting if the location is +- // relative to GOROOT? +- if loc == "" { +- loc = "" +- } +- fmt.Fprintf(&got, "%s %s %s\n", loc, s.Name, s.Kind) +- } +- +- want, ok := golden.Get(mark.run.env.T, "", got.Bytes()) +- if !ok { +- mark.errorf("missing golden file @%s", golden.id) +- return +- } +- +- if diff := compare.Bytes(want, got.Bytes()); diff != "" { +- mark.errorf("Symbol(%q) mismatch:\n%s", query, diff) +- } +-} diff -urN a/gopls/internal/lsp/regtest/options.go b/gopls/internal/lsp/regtest/options.go --- a/gopls/internal/lsp/regtest/options.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/regtest/options.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,105 +0,0 @@ +@@ -1,123 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -61423,6 +68256,18 @@ diff -urN a/gopls/internal/lsp/regtest/options.go b/gopls/internal/lsp/regtest/o - skipHooks bool -} - +-func defaultConfig() runConfig { +- return runConfig{ +- editor: fake.EditorConfig{ +- Settings: map[string]interface{}{ +- // Shorten the diagnostic delay to speed up test execution (else we'd add +- // the default delay to each assertion about diagnostics) +- "diagnosticsDelay": "10ms", +- }, +- }, +- } +-} +- -// A RunOption augments the behavior of the test runner. -type RunOption interface { - set(*runConfig) @@ -61462,8 +68307,14 @@ diff -urN a/gopls/internal/lsp/regtest/options.go b/gopls/internal/lsp/regtest/o - }) -} - --// Settings is a RunOption that sets user-provided configuration for the LSP --// server. +-// ClientName sets the LSP client name. +-func ClientName(name string) RunOption { +- return optionSetter(func(opts *runConfig) { +- opts.editor.ClientName = name +- }) +-} +- +-// Settings sets user-provided configuration for the LSP server. -// -// As a special case, the env setting must not be provided via Settings: use -// EnvVars instead. @@ -61516,7 +68367,7 @@ diff -urN a/gopls/internal/lsp/regtest/options.go b/gopls/internal/lsp/regtest/o diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/regtest.go --- a/gopls/internal/lsp/regtest/regtest.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/regtest/regtest.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,153 +0,0 @@ +@@ -1,156 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -61527,7 +68378,6 @@ diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/r - "context" - "flag" - "fmt" -- "io/ioutil" - "os" - "runtime" - "testing" @@ -61623,6 +68473,10 @@ diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/r - os.Exit(0) - } - +- if !testenv.HasExec() { +- fmt.Printf("skipping all tests: exec not supported on %s\n", runtime.GOOS) +- os.Exit(0) +- } - testenv.ExitIfSmallMachine() - - // Disable GOPACKAGESDRIVER, as it can cause spurious test failures. @@ -61648,7 +68502,7 @@ diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/r - } - } - -- dir, err := ioutil.TempDir("", "gopls-regtest-") +- dir, err := os.MkdirTemp("", "gopls-regtest-") - if err != nil { - panic(fmt.Errorf("creating regtest temp directory: %v", err)) - } @@ -61673,7 +68527,7 @@ diff -urN a/gopls/internal/lsp/regtest/regtest.go b/gopls/internal/lsp/regtest/r diff -urN a/gopls/internal/lsp/regtest/runner.go b/gopls/internal/lsp/regtest/runner.go --- a/gopls/internal/lsp/regtest/runner.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/regtest/runner.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,437 +0,0 @@ +@@ -1,436 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -61685,7 +68539,6 @@ diff -urN a/gopls/internal/lsp/regtest/runner.go b/gopls/internal/lsp/regtest/ru - "context" - "fmt" - "io" -- "io/ioutil" - "net" - "os" - "path/filepath" @@ -61830,7 +68683,7 @@ diff -urN a/gopls/internal/lsp/regtest/runner.go b/gopls/internal/lsp/regtest/ru - - for _, tc := range tests { - tc := tc -- var config runConfig +- config := defaultConfig() - for _, opt := range opts { - opt.set(&config) - } @@ -62046,7 +68899,7 @@ diff -urN a/gopls/internal/lsp/regtest/runner.go b/gopls/internal/lsp/regtest/ru - } - - r.startRemoteOnce.Do(func() { -- socketDir, err := ioutil.TempDir(r.tempDir, "gopls-regtest-socket") +- socketDir, err := os.MkdirTemp(r.tempDir, "gopls-regtest-socket") - if err != nil { - r.remoteErr = err - return @@ -62114,7 +68967,7 @@ diff -urN a/gopls/internal/lsp/regtest/runner.go b/gopls/internal/lsp/regtest/ru diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/wrappers.go --- a/gopls/internal/lsp/regtest/wrappers.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/regtest/wrappers.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,489 +0,0 @@ +@@ -1,533 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -62373,7 +69226,7 @@ diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/ -// directory. -func (e *Env) RunGoCommand(verb string, args ...string) { - e.T.Helper() -- if err := e.Sandbox.RunGoCommand(e.Ctx, "", verb, args, true); err != nil { +- if err := e.Sandbox.RunGoCommand(e.Ctx, "", verb, args, nil, true); err != nil { - e.T.Fatal(err) - } -} @@ -62382,7 +69235,16 @@ diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/ -// relative directory of the sandbox. -func (e *Env) RunGoCommandInDir(dir, verb string, args ...string) { - e.T.Helper() -- if err := e.Sandbox.RunGoCommand(e.Ctx, dir, verb, args, true); err != nil { +- if err := e.Sandbox.RunGoCommand(e.Ctx, dir, verb, args, nil, true); err != nil { +- e.T.Fatal(err) +- } +-} +- +-// RunGoCommandInDirWithEnv is like RunGoCommand, but executes in the given +-// relative directory of the sandbox with the given additional environment variables. +-func (e *Env) RunGoCommandInDirWithEnv(dir string, env []string, verb string, args ...string) { +- e.T.Helper() +- if err := e.Sandbox.RunGoCommand(e.Ctx, dir, verb, args, env, true); err != nil { - e.T.Fatal(err) - } -} @@ -62403,7 +69265,7 @@ diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/ -func (e *Env) DumpGoSum(dir string) { - e.T.Helper() - -- if err := e.Sandbox.RunGoCommand(e.Ctx, dir, "list", []string{"-mod=mod", "..."}, true); err != nil { +- if err := e.Sandbox.RunGoCommand(e.Ctx, dir, "list", []string{"-mod=mod", "..."}, nil, true); err != nil { - e.T.Fatal(err) - } - sumFile := path.Join(dir, "/go.sum") @@ -62478,6 +69340,41 @@ diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/ - } -} - +-// StartProfile starts a CPU profile with the given name, using the +-// gopls.start_profile custom command. It calls t.Fatal on any error. +-// +-// The resulting stop function must be called to stop profiling (using the +-// gopls.stop_profile custom command). +-func (e *Env) StartProfile() (stop func() string) { +- // TODO(golang/go#61217): revisit the ergonomics of these command APIs. +- // +- // This would be a lot simpler if we generated params constructors. +- args, err := command.MarshalArgs(command.StartProfileArgs{}) +- if err != nil { +- e.T.Fatal(err) +- } +- params := &protocol.ExecuteCommandParams{ +- Command: command.StartProfile.ID(), +- Arguments: args, +- } +- var result command.StartProfileResult +- e.ExecuteCommand(params, &result) +- +- return func() string { +- stopArgs, err := command.MarshalArgs(command.StopProfileArgs{}) +- if err != nil { +- e.T.Fatal(err) +- } +- stopParams := &protocol.ExecuteCommandParams{ +- Command: command.StopProfile.ID(), +- Arguments: stopArgs, +- } +- var result command.StopProfileResult +- e.ExecuteCommand(stopParams, &result) +- return result.File +- } +-} +- -// InlayHints calls textDocument/inlayHints for the given path, calling t.Fatal on -// any error. -func (e *Env) InlayHints(path string) []protocol.InlayHint { @@ -62607,7 +69504,7 @@ diff -urN a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/ diff -urN a/gopls/internal/lsp/rename.go b/gopls/internal/lsp/rename.go --- a/gopls/internal/lsp/rename.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/rename.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,78 +0,0 @@ +@@ -1,86 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -62620,9 +69517,14 @@ diff -urN a/gopls/internal/lsp/rename.go b/gopls/internal/lsp/rename.go - - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" -) - -func (s *Server) rename(ctx context.Context, params *protocol.RenameParams) (*protocol.WorkspaceEdit, error) { +- ctx, done := event.Start(ctx, "lsp.Server.rename", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { @@ -62636,9 +69538,9 @@ diff -urN a/gopls/internal/lsp/rename.go b/gopls/internal/lsp/rename.go - return nil, err - } - -- var docChanges []protocol.DocumentChanges +- docChanges := []protocol.DocumentChanges{} // must be a slice - for uri, e := range edits { -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -62668,6 +69570,9 @@ diff -urN a/gopls/internal/lsp/rename.go b/gopls/internal/lsp/rename.go -// TODO(rfindley): why wouldn't we want to show an error to the user, if the -// user initiated a rename request at the cursor? -func (s *Server) prepareRename(ctx context.Context, params *protocol.PrepareRenameParams) (*protocol.PrepareRename2Gn, error) { +- ctx, done := event.Start(ctx, "lsp.Server.prepareRename", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { @@ -62723,7 +69628,7 @@ diff -urN a/gopls/internal/lsp/reset_golden.sh b/gopls/internal/lsp/reset_golden diff -urN a/gopls/internal/lsp/safetoken/safetoken.go b/gopls/internal/lsp/safetoken/safetoken.go --- a/gopls/internal/lsp/safetoken/safetoken.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/safetoken/safetoken.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,122 +0,0 @@ +@@ -1,127 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -62817,6 +69722,11 @@ diff -urN a/gopls/internal/lsp/safetoken/safetoken.go b/gopls/internal/lsp/safet - return f.PositionFor(pos, false) -} - +-// Line returns the line number for the given offset in the given file. +-func Line(f *token.File, pos token.Pos) int { +- return Position(f, pos).Line +-} +- -// StartPosition converts a start Pos in the FileSet into a Position. -// -// Call this function only if start represents the start of a token or @@ -62849,7 +69759,7 @@ diff -urN a/gopls/internal/lsp/safetoken/safetoken.go b/gopls/internal/lsp/safet diff -urN a/gopls/internal/lsp/safetoken/safetoken_test.go b/gopls/internal/lsp/safetoken/safetoken_test.go --- a/gopls/internal/lsp/safetoken/safetoken_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/safetoken/safetoken_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,121 +0,0 @@ +@@ -1,132 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -62924,10 +69834,20 @@ diff -urN a/gopls/internal/lsp/safetoken/safetoken_test.go b/gopls/internal/lsp/ -// suggests alternatives. -func TestGoplsSourceDoesNotCallTokenFileMethods(t *testing.T) { - testenv.NeedsGoPackages(t) +- testenv.NeedsGo1Point(t, 18) +- testenv.NeedsLocalXTools(t) - -- pkgs, err := packages.Load(&packages.Config{ +- cfg := &packages.Config{ - Mode: packages.NeedName | packages.NeedModule | packages.NeedCompiledGoFiles | packages.NeedTypes | packages.NeedTypesInfo | packages.NeedSyntax | packages.NeedImports | packages.NeedDeps, -- }, "go/token", "golang.org/x/tools/gopls/...") +- } +- cfg.Env = os.Environ() +- cfg.Env = append(cfg.Env, +- "GOPACKAGESDRIVER=off", +- "GOWORK=off", // necessary for -mod=mod below +- "GOFLAGS=-mod=mod", +- ) +- +- pkgs, err := packages.Load(cfg, "go/token", "golang.org/x/tools/gopls/...") - if err != nil { - t.Fatal(err) - } @@ -62950,6 +69870,7 @@ diff -urN a/gopls/internal/lsp/safetoken/safetoken_test.go b/gopls/internal/lsp/ - oldMethod, _, _ := types.LookupFieldOrMethod(recv.Type(), true, recv.Pkg(), old) - alternative[oldMethod] = new - } +- setAlternative(File, "Line", "safetoken.Line") - setAlternative(File, "Offset", "safetoken.Offset") - setAlternative(File, "Position", "safetoken.Position") - setAlternative(File, "PositionFor", "safetoken.Position") @@ -63002,7 +69923,7 @@ diff -urN a/gopls/internal/lsp/selection_range.go b/gopls/internal/lsp/selection -// returned for each cursor to avoid multiple round-trips when the user is -// likely to issue this command multiple times in quick succession. -func (s *Server) selectionRange(ctx context.Context, params *protocol.SelectionRangeParams) ([]protocol.SelectionRange, error) { -- ctx, done := event.Start(ctx, "lsp.Server.documentSymbol") +- ctx, done := event.Start(ctx, "lsp.Server.selectionRange") - defer done() - - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) @@ -63047,7 +69968,7 @@ diff -urN a/gopls/internal/lsp/selection_range.go b/gopls/internal/lsp/selection diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go --- a/gopls/internal/lsp/semantic.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/semantic.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1003 +0,0 @@ +@@ -1,999 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -63073,6 +69994,7 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/lsp/template" - "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" - "golang.org/x/tools/internal/typeparams" -) - @@ -63087,25 +70009,22 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go -// semDebug should NEVER be true in checked-in code -const semDebug = false - --func (s *Server) semanticTokensFull(ctx context.Context, p *protocol.SemanticTokensParams) (*protocol.SemanticTokens, error) { -- ret, err := s.computeSemanticTokens(ctx, p.TextDocument, nil) +-func (s *Server) semanticTokensFull(ctx context.Context, params *protocol.SemanticTokensParams) (*protocol.SemanticTokens, error) { +- ctx, done := event.Start(ctx, "lsp.Server.semanticTokensFull", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- +- ret, err := s.computeSemanticTokens(ctx, params.TextDocument, nil) - return ret, err -} - --func (s *Server) semanticTokensFullDelta(ctx context.Context, p *protocol.SemanticTokensDeltaParams) (interface{}, error) { -- return nil, fmt.Errorf("implement SemanticTokensFullDelta") --} +-func (s *Server) semanticTokensRange(ctx context.Context, params *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) { +- ctx, done := event.Start(ctx, "lsp.Server.semanticTokensRange", tag.URI.Of(params.TextDocument.URI)) +- defer done() - --func (s *Server) semanticTokensRange(ctx context.Context, p *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) { -- ret, err := s.computeSemanticTokens(ctx, p.TextDocument, &p.Range) +- ret, err := s.computeSemanticTokens(ctx, params.TextDocument, ¶ms.Range) - return ret, err -} - --func (s *Server) semanticTokensRefresh(ctx context.Context) error { -- // in the code, but not in the protocol spec -- return fmt.Errorf("implement SemanticTokensRefresh") --} -- -func (s *Server) computeSemanticTokens(ctx context.Context, td protocol.TextDocumentIdentifier, rng *protocol.Range) (*protocol.SemanticTokens, error) { - ans := protocol.SemanticTokens{ - Data: []uint32{}, @@ -63115,13 +70034,12 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go - if !ok { - return nil, err - } -- vv := snapshot.View() -- if !vv.Options().SemanticTokens { +- if !snapshot.Options().SemanticTokens { - // return an error, so if the option changes - // the client won't remember the wrong answer - return nil, fmt.Errorf("semantictokens are disabled") - } -- kind := snapshot.View().FileKind(fh) +- kind := snapshot.FileKind(fh) - if kind == source.Tmpl { - // this is a little cumbersome to avoid both exporting 'encoded' and its methods - // and to avoid import cycles @@ -63143,7 +70061,7 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go - if kind != source.Go { - return nil, nil - } -- pkg, pgf, err := source.PackageForFile(ctx, snapshot, fh.URI(), source.NarrowestPackage) +- pkg, pgf, err := source.NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err - } @@ -63163,8 +70081,8 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go - fset: pkg.FileSet(), - tokTypes: s.session.Options().SemanticTypes, - tokMods: s.session.Options().SemanticMods, -- noStrings: vv.Options().NoSemanticString, -- noNumbers: vv.Options().NoSemanticNumber, +- noStrings: snapshot.Options().NoSemanticString, +- noNumbers: snapshot.Options().NoSemanticNumber, - } - if err := e.init(); err != nil { - // e.init should never return an error, unless there's some @@ -63308,7 +70226,7 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go -// find the line in the source -func (e *encoded) srcLine(x ast.Node) string { - file := e.pgf.Tok -- line := file.Line(x.Pos()) +- line := safetoken.Line(file, x.Pos()) - start, err := safetoken.Offset(file, file.LineStart(line)) - if err != nil { - return "" @@ -63889,17 +70807,16 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go -} - -func (e *encoded) init() error { -- e.start = token.Pos(e.pgf.Tok.Base()) -- e.end = e.start + token.Pos(e.pgf.Tok.Size()) -- if e.rng == nil { -- return nil -- } -- span, err := e.pgf.Mapper.RangeSpan(*e.rng) -- if err != nil { -- return fmt.Errorf("range span (%w) error for %s", err, e.pgf.File.Name) +- if e.rng != nil { +- var err error +- e.start, e.end, err = e.pgf.RangePos(*e.rng) +- if err != nil { +- return fmt.Errorf("range span (%w) error for %s", err, e.pgf.File.Name) +- } +- } else { +- tok := e.pgf.Tok +- e.start, e.end = tok.Pos(0), tok.Pos(tok.Size()) // entire file - } -- e.end = e.start + token.Pos(span.End().Offset()) -- e.start += token.Pos(span.Start().Offset()) - return nil -} - @@ -64054,7 +70971,7 @@ diff -urN a/gopls/internal/lsp/semantic.go b/gopls/internal/lsp/semantic.go diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go --- a/gopls/internal/lsp/server_gen.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/server_gen.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,301 +0,0 @@ +@@ -1,309 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -64213,6 +71130,10 @@ diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go - return s.inlayHint(ctx, params) -} - +-func (s *Server) InlineCompletion(context.Context, *protocol.InlineCompletionParams) (*protocol.Or_Result_textDocument_inlineCompletion, error) { +- return nil, notImplemented("InlineCompletion") +-} +- -func (s *Server) InlineValue(context.Context, *protocol.InlineValueParams) ([]protocol.InlineValue, error) { - return nil, notImplemented("InlineValue") -} @@ -64257,6 +71178,10 @@ diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go - return nil, notImplemented("RangeFormatting") -} - +-func (s *Server) RangesFormatting(context.Context, *protocol.DocumentRangesFormattingParams) ([]protocol.TextEdit, error) { +- return nil, notImplemented("RangesFormatting") +-} +- -func (s *Server) References(ctx context.Context, params *protocol.ReferenceParams) ([]protocol.Location, error) { - return s.references(ctx, params) -} @@ -64293,16 +71218,16 @@ diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go - return s.selectionRange(ctx, params) -} - --func (s *Server) SemanticTokensFull(ctx context.Context, p *protocol.SemanticTokensParams) (*protocol.SemanticTokens, error) { -- return s.semanticTokensFull(ctx, p) +-func (s *Server) SemanticTokensFull(ctx context.Context, params *protocol.SemanticTokensParams) (*protocol.SemanticTokens, error) { +- return s.semanticTokensFull(ctx, params) -} - --func (s *Server) SemanticTokensFullDelta(ctx context.Context, p *protocol.SemanticTokensDeltaParams) (interface{}, error) { -- return s.semanticTokensFullDelta(ctx, p) +-func (s *Server) SemanticTokensFullDelta(context.Context, *protocol.SemanticTokensDeltaParams) (interface{}, error) { +- return nil, notImplemented("SemanticTokensFullDelta") -} - --func (s *Server) SemanticTokensRange(ctx context.Context, p *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) { -- return s.semanticTokensRange(ctx, p) +-func (s *Server) SemanticTokensRange(ctx context.Context, params *protocol.SemanticTokensRangeParams) (*protocol.SemanticTokens, error) { +- return s.semanticTokensRange(ctx, params) -} - -func (s *Server) SetTrace(context.Context, *protocol.SetTraceParams) error { @@ -64359,7 +71284,7 @@ diff -urN a/gopls/internal/lsp/server_gen.go b/gopls/internal/lsp/server_gen.go diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go --- a/gopls/internal/lsp/server.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/server.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,158 +0,0 @@ +@@ -1,200 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -64372,6 +71297,7 @@ diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go -import ( - "context" - "fmt" +- "os" - "sync" - - "golang.org/x/tools/gopls/internal/lsp/cache" @@ -64379,24 +71305,24 @@ diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/jsonrpc2" -) - -const concurrentAnalyses = 1 - -// NewServer creates an LSP server and binds it to handle incoming client --// messages on on the supplied stream. +-// messages on the supplied stream. -func NewServer(session *cache.Session, client protocol.ClientCloser) *Server { - return &Server{ - diagnostics: map[span.URI]*fileReports{}, - gcOptimizationDetails: make(map[source.PackageID]struct{}), -- watchedGlobPatterns: make(map[string]struct{}), +- watchedGlobPatterns: nil, // empty - changedFiles: make(map[span.URI]struct{}), - session: session, - client: client, - diagnosticsSema: make(chan struct{}, concurrentAnalyses), - progress: progress.NewTracker(client), -- diagDebouncer: newDebouncer(), - } -} - @@ -64447,6 +71373,7 @@ diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go - // watchedGlobPatterns is the set of glob patterns that we have requested - // the client watch on disk. It will be updated as the set of directories - // that the server should watch changes. +- // The map field may be reassigned but the map is immutable. - watchedGlobPatternsMu sync.Mutex - watchedGlobPatterns map[string]struct{} - watchRegistrationCount int @@ -64466,20 +71393,28 @@ diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go - - progress *progress.Tracker - -- // diagDebouncer is used for debouncing diagnostics. -- diagDebouncer *debouncer -- - // When the workspace fails to load, we show its status through a progress - // report with an error message. - criticalErrorStatusMu sync.Mutex - criticalErrorStatus *progress.WorkDone +- +- // Track an ongoing CPU profile created with the StartProfile command and +- // terminated with the StopProfile command. +- ongoingProfileMu sync.Mutex +- ongoingProfile *os.File // if non-nil, an ongoing profile is writing to this file -} - -func (s *Server) workDoneProgressCancel(ctx context.Context, params *protocol.WorkDoneProgressCancelParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.workDoneProgressCancel") +- defer done() +- - return s.progress.Cancel(params.Token) -} - -func (s *Server) nonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) { +- ctx, done := event.Start(ctx, "lsp.Server.nonstandardRequest") +- defer done() +- - switch method { - case "gopls/diagnoseFiles": - paramMap := params.(map[string]interface{}) @@ -64493,7 +71428,7 @@ diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go - return nil, err - } - -- fileID, diagnostics, err := source.FileDiagnostics(ctx, snapshot, fh.URI()) +- fileID, diagnostics, err := s.diagnoseFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err - } @@ -64515,13 +71450,45 @@ diff -urN a/gopls/internal/lsp/server.go b/gopls/internal/lsp/server.go - return nil, notImplemented(method) -} - +-// fileDiagnostics reports diagnostics in the specified file, +-// as used by the "gopls check" or "gopls fix" commands. +-// +-// TODO(adonovan): opt: this function is called in a loop from the +-// "gopls/diagnoseFiles" nonstandard request handler. It would be more +-// efficient to compute the set of packages and TypeCheck and +-// Analyze them all at once. Or instead support textDocument/diagnostic +-// (golang/go#60122). +-func (s *Server) diagnoseFile(ctx context.Context, snapshot source.Snapshot, uri span.URI) (source.FileHandle, []*source.Diagnostic, error) { +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, nil, err +- } +- pkg, _, err := source.NarrowestPackageForFile(ctx, snapshot, uri) +- if err != nil { +- return nil, nil, err +- } +- pkgDiags, err := pkg.DiagnosticsForFile(ctx, snapshot, uri) +- if err != nil { +- return nil, nil, err +- } +- adiags, err := source.Analyze(ctx, snapshot, map[source.PackageID]unit{pkg.Metadata().ID: {}}, nil /* progress tracker */) +- if err != nil { +- return nil, nil, err +- } +- var td, ad []*source.Diagnostic // combine load/parse/type + analysis diagnostics +- source.CombineDiagnostics(pkgDiags, adiags[uri], &td, &ad) +- s.storeDiagnostics(snapshot, uri, typeCheckSource, td, true) +- s.storeDiagnostics(snapshot, uri, analysisSource, ad, true) +- return fh, append(td, ad...), nil +-} +- -func notImplemented(method string) error { - return fmt.Errorf("%w: %q not yet implemented", jsonrpc2.ErrMethodNotFound, method) -} diff -urN a/gopls/internal/lsp/signature_help.go b/gopls/internal/lsp/signature_help.go --- a/gopls/internal/lsp/signature_help.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/signature_help.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ +@@ -1,34 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -64538,6 +71505,9 @@ diff -urN a/gopls/internal/lsp/signature_help.go b/gopls/internal/lsp/signature_ -) - -func (s *Server) signatureHelp(ctx context.Context, params *protocol.SignatureHelpParams) (*protocol.SignatureHelp, error) { +- ctx, done := event.Start(ctx, "lsp.Server.signatureHelp", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.Go) - defer release() - if !ok { @@ -64767,7 +71737,7 @@ diff -urN a/gopls/internal/lsp/source/add_import.go b/gopls/internal/lsp/source/ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/api_json.go --- a/gopls/internal/lsp/source/api_json.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/api_json.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1118 +0,0 @@ +@@ -1,1233 +0,0 @@ -// Code generated by "golang.org/x/tools/gopls/doc/generate"; DO NOT EDIT. - -package source @@ -64965,6 +71935,23 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Hierarchy: "ui.navigation", - }, - { +- Name: "symbolScope", +- Type: "enum", +- Doc: "symbolScope controls which packages are searched for workspace/symbol\nrequests. The default value, \"workspace\", searches only workspace\npackages. The legacy behavior, \"all\", causes all loaded packages to be\nsearched, including dependencies; this is more expensive and may return\nunwanted results.\n", +- EnumValues: []EnumValue{ +- { +- Value: "\"all\"", +- Doc: "`\"all\"` matches symbols in any loaded package, including\ndependencies.\n", +- }, +- { +- Value: "\"workspace\"", +- Doc: "`\"workspace\"` matches symbols in workspace packages only.\n", +- }, +- }, +- Default: "\"all\"", +- Hierarchy: "ui.navigation", +- }, +- { - Name: "analyses", - Type: "map[string]bool", - Doc: "analyses specify analyses that the user would like to enable or disable.\nA map of the names of analysis passes that should be enabled/disabled.\nA full list of analyzers that gopls uses can be found in\n[analyzers.md](https://github.com/golang/tools/blob/master/gopls/doc/analyzers.md).\n\nExample Usage:\n\n```json5\n...\n\"analyses\": {\n \"unreachable\": false, // Disable the unreachable analyzer.\n \"unusedparams\": true // Enable the unusedparams analyzer.\n}\n...\n```\n", @@ -65022,13 +72009,23 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Default: "true", - }, - { +- Name: "\"defer\"", +- Doc: "report common mistakes in defer statements\n\nThe defer analyzer reports a diagnostic when a defer statement would\nresult in a non-deferred call to time.Since, as experience has shown\nthat this is nearly always a mistake.\n\nFor example:\n\n\tstart := time.Now()\n\t...\n\tdefer recordLatency(time.Since(start)) // error: call to time.Since is not deferred\n\nThe correct code is:\n\n\tdefer func() { recordLatency(time.Since(start)) }()", +- Default: "true", +- }, +- { +- Name: "\"deprecated\"", +- Doc: "check for use of deprecated identifiers\n\nThe deprecated analyzer looks for deprecated symbols and package imports.\n\nSee https://go.dev/wiki/Deprecated to learn about Go's convention\nfor documenting and signaling deprecated identifiers.", +- Default: "true", +- }, +- { - Name: "\"directive\"", - Doc: "check Go toolchain directives such as //go:debug\n\nThis analyzer checks for problems with known Go toolchain directives\nin all Go source files in a package directory, even those excluded by\n//go:build constraints, and all non-Go source files too.\n\nFor //go:debug (see https://go.dev/doc/godebug), the analyzer checks\nthat the directives are placed only in Go source files, only above the\npackage comment, and only in package main or *_test.go files.\n\nSupport for other known directives may be added in the future.\n\nThis analyzer does not check //go:build, which is handled by the\nbuildtag analyzer.\n", - Default: "true", - }, - { - Name: "\"embed\"", -- Doc: "check for //go:embed directive import\n\nThis analyzer checks that the embed package is imported when source code contains //go:embed comment directives.\nThe embed package must be imported for //go:embed directives to function.import _ \"embed\".", +- Doc: "check //go:embed directive usage\n\nThis analyzer checks that the embed package is imported if //go:embed\ndirectives are present, providing a suggested fix to add the import if\nit is missing.\n\nThis analyzer also checks that //go:embed directives precede the\ndeclaration of a single variable.", - Default: "true", - }, - { @@ -65048,17 +72045,12 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - }, - { - Name: "\"ifaceassert\"", -- Doc: "detect impossible interface-to-interface type assertions\n\nThis checker flags type assertions v.(T) and corresponding type-switch cases\nin which the static type V of v is an interface that cannot possibly implement\nthe target interface T. This occurs when V and T contain methods with the same\nname but different signatures. Example:\n\n\tvar v interface {\n\t\tRead()\n\t}\n\t_ = v.(io.Reader)\n\nThe Read method in v has a different signature than the Read method in\nio.Reader, so this assertion cannot succeed.\n", -- Default: "true", -- }, -- { -- Name: "\"infertypeargs\"", -- Doc: "check for unnecessary type arguments in call expressions\n\nExplicit type arguments may be omitted from call expressions if they can be\ninferred from function arguments, or from other type arguments:\n\n\tfunc f[T any](T) {}\n\t\n\tfunc _() {\n\t\tf[string](\"foo\") // string could be inferred\n\t}\n", +- Doc: "detect impossible interface-to-interface type assertions\n\nThis checker flags type assertions v.(T) and corresponding type-switch cases\nin which the static type V of v is an interface that cannot possibly implement\nthe target interface T. This occurs when V and T contain methods with the same\nname but different signatures. Example:\n\n\tvar v interface {\n\t\tRead()\n\t}\n\t_ = v.(io.Reader)\n\nThe Read method in v has a different signature than the Read method in\nio.Reader, so this assertion cannot succeed.", - Default: "true", - }, - { - Name: "\"loopclosure\"", -- Doc: "check references to loop variables from within nested functions\n\nThis analyzer reports places where a function literal references the\niteration variable of an enclosing loop, and the loop calls the function\nin such a way (e.g. with go or defer) that it may outlive the loop\niteration and possibly observe the wrong value of the variable.\n\nIn this example, all the deferred functions run after the loop has\ncompleted, so all observe the final value of v.\n\n for _, v := range list {\n defer func() {\n use(v) // incorrect\n }()\n }\n\nOne fix is to create a new variable for each iteration of the loop:\n\n for _, v := range list {\n v := v // new var per iteration\n defer func() {\n use(v) // ok\n }()\n }\n\nThe next example uses a go statement and has a similar problem.\nIn addition, it has a data race because the loop updates v\nconcurrent with the goroutines accessing it.\n\n for _, v := range elem {\n go func() {\n use(v) // incorrect, and a data race\n }()\n }\n\nA fix is the same as before. The checker also reports problems\nin goroutines started by golang.org/x/sync/errgroup.Group.\nA hard-to-spot variant of this form is common in parallel tests:\n\n func Test(t *testing.T) {\n for _, test := range tests {\n t.Run(test.name, func(t *testing.T) {\n t.Parallel()\n use(test) // incorrect, and a data race\n })\n }\n }\n\nThe t.Parallel() call causes the rest of the function to execute\nconcurrent with the loop.\n\nThe analyzer reports references only in the last statement,\nas it is not deep enough to understand the effects of subsequent\nstatements that might render the reference benign.\n(\"Last statement\" is defined recursively in compound\nstatements such as if, switch, and select.)\n\nSee: https://golang.org/doc/go_faq.html#closures_and_goroutines", +- Doc: "check references to loop variables from within nested functions\n\nThis analyzer reports places where a function literal references the\niteration variable of an enclosing loop, and the loop calls the function\nin such a way (e.g. with go or defer) that it may outlive the loop\niteration and possibly observe the wrong value of the variable.\n\nIn this example, all the deferred functions run after the loop has\ncompleted, so all observe the final value of v.\n\n\tfor _, v := range list {\n\t defer func() {\n\t use(v) // incorrect\n\t }()\n\t}\n\nOne fix is to create a new variable for each iteration of the loop:\n\n\tfor _, v := range list {\n\t v := v // new var per iteration\n\t defer func() {\n\t use(v) // ok\n\t }()\n\t}\n\nThe next example uses a go statement and has a similar problem.\nIn addition, it has a data race because the loop updates v\nconcurrent with the goroutines accessing it.\n\n\tfor _, v := range elem {\n\t go func() {\n\t use(v) // incorrect, and a data race\n\t }()\n\t}\n\nA fix is the same as before. The checker also reports problems\nin goroutines started by golang.org/x/sync/errgroup.Group.\nA hard-to-spot variant of this form is common in parallel tests:\n\n\tfunc Test(t *testing.T) {\n\t for _, test := range tests {\n\t t.Run(test.name, func(t *testing.T) {\n\t t.Parallel()\n\t use(test) // incorrect, and a data race\n\t })\n\t }\n\t}\n\nThe t.Parallel() call causes the rest of the function to execute\nconcurrent with the loop.\n\nThe analyzer reports references only in the last statement,\nas it is not deep enough to understand the effects of subsequent\nstatements that might render the reference benign.\n(\"Last statement\" is defined recursively in compound\nstatements such as if, switch, and select.)\n\nSee: https://golang.org/doc/go_faq.html#closures_and_goroutines", - Default: "true", - }, - { @@ -65073,17 +72065,17 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - }, - { - Name: "\"nilness\"", -- Doc: "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}\n", +- Doc: "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}", - Default: "false", - }, - { - Name: "\"printf\"", -- Doc: "check consistency of Printf format strings and arguments\n\nThe check applies to known functions (for example, those in package fmt)\nas well as any detected wrappers of known functions.\n\nA function that wants to avail itself of printf checking but is not\nfound by this analyzer's heuristics (for example, due to use of\ndynamic calls) can insert a bogus call:\n\n\tif false {\n\t\t_ = fmt.Sprintf(format, args...) // enable printf checking\n\t}\n\nThe -funcs flag specifies a comma-separated list of names of additional\nknown formatting functions or methods. If the name contains a period,\nit must denote a specific function using one of the following forms:\n\n\tdir/pkg.Function\n\tdir/pkg.Type.Method\n\t(*dir/pkg.Type).Method\n\nOtherwise the name is interpreted as a case-insensitive unqualified\nidentifier such as \"errorf\". Either way, if a listed name ends in f, the\nfunction is assumed to be Printf-like, taking a format string before the\nargument list. Otherwise it is assumed to be Print-like, taking a list\nof arguments with no format string.\n", +- Doc: "check consistency of Printf format strings and arguments\n\nThe check applies to calls of the formatting functions such as\n[fmt.Printf] and [fmt.Sprintf], as well as any detected wrappers of\nthose functions.\n\nIn this example, the %d format operator requires an integer operand:\n\n\tfmt.Printf(\"%d\", \"hello\") // fmt.Printf format %d has arg \"hello\" of wrong type string\n\nSee the documentation of the fmt package for the complete set of\nformat operators and their operand types.\n\nTo enable printf checking on a function that is not found by this\nanalyzer's heuristics (for example, because control is obscured by\ndynamic method calls), insert a bogus call:\n\n\tfunc MyPrintf(format string, args ...any) {\n\t\tif false {\n\t\t\t_ = fmt.Sprintf(format, args...) // enable printf checker\n\t\t}\n\t\t...\n\t}\n\nThe -funcs flag specifies a comma-separated list of names of additional\nknown formatting functions or methods. If the name contains a period,\nit must denote a specific function using one of the following forms:\n\n\tdir/pkg.Function\n\tdir/pkg.Type.Method\n\t(*dir/pkg.Type).Method\n\nOtherwise the name is interpreted as a case-insensitive unqualified\nidentifier such as \"errorf\". Either way, if a listed name ends in f, the\nfunction is assumed to be Printf-like, taking a format string before the\nargument list. Otherwise it is assumed to be Print-like, taking a list\nof arguments with no format string.", - Default: "true", - }, - { - Name: "\"shadow\"", -- Doc: "check for possible unintended shadowing of variables\n\nThis analyzer check for shadowed variables.\nA shadowed variable is a variable declared in an inner scope\nwith the same name and type as a variable in an outer scope,\nand where the outer variable is mentioned after the inner one\nis declared.\n\n(This definition can be refined; the module generates too many\nfalse positives and is not yet enabled by default.)\n\nFor example:\n\n\tfunc BadRead(f *os.File, buf []byte) error {\n\t\tvar err error\n\t\tfor {\n\t\t\tn, err := f.Read(buf) // shadows the function variable 'err'\n\t\t\tif err != nil {\n\t\t\t\tbreak // causes return of wrong value\n\t\t\t}\n\t\t\tfoo(buf)\n\t\t}\n\t\treturn err\n\t}\n", +- Doc: "check for possible unintended shadowing of variables\n\nThis analyzer check for shadowed variables.\nA shadowed variable is a variable declared in an inner scope\nwith the same name and type as a variable in an outer scope,\nand where the outer variable is mentioned after the inner one\nis declared.\n\n(This definition can be refined; the module generates too many\nfalse positives and is not yet enabled by default.)\n\nFor example:\n\n\tfunc BadRead(f *os.File, buf []byte) error {\n\t\tvar err error\n\t\tfor {\n\t\t\tn, err := f.Read(buf) // shadows the function variable 'err'\n\t\t\tif err != nil {\n\t\t\t\tbreak // causes return of wrong value\n\t\t\t}\n\t\t\tfoo(buf)\n\t\t}\n\t\treturn err\n\t}", - Default: "false", - }, - { @@ -65107,18 +72099,23 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Default: "true", - }, - { +- Name: "\"slog\"", +- Doc: "check for invalid structured logging calls\n\nThe slog checker looks for calls to functions from the log/slog\npackage that take alternating key-value pairs. It reports calls\nwhere an argument in a key position is neither a string nor a\nslog.Attr, and where a final key is missing its value.\nFor example,it would report\n\n\tslog.Warn(\"message\", 11, \"k\") // slog.Warn arg \"11\" should be a string or a slog.Attr\n\nand\n\n\tslog.Info(\"message\", \"k1\", v1, \"k2\") // call to slog.Info missing a final value", +- Default: "true", +- }, +- { - Name: "\"sortslice\"", - Doc: "check the argument type of sort.Slice\n\nsort.Slice requires an argument of a slice type. Check that\nthe interface{} value passed to sort.Slice is actually a slice.", - Default: "true", - }, - { - Name: "\"stdmethods\"", -- Doc: "check signature of methods of well-known interfaces\n\nSometimes a type may be intended to satisfy an interface but may fail to\ndo so because of a mistake in its method signature.\nFor example, the result of this WriteTo method should be (int64, error),\nnot error, to satisfy io.WriterTo:\n\n\ttype myWriterTo struct{...}\n func (myWriterTo) WriteTo(w io.Writer) error { ... }\n\nThis check ensures that each method whose name matches one of several\nwell-known interface methods from the standard library has the correct\nsignature for that interface.\n\nChecked method names include:\n\tFormat GobEncode GobDecode MarshalJSON MarshalXML\n\tPeek ReadByte ReadFrom ReadRune Scan Seek\n\tUnmarshalJSON UnreadByte UnreadRune WriteByte\n\tWriteTo\n", +- Doc: "check signature of methods of well-known interfaces\n\nSometimes a type may be intended to satisfy an interface but may fail to\ndo so because of a mistake in its method signature.\nFor example, the result of this WriteTo method should be (int64, error),\nnot error, to satisfy io.WriterTo:\n\n\ttype myWriterTo struct{...}\n\tfunc (myWriterTo) WriteTo(w io.Writer) error { ... }\n\nThis check ensures that each method whose name matches one of several\nwell-known interface methods from the standard library has the correct\nsignature for that interface.\n\nChecked method names include:\n\n\tFormat GobEncode GobDecode MarshalJSON MarshalXML\n\tPeek ReadByte ReadFrom ReadRune Scan Seek\n\tUnmarshalJSON UnreadByte UnreadRune WriteByte\n\tWriteTo", - Default: "true", - }, - { - Name: "\"stringintconv\"", -- Doc: "check for string(int) conversions\n\nThis checker flags conversions of the form string(x) where x is an integer\n(but not byte or rune) type. Such conversions are discouraged because they\nreturn the UTF-8 representation of the Unicode code point x, and not a decimal\nstring representation of x as one might expect. Furthermore, if x denotes an\ninvalid code point, the conversion cannot be statically rejected.\n\nFor conversions that intend on using the code point, consider replacing them\nwith string(rune(x)). Otherwise, strconv.Itoa and its equivalents return the\nstring representation of the value in the desired base.\n", +- Doc: "check for string(int) conversions\n\nThis checker flags conversions of the form string(x) where x is an integer\n(but not byte or rune) type. Such conversions are discouraged because they\nreturn the UTF-8 representation of the Unicode code point x, and not a decimal\nstring representation of x as one might expect. Furthermore, if x denotes an\ninvalid code point, the conversion cannot be statically rejected.\n\nFor conversions that intend on using the code point, consider replacing them\nwith string(rune(x)). Otherwise, strconv.Itoa and its equivalents return the\nstring representation of the value in the desired base.", - Default: "true", - }, - { @@ -65128,17 +72125,17 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - }, - { - Name: "\"testinggoroutine\"", -- Doc: "report calls to (*testing.T).Fatal from goroutines started by a test.\n\nFunctions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and\nSkip{,f,Now} methods of *testing.T, must be called from the test goroutine itself.\nThis checker detects calls to these functions that occur within a goroutine\nstarted by the test. For example:\n\nfunc TestFoo(t *testing.T) {\n go func() {\n t.Fatal(\"oops\") // error: (*T).Fatal called from non-test goroutine\n }()\n}\n", +- Doc: "report calls to (*testing.T).Fatal from goroutines started by a test.\n\nFunctions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and\nSkip{,f,Now} methods of *testing.T, must be called from the test goroutine itself.\nThis checker detects calls to these functions that occur within a goroutine\nstarted by the test. For example:\n\n\tfunc TestFoo(t *testing.T) {\n\t go func() {\n\t t.Fatal(\"oops\") // error: (*T).Fatal called from non-test goroutine\n\t }()\n\t}", - Default: "true", - }, - { - Name: "\"tests\"", -- Doc: "check for common mistaken usages of tests and examples\n\nThe tests checker walks Test, Benchmark and Example functions checking\nmalformed names, wrong signatures and examples documenting non-existent\nidentifiers.\n\nPlease see the documentation for package testing in golang.org/pkg/testing\nfor the conventions that are enforced for Tests, Benchmarks, and Examples.", +- Doc: "check for common mistaken usages of tests and examples\n\nThe tests checker walks Test, Benchmark, Fuzzing and Example functions checking\nmalformed names, wrong signatures and examples documenting non-existent\nidentifiers.\n\nPlease see the documentation for package testing in golang.org/pkg/testing\nfor the conventions that are enforced for Tests, Benchmarks, and Examples.", - Default: "true", - }, - { - Name: "\"timeformat\"", -- Doc: "check for calls of (time.Time).Format or time.Parse with 2006-02-01\n\nThe timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm)\nformat. Internationally, \"yyyy-dd-mm\" does not occur in common calendar date\nstandards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended.\n", +- Doc: "check for calls of (time.Time).Format or time.Parse with 2006-02-01\n\nThe timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm)\nformat. Internationally, \"yyyy-dd-mm\" does not occur in common calendar date\nstandards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended.", - Default: "true", - }, - { @@ -65158,17 +72155,17 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - }, - { - Name: "\"unusedparams\"", -- Doc: "check for unused parameters of functions\n\nThe unusedparams analyzer checks functions to see if there are\nany parameters that are not being used.\n\nTo reduce false positives it ignores:\n- methods\n- parameters that do not have a name or are underscored\n- functions in test files\n- functions with empty bodies or those with just a return stmt", +- Doc: "check for unused parameters of functions\n\nThe unusedparams analyzer checks functions to see if there are\nany parameters that are not being used.\n\nTo reduce false positives it ignores:\n- methods\n- parameters that do not have a name or have the name '_' (the blank identifier)\n- functions in test files\n- functions with empty bodies or those with just a return stmt", - Default: "false", - }, - { - Name: "\"unusedresult\"", -- Doc: "check for unused results of calls to some functions\n\nSome functions like fmt.Errorf return a result and have no side effects,\nso it is always a mistake to discard the result. This analyzer reports\ncalls to certain functions in which the result of the call is ignored.\n\nThe set of functions may be controlled using flags.", +- Doc: "check for unused results of calls to some functions\n\nSome functions like fmt.Errorf return a result and have no side\neffects, so it is always a mistake to discard the result. Other\nfunctions may return an error that must not be ignored, or a cleanup\noperation that must be called. This analyzer reports calls to\nfunctions like these when the result of the call is ignored.\n\nThe set of functions may be controlled using flags.", - Default: "true", - }, - { - Name: "\"unusedwrite\"", -- Doc: "checks for unused writes\n\nThe analyzer reports instances of writes to struct fields and\narrays that are never read. Specifically, when a struct object\nor an array is copied, its elements are copied implicitly by\nthe compiler, and any element write to this copy does nothing\nwith the original object.\n\nFor example:\n\n\ttype T struct { x int }\n\tfunc f(input []T) {\n\t\tfor i, v := range input { // v is a copy\n\t\t\tv.x = i // unused write to field x\n\t\t}\n\t}\n\nAnother example is about non-pointer receiver:\n\n\ttype T struct { x int }\n\tfunc (t T) f() { // t is a copy\n\t\tt.x = i // unused write to field x\n\t}\n", +- Doc: "checks for unused writes\n\nThe analyzer reports instances of writes to struct fields and\narrays that are never read. Specifically, when a struct object\nor an array is copied, its elements are copied implicitly by\nthe compiler, and any element write to this copy does nothing\nwith the original object.\n\nFor example:\n\n\ttype T struct { x int }\n\n\tfunc f(input []T) {\n\t\tfor i, v := range input { // v is a copy\n\t\t\tv.x = i // unused write to field x\n\t\t}\n\t}\n\nAnother example is about non-pointer receiver:\n\n\ttype T struct { x int }\n\n\tfunc (t T) f() { // t is a copy\n\t\tt.x = i // unused write to field x\n\t}", - Default: "false", - }, - { @@ -65207,6 +72204,11 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Default: "true", - }, - { +- Name: "\"infertypeargs\"", +- Doc: "check for unnecessary type arguments in call expressions\n\nExplicit type arguments may be omitted from call expressions if they can be\ninferred from function arguments, or from other type arguments:\n\n\tfunc f[T any](T) {}\n\t\n\tfunc _() {\n\t\tf[string](\"foo\") // string could be inferred\n\t}\n", +- Default: "true", +- }, +- { - Name: "\"stubmethods\"", - Doc: "stub methods analyzer\n\nThis analyzer generates method stubs for concrete types\nin order to implement a target interface", - Default: "true", @@ -65279,11 +72281,18 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Name: "diagnosticsDelay", - Type: "time.Duration", - Doc: "diagnosticsDelay controls the amount of time that gopls waits\nafter the most recent file modification before computing deep diagnostics.\nSimple diagnostics (parsing and type-checking) are always run immediately\non recently modified packages.\n\nThis option must be set to a valid duration string, for example `\"250ms\"`.\n", -- Default: "\"250ms\"", +- Default: "\"1s\"", - Status: "advanced", - Hierarchy: "ui.diagnostic", - }, - { +- Name: "analysisProgressReporting", +- Type: "bool", +- Doc: "analysisProgressReporting controls whether gopls sends progress\nnotifications when construction of its index of analysis facts is taking a\nlong time. Cancelling these notifications will cancel the indexing task,\nthough it will restart after the next change in the workspace.\n\nWhen a package is opened for the first time and heavyweight analyses such as\nstaticcheck are enabled, it can take a while to construct the index of\nanalysis facts for all its dependencies. The index is cached in the\nfilesystem, so subsequent analysis should be faster.\n", +- Default: "true", +- Hierarchy: "ui.diagnostic", +- }, +- { - Name: "hints", - Type: "map[string]bool", - Doc: "hints specify inlay hints that users want to see. A full list of hints\nthat gopls uses can be found in\n[inlayHints.md](https://github.com/golang/tools/blob/master/gopls/doc/inlayHints.md).\n", @@ -65501,7 +72510,7 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Command: "gopls.mem_stats", - Title: "fetch memory statistics", - Doc: "Call runtime.GC multiple times and return memory statistics as reported by\nruntime.MemStats.\n\nThis command is used for benchmarking, and may change in the future.", -- ResultDoc: "{\n\t\"HeapAlloc\": uint64,\n\t\"HeapInUse\": uint64,\n}", +- ResultDoc: "{\n\t\"HeapAlloc\": uint64,\n\t\"HeapInUse\": uint64,\n\t\"TotalAlloc\": uint64,\n}", - }, - { - Command: "gopls.regenerate_cgo", @@ -65513,7 +72522,7 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Command: "gopls.remove_dependency", - Title: "Remove a dependency", - Doc: "Removes a dependency from the go.mod file of a module.", -- ArgDoc: "{\n\t// The go.mod file URI.\n\t\"URI\": string,\n\t// The module path to remove.\n\t\"ModulePath\": string,\n\t\"OnlyDiagnostic\": bool,\n}", +- ArgDoc: "{\n\t// The go.mod file URI.\n\t\"URI\": string,\n\t// The module path to remove.\n\t\"ModulePath\": string,\n\t// If the module is tidied apart from the one unused diagnostic, we can\n\t// run `go get module@none`, and then run `go mod tidy`. Otherwise, we\n\t// must make textual edits.\n\t\"OnlyDiagnostic\": bool,\n}", - }, - { - Command: "gopls.reset_go_mod_diagnostics", @@ -65522,6 +72531,12 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - ArgDoc: "{\n\t\"URIArg\": {\n\t\t\"URI\": string,\n\t},\n\t// Optional: source of the diagnostics to reset.\n\t// If not set, all resettable go.mod diagnostics will be cleared.\n\t\"DiagnosticSource\": string,\n}", - }, - { +- Command: "gopls.run_go_work_command", +- Title: "run `go work [args...]`, and apply the resulting go.work", +- Doc: "edits to the current go.work file.", +- ArgDoc: "{\n\t\"ViewID\": string,\n\t\"InitFirst\": bool,\n\t\"Args\": []string,\n}", +- }, +- { - Command: "gopls.run_govulncheck", - Title: "Run govulncheck.", - Doc: "Run vulnerability check (`govulncheck`).", @@ -65538,8 +72553,22 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Command: "gopls.start_debugging", - Title: "Start the gopls debug server", - Doc: "Start the gopls debug server if it isn't running, and return the debug\naddress.", -- ArgDoc: "{\n\t// Optional: the address (including port) for the debug server to listen on.\n\t// If not provided, the debug server will bind to \"localhost:0\", and the\n\t// full debug URL will be contained in the result.\n\t// \n\t// If there is more than one gopls instance along the serving path (i.e. you\n\t// are using a daemon), each gopls instance will attempt to start debugging.\n\t// If Addr specifies a port, only the daemon will be able to bind to that\n\t// port, and each intermediate gopls instance will fail to start debugging.\n\t// For this reason it is recommended not to specify a port (or equivalently,\n\t// to specify \":0\").\n\t// \n\t// If the server was already debugging this field has no effect, and the\n\t// result will contain the previously configured debug URL(s).\n\t\"Addr\": string,\n}", -- ResultDoc: "{\n\t// The URLs to use to access the debug servers, for all gopls instances in\n\t// the serving path. For the common case of a single gopls instance (i.e. no\n\t// daemon), this will be exactly one address.\n\t// \n\t// In the case of one or more gopls instances forwarding the LSP to a daemon,\n\t// URLs will contain debug addresses for each server in the serving path, in\n\t// serving order. The daemon debug address will be the last entry in the\n\t// slice. If any intermediate gopls instance fails to start debugging, no\n\t// error will be returned but the debug URL for that server in the URLs slice\n\t// will be empty.\n\t\"URLs\": []string,\n}", +- ArgDoc: "{\n\t// Optional: the address (including port) for the debug server to listen on.\n\t// If not provided, the debug server will bind to \"localhost:0\", and the\n\t// full debug URL will be contained in the result.\n\t//\n\t// If there is more than one gopls instance along the serving path (i.e. you\n\t// are using a daemon), each gopls instance will attempt to start debugging.\n\t// If Addr specifies a port, only the daemon will be able to bind to that\n\t// port, and each intermediate gopls instance will fail to start debugging.\n\t// For this reason it is recommended not to specify a port (or equivalently,\n\t// to specify \":0\").\n\t//\n\t// If the server was already debugging this field has no effect, and the\n\t// result will contain the previously configured debug URL(s).\n\t\"Addr\": string,\n}", +- ResultDoc: "{\n\t// The URLs to use to access the debug servers, for all gopls instances in\n\t// the serving path. For the common case of a single gopls instance (i.e. no\n\t// daemon), this will be exactly one address.\n\t//\n\t// In the case of one or more gopls instances forwarding the LSP to a daemon,\n\t// URLs will contain debug addresses for each server in the serving path, in\n\t// serving order. The daemon debug address will be the last entry in the\n\t// slice. If any intermediate gopls instance fails to start debugging, no\n\t// error will be returned but the debug URL for that server in the URLs slice\n\t// will be empty.\n\t\"URLs\": []string,\n}", +- }, +- { +- Command: "gopls.start_profile", +- Title: "start capturing a profile of gopls' execution.", +- Doc: "Start a new pprof profile. Before using the resulting file, profiling must\nbe stopped with a corresponding call to StopProfile.\n\nThis command is intended for internal use only, by the gopls benchmark\nrunner.", +- ArgDoc: "struct{}", +- ResultDoc: "struct{}", +- }, +- { +- Command: "gopls.stop_profile", +- Title: "stop an ongoing profile.", +- Doc: "This command is intended for internal use only, by the gopls benchmark\nrunner.", +- ArgDoc: "struct{}", +- ResultDoc: "{\n\t// File is the profile file name.\n\t\"File\": string,\n}", - }, - { - Command: "gopls.test", @@ -65577,6 +72606,12 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Doc: "Runs `go mod vendor` for a module.", - ArgDoc: "{\n\t// The file URI.\n\t\"URI\": string,\n}", - }, +- { +- Command: "gopls.workspace_stats", +- Title: "fetch workspace statistics", +- Doc: "Query statistics about workspace builds, modules, packages, and files.\n\nThis command is intended for internal use only, by the gopls stats\ncommand.", +- ResultDoc: "{\n\t\"Files\": {\n\t\t\"Total\": int,\n\t\t\"Largest\": int,\n\t\t\"Errs\": int,\n\t},\n\t\"Views\": []{\n\t\t\"GoCommandVersion\": string,\n\t\t\"AllPackages\": {\n\t\t\t\"Packages\": int,\n\t\t\t\"LargestPackage\": int,\n\t\t\t\"CompiledGoFiles\": int,\n\t\t\t\"Modules\": int,\n\t\t},\n\t\t\"WorkspacePackages\": {\n\t\t\t\"Packages\": int,\n\t\t\t\"LargestPackage\": int,\n\t\t\t\"CompiledGoFiles\": int,\n\t\t\t\"Modules\": int,\n\t\t},\n\t\t\"Diagnostics\": int,\n\t},\n}", +- }, - }, - Lenses: []*LensJSON{ - { @@ -65624,118 +72659,145 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - { - Name: "asmdecl", - Doc: "report mismatches between assembly files and Go declarations", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/asmdecl", - Default: true, - }, - { - Name: "assign", - Doc: "check for useless assignments\n\nThis checker reports assignments of the form x = x or a[i] = a[i].\nThese are almost always useless, and even when they aren't they are\nusually a mistake.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/assign", - Default: true, - }, - { - Name: "atomic", - Doc: "check for common mistakes using the sync/atomic package\n\nThe atomic checker looks for assignment statements of the form:\n\n\tx = atomic.AddUint64(&x, 1)\n\nwhich are not atomic.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/atomic", - Default: true, - }, - { - Name: "atomicalign", - Doc: "check for non-64-bits-aligned arguments to sync/atomic functions", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/atomicalign", - Default: true, - }, - { - Name: "bools", - Doc: "check for common mistakes involving boolean operators", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/bools", - Default: true, - }, - { - Name: "buildtag", - Doc: "check //go:build and // +build directives", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/buildtag", - Default: true, - }, - { - Name: "cgocall", - Doc: "detect some violations of the cgo pointer passing rules\n\nCheck for invalid cgo pointer passing.\nThis looks for code that uses cgo to call C code passing values\nwhose types are almost always invalid according to the cgo pointer\nsharing rules.\nSpecifically, it warns about attempts to pass a Go chan, map, func,\nor slice to C, either directly, or via a pointer, array, or struct.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/cgocall", - Default: true, - }, - { - Name: "composites", - Doc: "check for unkeyed composite literals\n\nThis analyzer reports a diagnostic for composite literals of struct\ntypes imported from another package that do not use the field-keyed\nsyntax. Such literals are fragile because the addition of a new field\n(even if unexported) to the struct will cause compilation to fail.\n\nAs an example,\n\n\terr = &net.DNSConfigError{err}\n\nshould be replaced by:\n\n\terr = &net.DNSConfigError{Err: err}\n", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/composite", - Default: true, - }, - { - Name: "copylocks", - Doc: "check for locks erroneously passed by value\n\nInadvertently copying a value containing a lock, such as sync.Mutex or\nsync.WaitGroup, may cause both copies to malfunction. Generally such\nvalues should be referred to through a pointer.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/copylocks", - Default: true, - }, - { - Name: "deepequalerrors", - Doc: "check for calls of reflect.DeepEqual on error values\n\nThe deepequalerrors checker looks for calls of the form:\n\n reflect.DeepEqual(err1, err2)\n\nwhere err1 and err2 are errors. Using reflect.DeepEqual to compare\nerrors is discouraged.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/deepequalerrors", +- Default: true, +- }, +- { +- Name: "defer", +- Doc: "report common mistakes in defer statements\n\nThe defer analyzer reports a diagnostic when a defer statement would\nresult in a non-deferred call to time.Since, as experience has shown\nthat this is nearly always a mistake.\n\nFor example:\n\n\tstart := time.Now()\n\t...\n\tdefer recordLatency(time.Since(start)) // error: call to time.Since is not deferred\n\nThe correct code is:\n\n\tdefer func() { recordLatency(time.Since(start)) }()", +- Default: true, +- }, +- { +- Name: "deprecated", +- Doc: "check for use of deprecated identifiers\n\nThe deprecated analyzer looks for deprecated symbols and package imports.\n\nSee https://go.dev/wiki/Deprecated to learn about Go's convention\nfor documenting and signaling deprecated identifiers.", - Default: true, - }, - { - Name: "directive", - Doc: "check Go toolchain directives such as //go:debug\n\nThis analyzer checks for problems with known Go toolchain directives\nin all Go source files in a package directory, even those excluded by\n//go:build constraints, and all non-Go source files too.\n\nFor //go:debug (see https://go.dev/doc/godebug), the analyzer checks\nthat the directives are placed only in Go source files, only above the\npackage comment, and only in package main or *_test.go files.\n\nSupport for other known directives may be added in the future.\n\nThis analyzer does not check //go:build, which is handled by the\nbuildtag analyzer.\n", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/directive", - Default: true, - }, - { - Name: "embed", -- Doc: "check for //go:embed directive import\n\nThis analyzer checks that the embed package is imported when source code contains //go:embed comment directives.\nThe embed package must be imported for //go:embed directives to function.import _ \"embed\".", +- Doc: "check //go:embed directive usage\n\nThis analyzer checks that the embed package is imported if //go:embed\ndirectives are present, providing a suggested fix to add the import if\nit is missing.\n\nThis analyzer also checks that //go:embed directives precede the\ndeclaration of a single variable.", - Default: true, - }, - { - Name: "errorsas", - Doc: "report passing non-pointer or non-error values to errors.As\n\nThe errorsas analysis reports calls to errors.As where the type\nof the second argument is not a pointer to a type implementing error.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/errorsas", - Default: true, - }, - { - Name: "fieldalignment", - Doc: "find structs that would use less memory if their fields were sorted\n\nThis analyzer find structs that can be rearranged to use less memory, and provides\na suggested edit with the most compact order.\n\nNote that there are two different diagnostics reported. One checks struct size,\nand the other reports \"pointer bytes\" used. Pointer bytes is how many bytes of the\nobject that the garbage collector has to potentially scan for pointers, for example:\n\n\tstruct { uint32; string }\n\nhave 16 pointer bytes because the garbage collector has to scan up through the string's\ninner pointer.\n\n\tstruct { string; *uint32 }\n\nhas 24 pointer bytes because it has to scan further through the *uint32.\n\n\tstruct { string; uint32 }\n\nhas 8 because it can stop immediately after the string pointer.\n\nBe aware that the most compact order is not always the most efficient.\nIn rare cases it may cause two variables each updated by its own goroutine\nto occupy the same CPU cache line, inducing a form of memory contention\nknown as \"false sharing\" that slows down both goroutines.\n", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/fieldalignment", - }, - { - Name: "httpresponse", - Doc: "check for mistakes using HTTP responses\n\nA common mistake when using the net/http package is to defer a function\ncall to close the http.Response Body before checking the error that\ndetermines whether the response is valid:\n\n\tresp, err := http.Head(url)\n\tdefer resp.Body.Close()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\t// (defer statement belongs here)\n\nThis checker helps uncover latent nil dereference bugs by reporting a\ndiagnostic for such mistakes.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/httpresponse", - Default: true, - }, - { - Name: "ifaceassert", -- Doc: "detect impossible interface-to-interface type assertions\n\nThis checker flags type assertions v.(T) and corresponding type-switch cases\nin which the static type V of v is an interface that cannot possibly implement\nthe target interface T. This occurs when V and T contain methods with the same\nname but different signatures. Example:\n\n\tvar v interface {\n\t\tRead()\n\t}\n\t_ = v.(io.Reader)\n\nThe Read method in v has a different signature than the Read method in\nio.Reader, so this assertion cannot succeed.\n", -- Default: true, -- }, -- { -- Name: "infertypeargs", -- Doc: "check for unnecessary type arguments in call expressions\n\nExplicit type arguments may be omitted from call expressions if they can be\ninferred from function arguments, or from other type arguments:\n\n\tfunc f[T any](T) {}\n\t\n\tfunc _() {\n\t\tf[string](\"foo\") // string could be inferred\n\t}\n", +- Doc: "detect impossible interface-to-interface type assertions\n\nThis checker flags type assertions v.(T) and corresponding type-switch cases\nin which the static type V of v is an interface that cannot possibly implement\nthe target interface T. This occurs when V and T contain methods with the same\nname but different signatures. Example:\n\n\tvar v interface {\n\t\tRead()\n\t}\n\t_ = v.(io.Reader)\n\nThe Read method in v has a different signature than the Read method in\nio.Reader, so this assertion cannot succeed.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/ifaceassert", - Default: true, - }, - { - Name: "loopclosure", -- Doc: "check references to loop variables from within nested functions\n\nThis analyzer reports places where a function literal references the\niteration variable of an enclosing loop, and the loop calls the function\nin such a way (e.g. with go or defer) that it may outlive the loop\niteration and possibly observe the wrong value of the variable.\n\nIn this example, all the deferred functions run after the loop has\ncompleted, so all observe the final value of v.\n\n for _, v := range list {\n defer func() {\n use(v) // incorrect\n }()\n }\n\nOne fix is to create a new variable for each iteration of the loop:\n\n for _, v := range list {\n v := v // new var per iteration\n defer func() {\n use(v) // ok\n }()\n }\n\nThe next example uses a go statement and has a similar problem.\nIn addition, it has a data race because the loop updates v\nconcurrent with the goroutines accessing it.\n\n for _, v := range elem {\n go func() {\n use(v) // incorrect, and a data race\n }()\n }\n\nA fix is the same as before. The checker also reports problems\nin goroutines started by golang.org/x/sync/errgroup.Group.\nA hard-to-spot variant of this form is common in parallel tests:\n\n func Test(t *testing.T) {\n for _, test := range tests {\n t.Run(test.name, func(t *testing.T) {\n t.Parallel()\n use(test) // incorrect, and a data race\n })\n }\n }\n\nThe t.Parallel() call causes the rest of the function to execute\nconcurrent with the loop.\n\nThe analyzer reports references only in the last statement,\nas it is not deep enough to understand the effects of subsequent\nstatements that might render the reference benign.\n(\"Last statement\" is defined recursively in compound\nstatements such as if, switch, and select.)\n\nSee: https://golang.org/doc/go_faq.html#closures_and_goroutines", +- Doc: "check references to loop variables from within nested functions\n\nThis analyzer reports places where a function literal references the\niteration variable of an enclosing loop, and the loop calls the function\nin such a way (e.g. with go or defer) that it may outlive the loop\niteration and possibly observe the wrong value of the variable.\n\nIn this example, all the deferred functions run after the loop has\ncompleted, so all observe the final value of v.\n\n\tfor _, v := range list {\n\t defer func() {\n\t use(v) // incorrect\n\t }()\n\t}\n\nOne fix is to create a new variable for each iteration of the loop:\n\n\tfor _, v := range list {\n\t v := v // new var per iteration\n\t defer func() {\n\t use(v) // ok\n\t }()\n\t}\n\nThe next example uses a go statement and has a similar problem.\nIn addition, it has a data race because the loop updates v\nconcurrent with the goroutines accessing it.\n\n\tfor _, v := range elem {\n\t go func() {\n\t use(v) // incorrect, and a data race\n\t }()\n\t}\n\nA fix is the same as before. The checker also reports problems\nin goroutines started by golang.org/x/sync/errgroup.Group.\nA hard-to-spot variant of this form is common in parallel tests:\n\n\tfunc Test(t *testing.T) {\n\t for _, test := range tests {\n\t t.Run(test.name, func(t *testing.T) {\n\t t.Parallel()\n\t use(test) // incorrect, and a data race\n\t })\n\t }\n\t}\n\nThe t.Parallel() call causes the rest of the function to execute\nconcurrent with the loop.\n\nThe analyzer reports references only in the last statement,\nas it is not deep enough to understand the effects of subsequent\nstatements that might render the reference benign.\n(\"Last statement\" is defined recursively in compound\nstatements such as if, switch, and select.)\n\nSee: https://golang.org/doc/go_faq.html#closures_and_goroutines", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/loopclosure", - Default: true, - }, - { - Name: "lostcancel", - Doc: "check cancel func returned by context.WithCancel is called\n\nThe cancellation function returned by context.WithCancel, WithTimeout,\nand WithDeadline must be called or the new context will remain live\nuntil its parent context is cancelled.\n(The background context is never cancelled.)", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/lostcancel", - Default: true, - }, - { - Name: "nilfunc", - Doc: "check for useless comparisons between functions and nil\n\nA useless comparison is one like f == nil as opposed to f() == nil.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/nilfunc", - Default: true, - }, - { - Name: "nilness", -- Doc: "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}\n", +- Doc: "check for redundant or impossible nil comparisons\n\nThe nilness checker inspects the control-flow graph of each function in\na package and reports nil pointer dereferences, degenerate nil\npointers, and panics with nil values. A degenerate comparison is of the form\nx==nil or x!=nil where x is statically known to be nil or non-nil. These are\noften a mistake, especially in control flow related to errors. Panics with nil\nvalues are checked because they are not detectable by\n\n\tif r := recover(); r != nil {\n\nThis check reports conditions such as:\n\n\tif f == nil { // impossible condition (f is a function)\n\t}\n\nand:\n\n\tp := &v\n\t...\n\tif p != nil { // tautological condition\n\t}\n\nand:\n\n\tif p == nil {\n\t\tprint(*p) // nil dereference\n\t}\n\nand:\n\n\tif p == nil {\n\t\tpanic(p)\n\t}", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/nilness", - }, - { - Name: "printf", -- Doc: "check consistency of Printf format strings and arguments\n\nThe check applies to known functions (for example, those in package fmt)\nas well as any detected wrappers of known functions.\n\nA function that wants to avail itself of printf checking but is not\nfound by this analyzer's heuristics (for example, due to use of\ndynamic calls) can insert a bogus call:\n\n\tif false {\n\t\t_ = fmt.Sprintf(format, args...) // enable printf checking\n\t}\n\nThe -funcs flag specifies a comma-separated list of names of additional\nknown formatting functions or methods. If the name contains a period,\nit must denote a specific function using one of the following forms:\n\n\tdir/pkg.Function\n\tdir/pkg.Type.Method\n\t(*dir/pkg.Type).Method\n\nOtherwise the name is interpreted as a case-insensitive unqualified\nidentifier such as \"errorf\". Either way, if a listed name ends in f, the\nfunction is assumed to be Printf-like, taking a format string before the\nargument list. Otherwise it is assumed to be Print-like, taking a list\nof arguments with no format string.\n", +- Doc: "check consistency of Printf format strings and arguments\n\nThe check applies to calls of the formatting functions such as\n[fmt.Printf] and [fmt.Sprintf], as well as any detected wrappers of\nthose functions.\n\nIn this example, the %d format operator requires an integer operand:\n\n\tfmt.Printf(\"%d\", \"hello\") // fmt.Printf format %d has arg \"hello\" of wrong type string\n\nSee the documentation of the fmt package for the complete set of\nformat operators and their operand types.\n\nTo enable printf checking on a function that is not found by this\nanalyzer's heuristics (for example, because control is obscured by\ndynamic method calls), insert a bogus call:\n\n\tfunc MyPrintf(format string, args ...any) {\n\t\tif false {\n\t\t\t_ = fmt.Sprintf(format, args...) // enable printf checker\n\t\t}\n\t\t...\n\t}\n\nThe -funcs flag specifies a comma-separated list of names of additional\nknown formatting functions or methods. If the name contains a period,\nit must denote a specific function using one of the following forms:\n\n\tdir/pkg.Function\n\tdir/pkg.Type.Method\n\t(*dir/pkg.Type).Method\n\nOtherwise the name is interpreted as a case-insensitive unqualified\nidentifier such as \"errorf\". Either way, if a listed name ends in f, the\nfunction is assumed to be Printf-like, taking a format string before the\nargument list. Otherwise it is assumed to be Print-like, taking a list\nof arguments with no format string.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/printf", - Default: true, - }, - { - Name: "shadow", -- Doc: "check for possible unintended shadowing of variables\n\nThis analyzer check for shadowed variables.\nA shadowed variable is a variable declared in an inner scope\nwith the same name and type as a variable in an outer scope,\nand where the outer variable is mentioned after the inner one\nis declared.\n\n(This definition can be refined; the module generates too many\nfalse positives and is not yet enabled by default.)\n\nFor example:\n\n\tfunc BadRead(f *os.File, buf []byte) error {\n\t\tvar err error\n\t\tfor {\n\t\t\tn, err := f.Read(buf) // shadows the function variable 'err'\n\t\t\tif err != nil {\n\t\t\t\tbreak // causes return of wrong value\n\t\t\t}\n\t\t\tfoo(buf)\n\t\t}\n\t\treturn err\n\t}\n", +- Doc: "check for possible unintended shadowing of variables\n\nThis analyzer check for shadowed variables.\nA shadowed variable is a variable declared in an inner scope\nwith the same name and type as a variable in an outer scope,\nand where the outer variable is mentioned after the inner one\nis declared.\n\n(This definition can be refined; the module generates too many\nfalse positives and is not yet enabled by default.)\n\nFor example:\n\n\tfunc BadRead(f *os.File, buf []byte) error {\n\t\tvar err error\n\t\tfor {\n\t\t\tn, err := f.Read(buf) // shadows the function variable 'err'\n\t\t\tif err != nil {\n\t\t\t\tbreak // causes return of wrong value\n\t\t\t}\n\t\t\tfoo(buf)\n\t\t}\n\t\treturn err\n\t}", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/shadow", - }, - { - Name: "shift", - Doc: "check for shifts that equal or exceed the width of the integer", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/shift", - Default: true, - }, - { @@ -65754,67 +72816,85 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Default: true, - }, - { +- Name: "slog", +- Doc: "check for invalid structured logging calls\n\nThe slog checker looks for calls to functions from the log/slog\npackage that take alternating key-value pairs. It reports calls\nwhere an argument in a key position is neither a string nor a\nslog.Attr, and where a final key is missing its value.\nFor example,it would report\n\n\tslog.Warn(\"message\", 11, \"k\") // slog.Warn arg \"11\" should be a string or a slog.Attr\n\nand\n\n\tslog.Info(\"message\", \"k1\", v1, \"k2\") // call to slog.Info missing a final value", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/slog", +- Default: true, +- }, +- { - Name: "sortslice", - Doc: "check the argument type of sort.Slice\n\nsort.Slice requires an argument of a slice type. Check that\nthe interface{} value passed to sort.Slice is actually a slice.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/sortslice", - Default: true, - }, - { - Name: "stdmethods", -- Doc: "check signature of methods of well-known interfaces\n\nSometimes a type may be intended to satisfy an interface but may fail to\ndo so because of a mistake in its method signature.\nFor example, the result of this WriteTo method should be (int64, error),\nnot error, to satisfy io.WriterTo:\n\n\ttype myWriterTo struct{...}\n func (myWriterTo) WriteTo(w io.Writer) error { ... }\n\nThis check ensures that each method whose name matches one of several\nwell-known interface methods from the standard library has the correct\nsignature for that interface.\n\nChecked method names include:\n\tFormat GobEncode GobDecode MarshalJSON MarshalXML\n\tPeek ReadByte ReadFrom ReadRune Scan Seek\n\tUnmarshalJSON UnreadByte UnreadRune WriteByte\n\tWriteTo\n", +- Doc: "check signature of methods of well-known interfaces\n\nSometimes a type may be intended to satisfy an interface but may fail to\ndo so because of a mistake in its method signature.\nFor example, the result of this WriteTo method should be (int64, error),\nnot error, to satisfy io.WriterTo:\n\n\ttype myWriterTo struct{...}\n\tfunc (myWriterTo) WriteTo(w io.Writer) error { ... }\n\nThis check ensures that each method whose name matches one of several\nwell-known interface methods from the standard library has the correct\nsignature for that interface.\n\nChecked method names include:\n\n\tFormat GobEncode GobDecode MarshalJSON MarshalXML\n\tPeek ReadByte ReadFrom ReadRune Scan Seek\n\tUnmarshalJSON UnreadByte UnreadRune WriteByte\n\tWriteTo", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/stdmethods", - Default: true, - }, - { - Name: "stringintconv", -- Doc: "check for string(int) conversions\n\nThis checker flags conversions of the form string(x) where x is an integer\n(but not byte or rune) type. Such conversions are discouraged because they\nreturn the UTF-8 representation of the Unicode code point x, and not a decimal\nstring representation of x as one might expect. Furthermore, if x denotes an\ninvalid code point, the conversion cannot be statically rejected.\n\nFor conversions that intend on using the code point, consider replacing them\nwith string(rune(x)). Otherwise, strconv.Itoa and its equivalents return the\nstring representation of the value in the desired base.\n", +- Doc: "check for string(int) conversions\n\nThis checker flags conversions of the form string(x) where x is an integer\n(but not byte or rune) type. Such conversions are discouraged because they\nreturn the UTF-8 representation of the Unicode code point x, and not a decimal\nstring representation of x as one might expect. Furthermore, if x denotes an\ninvalid code point, the conversion cannot be statically rejected.\n\nFor conversions that intend on using the code point, consider replacing them\nwith string(rune(x)). Otherwise, strconv.Itoa and its equivalents return the\nstring representation of the value in the desired base.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/stringintconv", - Default: true, - }, - { - Name: "structtag", - Doc: "check that struct field tags conform to reflect.StructTag.Get\n\nAlso report certain struct tags (json, xml) used with unexported fields.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/structtag", - Default: true, - }, - { - Name: "testinggoroutine", -- Doc: "report calls to (*testing.T).Fatal from goroutines started by a test.\n\nFunctions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and\nSkip{,f,Now} methods of *testing.T, must be called from the test goroutine itself.\nThis checker detects calls to these functions that occur within a goroutine\nstarted by the test. For example:\n\nfunc TestFoo(t *testing.T) {\n go func() {\n t.Fatal(\"oops\") // error: (*T).Fatal called from non-test goroutine\n }()\n}\n", +- Doc: "report calls to (*testing.T).Fatal from goroutines started by a test.\n\nFunctions that abruptly terminate a test, such as the Fatal, Fatalf, FailNow, and\nSkip{,f,Now} methods of *testing.T, must be called from the test goroutine itself.\nThis checker detects calls to these functions that occur within a goroutine\nstarted by the test. For example:\n\n\tfunc TestFoo(t *testing.T) {\n\t go func() {\n\t t.Fatal(\"oops\") // error: (*T).Fatal called from non-test goroutine\n\t }()\n\t}", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/testinggoroutine", - Default: true, - }, - { - Name: "tests", -- Doc: "check for common mistaken usages of tests and examples\n\nThe tests checker walks Test, Benchmark and Example functions checking\nmalformed names, wrong signatures and examples documenting non-existent\nidentifiers.\n\nPlease see the documentation for package testing in golang.org/pkg/testing\nfor the conventions that are enforced for Tests, Benchmarks, and Examples.", +- Doc: "check for common mistaken usages of tests and examples\n\nThe tests checker walks Test, Benchmark, Fuzzing and Example functions checking\nmalformed names, wrong signatures and examples documenting non-existent\nidentifiers.\n\nPlease see the documentation for package testing in golang.org/pkg/testing\nfor the conventions that are enforced for Tests, Benchmarks, and Examples.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/tests", - Default: true, - }, - { - Name: "timeformat", -- Doc: "check for calls of (time.Time).Format or time.Parse with 2006-02-01\n\nThe timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm)\nformat. Internationally, \"yyyy-dd-mm\" does not occur in common calendar date\nstandards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended.\n", +- Doc: "check for calls of (time.Time).Format or time.Parse with 2006-02-01\n\nThe timeformat checker looks for time formats with the 2006-02-01 (yyyy-dd-mm)\nformat. Internationally, \"yyyy-dd-mm\" does not occur in common calendar date\nstandards, and so it is more likely that 2006-01-02 (yyyy-mm-dd) was intended.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/timeformat", - Default: true, - }, - { - Name: "unmarshal", - Doc: "report passing non-pointer or non-interface values to unmarshal\n\nThe unmarshal analysis reports calls to functions such as json.Unmarshal\nin which the argument type is not a pointer or an interface.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/unmarshal", - Default: true, - }, - { - Name: "unreachable", - Doc: "check for unreachable code\n\nThe unreachable analyzer finds statements that execution can never reach\nbecause they are preceded by an return statement, a call to panic, an\ninfinite loop, or similar constructs.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/unreachable", - Default: true, - }, - { - Name: "unsafeptr", - Doc: "check for invalid conversions of uintptr to unsafe.Pointer\n\nThe unsafeptr analyzer reports likely incorrect uses of unsafe.Pointer\nto convert integers to pointers. A conversion from uintptr to\nunsafe.Pointer is invalid if it implies that there is a uintptr-typed\nword in memory that holds a pointer value, because that word will be\ninvisible to stack copying and to the garbage collector.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/unsafeptr", - Default: true, - }, - { - Name: "unusedparams", -- Doc: "check for unused parameters of functions\n\nThe unusedparams analyzer checks functions to see if there are\nany parameters that are not being used.\n\nTo reduce false positives it ignores:\n- methods\n- parameters that do not have a name or are underscored\n- functions in test files\n- functions with empty bodies or those with just a return stmt", +- Doc: "check for unused parameters of functions\n\nThe unusedparams analyzer checks functions to see if there are\nany parameters that are not being used.\n\nTo reduce false positives it ignores:\n- methods\n- parameters that do not have a name or have the name '_' (the blank identifier)\n- functions in test files\n- functions with empty bodies or those with just a return stmt", - }, - { - Name: "unusedresult", -- Doc: "check for unused results of calls to some functions\n\nSome functions like fmt.Errorf return a result and have no side effects,\nso it is always a mistake to discard the result. This analyzer reports\ncalls to certain functions in which the result of the call is ignored.\n\nThe set of functions may be controlled using flags.", +- Doc: "check for unused results of calls to some functions\n\nSome functions like fmt.Errorf return a result and have no side\neffects, so it is always a mistake to discard the result. Other\nfunctions may return an error that must not be ignored, or a cleanup\noperation that must be called. This analyzer reports calls to\nfunctions like these when the result of the call is ignored.\n\nThe set of functions may be controlled using flags.", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/unusedresult", - Default: true, - }, - { - Name: "unusedwrite", -- Doc: "checks for unused writes\n\nThe analyzer reports instances of writes to struct fields and\narrays that are never read. Specifically, when a struct object\nor an array is copied, its elements are copied implicitly by\nthe compiler, and any element write to this copy does nothing\nwith the original object.\n\nFor example:\n\n\ttype T struct { x int }\n\tfunc f(input []T) {\n\t\tfor i, v := range input { // v is a copy\n\t\t\tv.x = i // unused write to field x\n\t\t}\n\t}\n\nAnother example is about non-pointer receiver:\n\n\ttype T struct { x int }\n\tfunc (t T) f() { // t is a copy\n\t\tt.x = i // unused write to field x\n\t}\n", +- Doc: "checks for unused writes\n\nThe analyzer reports instances of writes to struct fields and\narrays that are never read. Specifically, when a struct object\nor an array is copied, its elements are copied implicitly by\nthe compiler, and any element write to this copy does nothing\nwith the original object.\n\nFor example:\n\n\ttype T struct { x int }\n\n\tfunc f(input []T) {\n\t\tfor i, v := range input { // v is a copy\n\t\t\tv.x = i // unused write to field x\n\t\t}\n\t}\n\nAnother example is about non-pointer receiver:\n\n\ttype T struct { x int }\n\n\tfunc (t T) f() { // t is a copy\n\t\tt.x = i // unused write to field x\n\t}", +- URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/unusedwrite", - }, - { - Name: "useany", @@ -65850,6 +72930,11 @@ diff -urN a/gopls/internal/lsp/source/api_json.go b/gopls/internal/lsp/source/ap - Default: true, - }, - { +- Name: "infertypeargs", +- Doc: "check for unnecessary type arguments in call expressions\n\nExplicit type arguments may be omitted from call expressions if they can be\ninferred from function arguments, or from other type arguments:\n\n\tfunc f[T any](T) {}\n\t\n\tfunc _() {\n\t\tf[string](\"foo\") // string could be inferred\n\t}\n", +- Default: true, +- }, +- { - Name: "stubmethods", - Doc: "stub methods analyzer\n\nThis analyzer generates method stubs for concrete types\nin order to implement a target interface", - Default: true, @@ -65906,10 +72991,10 @@ diff -urN a/gopls/internal/lsp/source/call_hierarchy.go b/gopls/internal/lsp/sou - "path/filepath" - - "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/event/tag" -) @@ -65919,7 +73004,7 @@ diff -urN a/gopls/internal/lsp/source/call_hierarchy.go b/gopls/internal/lsp/sou - ctx, done := event.Start(ctx, "source.PrepareCallHierarchy") - defer done() - -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err - } @@ -65999,7 +73084,7 @@ diff -urN a/gopls/internal/lsp/source/call_hierarchy.go b/gopls/internal/lsp/sou -// enclosingNodeCallItem creates a CallHierarchyItem representing the function call at loc. -func enclosingNodeCallItem(ctx context.Context, snapshot Snapshot, pkgPath PackagePath, loc protocol.Location) (protocol.CallHierarchyItem, error) { - // Parse the file containing the reference. -- fh, err := snapshot.GetFile(ctx, loc.URI.SpanURI()) +- fh, err := snapshot.ReadFile(ctx, loc.URI.SpanURI()) - if err != nil { - return protocol.CallHierarchyItem{}, err - } @@ -66074,7 +73159,7 @@ diff -urN a/gopls/internal/lsp/source/call_hierarchy.go b/gopls/internal/lsp/sou - ctx, done := event.Start(ctx, "source.OutgoingCalls") - defer done() - -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err - } @@ -66113,7 +73198,7 @@ diff -urN a/gopls/internal/lsp/source/call_hierarchy.go b/gopls/internal/lsp/sou - } - - // Use TypecheckFull as we want to inspect the body of the function declaration. -- declPkg, declPGF, err := PackageForFile(ctx, snapshot, uri, NarrowestPackage) +- declPkg, declPGF, err := NarrowestPackageForFile(ctx, snapshot, uri) - if err != nil { - return nil, err - } @@ -66243,9 +73328,13 @@ diff -urN a/gopls/internal/lsp/source/code_lens.go b/gopls/internal/lsp/source/c -) - -func runTestCodeLens(ctx context.Context, snapshot Snapshot, fh FileHandle) ([]protocol.CodeLens, error) { -- codeLens := make([]protocol.CodeLens, 0) +- var codeLens []protocol.CodeLens - -- fns, err := TestsAndBenchmarks(ctx, snapshot, fh) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) +- if err != nil { +- return nil, err +- } +- fns, err := TestsAndBenchmarks(ctx, snapshot, pkg, pgf) - if err != nil { - return nil, err - } @@ -66301,16 +73390,12 @@ diff -urN a/gopls/internal/lsp/source/code_lens.go b/gopls/internal/lsp/source/c - Benchmarks []testFn -} - --func TestsAndBenchmarks(ctx context.Context, snapshot Snapshot, fh FileHandle) (testFns, error) { +-func TestsAndBenchmarks(ctx context.Context, snapshot Snapshot, pkg Package, pgf *ParsedGoFile) (testFns, error) { - var out testFns - -- if !strings.HasSuffix(fh.URI().Filename(), "_test.go") { +- if !strings.HasSuffix(pgf.URI.Filename(), "_test.go") { - return out, nil - } -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) -- if err != nil { -- return out, err -- } - - for _, d := range pgf.File.Decls { - fn, ok := d.(*ast.FuncDecl) @@ -67440,12 +74525,12 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ -package completion - -import ( -- "bytes" - "context" - "fmt" - "go/ast" - "go/constant" - "go/parser" +- "go/printer" - "go/scanner" - "go/token" - "go/types" @@ -67460,6 +74545,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - - "golang.org/x/sync/errgroup" - "golang.org/x/tools/go/ast/astutil" +- goplsastutil "golang.org/x/tools/gopls/internal/astutil" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/lsp/snippet" @@ -67633,7 +74719,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // completionCallbacks is a list of callbacks to collect completions that - // require expensive operations. This includes operations where we search - // through the entire module cache. -- completionCallbacks []func(opts *imports.Options) error +- completionCallbacks []func(context.Context, *imports.Options) error - - // surrounding describes the identifier surrounding the position. - surrounding *Selection @@ -67664,10 +74750,6 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // mapper converts the positions in the file from which the completion originated. - mapper *protocol.Mapper - -- // startTime is when we started processing this completion request. It does -- // not include any time the request spent in the queue. -- startTime time.Time -- - // scopes contains all scopes defined by nodes in our path, - // including nil values for nodes that don't defined a scope. It - // also includes our package scope and the universal scope at the @@ -67738,10 +74820,6 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - mapper *protocol.Mapper -} - --func (p Selection) Content() string { -- return p.content --} -- -func (p Selection) Range() (protocol.Range, error) { - return p.mapper.PosRange(p.tokFile, p.start, p.end) -} @@ -67877,9 +74955,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - ctx, done := event.Start(ctx, "completion.Completion") - defer done() - -- startTime := time.Now() -- -- pkg, pgf, err := source.PackageForFile(ctx, snapshot, fh.URI(), source.NarrowestPackage) +- pkg, pgf, err := source.NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil || pgf.File.Package == token.NoPos { - // If we can't parse this file or find position for the package - // keyword, it may be missing a package declaration. Try offering @@ -67950,7 +75026,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - scopes := source.CollectScopes(pkg.GetTypesInfo(), path, pos) - scopes = append(scopes, pkg.GetTypes().Scope(), types.Universe) - -- opts := snapshot.View().Options() +- opts := snapshot.Options() - c := &completer{ - pkg: pkg, - snapshot: snapshot, @@ -67987,22 +75063,30 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - matcher: prefixMatcher(""), - methodSetCache: make(map[methodSetKey]*types.MethodSet), - mapper: pgf.Mapper, -- startTime: startTime, - scopes: scopes, - } - -- var cancel context.CancelFunc -- if c.opts.budget == 0 { -- ctx, cancel = context.WithCancel(ctx) -- } else { -- // timeoutDuration is the completion budget remaining. If less than -- // 10ms, set to 10ms -- timeoutDuration := time.Until(c.startTime.Add(c.opts.budget)) -- if timeoutDuration < 10*time.Millisecond { -- timeoutDuration = 10 * time.Millisecond -- } -- ctx, cancel = context.WithTimeout(ctx, timeoutDuration) +- ctx, cancel := context.WithCancel(ctx) +- +- // Compute the deadline for this operation. Deadline is relative to the +- // search operation, not the entire completion RPC, as the work up until this +- // point depends significantly on how long it took to type-check, which in +- // turn depends on the timing of the request relative to other operations on +- // the snapshot. Including that work in the budget leads to inconsistent +- // results (and realistically, if type-checking took 200ms already, the user +- // is unlikely to be significantly more bothered by e.g. another 100ms of +- // search). +- // +- // Don't overload the context with this deadline, as we don't want to +- // conflate user cancellation (=fail the operation) with our time limit +- // (=stop searching and succeed with partial results). +- start := time.Now() +- var deadline *time.Time +- if c.opts.budget > 0 { +- d := start.Add(c.opts.budget) +- deadline = &d - } +- - defer cancel() - - if surrounding := c.containingIdent(pgf.Src); surrounding != nil { @@ -68017,7 +75101,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - } - - // Deep search collected candidates and their members for more candidates. -- c.deepSearch(ctx) +- c.deepSearch(ctx, start, deadline) - - for _, callback := range c.completionCallbacks { - if err := c.snapshot.RunProcessEnvFunc(ctx, callback); err != nil { @@ -68027,7 +75111,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - - // Search candidates populated by expensive operations like - // unimportedMembers etc. for more completion items. -- c.deepSearch(ctx) +- c.deepSearch(ctx, start, deadline) - - // Statement candidates offer an entire statement in certain contexts, as - // opposed to a single object. Add statement candidates last because they @@ -68046,7 +75130,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - if !(importSpec.Path.Pos() <= c.pos && c.pos <= importSpec.Path.End()) { - continue - } -- return c.populateImportCompletions(ctx, importSpec) +- return c.populateImportCompletions(importSpec) - } - - // Inside comments, offer completions for the name of the relevant symbol. @@ -68091,7 +75175,11 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // recv.‸(arg) - case *ast.TypeAssertExpr: - // Create a fake selector expression. -- return c.selector(ctx, &ast.SelectorExpr{X: n.X}) +- // +- // The name "_" is the convention used by go/parser to represent phantom +- // selectors. +- sel := &ast.Ident{NamePos: n.X.End() + token.Pos(len(".")), Name: "_"} +- return c.selector(ctx, &ast.SelectorExpr{X: n.X, Sel: sel}) - case *ast.SelectorExpr: - return c.selector(ctx, n) - // At the file scope, only keywords are allowed. @@ -68195,7 +75283,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ -// Completions for "golang.org/" yield its subdirectories -// (i.e. "golang.org/x/"). The user is meant to accept completion suggestions -// until they reach a complete import path. --func (c *completer) populateImportCompletions(ctx context.Context, searchImport *ast.ImportSpec) error { +-func (c *completer) populateImportCompletions(searchImport *ast.ImportSpec) error { - if !strings.HasPrefix(searchImport.Path.Value, `"`) { - return nil - } @@ -68316,7 +75404,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - }) - } - -- c.completionCallbacks = append(c.completionCallbacks, func(opts *imports.Options) error { +- c.completionCallbacks = append(c.completionCallbacks, func(ctx context.Context, opts *imports.Options) error { - return imports.GetImportPaths(ctx, searchImports, prefix, c.filename, c.pkg.GetTypes().Name(), opts.Env) - }) - return nil @@ -68345,14 +75433,14 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // comment itself. - c.opts.documentation = false - -- commentLine := file.Line(comment.End()) +- commentLine := safetoken.Line(file, comment.End()) - - // comment is valid, set surrounding as word boundaries around cursor - c.setSurroundingForComment(comment) - - // Using the next line pos, grab and parse the exported symbol on that line - for _, n := range c.file.Decls { -- declLine := file.Line(n.Pos()) +- declLine := safetoken.Line(file, n.Pos()) - // if the comment is not in, directly above or on the same line as a declaration - if declLine != commentLine && declLine != commentLine+1 && - !(n.Pos() <= comment.Pos() && comment.End() <= n.End()) { @@ -68567,7 +75655,6 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // Imported declaration with missing type information. - // Fall through to shallow completion of unimported package members. - // Match candidate packages by path. -- // TODO(adonovan): simplify by merging with else case and matching on name only? - filter = func(m *source.Metadata) bool { - return strings.TrimPrefix(string(m.PkgPath), "vendor/") == imp.Path() - } @@ -68604,27 +75691,47 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // not assume global Pos/Object realms and then use export - // data instead of the quick parse approach taken here. - -- // First, we search among packages in the workspace. +- // First, we search among packages in the forward transitive +- // closure of the workspace. - // We'll use a fast parse to extract package members - // from those that match the name/path criterion. - all, err := c.snapshot.AllMetadata(ctx) - if err != nil { - return err - } -- var paths []string -- known := make(map[source.PackagePath][]*source.Metadata) // may include test variant +- known := make(map[source.PackagePath]*source.Metadata) - for _, m := range all { -- if m.IsIntermediateTestVariant() || m.Name == "main" || !filter(m) { +- if m.Name == "main" { +- continue // not importable +- } +- if m.IsIntermediateTestVariant() { - continue - } -- known[m.PkgPath] = append(known[m.PkgPath], m) -- paths = append(paths, string(m.PkgPath)) +- // The only test variant we admit is "p [p.test]" +- // when we are completing within "p_test [p.test]", +- // as in that case we would like to offer completions +- // of the test variants' additional symbols. +- if m.ForTest != "" && c.pkg.Metadata().PkgPath != m.ForTest+"_test" { +- continue +- } +- if !filter(m) { +- continue +- } +- // Prefer previous entry unless this one is its test variant. +- if m.ForTest != "" || known[m.PkgPath] == nil { +- known[m.PkgPath] = m +- } +- } +- +- paths := make([]string, 0, len(known)) +- for path := range known { +- paths = append(paths, string(path)) - } - - // Rank import paths as goimports would. - var relevances map[string]float64 - if len(paths) > 0 { -- if err := c.snapshot.RunProcessEnvFunc(ctx, func(opts *imports.Options) error { +- if err := c.snapshot.RunProcessEnvFunc(ctx, func(ctx context.Context, opts *imports.Options) error { - var err error - relevances, err = imports.ScoreImportPaths(ctx, opts.Env, paths) - return err @@ -68638,18 +75745,20 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - - // quickParse does a quick parse of a single file of package m, - // extracts exported package members and adds candidates to c.items. -- var itemsMu sync.Mutex // guards c.items -- var enough int32 // atomic bool +- // TODO(rfindley): synchronizing access to c here does not feel right. +- // Consider adding a concurrency-safe API for completer. +- var cMu sync.Mutex // guards c.items and c.matcher +- var enough int32 // atomic bool - quickParse := func(uri span.URI, m *source.Metadata) error { - if atomic.LoadInt32(&enough) != 0 { - return nil - } - -- fh, err := c.snapshot.GetFile(ctx, uri) +- fh, err := c.snapshot.ReadFile(ctx, uri) - if err != nil { - return err - } -- content, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return err - } @@ -68659,13 +75768,22 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - return - } - -- if !id.IsExported() || -- sel.Sel.Name != "_" && !strings.HasPrefix(id.Name, sel.Sel.Name) { -- return // not a match +- if !id.IsExported() { +- return +- } +- +- cMu.Lock() +- score := c.matcher.Score(id.Name) +- cMu.Unlock() +- +- if sel.Sel.Name != "_" && score == 0 { +- return // not a match; avoid constructing the completion item below - } - - // The only detail is the kind and package: `var (from "example.com/foo")` - // TODO(adonovan): pretty-print FuncDecl.FuncType or TypeSpec.Type? +- // TODO(adonovan): should this score consider the actual c.matcher.Score +- // of the item? How does this compare with the deepState.enqueue path? - item := CompletionItem{ - Label: id.Name, - Detail: fmt.Sprintf("%s (from %q)", strings.ToLower(tok.String()), m.PkgPath), @@ -68696,31 +75814,55 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - if fn != nil { - var sn snippet.Builder - sn.WriteText(id.Name) -- sn.WriteText("(") -- var nparams int -- for _, field := range fn.Type.Params.List { -- if field.Names != nil { -- nparams += len(field.Names) -- } else { -- nparams++ -- } -- } -- for i := 0; i < nparams; i++ { -- if i > 0 { -- sn.WriteText(", ") +- +- paramList := func(open, close string, list *ast.FieldList) { +- if list != nil { +- var cfg printer.Config // slight overkill +- var nparams int +- param := func(name string, typ ast.Expr) { +- if nparams > 0 { +- sn.WriteText(", ") +- } +- nparams++ +- if c.opts.placeholders { +- sn.WritePlaceholder(func(b *snippet.Builder) { +- var buf strings.Builder +- buf.WriteString(name) +- buf.WriteByte(' ') +- cfg.Fprint(&buf, token.NewFileSet(), typ) +- b.WriteText(buf.String()) +- }) +- } else { +- sn.WriteText(name) +- } +- } +- +- sn.WriteText(open) +- for _, field := range list.List { +- if field.Names != nil { +- for _, name := range field.Names { +- param(name.Name, field.Type) +- } +- } else { +- param("_", field.Type) +- } +- } +- sn.WriteText(close) - } -- sn.WritePlaceholder(nil) - } -- sn.WriteText(")") +- +- paramList("[", "]", typeparams.ForFuncType(fn.Type)) +- paramList("(", ")", fn.Type.Params) +- - item.snippet = &sn - } - -- itemsMu.Lock() +- cMu.Lock() - c.items = append(c.items, item) - if len(c.items) >= unimportedMemberTarget { - atomic.StoreInt32(&enough, 1) - } -- itemsMu.Unlock() +- cMu.Unlock() - }) - return nil - } @@ -68728,14 +75870,12 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // Extract the package-level candidates using a quick parse. - var g errgroup.Group - for _, path := range paths { -- for _, m := range known[source.PackagePath(path)] { -- m := m -- for _, uri := range m.CompiledGoFiles { -- uri := uri -- g.Go(func() error { -- return quickParse(uri, m) -- }) -- } +- m := known[source.PackagePath(path)] +- for _, uri := range m.CompiledGoFiles { +- uri := uri +- g.Go(func() error { +- return quickParse(uri, m) +- }) - } - } - if err := g.Wait(); err != nil { @@ -68771,7 +75911,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - } - } - -- c.completionCallbacks = append(c.completionCallbacks, func(opts *imports.Options) error { +- c.completionCallbacks = append(c.completionCallbacks, func(ctx context.Context, opts *imports.Options) error { - defer cancel() - return imports.GetPackageExports(ctx, add, id.Name, c.filename, c.pkg.GetTypes().Name(), opts.Env) - }) @@ -69040,7 +76180,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - - count := 0 - -- // Search packages across the entire workspace. +- // Search the forward transitive closure of the workspace. - all, err := c.snapshot.AllMetadata(ctx) - if err != nil { - return err @@ -69064,7 +76204,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - // Rank candidates using goimports' algorithm. - var relevances map[string]float64 - if len(paths) != 0 { -- if err := c.snapshot.RunProcessEnvFunc(ctx, func(opts *imports.Options) error { +- if err := c.snapshot.RunProcessEnvFunc(ctx, func(ctx context.Context, opts *imports.Options) error { - var err error - relevances, err = imports.ScoreImportPaths(ctx, opts.Env, paths) - return err @@ -69137,7 +76277,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - }) - count++ - } -- c.completionCallbacks = append(c.completionCallbacks, func(opts *imports.Options) error { +- c.completionCallbacks = append(c.completionCallbacks, func(ctx context.Context, opts *imports.Options) error { - defer cancel() - return imports.GetAllCandidates(ctx, add, prefix, c.filename, c.pkg.GetTypes().Name(), opts.Env) - }) @@ -70606,7 +77746,7 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ -// quick partial parse. fn is non-nil only for function declarations. -// The AST position information is garbage. -func forEachPackageMember(content []byte, f func(tok token.Token, id *ast.Ident, fn *ast.FuncDecl)) { -- purged := purgeFuncBodies(content) +- purged := goplsastutil.PurgeFuncBodies(content) - file, _ := parser.ParseFile(token.NewFileSet(), "", purged, 0) - for _, decl := range file.Decls { - switch decl := decl.(type) { @@ -70628,65 +77768,10 @@ diff -urN a/gopls/internal/lsp/source/completion/completion.go b/gopls/internal/ - } - } -} -- --// purgeFuncBodies returns a copy of src in which the contents of each --// outermost {...} region except struct and interface types have been --// deleted. It does not preserve newlines. This reduces the amount of --// work required to parse the top-level declarations. --func purgeFuncBodies(src []byte) []byte { -- // Destroy the content of any {...}-bracketed regions that are -- // not immediately preceded by a "struct" or "interface" -- // token. That includes function bodies, composite literals, -- // switch/select bodies, and all blocks of statements. -- // This will lead to non-void functions that don't have return -- // statements, which of course is a type error, but that's ok. -- -- var out bytes.Buffer -- file := token.NewFileSet().AddFile("", -1, len(src)) -- var sc scanner.Scanner -- sc.Init(file, src, nil, 0) -- var prev token.Token -- var cursor int // last consumed src offset -- var braces []token.Pos // stack of unclosed braces or -1 for struct/interface type -- for { -- pos, tok, _ := sc.Scan() -- if tok == token.EOF { -- break -- } -- switch tok { -- case token.COMMENT: -- // TODO(adonovan): opt: skip, to save an estimated 20% of time. -- -- case token.LBRACE: -- if prev == token.STRUCT || prev == token.INTERFACE { -- pos = -1 -- } -- braces = append(braces, pos) -- -- case token.RBRACE: -- if last := len(braces) - 1; last >= 0 { -- top := braces[last] -- braces = braces[:last] -- if top < 0 { -- // struct/interface type: leave alone -- } else if len(braces) == 0 { // toplevel only -- // Delete {...} body. -- start, _ := safetoken.Offset(file, top) -- end, _ := safetoken.Offset(file, pos) -- out.Write(src[cursor : start+len("{")]) -- cursor = end -- } -- } -- } -- prev = tok -- } -- out.Write(src[cursor:]) -- return out.Bytes() --} diff -urN a/gopls/internal/lsp/source/completion/deep_completion.go b/gopls/internal/lsp/source/completion/deep_completion.go --- a/gopls/internal/lsp/source/completion/deep_completion.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/completion/deep_completion.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,362 +0,0 @@ +@@ -1,364 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -70802,7 +77887,7 @@ diff -urN a/gopls/internal/lsp/source/completion/deep_completion.go b/gopls/inte -// deepSearch searches a candidate and its subordinate objects for completion -// items if deep completion is enabled and adds the valid candidates to -// completion items. --func (c *completer) deepSearch(ctx context.Context) { +-func (c *completer) deepSearch(ctx context.Context, start time.Time, deadline *time.Time) { - defer func() { - // We can return early before completing the search, so be sure to - // clear out our queues to not impact any further invocations. @@ -70810,7 +77895,9 @@ diff -urN a/gopls/internal/lsp/source/completion/deep_completion.go b/gopls/inte - c.deepState.nextQueue = c.deepState.nextQueue[:0] - }() - -- for len(c.deepState.nextQueue) > 0 { +- first := true // always fully process the first set of candidates +- for len(c.deepState.nextQueue) > 0 && (first || deadline == nil || time.Now().Before(*deadline)) { +- first = false - c.deepState.thisQueue, c.deepState.nextQueue = c.deepState.nextQueue, c.deepState.thisQueue[:0] - - outer: @@ -70859,7 +77946,7 @@ diff -urN a/gopls/internal/lsp/source/completion/deep_completion.go b/gopls/inte - - c.deepState.candidateCount++ - if c.opts.budget > 0 && c.deepState.candidateCount%100 == 0 { -- spent := float64(time.Since(c.startTime)) / float64(c.opts.budget) +- spent := float64(time.Since(start)) / float64(c.opts.budget) - select { - case <-ctx.Done(): - return @@ -71253,7 +78340,7 @@ diff -urN a/gopls/internal/lsp/source/completion/definition.go b/gopls/internal/ diff -urN a/gopls/internal/lsp/source/completion/format.go b/gopls/internal/lsp/source/completion/format.go --- a/gopls/internal/lsp/source/completion/format.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/completion/format.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,338 +0,0 @@ +@@ -1,345 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -71439,11 +78526,18 @@ diff -urN a/gopls/internal/lsp/source/completion/format.go b/gopls/internal/lsp/ - if cand.convertTo != nil { - typeName := types.TypeString(cand.convertTo, c.qf) - -- switch cand.convertTo.(type) { +- switch t := cand.convertTo.(type) { - // We need extra parens when casting to these types. For example, - // we need "(*int)(foo)", not "*int(foo)". - case *types.Pointer, *types.Signature: - typeName = "(" + typeName + ")" +- case *types.Basic: +- // If the types are incompatible (as determined by typeMatches), then we +- // must need a conversion here. However, if the target type is untyped, +- // don't suggest converting to e.g. "untyped float" (golang/go#62141). +- if t.Info()&types.IsUntyped != 0 { +- typeName = types.TypeString(types.Default(cand.convertTo), c.qf) +- } - } - - prefix = typeName + "(" + prefix @@ -71512,9 +78606,9 @@ diff -urN a/gopls/internal/lsp/source/completion/format.go b/gopls/internal/lsp/ - // TODO(rfindley): It doesn't look like this does the right thing for - // multi-line comments. - if strings.HasPrefix(comment.Text(), "Deprecated") { -- if c.snapshot.View().Options().CompletionTags { +- if c.snapshot.Options().CompletionTags { - item.Tags = []protocol.CompletionItemTag{protocol.ComplDeprecated} -- } else if c.snapshot.View().Options().CompletionDeprecated { +- } else if c.snapshot.Options().CompletionDeprecated { - item.Deprecated = true - } - } @@ -72722,7 +79816,7 @@ diff -urN a/gopls/internal/lsp/source/completion/package.go b/gopls/internal/lsp - // appear on any line of the file as long as it's the first code expression - // in the file. - lines := strings.Split(string(pgf.Src), "\n") -- cursorLine := tok.Line(cursor) +- cursorLine := safetoken.Line(tok, cursor) - if cursorLine <= 0 || cursorLine > len(lines) { - return nil, fmt.Errorf("invalid line number") - } @@ -72817,7 +79911,7 @@ diff -urN a/gopls/internal/lsp/source/completion/package.go b/gopls/internal/lsp -// file. This also includes test packages for these packages (_test) and -// the directory name itself. -func packageSuggestions(ctx context.Context, snapshot source.Snapshot, fileURI span.URI, prefix string) (packages []candidate, err error) { -- active, err := snapshot.ActiveMetadata(ctx) +- active, err := snapshot.WorkspaceMetadata(ctx) - if err != nil { - return nil, err - } @@ -73051,7 +80145,7 @@ diff -urN a/gopls/internal/lsp/source/completion/package_test.go b/gopls/interna diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/internal/lsp/source/completion/postfix_snippets.go --- a/gopls/internal/lsp/source/completion/postfix_snippets.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/completion/postfix_snippets.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,471 +0,0 @@ +@@ -1,481 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -73071,6 +80165,7 @@ diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/int - "text/template" - - "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/lsp/snippet" - "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/internal/event" @@ -73247,6 +80342,14 @@ diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/int - body: `{{if and (eq .Kind "slice") (eq (.TypeName .ElemType) "string") -}} -{{.Import "strings"}}.Join({{.X}}, "{{.Cursor}}") -{{- end}}`, +-}, { +- label: "ifnotnil", +- details: "if expr != nil", +- body: `{{if and (or (eq .Kind "pointer") (eq .Kind "chan") (eq .Kind "signature") (eq .Kind "interface") (eq .Kind "map") (eq .Kind "slice")) .StmtOK -}} +-if {{.X}} != nil {{"{"}} +- {{.Cursor}} +-{{"}"}} +-{{- end}}`, -}} - -// Cursor indicates where the client's cursor should end up after the @@ -73264,6 +80367,7 @@ diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/int - return "", fmt.Errorf("couldn't import %q: %w", path, err) - } - a.edits = append(a.edits, edits...) +- - return name, nil -} - @@ -73394,7 +80498,7 @@ diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/int - // - // detect that "foo." makes up the entire statement since the - // apparent selector spans lines. -- stmtOK = tokFile.Line(c.pos) < tokFile.Line(p.TokPos) +- stmtOK = safetoken.Line(tokFile, c.pos) < safetoken.Line(tokFile, p.TokPos) - } - break - } @@ -73416,8 +80520,8 @@ diff -urN a/gopls/internal/lsp/source/completion/postfix_snippets.go b/gopls/int - // - // and adjust afterDot so that we don't mistakenly delete the - // newline thinking "bar" is part of our selector. -- if startLine := tokFile.Line(sel.Pos()); startLine != tokFile.Line(afterDot) { -- if tokFile.Line(c.pos) != startLine { +- if startLine := safetoken.Line(tokFile, sel.Pos()); startLine != safetoken.Line(tokFile, afterDot) { +- if safetoken.Line(tokFile, c.pos) != startLine { - return - } - afterDot = c.pos @@ -74643,7 +81747,7 @@ diff -urN a/gopls/internal/lsp/source/completion/util_test.go b/gopls/internal/l diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/definition.go --- a/gopls/internal/lsp/source/definition.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/definition.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,229 +0,0 @@ +@@ -1,248 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -74657,9 +81761,9 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ - "go/token" - "go/types" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" -) - @@ -74668,7 +81772,7 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ - ctx, done := event.Start(ctx, "source.Definition") - defer done() - -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err - } @@ -74710,25 +81814,49 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ - return nil, nil - } - -- // Handle built-in identifiers. -- if obj.Parent() == types.Universe { -- builtin, err := snapshot.BuiltinFile(ctx) -- if err != nil { -- return nil, err +- // Handle objects with no position: builtin, unsafe. +- if !obj.Pos().IsValid() { +- var pgf *ParsedGoFile +- if obj.Parent() == types.Universe { +- // pseudo-package "builtin" +- builtinPGF, err := snapshot.BuiltinFile(ctx) +- if err != nil { +- return nil, err +- } +- pgf = builtinPGF +- +- } else if obj.Pkg() == types.Unsafe { +- // package "unsafe" +- unsafe := snapshot.Metadata("unsafe") +- if unsafe == nil { +- return nil, fmt.Errorf("no metadata for package 'unsafe'") +- } +- uri := unsafe.GoFiles[0] +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- pgf, err = snapshot.ParseGo(ctx, fh, ParseFull&^SkipObjectResolution) +- if err != nil { +- return nil, err +- } +- +- } else { +- return nil, bug.Errorf("internal error: no position for %v", obj.Name()) - } -- // Note that builtinObj is an ast.Object, not types.Object :) -- builtinObj := builtin.File.Scope.Lookup(obj.Name()) -- if builtinObj == nil { -- // Every builtin should have documentation. -- return nil, bug.Errorf("internal error: no builtin object for %s", obj.Name()) +- // Inv: pgf ∈ {builtin,unsafe}.go +- +- // Use legacy (go/ast) object resolution. +- astObj := pgf.File.Scope.Lookup(obj.Name()) +- if astObj == nil { +- // Every built-in should have documentation syntax. +- return nil, bug.Errorf("internal error: no object for %s", obj.Name()) - } -- decl, ok := builtinObj.Decl.(ast.Node) +- decl, ok := astObj.Decl.(ast.Node) - if !ok { - return nil, bug.Errorf("internal error: no declaration for %s", obj.Name()) - } -- // The builtin package isn't in the dependency graph, so the usual -- // utilities won't work here. -- loc, err := builtin.PosLocation(decl.Pos(), decl.Pos()+token.Pos(len(obj.Name()))) +- loc, err := pgf.PosLocation(decl.Pos(), decl.Pos()+token.Pos(len(obj.Name()))) - if err != nil { - return nil, err - } @@ -74736,16 +81864,11 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ - } - - // Finally, map the object position. -- var locs []protocol.Location -- if !obj.Pos().IsValid() { -- return nil, bug.Errorf("internal error: no position for %v", obj.Name()) -- } - loc, err := mapPosition(ctx, pkg.FileSet(), snapshot, obj.Pos(), adjustedObjEnd(obj)) - if err != nil { - return nil, err - } -- locs = append(locs, loc) -- return locs, nil +- return []protocol.Location{loc}, nil -} - -// referencedObject returns the identifier and object referenced at the @@ -74829,7 +81952,7 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ - - var locs []protocol.Location - for _, f := range impMetadata.CompiledGoFiles { -- fh, err := s.GetFile(ctx, f) +- fh, err := s.ReadFile(ctx, f) - if err != nil { - if ctx.Err() != nil { - return nil, ctx.Err() @@ -74862,11 +81985,11 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ -func mapPosition(ctx context.Context, fset *token.FileSet, s FileSource, start, end token.Pos) (protocol.Location, error) { - file := fset.File(start) - uri := span.URIFromPath(file.Name()) -- fh, err := s.GetFile(ctx, uri) +- fh, err := s.ReadFile(ctx, uri) - if err != nil { - return protocol.Location{}, err - } -- content, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return protocol.Location{}, err - } @@ -74876,7 +81999,7 @@ diff -urN a/gopls/internal/lsp/source/definition.go b/gopls/internal/lsp/source/ diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source/diagnostics.go --- a/gopls/internal/lsp/source/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,138 +0,0 @@ +@@ -1,187 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -74885,7 +82008,10 @@ diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source - -import ( - "context" +- "encoding/json" - +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/progress" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/span" -) @@ -74898,22 +82024,22 @@ diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source -} - -// Analyze reports go/analysis-framework diagnostics in the specified package. --func Analyze(ctx context.Context, snapshot Snapshot, pkgid PackageID, includeConvenience bool) (map[span.URI][]*Diagnostic, error) { +-// +-// If the provided tracker is non-nil, it may be used to provide notifications +-// of the ongoing analysis pass. +-func Analyze(ctx context.Context, snapshot Snapshot, pkgIDs map[PackageID]unit, tracker *progress.Tracker) (map[span.URI][]*Diagnostic, error) { - // Exit early if the context has been canceled. This also protects us - // from a race on Options, see golang/go#36699. - if ctx.Err() != nil { - return nil, ctx.Err() - } - -- options := snapshot.View().Options() +- options := snapshot.Options() - categories := []map[string]*Analyzer{ - options.DefaultAnalyzers, - options.StaticcheckAnalyzers, - options.TypeErrorAnalyzers, - } -- if includeConvenience { // e.g. for codeAction -- categories = append(categories, options.ConvenienceAnalyzers) // e.g. fillstruct -- } - - var analyzers []*Analyzer - for _, cat := range categories { @@ -74922,7 +82048,7 @@ diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source - } - } - -- analysisDiagnostics, err := snapshot.Analyze(ctx, pkgid, analyzers) +- analysisDiagnostics, err := snapshot.Analyze(ctx, pkgIDs, analyzers, tracker) - if err != nil { - return nil, err - } @@ -74935,38 +82061,6 @@ diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source - return reports, nil -} - --// FileDiagnostics reports diagnostics in the specified file, --// as used by the "gopls check" command. --// --// TODO(adonovan): factor in common with (*Server).codeAction, which --// executes { PackageForFile; Analyze } too? --// --// TODO(adonovan): opt: this function is called in a loop from the --// "gopls/diagnoseFiles" nonstandard request handler. It would be more --// efficient to compute the set of packages and TypeCheck and --// Analyze them all at once. --func FileDiagnostics(ctx context.Context, snapshot Snapshot, uri span.URI) (FileHandle, []*Diagnostic, error) { -- fh, err := snapshot.GetFile(ctx, uri) -- if err != nil { -- return nil, nil, err -- } -- pkg, _, err := PackageForFile(ctx, snapshot, uri, NarrowestPackage) -- if err != nil { -- return nil, nil, err -- } -- pkgDiags, err := pkg.DiagnosticsForFile(ctx, snapshot, uri) -- if err != nil { -- return nil, nil, err -- } -- adiags, err := Analyze(ctx, snapshot, pkg.Metadata().ID, false) -- if err != nil { -- return nil, nil, err -- } -- var fileDiags []*Diagnostic // combine load/parse/type + analysis diagnostics -- CombineDiagnostics(pkgDiags, adiags[uri], &fileDiags, &fileDiags) -- return fh, fileDiags, nil --} -- -// CombineDiagnostics combines and filters list/parse/type diagnostics from -// tdiags with adiags, and appends the two lists to *outT and *outA, -// respectively. @@ -75015,10 +82109,88 @@ diff -urN a/gopls/internal/lsp/source/diagnostics.go b/gopls/internal/lsp/source - - *outT = append(*outT, tdiags...) -} +- +-// quickFixesJSON is a JSON-serializable list of quick fixes +-// to be saved in the protocol.Diagnostic.Data field. +-type quickFixesJSON struct { +- // TODO(rfindley): pack some sort of identifier here for later +- // lookup/validation? +- Fixes []protocol.CodeAction +-} +- +-// BundleQuickFixes attempts to bundle sd.SuggestedFixes into the +-// sd.BundledFixes field, so that it can be round-tripped through the client. +-// It returns false if the quick-fixes cannot be bundled. +-func BundleQuickFixes(sd *Diagnostic) bool { +- if len(sd.SuggestedFixes) == 0 { +- return true +- } +- var actions []protocol.CodeAction +- for _, fix := range sd.SuggestedFixes { +- if fix.Edits != nil { +- // For now, we only support bundled code actions that execute commands. +- // +- // In order to cleanly support bundled edits, we'd have to guarantee that +- // the edits were generated on the current snapshot. But this naively +- // implies that every fix would have to include a snapshot ID, which +- // would require us to republish all diagnostics on each new snapshot. +- // +- // TODO(rfindley): in order to avoid this additional chatter, we'd need +- // to build some sort of registry or other mechanism on the snapshot to +- // check whether a diagnostic is still valid. +- return false +- } +- action := protocol.CodeAction{ +- Title: fix.Title, +- Kind: fix.ActionKind, +- Command: fix.Command, +- } +- actions = append(actions, action) +- } +- fixes := quickFixesJSON{ +- Fixes: actions, +- } +- data, err := json.Marshal(fixes) +- if err != nil { +- bug.Reportf("marshalling quick fixes: %v", err) +- return false +- } +- msg := json.RawMessage(data) +- sd.BundledFixes = &msg +- return true +-} +- +-// BundledQuickFixes extracts any bundled codeActions from the +-// diag.Data field. +-func BundledQuickFixes(diag protocol.Diagnostic) []protocol.CodeAction { +- if diag.Data == nil { +- return nil +- } +- var fix quickFixesJSON +- if err := json.Unmarshal(*diag.Data, &fix); err != nil { +- bug.Reportf("unmarshalling quick fix: %v", err) +- return nil +- } +- +- var actions []protocol.CodeAction +- for _, action := range fix.Fixes { +- // See BundleQuickFixes: for now we only support bundling commands. +- if action.Edit != nil { +- bug.Reportf("bundled fix %q includes workspace edits", action.Title) +- continue +- } +- // associate the action with the incoming diagnostic +- // (Note that this does not mutate the fix.Fixes slice). +- action.Diagnostics = []protocol.Diagnostic{diag} +- actions = append(actions, action) +- } +- +- return actions +-} diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/extract.go --- a/gopls/internal/lsp/source/extract.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/extract.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1331 +0,0 @@ +@@ -1,1352 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -75039,12 +82211,12 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/internal/analysisinternal" -- "golang.org/x/tools/internal/bug" -) - --func extractVariable(fset *token.FileSet, start, end token.Pos, src []byte, file *ast.File, _ *types.Package, info *types.Info) (*analysis.SuggestedFix, error) { +-func extractVariable(fset *token.FileSet, start, end token.Pos, src []byte, file *ast.File, pkg *types.Package, info *types.Info) (*analysis.SuggestedFix, error) { - tokFile := fset.File(file.Pos()) - expr, path, ok, err := CanExtractVariable(start, end, file) - if !ok { @@ -75057,14 +82229,14 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - // TODO: stricter rules for selectorExpr. - case *ast.BasicLit, *ast.CompositeLit, *ast.IndexExpr, *ast.SliceExpr, - *ast.UnaryExpr, *ast.BinaryExpr, *ast.SelectorExpr: -- lhsName, _ := generateAvailableIdentifier(expr.Pos(), file, path, info, "x", 0) +- lhsName, _ := generateAvailableIdentifier(expr.Pos(), file, path, pkg, info, "x", 0) - lhsNames = append(lhsNames, lhsName) - case *ast.CallExpr: - tup, ok := info.TypeOf(expr).(*types.Tuple) - if !ok { - // If the call expression only has one return value, we can treat it the - // same as our standard extract variable case. -- lhsName, _ := generateAvailableIdentifier(expr.Pos(), file, path, info, "x", 0) +- lhsName, _ := generateAvailableIdentifier(expr.Pos(), file, path, pkg, info, "x", 0) - lhsNames = append(lhsNames, lhsName) - break - } @@ -75072,7 +82244,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - for i := 0; i < tup.Len(); i++ { - // Generate a unique variable for each return value. - var lhsName string -- lhsName, idx = generateAvailableIdentifier(expr.Pos(), file, path, info, "x", idx) +- lhsName, idx = generateAvailableIdentifier(expr.Pos(), file, path, pkg, info, "x", idx) - lhsNames = append(lhsNames, lhsName) - } - default: @@ -75153,7 +82325,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext -// formatting (i.e. the proper indentation). To do so, we observe the indentation on the -// line of code on which the insertion occurs. -func calculateIndentation(content []byte, tok *token.File, insertBeforeStmt ast.Node) (string, error) { -- line := tok.Line(insertBeforeStmt.Pos()) +- line := safetoken.Line(tok, insertBeforeStmt.Pos()) - lineOffset, stmtOffset, err := safetoken.Offsets(tok, tok.LineStart(line), insertBeforeStmt.Pos()) - if err != nil { - return "", err @@ -75163,10 +82335,16 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - -// generateAvailableIdentifier adjusts the new function name until there are no collisions in scope. -// Possible collisions include other function and variable names. Returns the next index to check for prefix. --func generateAvailableIdentifier(pos token.Pos, file *ast.File, path []ast.Node, info *types.Info, prefix string, idx int) (string, int) { +-func generateAvailableIdentifier(pos token.Pos, file *ast.File, path []ast.Node, pkg *types.Package, info *types.Info, prefix string, idx int) (string, int) { - scopes := CollectScopes(info, path, pos) +- scopes = append(scopes, pkg.Scope()) - return generateIdentifier(idx, prefix, func(name string) bool { -- return file.Scope.Lookup(name) != nil || !isValidName(name, scopes) +- for _, scope := range scopes { +- if scope != nil && scope.Lookup(name) != nil { +- return true +- } +- } +- return false - }) -} - @@ -75182,19 +82360,6 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - return name, idx + 1 -} - --// isValidName checks for variable collision in scope. --func isValidName(name string, scopes []*types.Scope) bool { -- for _, scope := range scopes { -- if scope == nil { -- continue -- } -- if scope.Lookup(name) != nil { -- return false -- } -- } -- return true --} -- -// returnVariable keeps track of the information we need to properly introduce a new variable -// that we will return in the extracted function. -type returnVariable struct { @@ -75391,6 +82556,8 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - } - } - +- reorderParams(params, paramTypes) +- - // Find the function literal that encloses the selection. The enclosing function literal - // may not be the enclosing function declaration (i.e. 'outer'). For example, in the - // following block: @@ -75555,7 +82722,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - funName = name - } else { - name = "newFunction" -- funName, _ = generateAvailableIdentifier(start, file, path, info, name, 0) +- funName, _ = generateAvailableIdentifier(start, file, path, pkg, info, name, 0) - } - extractedFunCall := generateFuncCall(hasNonNestedReturn, hasReturnValues, params, - append(returns, getNames(retVars)...), funName, sym, receiverName) @@ -75659,6 +82826,33 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - }, nil -} - +-// isSelector reports if e is the selector expr , . +-func isSelector(e ast.Expr, x, sel string) bool { +- selectorExpr, ok := e.(*ast.SelectorExpr) +- if !ok { +- return false +- } +- ident, ok := selectorExpr.X.(*ast.Ident) +- if !ok { +- return false +- } +- return ident.Name == x && selectorExpr.Sel.Name == sel +-} +- +-// reorderParams reorders the given parameters in-place to follow common Go conventions. +-func reorderParams(params []ast.Expr, paramTypes []*ast.Field) { +- // Move Context parameter (if any) to front. +- for i, t := range paramTypes { +- if isSelector(t.Type, "context", "Context") { +- p, t := params[i], paramTypes[i] +- copy(params[1:], params[:i]) +- copy(paramTypes[1:], paramTypes[:i]) +- params[0], paramTypes[0] = p, t +- break +- } +- } +-} +- -// adjustRangeForCommentsAndWhiteSpace adjusts the given range to exclude unnecessary leading or -// trailing whitespace characters from selection as well as leading or trailing comments. -// In the following example, each line of the if statement is indented once. There are also two @@ -76158,7 +83352,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - var cond *ast.Ident - if !hasNonNestedReturns { - // Generate information for the added bool value. -- name, _ := generateAvailableIdentifier(pos, file, path, info, "shouldReturn", 0) +- name, _ := generateAvailableIdentifier(pos, file, path, pkg, info, "shouldReturn", 0) - cond = &ast.Ident{Name: name} - retVars = append(retVars, &returnVariable{ - name: cond, @@ -76180,8 +83374,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext - return nil, nil, fmt.Errorf("nil AST expression") - } - var name string -- name, idx = generateAvailableIdentifier(pos, file, -- path, info, "returnValue", idx) +- name, idx = generateAvailableIdentifier(pos, file, path, pkg, info, "returnValue", idx) - retVars = append(retVars, &returnVariable{ - name: ast.NewIdent(name), - decl: &ast.Field{Type: expr}, @@ -76353,7 +83546,7 @@ diff -urN a/gopls/internal/lsp/source/extract.go b/gopls/internal/lsp/source/ext diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go --- a/gopls/internal/lsp/source/fix.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/fix.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,138 +0,0 @@ +@@ -1,195 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -76368,11 +83561,13 @@ diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go - "go/types" - - "golang.org/x/tools/go/analysis" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/analysis/embeddirective" - "golang.org/x/tools/gopls/internal/lsp/analysis/fillstruct" - "golang.org/x/tools/gopls/internal/lsp/analysis/undeclaredname" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" +- "golang.org/x/tools/internal/imports" -) - -type ( @@ -76389,29 +83584,37 @@ diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go - singleFileFixFunc func(fset *token.FileSet, start, end token.Pos, src []byte, file *ast.File, pkg *types.Package, info *types.Info) (*analysis.SuggestedFix, error) -) - +-// These strings identify kinds of suggested fix, both in Analyzer.Fix +-// and in the ApplyFix subcommand (see ExecuteCommand and ApplyFixArgs.Fix). -const ( -- FillStruct = "fill_struct" -- StubMethods = "stub_methods" -- UndeclaredName = "undeclared_name" -- ExtractVariable = "extract_variable" -- ExtractFunction = "extract_function" -- ExtractMethod = "extract_method" +- FillStruct = "fill_struct" +- StubMethods = "stub_methods" +- UndeclaredName = "undeclared_name" +- ExtractVariable = "extract_variable" +- ExtractFunction = "extract_function" +- ExtractMethod = "extract_method" +- InlineCall = "inline_call" +- InvertIfCondition = "invert_if_condition" +- AddEmbedImport = "add_embed_import" -) - -// suggestedFixes maps a suggested fix command id to its handler. -var suggestedFixes = map[string]SuggestedFixFunc{ -- FillStruct: singleFile(fillstruct.SuggestedFix), -- UndeclaredName: singleFile(undeclaredname.SuggestedFix), -- ExtractVariable: singleFile(extractVariable), -- ExtractFunction: singleFile(extractFunction), -- ExtractMethod: singleFile(extractMethod), -- StubMethods: stubSuggestedFixFunc, +- FillStruct: singleFile(fillstruct.SuggestedFix), +- UndeclaredName: singleFile(undeclaredname.SuggestedFix), +- ExtractVariable: singleFile(extractVariable), +- InlineCall: inlineCall, +- ExtractFunction: singleFile(extractFunction), +- ExtractMethod: singleFile(extractMethod), +- InvertIfCondition: singleFile(invertIfCondition), +- StubMethods: stubSuggestedFixFunc, +- AddEmbedImport: addEmbedImport, -} - -// singleFile calls analyzers that expect inputs for a single file -func singleFile(sf singleFileFixFunc) SuggestedFixFunc { - return func(ctx context.Context, snapshot Snapshot, fh FileHandle, pRng protocol.Range) (*token.FileSet, *analysis.SuggestedFix, error) { -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, nil, err - } @@ -76456,7 +83659,7 @@ diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go - if !end.IsValid() { - end = edit.Pos - } -- fh, err := snapshot.GetFile(ctx, span.URIFromPath(tokFile.Name())) +- fh, err := snapshot.ReadFile(ctx, span.URIFromPath(tokFile.Name())) - if err != nil { - return nil, err - } @@ -76472,7 +83675,7 @@ diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go - } - editsPerFile[fh.URI()] = te - } -- content, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return nil, err - } @@ -76492,10 +83695,57 @@ diff -urN a/gopls/internal/lsp/source/fix.go b/gopls/internal/lsp/source/fix.go - } - return edits, nil -} +- +-// fixedByImportingEmbed returns true if diag can be fixed by addEmbedImport. +-func fixedByImportingEmbed(diag *Diagnostic) bool { +- if diag == nil { +- return false +- } +- return diag.Message == embeddirective.MissingImportMessage +-} +- +-// addEmbedImport adds a missing embed "embed" import with blank name. +-func addEmbedImport(ctx context.Context, snapshot Snapshot, fh FileHandle, rng protocol.Range) (*token.FileSet, *analysis.SuggestedFix, error) { +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) +- if err != nil { +- return nil, nil, fmt.Errorf("narrow pkg: %w", err) +- } +- +- // Like source.AddImport, but with _ as Name and using our pgf. +- protoEdits, err := ComputeOneImportFixEdits(snapshot, pgf, &imports.ImportFix{ +- StmtInfo: imports.ImportInfo{ +- ImportPath: "embed", +- Name: "_", +- }, +- FixType: imports.AddImport, +- }) +- if err != nil { +- return nil, nil, fmt.Errorf("compute edits: %w", err) +- } +- +- var edits []analysis.TextEdit +- for _, e := range protoEdits { +- start, end, err := pgf.RangePos(e.Range) +- if err != nil { +- return nil, nil, fmt.Errorf("map range: %w", err) +- } +- edits = append(edits, analysis.TextEdit{ +- Pos: start, +- End: end, +- NewText: []byte(e.NewText), +- }) +- } +- +- fix := &analysis.SuggestedFix{ +- Message: "Add embed import", +- TextEdits: edits, +- } +- return pkg.FileSet(), fix, nil +-} diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/source/folding_range.go --- a/gopls/internal/lsp/source/folding_range.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/folding_range.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,193 +0,0 @@ +@@ -1,194 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -76509,8 +83759,9 @@ diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/sour - "sort" - "strings" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" -) - -// FoldingRangeInfo holds range and kind info of folding for an ast.Node @@ -76622,7 +83873,7 @@ diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/sour - return nil - } - // in line folding mode, do not fold if the start and end lines are the same. -- if lineFoldingOnly && pgf.Tok.Line(start) == pgf.Tok.Line(end) { +- if lineFoldingOnly && safetoken.Line(pgf.Tok, start) == safetoken.Line(pgf.Tok, end) { - return nil - } - mrng, err := pgf.PosMappedRange(start, end) @@ -76647,8 +83898,8 @@ diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/sour - // as an example, the example below should *not* fold: - // var x = [2]string{"d", - // "e" } -- if tokFile.Line(open) == tokFile.Line(start) || -- tokFile.Line(close) == tokFile.Line(end) { +- if safetoken.Line(tokFile, open) == safetoken.Line(tokFile, start) || +- safetoken.Line(tokFile, close) == safetoken.Line(tokFile, end) { - return token.NoPos, token.NoPos - } - @@ -76663,7 +83914,7 @@ diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/sour -func commentsFoldingRange(pgf *ParsedGoFile) (comments []*FoldingRangeInfo) { - tokFile := pgf.Tok - for _, commentGrp := range pgf.File.Comments { -- startGrpLine, endGrpLine := tokFile.Line(commentGrp.Pos()), tokFile.Line(commentGrp.End()) +- startGrpLine, endGrpLine := safetoken.Line(tokFile, commentGrp.Pos()), safetoken.Line(tokFile, commentGrp.End()) - if startGrpLine == endGrpLine { - // Don't fold single line comments. - continue @@ -76671,7 +83922,7 @@ diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/sour - - firstComment := commentGrp.List[0] - startPos, endLinePos := firstComment.Pos(), firstComment.End() -- startCmmntLine, endCmmntLine := tokFile.Line(startPos), tokFile.Line(endLinePos) +- startCmmntLine, endCmmntLine := safetoken.Line(tokFile, startPos), safetoken.Line(tokFile, endLinePos) - if startCmmntLine != endCmmntLine { - // If the first comment spans multiple lines, then we want to have the - // folding range start at the end of the first line. @@ -76692,7 +83943,7 @@ diff -urN a/gopls/internal/lsp/source/folding_range.go b/gopls/internal/lsp/sour diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/format.go --- a/gopls/internal/lsp/source/format.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/format.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,391 +0,0 @@ +@@ -1,388 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -76716,6 +83967,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - "golang.org/x/tools/internal/diff" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/imports" +- "golang.org/x/tools/internal/tokeninternal" -) - -// Format formats a file with a given range. @@ -76748,7 +84000,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - // This should be acceptable for all users, who likely be prompted to rebuild - // the LSP server on each Go release. - buf := &bytes.Buffer{} -- fset := FileSetFor(pgf.Tok) +- fset := tokeninternal.FileSetFor(pgf.Tok) - if err := format.Node(buf, fset, pgf.File); err != nil { - return nil, err - } @@ -76756,7 +84008,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - - // Apply additional formatting, if any is supported. Currently, the only - // supported additional formatter is gofumpt. -- if format := snapshot.View().Options().GofumptFormat; snapshot.View().Options().Gofumpt && format != nil { +- if format := snapshot.Options().GofumptFormat; snapshot.Options().Gofumpt && format != nil { - // gofumpt can customize formatting based on language version and module - // path, if available. - // @@ -76766,9 +84018,9 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - // Can this, for example, result in inconsistent formatting across saves, - // due to pending calls to packages.Load? - var langVersion, modulePath string -- mds, err := snapshot.MetadataForFile(ctx, fh.URI()) -- if err == nil && len(mds) > 0 { -- if mi := mds[0].Module; mi != nil { +- meta, err := NarrowestMetadataForFile(ctx, snapshot, fh.URI()) +- if err == nil { +- if mi := meta.Module; mi != nil { - langVersion = mi.GoVersion - modulePath = mi.Path - } @@ -76786,7 +84038,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - _, done := event.Start(ctx, "source.formatSource") - defer done() - -- data, err := fh.Read() +- data, err := fh.Content() - if err != nil { - return nil, err - } @@ -76802,16 +84054,12 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form -// In addition to returning the result of applying all edits, -// it returns a list of fixes that could be applied to the file, with the -// corresponding TextEdits that would be needed to apply that fix. --func AllImportsFixes(ctx context.Context, snapshot Snapshot, fh FileHandle) (allFixEdits []protocol.TextEdit, editsPerFix []*ImportFix, err error) { +-func AllImportsFixes(ctx context.Context, snapshot Snapshot, pgf *ParsedGoFile) (allFixEdits []protocol.TextEdit, editsPerFix []*ImportFix, err error) { - ctx, done := event.Start(ctx, "source.AllImportsFixes") - defer done() - -- pgf, err := snapshot.ParseGo(ctx, fh, ParseFull) -- if err != nil { -- return nil, nil, err -- } -- if err := snapshot.RunProcessEnvFunc(ctx, func(opts *imports.Options) error { -- allFixEdits, editsPerFix, err = computeImportEdits(snapshot, pgf, opts) +- if err := snapshot.RunProcessEnvFunc(ctx, func(ctx context.Context, opts *imports.Options) error { +- allFixEdits, editsPerFix, err = computeImportEdits(ctx, snapshot, pgf, opts) - return err - }); err != nil { - return nil, nil, fmt.Errorf("AllImportsFixes: %v", err) @@ -76821,11 +84069,11 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - -// computeImportEdits computes a set of edits that perform one or all of the -// necessary import fixes. --func computeImportEdits(snapshot Snapshot, pgf *ParsedGoFile, options *imports.Options) (allFixEdits []protocol.TextEdit, editsPerFix []*ImportFix, err error) { +-func computeImportEdits(ctx context.Context, snapshot Snapshot, pgf *ParsedGoFile, options *imports.Options) (allFixEdits []protocol.TextEdit, editsPerFix []*ImportFix, err error) { - filename := pgf.URI.Filename() - - // Build up basic information about the original file. -- allFixes, err := imports.FixImports(filename, pgf.Src, options) +- allFixes, err := imports.FixImports(ctx, filename, pgf.Src, options) - if err != nil { - return nil, nil, err - } @@ -76853,7 +84101,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form -// ComputeOneImportFixEdits returns text edits for a single import fix. -func ComputeOneImportFixEdits(snapshot Snapshot, pgf *ParsedGoFile, fix *imports.ImportFix) ([]protocol.TextEdit, error) { - options := &imports.Options{ -- LocalPrefix: snapshot.View().Options().Local, +- LocalPrefix: snapshot.Options().Local, - // Defaults. - AllErrors: true, - Comments: true, @@ -76892,7 +84140,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - if fixedData == nil || fixedData[len(fixedData)-1] != '\n' { - fixedData = append(fixedData, '\n') // ApplyFixes may miss the newline, go figure. - } -- edits := snapshot.View().Options().ComputeEdits(left, string(fixedData)) +- edits := snapshot.Options().ComputeEdits(left, string(fixedData)) - return protocolEditsFromSource([]byte(left), edits) -} - @@ -76932,7 +84180,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - // specifically, in the text of a comment, it will strip out \r\n line - // endings in favor of \n. To account for these differences, we try to - // return a position on the next line whenever possible. -- switch line := tok.Line(tok.Pos(offset)); { +- switch line := safetoken.Line(tok, tok.Pos(offset)); { - case line < tok.LineCount(): - nextLineOffset, err := safetoken.Offset(tok, tok.LineStart(line+1)) - if err != nil { @@ -77002,7 +84250,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - _, done := event.Start(ctx, "source.computeTextEdits") - defer done() - -- edits := snapshot.View().Options().ComputeEdits(string(pgf.Src), formatted) +- edits := snapshot.Options().ComputeEdits(string(pgf.Src), formatted) - return ToProtocolEdits(pgf.Mapper, edits) -} - @@ -77030,7 +84278,7 @@ diff -urN a/gopls/internal/lsp/source/format.go b/gopls/internal/lsp/source/form - return result, nil -} - --// ToProtocolEdits converts diff.Edits to LSP TextEdits. +-// ToProtocolEdits converts diff.Edits to a non-nil slice of LSP TextEdits. -// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textEditArray -func ToProtocolEdits(m *protocol.Mapper, edits []diff.Edit) ([]protocol.TextEdit, error) { - // LSP doesn't require TextEditArray to be sorted: @@ -77178,7 +84426,6 @@ diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/sou - "context" - "encoding/json" - "fmt" -- "io/ioutil" - "os" - "path/filepath" - "strings" @@ -77214,7 +84461,7 @@ diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/sou - if err := os.MkdirAll(outDir, 0700); err != nil { - return nil, err - } -- tmpFile, err := ioutil.TempFile(os.TempDir(), "gopls-x") +- tmpFile, err := os.CreateTemp(os.TempDir(), "gopls-x") - if err != nil { - return nil, err - } @@ -77244,7 +84491,7 @@ diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/sou - return nil, err - } - reports := make(map[span.URI][]*Diagnostic) -- opts := snapshot.View().Options() +- opts := snapshot.Options() - var parseError error - for _, fn := range files { - uri, diagnostics, err := parseDetailsFile(fn, opts) @@ -77268,7 +84515,7 @@ diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/sou -} - -func parseDetailsFile(filename string, options *Options) (span.URI, []*Diagnostic, error) { -- buf, err := ioutil.ReadFile(filename) +- buf, err := os.ReadFile(filename) - if err != nil { - return "", nil, err - } @@ -77298,6 +84545,7 @@ diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/sou - if err := dec.Decode(d); err != nil { - return "", nil, err - } +- d.Tags = []protocol.DiagnosticTag{} // must be an actual slice - msg := d.Code.(string) - if msg != "" { - msg = fmt.Sprintf("%s(%s)", msg, d.Message) @@ -77391,7 +84639,7 @@ diff -urN a/gopls/internal/lsp/source/gc_annotations.go b/gopls/internal/lsp/sou diff -urN a/gopls/internal/lsp/source/highlight.go b/gopls/internal/lsp/source/highlight.go --- a/gopls/internal/lsp/source/highlight.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/highlight.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,484 +0,0 @@ +@@ -1,480 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -77404,7 +84652,6 @@ diff -urN a/gopls/internal/lsp/source/highlight.go b/gopls/internal/lsp/source/h - "go/ast" - "go/token" - "go/types" -- "strings" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/gopls/internal/lsp/protocol" @@ -77417,7 +84664,7 @@ diff -urN a/gopls/internal/lsp/source/highlight.go b/gopls/internal/lsp/source/h - - // We always want fully parsed files for highlight, regardless - // of whether the file belongs to a workspace package. -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, fmt.Errorf("getting package for Highlight: %w", err) - } @@ -77461,10 +84708,27 @@ diff -urN a/gopls/internal/lsp/source/highlight.go b/gopls/internal/lsp/source/h - result := make(map[posRange]struct{}) - switch node := path[0].(type) { - case *ast.BasicLit: +- // Import path string literal? - if len(path) > 1 { -- if _, ok := path[1].(*ast.ImportSpec); ok { -- err := highlightImportUses(path, info, result) -- return result, err +- if imp, ok := path[1].(*ast.ImportSpec); ok { +- highlight := func(n ast.Node) { +- result[posRange{start: n.Pos(), end: n.End()}] = struct{}{} +- } +- +- // Highlight the import itself... +- highlight(imp) +- +- // ...and all references to it in the file. +- if pkgname, ok := ImportedPkgName(info, imp); ok { +- ast.Inspect(file, func(n ast.Node) bool { +- if id, ok := n.(*ast.Ident); ok && +- info.Uses[id] == pkgname { +- highlight(id) +- } +- return true +- }) +- } +- return result, nil - } - } - highlightFuncControlFlow(path, result) @@ -77813,73 +85077,53 @@ diff -urN a/gopls/internal/lsp/source/highlight.go b/gopls/internal/lsp/source/h - }) -} - --func highlightImportUses(path []ast.Node, info *types.Info, result map[posRange]struct{}) error { -- basicLit, ok := path[0].(*ast.BasicLit) -- if !ok { -- return fmt.Errorf("highlightImportUses called with an ast.Node of type %T", basicLit) -- } -- ast.Inspect(path[len(path)-1], func(node ast.Node) bool { -- if imp, ok := node.(*ast.ImportSpec); ok && imp.Path == basicLit { -- result[posRange{start: node.Pos(), end: node.End()}] = struct{}{} -- return false -- } -- n, ok := node.(*ast.Ident) -- if !ok { -- return true -- } -- obj, ok := info.ObjectOf(n).(*types.PkgName) -- if !ok { -- return true -- } -- if !strings.Contains(basicLit.Value, obj.Name()) { -- return true -- } +-func highlightIdentifier(id *ast.Ident, file *ast.File, info *types.Info, result map[posRange]struct{}) { +- highlight := func(n ast.Node) { - result[posRange{start: n.Pos(), end: n.End()}] = struct{}{} -- return false -- }) -- return nil --} +- } - --func highlightIdentifier(id *ast.Ident, file *ast.File, info *types.Info, result map[posRange]struct{}) { -- // TODO(rfindley): idObj may be nil. Note that returning early in this case -- // causes tests to fail (because the nObj == idObj check below was succeeded -- // for nil == nil!) -- // -- // Revisit this. If ObjectOf is nil, there are type errors, and it seems -- // reasonable for identifier highlighting not to work. -- idObj := info.ObjectOf(id) -- pkgObj, isImported := idObj.(*types.PkgName) -- ast.Inspect(file, func(node ast.Node) bool { -- if imp, ok := node.(*ast.ImportSpec); ok && isImported { -- highlightImport(pkgObj, imp, result) -- } -- n, ok := node.(*ast.Ident) -- if !ok { -- return true -- } -- if n.Name != id.Name { -- return false -- } -- if nObj := info.ObjectOf(n); nObj == idObj { -- result[posRange{start: n.Pos(), end: n.End()}] = struct{}{} +- // obj may be nil if the Ident is undefined. +- // In this case, the behavior expected by tests is +- // to match other undefined Idents of the same name. +- obj := info.ObjectOf(id) +- +- ast.Inspect(file, func(n ast.Node) bool { +- switch n := n.(type) { +- case *ast.Ident: +- if n.Name == id.Name && info.ObjectOf(n) == obj { +- highlight(n) +- } +- +- case *ast.ImportSpec: +- pkgname, ok := ImportedPkgName(info, n) +- if ok && pkgname == obj { +- if n.Name != nil { +- highlight(n.Name) +- } else { +- highlight(n) +- } +- } - } -- return false +- return true - }) -} - --func highlightImport(obj *types.PkgName, imp *ast.ImportSpec, result map[posRange]struct{}) { -- if imp.Name != nil || imp.Path == nil { -- return -- } -- if !strings.Contains(imp.Path.Value, obj.Name()) { -- return +-// ImportedPkgName returns the PkgName object declared by an ImportSpec. +-// TODO(adonovan): make this a method of types.Info. +-func ImportedPkgName(info *types.Info, imp *ast.ImportSpec) (*types.PkgName, bool) { +- var obj types.Object +- if imp.Name != nil { +- obj = info.Defs[imp.Name] +- } else { +- obj = info.Implicits[imp] - } -- result[posRange{start: imp.Path.Pos(), end: imp.Path.End()}] = struct{}{} +- pkgname, ok := obj.(*types.PkgName) +- return pkgname, ok -} diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover.go --- a/gopls/internal/lsp/source/hover.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/hover.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,951 +0,0 @@ +@@ -1,1019 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -77904,11 +85148,12 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - "golang.org/x/text/unicode/runenames" - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/go/types/typeutil" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/tokeninternal" - "golang.org/x/tools/internal/typeparams" -) - @@ -77952,13 +85197,13 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - if h == nil { - return nil, nil - } -- hover, err := formatHover(h, snapshot.View().Options()) +- hover, err := formatHover(h, snapshot.Options()) - if err != nil { - return nil, err - } - return &protocol.Hover{ - Contents: protocol.MarkupContent{ -- Kind: snapshot.View().Options().PreferredContentFormat, +- Kind: snapshot.Options().PreferredContentFormat, - Value: hover, - }, - Range: rng, @@ -77969,7 +85214,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover -// hovering at the position, it returns _, nil, nil: an error is only returned -// if the position is valid but we fail to compute hover information. -func hover(ctx context.Context, snapshot Snapshot, fh FileHandle, pp protocol.Position) (protocol.Range, *HoverJSON, error) { -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return protocol.Range{}, nil, err - } @@ -78002,6 +85247,22 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - } - } - +- // Handle linkname directive by overriding what to look for. +- var linkedRange *protocol.Range // range referenced by linkname directive, or nil +- if pkgPath, name, offset := parseLinkname(ctx, snapshot, fh, pp); pkgPath != "" && name != "" { +- // rng covering 2nd linkname argument: pkgPath.name. +- rng, err := pgf.PosRange(pgf.Tok.Pos(offset), pgf.Tok.Pos(offset+len(pkgPath)+len(".")+len(name))) +- if err != nil { +- return protocol.Range{}, nil, fmt.Errorf("range over linkname arg: %w", err) +- } +- linkedRange = &rng +- +- pkg, pgf, pos, err = findLinkname(ctx, snapshot, PackagePath(pkgPath), name) +- if err != nil { +- return protocol.Range{}, nil, fmt.Errorf("find linkname: %w", err) +- } +- } +- - // The general case: compute hover information for the object referenced by - // the identifier at pos. - ident, obj, selectedType := referencedObject(pkg, pgf, pos) @@ -78009,9 +85270,15 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - return protocol.Range{}, nil, nil // no object to hover - } - -- rng, err := pgf.NodeRange(ident) -- if err != nil { -- return protocol.Range{}, nil, err +- // Unless otherwise specified, rng covers the ident being hovered. +- var rng protocol.Range +- if linkedRange != nil { +- rng = *linkedRange +- } else { +- rng, err = pgf.NodeRange(ident) +- if err != nil { +- return protocol.Range{}, nil, err +- } - } - - // By convention, we qualify hover information relative to the package @@ -78024,7 +85291,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - // There's not much useful information to provide. - if selectedType != nil { - fakeObj := types.NewVar(obj.Pos(), obj.Pkg(), obj.Name(), selectedType) -- signature := objectString(fakeObj, qf, nil) +- signature := types.ObjectString(fakeObj, qf) - return rng, &HoverJSON{ - Signature: signature, - SingleLine: signature, @@ -78049,10 +85316,14 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - docText := comment.Text() - - // By default, types.ObjectString provides a reasonable signature. -- signature := objectString(obj, qf, nil) +- signature := objectString(obj, qf, declPos, declPGF.Tok, spec) +- singleLineSignature := signature +- - // TODO(rfindley): we could do much better for inferred signatures. - if inferred := inferredSignature(pkg.GetTypesInfo(), ident); inferred != nil { -- signature = objectString(obj, qf, inferred) +- if s := inferredSignatureString(obj, qf, inferred); s != "" { +- signature = s +- } - } - - // For "objects defined by a type spec", the signature produced by @@ -78077,7 +85348,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - spec2.Comment = nil - var b strings.Builder - b.WriteString("type ") -- fset := FileSetFor(declPGF.Tok) +- fset := tokeninternal.FileSetFor(declPGF.Tok) - if err := format.Node(&b, fset, &spec2); err != nil { - return protocol.Range{}, nil, err - } @@ -78095,7 +85366,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - if (m.Obj().Exported() || m.Obj().Pkg() == pkg.GetTypes()) && len(m.Index()) == 1 { - b.WriteString(sep) - sep = "\n" -- b.WriteString(objectString(m.Obj(), qf, nil)) +- b.WriteString(types.ObjectString(m.Obj(), qf)) - } - } - } @@ -78202,7 +85473,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - return rng, &HoverJSON{ - Synopsis: doc.Synopsis(docText), - FullDocumentation: docText, -- SingleLine: objectString(obj, qf, nil), +- SingleLine: singleLineSignature, - SymbolName: linkName, - Signature: signature, - LinkPath: linkPath, @@ -78219,8 +85490,6 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - return nil, err - } - -- // TODO(rfindley): add a test for jump to definition of error.Error (which is -- // probably failing, considering it lacks special handling). - if obj.Name() == "Error" { - signature := obj.String() - return &HoverJSON{ @@ -78306,7 +85575,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - // Find the first file with a package doc comment. - var comment *ast.CommentGroup - for _, f := range impMetadata.CompiledGoFiles { -- fh, err := snapshot.GetFile(ctx, f) +- fh, err := snapshot.ReadFile(ctx, f) - if err != nil { - if ctx.Err() != nil { - return protocol.Range{}, nil, ctx.Err() @@ -78364,8 +85633,11 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover -// -// '∑', U+2211, N-ARY SUMMATION -func hoverLit(pgf *ParsedGoFile, lit *ast.BasicLit, pos token.Pos) (protocol.Range, *HoverJSON, error) { -- var r rune -- var start, end token.Pos +- var ( +- value string // if non-empty, a constant value to format in hover +- r rune // if non-zero, format a description of this rune in hover +- start, end token.Pos // hover span +- ) - // Extract a rune from the current position. - // 'Ω', "...Ω...", or 0x03A9 => 'Ω', U+03A9, GREEK CAPITAL LETTER OMEGA - switch lit.Kind { @@ -78381,23 +85653,34 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - return protocol.Range{}, nil, fmt.Errorf("rune error") - } - start, end = lit.Pos(), lit.End() -- case token.INT: -- // TODO(rfindley): add support for hex/octal/binary->int conversion here. - -- // It's an integer, scan only if it is a hex literal whose bitsize in -- // ranging from 8 to 32. -- if !(strings.HasPrefix(lit.Value, "0x") && len(lit.Value[2:]) >= 2 && len(lit.Value[2:]) <= 8) { +- case token.INT: +- // Short literals (e.g. 99 decimal, 07 octal) are uninteresting. +- if len(lit.Value) < 3 { - return protocol.Range{}, nil, nil - } -- v, err := strconv.ParseUint(lit.Value[2:], 16, 32) -- if err != nil { -- return protocol.Range{}, nil, fmt.Errorf("parsing int: %v", err) +- +- v := constant.MakeFromLiteral(lit.Value, lit.Kind, 0) +- if v.Kind() != constant.Int { +- return protocol.Range{}, nil, nil - } -- r = rune(v) -- if r == utf8.RuneError { -- return protocol.Range{}, nil, fmt.Errorf("rune error") +- +- switch lit.Value[:2] { +- case "0x", "0X": +- // As a special case, try to recognize hexadecimal literals as runes if +- // they are within the range of valid unicode values. +- if v, ok := constant.Int64Val(v); ok && v > 0 && v <= utf8.MaxRune && utf8.ValidRune(rune(v)) { +- r = rune(v) +- } +- fallthrough +- case "0o", "0O", "0b", "0B": +- // Format the decimal value of non-decimal literals. +- value = v.ExactString() +- start, end = lit.Pos(), lit.End() +- default: +- return protocol.Range{}, nil, nil - } -- start, end = lit.Pos(), lit.End() +- - case token.STRING: - // It's a string, scan only if it contains a unicode escape sequence under or before the - // current cursor position. @@ -78432,38 +85715,46 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - } - } - } -- if r == 0 { +- +- if value == "" && r == 0 { // nothing to format - return protocol.Range{}, nil, nil - } +- - rng, err := pgf.PosRange(start, end) - if err != nil { - return protocol.Range{}, nil, err - } - -- var desc string -- runeName := runenames.Name(r) -- if len(runeName) > 0 && runeName[0] == '<' { -- // Check if the rune looks like an HTML tag. If so, trim the surrounding <> -- // characters to work around https://github.com/microsoft/vscode/issues/124042. -- runeName = strings.TrimRight(runeName[1:], ">") +- var b strings.Builder +- if value != "" { +- b.WriteString(value) - } -- if strconv.IsPrint(r) { -- desc = fmt.Sprintf("'%s', U+%04X, %s", string(r), uint32(r), runeName) -- } else { -- desc = fmt.Sprintf("U+%04X, %s", uint32(r), runeName) +- if r != 0 { +- runeName := runenames.Name(r) +- if len(runeName) > 0 && runeName[0] == '<' { +- // Check if the rune looks like an HTML tag. If so, trim the surrounding <> +- // characters to work around https://github.com/microsoft/vscode/issues/124042. +- runeName = strings.TrimRight(runeName[1:], ">") +- } +- if b.Len() > 0 { +- b.WriteString(", ") +- } +- if strconv.IsPrint(r) { +- fmt.Fprintf(&b, "'%c', ", r) +- } +- fmt.Fprintf(&b, "U+%04X, %s", r, runeName) - } +- hover := b.String() - return rng, &HoverJSON{ -- Synopsis: desc, -- FullDocumentation: desc, +- Synopsis: hover, +- FullDocumentation: hover, - }, nil -} - --// objectString is a wrapper around the types.ObjectString function. --// It handles adding more information to the object string. --// --// TODO(rfindley): this function does too much. We should lift the special --// handling to callsites. --func objectString(obj types.Object, qf types.Qualifier, inferred *types.Signature) string { +-// inferredSignatureString is a wrapper around the types.ObjectString function +-// that adds more information to inferred signatures. It will return an empty string +-// if the passed types.Object is not a signature. +-func inferredSignatureString(obj types.Object, qf types.Qualifier, inferred *types.Signature) string { - // If the signature type was inferred, prefer the inferred signature with a - // comment showing the generic signature. - if sig, _ := obj.Type().(*types.Signature); sig != nil && typeparams.ForSignature(sig).Len() > 0 && inferred != nil { @@ -78478,22 +85769,65 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - str += "// " + types.TypeString(sig, qf) - return str - } +- return "" +-} +- +-// objectString is a wrapper around the types.ObjectString function. +-// It handles adding more information to the object string. +-// If spec is non-nil, it may be used to format additional declaration +-// syntax, and file must be the token.File describing its positions. +-func objectString(obj types.Object, qf types.Qualifier, declPos token.Pos, file *token.File, spec ast.Spec) string { - str := types.ObjectString(obj, qf) +- - switch obj := obj.(type) { - case *types.Const: -- str = fmt.Sprintf("%s = %s", str, obj.Val()) +- var ( +- declaration = obj.Val().String() // default formatted declaration +- comment = "" // if non-empty, a clarifying comment +- ) - -- // Try to add a formatted duration as an inline comment -- typ, ok := obj.Type().(*types.Named) -- if !ok { -- break +- // Try to use the original declaration. +- switch obj.Val().Kind() { +- case constant.String: +- // Usually the original declaration of a string doesn't carry much information. +- // Also strings can be very long. So, just use the constant's value. +- +- default: +- if spec, _ := spec.(*ast.ValueSpec); spec != nil { +- for i, name := range spec.Names { +- if declPos == name.Pos() { +- if i < len(spec.Values) { +- originalDeclaration := FormatNodeFile(file, spec.Values[i]) +- if originalDeclaration != declaration { +- comment = declaration +- declaration = originalDeclaration +- } +- } +- break +- } +- } +- } - } -- pkg := typ.Obj().Pkg() -- if pkg.Path() == "time" && typ.Obj().Name() == "Duration" { -- if d, ok := constant.Int64Val(obj.Val()); ok { -- str += " // " + time.Duration(d).String() +- +- // Special formatting cases. +- switch typ := obj.Type().(type) { +- case *types.Named: +- // Try to add a formatted duration as an inline comment. +- pkg := typ.Obj().Pkg() +- if pkg.Path() == "time" && typ.Obj().Name() == "Duration" { +- if d, ok := constant.Int64Val(obj.Val()); ok { +- comment = time.Duration(d).String() +- } - } - } +- if comment == declaration { +- comment = "" +- } +- +- str += " = " + declaration +- if comment != "" { +- str += " // " + comment +- } - } - return str -} @@ -78566,7 +85900,7 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - } - - uri := span.URIFromPath(f.Name()) -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return nil, 0, err - } @@ -78589,28 +85923,6 @@ diff -urN a/gopls/internal/lsp/source/hover.go b/gopls/internal/lsp/source/hover - return pgf, fullPos, nil -} - --// extractFieldList recursively tries to extract a field list. --// If it is not found, nil is returned. --func extractFieldList(specType ast.Expr) *ast.FieldList { -- switch t := specType.(type) { -- case *ast.StructType: -- return t.Fields -- case *ast.InterfaceType: -- return t.Methods -- case *ast.ArrayType: -- return extractFieldList(t.Elt) -- case *ast.MapType: -- // Map value has a greater chance to be a struct -- if fields := extractFieldList(t.Value); fields != nil { -- return fields -- } -- return extractFieldList(t.Key) -- case *ast.ChanType: -- return extractFieldList(t.Value) -- } -- return nil --} -- -func formatHover(h *HoverJSON, options *Options) (string, error) { - signature := formatSignature(h, options) - @@ -78893,7 +86205,7 @@ diff -urN a/gopls/internal/lsp/source/identifier.go b/gopls/internal/lsp/source/ - -// typeToObject returns the relevant type name for the given type, after -// unwrapping pointers, arrays, slices, channels, and function signatures with --// a single non-error result. +-// a single non-error result, and ignoring built-in named types. -func typeToObject(typ types.Type) *types.TypeName { - switch typ := typ.(type) { - case *types.Named: @@ -78916,7 +86228,7 @@ diff -urN a/gopls/internal/lsp/source/identifier.go b/gopls/internal/lsp/source/ - for i := 0; i < results.Len(); i++ { - obj := typeToObject(results.At(i).Type()) - if obj == nil || hasErrorType(obj) { -- // Skip builtins. +- // Skip builtins. TODO(rfindley): should comparable be handled here as well? - continue - } - if res != nil { @@ -79119,7 +86431,7 @@ diff -urN a/gopls/internal/lsp/source/identifier_test.go b/gopls/internal/lsp/so diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/source/implementation.go --- a/gopls/internal/lsp/source/implementation.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/implementation.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,482 +0,0 @@ +@@ -1,495 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -79139,6 +86451,7 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - "sync" - - "golang.org/x/sync/errgroup" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/lsp/source/methodsets" @@ -79152,7 +86465,6 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou -// -// TODO(adonovan): -// - Audit to ensure robustness in face of type errors. --// - Support 'error' and 'error.Error', which were also lacking from the old implementation. -// - Eliminate false positives due to 'tricky' cases of the global algorithm. -// - Ensure we have test coverage of: -// type aliases @@ -79172,7 +86484,7 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - ctx, done := event.Start(ctx, "source.Implementation") - defer done() - -- locs, err := implementations2(ctx, snapshot, f, pp) +- locs, err := implementations(ctx, snapshot, f, pp) - if err != nil { - return nil, err - } @@ -79192,60 +86504,37 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - return locs, nil -} - --func implementations2(ctx context.Context, snapshot Snapshot, fh FileHandle, pp protocol.Position) ([]protocol.Location, error) { -- -- // Type-check the query package, find the query identifier, -- // and locate the type or method declaration it refers to. -- declPosn, err := typeDeclPosition(ctx, snapshot, fh.URI(), pp) +-func implementations(ctx context.Context, snapshot Snapshot, fh FileHandle, pp protocol.Position) ([]protocol.Location, error) { +- obj, pkg, err := implementsObj(ctx, snapshot, fh.URI(), pp) - if err != nil { - return nil, err - } - -- // Type-check the declaring package (incl. variants) for use -- // by the "local" search, which uses type information to -- // enumerate all types within the package that satisfy the -- // query type, even those defined local to a function. -- declURI := span.URIFromPath(declPosn.Filename) -- declMetas, err := snapshot.MetadataForFile(ctx, declURI) -- if err != nil { -- return nil, err -- } -- if len(declMetas) == 0 { -- return nil, fmt.Errorf("no packages for file %s", declURI) -- } -- ids := make([]PackageID, len(declMetas)) -- for i, m := range declMetas { -- ids[i] = m.ID -- } -- localPkgs, err := snapshot.TypeCheck(ctx, ids...) -- if err != nil { -- return nil, err -- } -- // The narrowest package will do, since the local search is based -- // on position and the global search is based on fingerprint. -- // (Neither is based on object identity.) -- declPkg := localPkgs[0] -- declFile, err := declPkg.File(declURI) -- if err != nil { -- return nil, err // "can't happen" -- } -- -- // Find declaration of corresponding object -- // in this package based on (URI, offset). -- pos, err := safetoken.Pos(declFile.Tok, declPosn.Offset) -- if err != nil { -- return nil, err -- } -- // TODO(adonovan): simplify: use objectsAt? -- path := pathEnclosingObjNode(declFile.File, pos) -- if path == nil { -- return nil, ErrNoIdentFound // checked earlier -- } -- id, ok := path[0].(*ast.Ident) -- if !ok { -- return nil, ErrNoIdentFound // checked earlier +- var localPkgs []Package +- if obj.Pos().IsValid() { // no local package for error or error.Error +- declPosn := safetoken.StartPosition(pkg.FileSet(), obj.Pos()) +- // Type-check the declaring package (incl. variants) for use +- // by the "local" search, which uses type information to +- // enumerate all types within the package that satisfy the +- // query type, even those defined local to a function. +- declURI := span.URIFromPath(declPosn.Filename) +- declMetas, err := snapshot.MetadataForFile(ctx, declURI) +- if err != nil { +- return nil, err +- } +- RemoveIntermediateTestVariants(&declMetas) +- if len(declMetas) == 0 { +- return nil, fmt.Errorf("no packages for file %s", declURI) +- } +- ids := make([]PackageID, len(declMetas)) +- for i, m := range declMetas { +- ids[i] = m.ID +- } +- localPkgs, err = snapshot.TypeCheck(ctx, ids...) +- if err != nil { +- return nil, err +- } - } -- obj := declPkg.GetTypesInfo().ObjectOf(id) // may be nil - - // Is the selected identifier a type name or method? - // (For methods, report the corresponding method names.) @@ -79262,7 +86551,7 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - } - } - if queryType == nil { -- return nil, fmt.Errorf("%s is not a type or method", id.Name) +- return nil, bug.Errorf("%s is not a type or method", obj.Name()) // should have been handled by implementsObj - } - - // Compute the method-set fingerprint used as a key to the global search. @@ -79273,8 +86562,9 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - return nil, nil - } - -- // The global search needs to look at every package in the workspace; -- // see package ./methodsets. +- // The global search needs to look at every package in the +- // forward transitive closure of the workspace; see package +- // ./methodsets. - // - // For now we do all the type checking before beginning the search. - // TODO(adonovan): opt: search in parallel topological order @@ -79285,16 +86575,22 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - if err != nil { - return nil, err - } +- RemoveIntermediateTestVariants(&globalMetas) - globalIDs := make([]PackageID, 0, len(globalMetas)) +- +- var pkgPath PackagePath +- if obj.Pkg() != nil { // nil for error +- pkgPath = PackagePath(obj.Pkg().Path()) +- } - for _, m := range globalMetas { -- if m.PkgPath == declPkg.Metadata().PkgPath { +- if m.PkgPath == pkgPath { - continue // declaring package is handled by local implementation - } - globalIDs = append(globalIDs, m.ID) - } - indexes, err := snapshot.MethodSets(ctx, globalIDs...) - if err != nil { -- return nil, err +- return nil, fmt.Errorf("querying method sets: %v", err) - } - - // Search local and global packages in parallel. @@ -79349,11 +86645,11 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou -// which requires reading the file. -func offsetToLocation(ctx context.Context, snapshot Snapshot, filename string, start, end int) (protocol.Location, error) { - uri := span.URIFromPath(filename) -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return protocol.Location{}, err // cancelled, perhaps - } -- content, err := fh.Read() +- content, err := fh.Content() - if err != nil { - return protocol.Location{}, err // nonexistent or deleted ("can't happen") - } @@ -79361,18 +86657,19 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - return m.OffsetLocation(start, end) -} - --// typeDeclPosition returns the position of the declaration of the --// type (or one of its methods) referred to at (uri, ppos). --func typeDeclPosition(ctx context.Context, snapshot Snapshot, uri span.URI, ppos protocol.Position) (token.Position, error) { -- var noPosn token.Position -- -- pkg, pgf, err := PackageForFile(ctx, snapshot, uri, WidestPackage) +-// implementsObj returns the object to query for implementations, which is a +-// type name or method. +-// +-// The returned Package is the narrowest package containing ppos, which is the +-// package using the resulting obj but not necessarily the declaring package. +-func implementsObj(ctx context.Context, snapshot Snapshot, uri span.URI, ppos protocol.Position) (types.Object, Package, error) { +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, uri) - if err != nil { -- return noPosn, err +- return nil, nil, err - } - pos, err := pgf.PositionPos(ppos) - if err != nil { -- return noPosn, err +- return nil, nil, err - } - - // This function inherits the limitation of its predecessor in @@ -79387,11 +86684,11 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - // TODO(adonovan): simplify: use objectsAt? - path := pathEnclosingObjNode(pgf.File, pos) - if path == nil { -- return noPosn, ErrNoIdentFound +- return nil, nil, ErrNoIdentFound - } - id, ok := path[0].(*ast.Ident) - if !ok { -- return noPosn, ErrNoIdentFound +- return nil, nil, ErrNoIdentFound - } - - // Is the object a type or method? Reject other kinds. @@ -79407,18 +86704,17 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - // ok - case *types.Func: - if obj.Type().(*types.Signature).Recv() == nil { -- return noPosn, fmt.Errorf("%s is a function, not a method", id.Name) +- return nil, nil, fmt.Errorf("%s is a function, not a method", id.Name) - } - case nil: -- return noPosn, fmt.Errorf("%s denotes unknown object", id.Name) +- return nil, nil, fmt.Errorf("%s denotes unknown object", id.Name) - default: - // e.g. *types.Var -> "var". - kind := strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types.")) -- return noPosn, fmt.Errorf("%s is a %s, not a type", id.Name, kind) +- return nil, nil, fmt.Errorf("%s is a %s, not a type", id.Name, kind) - } - -- declPosn := safetoken.StartPosition(pkg.FileSet(), obj.Pos()) -- return declPosn, nil +- return obj, pkg, nil -} - -// localImplementations searches within pkg for declarations of all @@ -79507,9 +86803,38 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - locs = append(locs, loc) - } - +- // Special case: for types that satisfy error, report builtin.go (see #59527). +- if types.Implements(queryType, errorInterfaceType) { +- loc, err := errorLocation(ctx, snapshot) +- if err != nil { +- return nil, err +- } +- locs = append(locs, loc) +- } +- - return locs, nil -} - +-var errorInterfaceType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface) +- +-// errorLocation returns the location of the 'error' type in builtin.go. +-func errorLocation(ctx context.Context, snapshot Snapshot) (protocol.Location, error) { +- pgf, err := snapshot.BuiltinFile(ctx) +- if err != nil { +- return protocol.Location{}, err +- } +- for _, decl := range pgf.File.Decls { +- if decl, ok := decl.(*ast.GenDecl); ok { +- for _, spec := range decl.Specs { +- if spec, ok := spec.(*ast.TypeSpec); ok && spec.Name.Name == "error" { +- return pgf.NodeLocation(spec.Name) +- } +- } +- } +- } +- return protocol.Location{}, fmt.Errorf("built-in error type not found") +-} +- -// concreteImplementsIntf returns true if a is an interface type implemented by -// concrete type b, or vice versa. -func concreteImplementsIntf(a, b types.Type) bool { @@ -79529,7 +86854,7 @@ diff -urN a/gopls/internal/lsp/source/implementation.go b/gopls/internal/lsp/sou - // to report (e.g.) "ArrayList[T] implements List[T]", but - // GenericAssignableTo doesn't work correctly on pointers to - // generic named types. Thus the legacy implementation and the -- // "local" part of implementation2 fail to report generics. +- // "local" part of implementations fail to report generics. - // The global algorithm based on subsets does the right thing. - return types.AssignableTo(a, b) -} @@ -79690,13 +87015,13 @@ diff -urN a/gopls/internal/lsp/source/inlay_hint.go b/gopls/internal/lsp/source/ - ctx, done := event.Start(ctx, "source.InlayHint") - defer done() - -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, fmt.Errorf("getting file for InlayHint: %w", err) - } - - // Collect a list of the inlay hints that are enabled. -- inlayHintOptions := snapshot.View().Options().InlayHintOptions +- inlayHintOptions := snapshot.Options().InlayHintOptions - var enabledHints []InlayHintFunc - for hint, enabled := range inlayHintOptions.Hints { - if !enabled { @@ -79765,7 +87090,7 @@ diff -urN a/gopls/internal/lsp/source/inlay_hint.go b/gopls/internal/lsp/source/ - if param.Name() == "" { - continue - } -- // Skip the parameter name hint if the arg matches the +- // Skip the parameter name hint if the arg matches - // the parameter name. - if i, ok := v.(*ast.Ident); ok && i.Name == param.Name() { - continue @@ -80000,10 +87325,399 @@ diff -urN a/gopls/internal/lsp/source/inlay_hint.go b/gopls/internal/lsp/source/ - } - return []protocol.InlayHintLabelPart{label} -} +diff -urN a/gopls/internal/lsp/source/inline.go b/gopls/internal/lsp/source/inline.go +--- a/gopls/internal/lsp/source/inline.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/inline.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,113 +0,0 @@ +-// Copyright 2023 The Go Authors. 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 +- +-// This file defines the refactor.inline code action. +- +-import ( +- "context" +- "fmt" +- "go/ast" +- "go/token" +- "go/types" +- +- "golang.org/x/tools/go/analysis" +- "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/go/types/typeutil" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/diff" +- "golang.org/x/tools/internal/refactor/inline" +-) +- +-// EnclosingStaticCall returns the innermost function call enclosing +-// the selected range, along with the callee. +-func EnclosingStaticCall(pkg Package, pgf *ParsedGoFile, rng protocol.Range) (*ast.CallExpr, *types.Func, error) { +- start, end, err := pgf.RangePos(rng) +- if err != nil { +- return nil, nil, err +- } +- path, _ := astutil.PathEnclosingInterval(pgf.File, start, end) +- +- var call *ast.CallExpr +-loop: +- for _, n := range path { +- switch n := n.(type) { +- case *ast.FuncLit: +- break loop +- case *ast.CallExpr: +- call = n +- break loop +- } +- } +- if call == nil { +- return nil, nil, fmt.Errorf("no enclosing call") +- } +- if safetoken.Line(pgf.Tok, call.Lparen) != safetoken.Line(pgf.Tok, start) { +- return nil, nil, fmt.Errorf("enclosing call is not on this line") +- } +- fn := typeutil.StaticCallee(pkg.GetTypesInfo(), call) +- if fn == nil { +- return nil, nil, fmt.Errorf("not a static call to a Go function") +- } +- return call, fn, nil +-} +- +-func inlineCall(ctx context.Context, snapshot Snapshot, fh FileHandle, rng protocol.Range) (*token.FileSet, *analysis.SuggestedFix, error) { +- // Find enclosing static call. +- callerPkg, callerPGF, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) +- if err != nil { +- return nil, nil, err +- } +- call, fn, err := EnclosingStaticCall(callerPkg, callerPGF, rng) +- if err != nil { +- return nil, nil, err +- } +- +- // Locate callee by file/line and analyze it. +- calleePosn := safetoken.StartPosition(callerPkg.FileSet(), fn.Pos()) +- calleePkg, calleePGF, err := NarrowestPackageForFile(ctx, snapshot, span.URIFromPath(calleePosn.Filename)) +- if err != nil { +- return nil, nil, err +- } +- var calleeDecl *ast.FuncDecl +- for _, decl := range calleePGF.File.Decls { +- if decl, ok := decl.(*ast.FuncDecl); ok { +- posn := safetoken.StartPosition(calleePkg.FileSet(), decl.Name.Pos()) +- if posn.Line == calleePosn.Line && posn.Column == calleePosn.Column { +- calleeDecl = decl +- break +- } +- } +- } +- if calleeDecl == nil { +- return nil, nil, fmt.Errorf("can't find callee") +- } +- callee, err := inline.AnalyzeCallee(calleePkg.FileSet(), calleePkg.GetTypes(), calleePkg.GetTypesInfo(), calleeDecl, calleePGF.Src) +- if err != nil { +- return nil, nil, err +- } +- +- // Inline the call. +- caller := &inline.Caller{ +- Fset: callerPkg.FileSet(), +- Types: callerPkg.GetTypes(), +- Info: callerPkg.GetTypesInfo(), +- File: callerPGF.File, +- Call: call, +- Content: callerPGF.Src, +- } +- got, err := inline.Inline(caller, callee) +- if err != nil { +- return nil, nil, err +- } +- +- // Suggest the fix. +- return callerPkg.FileSet(), &analysis.SuggestedFix{ +- Message: fmt.Sprintf("inline call of %v", callee), +- TextEdits: diffToTextEdits(callerPGF.Tok, diff.Bytes(callerPGF.Src, got)), +- }, nil +-} +diff -urN a/gopls/internal/lsp/source/invertifcondition.go b/gopls/internal/lsp/source/invertifcondition.go +--- a/gopls/internal/lsp/source/invertifcondition.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/invertifcondition.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,268 +0,0 @@ +-// Copyright 2023 The Go Authors. 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 ( +- "fmt" +- "go/ast" +- "go/token" +- "go/types" +- "strings" +- +- "golang.org/x/tools/go/analysis" +- "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +- "golang.org/x/tools/internal/typeparams" +-) +- +-// invertIfCondition is a singleFileFixFunc that inverts an if/else statement +-func invertIfCondition(fset *token.FileSet, start, end token.Pos, src []byte, file *ast.File, _ *types.Package, _ *types.Info) (*analysis.SuggestedFix, error) { +- ifStatement, _, err := CanInvertIfCondition(file, start, end) +- if err != nil { +- return nil, err +- } +- +- var replaceElse analysis.TextEdit +- +- endsWithReturn, err := endsWithReturn(ifStatement.Else) +- if err != nil { +- return nil, err +- } +- +- if endsWithReturn { +- // Replace the whole else part with an empty line and an unindented +- // version of the original if body +- sourcePos := safetoken.StartPosition(fset, ifStatement.Pos()) +- +- indent := sourcePos.Column - 1 +- if indent < 0 { +- indent = 0 +- } +- +- standaloneBodyText := ifBodyToStandaloneCode(fset, ifStatement.Body, src) +- replaceElse = analysis.TextEdit{ +- Pos: ifStatement.Body.Rbrace + 1, // 1 == len("}") +- End: ifStatement.End(), +- NewText: []byte("\n\n" + strings.Repeat("\t", indent) + standaloneBodyText), +- } +- } else { +- // Replace the else body text with the if body text +- bodyStart := safetoken.StartPosition(fset, ifStatement.Body.Lbrace) +- bodyEnd := safetoken.EndPosition(fset, ifStatement.Body.Rbrace+1) // 1 == len("}") +- bodyText := src[bodyStart.Offset:bodyEnd.Offset] +- replaceElse = analysis.TextEdit{ +- Pos: ifStatement.Else.Pos(), +- End: ifStatement.Else.End(), +- NewText: bodyText, +- } +- } +- +- // Replace the if text with the else text +- elsePosInSource := safetoken.StartPosition(fset, ifStatement.Else.Pos()) +- elseEndInSource := safetoken.EndPosition(fset, ifStatement.Else.End()) +- elseText := src[elsePosInSource.Offset:elseEndInSource.Offset] +- replaceBodyWithElse := analysis.TextEdit{ +- Pos: ifStatement.Body.Pos(), +- End: ifStatement.Body.End(), +- NewText: elseText, +- } +- +- // Replace the if condition with its inverse +- inverseCondition, err := invertCondition(fset, ifStatement.Cond, src) +- if err != nil { +- return nil, err +- } +- replaceConditionWithInverse := analysis.TextEdit{ +- Pos: ifStatement.Cond.Pos(), +- End: ifStatement.Cond.End(), +- NewText: inverseCondition, +- } +- +- // Return a SuggestedFix with just that TextEdit in there +- return &analysis.SuggestedFix{ +- TextEdits: []analysis.TextEdit{ +- replaceConditionWithInverse, +- replaceBodyWithElse, +- replaceElse, +- }, +- }, nil +-} +- +-func endsWithReturn(elseBranch ast.Stmt) (bool, error) { +- elseBlock, isBlockStatement := elseBranch.(*ast.BlockStmt) +- if !isBlockStatement { +- return false, fmt.Errorf("Unable to figure out whether this ends with return: %T", elseBranch) +- } +- +- if len(elseBlock.List) == 0 { +- // Empty blocks don't end in returns +- return false, nil +- } +- +- lastStatement := elseBlock.List[len(elseBlock.List)-1] +- +- _, lastStatementIsReturn := lastStatement.(*ast.ReturnStmt) +- return lastStatementIsReturn, nil +-} +- +-// Turn { fmt.Println("Hello") } into just fmt.Println("Hello"), with one less +-// level of indentation. +-// +-// The first line of the result will not be indented, but all of the following +-// lines will. +-func ifBodyToStandaloneCode(fset *token.FileSet, ifBody *ast.BlockStmt, src []byte) string { +- // Get the whole body (without the surrounding braces) as a string +- bodyStart := safetoken.StartPosition(fset, ifBody.Lbrace+1) // 1 == len("}") +- bodyEnd := safetoken.EndPosition(fset, ifBody.Rbrace) +- bodyWithoutBraces := string(src[bodyStart.Offset:bodyEnd.Offset]) +- bodyWithoutBraces = strings.TrimSpace(bodyWithoutBraces) +- +- // Unindent +- bodyWithoutBraces = strings.ReplaceAll(bodyWithoutBraces, "\n\t", "\n") +- +- return bodyWithoutBraces +-} +- +-func invertCondition(fset *token.FileSet, cond ast.Expr, src []byte) ([]byte, error) { +- condStart := safetoken.StartPosition(fset, cond.Pos()) +- condEnd := safetoken.EndPosition(fset, cond.End()) +- oldText := string(src[condStart.Offset:condEnd.Offset]) +- +- switch expr := cond.(type) { +- case *ast.Ident, *ast.ParenExpr, *ast.CallExpr, *ast.StarExpr, *ast.IndexExpr, *typeparams.IndexListExpr, *ast.SelectorExpr: +- newText := "!" + oldText +- if oldText == "true" { +- newText = "false" +- } else if oldText == "false" { +- newText = "true" +- } +- +- return []byte(newText), nil +- +- case *ast.UnaryExpr: +- if expr.Op != token.NOT { +- // This should never happen +- return dumbInvert(fset, cond, src), nil +- } +- +- inverse := expr.X +- if p, isParen := inverse.(*ast.ParenExpr); isParen { +- // We got !(x), remove the parentheses with the ! so we get just "x" +- inverse = p.X +- +- start := safetoken.StartPosition(fset, inverse.Pos()) +- end := safetoken.EndPosition(fset, inverse.End()) +- if start.Line != end.Line { +- // The expression is multi-line, so we can't remove the parentheses +- inverse = expr.X +- } +- } +- +- start := safetoken.StartPosition(fset, inverse.Pos()) +- end := safetoken.EndPosition(fset, inverse.End()) +- textWithoutNot := src[start.Offset:end.Offset] +- +- return textWithoutNot, nil +- +- case *ast.BinaryExpr: +- // These inversions are unsound for floating point NaN, but that's ok. +- negations := map[token.Token]string{ +- token.EQL: "!=", +- token.LSS: ">=", +- token.GTR: "<=", +- token.NEQ: "==", +- token.LEQ: ">", +- token.GEQ: "<", +- } +- +- negation, negationFound := negations[expr.Op] +- if !negationFound { +- return invertAndOr(fset, expr, src) +- } +- +- xPosInSource := safetoken.StartPosition(fset, expr.X.Pos()) +- opPosInSource := safetoken.StartPosition(fset, expr.OpPos) +- yPosInSource := safetoken.StartPosition(fset, expr.Y.Pos()) +- +- textBeforeOp := string(src[xPosInSource.Offset:opPosInSource.Offset]) +- +- oldOpWithTrailingWhitespace := string(src[opPosInSource.Offset:yPosInSource.Offset]) +- newOpWithTrailingWhitespace := negation + oldOpWithTrailingWhitespace[len(expr.Op.String()):] +- +- textAfterOp := string(src[yPosInSource.Offset:condEnd.Offset]) +- +- return []byte(textBeforeOp + newOpWithTrailingWhitespace + textAfterOp), nil +- } +- +- return dumbInvert(fset, cond, src), nil +-} +- +-// dumbInvert is a fallback, inverting cond into !(cond). +-func dumbInvert(fset *token.FileSet, expr ast.Expr, src []byte) []byte { +- start := safetoken.StartPosition(fset, expr.Pos()) +- end := safetoken.EndPosition(fset, expr.End()) +- text := string(src[start.Offset:end.Offset]) +- return []byte("!(" + text + ")") +-} +- +-func invertAndOr(fset *token.FileSet, expr *ast.BinaryExpr, src []byte) ([]byte, error) { +- if expr.Op != token.LAND && expr.Op != token.LOR { +- // Neither AND nor OR, don't know how to invert this +- return dumbInvert(fset, expr, src), nil +- } +- +- oppositeOp := "&&" +- if expr.Op == token.LAND { +- oppositeOp = "||" +- } +- +- xEndInSource := safetoken.EndPosition(fset, expr.X.End()) +- opPosInSource := safetoken.StartPosition(fset, expr.OpPos) +- whitespaceAfterBefore := src[xEndInSource.Offset:opPosInSource.Offset] +- +- invertedBefore, err := invertCondition(fset, expr.X, src) +- if err != nil { +- return nil, err +- } +- +- invertedAfter, err := invertCondition(fset, expr.Y, src) +- if err != nil { +- return nil, err +- } +- +- yPosInSource := safetoken.StartPosition(fset, expr.Y.Pos()) +- +- oldOpWithTrailingWhitespace := string(src[opPosInSource.Offset:yPosInSource.Offset]) +- newOpWithTrailingWhitespace := oppositeOp + oldOpWithTrailingWhitespace[len(expr.Op.String()):] +- +- return []byte(string(invertedBefore) + string(whitespaceAfterBefore) + newOpWithTrailingWhitespace + string(invertedAfter)), nil +-} +- +-// CanInvertIfCondition reports whether we can do invert-if-condition on the +-// code in the given range +-func CanInvertIfCondition(file *ast.File, start, end token.Pos) (*ast.IfStmt, bool, error) { +- path, _ := astutil.PathEnclosingInterval(file, start, end) +- for _, node := range path { +- stmt, isIfStatement := node.(*ast.IfStmt) +- if !isIfStatement { +- continue +- } +- +- if stmt.Else == nil { +- // Can't invert conditions without else clauses +- return nil, false, fmt.Errorf("else clause required") +- } +- +- if _, hasElseIf := stmt.Else.(*ast.IfStmt); hasElseIf { +- // Can't invert conditions with else-if clauses, unclear what that +- // would look like +- return nil, false, fmt.Errorf("else-if not supported") +- } +- +- return stmt, true, nil +- } +- +- return nil, false, fmt.Errorf("not an if statement") +-} diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/source/known_packages.go --- a/gopls/internal/lsp/source/known_packages.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/known_packages.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,140 +0,0 @@ +@@ -1,134 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -80012,7 +87726,6 @@ diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/sou - -import ( - "context" -- "fmt" - "go/parser" - "go/token" - "sort" @@ -80034,19 +87747,14 @@ diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/sou - // This algorithm is expressed in terms of Metadata, not Packages, - // so it doesn't cause or wait for type checking. - -- // Find a Metadata containing the file. -- metas, err := snapshot.MetadataForFile(ctx, fh.URI()) +- current, err := NarrowestMetadataForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err // e.g. context cancelled - } -- if len(metas) == 0 { -- return nil, fmt.Errorf("no loaded package contain file %s", fh.URI()) -- } -- current := metas[0] // pick one arbitrarily (they should all have the same package path) - - // Parse the file's imports so we can compute which - // PackagePaths are imported by this specific file. -- src, err := fh.Read() +- src, err := fh.Content() - if err != nil { - return nil, err - } @@ -80063,7 +87771,7 @@ diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/sou - } - } - -- // Now find candidates among known packages. +- // Now find candidates among all known packages. - knownPkgs, err := snapshot.AllMetadata(ctx) - if err != nil { - return nil, err @@ -80097,7 +87805,7 @@ diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/sou - } - - // Augment the set by invoking the goimports algorithm. -- if err := snapshot.RunProcessEnvFunc(ctx, func(o *imports.Options) error { +- if err := snapshot.RunProcessEnvFunc(ctx, func(ctx context.Context, o *imports.Options) error { - ctx, cancel := context.WithTimeout(ctx, time.Millisecond*80) - defer cancel() - var seenMu sync.Mutex @@ -80147,7 +87855,7 @@ diff -urN a/gopls/internal/lsp/source/known_packages.go b/gopls/internal/lsp/sou diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/linkname.go --- a/gopls/internal/lsp/source/linkname.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/linkname.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,136 +0,0 @@ +@@ -1,156 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -80173,65 +87881,88 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li - -// LinknameDefinition finds the definition of the linkname directive in fh at pos. -// If there is no linkname directive at pos, returns ErrNoLinkname. --func LinknameDefinition(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position) ([]protocol.Location, error) { -- pkgPath, name := parseLinkname(ctx, snapshot, fh, pos) +-func LinknameDefinition(ctx context.Context, snapshot Snapshot, fh FileHandle, from protocol.Position) ([]protocol.Location, error) { +- pkgPath, name, _ := parseLinkname(ctx, snapshot, fh, from) - if pkgPath == "" { - return nil, ErrNoLinkname - } -- return findLinkname(ctx, snapshot, fh, pos, PackagePath(pkgPath), name) +- +- _, pgf, pos, err := findLinkname(ctx, snapshot, PackagePath(pkgPath), name) +- if err != nil { +- return nil, fmt.Errorf("find linkname: %w", err) +- } +- loc, err := pgf.PosLocation(pos, pos+token.Pos(len(name))) +- if err != nil { +- return nil, fmt.Errorf("location of linkname: %w", err) +- } +- return []protocol.Location{loc}, nil -} - -// parseLinkname attempts to parse a go:linkname declaration at the given pos. --// If successful, it returns the package path and object name referenced by the second --// argument of the linkname directive. --// --// If the position is not in the second argument of a go:linkname directive, or parsing fails, it returns "", "". --func parseLinkname(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position) (pkgPath, name string) { +-// If successful, it returns +-// - package path referenced +-// - object name referenced +-// - byte offset in fh of the start of the link target +-// of the linkname directives 2nd argument. +-// +-// If the position is not in the second argument of a go:linkname directive, +-// or parsing fails, it returns "", "", 0. +-func parseLinkname(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position) (pkgPath, name string, targetOffset int) { +- // TODO(adonovan): opt: parsing isn't necessary here. +- // We're only looking for a line comment. - pgf, err := snapshot.ParseGo(ctx, fh, ParseFull) - if err != nil { -- return "", "" +- return "", "", 0 - } - -- span, err := pgf.Mapper.PositionPoint(pos) +- offset, err := pgf.Mapper.PositionOffset(pos) - if err != nil { -- return "", "" +- return "", "", 0 - } -- atLine := span.Line() -- atColumn := span.Column() - - // Looking for pkgpath in '//go:linkname f pkgpath.g'. - // (We ignore 1-arg linkname directives.) -- directive, column := findLinknameOnLine(pgf, atLine) +- directive, end := findLinknameAtOffset(pgf, offset) - parts := strings.Fields(directive) - if len(parts) != 3 { -- return "", "" +- return "", "", 0 - } - - // Inside 2nd arg [start, end]? -- end := column + len(directive) +- // (Assumes no trailing spaces.) - start := end - len(parts[2]) -- if !(start <= atColumn && atColumn <= end) { -- return "", "" +- if !(start <= offset && offset <= end) { +- return "", "", 0 - } - linkname := parts[2] - - // Split the pkg path from the name. - dot := strings.LastIndexByte(linkname, '.') - if dot < 0 { -- return "", "" +- return "", "", 0 - } -- return linkname[:dot], linkname[dot+1:] +- +- return linkname[:dot], linkname[dot+1:], start -} - --// findLinknameOnLine returns the first linkname directive on line and the column it starts at. --// Returns "", 0 if no linkname directive is found on the line. --func findLinknameOnLine(pgf *ParsedGoFile, line int) (string, int) { +-// findLinknameAtOffset returns the first linkname directive on line and its end offset. +-// Returns "", 0 if the offset is not in a linkname directive. +-func findLinknameAtOffset(pgf *ParsedGoFile, offset int) (string, int) { - for _, grp := range pgf.File.Comments { - for _, com := range grp.List { - if strings.HasPrefix(com.Text, "//go:linkname") { - p := safetoken.Position(pgf.Tok, com.Pos()) -- if p.Line == line { -- return com.Text, p.Column +- +- // Sometimes source code (typically tests) has another +- // comment after the directive, trim that away. +- text := com.Text +- if i := strings.LastIndex(text, "//"); i != 0 { +- text = strings.TrimSpace(text[:i]) +- } +- +- end := p.Offset + len(text) +- if p.Offset <= offset && offset < end { +- return text, end - } - } - } @@ -80241,16 +87972,16 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li - -// findLinkname searches dependencies of packages containing fh for an object -// with linker name matching the given package path and name. --func findLinkname(ctx context.Context, snapshot Snapshot, fh FileHandle, pos protocol.Position, pkgPath PackagePath, name string) ([]protocol.Location, error) { +-func findLinkname(ctx context.Context, snapshot Snapshot, pkgPath PackagePath, name string) (Package, *ParsedGoFile, token.Pos, error) { - // Typically the linkname refers to a forward dependency - // or a reverse dependency, but in general it may refer -- // to any package in the workspace. +- // to any package that is linked with this one. - var pkgMeta *Metadata - metas, err := snapshot.AllMetadata(ctx) - if err != nil { -- return nil, err +- return nil, nil, token.NoPos, err - } -- metas = RemoveIntermediateTestVariants(metas) +- RemoveIntermediateTestVariants(&metas) - for _, meta := range metas { - if meta.PkgPath == pkgPath { - pkgMeta = meta @@ -80258,36 +87989,33 @@ diff -urN a/gopls/internal/lsp/source/linkname.go b/gopls/internal/lsp/source/li - } - } - if pkgMeta == nil { -- return nil, fmt.Errorf("cannot find package %q", pkgPath) +- return nil, nil, token.NoPos, fmt.Errorf("cannot find package %q", pkgPath) - } - - // When found, type check the desired package (snapshot.TypeCheck in TypecheckFull mode), - pkgs, err := snapshot.TypeCheck(ctx, pkgMeta.ID) - if err != nil { -- return nil, err +- return nil, nil, token.NoPos, err - } - pkg := pkgs[0] - - obj := pkg.GetTypes().Scope().Lookup(name) - if obj == nil { -- return nil, fmt.Errorf("package %q does not define %s", pkgPath, name) +- return nil, nil, token.NoPos, fmt.Errorf("package %q does not define %s", pkgPath, name) - } - - objURI := safetoken.StartPosition(pkg.FileSet(), obj.Pos()) - pgf, err := pkg.File(span.URIFromPath(objURI.Filename)) - if err != nil { -- return nil, err +- return nil, nil, token.NoPos, err - } -- loc, err := pgf.PosLocation(obj.Pos(), obj.Pos()+token.Pos(len(name))) -- if err != nil { -- return nil, err -- } -- return []protocol.Location{loc}, nil +- +- return pkg, pgf, obj.Pos(), nil -} diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/lsp/source/methodsets/methodsets.go --- a/gopls/internal/lsp/source/methodsets/methodsets.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/methodsets/methodsets.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,508 +0,0 @@ +@@ -1,490 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -80299,7 +88027,7 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ -// This package provides only the "global" (all workspace) search; the -// "local" search within a given package uses a different -// implementation based on type-checker data structures for a single --// package plus variants; see ../implementation2.go. +-// package plus variants; see ../implementation.go. -// The local algorithm is more precise as it tests function-local types too. -// -// A global index of function-local types is challenging since they @@ -80334,20 +88062,17 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ -// single 64-bit mask is quite effective. See CL 452060 for details. - -import ( -- "bytes" -- "encoding/gob" - "fmt" - "go/token" - "go/types" - "hash/crc32" -- "log" - "strconv" - "strings" - - "golang.org/x/tools/go/types/objectpath" +- "golang.org/x/tools/gopls/internal/lsp/frob" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/internal/typeparams" -- "golang.org/x/tools/internal/typesinternal" -) - -// An Index records the non-empty method sets of all package-level @@ -80360,27 +88085,13 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ -// Decode decodes the given gob-encoded data as an Index. -func Decode(data []byte) *Index { - var pkg gobPackage -- mustDecode(data, &pkg) +- packageCodec.Decode(data, &pkg) - return &Index{pkg} -} - -// Encode encodes the receiver as gob-encoded data. -func (index *Index) Encode() []byte { -- return mustEncode(index.pkg) --} -- --func mustEncode(x interface{}) []byte { -- var buf bytes.Buffer -- if err := gob.NewEncoder(&buf).Encode(x); err != nil { -- log.Fatalf("internal error encoding %T: %v", x, err) -- } -- return buf.Bytes() --} -- --func mustDecode(data []byte, ptr interface{}) { -- if err := gob.NewDecoder(bytes.NewReader(data)).Decode(ptr); err != nil { -- log.Fatalf("internal error decoding %T: %v", ptr, err) -- } +- return packageCodec.Encode(index.pkg) -} - -// NewIndex returns a new index of method-set information for all @@ -80522,7 +88233,7 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ - return gobPosition{b.string(posn.Filename), posn.Offset, len(obj.Name())} - } - -- objectpathFor := typesinternal.NewObjectpathFunc() +- objectpathFor := new(objectpath.Encoder).For - - // setindexInfo sets the (Posn, PkgPath, ObjectPath) fields for each method declaration. - setIndexInfo := func(m *gobMethod, method *types.Func) { @@ -80642,8 +88353,8 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ - if tname.Pkg() != nil { - buf.WriteString(strconv.Quote(tname.Pkg().Path())) - buf.WriteByte('.') -- } else if tname.Name() != "error" { -- panic(tname) // error is the only named type with no package +- } else if tname.Name() != "error" && tname.Name() != "comparable" { +- panic(tname) // error and comparable the only named types with no package - } - buf.WriteString(tname.Name()) - @@ -80761,9 +88472,8 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ - -// -- serial format of index -- - --// The cost of gob encoding and decoding for most packages in x/tools --// is under 50us, with occasional peaks of around 1-3ms. --// The encoded indexes are around 1KB-50KB. +-// (The name says gob but in fact we use frob.) +-var packageCodec = frob.CodecFor[gobPackage]() - -// A gobPackage records the method set of each package-level type for a single package. -type gobPackage struct { @@ -80799,7 +88509,7 @@ diff -urN a/gopls/internal/lsp/source/methodsets/methodsets.go b/gopls/internal/ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/options.go --- a/gopls/internal/lsp/source/options.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/options.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1631 +0,0 @@ +@@ -1,1762 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -80828,6 +88538,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - "golang.org/x/tools/go/analysis/passes/composite" - "golang.org/x/tools/go/analysis/passes/copylock" - "golang.org/x/tools/go/analysis/passes/deepequalerrors" +- "golang.org/x/tools/go/analysis/passes/defers" - "golang.org/x/tools/go/analysis/passes/directive" - "golang.org/x/tools/go/analysis/passes/errorsas" - "golang.org/x/tools/go/analysis/passes/fieldalignment" @@ -80840,6 +88551,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - "golang.org/x/tools/go/analysis/passes/printf" - "golang.org/x/tools/go/analysis/passes/shadow" - "golang.org/x/tools/go/analysis/passes/shift" +- "golang.org/x/tools/go/analysis/passes/slog" - "golang.org/x/tools/go/analysis/passes/sortslice" - "golang.org/x/tools/go/analysis/passes/stdmethods" - "golang.org/x/tools/go/analysis/passes/stringintconv" @@ -80852,6 +88564,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - "golang.org/x/tools/go/analysis/passes/unsafeptr" - "golang.org/x/tools/go/analysis/passes/unusedresult" - "golang.org/x/tools/go/analysis/passes/unusedwrite" +- "golang.org/x/tools/gopls/internal/lsp/analysis/deprecated" - "golang.org/x/tools/gopls/internal/lsp/analysis/embeddirective" - "golang.org/x/tools/gopls/internal/lsp/analysis/fillreturns" - "golang.org/x/tools/gopls/internal/lsp/analysis/fillstruct" @@ -80904,6 +88617,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - protocol.SourceOrganizeImports: true, - protocol.QuickFix: true, - protocol.RefactorRewrite: true, +- protocol.RefactorInline: true, - protocol.RefactorExtract: true, - }, - Mod: { @@ -80926,14 +88640,15 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - }, - UIOptions: UIOptions{ - DiagnosticOptions: DiagnosticOptions{ -- DiagnosticsDelay: 250 * time.Millisecond, - Annotations: map[Annotation]bool{ - Bounds: true, - Escape: true, - Inline: true, - Nil: true, - }, -- Vulncheck: ModeVulncheckOff, +- Vulncheck: ModeVulncheckOff, +- DiagnosticsDelay: 1 * time.Second, +- AnalysisProgressReporting: true, - }, - InlayHintOptions: InlayHintOptions{}, - DocumentationOptions: DocumentationOptions{ @@ -80945,6 +88660,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - ImportShortcut: BothShortcuts, - SymbolMatcher: SymbolFastFuzzy, - SymbolStyle: DynamicSymbols, +- SymbolScope: AllSymbolScope, - }, - CompletionOptions: CompletionOptions{ - Matcher: Fuzzy, @@ -80963,13 +88679,15 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - }, - }, - InternalOptions: InternalOptions{ -- LiteralCompletions: true, -- TempModfile: true, -- CompleteUnimported: true, -- CompletionDocumentation: true, -- DeepCompletion: true, -- ChattyDiagnostics: true, -- NewDiff: "both", +- LiteralCompletions: true, +- TempModfile: true, +- CompleteUnimported: true, +- CompletionDocumentation: true, +- DeepCompletion: true, +- ChattyDiagnostics: true, +- NewDiff: "new", +- SubdirWatchPatterns: SubdirWatchPatternsAuto, +- ReportAnalysisProgressAfter: 5 * time.Second, - }, - Hooks: Hooks{ - // TODO(adonovan): switch to new diff.Strings implementation. @@ -80996,9 +88714,26 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - Hooks -} - +-// IsAnalyzerEnabled reports whether an analyzer with the given name is +-// enabled. +-// +-// TODO(rfindley): refactor to simplify this function. We no longer need the +-// different categories of analyzer. +-func (opts *Options) IsAnalyzerEnabled(name string) bool { +- for _, amap := range []map[string]*Analyzer{opts.DefaultAnalyzers, opts.TypeErrorAnalyzers, opts.ConvenienceAnalyzers, opts.StaticcheckAnalyzers} { +- for _, analyzer := range amap { +- if analyzer.Analyzer.Name == name && analyzer.IsEnabled(opts) { +- return true +- } +- } +- } +- return false +-} +- -// ClientOptions holds LSP-specific configuration that is provided by the -// client. -type ClientOptions struct { +- ClientInfo *protocol.Msg_XInitializeParams_clientInfo - InsertTextFormat protocol.InsertTextFormat - ConfigurationSupported bool - DynamicConfigurationSupported bool @@ -81227,6 +88962,17 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - // - // This option must be set to a valid duration string, for example `"250ms"`. - DiagnosticsDelay time.Duration `status:"advanced"` +- +- // AnalysisProgressReporting controls whether gopls sends progress +- // notifications when construction of its index of analysis facts is taking a +- // long time. Cancelling these notifications will cancel the indexing task, +- // though it will restart after the next change in the workspace. +- // +- // When a package is opened for the first time and heavyweight analyses such as +- // staticcheck are enabled, it can take a while to construct the index of +- // analysis facts for all its dependencies. The index is cached in the +- // filesystem, so subsequent analysis should be faster. +- AnalysisProgressReporting bool -} - -type InlayHintOptions struct { @@ -81256,6 +89002,13 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - // } - // ``` - SymbolStyle SymbolStyle `status:"advanced"` +- +- // SymbolScope controls which packages are searched for workspace/symbol +- // requests. The default value, "workspace", searches only workspace +- // packages. The legacy behavior, "all", causes all loaded packages to be +- // searched, including dependencies; this is more expensive and may return +- // unwanted results. +- SymbolScope SymbolScope -} - -// UserOptions holds custom Gopls configuration (not part of the LSP) that is @@ -81330,6 +89083,9 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt -// average user. These may be settings used by tests or outdated settings that -// will soon be deprecated. Some of these settings may not even be configurable -// by the user. +-// +-// TODO(rfindley): even though these settings are not intended for +-// modification, some of them should be surfaced in our documentation. -type InternalOptions struct { - // LiteralCompletions controls whether literal candidates such as - // "&someStruct{}" are offered. Tests disable this flag to simplify @@ -81393,8 +89149,48 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - // file change. If unset, gopls only reports diagnostics when they change, or - // when a file is opened or closed. - ChattyDiagnostics bool +- +- // SubdirWatchPatterns configures the file watching glob patterns registered +- // by gopls. +- // +- // Some clients (namely VS Code) do not send workspace/didChangeWatchedFile +- // notifications for files contained in a directory when that directory is +- // deleted: +- // https://github.com/microsoft/vscode/issues/109754 +- // +- // In this case, gopls would miss important notifications about deleted +- // packages. To work around this, gopls registers a watch pattern for each +- // directory containing Go files. +- // +- // Unfortunately, other clients experience performance problems with this +- // many watch patterns, so there is no single behavior that works well for +- // all clients. +- // +- // The "subdirWatchPatterns" setting allows configuring this behavior. Its +- // default value of "auto" attempts to guess the correct behavior based on +- // the client name. We'd love to avoid this specialization, but as described +- // above there is no single value that works for all clients. +- // +- // If any LSP client does not behave well with the default value (for +- // example, if like VS Code it drops file notifications), please file an +- // issue. +- SubdirWatchPatterns SubdirWatchPatterns +- +- // ReportAnalysisProgressAfter sets the duration for gopls to wait before starting +- // progress reporting for ongoing go/analysis passes. +- // +- // It is intended to be used for testing only. +- ReportAnalysisProgressAfter time.Duration -} - +-type SubdirWatchPatterns string +- +-const ( +- SubdirWatchPatternsOn SubdirWatchPatterns = "on" +- SubdirWatchPatternsOff SubdirWatchPatterns = "off" +- SubdirWatchPatternsAuto SubdirWatchPatterns = "auto" +-) +- -type ImportShortcut string - -const ( @@ -81419,6 +89215,8 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - CaseSensitive Matcher = "CaseSensitive" -) - +-// A SymbolMatcher controls the matching of symbols for workspace/symbol +-// requests. -type SymbolMatcher string - -const ( @@ -81428,6 +89226,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - SymbolCaseSensitive SymbolMatcher = "CaseSensitive" -) - +-// A SymbolStyle controls the formatting of symbols in workspace/symbol results. -type SymbolStyle string - -const ( @@ -81444,6 +89243,17 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - DynamicSymbols SymbolStyle = "Dynamic" -) - +-// A SymbolScope controls the search scope for workspace/symbol requests. +-type SymbolScope string +- +-const ( +- // WorkspaceSymbolScope matches symbols in workspace packages only. +- WorkspaceSymbolScope SymbolScope = "workspace" +- // AllSymbolScope matches symbols in any loaded package, including +- // dependencies. +- AllSymbolScope SymbolScope = "all" +-) +- -type HoverKind string - -const ( @@ -81522,7 +89332,8 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - return results -} - --func (o *Options) ForClientCapabilities(caps protocol.ClientCapabilities) { +-func (o *Options) ForClientCapabilities(clientName *protocol.Msg_XInitializeParams_clientInfo, caps protocol.ClientCapabilities) { +- o.ClientInfo = clientName - // Check if the client supports snippets in completion items. - if caps.Workspace.WorkspaceEdit != nil { - o.SupportedResourceOperations = caps.Workspace.WorkspaceEdit.ResourceOperations @@ -81771,6 +89582,14 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - o.SymbolStyle = SymbolStyle(s) - } - +- case "symbolScope": +- if s, ok := result.asOneOf( +- string(WorkspaceSymbolScope), +- string(AllSymbolScope), +- ); ok { +- o.SymbolScope = SymbolScope(s) +- } +- - case "hoverKind": - if s, ok := result.asOneOf( - string(NoDocumentation), @@ -81903,6 +89722,9 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - case "diagnosticsDelay": - result.setDuration(&o.DiagnosticsDelay) - +- case "analysisProgressReporting": +- result.setBool(&o.AnalysisProgressReporting) +- - case "experimentalWatchedFileDelay": - result.deprecated("") - @@ -81931,6 +89753,18 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - case "chattyDiagnostics": - result.setBool(&o.ChattyDiagnostics) - +- case "subdirWatchPatterns": +- if s, ok := result.asOneOf( +- string(SubdirWatchPatternsOn), +- string(SubdirWatchPatternsOff), +- string(SubdirWatchPatternsAuto), +- ); ok { +- o.SubdirWatchPatterns = SubdirWatchPatterns(s) +- } +- +- case "reportAnalysisProgressAfter": +- result.setDuration(&o.ReportAnalysisProgressAfter) +- - // Replaced settings. - case "experimentalDisabledAnalyses": - result.deprecated("analyses") @@ -81990,14 +89824,6 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - return e.msg -} - --// softErrorf reports an error that does not affect the functionality of gopls --// (a warning in the UI). --// The formatted message will be shown to the user unmodified. --func (r *OptionResult) softErrorf(format string, values ...interface{}) { -- msg := fmt.Sprintf(format, values...) -- r.Error = &SoftError{msg} --} -- -// deprecated reports the current setting as deprecated. If 'replacement' is -// non-nil, it is suggested to the user. -func (r *OptionResult) deprecated(replacement string) { @@ -82166,7 +89992,8 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt -func typeErrorAnalyzers() map[string]*Analyzer { - return map[string]*Analyzer{ - fillreturns.Analyzer.Name: { -- Analyzer: fillreturns.Analyzer, +- Analyzer: fillreturns.Analyzer, +- // TODO(rfindley): is SourceFixAll even necessary here? Is that not implied? - ActionKind: []protocol.CodeActionKind{protocol.SourceFixAll, protocol.QuickFix}, - Enabled: true, - }, @@ -82190,6 +90017,8 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - } -} - +-// TODO(golang/go#61559): remove convenience analyzers now that they are not +-// used from the analysis framework. -func convenienceAnalyzers() map[string]*Analyzer { - return map[string]*Analyzer{ - fillstruct.Analyzer.Name: { @@ -82199,10 +90028,14 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - ActionKind: []protocol.CodeActionKind{protocol.RefactorRewrite}, - }, - stubmethods.Analyzer.Name: { -- Analyzer: stubmethods.Analyzer, -- ActionKind: []protocol.CodeActionKind{protocol.RefactorRewrite}, -- Fix: StubMethods, +- Analyzer: stubmethods.Analyzer, +- Fix: StubMethods, +- Enabled: true, +- }, +- infertypeargs.Analyzer.Name: { +- Analyzer: infertypeargs.Analyzer, - Enabled: true, +- ActionKind: []protocol.CodeActionKind{protocol.RefactorRewrite}, - }, - } -} @@ -82218,6 +90051,8 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - cgocall.Analyzer.Name: {Analyzer: cgocall.Analyzer, Enabled: true}, - composite.Analyzer.Name: {Analyzer: composite.Analyzer, Enabled: true}, - copylock.Analyzer.Name: {Analyzer: copylock.Analyzer, Enabled: true}, +- defers.Analyzer.Name: {Analyzer: defers.Analyzer, Enabled: true}, +- deprecated.Analyzer.Name: {Analyzer: deprecated.Analyzer, Enabled: true, Severity: protocol.SeverityHint, Tag: []protocol.DiagnosticTag{protocol.Deprecated}}, - directive.Analyzer.Name: {Analyzer: directive.Analyzer, Enabled: true}, - errorsas.Analyzer.Name: {Analyzer: errorsas.Analyzer, Enabled: true}, - httpresponse.Analyzer.Name: {Analyzer: httpresponse.Analyzer, Enabled: true}, @@ -82227,6 +90062,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - nilfunc.Analyzer.Name: {Analyzer: nilfunc.Analyzer, Enabled: true}, - printf.Analyzer.Name: {Analyzer: printf.Analyzer, Enabled: true}, - shift.Analyzer.Name: {Analyzer: shift.Analyzer, Enabled: true}, +- slog.Analyzer.Name: {Analyzer: slog.Analyzer, Enabled: true}, - stdmethods.Analyzer.Name: {Analyzer: stdmethods.Analyzer, Enabled: true}, - stringintconv.Analyzer.Name: {Analyzer: stringintconv.Analyzer, Enabled: true}, - structtag.Analyzer.Name: {Analyzer: structtag.Analyzer, Enabled: true}, @@ -82247,9 +90083,13 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt - unusedparams.Analyzer.Name: {Analyzer: unusedparams.Analyzer, Enabled: false}, - unusedwrite.Analyzer.Name: {Analyzer: unusedwrite.Analyzer, Enabled: false}, - useany.Analyzer.Name: {Analyzer: useany.Analyzer, Enabled: false}, -- infertypeargs.Analyzer.Name: {Analyzer: infertypeargs.Analyzer, Enabled: true}, -- embeddirective.Analyzer.Name: {Analyzer: embeddirective.Analyzer, Enabled: true}, - timeformat.Analyzer.Name: {Analyzer: timeformat.Analyzer, Enabled: true}, +- embeddirective.Analyzer.Name: { +- Analyzer: embeddirective.Analyzer, +- Enabled: true, +- Fix: AddEmbedImport, +- fixesDiagnostic: fixedByImportingEmbed, +- }, - - // gofmt -s suite: - simplifycompositelit.Analyzer.Name: { @@ -82407,6 +90247,7 @@ diff -urN a/gopls/internal/lsp/source/options.go b/gopls/internal/lsp/source/opt -type AnalyzerJSON struct { - Name string - Doc string +- URL string - Default bool -} - @@ -82641,10 +90482,110 @@ diff -urN a/gopls/internal/lsp/source/options_test.go b/gopls/internal/lsp/sourc - } - } -} +diff -urN a/gopls/internal/lsp/source/origin_119.go b/gopls/internal/lsp/source/origin_119.go +--- a/gopls/internal/lsp/source/origin_119.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/origin_119.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.19 +-// +build go1.19 +- +-package source +- +-import "go/types" +- +-// containsOrigin reports whether the provided object set contains an object +-// with the same origin as the provided obj (which may be a synthetic object +-// created during instantiation). +-func containsOrigin(objSet map[types.Object]bool, obj types.Object) bool { +- objOrigin := origin(obj) +- for target := range objSet { +- if origin(target) == objOrigin { +- return true +- } +- } +- return false +-} +- +-func origin(obj types.Object) types.Object { +- switch obj := obj.(type) { +- case *types.Var: +- return obj.Origin() +- case *types.Func: +- return obj.Origin() +- } +- return obj +-} +diff -urN a/gopls/internal/lsp/source/origin.go b/gopls/internal/lsp/source/origin.go +--- a/gopls/internal/lsp/source/origin.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/origin.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build !go1.19 +-// +build !go1.19 +- +-package source +- +-import "go/types" +- +-// containsOrigin reports whether the provided object set contains an object +-// with the same origin as the provided obj (which may be a synthetic object +-// created during instantiation). +-func containsOrigin(objSet map[types.Object]bool, obj types.Object) bool { +- if obj == nil { +- return objSet[obj] +- } +- // In Go 1.18, we can't use the types.Var.Origin and types.Func.Origin methods. +- for target := range objSet { +- if target.Pkg() == obj.Pkg() && target.Pos() == obj.Pos() && target.Name() == obj.Name() { +- return true +- } +- } +- return false +-} +diff -urN a/gopls/internal/lsp/source/parsemode_go116.go b/gopls/internal/lsp/source/parsemode_go116.go +--- a/gopls/internal/lsp/source/parsemode_go116.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/parsemode_go116.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build !go1.17 +-// +build !go1.17 +- +-package source +- +-import "go/parser" +- +-// The parser.SkipObjectResolution mode flag is not supported before Go 1.17. +-const SkipObjectResolution parser.Mode = 0 +diff -urN a/gopls/internal/lsp/source/parsemode_go117.go b/gopls/internal/lsp/source/parsemode_go117.go +--- a/gopls/internal/lsp/source/parsemode_go117.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/parsemode_go117.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.17 +-// +build go1.17 +- +-package source +- +-import "go/parser" +- +-const SkipObjectResolution = parser.SkipObjectResolution diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/references.go --- a/gopls/internal/lsp/source/references.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/references.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,582 +0,0 @@ +@@ -1,692 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -82672,11 +90613,11 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - - "golang.org/x/sync/errgroup" - "golang.org/x/tools/go/types/objectpath" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/lsp/source/methodsets" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/event" -) - @@ -82707,7 +90648,7 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ -// definitions before uses) to the object denoted by the identifier at -// the given file/position, searching the entire workspace. -func references(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position, includeDeclaration bool) ([]reference, error) { -- ctx, done := event.Start(ctx, "source.References2") +- ctx, done := event.Start(ctx, "source.references") - defer done() - - // Is the cursor within the package name declaration? @@ -82789,9 +90730,23 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - if err != nil { - return nil, err - } +- +- // Restrict search to workspace packages. +- workspace, err := snapshot.WorkspaceMetadata(ctx) +- if err != nil { +- return nil, err +- } +- workspaceMap := make(map[PackageID]*Metadata, len(workspace)) +- for _, m := range workspace { +- workspaceMap[m.ID] = m +- } +- - for _, rdep := range rdeps { +- if _, ok := workspaceMap[rdep.ID]; !ok { +- continue +- } - for _, uri := range rdep.CompiledGoFiles { -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -82818,9 +90773,9 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - // The widest package (possibly a test variant) has the - // greatest number of files and thus we choose it for the - // "internal" references. -- widest := metas[len(metas)-1] +- widest := metas[len(metas)-1] // may include _test.go files - for _, uri := range widest.CompiledGoFiles { -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return nil, err - } @@ -82851,12 +90806,13 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - // declaration (e.g. because the _test.go files can change the - // meaning of a field or method selection), but the narrower - // package reports the more broadly referenced object. -- pkg, pgf, err := PackageForFile(ctx, snapshot, uri, NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, uri) - if err != nil { - return nil, err - } - - // Find the selected object (declaration or reference). +- // For struct{T}, we choose the field (Def) over the type (Use). - pos, err := pgf.PositionPos(pp) - if err != nil { - return nil, err @@ -82879,14 +90835,14 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - - // nil, error, error.Error, iota, or other built-in? - if obj.Pkg() == nil { -- // For some reason, existing tests require that iota has no references, -- // nor an error. TODO(adonovan): do something more principled. -- if obj.Name() == "iota" { -- return nil, nil -- } -- - return nil, fmt.Errorf("references to builtin %q are not supported", obj.Name()) - } +- if !obj.Pos().IsValid() { +- if obj.Pkg().Path() != "unsafe" { +- bug.Reportf("references: object %v has no position", obj) +- } +- return nil, fmt.Errorf("references to unsafe.%s are not supported", obj.Name()) +- } - - // Find metadata of all packages containing the object's defining file. - // This may include the query pkg, and possibly other variants. @@ -82899,14 +90855,16 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - if len(variants) == 0 { - return nil, fmt.Errorf("no packages for file %q", declURI) // can't happen - } +- // (variants must include ITVs for reverse dependency computation below.) - - // Is object exported? - // If so, compute scope and targets of the global search. - var ( -- globalScope = make(map[PackageID]*Metadata) +- globalScope = make(map[PackageID]*Metadata) // (excludes ITVs) - globalTargets map[PackagePath]map[objectpath.Path]unit +- expansions = make(map[PackageID]unit) // packages that caused search expansion - ) -- // TODO(adonovan): what about generic functions. Need to consider both +- // TODO(adonovan): what about generic functions? Need to consider both - // uninstantiated and instantiated. The latter have no objectpath. Use Origin? - if path, err := objectpath.For(obj); err == nil && obj.Exported() { - pkgPath := variants[0].PkgPath // (all variants have same package path) @@ -82914,6 +90872,47 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - pkgPath: {path: {}}, // primary target - } - +- // Compute set of (non-ITV) workspace packages. +- // We restrict references to this subset. +- workspace, err := snapshot.WorkspaceMetadata(ctx) +- if err != nil { +- return nil, err +- } +- workspaceMap := make(map[PackageID]*Metadata, len(workspace)) +- workspaceIDs := make([]PackageID, 0, len(workspace)) +- for _, m := range workspace { +- workspaceMap[m.ID] = m +- workspaceIDs = append(workspaceIDs, m.ID) +- } +- +- // addRdeps expands the global scope to include the +- // reverse dependencies of the specified package. +- addRdeps := func(id PackageID, transitive bool) error { +- rdeps, err := snapshot.ReverseDependencies(ctx, id, transitive) +- if err != nil { +- return err +- } +- for rdepID, rdep := range rdeps { +- // Skip non-workspace packages. +- // +- // This means we also skip any expansion of the +- // search that might be caused by a non-workspace +- // package, possibly causing us to miss references +- // to the expanded target set from workspace packages. +- // +- // TODO(adonovan): don't skip those expansions. +- // The challenge is how to so without type-checking +- // a lot of non-workspace packages not covered by +- // the initial workspace load. +- if _, ok := workspaceMap[rdepID]; !ok { +- continue +- } +- +- globalScope[rdepID] = rdep +- } +- return nil +- } +- - // How far need we search? - // For package-level objects, we need only search the direct importers. - // For fields and methods, we must search transitively. @@ -82921,15 +90920,11 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - - // The scope is the union of rdeps of each variant. - // (Each set is disjoint so there's no benefit to -- // to combining the metadata graph traversals.) +- // combining the metadata graph traversals.) - for _, m := range variants { -- rdeps, err := snapshot.ReverseDependencies(ctx, m.ID, transitive) -- if err != nil { +- if err := addRdeps(m.ID, transitive); err != nil { - return nil, err - } -- for id, rdep := range rdeps { -- globalScope[id] = rdep -- } - } - - // Is object a method? @@ -82938,8 +90933,11 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - // all methods that correspond to it through interface - // satisfaction, and the scope includes the rdeps of - // the package that declares each corresponding type. +- // +- // 'expansions' records the packages that declared +- // such types. - if recv := effectiveReceiver(obj); recv != nil { -- if err := expandMethodSearch(ctx, snapshot, obj.(*types.Func), recv, globalScope, globalTargets); err != nil { +- if err := expandMethodSearch(ctx, snapshot, workspaceIDs, obj.(*types.Func), recv, addRdeps, globalTargets, expansions); err != nil { - return nil, err - } - } @@ -82973,6 +90971,7 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - var group errgroup.Group - - // Compute local references for each variant. +- // The target objects are identified by (URI, offset). - for _, m := range variants { - // We want the ordinary importable package, - // plus any test-augmented variants, since @@ -82988,7 +90987,73 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - } - m := m - group.Go(func() error { -- return localReferences(ctx, snapshot, declURI, declPosn.Offset, m, report) +- // TODO(adonovan): opt: batch these TypeChecks. +- pkgs, err := snapshot.TypeCheck(ctx, m.ID) +- if err != nil { +- return err +- } +- pkg := pkgs[0] +- +- // Find the declaration of the corresponding +- // object in this package based on (URI, offset). +- pgf, err := pkg.File(declURI) +- if err != nil { +- return err +- } +- pos, err := safetoken.Pos(pgf.Tok, declPosn.Offset) +- if err != nil { +- return err +- } +- objects, _, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) +- if err != nil { +- return err // unreachable? (probably caught earlier) +- } +- +- // Report the locations of the declaration(s). +- // TODO(adonovan): what about for corresponding methods? Add tests. +- for _, node := range objects { +- report(mustLocation(pgf, node), true) +- } +- +- // Convert targets map to set. +- targets := make(map[types.Object]bool) +- for obj := range objects { +- targets[obj] = true +- } +- +- return localReferences(pkg, targets, true, report) +- }) +- } +- +- // Also compute local references within packages that declare +- // corresponding methods (see above), which expand the global search. +- // The target objects are identified by (PkgPath, objectpath). +- for id := range expansions { +- id := id +- group.Go(func() error { +- // TODO(adonovan): opt: batch these TypeChecks. +- pkgs, err := snapshot.TypeCheck(ctx, id) +- if err != nil { +- return err +- } +- pkg := pkgs[0] +- +- targets := make(map[types.Object]bool) +- for objpath := range globalTargets[pkg.Metadata().PkgPath] { +- obj, err := objectpath.Object(pkg.GetTypes(), objpath) +- if err != nil { +- // No such object, because it was +- // declared only in the test variant. +- continue +- } +- targets[obj] = true +- } +- +- // Don't include corresponding types or methods +- // since expansions did that already, and we don't +- // want (e.g.) concrete -> interface -> concrete. +- const correspond = false +- return localReferences(pkg, targets, correspond, report) - }) - } - @@ -83017,30 +91082,28 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ -} - -// expandMethodSearch expands the scope and targets of a global search --// for an exported method to include all methods that correspond to --// it through interface satisfaction. +-// for an exported method to include all methods in the workspace +-// that correspond to it through interface satisfaction. +-// +-// Each package that declares a corresponding type is added to +-// expansions so that we can also find local references to the type +-// within the package, which of course requires type checking. +-// +-// The scope is expanded by a sequence of calls (not concurrent) to addRdeps. -// -// recv is the method's effective receiver type, for method-set computations. --func expandMethodSearch(ctx context.Context, snapshot Snapshot, method *types.Func, recv types.Type, scope map[PackageID]*Metadata, targets map[PackagePath]map[objectpath.Path]unit) error { +-func expandMethodSearch(ctx context.Context, snapshot Snapshot, workspaceIDs []PackageID, method *types.Func, recv types.Type, addRdeps func(id PackageID, transitive bool) error, targets map[PackagePath]map[objectpath.Path]unit, expansions map[PackageID]unit) error { - // Compute the method-set fingerprint used as a key to the global search. - key, hasMethods := methodsets.KeyOf(recv) - if !hasMethods { - return bug.Errorf("KeyOf(%s)={} yet %s is a method", recv, method) - } -- metas, err := snapshot.AllMetadata(ctx) -- if err != nil { -- return err -- } -- allIDs := make([]PackageID, 0, len(metas)) -- for _, m := range metas { -- allIDs = append(allIDs, m.ID) -- } - // Search the methodset index of each package in the workspace. -- indexes, err := snapshot.MethodSets(ctx, allIDs...) +- indexes, err := snapshot.MethodSets(ctx, workspaceIDs...) - if err != nil { - return err - } -- var mu sync.Mutex // guards scope and targets +- var mu sync.Mutex // guards addRdeps, targets, expansions - var group errgroup.Group - for i, index := range indexes { - i := i @@ -83052,17 +91115,21 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - return nil - } - -- // Expand global search scope to include rdeps of this pkg. -- rdeps, err := snapshot.ReverseDependencies(ctx, allIDs[i], true) -- if err != nil { -- return err -- } +- // We have discovered one or more corresponding types. +- id := workspaceIDs[i] +- - mu.Lock() - defer mu.Unlock() -- for _, rdep := range rdeps { -- scope[rdep.ID] = rdep +- +- // Expand global search scope to include rdeps of this pkg. +- if err := addRdeps(id, true); err != nil { +- return err - } - +- // Mark this package so that we search within it for +- // local references to the additional types/methods. +- expansions[id] = unit{} +- - // Add each corresponding method the to set of global search targets. - for _, res := range results { - methodPkg := PackagePath(res.PkgPath) @@ -83079,55 +91146,32 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - return group.Wait() -} - --// localReferences reports each reference to the object --// declared at the specified URI/offset within its enclosing package m. --func localReferences(ctx context.Context, snapshot Snapshot, declURI span.URI, declOffset int, m *Metadata, report func(loc protocol.Location, isDecl bool)) error { -- pkgs, err := snapshot.TypeCheck(ctx, m.ID) -- if err != nil { -- return err -- } -- pkg := pkgs[0] // narrowest -- -- // Find declaration of corresponding object -- // in this package based on (URI, offset). -- pgf, err := pkg.File(declURI) -- if err != nil { -- return err -- } -- pos, err := safetoken.Pos(pgf.Tok, declOffset) -- if err != nil { -- return err -- } -- targets, _, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) -- if err != nil { -- return err // unreachable? (probably caught earlier) -- } -- -- // Report the locations of the declaration(s). -- // TODO(adonovan): what about for corresponding methods? Add tests. -- for _, node := range targets { -- report(mustLocation(pgf, node), true) -- } -- -- // If we're searching for references to a method, broaden the -- // search to include references to corresponding methods of -- // mutually assignable receiver types. +-// localReferences traverses syntax and reports each reference to one +-// of the target objects, or (if correspond is set) an object that +-// corresponds to one of them via interface satisfaction. +-func localReferences(pkg Package, targets map[types.Object]bool, correspond bool, report func(loc protocol.Location, isDecl bool)) error { +- // If we're searching for references to a method optionally +- // broaden the search to include references to corresponding +- // methods of mutually assignable receiver types. - // (We use a slice, but objectsAt never returns >1 methods.) - var methodRecvs []types.Type - var methodName string // name of an arbitrary target, iff a method -- for obj := range targets { -- if t := effectiveReceiver(obj); t != nil { -- methodRecvs = append(methodRecvs, t) -- methodName = obj.Name() +- if correspond { +- for obj := range targets { +- if t := effectiveReceiver(obj); t != nil { +- methodRecvs = append(methodRecvs, t) +- methodName = obj.Name() +- } - } - } - - // matches reports whether obj either is or corresponds to a target. - // (Correspondence is defined as usual for interface methods.) - matches := func(obj types.Object) bool { -- if targets[obj] != nil { +- if containsOrigin(targets, obj) { - return true -- } else if methodRecvs != nil && obj.Name() == methodName { +- } +- if methodRecvs != nil && obj.Name() == methodName { - if orecv := effectiveReceiver(obj); orecv != nil { - for _, mrecv := range methodRecvs { - if concreteImplementsIntf(orecv, mrecv) { @@ -83195,6 +91239,13 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ - targets[obj] = leaf - } - } else { +- // Note: prior to go1.21, go/types issue #60372 causes the position +- // a field Var T created for struct{*p.T} to be recorded at the +- // start of the field type ("*") not the location of the T. +- // This affects references and other gopls operations (issue #60369). +- // TODO(adonovan): delete this comment when we drop support for go1.20. +- +- // For struct{T}, we prefer the defined field Var over the used TypeName. - obj := info.ObjectOf(leaf) - if obj == nil { - return nil, nil, fmt.Errorf("%w for %q", errNoObjectFound, leaf.Name) @@ -83219,11 +91270,11 @@ diff -urN a/gopls/internal/lsp/source/references.go b/gopls/internal/lsp/source/ -// mustLocation reports the location interval a syntax node, -// which must belong to m.File. -// --// Safe for use only by references2 and implementations2. +-// Safe for use only by references and implementations. -func mustLocation(pgf *ParsedGoFile, n ast.Node) protocol.Location { - loc, err := pgf.NodeLocation(n) - if err != nil { -- panic(err) // can't happen in references2 or implementations2 +- panic(err) // can't happen in references or implementations - } - return loc -} @@ -83631,63 +91682,63 @@ diff -urN a/gopls/internal/lsp/source/rename_check.go b/gopls/internal/lsp/sourc -// checkStructField checks that the field renaming will not cause -// conflicts at its declaration, or ambiguity or changes to any selection. -func (r *renamer) checkStructField(from *types.Var) { -- // Check that the struct declaration is free of field conflicts, -- // and field/method conflicts. - +- // If this is the declaring package, check that the struct +- // declaration is free of field conflicts, and field/method +- // conflicts. +- // - // go/types offers no easy way to get from a field (or interface - // method) to its declaring struct (or interface), so we must - // ascend the AST. -- pgf, ok := enclosingFile(r.pkg, from.Pos()) -- if !ok { -- return // not declared by syntax of this package -- } -- path, _ := astutil.PathEnclosingInterval(pgf.File, from.Pos(), from.Pos()) -- // path matches this pattern: -- // [Ident SelectorExpr? StarExpr? Field FieldList StructType ParenExpr* ... File] +- if pgf, ok := enclosingFile(r.pkg, from.Pos()); ok { +- path, _ := astutil.PathEnclosingInterval(pgf.File, from.Pos(), from.Pos()) +- // path matches this pattern: +- // [Ident SelectorExpr? StarExpr? Field FieldList StructType ParenExpr* ... File] - -- // Ascend to FieldList. -- var i int -- for { -- if _, ok := path[i].(*ast.FieldList); ok { -- break +- // Ascend to FieldList. +- var i int +- for { +- if _, ok := path[i].(*ast.FieldList); ok { +- break +- } +- i++ - } - i++ -- } -- i++ -- tStruct := path[i].(*ast.StructType) -- i++ -- // Ascend past parens (unlikely). -- for { -- _, ok := path[i].(*ast.ParenExpr) -- if !ok { -- break -- } +- tStruct := path[i].(*ast.StructType) - i++ -- } -- if spec, ok := path[i].(*ast.TypeSpec); ok { -- // This struct is also a named type. -- // We must check for direct (non-promoted) field/field -- // and method/field conflicts. -- named := r.pkg.GetTypesInfo().Defs[spec.Name].Type() -- prev, indices, _ := types.LookupFieldOrMethod(named, true, r.pkg.GetTypes(), r.to) -- if len(indices) == 1 { -- r.errorf(from.Pos(), "renaming this field %q to %q", -- from.Name(), r.to) -- r.errorf(prev.Pos(), "\twould conflict with this %s", -- objectKind(prev)) -- return // skip checkSelections to avoid redundant errors +- // Ascend past parens (unlikely). +- for { +- _, ok := path[i].(*ast.ParenExpr) +- if !ok { +- break +- } +- i++ - } -- } else { -- // This struct is not a named type. -- // We need only check for direct (non-promoted) field/field conflicts. -- T := r.pkg.GetTypesInfo().Types[tStruct].Type.Underlying().(*types.Struct) -- for i := 0; i < T.NumFields(); i++ { -- if prev := T.Field(i); prev.Name() == r.to { +- if spec, ok := path[i].(*ast.TypeSpec); ok { +- // This struct is also a named type. +- // We must check for direct (non-promoted) field/field +- // and method/field conflicts. +- named := r.pkg.GetTypesInfo().Defs[spec.Name].Type() +- prev, indices, _ := types.LookupFieldOrMethod(named, true, r.pkg.GetTypes(), r.to) +- if len(indices) == 1 { - r.errorf(from.Pos(), "renaming this field %q to %q", - from.Name(), r.to) -- r.errorf(prev.Pos(), "\twould conflict with this field") +- r.errorf(prev.Pos(), "\twould conflict with this %s", +- objectKind(prev)) - return // skip checkSelections to avoid redundant errors - } +- } else { +- // This struct is not a named type. +- // We need only check for direct (non-promoted) field/field conflicts. +- T := r.pkg.GetTypesInfo().Types[tStruct].Type.Underlying().(*types.Struct) +- for i := 0; i < T.NumFields(); i++ { +- if prev := T.Field(i); prev.Name() == r.to { +- r.errorf(from.Pos(), "renaming this field %q to %q", +- from.Name(), r.to) +- r.errorf(prev.Pos(), "\twould conflict with this field") +- return // skip checkSelections to avoid redundant errors +- } +- } - } - } - @@ -84060,7 +92111,7 @@ diff -urN a/gopls/internal/lsp/source/rename_check.go b/gopls/internal/lsp/sourc - // type-checker. - // - // Only proceed if all packages have no errors. -- if pkg.HasParseErrors() || pkg.HasTypeErrors() { +- if len(pkg.GetParseErrors()) > 0 || len(pkg.GetTypeErrors()) > 0 { - r.errorf(token.NoPos, // we don't have a position for this error. - "renaming %q to %q not possible because %q has errors", - r.from, r.to, pkg.Metadata().PkgPath) @@ -84155,7 +92206,7 @@ diff -urN a/gopls/internal/lsp/source/rename_check.go b/gopls/internal/lsp/sourc diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rename.go --- a/gopls/internal/lsp/source/rename.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/rename.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1244 +0,0 @@ +@@ -1,1277 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -84179,7 +92230,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -// - special cases: embedded fields, interfaces, test variants, -// function-local things with uppercase names; -// packages with type errors (currently 'satisfy' rejects them), --// pakage with missing imports; +-// package with missing imports; -// -// - measure performance in k8s. -// @@ -84217,10 +92268,10 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/go/types/objectpath" - "golang.org/x/tools/go/types/typeutil" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/diff" - "golang.org/x/tools/internal/event" - "golang.org/x/tools/internal/typeparams" @@ -84274,7 +92325,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - // which means we return (nil, nil) at the protocol - // layer. This seems like a bug, or at best an exploitation of - // knowledge of VSCode-specific behavior. Can we avoid that? -- pkg, pgf, err := PackageForFile(ctx, snapshot, f.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, f.URI()) - if err != nil { - return nil, nil, err - } @@ -84310,7 +92361,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -func prepareRenamePackageName(ctx context.Context, snapshot Snapshot, pgf *ParsedGoFile) (*PrepareItem, error) { - // Does the client support file renaming? - fileRenameSupported := false -- for _, op := range snapshot.View().Options().SupportedResourceOperations { +- for _, op := range snapshot.Options().SupportedResourceOperations { - if op == protocol.Rename { - fileRenameSupported = true - break @@ -84321,14 +92372,10 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - } - - // Check validity of the metadata for the file's containing package. -- fileMeta, err := snapshot.MetadataForFile(ctx, pgf.URI) +- meta, err := NarrowestMetadataForFile(ctx, snapshot, pgf.URI) - if err != nil { - return nil, err - } -- if len(fileMeta) == 0 { -- return nil, fmt.Errorf("no packages found for file %q", pgf.URI) -- } -- meta := fileMeta[0] - if meta.Name == "main" { - return nil, fmt.Errorf("can't rename package \"main\"") - } @@ -84429,11 +92476,11 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - // See https://go.dev/cl/457615 for example. - // This really occurs in practice, e.g. kubernetes has - // vendor/k8s.io/kubectl -> ../../staging/src/k8s.io/kubectl. -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return nil, false, err - } -- data, err := fh.Read() +- data, err := fh.Content() - if err != nil { - return nil, false, err - } @@ -84451,19 +92498,42 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -// renameOrdinary renames an ordinary (non-package) name throughout the workspace. -func renameOrdinary(ctx context.Context, snapshot Snapshot, f FileHandle, pp protocol.Position, newName string) (map[span.URI][]diff.Edit, error) { - // Type-check the referring package and locate the object(s). -- // We choose the widest variant as, for non-exported -- // identifiers, it is the only package we need. -- pkg, pgf, err := PackageForFile(ctx, snapshot, f.URI(), WidestPackage) -- if err != nil { -- return nil, err -- } -- pos, err := pgf.PositionPos(pp) -- if err != nil { -- return nil, err -- } -- targets, _, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) -- if err != nil { -- return nil, err +- // +- // Unlike NarrowestPackageForFile, this operation prefers the +- // widest variant as, for non-exported identifiers, it is the +- // only package we need. (In case you're wondering why +- // 'references' doesn't also want the widest variant: it +- // computes the union across all variants.) +- var targets map[types.Object]ast.Node +- var pkg Package +- { +- metas, err := snapshot.MetadataForFile(ctx, f.URI()) +- if err != nil { +- return nil, err +- } +- RemoveIntermediateTestVariants(&metas) +- if len(metas) == 0 { +- return nil, fmt.Errorf("no package metadata for file %s", f.URI()) +- } +- widest := metas[len(metas)-1] // widest variant may include _test.go files +- pkgs, err := snapshot.TypeCheck(ctx, widest.ID) +- if err != nil { +- return nil, err +- } +- pkg = pkgs[0] +- pgf, err := pkg.File(f.URI()) +- if err != nil { +- return nil, err // "can't happen" +- } +- pos, err := pgf.PositionPos(pp) +- if err != nil { +- return nil, err +- } +- objects, _, err := objectsAt(pkg.GetTypesInfo(), pgf.File, pos) +- if err != nil { +- return nil, err +- } +- targets = objects - } - - // Pick a representative object arbitrarily. @@ -84482,24 +92552,42 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - // Find objectpath, if object is exported ("" otherwise). - var declObjPath objectpath.Path - if obj.Exported() { -- // objectpath.For requires the origin of a generic -- // function or type, not an instantiation (a bug?). -- // Unfortunately we can't call {Func,TypeName}.Origin -- // as these are not available in go/types@go1.18. -- // So we take a scenic route. +- // objectpath.For requires the origin of a generic function or type, not an +- // instantiation (a bug?). Unfortunately we can't call Func.Origin as this +- // is not available in go/types@go1.18. So we take a scenic route. +- // +- // Note that unlike Funcs, TypeNames are always canonical (they are "left" +- // of the type parameters, unlike methods). - switch obj.(type) { // avoid "obj :=" since cases reassign the var - case *types.TypeName: -- if named, ok := obj.Type().(*types.Named); ok { -- obj = named.Obj() +- if _, ok := obj.Type().(*typeparams.TypeParam); ok { +- // As with capitalized function parameters below, type parameters are +- // local. +- goto skipObjectPath - } - case *types.Func: - obj = funcOrigin(obj.(*types.Func)) - case *types.Var: - // TODO(adonovan): do vars need the origin treatment too? (issue #58462) +- +- // Function parameter and result vars that are (unusually) +- // capitalized are technically exported, even though they +- // cannot be referenced, because they may affect downstream +- // error messages. But we can safely treat them as local. +- // +- // This is not merely an optimization: the renameExported +- // operation gets confused by such vars. It finds them from +- // objectpath, the classifies them as local vars, but as +- // they came from export data they lack syntax and the +- // correct scope tree (issue #61294). +- if !obj.(*types.Var).IsField() && !isPackageLevel(obj) { +- goto skipObjectPath +- } - } - if path, err := objectpath.For(obj); err == nil { - declObjPath = path - } +- skipObjectPath: - } - - // Nonexported? Search locally. @@ -84602,6 +92690,8 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - if err != nil { - return nil, err - } +- // variants must include ITVs for the reverse dependency +- // computation, but they are filtered out before we typecheck. - allRdeps := make(map[PackageID]*Metadata) - for _, variant := range variants { - rdeps, err := snapshot.ReverseDependencies(ctx, variant.ID, transitive) @@ -84706,12 +92796,15 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - } - obj, err := objectpath.Object(p, t.obj) - if err != nil { -- // Though this can happen with regular export data -- // due to trimming of inconsequential objects, -- // it can't happen if we load dependencies from full -- // syntax (as today) or shallow export data (soon), -- // as both are complete. -- bug.Reportf("objectpath.Object(%v, %v) failed: %v", p, t.obj, err) +- // Possibly a method or an unexported type +- // that is not reachable through export data? +- // See https://github.com/golang/go/issues/60789. +- // +- // TODO(adonovan): it seems unsatisfactory that Object +- // should return an error for a "valid" path. Perhaps +- // we should define such paths as invalid and make +- // objectpath.For compute reachability? +- // Would that be a compatible change? - continue - } - objects = append(objects, obj) @@ -84768,11 +92861,12 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - // Update any affected replace directives in go.mod files. - // TODO(adonovan): extract into its own function. - // -- // TODO: should this operate on all go.mod files, irrespective of whether they are included in the workspace? -- // Get all active mod files in the workspace +- // Get all workspace modules. +- // TODO(adonovan): should this operate on all go.mod files, +- // irrespective of whether they are included in the workspace? - modFiles := s.ModFiles() - for _, m := range modFiles { -- fh, err := s.GetFile(ctx, m) +- fh, err := s.ReadFile(ctx, m) - if err != nil { - return nil, err - } @@ -84842,7 +92936,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - } - - // Calculate the edits to be made due to the change. -- edits := s.View().Options().ComputeEdits(string(pm.Mapper.Content), string(newContent)) +- edits := s.Options().ComputeEdits(string(pm.Mapper.Content), string(newContent)) - renamingEdits[pm.URI] = append(renamingEdits[pm.URI], edits...) - } - @@ -84854,8 +92948,8 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -// directory. -// -// It updates package clauses and import paths for the renamed package as well --// as any other packages affected by the directory renaming among packages --// described by allMetadata. +-// as any other packages affected by the directory renaming among all packages +-// known to the snapshot. -func renamePackage(ctx context.Context, s Snapshot, f FileHandle, newName PackageName) (map[span.URI][]diff.Edit, error) { - if strings.HasSuffix(string(newName), "_test") { - return nil, fmt.Errorf("cannot rename to _test package") @@ -84863,14 +92957,10 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - - // We need metadata for the relevant package and module paths. - // These should be the same for all packages containing the file. -- metas, err := s.MetadataForFile(ctx, f.URI()) +- meta, err := NarrowestMetadataForFile(ctx, s, f.URI()) - if err != nil { - return nil, err - } -- if len(metas) == 0 { -- return nil, fmt.Errorf("no packages found for file %q", f.URI()) -- } -- meta := metas[0] // narrowest - - oldPkgPath := meta.PkgPath - if meta.Module == nil { @@ -84896,7 +92986,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - edits := make(map[span.URI][]diff.Edit) - for _, m := range allMetadata { - // Special case: x_test packages for the renamed package will not have the -- // package path as as a dir prefix, but still need their package clauses +- // package path as a dir prefix, but still need their package clauses - // renamed. - if m.PkgPath == oldPkgPath+"_test" { - if err := renamePackageClause(ctx, m, s, newName+"_test", edits); err != nil { @@ -84950,7 +93040,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -func renamePackageClause(ctx context.Context, m *Metadata, snapshot Snapshot, newName PackageName, edits map[span.URI][]diff.Edit) error { - // Rename internal references to the package in the renaming package. - for _, uri := range m.CompiledGoFiles { -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return err - } @@ -84991,7 +93081,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - } - - for _, uri := range rdep.CompiledGoFiles { -- fh, err := snapshot.GetFile(ctx, uri) +- fh, err := snapshot.ReadFile(ctx, uri) - if err != nil { - return err - } @@ -85173,17 +93263,11 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - // shouldUpdate reports whether obj is one of (or an - // instantiation of one of) the target objects. - shouldUpdate := func(obj types.Object) bool { -- if r.objsToUpdate[obj] { -- return true -- } -- if fn, ok := obj.(*types.Func); ok && r.objsToUpdate[funcOrigin(fn)] { -- return true -- } -- return false +- return containsOrigin(r.objsToUpdate, obj) - } - - // Find all identifiers in the package that define or use a -- // renamed object. We iterate over info as it is more efficent +- // renamed object. We iterate over info as it is more efficient - // than calling ast.Inspect for each of r.pkg.CompiledGoFiles(). - type item struct { - node ast.Node // Ident, ImportSpec (obj=PkgName), or CaseClause (obj=Var) @@ -85271,7 +93355,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - // Just run the loop body once over the entire multiline comment. - lines := strings.Split(comment.Text, "\n") - tokFile := pgf.Tok -- commentLine := tokFile.Line(comment.Pos()) +- commentLine := safetoken.Line(tokFile, comment.Pos()) - uri := span.URIFromPath(tokFile.Name()) - for i, line := range lines { - lineStart := comment.Pos() @@ -85323,14 +93407,14 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena - return nil - } - -- identLine := pgf.Tok.Line(id.Pos()) +- identLine := safetoken.Line(pgf.Tok, id.Pos()) - for _, comment := range nodes[len(nodes)-1].(*ast.File).Comments { - if comment.Pos() > id.Pos() { - // Comment is after the identifier. - continue - } - -- lastCommentLine := pgf.Tok.Line(comment.End()) +- lastCommentLine := safetoken.Line(pgf.Tok, comment.End()) - if lastCommentLine+1 == identLine { - return comment - } @@ -85370,7 +93454,7 @@ diff -urN a/gopls/internal/lsp/source/rename.go b/gopls/internal/lsp/source/rena -// returns the package name declaration of file fh, and reports -// whether the position ppos lies within it. -// --// Note: also used by references2. +-// Note: also used by references. -func parsePackageNameDecl(ctx context.Context, snapshot Snapshot, fh FileHandle, ppos protocol.Position) (*ParsedGoFile, bool, error) { - pgf, err := snapshot.ParseGo(ctx, fh, ParseHeader) - if err != nil { @@ -85429,7 +93513,7 @@ diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/sou - - // We need full type-checking here, as we must type-check function bodies in - // order to provide signature help at the requested position. -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, 0, fmt.Errorf("getting file for SignatureHelp: %w", err) - } @@ -85523,7 +93607,7 @@ diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/sou - } - return &protocol.SignatureInformation{ - Label: name + s.Format(), -- Documentation: stringToSigInfoDocumentation(s.doc, snapshot.View().Options()), +- Documentation: stringToSigInfoDocumentation(s.doc, snapshot.Options()), - Parameters: paramInfo, - }, activeParam, nil -} @@ -85540,7 +93624,7 @@ diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/sou - activeParam := activeParameter(callExpr, len(sig.params), sig.variadic, pos) - return &protocol.SignatureInformation{ - Label: sig.name + sig.Format(), -- Documentation: stringToSigInfoDocumentation(sig.doc, snapshot.View().Options()), +- Documentation: stringToSigInfoDocumentation(sig.doc, snapshot.Options()), - Parameters: paramInfo, - }, activeParam, nil - @@ -85592,7 +93676,7 @@ diff -urN a/gopls/internal/lsp/source/signature_help.go b/gopls/internal/lsp/sou diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.go --- a/gopls/internal/lsp/source/stub.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/stub.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,238 +0,0 @@ +@@ -1,250 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -85613,10 +93697,12 @@ diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.g - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/astutil" +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/analysis/stubmethods" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/safetoken" -- "golang.org/x/tools/internal/bug" +- "golang.org/x/tools/internal/diff" +- "golang.org/x/tools/internal/tokeninternal" - "golang.org/x/tools/internal/typeparams" -) - @@ -85624,7 +93710,7 @@ diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.g -// methods of the concrete type that is assigned to an interface type -// at the cursor position. -func stubSuggestedFixFunc(ctx context.Context, snapshot Snapshot, fh FileHandle, rng protocol.Range) (*token.FileSet, *analysis.SuggestedFix, error) { -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, nil, fmt.Errorf("GetTypedFile: %w", err) - } @@ -85654,7 +93740,7 @@ diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.g - if err != nil { - return nil, nil, fmt.Errorf("failed to parse file %q declaring implementation type: %w", declPGF.URI, err) - } -- if declPGF.Fixed { +- if declPGF.Fixed() { - return nil, nil, fmt.Errorf("file contains parse errors: %s", declPGF.URI) - } - @@ -85719,6 +93805,12 @@ diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.g - var newImports []newImport // for AddNamedImport - qual := func(pkg *types.Package) string { - // TODO(adonovan): don't ignore vendor prefix. +- // +- // Ignore the current package import. +- if pkg.Path() == conc.Pkg().Path() { +- return "" +- } +- - importPath := ImportPath(pkg.Path()) - name, ok := importEnv[importPath] - if !ok { @@ -85756,7 +93848,7 @@ diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.g - // Format the new methods. - var newMethods bytes.Buffer - for _, method := range missing { -- fmt.Fprintf(&newMethods, `// %s implements %s +- fmt.Fprintf(&newMethods, `// %s implements %s. -func (%s%s%s) %s%s { - panic("unimplemented") -} @@ -85818,18 +93910,22 @@ diff -urN a/gopls/internal/lsp/source/stub.go b/gopls/internal/lsp/source/stub.g - } - - // Report the diff. -- diffs := snapshot.View().Options().ComputeEdits(string(input), output.String()) -- var edits []analysis.TextEdit +- diffs := snapshot.Options().ComputeEdits(string(input), output.String()) +- return tokeninternal.FileSetFor(declPGF.Tok), // edits use declPGF.Tok +- &analysis.SuggestedFix{TextEdits: diffToTextEdits(declPGF.Tok, diffs)}, +- nil +-} +- +-func diffToTextEdits(tok *token.File, diffs []diff.Edit) []analysis.TextEdit { +- edits := make([]analysis.TextEdit, 0, len(diffs)) - for _, edit := range diffs { - edits = append(edits, analysis.TextEdit{ -- Pos: declPGF.Tok.Pos(edit.Start), -- End: declPGF.Tok.Pos(edit.End), +- Pos: tok.Pos(edit.Start), +- End: tok.Pos(edit.End), - NewText: []byte(edit.New), - }) - } -- return FileSetFor(declPGF.Tok), // edits use declPGF.Tok -- &analysis.SuggestedFix{TextEdits: edits}, -- nil +- return edits -} diff -urN a/gopls/internal/lsp/source/symbols.go b/gopls/internal/lsp/source/symbols.go --- a/gopls/internal/lsp/source/symbols.go 2000-01-01 00:00:00.000000000 -0000 @@ -86065,7 +94161,7 @@ diff -urN a/gopls/internal/lsp/source/symbols.go b/gopls/internal/lsp/source/sym diff -urN a/gopls/internal/lsp/source/type_definition.go b/gopls/internal/lsp/source/type_definition.go --- a/gopls/internal/lsp/source/type_definition.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/lsp/source/type_definition.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,55 +0,0 @@ +@@ -1,57 +0,0 @@ -// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -86077,6 +94173,7 @@ diff -urN a/gopls/internal/lsp/source/type_definition.go b/gopls/internal/lsp/so - "fmt" - "go/token" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/internal/event" -) @@ -86086,7 +94183,7 @@ diff -urN a/gopls/internal/lsp/source/type_definition.go b/gopls/internal/lsp/so - ctx, done := event.Start(ctx, "source.TypeDefinition") - defer done() - -- pkg, pgf, err := PackageForFile(ctx, snapshot, fh.URI(), NarrowestPackage) +- pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI()) - if err != nil { - return nil, err - } @@ -86103,22876 +94200,27862 @@ diff -urN a/gopls/internal/lsp/source/type_definition.go b/gopls/internal/lsp/so - return nil, nil - } - -- typObj := typeToObject(obj.Type()) -- if typObj == nil { +- tname := typeToObject(obj.Type()) +- if tname == nil { - return nil, fmt.Errorf("no type definition for %s", obj.Name()) - } - -- // Identifiers with the type "error" are a special case with no position. -- if hasErrorType(typObj) { -- // TODO(rfindley): we can do better here, returning a link to the builtin -- // file. +- if !tname.Pos().IsValid() { +- // The only defined types with no position are error and comparable. +- if tname.Name() != "error" && tname.Name() != "comparable" { +- bug.Reportf("unexpected type name with no position: %s", tname) +- } - return nil, nil - } - -- loc, err := mapPosition(ctx, pkg.FileSet(), snapshot, typObj.Pos(), typObj.Pos()+token.Pos(len(typObj.Name()))) +- loc, err := mapPosition(ctx, pkg.FileSet(), snapshot, tname.Pos(), tname.Pos()+token.Pos(len(tname.Name()))) - if err != nil { - return nil, err - } - return []protocol.Location{loc}, nil -} -diff -urN a/gopls/internal/lsp/source/types_format.go b/gopls/internal/lsp/source/types_format.go ---- a/gopls/internal/lsp/source/types_format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/types_format.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,517 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/lsp/source/typerefs/doc.go b/gopls/internal/lsp/source/typerefs/doc.go +--- a/gopls/internal/lsp/source/typerefs/doc.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/typerefs/doc.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,151 +0,0 @@ +-// Copyright 2023 The Go Authors. 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 +-// Package typerefs extracts symbol-level reachability information +-// from the syntax of a Go package. +-// +-// # Background +-// +-// The goal of this analysis is to determine, for each package P, a nearly +-// minimal set of packages that could affect the type checking of P. This set +-// may contain false positives, but the smaller this set the better we can +-// invalidate and prune packages in gopls. +-// +-// More precisely, for each package P we define the set of "reachable" packages +-// from P as the set of packages that may affect the (deep) export data of the +-// direct dependencies of P. By this definition, the complement of this set +-// cannot affect any information derived from type checking P, such as +-// diagnostics, cross references, or method sets. Therefore we need not +-// invalidate any results for P when a package in the complement of this set +-// changes. +-// +-// # Computing references +-// +-// For a given declaration D, references are computed based on identifiers or +-// dotted identifiers referenced in the declaration of D, that may affect +-// the type of D. However, these references reflect only local knowledge of the +-// package and its dependency metadata, and do not depend on any analysis of +-// the dependencies themselves. This allows the reference information for +-// a package to be cached independent of all others. +-// +-// Specifically, if a referring identifier I appears in the declaration, we +-// record an edge from D to each object possibly referenced by I. We search for +-// references within type syntax, but do not actually type-check, so we can't +-// reliably determine whether an expression is a type or a term, or whether a +-// function is a builtin or generic. For example, the type of x in var x = +-// p.F(W) only depends on W if p.F is a builtin or generic function, which we +-// cannot know without type-checking package p. So we may over-approximate in +-// this way. +-// +-// - If I is declared in the current package, record a reference to its +-// declaration. +-// - Otherwise, if there are any dot imports in the current +-// file and I is exported, record a (possibly dangling) edge to +-// the corresponding declaration in each dot-imported package. +-// +-// If a dotted identifier q.I appears in the declaration, we +-// perform a similar operation: +-// +-// - If q is declared in the current package, we record a reference to that +-// object. It may be a var or const that has a field or method I. +-// - Otherwise, if q is a valid import name based on imports in the current file +-// and the provided metadata for dependency package names, record a +-// reference to the object I in that package. +-// - Additionally, handle the case where Q is exported, and Q.I may refer to +-// a field or method in a dot-imported package. +-// +-// That is essentially the entire algorithm, though there is some subtlety to +-// visiting the set of identifiers or dotted identifiers that may affect the +-// declaration type. See the visitDeclOrSpec function for the details of this +-// analysis. Notably, we also skip identifiers that refer to type parameters in +-// generic declarations. +-// +-// # Graph optimizations +-// +-// The references extracted from the syntax are used to construct +-// edges between nodes representing declarations. Edges are of two +-// kinds: internal references, from one package-level declaration to +-// another; and external references, from a symbol in this package to +-// a symbol imported from a direct dependency. +-// +-// Once the symbol reference graph is constructed, we find its +-// strongly connected components (SCCs) using Tarjan's algorithm. +-// As we coalesce the nodes of each SCC we compute the union of +-// external references reached by each package-level declaration. +-// The final result is the mapping from each exported package-level +-// declaration to the set of external (imported) declarations that it +-// reaches. +-// +-// Because it is common for many package members to have the same +-// reachability, the result takes the form of a set of equivalence +-// classes, each mapping a set of package-level declarations to a set +-// of external symbols. We use a hash table to canonicalize sets so that +-// repeated occurrences of the same set (which are common) are only +-// represented once in memory or in the file system. +-// For example, all declarations that ultimately reference only +-// {fmt.Println,strings.Join} would be classed as equivalent. +-// +-// This approach was inspired by the Hash-Value Numbering (HVN) +-// optimization described by Hardekopf and Lin. See +-// golang.org/x/tools/go/pointer/hvn.go for an implementation. (Like +-// pointer analysis, this problem is fundamentally one of graph +-// reachability.) The HVN algorithm takes the compression a step +-// further by preserving the topology of the SCC DAG, in which edges +-// represent "is a superset of" constraints. Redundant edges that +-// don't increase the solution can be deleted. We could apply the same +-// technique here to further reduce the worst-case size of the result, +-// but the current implementation seems adequate. +-// +-// # API +-// +-// The main entry point for this analysis is the [Encode] function, +-// which implements the analysis described above for one package, and +-// encodes the result as a binary message. +-// +-// The [Decode] function decodes the message into a usable form: a set +-// of equivalence classes. The decoder uses a shared [PackageIndex] to +-// enable more compact representations of sets of packages +-// ([PackageSet]) during the global reacahability computation. +-// +-// The [BuildPackageGraph] constructor implements a whole-graph analysis similar +-// to that which will be implemented by gopls, but for various reasons the +-// logic for this analysis will eventually live in the +-// [golang.org/x/tools/gopls/internal/lsp/cache] package. Nevertheless, +-// BuildPackageGraph and its test serve to verify the syntactic analysis, and +-// may serve as a proving ground for new optimizations of the whole-graph analysis. +-// +-// # Export data is insufficient +-// +-// At first it may seem that the simplest way to implement this analysis would +-// be to consider the types.Packages of the dependencies of P, for example +-// during export. After all, it makes sense that the type checked packages +-// themselves could describe their dependencies. However, this does not work as +-// type information does not describe certain syntactic relationships. +-// +-// For example, the following scenarios cause type information to miss +-// syntactic relationships: +-// +-// Named type forwarding: +-// +-// package a; type A b.B +-// package b; type B int +-// +-// Aliases: +-// +-// package a; func A(f b.B) +-// package b; type B = func() +-// +-// Initializers: +-// +-// package a; var A = b.B() +-// package b; func B() string { return "hi" } +-// +-// Use of the unsafe package: +-// +-// package a; type A [unsafe.Sizeof(B{})]int +-// package b; type B struct { f1, f2, f3 int } +-// +-// In all of these examples, types do not contain information about the edge +-// between the a.A and b.B declarations. +-package typerefs +diff -urN a/gopls/internal/lsp/source/typerefs/packageset.go b/gopls/internal/lsp/source/typerefs/packageset.go +--- a/gopls/internal/lsp/source/typerefs/packageset.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/typerefs/packageset.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,148 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package typerefs - -import ( -- "bytes" -- "context" - "fmt" -- "go/ast" -- "go/doc" -- "go/printer" -- "go/token" -- "go/types" +- "math/bits" +- "sort" - "strings" +- "sync" - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/internal/bug" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/event/tag" -- "golang.org/x/tools/internal/typeparams" +- "golang.org/x/tools/gopls/internal/lsp/source" -) - --// FormatType returns the detail and kind for a types.Type. --func FormatType(typ types.Type, qf types.Qualifier) (detail string, kind protocol.CompletionItemKind) { -- if types.IsInterface(typ) { -- detail = "interface{...}" -- kind = protocol.InterfaceCompletion -- } else if _, ok := typ.(*types.Struct); ok { -- detail = "struct{...}" -- kind = protocol.StructCompletion -- } else if typ != typ.Underlying() { -- detail, kind = FormatType(typ.Underlying(), qf) -- } else { -- detail = types.TypeString(typ, qf) -- kind = protocol.ClassCompletion -- } -- return detail, kind +-// PackageIndex stores common data to enable efficient representation of +-// references and package sets. +-type PackageIndex struct { +- // For now, PackageIndex just indexes package ids, to save space and allow for +- // faster unions via sparse int vectors. +- mu sync.Mutex +- ids []source.PackageID +- m map[source.PackageID]IndexID -} - --type signature struct { -- name, doc string -- typeParams, params, results []string -- variadic bool -- needResultParens bool +-// NewPackageIndex creates a new PackageIndex instance for use in building +-// reference and package sets. +-func NewPackageIndex() *PackageIndex { +- return &PackageIndex{ +- m: make(map[source.PackageID]IndexID), +- } -} - --func (s *signature) Format() string { -- var b strings.Builder -- b.WriteByte('(') -- for i, p := range s.params { -- if i > 0 { -- b.WriteString(", ") -- } -- b.WriteString(p) +-// IndexID returns the packageIdx referencing id, creating one if id is not yet +-// tracked by the receiver. +-func (index *PackageIndex) IndexID(id source.PackageID) IndexID { +- index.mu.Lock() +- defer index.mu.Unlock() +- if i, ok := index.m[id]; ok { +- return i - } -- b.WriteByte(')') +- i := IndexID(len(index.ids)) +- index.m[id] = i +- index.ids = append(index.ids, id) +- return i +-} - -- // Add space between parameters and results. -- if len(s.results) > 0 { -- b.WriteByte(' ') -- } -- if s.needResultParens { -- b.WriteByte('(') -- } -- for i, r := range s.results { -- if i > 0 { -- b.WriteString(", ") -- } -- b.WriteString(r) -- } -- if s.needResultParens { -- b.WriteByte(')') +-// PackageID returns the PackageID for idx. +-// +-// idx must have been created by this PackageIndex instance. +-func (index *PackageIndex) PackageID(idx IndexID) source.PackageID { +- index.mu.Lock() +- defer index.mu.Unlock() +- return index.ids[idx] +-} +- +-// A PackageSet is a set of source.PackageIDs, optimized for inuse memory +-// footprint and efficient union operations. +-type PackageSet struct { +- // PackageSet is a sparse int vector of package indexes from parent. +- parent *PackageIndex +- sparse map[int]blockType // high bits in key, set of low bits in value +-} +- +-type blockType = uint // type of each sparse vector element +-const blockSize = bits.UintSize +- +-// NewSet creates a new PackageSet bound to this PackageIndex instance. +-// +-// PackageSets may only be combined with other PackageSets from the same +-// instance. +-func (index *PackageIndex) NewSet() *PackageSet { +- return &PackageSet{ +- parent: index, +- sparse: make(map[int]blockType), - } -- return b.String() -} - --func (s *signature) TypeParams() []string { -- return s.typeParams +-// DeclaringPackage returns the ID of the symbol's declaring package. +-// The package index must be the one used during decoding. +-func (index *PackageIndex) DeclaringPackage(sym Symbol) source.PackageID { +- return index.PackageID(sym.Package) -} - --func (s *signature) Params() []string { -- return s.params +-// Add records a new element in the package set, for the provided package ID. +-func (s *PackageSet) AddPackage(id source.PackageID) { +- s.Add(s.parent.IndexID(id)) -} - --// NewBuiltinSignature returns signature for the builtin object with a given --// name, if a builtin object with the name exists. --func NewBuiltinSignature(ctx context.Context, s Snapshot, name string) (*signature, error) { -- builtin, err := s.BuiltinFile(ctx) -- if err != nil { -- return nil, err +-// Add records a new element in the package set. +-// It is the caller's responsibility to ensure that idx was created with the +-// same PackageIndex as the PackageSet. +-func (s *PackageSet) Add(idx IndexID) { +- i := int(idx) +- s.sparse[i/blockSize] |= 1 << (i % blockSize) +-} +- +-// Union records all elements from other into the receiver, mutating the +-// receiver set but not the argument set. The receiver must not be nil, but the +-// argument set may be nil. +-// +-// Precondition: both package sets were created with the same PackageIndex. +-func (s *PackageSet) Union(other *PackageSet) { +- if other == nil { +- return // e.g. unsafe - } -- obj := builtin.File.Scope.Lookup(name) -- if obj == nil { -- return nil, fmt.Errorf("no builtin object for %s", name) +- if other.parent != s.parent { +- panic("other set is from a different PackageIndex instance") - } -- decl, ok := obj.Decl.(*ast.FuncDecl) -- if !ok { -- return nil, fmt.Errorf("no function declaration for builtin: %s", name) +- for k, v := range other.sparse { +- if v0 := s.sparse[k]; v0 != v { +- s.sparse[k] = v0 | v +- } - } -- if decl.Type == nil { -- return nil, fmt.Errorf("no type for builtin decl %s", decl.Name) +-} +- +-// Contains reports whether id is contained in the receiver set. +-func (s *PackageSet) Contains(id source.PackageID) bool { +- i := int(s.parent.IndexID(id)) +- return s.sparse[i/blockSize]&(1<<(i%blockSize)) != 0 +-} +- +-// Elems calls f for each element of the set in ascending order. +-func (s *PackageSet) Elems(f func(IndexID)) { +- blockIndexes := make([]int, 0, len(s.sparse)) +- for k := range s.sparse { +- blockIndexes = append(blockIndexes, k) - } -- var variadic bool -- if decl.Type.Params.List != nil { -- numParams := len(decl.Type.Params.List) -- lastParam := decl.Type.Params.List[numParams-1] -- if _, ok := lastParam.Type.(*ast.Ellipsis); ok { -- variadic = true +- sort.Ints(blockIndexes) +- for _, i := range blockIndexes { +- v := s.sparse[i] +- for b := 0; b < blockSize; b++ { +- if (v & (1 << b)) != 0 { +- f(IndexID(i*blockSize + b)) +- } - } - } -- fset := FileSetFor(builtin.Tok) -- params, _ := formatFieldList(ctx, fset, decl.Type.Params, variadic) -- results, needResultParens := formatFieldList(ctx, fset, decl.Type.Results, false) -- d := decl.Doc.Text() -- switch s.View().Options().HoverKind { -- case SynopsisDocumentation: -- d = doc.Synopsis(d) -- case NoDocumentation: -- d = "" -- } -- return &signature{ -- doc: d, -- name: name, -- needResultParens: needResultParens, -- params: params, -- results: results, -- variadic: variadic, -- }, nil -} - --// replacer replaces some synthetic "type classes" used in the builtin file --// with their most common constituent type. --var replacer = strings.NewReplacer( -- `ComplexType`, `complex128`, -- `FloatType`, `float64`, -- `IntegerType`, `int`, +-// String returns a human-readable representation of the set: {A, B, ...}. +-func (s *PackageSet) String() string { +- var ids []string +- s.Elems(func(id IndexID) { +- ids = append(ids, string(s.parent.PackageID(id))) +- }) +- return fmt.Sprintf("{%s}", strings.Join(ids, ", ")) +-} +diff -urN a/gopls/internal/lsp/source/typerefs/pkggraph_test.go b/gopls/internal/lsp/source/typerefs/pkggraph_test.go +--- a/gopls/internal/lsp/source/typerefs/pkggraph_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/typerefs/pkggraph_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,243 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package typerefs_test +- +-// This file is logically part of the test in pkgrefs_test.go: that +-// file defines the test assertion logic; this file provides a +-// reference implementation of a client of the typerefs package. +- +-import ( +- "bytes" +- "context" +- "fmt" +- "os" +- "runtime" +- "sync" +- +- "golang.org/x/sync/errgroup" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/source/typerefs" +- "golang.org/x/tools/gopls/internal/span" -) - --func formatFieldList(ctx context.Context, fset *token.FileSet, list *ast.FieldList, variadic bool) ([]string, bool) { -- if list == nil { -- return nil, false +-const ( +- // trace enables additional trace output to stdout, for debugging. +- // +- // Warning: produces a lot of output! Best to run with small package queries. +- trace = false +-) +- +-// A Package holds reference information for a single package. +-type Package struct { +- // metadata holds metadata about this package and its dependencies. +- metadata *source.Metadata +- +- // transitiveRefs records, for each exported declaration in the package, the +- // transitive set of packages within the containing graph that are +- // transitively reachable through references, starting with the given decl. +- transitiveRefs map[string]*typerefs.PackageSet +- +- // ReachesViaDeps records the set of packages in the containing graph whose +- // syntax may affect the current package's types. See the package +- // documentation for more details of what this means. +- ReachesByDeps *typerefs.PackageSet +-} +- +-// A PackageGraph represents a fully analyzed graph of packages and their +-// dependencies. +-type PackageGraph struct { +- pkgIndex *typerefs.PackageIndex +- meta source.MetadataSource +- parse func(context.Context, span.URI) (*source.ParsedGoFile, error) +- +- mu sync.Mutex +- packages map[source.PackageID]*futurePackage +-} +- +-// BuildPackageGraph analyzes the package graph for the requested ids, whose +-// metadata is described by meta. +-// +-// The provided parse function is used to parse the CompiledGoFiles of each package. +-// +-// The resulting PackageGraph is fully evaluated, and may be investigated using +-// the Package method. +-// +-// See the package documentation for more information on the package reference +-// algorithm. +-func BuildPackageGraph(ctx context.Context, meta source.MetadataSource, ids []source.PackageID, parse func(context.Context, span.URI) (*source.ParsedGoFile, error)) (*PackageGraph, error) { +- g := &PackageGraph{ +- pkgIndex: typerefs.NewPackageIndex(), +- meta: meta, +- parse: parse, +- packages: make(map[source.PackageID]*futurePackage), - } -- var writeResultParens bool -- var result []string -- for i := 0; i < len(list.List); i++ { -- if i >= 1 { -- writeResultParens = true -- } -- p := list.List[i] -- cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 4} -- b := &bytes.Buffer{} -- if err := cfg.Fprint(b, fset, p.Type); err != nil { -- event.Error(ctx, "unable to print type", nil, tag.Type.Of(p.Type)) -- continue -- } -- typ := replacer.Replace(b.String()) -- if len(p.Names) == 0 { -- result = append(result, typ) -- } -- for _, name := range p.Names { -- if name.Name != "" { -- if i == 0 { -- writeResultParens = true -- } -- result = append(result, fmt.Sprintf("%s %s", name.Name, typ)) -- } else { -- result = append(result, typ) -- } -- } +- source.SortPostOrder(meta, ids) +- +- workers := runtime.GOMAXPROCS(0) +- if trace { +- workers = 1 - } -- if variadic { -- result[len(result)-1] = strings.Replace(result[len(result)-1], "[]", "...", 1) +- +- var eg errgroup.Group +- eg.SetLimit(workers) +- for _, id := range ids { +- id := id +- eg.Go(func() error { +- _, err := g.Package(ctx, id) +- return err +- }) - } -- return result, writeResultParens +- return g, eg.Wait() -} - --// FormatTypeParams turns TypeParamList into its Go representation, such as: --// [T, Y]. Note that it does not print constraints as this is mainly used for --// formatting type params in method receivers. --func FormatTypeParams(tparams *typeparams.TypeParamList) string { -- if tparams == nil || tparams.Len() == 0 { -- return "" -- } -- var buf bytes.Buffer -- buf.WriteByte('[') -- for i := 0; i < tparams.Len(); i++ { -- if i > 0 { -- buf.WriteString(", ") +-// futurePackage is a future result of analyzing a package, for use from Package only. +-type futurePackage struct { +- done chan struct{} +- pkg *Package +- err error +-} +- +-// Package gets the result of analyzing references for a single package. +-func (g *PackageGraph) Package(ctx context.Context, id source.PackageID) (*Package, error) { +- g.mu.Lock() +- fut, ok := g.packages[id] +- if ok { +- g.mu.Unlock() +- select { +- case <-fut.done: +- case <-ctx.Done(): +- return nil, ctx.Err() - } -- buf.WriteString(tparams.At(i).Obj().Name()) +- } else { +- fut = &futurePackage{done: make(chan struct{})} +- g.packages[id] = fut +- g.mu.Unlock() +- fut.pkg, fut.err = g.buildPackage(ctx, id) +- close(fut.done) - } -- buf.WriteByte(']') -- return buf.String() +- return fut.pkg, fut.err -} - --// NewSignature returns formatted signature for a types.Signature struct. --func NewSignature(ctx context.Context, s Snapshot, pkg Package, sig *types.Signature, comment *ast.CommentGroup, qf types.Qualifier, mq MetadataQualifier) (*signature, error) { -- var tparams []string -- tpList := typeparams.ForSignature(sig) -- for i := 0; i < tpList.Len(); i++ { -- tparam := tpList.At(i) -- // TODO: is it possible to reuse the logic from FormatVarType here? -- s := tparam.Obj().Name() + " " + tparam.Constraint().String() -- tparams = append(tparams, s) +-// buildPackage parses a package and extracts its reference graph. It should +-// only be called from Package. +-func (g *PackageGraph) buildPackage(ctx context.Context, id source.PackageID) (*Package, error) { +- p := &Package{ +- metadata: g.meta.Metadata(id), +- transitiveRefs: make(map[string]*typerefs.PackageSet), - } -- -- params := make([]string, 0, sig.Params().Len()) -- for i := 0; i < sig.Params().Len(); i++ { -- el := sig.Params().At(i) -- typ, err := FormatVarType(ctx, s, pkg, el, qf, mq) +- var files []*source.ParsedGoFile +- for _, filename := range p.metadata.CompiledGoFiles { +- f, err := g.parse(ctx, filename) - if err != nil { - return nil, err - } -- p := typ -- if el.Name() != "" { -- p = el.Name() + " " + typ +- files = append(files, f) +- } +- imports := make(map[source.ImportPath]*source.Metadata) +- for impPath, depID := range p.metadata.DepsByImpPath { +- if depID != "" { +- imports[impPath] = g.meta.Metadata(depID) - } -- params = append(params, p) - } - -- var needResultParens bool -- results := make([]string, 0, sig.Results().Len()) -- for i := 0; i < sig.Results().Len(); i++ { -- if i >= 1 { -- needResultParens = true -- } -- el := sig.Results().At(i) -- typ, err := FormatVarType(ctx, s, pkg, el, qf, mq) -- if err != nil { -- return nil, err -- } -- if el.Name() == "" { -- results = append(results, typ) -- } else { -- if i == 0 { -- needResultParens = true +- // Compute the symbol-level dependencies through this package. +- data := typerefs.Encode(files, id, imports) +- +- // data can be persisted in a filecache, keyed +- // by hash(id, CompiledGoFiles, imports). +- +- // This point separates the local preprocessing +- // -- of a single package (above) from the global -- +- // transitive reachability query (below). +- +- // classes records syntactic edges between declarations in this +- // package and declarations in this package or another +- // package. See the package documentation for a detailed +- // description of what these edges do (and do not) represent. +- classes := typerefs.Decode(g.pkgIndex, id, data) +- +- // Debug +- if trace && len(classes) > 0 { +- var buf bytes.Buffer +- fmt.Fprintf(&buf, "%s\n", id) +- for _, class := range classes { +- for i, name := range class.Decls { +- if i == 0 { +- fmt.Fprintf(&buf, "\t") +- } +- fmt.Fprintf(&buf, " .%s", name) +- } +- // Group symbols by package. +- var prevID PackageID +- for _, sym := range class.Refs { +- id := g.pkgIndex.DeclaringPackage(sym) +- if id != prevID { +- prevID = id +- fmt.Fprintf(&buf, "\n\t\t-> %s:", id) +- } +- fmt.Fprintf(&buf, " .%s", sym.Name) - } -- results = append(results, el.Name()+" "+typ) +- fmt.Fprintln(&buf) - } +- os.Stderr.Write(buf.Bytes()) - } -- var d string -- if comment != nil { -- d = comment.Text() +- +- // Now compute the transitive closure of packages reachable +- // from any exported symbol of this package. +- for _, class := range classes { +- set := g.pkgIndex.NewSet() +- +- // The Refs slice is sorted by (PackageID, name), +- // so we can economize by calling g.Package only +- // when the package id changes. +- depP := p +- for _, sym := range class.Refs { +- symPkgID := g.pkgIndex.DeclaringPackage(sym) +- if symPkgID == id { +- panic("intra-package edge") +- } +- if depP.metadata.ID != symPkgID { +- // package changed +- var err error +- depP, err = g.Package(ctx, symPkgID) +- if err != nil { +- return nil, err +- } +- } +- set.Add(sym.Package) +- set.Union(depP.transitiveRefs[sym.Name]) +- } +- for _, name := range class.Decls { +- p.transitiveRefs[name] = set +- } - } -- switch s.View().Options().HoverKind { -- case SynopsisDocumentation: -- d = doc.Synopsis(d) -- case NoDocumentation: -- d = "" +- +- // Finally compute the union of transitiveRefs +- // across the direct deps of this package. +- byDeps, err := g.reachesByDeps(ctx, p.metadata) +- if err != nil { +- return nil, err - } -- return &signature{ -- doc: d, -- typeParams: tparams, -- params: params, -- results: results, -- variadic: sig.Variadic(), -- needResultParens: needResultParens, -- }, nil +- p.ReachesByDeps = byDeps +- +- return p, nil -} - --// FormatVarType formats a *types.Var, accounting for type aliases. --// To do this, it looks in the AST of the file in which the object is declared. --// On any errors, it always falls back to types.TypeString. --// --// TODO(rfindley): this function could return the actual name used in syntax, --// for better parameter names. --func FormatVarType(ctx context.Context, snapshot Snapshot, srcpkg Package, obj *types.Var, qf types.Qualifier, mq MetadataQualifier) (string, error) { -- // TODO(rfindley): This looks wrong. The previous comment said: -- // "If the given expr refers to a type parameter, then use the -- // object's Type instead of the type parameter declaration. This helps -- // format the instantiated type as opposed to the original undeclared -- // generic type". -- // -- // But of course, if obj is a type param, we are formatting a generic type -- // and not an instantiated type. Handling for instantiated types must be done -- // at a higher level. -- // -- // Left this during refactoring in order to preserve pre-existing logic. -- if typeparams.IsTypeParam(obj.Type()) { -- return types.TypeString(obj.Type(), qf), nil +-// reachesByDeps computes the set of packages that are reachable through +-// dependencies of the package m. +-func (g *PackageGraph) reachesByDeps(ctx context.Context, m *source.Metadata) (*typerefs.PackageSet, error) { +- transitive := g.pkgIndex.NewSet() +- for _, depID := range m.DepsByPkgPath { +- dep, err := g.Package(ctx, depID) +- if err != nil { +- return nil, err +- } +- transitive.AddPackage(dep.metadata.ID) +- for _, set := range dep.transitiveRefs { +- transitive.Union(set) +- } - } +- return transitive, nil +-} +diff -urN a/gopls/internal/lsp/source/typerefs/pkgrefs_test.go b/gopls/internal/lsp/source/typerefs/pkgrefs_test.go +--- a/gopls/internal/lsp/source/typerefs/pkgrefs_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/typerefs/pkgrefs_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,407 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- if obj.Pkg() == nil || !obj.Pos().IsValid() { -- // This is defensive, though it is extremely unlikely we'll ever have a -- // builtin var. -- return types.TypeString(obj.Type(), qf), nil +-package typerefs_test +- +-import ( +- "bytes" +- "context" +- "flag" +- "fmt" +- "go/token" +- "go/types" +- "os" +- "sort" +- "strings" +- "sync" +- "testing" +- "time" +- +- "golang.org/x/tools/go/gcexportdata" +- "golang.org/x/tools/go/packages" +- "golang.org/x/tools/gopls/internal/astutil" +- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/source/typerefs" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/packagesinternal" +- "golang.org/x/tools/internal/testenv" +-) +- +-var ( +- dir = flag.String("dir", "", "dir to run go/packages from") +- query = flag.String("query", "std", "go/packages load query to use for walkdecl tests") +- verify = flag.Bool("verify", true, "whether to verify reachable packages using export data (may be slow on large graphs)") +-) +- +-type ( +- packageName = source.PackageName +- PackageID = source.PackageID +- ImportPath = source.ImportPath +- PackagePath = source.PackagePath +- Metadata = source.Metadata +- MetadataSource = source.MetadataSource +- ParsedGoFile = source.ParsedGoFile +-) +- +-// TestBuildPackageGraph tests the BuildPackageGraph constructor, which uses +-// the reference analysis of the Refs function to build a graph of +-// relationships between packages. +-// +-// It simulates the operation of gopls at startup: packages are loaded via +-// go/packages, and their syntax+metadata analyzed to determine which packages +-// are reachable from others. +-// +-// The test then verifies that the 'load' graph (the graph of relationships in +-// export data) is a subgraph of the 'reach' graph constructed by +-// BuildPackageGraph. While doing so, it constructs some statistics about the +-// relative sizes of these graphs, along with the 'transitive imports' graph, +-// to report the effectiveness of the reachability analysis. +-// +-// The following flags affect this test: +-// - dir sets the dir from which to run go/packages +-// - query sets the go/packages query to load +-// - verify toggles the verification w.r.t. the load graph (which may be +-// prohibitively expensive with large queries). +-func TestBuildPackageGraph(t *testing.T) { +- if testing.Short() { +- t.Skip("skipping with -short: loading the packages can take a long time with a cold cache") - } +- testenv.NeedsGoBuild(t) // for go/packages - -- targetpgf, pos, err := parseFull(ctx, snapshot, srcpkg.FileSet(), obj.Pos()) +- t0 := time.Now() +- exports, meta, err := load(*query, *verify) - if err != nil { -- return "", err // e.g. ctx cancelled +- t.Fatalf("loading failed: %v", err) - } +- t.Logf("loaded %d packages in %v", len(exports), time.Since(t0)) - -- targetMeta := findFileInDeps(snapshot, srcpkg.Metadata(), targetpgf.URI) -- if targetMeta == nil { -- // If we have an object from type-checking, it should exist in a file in -- // the forward transitive closure. -- return "", bug.Errorf("failed to find file %q in deps of %q", targetpgf.URI, srcpkg.Metadata().ID) +- ctx := context.Background() +- var ids []PackageID +- for id := range exports { +- ids = append(ids, id) - } +- sort.Slice(ids, func(i, j int) bool { +- return ids[i] < ids[j] +- }) - -- decl, spec, field := findDeclInfo([]*ast.File{targetpgf.File}, pos) +- t0 = time.Now() +- g, err := BuildPackageGraph(ctx, meta, ids, newParser().parse) +- if err != nil { +- t.Fatal(err) +- } +- t.Logf("building package graph took %v", time.Since(t0)) - -- // We can't handle type parameters correctly, so we fall back on TypeString -- // for parameterized decls. -- if decl, _ := decl.(*ast.FuncDecl); decl != nil { -- if typeparams.ForFuncType(decl.Type).NumFields() > 0 { -- return types.TypeString(obj.Type(), qf), nil // in generic function +- // Collect information about the edges between packages for later analysis. +- // +- // We compare the following package graphs: +- // - the imports graph: edges are transitive imports +- // - the reaches graph: edges are reachability relationships through syntax +- // of imports (as defined in the package doc) +- // - the loads graph: edges are packages loaded through the export data of +- // imports +- // +- // By definition, loads < reaches < imports. +- type edgeSet map[PackageID]map[PackageID]bool +- var ( +- imports = make(edgeSet) // A imports B transitively +- importedBy = make(edgeSet) // A is imported by B transitively +- reaches = make(edgeSet) // A reaches B through top-level declaration syntax +- reachedBy = make(edgeSet) // A is reached by B through top-level declaration syntax +- loads = make(edgeSet) // A loads B through export data of its direct dependencies +- loadedBy = make(edgeSet) // A is loaded by B through export data of B's direct dependencies +- ) +- recordEdge := func(from, to PackageID, fwd, rev edgeSet) { +- if fwd[from] == nil { +- fwd[from] = make(map[PackageID]bool) - } -- if decl.Recv != nil && len(decl.Recv.List) > 0 { -- if x, _, _, _ := typeparams.UnpackIndexExpr(decl.Recv.List[0].Type); x != nil { -- return types.TypeString(obj.Type(), qf), nil // in method of generic type -- } +- fwd[from][to] = true +- if rev[to] == nil { +- rev[to] = make(map[PackageID]bool) - } -- } -- if spec, _ := spec.(*ast.TypeSpec); spec != nil && typeparams.ForTypeSpec(spec).NumFields() > 0 { -- return types.TypeString(obj.Type(), qf), nil // in generic type decl +- rev[to][from] = true - } - -- if field == nil { -- // TODO(rfindley): we should never reach here from an ordinary var, so -- // should probably return an error here. -- return types.TypeString(obj.Type(), qf), nil +- exportedPackages := make(map[PackageID]*types.Package) +- importPackage := func(id PackageID) *types.Package { +- exportFile := exports[id] +- if exportFile == "" { +- return nil // no exported symbols +- } +- m := meta.Metadata(id) +- tpkg, ok := exportedPackages[id] +- if !ok { +- pkgPath := string(m.PkgPath) +- tpkg, err = importFromExportData(pkgPath, exportFile) +- if err != nil { +- t.Fatalf("importFromExportData(%s, %s) failed: %v", pkgPath, exportFile, err) +- } +- exportedPackages[id] = tpkg +- } +- return tpkg - } -- expr := field.Type - -- rq := requalifier(snapshot, targetpgf.File, targetMeta, mq) +- for _, id := range ids { +- pkg, err := g.Package(ctx, id) +- if err != nil { +- t.Fatal(err) +- } +- pkg.ReachesByDeps.Elems(func(id2 typerefs.IndexID) { +- recordEdge(id, g.pkgIndex.PackageID(id2), reaches, reachedBy) +- }) - -- // The type names in the AST may not be correctly qualified. -- // Determine the package name to use based on the package that originated -- // the query and the package in which the type is declared. -- // We then qualify the value by cloning the AST node and editing it. -- expr = qualifyTypeExpr(expr, rq) +- importMap := importMap(id, meta) +- for _, id2 := range importMap { +- recordEdge(id, id2, imports, importedBy) +- } - -- // If the request came from a different package than the one in which the -- // types are defined, we may need to modify the qualifiers. -- return FormatNodeFile(targetpgf.Tok, expr), nil --} +- if *verify { +- for _, depID := range meta.Metadata(id).DepsByPkgPath { +- tpkg := importPackage(depID) +- if tpkg == nil { +- continue +- } +- for _, imp := range tpkg.Imports() { +- depID, ok := importMap[PackagePath(imp.Path())] +- if !ok { +- t.Errorf("import map (len: %d) for %s missing imported types.Package %s", len(importMap), id, imp.Path()) +- continue +- } +- recordEdge(id, depID, loads, loadedBy) +- } +- } - --// qualifyTypeExpr clones the type expression expr after re-qualifying type --// names using the given function, which accepts the current syntactic --// qualifier (possibly "" for unqualified idents), and returns a new qualifier --// (again, possibly "" if the identifier should be unqualified). --// --// The resulting expression may be inaccurate: without type-checking we don't --// properly account for "." imported identifiers or builtins. --// --// TODO(rfindley): add many more tests for this function. --func qualifyTypeExpr(expr ast.Expr, qf func(string) string) ast.Expr { -- switch expr := expr.(type) { -- case *ast.ArrayType: -- return &ast.ArrayType{ -- Lbrack: expr.Lbrack, -- Elt: qualifyTypeExpr(expr.Elt, qf), -- Len: expr.Len, +- for depID := range loads[id] { +- if !pkg.ReachesByDeps.Contains(depID) { +- t.Errorf("package %s was imported by %s, but not detected as reachable", depID, id) +- } +- } - } +- } - -- case *ast.BinaryExpr: -- if expr.Op != token.OR { -- return expr -- } -- return &ast.BinaryExpr{ -- X: qualifyTypeExpr(expr.X, qf), -- OpPos: expr.OpPos, -- Op: expr.Op, -- Y: qualifyTypeExpr(expr.Y, qf), +- if testing.Verbose() { +- fmt.Printf("%-52s%8s%8s%8s%8s%8s%8s\n", "package ID", "imp", "impBy", "reach", "reachBy", "load", "loadBy") +- for _, id := range ids { +- fmt.Printf("%-52s%8d%8d%8d%8d%8d%8d\n", id, len(imports[id]), len(importedBy[id]), len(reaches[id]), len(reachedBy[id]), len(loads[id]), len(loadedBy[id])) - } +- fmt.Println(strings.Repeat("-", 100)) +- fmt.Printf("%-52s%8s%8s%8s%8s%8s%8s\n", "package ID", "imp", "impBy", "reach", "reachBy", "load", "loadBy") - -- case *ast.ChanType: -- return &ast.ChanType{ -- Arrow: expr.Arrow, -- Begin: expr.Begin, -- Dir: expr.Dir, -- Value: qualifyTypeExpr(expr.Value, qf), +- avg := func(m edgeSet) float64 { +- var avg float64 +- for _, id := range ids { +- s := m[id] +- avg += float64(len(s)) / float64(len(ids)) +- } +- return avg - } +- fmt.Printf("%52s%8.1f%8.1f%8.1f%8.1f%8.1f%8.1f\n", "averages:", avg(imports), avg(importedBy), avg(reaches), avg(reachedBy), avg(loads), avg(loadedBy)) +- } +-} - -- case *ast.Ellipsis: -- return &ast.Ellipsis{ -- Ellipsis: expr.Ellipsis, -- Elt: qualifyTypeExpr(expr.Elt, qf), +-func importMap(id PackageID, meta MetadataSource) map[PackagePath]PackageID { +- imports := make(map[PackagePath]PackageID) +- var recordIDs func(PackageID) +- recordIDs = func(id PackageID) { +- m := meta.Metadata(id) +- if _, ok := imports[m.PkgPath]; ok { +- return - } -- -- case *ast.FuncType: -- return &ast.FuncType{ -- Func: expr.Func, -- Params: qualifyFieldList(expr.Params, qf), -- Results: qualifyFieldList(expr.Results, qf), +- imports[m.PkgPath] = id +- for _, id := range m.DepsByPkgPath { +- recordIDs(id) - } +- } +- for _, id := range meta.Metadata(id).DepsByPkgPath { +- recordIDs(id) +- } +- return imports +-} - -- case *ast.Ident: -- // Unqualified type (builtin, package local, or dot-imported). +-func importFromExportData(pkgPath, exportFile string) (*types.Package, error) { +- file, err := os.Open(exportFile) +- if err != nil { +- return nil, err +- } +- r, err := gcexportdata.NewReader(file) +- if err != nil { +- file.Close() +- return nil, err +- } +- fset := token.NewFileSet() +- tpkg, err := gcexportdata.Read(r, fset, make(map[string]*types.Package), pkgPath) +- file.Close() +- if err != nil { +- return nil, err +- } +- // The export file reported by go/packages is produced by the compiler, which +- // has additional package dependencies due to inlining. +- // +- // Export and re-import so that we only observe dependencies from the +- // exported API. +- var out bytes.Buffer +- err = gcexportdata.Write(&out, fset, tpkg) +- if err != nil { +- return nil, err +- } +- return gcexportdata.Read(&out, token.NewFileSet(), make(map[string]*types.Package), pkgPath) +-} - -- // Don't qualify names that look like builtins. -- // -- // Without type-checking this may be inaccurate. It could be made accurate -- // by doing syntactic object resolution for the entire package, but that -- // does not seem worthwhile and we generally want to avoid using -- // ast.Object, which may be inaccurate. -- if obj := types.Universe.Lookup(expr.Name); obj != nil { -- return expr -- } +-func BenchmarkBuildPackageGraph(b *testing.B) { +- t0 := time.Now() +- exports, meta, err := load(*query, *verify) +- if err != nil { +- b.Fatalf("loading failed: %v", err) +- } +- b.Logf("loaded %d packages in %v", len(exports), time.Since(t0)) +- ctx := context.Background() +- var ids []PackageID +- for id := range exports { +- ids = append(ids, id) +- } +- b.ResetTimer() - -- newName := qf("") -- if newName != "" { -- return &ast.SelectorExpr{ -- X: &ast.Ident{ -- NamePos: expr.Pos(), -- Name: newName, -- }, -- Sel: expr, -- } +- for i := 0; i < b.N; i++ { +- _, err := BuildPackageGraph(ctx, meta, ids, newParser().parse) +- if err != nil { +- b.Fatal(err) - } -- return expr +- } +-} - -- case *ast.IndexExpr: -- return &ast.IndexExpr{ -- X: qualifyTypeExpr(expr.X, qf), -- Lbrack: expr.Lbrack, -- Index: qualifyTypeExpr(expr.Index, qf), -- Rbrack: expr.Rbrack, -- } +-type memoizedParser struct { +- mu sync.Mutex +- files map[span.URI]*futureParse +-} - -- case *typeparams.IndexListExpr: -- indices := make([]ast.Expr, len(expr.Indices)) -- for i, idx := range expr.Indices { -- indices[i] = qualifyTypeExpr(idx, qf) -- } -- return &typeparams.IndexListExpr{ -- X: qualifyTypeExpr(expr.X, qf), -- Lbrack: expr.Lbrack, -- Indices: indices, -- Rbrack: expr.Rbrack, -- } +-type futureParse struct { +- done chan struct{} +- pgf *ParsedGoFile +- err error +-} - -- case *ast.InterfaceType: -- return &ast.InterfaceType{ -- Interface: expr.Interface, -- Methods: qualifyFieldList(expr.Methods, qf), -- Incomplete: expr.Incomplete, -- } +-func newParser() *memoizedParser { +- return &memoizedParser{ +- files: make(map[span.URI]*futureParse), +- } +-} - -- case *ast.MapType: -- return &ast.MapType{ -- Map: expr.Map, -- Key: qualifyTypeExpr(expr.Key, qf), -- Value: qualifyTypeExpr(expr.Value, qf), +-func (p *memoizedParser) parse(ctx context.Context, uri span.URI) (*ParsedGoFile, error) { +- doParse := func(ctx context.Context, uri span.URI) (*ParsedGoFile, error) { +- // TODO(adonovan): hoist this operation outside the benchmark critsec. +- content, err := os.ReadFile(uri.Filename()) +- if err != nil { +- return nil, err - } +- content = astutil.PurgeFuncBodies(content) +- pgf, _ := cache.ParseGoSrc(ctx, token.NewFileSet(), uri, content, source.ParseFull, false) +- return pgf, nil +- } - -- case *ast.ParenExpr: -- return &ast.ParenExpr{ -- Lparen: expr.Lparen, -- Rparen: expr.Rparen, -- X: qualifyTypeExpr(expr.X, qf), +- p.mu.Lock() +- fut, ok := p.files[uri] +- if ok { +- p.mu.Unlock() +- select { +- case <-fut.done: +- case <-ctx.Done(): +- return nil, ctx.Err() - } +- } else { +- fut = &futureParse{done: make(chan struct{})} +- p.files[uri] = fut +- p.mu.Unlock() +- fut.pgf, fut.err = doParse(ctx, uri) +- close(fut.done) +- } +- return fut.pgf, fut.err +-} - -- case *ast.SelectorExpr: -- if id, ok := expr.X.(*ast.Ident); ok { -- // qualified type -- newName := qf(id.Name) -- if newName == "" { -- return expr.Sel -- } -- return &ast.SelectorExpr{ -- X: &ast.Ident{ -- NamePos: id.NamePos, -- Name: newName, -- }, -- Sel: expr.Sel, -- } -- } -- return expr +-type mapMetadataSource struct { +- m map[PackageID]*Metadata +-} - -- case *ast.StarExpr: -- return &ast.StarExpr{ -- Star: expr.Star, -- X: qualifyTypeExpr(expr.X, qf), +-func (s mapMetadataSource) Metadata(id PackageID) *Metadata { +- return s.m[id] +-} +- +-// This function is a compressed version of snapshot.load from the +-// internal/lsp/cache package, for use in testing. +-// +-// TODO(rfindley): it may be valuable to extract this logic from the snapshot, +-// since it is otherwise standalone. +-func load(query string, needExport bool) (map[PackageID]string, MetadataSource, error) { +- cfg := &packages.Config{ +- Dir: *dir, +- Mode: packages.NeedName | +- packages.NeedFiles | +- packages.NeedCompiledGoFiles | +- packages.NeedImports | +- packages.NeedDeps | +- packages.NeedTypesSizes | +- packages.NeedModule | +- packages.NeedEmbedFiles | +- packages.LoadMode(packagesinternal.DepsErrors) | +- packages.LoadMode(packagesinternal.ForTest), +- Tests: true, +- } +- if needExport { +- cfg.Mode |= packages.NeedExportFile // ExportFile is not requested by gopls: this is used to verify reachability +- } +- pkgs, err := packages.Load(cfg, query) +- if err != nil { +- return nil, nil, err +- } +- +- meta := make(map[PackageID]*Metadata) +- var buildMetadata func(pkg *packages.Package) +- buildMetadata = func(pkg *packages.Package) { +- id := PackageID(pkg.ID) +- if meta[id] != nil { +- return +- } +- m := &Metadata{ +- ID: id, +- PkgPath: PackagePath(pkg.PkgPath), +- Name: packageName(pkg.Name), +- ForTest: PackagePath(packagesinternal.GetForTest(pkg)), +- TypesSizes: pkg.TypesSizes, +- LoadDir: cfg.Dir, +- Module: pkg.Module, +- Errors: pkg.Errors, +- DepsErrors: packagesinternal.GetDepsErrors(pkg), - } +- meta[id] = m - -- case *ast.StructType: -- return &ast.StructType{ -- Struct: expr.Struct, -- Fields: qualifyFieldList(expr.Fields, qf), -- Incomplete: expr.Incomplete, +- for _, filename := range pkg.CompiledGoFiles { +- m.CompiledGoFiles = append(m.CompiledGoFiles, span.URIFromPath(filename)) +- } +- for _, filename := range pkg.GoFiles { +- m.GoFiles = append(m.GoFiles, span.URIFromPath(filename)) - } - -- default: -- return expr -- } --} +- m.DepsByImpPath = make(map[ImportPath]PackageID) +- m.DepsByPkgPath = make(map[PackagePath]PackageID) +- for importPath, imported := range pkg.Imports { +- importPath := ImportPath(importPath) - --func qualifyFieldList(fl *ast.FieldList, qf func(string) string) *ast.FieldList { -- if fl == nil { -- return nil -- } -- if fl.List == nil { -- return &ast.FieldList{ -- Closing: fl.Closing, -- Opening: fl.Opening, +- // see note in gopls/internal/lsp/cache/load.go for an explanation of this check. +- if importPath != "unsafe" && len(imported.CompiledGoFiles) == 0 { +- m.DepsByImpPath[importPath] = "" // missing +- continue +- } +- +- m.DepsByImpPath[importPath] = PackageID(imported.ID) +- m.DepsByPkgPath[PackagePath(imported.PkgPath)] = PackageID(imported.ID) +- buildMetadata(imported) - } - } -- list := make([]*ast.Field, 0, len(fl.List)) -- for _, f := range fl.List { -- list = append(list, &ast.Field{ -- Comment: f.Comment, -- Doc: f.Doc, -- Names: f.Names, -- Tag: f.Tag, -- Type: qualifyTypeExpr(f.Type, qf), -- }) -- } -- return &ast.FieldList{ -- Closing: fl.Closing, -- Opening: fl.Opening, -- List: list, +- +- exportFiles := make(map[PackageID]string) +- for _, pkg := range pkgs { +- exportFiles[PackageID(pkg.ID)] = pkg.ExportFile +- buildMetadata(pkg) - } +- return exportFiles, &mapMetadataSource{meta}, nil -} -diff -urN a/gopls/internal/lsp/source/util.go b/gopls/internal/lsp/source/util.go ---- a/gopls/internal/lsp/source/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/util.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,555 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/lsp/source/typerefs/refs.go b/gopls/internal/lsp/source/typerefs/refs.go +--- a/gopls/internal/lsp/source/typerefs/refs.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/typerefs/refs.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,832 +0,0 @@ +-// Copyright 2023 The Go Authors. 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 +-package typerefs - -import ( -- "context" +- "fmt" - "go/ast" -- "go/printer" - "go/token" -- "go/types" -- "path/filepath" -- "regexp" - "sort" -- "strconv" - "strings" - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/safetoken" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/bug" -- "golang.org/x/tools/internal/tokeninternal" +- "golang.org/x/tools/gopls/internal/astutil" +- "golang.org/x/tools/gopls/internal/lsp/frob" +- "golang.org/x/tools/gopls/internal/lsp/source" - "golang.org/x/tools/internal/typeparams" -) - --// IsGenerated gets and reads the file denoted by uri and reports --// whether it contains a "generated file" comment as described at --// https://golang.org/s/generatedcode. +-// Encode analyzes the Go syntax trees of a package, constructs a +-// reference graph, and uses it to compute, for each exported +-// declaration, the set of exported symbols of directly imported +-// packages that it references, perhaps indirectly. -// --// TODO(adonovan): opt: this function does too much. --// Move snapshot.GetFile into the caller (most of which have already done it). --func IsGenerated(ctx context.Context, snapshot Snapshot, uri span.URI) bool { -- fh, err := snapshot.GetFile(ctx, uri) -- if err != nil { -- return false -- } -- pgf, err := snapshot.ParseGo(ctx, fh, ParseHeader) -- if err != nil { -- return false -- } -- for _, commentGroup := range pgf.File.Comments { -- for _, comment := range commentGroup.List { -- if matched := generatedRx.MatchString(comment.Text); matched { -- // Check if comment is at the beginning of the line in source. -- if safetoken.Position(pgf.Tok, comment.Slash).Column == 1 { -- return true -- } -- } -- } -- } -- return false +-// It returns a serializable index of this information. +-// Use Decode to expand the result. +-func Encode(files []*source.ParsedGoFile, id source.PackageID, imports map[source.ImportPath]*source.Metadata) []byte { +- return index(files, id, imports) -} - --// adjustedObjEnd returns the end position of obj, possibly modified for --// package names. +-// Decode decodes a serializable index of symbol +-// reachability produced by Encode. -// --// TODO(rfindley): eliminate this function, by inlining it at callsites where --// it makes sense. --func adjustedObjEnd(obj types.Object) token.Pos { -- nameLen := len(obj.Name()) -- if pkgName, ok := obj.(*types.PkgName); ok { -- // An imported Go package has a package-local, unqualified name. -- // When the name matches the imported package name, there is no -- // identifier in the import spec with the local package name. -- // -- // For example: -- // import "go/ast" // name "ast" matches package name -- // import a "go/ast" // name "a" does not match package name -- // -- // When the identifier does not appear in the source, have the range -- // of the object be the import path, including quotes. -- if pkgName.Imported().Name() == pkgName.Name() { -- nameLen = len(pkgName.Imported().Path()) + len(`""`) -- } -- } -- return obj.Pos() + token.Pos(nameLen) +-// Because many declarations reference the exact same set of symbols, +-// the results are grouped into equivalence classes. +-// Classes are sorted by Decls[0], ascending. +-// The class with empty reachability is omitted. +-// +-// See the package documentation for more details as to what a +-// reference does (and does not) represent. +-func Decode(pkgIndex *PackageIndex, id source.PackageID, data []byte) []Class { +- return decode(pkgIndex, id, data) -} - --// Matches cgo generated comment as well as the proposed standard: +-// A Class is a reachability equivalence class. -// --// https://golang.org/s/generatedcode --var generatedRx = regexp.MustCompile(`// .*DO NOT EDIT\.?`) -- --// FileKindForLang returns the file kind associated with the given language ID, --// or UnknownKind if the language ID is not recognized. --func FileKindForLang(langID string) FileKind { -- switch langID { -- case "go": -- return Go -- case "go.mod": -- return Mod -- case "go.sum": -- return Sum -- case "tmpl", "gotmpl": -- return Tmpl -- case "go.work": -- return Work -- default: -- return UnknownKind -- } +-// It attests that each exported package-level declaration in Decls +-// references (perhaps indirectly) one of the external (imported) +-// symbols in Refs. +-// +-// Because many Decls reach the same Refs, +-// it is more efficient to group them into classes. +-type Class struct { +- Decls []string // sorted set of names of exported decls with same reachability +- Refs []Symbol // set of external symbols, in ascending (PackageID, Name) order -} - --// nodeAtPos returns the index and the node whose position is contained inside --// the node list. --func nodeAtPos(nodes []ast.Node, pos token.Pos) (ast.Node, int) { -- if nodes == nil { -- return nil, -1 -- } -- for i, node := range nodes { -- if node.Pos() <= pos && pos <= node.End() { -- return node, i -- } -- } -- return nil, -1 +-// A Symbol represents an external (imported) symbol +-// referenced by the analyzed package. +-type Symbol struct { +- Package IndexID // w.r.t. PackageIndex passed to decoder +- Name string -} - --// FormatNode returns the "pretty-print" output for an ast node. --func FormatNode(fset *token.FileSet, n ast.Node) string { -- var buf strings.Builder -- if err := printer.Fprint(&buf, fset, n); err != nil { -- return "" -- } -- return buf.String() --} +-// An IndexID is a small integer that uniquely identifies a package within a +-// given PackageIndex. +-type IndexID int - --// FormatNodeFile is like FormatNode, but requires only the token.File for the --// syntax containing the given ast node. --func FormatNodeFile(file *token.File, n ast.Node) string { -- fset := FileSetFor(file) -- return FormatNode(fset, n) +-// -- internals -- +- +-// A symbolSet is a set of symbols used internally during index construction. +-// +-// TODO(adonovan): opt: evaluate unifying Symbol and symbol. +-// (Encode would have to create a private PackageIndex.) +-type symbolSet map[symbol]bool +- +-// A symbol is the internal representation of an external +-// (imported) symbol referenced by the analyzed package. +-type symbol struct { +- pkg source.PackageID +- name string -} - --// FileSetFor returns a new FileSet containing a sequence of new Files with --// the same base, size, and line as the input files, for use in APIs that --// require a FileSet. +-// declNode holds information about a package-level declaration +-// (or more than one with the same name, in ill-typed code). -// --// Precondition: the input files must be non-overlapping, and sorted in order --// of their Base. --func FileSetFor(files ...*token.File) *token.FileSet { -- fset := token.NewFileSet() -- for _, f := range files { -- f2 := fset.AddFile(f.Name(), f.Base(), f.Size()) -- lines := tokeninternal.GetLines(f) -- f2.SetLines(lines) -- } -- return fset +-// It is a node in the symbol reference graph, whose outgoing edges +-// are of two kinds: intRefs and extRefs. +-type declNode struct { +- name string +- rep *declNode // canonical representative of this SCC (initially self) +- +- // outgoing graph edges +- intRefs map[*declNode]bool // to symbols in this package +- extRefs symbolSet // to imported symbols +- extRefsClass int // extRefs equivalence class number (-1 until set at end) +- +- // Tarjan's SCC algorithm +- index, lowlink int32 // Tarjan numbering +- scc int32 // -ve => on stack; 0 => unvisited; +ve => node is root of a found SCC -} - --// Deref returns a pointer's element type, traversing as many levels as needed. --// Otherwise it returns typ. +-// state holds the working state of the Refs algorithm for a single package. -// --// It can return a pointer type for cyclic types (see golang/go#45510). --func Deref(typ types.Type) types.Type { -- var seen map[types.Type]struct{} -- for { -- p, ok := typ.Underlying().(*types.Pointer) -- if !ok { -- return typ -- } -- if _, ok := seen[p.Elem()]; ok { -- return typ -- } +-// The number of distinct symbols referenced by a single package +-// (measured across all of kubernetes), was found to be: +-// - max = 1750. +-// - Several packages reference > 100 symbols. +-// - p95 = 32, p90 = 22, p50 = 8. +-type state struct { +- // numbering of unique symbol sets +- class []symbolSet // unique symbol sets +- classIndex map[string]int // index of above (using SymbolSet.hash as key) - -- typ = p.Elem() +- // Tarjan's SCC algorithm +- index int32 +- stack []*declNode +-} - -- if seen == nil { -- seen = make(map[types.Type]struct{}) -- } -- seen[typ] = struct{}{} +-// getClassIndex returns the small integer (an index into +-// state.class) that identifies the given set. +-func (st *state) getClassIndex(set symbolSet) int { +- key := classKey(set) +- i, ok := st.classIndex[key] +- if !ok { +- i = len(st.class) +- st.classIndex[key] = i +- st.class = append(st.class, set) - } +- return i -} - --func SortDiagnostics(d []*Diagnostic) { -- sort.Slice(d, func(i int, j int) bool { -- return CompareDiagnostic(d[i], d[j]) < 0 +-// appendSorted appends the symbols to syms, sorts by ascending +-// (PackageID, name), and returns the result. +-// The argument must be an empty slice, ideally with capacity len(set). +-func (set symbolSet) appendSorted(syms []symbol) []symbol { +- for sym := range set { +- syms = append(syms, sym) +- } +- sort.Slice(syms, func(i, j int) bool { +- x, y := syms[i], syms[j] +- if x.pkg != y.pkg { +- return x.pkg < y.pkg +- } +- return x.name < y.name - }) +- return syms -} - --func CompareDiagnostic(a, b *Diagnostic) int { -- if r := protocol.CompareRange(a.Range, b.Range); r != 0 { -- return r +-// classKey returns a key such that equal keys imply equal sets. +-// (e.g. a sorted string representation, or a cryptographic hash of same). +-func classKey(set symbolSet) string { +- // Sort symbols into a stable order. +- // TODO(adonovan): opt: a cheap crypto hash (e.g. BLAKE2b) might +- // make a cheaper map key than a large string. +- // Try using a hasher instead of a builder. +- var s strings.Builder +- for _, sym := range set.appendSorted(make([]symbol, 0, len(set))) { +- fmt.Fprintf(&s, "%s:%s;", sym.pkg, sym.name) - } -- if a.Source < b.Source { -- return -1 +- return s.String() +-} +- +-// index builds the reference graph and encodes the index. +-func index(pgfs []*source.ParsedGoFile, id source.PackageID, imports map[source.ImportPath]*source.Metadata) []byte { +- // First pass: gather package-level names and create a declNode for each. +- // +- // In ill-typed code, there may be multiple declarations of the +- // same name; a single declInfo node will represent them all. +- decls := make(map[string]*declNode) +- addDecl := func(id *ast.Ident) { +- if name := id.Name; name != "_" && decls[name] == nil { +- node := &declNode{name: name, extRefsClass: -1} +- node.rep = node +- decls[name] = node +- } - } -- if a.Source > b.Source { -- return +1 +- for _, pgf := range pgfs { +- for _, d := range pgf.File.Decls { +- switch d := d.(type) { +- case *ast.GenDecl: +- switch d.Tok { +- case token.TYPE: +- for _, spec := range d.Specs { +- addDecl(spec.(*ast.TypeSpec).Name) +- } +- +- case token.VAR, token.CONST: +- for _, spec := range d.Specs { +- for _, ident := range spec.(*ast.ValueSpec).Names { +- addDecl(ident) +- } +- } +- } +- +- case *ast.FuncDecl: +- // non-method functions +- if d.Recv.NumFields() == 0 { +- addDecl(d.Name) +- } +- } +- } - } -- if a.Message < b.Message { -- return -1 +- +- // Second pass: process files to collect referring identifiers. +- st := &state{classIndex: make(map[string]int)} +- for _, pgf := range pgfs { +- visitFile(pgf.File, imports, decls) - } -- if a.Message > b.Message { -- return +1 +- +- // Find the strong components of the declNode graph +- // using Tarjan's algorithm, and coalesce each component. +- st.index = 1 +- for _, decl := range decls { +- if decl.index == 0 { // unvisited +- st.visit(decl) +- } - } -- return 0 --} - --// findFileInDeps finds package metadata containing URI in the transitive --// dependencies of m. When using the Go command, the answer is unique. --// --// TODO(rfindley): refactor to share logic with findPackageInDeps? --func findFileInDeps(s MetadataSource, m *Metadata, uri span.URI) *Metadata { -- seen := make(map[PackageID]bool) -- var search func(*Metadata) *Metadata -- search = func(m *Metadata) *Metadata { -- if seen[m.ID] { -- return nil +- // TODO(adonovan): opt: consider compressing the serialized +- // representation by recording not the classes but the DAG of +- // non-trivial union operations (the "pointer equivalence" +- // optimization of Hardekopf & Lin). Unlike that algorithm, +- // which piggybacks on SCC coalescing, in our case it would +- // be better to make a forward traversal from the exported +- // decls, since it avoids visiting unreachable nodes, and +- // results in a dense (not sparse) numbering of the sets. +- +- // Tabulate the unique reachability sets of +- // each exported package member. +- classNames := make(map[int][]string) // set of decls (names) for a given reachability set +- for name, decl := range decls { +- if !ast.IsExported(name) { +- continue - } -- seen[m.ID] = true -- for _, cgf := range m.CompiledGoFiles { -- if cgf == uri { -- return m -- } +- +- decl = decl.find() +- +- // Skip decls with empty reachability. +- if len(decl.extRefs) == 0 { +- continue - } -- for _, dep := range m.DepsByPkgPath { -- m := s.Metadata(dep) -- if m == nil { -- bug.Reportf("nil metadata for %q", dep) -- continue -- } -- if found := search(m); found != nil { -- return found -- } +- +- // Canonicalize the set (and memoize). +- class := decl.extRefsClass +- if class < 0 { +- class = st.getClassIndex(decl.extRefs) +- decl.extRefsClass = class - } -- return nil +- classNames[class] = append(classNames[class], name) - } -- return search(m) --} - --// UnquoteImportPath returns the unquoted import path of s, --// or "" if the path is not properly quoted. --func UnquoteImportPath(s *ast.ImportSpec) ImportPath { -- path, err := strconv.Unquote(s.Path.Value) -- if err != nil { -- return "" -- } -- return ImportPath(path) +- return encode(classNames, st.class) -} - --// NodeContains returns true if a node encloses a given position pos. --func NodeContains(n ast.Node, pos token.Pos) bool { -- return n != nil && n.Pos() <= pos && pos <= n.End() --} +-// visitFile inspects the file syntax for referring identifiers, and +-// populates the internal and external references of decls. +-func visitFile(file *ast.File, imports map[source.ImportPath]*source.Metadata, decls map[string]*declNode) { +- // Import information for this file. Multiple packages +- // may be referenced by a given name in the presence +- // of type errors (or multiple dot imports, which are +- // keyed by "."). +- fileImports := make(map[string][]source.PackageID) - --// CollectScopes returns all scopes in an ast path, ordered as innermost scope --// first. --func CollectScopes(info *types.Info, path []ast.Node, pos token.Pos) []*types.Scope { -- // scopes[i], where i import path mapping. -- inverseDeps := make(map[PackageID]PackagePath) -- for path, id := range m.DepsByPkgPath { -- inverseDeps[id] = path -- } -- importsByPkgPath := make(map[PackagePath]ImportPath) // best import paths by pkgPath -- for impPath, id := range m.DepsByImpPath { -- if id == "" { -- continue -- } -- pkgPath := inverseDeps[id] -- _, hasPath := importsByPkgPath[pkgPath] -- _, hasImp := localNames[impPath] -- // In rare cases, there may be multiple import paths with the same package -- // path. In such scenarios, prefer an import path that already exists in -- // the file. -- if !hasPath || hasImp { -- importsByPkgPath[pkgPath] = impPath +- case token.VAR, token.CONST: +- for _, spec := range d.Specs { +- spec := spec.(*ast.ValueSpec) +- for _, name := range spec.Names { +- visit(name, spec, nil) +- } +- } +- } +- +- case *ast.FuncDecl: +- // This check for NumFields() > 0 is consistent with go/types, +- // which reports an error but treats the declaration like a +- // normal function when Recv is non-nil but empty +- // (as in func () f()). +- if d.Recv.NumFields() > 0 { +- // Method. Associate it with the receiver. +- _, id, typeParams := astutil.UnpackRecv(d.Recv.List[0].Type) +- if id != nil { +- var tparams map[string]bool +- if len(typeParams) > 0 { +- tparams = make(map[string]bool) +- for _, tparam := range typeParams { +- if tparam.Name != "_" { +- tparams[tparam.Name] = true +- } +- } +- } +- visit(id, d, tparams) +- } +- } else { +- // Non-method. +- tparams := tparamsMap(typeparams.ForFuncType(d.Type)) +- visit(d.Name, d, tparams) +- } - } - } +-} - -- return func(pkgName PackageName, impPath ImportPath, pkgPath PackagePath) string { -- // If supplied, translate the package path to an import path in the source -- // package. -- if pkgPath != "" { -- if srcImp := importsByPkgPath[pkgPath]; srcImp != "" { -- impPath = srcImp -- } -- if pkgPath == m.PkgPath { -- return "" +-// tparamsMap returns a set recording each name declared by the provided field +-// list. It so happens that we only care about names declared by type parameter +-// lists. +-func tparamsMap(tparams *ast.FieldList) map[string]bool { +- if tparams == nil || len(tparams.List) == 0 { +- return nil +- } +- m := make(map[string]bool) +- for _, f := range tparams.List { +- for _, name := range f.Names { +- if name.Name != "_" { +- m[name.Name] = true - } - } -- if localName, ok := localNames[impPath]; ok && impPath != "" { -- return string(localName) -- } -- if pkgName != "" { -- return string(pkgName) -- } -- idx := strings.LastIndexByte(string(impPath), '/') -- return string(impPath[idx+1:]) - } +- return m -} - --// importInfo collects information about the import specified by imp, --// extracting its file-local name, package name, import path, and package path. --// --// If metadata is missing for the import, the resulting package name and --// package path may be empty, and the file local name may be guessed based on --// the import path. +-// A refVisitor visits referring identifiers and dotted identifiers. -// --// Note: previous versions of this helper used a PackageID->PackagePath map --// extracted from m, for extracting package path even in the case where --// metadata for a dep was missing. This should not be necessary, as we should --// always have metadata for IDs contained in DepsByPkgPath. --func importInfo(s MetadataSource, imp *ast.ImportSpec, m *Metadata) (string, PackageName, ImportPath, PackagePath) { -- var ( -- name string // local name -- pkgName PackageName -- impPath = UnquoteImportPath(imp) -- pkgPath PackagePath -- ) +-// For a referring identifier I, name="I" and sel="". For a dotted identifier +-// q.I, name="q" and sel="I". +-type refVisitor = func(name, sel string) - -- // If the import has a local name, use it. -- if imp.Name != nil { -- name = imp.Name.Name -- } +-// visitDeclOrSpec visits referring idents or dotted idents that may affect +-// the type of the declaration at the given node, which must be an ast.Decl or +-// ast.Spec. +-func visitDeclOrSpec(node ast.Node, f refVisitor) { +- // Declarations +- switch n := node.(type) { +- // ImportSpecs should not appear here, and will panic in the default case. - -- // Try to find metadata for the import. If successful and there is no local -- // name, the package name is the local name. -- if depID := m.DepsByImpPath[impPath]; depID != "" { -- if depm := s.Metadata(depID); depm != nil { -- if name == "" { -- name = string(depm.Name) -- } -- pkgName = depm.Name -- pkgPath = depm.PkgPath +- case *ast.ValueSpec: +- // Skip Doc, Names, Comments, which do not affect the decl type. +- // Initializers only affect the type of a value spec if the type is unset. +- if n.Type != nil { +- visitExpr(n.Type, f) +- } else { // only need to walk expr list if type is nil +- visitExprList(n.Values, f) - } -- } - -- // If the local name is still unknown, guess it based on the import path. -- if name == "" { -- idx := strings.LastIndexByte(string(impPath), '/') -- name = string(impPath[idx+1:]) +- case *ast.TypeSpec: +- // Skip Doc, Name, and Comment, which do not affect the decl type. +- if tparams := typeparams.ForTypeSpec(n); tparams != nil { +- visitFieldList(tparams, f) +- } +- visitExpr(n.Type, f) +- +- case *ast.BadDecl: +- // nothing to do +- +- // We should not reach here with a GenDecl, so panic below in the default case. +- +- case *ast.FuncDecl: +- // Skip Doc, Name, and Body, which do not affect the type. +- // Recv is handled by Refs: methods are associated with their type. +- visitExpr(n.Type, f) +- +- default: +- panic(fmt.Sprintf("unexpected node type %T", node)) - } -- return name, pkgName, impPath, pkgPath -} - --// isDirective reports whether c is a comment directive. +-// visitExpr visits referring idents and dotted idents that may affect the +-// type of expr. -// --// Copied and adapted from go/src/go/ast/ast.go. --func isDirective(c string) bool { -- if len(c) < 3 { -- return false -- } -- if c[1] != '/' { -- return false -- } -- //-style comment (no newline at the end) -- c = c[2:] -- if len(c) == 0 { -- // empty line -- return false +-// visitExpr can't reliably distinguish a dotted ident pkg.X from a +-// selection expr.f or T.method. +-func visitExpr(expr ast.Expr, f refVisitor) { +- switch n := expr.(type) { +- // These four cases account for about two thirds of all nodes, +- // so we place them first to shorten the common control paths. +- // (See go.dev/cl/480915.) +- case *ast.Ident: +- f(n.Name, "") +- +- case *ast.BasicLit: +- // nothing to do +- +- case *ast.SelectorExpr: +- if ident, ok := n.X.(*ast.Ident); ok { +- f(ident.Name, n.Sel.Name) +- } else { +- visitExpr(n.X, f) +- // Skip n.Sel as we don't care about which field or method is selected, +- // as we'll have recorded an edge to all declarations relevant to the +- // receiver type via visiting n.X above. +- } +- +- case *ast.CallExpr: +- visitExpr(n.Fun, f) +- visitExprList(n.Args, f) // args affect types for unsafe.Sizeof or builtins or generics +- +- // Expressions +- case *ast.Ellipsis: +- if n.Elt != nil { +- visitExpr(n.Elt, f) +- } +- +- case *ast.FuncLit: +- visitExpr(n.Type, f) +- // Skip Body, which does not affect the type. +- +- case *ast.CompositeLit: +- if n.Type != nil { +- visitExpr(n.Type, f) +- } +- // Skip Elts, which do not affect the type. +- +- case *ast.ParenExpr: +- visitExpr(n.X, f) +- +- case *ast.IndexExpr: +- visitExpr(n.X, f) +- visitExpr(n.Index, f) // may affect type for instantiations +- +- case *typeparams.IndexListExpr: +- visitExpr(n.X, f) +- for _, index := range n.Indices { +- visitExpr(index, f) // may affect the type for instantiations +- } +- +- case *ast.SliceExpr: +- visitExpr(n.X, f) +- // skip Low, High, and Max, which do not affect type. +- +- case *ast.TypeAssertExpr: +- // Skip X, as it doesn't actually affect the resulting type of the type +- // assertion. +- if n.Type != nil { +- visitExpr(n.Type, f) +- } +- +- case *ast.StarExpr: +- visitExpr(n.X, f) +- +- case *ast.UnaryExpr: +- visitExpr(n.X, f) +- +- case *ast.BinaryExpr: +- visitExpr(n.X, f) +- visitExpr(n.Y, f) +- +- case *ast.KeyValueExpr: +- panic("unreachable") // unreachable, as we don't descend into elts of composite lits. +- +- case *ast.ArrayType: +- if n.Len != nil { +- visitExpr(n.Len, f) +- } +- visitExpr(n.Elt, f) +- +- case *ast.StructType: +- visitFieldList(n.Fields, f) +- +- case *ast.FuncType: +- if tparams := typeparams.ForFuncType(n); tparams != nil { +- visitFieldList(tparams, f) +- } +- if n.Params != nil { +- visitFieldList(n.Params, f) +- } +- if n.Results != nil { +- visitFieldList(n.Results, f) +- } +- +- case *ast.InterfaceType: +- visitFieldList(n.Methods, f) +- +- case *ast.MapType: +- visitExpr(n.Key, f) +- visitExpr(n.Value, f) +- +- case *ast.ChanType: +- visitExpr(n.Value, f) +- +- case *ast.BadExpr: +- // nothing to do +- +- default: +- panic(fmt.Sprintf("ast.Walk: unexpected node type %T", n)) - } -- // "//line " is a line directive. -- // (The // has been removed.) -- if strings.HasPrefix(c, "line ") { -- return true +-} +- +-func visitExprList(list []ast.Expr, f refVisitor) { +- for _, x := range list { +- visitExpr(x, f) - } +-} - -- // "//[a-z0-9]+:[a-z0-9]" -- // (The // has been removed.) -- colon := strings.Index(c, ":") -- if colon <= 0 || colon+1 >= len(c) { -- return false +-func visitFieldList(n *ast.FieldList, f refVisitor) { +- for _, field := range n.List { +- visitExpr(field.Type, f) - } -- for i := 0; i <= colon+1; i++ { -- if i == colon { -- continue +-} +- +-// -- strong component graph construction (plundered from go/pointer) -- +- +-// visit implements the depth-first search of Tarjan's SCC algorithm +-// (see https://doi.org/10.1137/0201010). +-// Precondition: x is canonical. +-func (st *state) visit(x *declNode) { +- checkCanonical(x) +- x.index = st.index +- x.lowlink = st.index +- st.index++ +- +- st.stack = append(st.stack, x) // push +- assert(x.scc == 0, "node revisited") +- x.scc = -1 +- +- for y := range x.intRefs { +- // Loop invariant: x is canonical. +- +- y := y.find() +- +- if x == y { +- continue // nodes already coalesced - } -- b := c[i] -- if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') { -- return false +- +- switch { +- case y.scc > 0: +- // y is already a collapsed SCC +- +- case y.scc < 0: +- // y is on the stack, and thus in the current SCC. +- if y.index < x.lowlink { +- x.lowlink = y.index +- } +- +- default: +- // y is unvisited; visit it now. +- st.visit(y) +- // Note: x and y are now non-canonical. +- +- x = x.find() +- +- if y.lowlink < x.lowlink { +- x.lowlink = y.lowlink +- } - } - } -- return true --} +- checkCanonical(x) - --// InDir checks whether path is in the file tree rooted at dir. --// It checks only the lexical form of the file names. --// It does not consider symbolic links. --// --// Copied from go/src/cmd/go/internal/search/search.go. --func InDir(dir, path string) bool { -- pv := strings.ToUpper(filepath.VolumeName(path)) -- dv := strings.ToUpper(filepath.VolumeName(dir)) -- path = path[len(pv):] -- dir = dir[len(dv):] -- switch { -- default: -- return false -- case pv != dv: -- return false -- case len(path) == len(dir): -- if path == dir { -- return true -- } -- return false -- case dir == "": -- return path != "" -- case len(path) > len(dir): -- if dir[len(dir)-1] == filepath.Separator { -- if path[:len(dir)] == dir { -- return path[len(dir):] != "" +- // Is x the root of an SCC? +- if x.lowlink == x.index { +- // Coalesce all nodes in the SCC. +- for { +- // Pop y from stack. +- i := len(st.stack) - 1 +- y := st.stack[i] +- st.stack = st.stack[:i] +- +- checkCanonical(x) +- checkCanonical(y) +- +- if x == y { +- break // SCC is complete. - } -- return false +- coalesce(x, y) - } -- if path[len(dir)] == filepath.Separator && path[:len(dir)] == dir { -- if len(path) == len(dir)+1 { -- return true +- +- // Accumulate union of extRefs over +- // internal edges (to other SCCs). +- for y := range x.intRefs { +- y := y.find() +- if y == x { +- continue // already coalesced +- } +- assert(y.scc == 1, "edge to non-scc node") +- for z := range y.extRefs { +- if x.extRefs == nil { +- x.extRefs = make(symbolSet) +- } +- x.extRefs[z] = true // extRefs: x U= y - } -- return path[len(dir)+1:] != "" - } -- return false +- +- x.scc = 1 - } -} - --// IsValidImport returns whether importPkgPath is importable --// by pkgPath --func IsValidImport(pkgPath, importPkgPath PackagePath) bool { -- i := strings.LastIndex(string(importPkgPath), "/internal/") -- if i == -1 { -- return true +-// coalesce combines two nodes in the strong component graph. +-// Precondition: x and y are canonical. +-func coalesce(x, y *declNode) { +- // x becomes y's canonical representative. +- y.rep = x +- +- // x accumulates y's internal references. +- for z := range y.intRefs { +- x.intRefs[z] = true - } -- // TODO(rfindley): this looks wrong: IsCommandLineArguments is meant to -- // operate on package IDs, not package paths. -- if IsCommandLineArguments(PackageID(pkgPath)) { -- return true +- y.intRefs = nil +- +- // x accumulates y's external references. +- for z := range y.extRefs { +- if x.extRefs == nil { +- x.extRefs = make(symbolSet) +- } +- x.extRefs[z] = true - } -- // TODO(rfindley): this is wrong. mod.testx/p should not be able to -- // import mod.test/internal: https://go.dev/play/p/-Ca6P-E4V4q -- return strings.HasPrefix(string(pkgPath), string(importPkgPath[:i])) +- y.extRefs = nil -} - --// IsCommandLineArguments reports whether a given value denotes --// "command-line-arguments" package, which is a package with an unknown ID --// created by the go command. It can have a test variant, which is why callers --// should not check that a value equals "command-line-arguments" directly. --func IsCommandLineArguments(id PackageID) bool { -- return strings.Contains(string(id), "command-line-arguments") +-// find returns the canonical node decl. +-// (The nodes form a disjoint set forest.) +-func (decl *declNode) find() *declNode { +- rep := decl.rep +- if rep != decl { +- rep = rep.find() +- decl.rep = rep // simple path compression (no union-by-rank) +- } +- return rep -} - --// embeddedIdent returns the type name identifier for an embedding x, if x in a --// valid embedding. Otherwise, it returns nil. +-const debugSCC = false // enable assertions in strong-component algorithm +- +-func checkCanonical(x *declNode) { +- if debugSCC { +- assert(x == x.find(), "not canonical") +- } +-} +- +-func assert(cond bool, msg string) { +- if debugSCC && !cond { +- panic(msg) +- } +-} +- +-// -- serialization -- +- +-// (The name says gob but in fact we use frob.) +-var classesCodec = frob.CodecFor[gobClasses]() +- +-type gobClasses struct { +- Strings []string // table of strings (PackageIDs and names) +- Classes []gobClass +-} +- +-type gobClass struct { +- Decls []int32 // indices into gobClasses.Strings +- Refs []int32 // list of (package, name) pairs, each an index into gobClasses.Strings +-} +- +-// encode encodes the equivalence classes, +-// (classNames[i], classes[i]), for i in range classes. -// --// Spec: An embedded field must be specified as a type name T or as a pointer --// to a non-interface type name *T --func embeddedIdent(x ast.Expr) *ast.Ident { -- if star, ok := x.(*ast.StarExpr); ok { -- x = star.X +-// With the current encoding, across kubernetes, +-// the encoded size distribution has +-// p50 = 511B, p95 = 4.4KB, max = 108K. +-func encode(classNames map[int][]string, classes []symbolSet) []byte { +- payload := gobClasses{ +- Classes: make([]gobClass, 0, len(classNames)), - } -- switch ix := x.(type) { // check for instantiated receivers -- case *ast.IndexExpr: -- x = ix.X -- case *typeparams.IndexListExpr: -- x = ix.X +- +- // index of unique strings +- strings := make(map[string]int32) +- stringIndex := func(s string) int32 { +- i, ok := strings[s] +- if !ok { +- i = int32(len(payload.Strings)) +- strings[s] = i +- payload.Strings = append(payload.Strings, s) +- } +- return i - } -- switch x := x.(type) { -- case *ast.Ident: -- return x -- case *ast.SelectorExpr: -- if _, ok := x.X.(*ast.Ident); ok { -- return x.Sel +- +- var refs []symbol // recycled temporary +- for class, names := range classNames { +- set := classes[class] +- +- // names, sorted +- sort.Strings(names) +- gobDecls := make([]int32, len(names)) +- for i, name := range names { +- gobDecls[i] = stringIndex(name) +- } +- +- // refs, sorted by ascending (PackageID, name) +- gobRefs := make([]int32, 0, 2*len(set)) +- for _, sym := range set.appendSorted(refs[:0]) { +- gobRefs = append(gobRefs, +- stringIndex(string(sym.pkg)), +- stringIndex(sym.name)) - } +- payload.Classes = append(payload.Classes, gobClass{ +- Decls: gobDecls, +- Refs: gobRefs, +- }) - } -- return nil +- +- return classesCodec.Encode(payload) -} -diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.go ---- a/gopls/internal/lsp/source/view.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/view.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,857 +0,0 @@ --// Copyright 2018 The Go Authors. All rights reserved. +- +-func decode(pkgIndex *PackageIndex, id source.PackageID, data []byte) []Class { +- var payload gobClasses +- classesCodec.Decode(data, &payload) +- +- classes := make([]Class, len(payload.Classes)) +- for i, gobClass := range payload.Classes { +- decls := make([]string, len(gobClass.Decls)) +- for i, decl := range gobClass.Decls { +- decls[i] = payload.Strings[decl] +- } +- refs := make([]Symbol, len(gobClass.Refs)/2) +- for i := range refs { +- pkgID := pkgIndex.IndexID(source.PackageID(payload.Strings[gobClass.Refs[2*i]])) +- name := payload.Strings[gobClass.Refs[2*i+1]] +- refs[i] = Symbol{Package: pkgID, Name: name} +- } +- classes[i] = Class{ +- Decls: decls, +- Refs: refs, +- } +- } +- +- // Sort by ascending Decls[0]. +- // TODO(adonovan): move sort to encoder. Determinism is good. +- sort.Slice(classes, func(i, j int) bool { +- return classes[i].Decls[0] < classes[j].Decls[0] +- }) +- +- return classes +-} +diff -urN a/gopls/internal/lsp/source/typerefs/refs_test.go b/gopls/internal/lsp/source/typerefs/refs_test.go +--- a/gopls/internal/lsp/source/typerefs/refs_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/typerefs/refs_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,558 +0,0 @@ +-// Copyright 2023 The Go Authors. 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 +-package typerefs_test - -import ( -- "bytes" - "context" -- "crypto/sha256" -- "errors" - "fmt" -- "go/ast" -- "go/scanner" - "go/token" -- "go/types" -- "io" +- "sort" +- "testing" - -- "golang.org/x/mod/modfile" -- "golang.org/x/tools/go/analysis" -- "golang.org/x/tools/go/packages" -- "golang.org/x/tools/go/types/objectpath" -- "golang.org/x/tools/gopls/internal/govulncheck" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/safetoken" -- "golang.org/x/tools/gopls/internal/lsp/source/methodsets" +- "github.com/google/go-cmp/cmp" +- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/source/typerefs" - "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event/label" -- "golang.org/x/tools/internal/event/tag" -- "golang.org/x/tools/internal/gocommand" -- "golang.org/x/tools/internal/imports" -- "golang.org/x/tools/internal/packagesinternal" +- "golang.org/x/tools/internal/testenv" -) - --// A GlobalSnapshotID uniquely identifies a snapshot within this process and --// increases monotonically with snapshot creation time. --// --// We use a distinct integral type for global IDs to help enforce correct --// usage. --type GlobalSnapshotID uint64 +-// TestRefs checks that the analysis reports, for each exported member +-// of the test package ("p"), its correct dependencies on exported +-// members of its direct imports (e.g. "ext"). +-func TestRefs(t *testing.T) { +- ctx := context.Background() - --// Snapshot represents the current state for the given view. --type Snapshot interface { -- // SequenceID is the sequence id of this snapshot within its containing -- // view. -- // -- // Relative to their view sequence ids are monotonically increasing, but this -- // does not hold globally: when new views are created their initial snapshot -- // has sequence ID 0. For operations that span multiple views, use global -- // IDs. -- SequenceID() uint64 +- tests := []struct { +- label string +- srcs []string // source for the local package; package name must be p +- imports map[string]string // for simplicity: importPath -> pkgID/pkgName (we set pkgName == pkgID); 'ext' is always available. +- want map[string][]string // decl name -> id. +- go118 bool // test uses generics +- allowErrs bool // whether we expect parsing errors +- }{ +- { +- label: "empty package", +- want: map[string][]string{}, +- }, +- { +- label: "fields", +- srcs: []string{` +-package p - -- // GlobalID is a globally unique identifier for this snapshot. Global IDs are -- // monotonic: subsequent snapshots will have higher global ID, though -- // subsequent snapshots in a view may not have adjacent global IDs. -- GlobalID() GlobalSnapshotID +-import "ext" +- +-type A struct{ b B } +-type B func(c C) (d D) +-type C ext.C +-type D ext.D +- +-// Should not be referenced by field names. +-type b ext.B_ +-type c int.C_ +-type d ext.D_ +-`}, +- want: map[string][]string{ +- "A": {"ext.C", "ext.D"}, +- "B": {"ext.C", "ext.D"}, +- "C": {"ext.C"}, +- "D": {"ext.D"}, +- }, +- }, +- { +- label: "embedding", +- srcs: []string{` +-package p - -- // View returns the View associated with this snapshot. -- View() View +-import "ext" - -- // BackgroundContext returns a context used for all background processing -- // on behalf of this snapshot. -- BackgroundContext() context.Context +-type A struct{ +- B +- _ struct { +- C +- } +- D +-} +-type B ext.B +-type C ext.C +-type D interface{ +- B +-} +-`}, +- want: map[string][]string{ +- "A": {"ext.B", "ext.C"}, +- "B": {"ext.B"}, +- "C": {"ext.C"}, +- "D": {"ext.B"}, +- }, +- }, +- { +- label: "constraint embedding", +- srcs: []string{` +-package p - -- // ValidBuildConfiguration returns true if there is some error in the -- // user's workspace. In particular, if they are both outside of a module -- // and their GOPATH. -- ValidBuildConfiguration() bool +-import "ext" - -- // FindFile returns the FileHandle for the given URI, if it is already -- // in the given snapshot. -- FindFile(uri span.URI) FileHandle +-type A interface{ +- int | B | ~C +- struct{D} +-} - -- // GetFile returns the FileHandle for a given URI, initializing it if it is -- // not already part of the snapshot. -- GetFile(ctx context.Context, uri span.URI) (FileHandle, error) +-type B ext.B +-type C ext.C +-type D ext.D +-`}, +- want: map[string][]string{ +- "A": {"ext.B", "ext.C", "ext.D"}, +- "B": {"ext.B"}, +- "C": {"ext.C"}, +- "D": {"ext.D"}, +- }, +- go118: true, +- }, +- { +- label: "funcs", +- srcs: []string{` +-package p - -- // AwaitInitialized waits until the snapshot's view is initialized. -- AwaitInitialized(ctx context.Context) +-import "ext" +- +-type A ext.A +-type B ext.B +-const C B = 2 +-func F(A) B { +- return C +-} +-var V = F(W) +-var W A +-`}, +- want: map[string][]string{ +- "A": {"ext.A"}, +- "B": {"ext.B"}, +- "C": {"ext.B"}, +- "F": {"ext.A", "ext.B"}, +- "V": { +- "ext.A", // via F +- "ext.B", // via W: can't be eliminated: F could be builtin or generic +- }, +- "W": {"ext.A"}, +- }, +- }, +- { +- label: "methods", +- srcs: []string{`package p - -- // IsOpen returns whether the editor currently has a file open. -- IsOpen(uri span.URI) bool +-import "ext" - -- // IgnoredFile reports if a file would be ignored by a `go list` of the whole -- // workspace. -- IgnoredFile(uri span.URI) bool +-type A ext.A +-type B ext.B +-`, `package p - -- // Templates returns the .tmpl files -- Templates() map[span.URI]FileHandle +-func (A) M(B) +-func (*B) M(A) +-`}, +- want: map[string][]string{ +- "A": {"ext.A", "ext.B"}, +- "B": {"ext.A", "ext.B"}, +- }, +- }, +- { +- label: "initializers", +- srcs: []string{` +-package p - -- // ParseGo returns the parsed AST for the file. -- // If the file is not available, returns nil and an error. -- // Position information is added to FileSet(). -- ParseGo(ctx context.Context, fh FileHandle, mode ParseMode) (*ParsedGoFile, error) +-import "ext" - -- // Analyze runs the specified analyzers on the given package at this snapshot. -- Analyze(ctx context.Context, id PackageID, analyzers []*Analyzer) ([]*Diagnostic, error) +-var A b = C // type does not depend on C +-type b ext.B +-var C = d // type does depend on D +-var d b - -- // RunGoCommandPiped runs the given `go` command, writing its output -- // to stdout and stderr. Verb, Args, and WorkingDir must be specified. -- // -- // RunGoCommandPiped runs the command serially using gocommand.RunPiped, -- // enforcing that this command executes exclusively to other commands on the -- // server. -- RunGoCommandPiped(ctx context.Context, mode InvocationFlags, inv *gocommand.Invocation, stdout, stderr io.Writer) error +-var e = d + a - -- // RunGoCommandDirect runs the given `go` command. Verb, Args, and -- // WorkingDir must be specified. -- RunGoCommandDirect(ctx context.Context, mode InvocationFlags, inv *gocommand.Invocation) (*bytes.Buffer, error) +-var F = func() B { return E } - -- // RunGoCommands runs a series of `go` commands that updates the go.mod -- // and go.sum file for wd, and returns their updated contents. -- RunGoCommands(ctx context.Context, allowNetwork bool, wd string, run func(invoke func(...string) (*bytes.Buffer, error)) error) (bool, []byte, []byte, error) +-var G = struct{ +- A b +- _ [unsafe.Sizeof(ext.V)]int // array size + Sizeof creates edge to a var +- _ [unsafe.Sizeof(G)]int // creates a self edge; doesn't affect output though +-}{} - -- // RunProcessEnvFunc runs fn with the process env for this snapshot's view. -- // Note: the process env contains cached module and filesystem state. -- RunProcessEnvFunc(ctx context.Context, fn func(*imports.Options) error) error +-var H = (D + A + C*C) - -- // ModFiles are the go.mod files enclosed in the snapshot's view and known -- // to the snapshot. -- ModFiles() []span.URI +-var I = (A+C).F +-`}, +- want: map[string][]string{ +- "A": {"ext.B"}, +- "C": {"ext.B"}, // via d +- "G": {"ext.B", "ext.V"}, // via b,C +- "H": {"ext.B"}, // via d,A,C +- "I": {"ext.B"}, +- }, +- }, +- { +- label: "builtins", +- srcs: []string{`package p - -- // ParseMod is used to parse go.mod files. -- ParseMod(ctx context.Context, fh FileHandle) (*ParsedModule, error) +-import "ext" - -- // ModWhy returns the results of `go mod why` for the module specified by -- // the given go.mod file. -- ModWhy(ctx context.Context, fh FileHandle) (map[string]string, error) +-var A = new(b) +-type b struct{ ext.B } - -- // ModTidy returns the results of `go mod tidy` for the module specified by -- // the given go.mod file. -- ModTidy(ctx context.Context, pm *ParsedModule) (*TidiedModule, error) +-type C chan d +-type d ext.D - -- // ModVuln returns import vulnerability analysis for the given go.mod URI. -- // Concurrent requests are combined into a single command. -- ModVuln(ctx context.Context, modURI span.URI) (*govulncheck.Result, error) +-type S []ext.S +-type t ext.T +-var U = append(([]*S)(nil), new(t)) - -- // GoModForFile returns the URI of the go.mod file for the given URI. -- GoModForFile(uri span.URI) span.URI +-type X map[k]v +-type k ext.K +-type v ext.V - -- // WorkFile, if non-empty, is the go.work file for the workspace. -- WorkFile() span.URI +-var Z = make(map[k]A) - -- // ParseWork is used to parse go.work files. -- ParseWork(ctx context.Context, fh FileHandle) (*ParsedWorkFile, error) +-// close, delete, and panic cannot occur outside of statements +-`}, +- want: map[string][]string{ +- "A": {"ext.B"}, +- "C": {"ext.D"}, +- "S": {"ext.S"}, +- "U": {"ext.S", "ext.T"}, // ext.T edge could be eliminated +- "X": {"ext.K", "ext.V"}, +- "Z": {"ext.B", "ext.K"}, +- }, +- }, +- { +- label: "builtin shadowing", +- srcs: []string{`package p - -- // BuiltinFile returns information about the special builtin package. -- BuiltinFile(ctx context.Context) (*ParsedGoFile, error) +-import "ext" - -- // IsBuiltin reports whether uri is part of the builtin package. -- IsBuiltin(ctx context.Context, uri span.URI) bool +-var A = new(ext.B) +-func new() c +-type c ext.C +-`}, +- want: map[string][]string{ +- "A": {"ext.B", "ext.C"}, +- }, +- }, +- { +- label: "named forwarding", +- srcs: []string{`package p +- +-import "ext" +- +-type A B +-type B c +-type c ext.C +-`}, +- want: map[string][]string{ +- "A": {"ext.C"}, +- "B": {"ext.C"}, +- }, +- }, +- { +- label: "aliases", +- srcs: []string{`package p +- +-import "ext" +- +-type A = B +-type B = C +-type C = ext.C +-`}, +- want: map[string][]string{ +- "A": {"ext.C"}, +- "B": {"ext.C"}, +- "C": {"ext.C"}, +- }, +- }, +- { +- label: "array length", +- srcs: []string{`package p - -- // ReverseDependencies returns a new mapping whose entries are -- // the ID and Metadata of each package in the workspace that -- // directly or transitively depend on the package denoted by id, -- // excluding id itself. -- ReverseDependencies(ctx context.Context, id PackageID, transitive bool) (map[PackageID]*Metadata, error) +-import "ext" +-import "unsafe" - -- // ActiveMetadata returns a new, unordered slice containing -- // metadata for all packages considered 'active' in the workspace. -- // -- // In normal memory mode, this is all workspace packages. In degraded memory -- // mode, this is just the reverse transitive closure of open packages. -- ActiveMetadata(ctx context.Context) ([]*Metadata, error) +-type A [unsafe.Sizeof(ext.B{ext.C})]int +-type A2 [unsafe.Sizeof(ext.B{f:ext.C})]int // use a KeyValueExpr +- +-type D [unsafe.Sizeof(struct{ f E })]int +-type E ext.E +- +-type F [3]G +-type G [ext.C]int +-`}, +- want: map[string][]string{ +- "A": {"ext.B"}, // no ext.C: doesn't enter CompLit +- "A2": {"ext.B"}, // ditto +- "D": {"ext.E"}, +- "E": {"ext.E"}, +- "F": {"ext.C"}, +- "G": {"ext.C"}, +- }, +- }, +- { +- label: "imports", +- srcs: []string{`package p - -- // AllMetadata returns a new unordered array of metadata for all packages in the workspace. -- AllMetadata(ctx context.Context) ([]*Metadata, error) +-import "ext" - -- // Symbols returns all symbols in the snapshot. -- Symbols(ctx context.Context) (map[span.URI][]Symbol, error) -- -- // Metadata returns the metadata for the specified package, -- // or nil if it was not found. -- Metadata(id PackageID) *Metadata -- -- // MetadataForFile returns a new slice containing metadata for each -- // package containing the Go file identified by uri, ordered by the -- // number of CompiledGoFiles (i.e. "narrowest" to "widest" package). -- // The result may include tests and intermediate test variants of -- // importable packages. -- // It returns an error if the context was cancelled. -- MetadataForFile(ctx context.Context, uri span.URI) ([]*Metadata, error) +-import ( +- "q" +- r2 "r" +- "s" // note: package name is t +- "z" +-) - -- // TypeCheck parses and type-checks the specified packages, -- // and returns them in the same order as the ids. -- // The resulting packages' types may belong to different importers, -- // so types from different packages are incommensurable. -- TypeCheck(ctx context.Context, ids ...PackageID) ([]Package, error) +-type A struct { +- q.Q +- r2.R +- s.S // invalid ref +- z.Z // references both external z.Z as well as package-level type z +-} - -- // PackageDiagnostics returns diagnostics for files contained in specified -- // packages. -- // -- // If these diagnostics cannot be loaded from cache, the requested packages -- // may be type-checked. -- PackageDiagnostics(ctx context.Context, ids ...PackageID) (map[span.URI][]*Diagnostic, error) +-type B struct { +- r.R // invalid ref +- t.T +-} - -- // References returns cross-references indexes for the specified packages. -- // -- // If these indexes cannot be loaded from cache, the requested packages may -- // be type-checked. -- References(ctx context.Context, ids ...PackageID) ([]XrefIndex, error) +-var X int = q.V // X={}: no descent into RHS of 'var v T = rhs' +-var Y = q.V.W - -- // MethodSets returns method-set indexes for the specified packages. -- // -- // If these indexes cannot be loaded from cache, the requested packages may -- // be type-checked. -- MethodSets(ctx context.Context, ids ...PackageID) ([]*methodsets.Index, error) +-type z ext.Z +-`}, +- imports: map[string]string{"q": "q", "r": "r", "s": "t", "z": "z"}, +- want: map[string][]string{ +- "A": {"ext.Z", "q.Q", "r.R", "z.Z"}, +- "B": {"t.T"}, +- "Y": {"q.V"}, +- }, +- }, +- { +- label: "import blank", +- srcs: []string{`package p - -- // GetCriticalError returns any critical errors in the workspace. -- // -- // A nil result may mean success, or context cancellation. -- GetCriticalError(ctx context.Context) *CriticalError --} +-import _ "q" - --type XrefIndex interface { -- Lookup(targets map[PackagePath]map[objectpath.Path]struct{}) (locs []protocol.Location) --} +-type A q.Q +-`}, +- imports: map[string]string{"q": "q"}, +- want: map[string][]string{}, +- }, +- { +- label: "import dot", +- srcs: []string{`package p - --// SnapshotLabels returns a new slice of labels that should be used for events --// related to a snapshot. --func SnapshotLabels(snapshot Snapshot) []label.Label { -- return []label.Label{tag.Snapshot.Of(snapshot.SequenceID()), tag.Directory.Of(snapshot.View().Folder())} --} +-import . "q" - --// PackageForFile is a convenience function that selects a package to --// which this file belongs (narrowest or widest), type-checks it in --// the requested mode (full or workspace), and returns it, along with --// the parse tree of that file. --// --// Type-checking is expensive. Call snapshot.ParseGo if all you need --// is a parse tree, or snapshot.MetadataForFile if you only need metadata. --func PackageForFile(ctx context.Context, snapshot Snapshot, uri span.URI, pkgSel PackageSelector) (Package, *ParsedGoFile, error) { -- metas, err := snapshot.MetadataForFile(ctx, uri) -- if err != nil { -- return nil, nil, err -- } -- if len(metas) == 0 { -- return nil, nil, fmt.Errorf("no package metadata for file %s", uri) -- } -- switch pkgSel { -- case NarrowestPackage: -- metas = metas[:1] -- case WidestPackage: -- metas = metas[len(metas)-1:] -- } -- pkgs, err := snapshot.TypeCheck(ctx, metas[0].ID) -- if err != nil { -- return nil, nil, err -- } -- pkg := pkgs[0] -- pgf, err := pkg.File(uri) -- if err != nil { -- return nil, nil, err // "can't happen" -- } -- return pkg, pgf, err +-type A q.Q // not actually an edge, since q is imported . +-type B struct { +- C // assumed to be an edge to q +- D // resolved to package decl -} - --// PackageSelector sets how a package is selected out from a set of packages --// containing a given file. --type PackageSelector int -- --const ( -- // NarrowestPackage picks the "narrowest" package for a given file. -- // By "narrowest" package, we mean the package with the fewest number of -- // files that includes the given file. This solves the problem of test -- // variants, as the test will have more files than the non-test package. -- NarrowestPackage PackageSelector = iota -- -- // WidestPackage returns the Package containing the most files. -- // This is useful for something like diagnostics, where we'd prefer to -- // offer diagnostics for as many files as possible. -- WidestPackage --) - --// InvocationFlags represents the settings of a particular go command invocation. --// It is a mode, plus a set of flag bits. --type InvocationFlags int +-type E error // unexported, therefore must be universe.error +-type F Field +-var G = Field.X +-`, `package p - --const ( -- // Normal is appropriate for commands that might be run by a user and don't -- // deliberately modify go.mod files, e.g. `go test`. -- Normal InvocationFlags = iota -- // WriteTemporaryModFile is for commands that need information from a -- // modified version of the user's go.mod file, e.g. `go mod tidy` used to -- // generate diagnostics. -- WriteTemporaryModFile -- // LoadWorkspace is for packages.Load, and other operations that should -- // consider the whole workspace at once. -- LoadWorkspace +-import "ext" +-import "q" - -- // AllowNetwork is a flag bit that indicates the invocation should be -- // allowed to access the network. -- AllowNetwork InvocationFlags = 1 << 10 --) +-type D ext.D +-`}, +- imports: map[string]string{"q": "q"}, +- want: map[string][]string{ +- "B": {"ext.D", "q.C"}, +- "D": {"ext.D"}, +- "F": {"q.Field"}, +- "G": {"q.Field"}, +- }, +- }, +- { +- label: "typeparams", +- srcs: []string{`package p - --func (m InvocationFlags) Mode() InvocationFlags { -- return m & (AllowNetwork - 1) --} +-import "ext" - --func (m InvocationFlags) AllowNetwork() bool { -- return m&AllowNetwork != 0 +-type A[T any] struct { +- t T +- b B -} - --// View represents a single workspace. --// This is the level at which we maintain configuration like working directory --// and build tags. --type View interface { -- // Name returns the name this view was constructed with. -- Name() string +-type B ext.B - -- // Folder returns the folder with which this view was created. -- Folder() span.URI +-func F1[T any](T, B) +-func F2[T C]()(T, B) - -- // Options returns a copy of the Options for this view. -- Options() *Options +-type T ext.T - -- // Snapshot returns the current snapshot for the view, and a -- // release function that must be called when the Snapshot is -- // no longer needed. -- // -- // If the view is shut down, the resulting error will be non-nil, and the -- // release function need not be called. -- Snapshot() (Snapshot, func(), error) +-type C ext.C - -- // IsGoPrivatePath reports whether target is a private import path, as identified -- // by the GOPRIVATE environment variable. -- IsGoPrivatePath(path string) bool +-func F3[T1 ~[]T2, T2 ~[]T3](t1 T1, t2 T2) +-type T3 ext.T3 +-`, `package p - -- // ModuleUpgrades returns known module upgrades for the dependencies of -- // modfile. -- ModuleUpgrades(modfile span.URI) map[string]string +-func (A[B]) M(C) {} +-`}, +- want: map[string][]string{ +- "A": {"ext.B", "ext.C"}, +- "B": {"ext.B"}, +- "C": {"ext.C"}, +- "F1": {"ext.B"}, +- "F2": {"ext.B", "ext.C"}, +- "F3": {"ext.T3"}, +- "T": {"ext.T"}, +- "T3": {"ext.T3"}, +- }, +- go118: true, +- }, +- { +- label: "instances", +- srcs: []string{`package p +- +-import "ext" +- +-type A[T any] ext.A +-type B[T1, T2 any] ext.B +- +-type C A[int] +-type D B[int, A[E]] +-type E ext.E +-`}, +- want: map[string][]string{ +- "A": {"ext.A"}, +- "B": {"ext.B"}, +- "C": {"ext.A"}, +- "D": {"ext.A", "ext.B", "ext.E"}, +- "E": {"ext.E"}, +- }, +- go118: true, +- }, +- { +- label: "duplicate decls", +- srcs: []string{`package p +- +-import "a" +-import "ext" +- +-type a a.A +-type A a +-type b ext.B +-type C a.A +-func (C) Foo(x) {} // invalid parameter, but that does not matter +-type C b +-func (C) Bar(y) {} // invalid parameter, but that does not matter +- +-var x ext.X +-var y ext.Y +-`}, +- imports: map[string]string{"a": "a", "b": "b"}, // "b" import should not matter, since it isn't in this file +- want: map[string][]string{ +- "A": {"a.A"}, +- "C": {"a.A", "ext.B", "ext.X", "ext.Y"}, +- }, +- }, +- { +- label: "invalid decls", +- srcs: []string{`package p - -- // RegisterModuleUpgrades registers that upgrades exist for the given modules -- // required by modfile. -- RegisterModuleUpgrades(modfile span.URI, upgrades map[string]string) +-import "ext" - -- // ClearModuleUpgrades clears all upgrades for the modules in modfile. -- ClearModuleUpgrades(modfile span.URI) +-type A B - -- // Vulnerabilities returns known vulnerabilities for the given modfile. -- // TODO(suzmue): replace command.Vuln with a different type, maybe -- // https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck/govulnchecklib#Summary? -- Vulnerabilities(modfile ...span.URI) map[span.URI]*govulncheck.Result +-func () Foo(B){} - -- // SetVulnerabilities resets the list of vulnerabilities that exists for the given modules -- // required by modfile. -- SetVulnerabilities(modfile span.URI, vulncheckResult *govulncheck.Result) +-var B struct{ ext.B +-`}, +- want: map[string][]string{ +- "A": {"ext.B"}, +- "B": {"ext.B"}, +- "Foo": {"ext.B"}, +- }, +- allowErrs: true, +- }, +- { +- label: "unmapped receiver", +- srcs: []string{`package p - -- // FileKind returns the type of a file. -- // -- // We can't reliably deduce the kind from the file name alone, -- // as some editors can be told to interpret a buffer as -- // language different from the file name heuristic, e.g. that -- // an .html file actually contains Go "html/template" syntax, -- // or even that a .go file contains Python. -- FileKind(FileHandle) FileKind +-type P struct{} - -- // GoVersion returns the configured Go version for this view. -- GoVersion() int +-func (a) x(P) +-`}, +- want: map[string][]string{}, +- allowErrs: true, +- }, +- { +- label: "SCC special case", +- srcs: []string{`package p +- +-import "ext" +- +-type X Y +-type Y struct { Z; *X } +-type Z map[ext.A]ext.B +-`}, +- want: map[string][]string{ +- "X": {"ext.A", "ext.B"}, +- "Y": {"ext.A", "ext.B"}, +- "Z": {"ext.A", "ext.B"}, +- }, +- allowErrs: true, +- }, +- } - -- // GoVersionString returns the go version string configured for this view. -- // Unlike [GoVersion], this encodes the minor version and commit hash information. -- GoVersionString() string --} +- for _, test := range tests { +- t.Run(test.label, func(t *testing.T) { +- if test.go118 { +- testenv.NeedsGo1Point(t, 18) +- } - --// A FileSource maps uris to FileHandles. --type FileSource interface { -- // GetFile returns the FileHandle for a given URI. -- GetFile(ctx context.Context, uri span.URI) (FileHandle, error) --} +- var pgfs []*source.ParsedGoFile +- for i, src := range test.srcs { +- uri := span.URI(fmt.Sprintf("file:///%d.go", i)) +- pgf, _ := cache.ParseGoSrc(ctx, token.NewFileSet(), uri, []byte(src), source.ParseFull, false) +- if !test.allowErrs && pgf.ParseErr != nil { +- t.Fatalf("ParseGoSrc(...) returned parse errors: %v", pgf.ParseErr) +- } +- pgfs = append(pgfs, pgf) +- } - --// A MetadataSource maps package IDs to metadata. --// --// TODO(rfindley): replace this with a concrete metadata graph, once it is --// exposed from the snapshot. --type MetadataSource interface { -- // Metadata returns Metadata for the given package ID, or nil if it does not -- // exist. -- Metadata(PackageID) *Metadata --} +- imports := map[source.ImportPath]*source.Metadata{ +- "ext": {ID: "ext", Name: "ext"}, // this one comes for free +- } +- for path, m := range test.imports { +- imports[source.ImportPath(path)] = &source.Metadata{ +- ID: source.PackageID(m), +- Name: source.PackageName(m), +- } +- } - --// A ParsedGoFile contains the results of parsing a Go file. --type ParsedGoFile struct { -- URI span.URI -- Mode ParseMode -- File *ast.File -- Tok *token.File -- // Source code used to build the AST. It may be different from the -- // actual content of the file if we have fixed the AST. -- Src []byte -- Fixed bool -- Mapper *protocol.Mapper // may map fixed Src, not file content -- ParseErr scanner.ErrorList --} +- data := typerefs.Encode(pgfs, "p", imports) - --// -- go/token domain convenience helpers -- +- got := make(map[string][]string) +- index := typerefs.NewPackageIndex() +- for _, class := range typerefs.Decode(index, "p", data) { +- // We redundantly expand out the name x refs cross product +- // here since that's what the existing tests expect. +- for _, name := range class.Decls { +- var syms []string +- for _, sym := range class.Refs { +- syms = append(syms, fmt.Sprintf("%s.%s", index.DeclaringPackage(sym), sym.Name)) +- } +- sort.Strings(syms) +- got[name] = syms +- } +- } - --// PositionPos returns the token.Pos of protocol position p within the file. --func (pgf *ParsedGoFile) PositionPos(p protocol.Position) (token.Pos, error) { -- offset, err := pgf.Mapper.PositionOffset(p) -- if err != nil { -- return token.NoPos, err +- if diff := cmp.Diff(test.want, got); diff != "" { +- t.Errorf("Refs(...) returned unexpected refs (-want +got):\n%s", diff) +- } +- }) - } -- return safetoken.Pos(pgf.Tok, offset) --} -- --// PosRange returns a protocol Range for the token.Pos interval in this file. --func (pgf *ParsedGoFile) PosRange(start, end token.Pos) (protocol.Range, error) { -- return pgf.Mapper.PosRange(pgf.Tok, start, end) -} +diff -urN a/gopls/internal/lsp/source/types_format.go b/gopls/internal/lsp/source/types_format.go +--- a/gopls/internal/lsp/source/types_format.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/types_format.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,520 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --// PosMappedRange returns a MappedRange for the token.Pos interval in this file. --// A MappedRange can be converted to any other form. --func (pgf *ParsedGoFile) PosMappedRange(start, end token.Pos) (protocol.MappedRange, error) { -- return pgf.Mapper.PosMappedRange(pgf.Tok, start, end) --} +-package source - --// PosLocation returns a protocol Location for the token.Pos interval in this file. --func (pgf *ParsedGoFile) PosLocation(start, end token.Pos) (protocol.Location, error) { -- return pgf.Mapper.PosLocation(pgf.Tok, start, end) --} +-import ( +- "bytes" +- "context" +- "fmt" +- "go/ast" +- "go/doc" +- "go/printer" +- "go/token" +- "go/types" +- "strings" - --// NodeRange returns a protocol Range for the ast.Node interval in this file. --func (pgf *ParsedGoFile) NodeRange(node ast.Node) (protocol.Range, error) { -- return pgf.Mapper.NodeRange(pgf.Tok, node) --} +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" +- "golang.org/x/tools/internal/tokeninternal" +- "golang.org/x/tools/internal/typeparams" +-) - --// NodeMappedRange returns a MappedRange for the ast.Node interval in this file. --// A MappedRange can be converted to any other form. --func (pgf *ParsedGoFile) NodeMappedRange(node ast.Node) (protocol.MappedRange, error) { -- return pgf.Mapper.NodeMappedRange(pgf.Tok, node) +-// FormatType returns the detail and kind for a types.Type. +-func FormatType(typ types.Type, qf types.Qualifier) (detail string, kind protocol.CompletionItemKind) { +- if types.IsInterface(typ) { +- detail = "interface{...}" +- kind = protocol.InterfaceCompletion +- } else if _, ok := typ.(*types.Struct); ok { +- detail = "struct{...}" +- kind = protocol.StructCompletion +- } else if typ != typ.Underlying() { +- detail, kind = FormatType(typ.Underlying(), qf) +- } else { +- detail = types.TypeString(typ, qf) +- kind = protocol.ClassCompletion +- } +- return detail, kind -} - --// NodeLocation returns a protocol Location for the ast.Node interval in this file. --func (pgf *ParsedGoFile) NodeLocation(node ast.Node) (protocol.Location, error) { -- return pgf.Mapper.PosLocation(pgf.Tok, node.Pos(), node.End()) +-type signature struct { +- name, doc string +- typeParams, params, results []string +- variadic bool +- needResultParens bool -} - --// RangePos parses a protocol Range back into the go/token domain. --func (pgf *ParsedGoFile) RangePos(r protocol.Range) (token.Pos, token.Pos, error) { -- start, end, err := pgf.Mapper.RangeOffsets(r) -- if err != nil { -- return token.NoPos, token.NoPos, err +-func (s *signature) Format() string { +- var b strings.Builder +- b.WriteByte('(') +- for i, p := range s.params { +- if i > 0 { +- b.WriteString(", ") +- } +- b.WriteString(p) - } -- return pgf.Tok.Pos(start), pgf.Tok.Pos(end), nil --} +- b.WriteByte(')') - --// A ParsedModule contains the results of parsing a go.mod file. --type ParsedModule struct { -- URI span.URI -- File *modfile.File -- Mapper *protocol.Mapper -- ParseErrors []*Diagnostic +- // Add space between parameters and results. +- if len(s.results) > 0 { +- b.WriteByte(' ') +- } +- if s.needResultParens { +- b.WriteByte('(') +- } +- for i, r := range s.results { +- if i > 0 { +- b.WriteString(", ") +- } +- b.WriteString(r) +- } +- if s.needResultParens { +- b.WriteByte(')') +- } +- return b.String() -} - --// A ParsedWorkFile contains the results of parsing a go.work file. --type ParsedWorkFile struct { -- URI span.URI -- File *modfile.WorkFile -- Mapper *protocol.Mapper -- ParseErrors []*Diagnostic +-func (s *signature) TypeParams() []string { +- return s.typeParams -} - --// A TidiedModule contains the results of running `go mod tidy` on a module. --type TidiedModule struct { -- // Diagnostics representing changes made by `go mod tidy`. -- Diagnostics []*Diagnostic -- // The bytes of the go.mod file after it was tidied. -- TidiedContent []byte +-func (s *signature) Params() []string { +- return s.params -} - --// Metadata represents package metadata retrieved from go/packages. --type Metadata struct { -- ID PackageID -- PkgPath PackagePath -- Name PackageName -- GoFiles []span.URI -- CompiledGoFiles []span.URI -- ForTest PackagePath // package path under test, or "" -- TypesSizes types.Sizes -- Errors []packages.Error -- DepsByImpPath map[ImportPath]PackageID // may contain dups; empty ID => missing -- DepsByPkgPath map[PackagePath]PackageID // values are unique and non-empty -- Module *packages.Module -- DepsErrors []*packagesinternal.PackageError -- Diagnostics []*Diagnostic // processed diagnostics from 'go list' -- LoadDir string // directory from which go/packages was run +-// NewBuiltinSignature returns signature for the builtin object with a given +-// name, if a builtin object with the name exists. +-func NewBuiltinSignature(ctx context.Context, s Snapshot, name string) (*signature, error) { +- builtin, err := s.BuiltinFile(ctx) +- if err != nil { +- return nil, err +- } +- obj := builtin.File.Scope.Lookup(name) +- if obj == nil { +- return nil, fmt.Errorf("no builtin object for %s", name) +- } +- decl, ok := obj.Decl.(*ast.FuncDecl) +- if !ok { +- return nil, fmt.Errorf("no function declaration for builtin: %s", name) +- } +- if decl.Type == nil { +- return nil, fmt.Errorf("no type for builtin decl %s", decl.Name) +- } +- var variadic bool +- if decl.Type.Params.List != nil { +- numParams := len(decl.Type.Params.List) +- lastParam := decl.Type.Params.List[numParams-1] +- if _, ok := lastParam.Type.(*ast.Ellipsis); ok { +- variadic = true +- } +- } +- fset := tokeninternal.FileSetFor(builtin.Tok) +- params, _ := formatFieldList(ctx, fset, decl.Type.Params, variadic) +- results, needResultParens := formatFieldList(ctx, fset, decl.Type.Results, false) +- d := decl.Doc.Text() +- switch s.Options().HoverKind { +- case SynopsisDocumentation: +- d = doc.Synopsis(d) +- case NoDocumentation: +- d = "" +- } +- return &signature{ +- doc: d, +- name: name, +- needResultParens: needResultParens, +- params: params, +- results: results, +- variadic: variadic, +- }, nil -} - --func (m *Metadata) String() string { return string(m.ID) } +-// replacer replaces some synthetic "type classes" used in the builtin file +-// with their most common constituent type. +-var replacer = strings.NewReplacer( +- `ComplexType`, `complex128`, +- `FloatType`, `float64`, +- `IntegerType`, `int`, +-) - --// IsIntermediateTestVariant reports whether the given package is an --// intermediate test variant, e.g. "net/http [net/url.test]". --// --// Such test variants arise when an x_test package (in this case net/url_test) --// imports a package (in this case net/http) that itself imports the the --// non-x_test package (in this case net/url). --// --// This is done so that the forward transitive closure of net/url_test has --// only one package for the "net/url" import. --// The intermediate test variant exists to hold the test variant import: --// --// net/url_test [net/url.test] --// --// | "net/http" -> net/http [net/url.test] --// | "net/url" -> net/url [net/url.test] --// | ... --// --// net/http [net/url.test] --// --// | "net/url" -> net/url [net/url.test] --// | ... --// --// This restriction propagates throughout the import graph of net/http: for --// every package imported by net/http that imports net/url, there must be an --// intermediate test variant that instead imports "net/url [net/url.test]". --// --// As one can see from the example of net/url and net/http, intermediate test --// variants can result in many additional packages that are essentially (but --// not quite) identical. For this reason, we filter these variants wherever --// possible. --func (m *Metadata) IsIntermediateTestVariant() bool { -- return m.ForTest != "" && m.ForTest != m.PkgPath && m.ForTest+"_test" != m.PkgPath +-func formatFieldList(ctx context.Context, fset *token.FileSet, list *ast.FieldList, variadic bool) ([]string, bool) { +- if list == nil { +- return nil, false +- } +- var writeResultParens bool +- var result []string +- for i := 0; i < len(list.List); i++ { +- if i >= 1 { +- writeResultParens = true +- } +- p := list.List[i] +- cfg := printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 4} +- b := &bytes.Buffer{} +- if err := cfg.Fprint(b, fset, p.Type); err != nil { +- event.Error(ctx, "unable to print type", nil, tag.Type.Of(p.Type)) +- continue +- } +- typ := replacer.Replace(b.String()) +- if len(p.Names) == 0 { +- result = append(result, typ) +- } +- for _, name := range p.Names { +- if name.Name != "" { +- if i == 0 { +- writeResultParens = true +- } +- result = append(result, fmt.Sprintf("%s %s", name.Name, typ)) +- } else { +- result = append(result, typ) +- } +- } +- } +- if variadic { +- result[len(result)-1] = strings.Replace(result[len(result)-1], "[]", "...", 1) +- } +- return result, writeResultParens -} - --// RemoveIntermediateTestVariants removes intermediate test variants, modifying the array. --func RemoveIntermediateTestVariants(metas []*Metadata) []*Metadata { -- res := metas[:0] -- for _, m := range metas { -- if !m.IsIntermediateTestVariant() { -- res = append(res, m) +-// FormatTypeParams turns TypeParamList into its Go representation, such as: +-// [T, Y]. Note that it does not print constraints as this is mainly used for +-// formatting type params in method receivers. +-func FormatTypeParams(tparams *typeparams.TypeParamList) string { +- if tparams == nil || tparams.Len() == 0 { +- return "" +- } +- var buf bytes.Buffer +- buf.WriteByte('[') +- for i := 0; i < tparams.Len(); i++ { +- if i > 0 { +- buf.WriteString(", ") - } +- buf.WriteString(tparams.At(i).Obj().Name()) - } -- return res +- buf.WriteByte(']') +- return buf.String() -} - --var ErrViewExists = errors.New("view already exists for session") -- --// FileModification represents a modification to a file. --type FileModification struct { -- URI span.URI -- Action FileAction -- -- // OnDisk is true if a watched file is changed on disk. -- // If true, Version will be -1 and Text will be nil. -- OnDisk bool +-// NewSignature returns formatted signature for a types.Signature struct. +-func NewSignature(ctx context.Context, s Snapshot, pkg Package, sig *types.Signature, comment *ast.CommentGroup, qf types.Qualifier, mq MetadataQualifier) (*signature, error) { +- var tparams []string +- tpList := typeparams.ForSignature(sig) +- for i := 0; i < tpList.Len(); i++ { +- tparam := tpList.At(i) +- // TODO: is it possible to reuse the logic from FormatVarType here? +- s := tparam.Obj().Name() + " " + tparam.Constraint().String() +- tparams = append(tparams, s) +- } - -- // Version will be -1 and Text will be nil when they are not supplied, -- // specifically on textDocument/didClose and for on-disk changes. -- Version int32 -- Text []byte +- params := make([]string, 0, sig.Params().Len()) +- for i := 0; i < sig.Params().Len(); i++ { +- el := sig.Params().At(i) +- typ, err := FormatVarType(ctx, s, pkg, el, qf, mq) +- if err != nil { +- return nil, err +- } +- p := typ +- if el.Name() != "" { +- p = el.Name() + " " + typ +- } +- params = append(params, p) +- } - -- // LanguageID is only sent from the language client on textDocument/didOpen. -- LanguageID string +- var needResultParens bool +- results := make([]string, 0, sig.Results().Len()) +- for i := 0; i < sig.Results().Len(); i++ { +- if i >= 1 { +- needResultParens = true +- } +- el := sig.Results().At(i) +- typ, err := FormatVarType(ctx, s, pkg, el, qf, mq) +- if err != nil { +- return nil, err +- } +- if el.Name() == "" { +- results = append(results, typ) +- } else { +- if i == 0 { +- needResultParens = true +- } +- results = append(results, el.Name()+" "+typ) +- } +- } +- var d string +- if comment != nil { +- d = comment.Text() +- } +- switch s.Options().HoverKind { +- case SynopsisDocumentation: +- d = doc.Synopsis(d) +- case NoDocumentation: +- d = "" +- } +- return &signature{ +- doc: d, +- typeParams: tparams, +- params: params, +- results: results, +- variadic: sig.Variadic(), +- needResultParens: needResultParens, +- }, nil -} - --type FileAction int +-// FormatVarType formats a *types.Var, accounting for type aliases. +-// To do this, it looks in the AST of the file in which the object is declared. +-// On any errors, it always falls back to types.TypeString. +-// +-// TODO(rfindley): this function could return the actual name used in syntax, +-// for better parameter names. +-func FormatVarType(ctx context.Context, snapshot Snapshot, srcpkg Package, obj *types.Var, qf types.Qualifier, mq MetadataQualifier) (string, error) { +- // TODO(rfindley): This looks wrong. The previous comment said: +- // "If the given expr refers to a type parameter, then use the +- // object's Type instead of the type parameter declaration. This helps +- // format the instantiated type as opposed to the original undeclared +- // generic type". +- // +- // But of course, if obj is a type param, we are formatting a generic type +- // and not an instantiated type. Handling for instantiated types must be done +- // at a higher level. +- // +- // Left this during refactoring in order to preserve pre-existing logic. +- if typeparams.IsTypeParam(obj.Type()) { +- return types.TypeString(obj.Type(), qf), nil +- } - --const ( -- UnknownFileAction = FileAction(iota) -- Open -- Change -- Close -- Save -- Create -- Delete -- InvalidateMetadata --) +- if obj.Pkg() == nil || !obj.Pos().IsValid() { +- // This is defensive, though it is extremely unlikely we'll ever have a +- // builtin var. +- return types.TypeString(obj.Type(), qf), nil +- } - --func (a FileAction) String() string { -- switch a { -- case Open: -- return "Open" -- case Change: -- return "Change" -- case Close: -- return "Close" -- case Save: -- return "Save" -- case Create: -- return "Create" -- case Delete: -- return "Delete" -- case InvalidateMetadata: -- return "InvalidateMetadata" -- default: -- return "Unknown" +- // TODO(rfindley): parsing to produce candidates can be costly; consider +- // using faster methods. +- targetpgf, pos, err := parseFull(ctx, snapshot, srcpkg.FileSet(), obj.Pos()) +- if err != nil { +- return "", err // e.g. ctx cancelled - } --} - --var ErrTmpModfileUnsupported = errors.New("-modfile is unsupported for this Go version") --var ErrNoModOnDisk = errors.New("go.mod file is not on disk") +- targetMeta := findFileInDeps(snapshot, srcpkg.Metadata(), targetpgf.URI) +- if targetMeta == nil { +- // If we have an object from type-checking, it should exist in a file in +- // the forward transitive closure. +- return "", bug.Errorf("failed to find file %q in deps of %q", targetpgf.URI, srcpkg.Metadata().ID) +- } - --func IsNonFatalGoModError(err error) bool { -- return err == ErrTmpModfileUnsupported || err == ErrNoModOnDisk --} +- decl, spec, field := findDeclInfo([]*ast.File{targetpgf.File}, pos) - --// ParseMode controls the content of the AST produced when parsing a source file. --type ParseMode int +- // We can't handle type parameters correctly, so we fall back on TypeString +- // for parameterized decls. +- if decl, _ := decl.(*ast.FuncDecl); decl != nil { +- if typeparams.ForFuncType(decl.Type).NumFields() > 0 { +- return types.TypeString(obj.Type(), qf), nil // in generic function +- } +- if decl.Recv != nil && len(decl.Recv.List) > 0 { +- if x, _, _, _ := typeparams.UnpackIndexExpr(decl.Recv.List[0].Type); x != nil { +- return types.TypeString(obj.Type(), qf), nil // in method of generic type +- } +- } +- } +- if spec, _ := spec.(*ast.TypeSpec); spec != nil && typeparams.ForTypeSpec(spec).NumFields() > 0 { +- return types.TypeString(obj.Type(), qf), nil // in generic type decl +- } - --const ( -- // ParseHeader specifies that the main package declaration and imports are needed. -- // This is the mode used when attempting to examine the package graph structure. -- ParseHeader ParseMode = iota +- if field == nil { +- // TODO(rfindley): we should never reach here from an ordinary var, so +- // should probably return an error here. +- return types.TypeString(obj.Type(), qf), nil +- } +- expr := field.Type - -- // ParseFull specifies the full AST is needed. -- // This is used for files of direct interest where the entire contents must -- // be considered. -- ParseFull --) +- rq := requalifier(snapshot, targetpgf.File, targetMeta, mq) - --// A FileHandle is an interface to files tracked by the LSP session, which may --// be either files read from disk, or open in the editor session (overlays). --type FileHandle interface { -- // URI is the URI for this file handle. -- // TODO(rfindley): this is not actually well-defined. In some cases, there -- // may be more than one URI that resolve to the same FileHandle. Which one is -- // this? -- URI() span.URI -- // FileIdentity returns a FileIdentity for the file, even if there was an -- // error reading it. -- FileIdentity() FileIdentity -- // Saved reports whether the file has the same content on disk. -- // For on-disk files, this is trivially true. -- Saved() bool -- // Version returns the file version, as defined by the LSP client. -- // For on-disk file handles, Version returns 0. -- Version() int32 -- // Read reads the contents of a file. -- // If the file is not available, returns a nil slice and an error. -- Read() ([]byte, error) +- // The type names in the AST may not be correctly qualified. +- // Determine the package name to use based on the package that originated +- // the query and the package in which the type is declared. +- // We then qualify the value by cloning the AST node and editing it. +- expr = qualifyTypeExpr(expr, rq) +- +- // If the request came from a different package than the one in which the +- // types are defined, we may need to modify the qualifiers. +- return FormatNodeFile(targetpgf.Tok, expr), nil -} - --// A Hash is a cryptographic digest of the contents of a file. --// (Although at 32B it is larger than a 16B string header, it is smaller --// and has better locality than the string header + 64B of hex digits.) --type Hash [sha256.Size]byte +-// qualifyTypeExpr clones the type expression expr after re-qualifying type +-// names using the given function, which accepts the current syntactic +-// qualifier (possibly "" for unqualified idents), and returns a new qualifier +-// (again, possibly "" if the identifier should be unqualified). +-// +-// The resulting expression may be inaccurate: without type-checking we don't +-// properly account for "." imported identifiers or builtins. +-// +-// TODO(rfindley): add many more tests for this function. +-func qualifyTypeExpr(expr ast.Expr, qf func(string) string) ast.Expr { +- switch expr := expr.(type) { +- case *ast.ArrayType: +- return &ast.ArrayType{ +- Lbrack: expr.Lbrack, +- Elt: qualifyTypeExpr(expr.Elt, qf), +- Len: expr.Len, +- } - --// HashOf returns the hash of some data. --func HashOf(data []byte) Hash { -- return Hash(sha256.Sum256(data)) --} +- case *ast.BinaryExpr: +- if expr.Op != token.OR { +- return expr +- } +- return &ast.BinaryExpr{ +- X: qualifyTypeExpr(expr.X, qf), +- OpPos: expr.OpPos, +- Op: expr.Op, +- Y: qualifyTypeExpr(expr.Y, qf), +- } - --// Hashf returns the hash of a printf-formatted string. --func Hashf(format string, args ...interface{}) Hash { -- // Although this looks alloc-heavy, it is faster than using -- // Fprintf on sha256.New() because the allocations don't escape. -- return HashOf([]byte(fmt.Sprintf(format, args...))) --} +- case *ast.ChanType: +- return &ast.ChanType{ +- Arrow: expr.Arrow, +- Begin: expr.Begin, +- Dir: expr.Dir, +- Value: qualifyTypeExpr(expr.Value, qf), +- } - --// String returns the digest as a string of hex digits. --func (h Hash) String() string { -- return fmt.Sprintf("%64x", [sha256.Size]byte(h)) --} +- case *ast.Ellipsis: +- return &ast.Ellipsis{ +- Ellipsis: expr.Ellipsis, +- Elt: qualifyTypeExpr(expr.Elt, qf), +- } - --// Less returns true if the given hash is less than the other. --func (h Hash) Less(other Hash) bool { -- return bytes.Compare(h[:], other[:]) < 0 --} +- case *ast.FuncType: +- return &ast.FuncType{ +- Func: expr.Func, +- Params: qualifyFieldList(expr.Params, qf), +- Results: qualifyFieldList(expr.Results, qf), +- } - --// XORWith updates *h to *h XOR h2. --func (h *Hash) XORWith(h2 Hash) { -- // Small enough that we don't need crypto/subtle.XORBytes. -- for i := range h { -- h[i] ^= h2[i] -- } --} +- case *ast.Ident: +- // Unqualified type (builtin, package local, or dot-imported). - --// FileIdentity uniquely identifies a file at a version from a FileSystem. --type FileIdentity struct { -- URI span.URI -- Hash Hash // digest of file contents --} +- // Don't qualify names that look like builtins. +- // +- // Without type-checking this may be inaccurate. It could be made accurate +- // by doing syntactic object resolution for the entire package, but that +- // does not seem worthwhile and we generally want to avoid using +- // ast.Object, which may be inaccurate. +- if obj := types.Universe.Lookup(expr.Name); obj != nil { +- return expr +- } - --func (id FileIdentity) String() string { -- return fmt.Sprintf("%s%s", id.URI, id.Hash) --} +- newName := qf("") +- if newName != "" { +- return &ast.SelectorExpr{ +- X: &ast.Ident{ +- NamePos: expr.Pos(), +- Name: newName, +- }, +- Sel: expr, +- } +- } +- return expr - --// FileKind describes the kind of the file in question. --// It can be one of Go,mod, Sum, or Tmpl. --type FileKind int +- case *ast.IndexExpr: +- return &ast.IndexExpr{ +- X: qualifyTypeExpr(expr.X, qf), +- Lbrack: expr.Lbrack, +- Index: qualifyTypeExpr(expr.Index, qf), +- Rbrack: expr.Rbrack, +- } - --const ( -- // UnknownKind is a file type we don't know about. -- UnknownKind = FileKind(iota) +- case *typeparams.IndexListExpr: +- indices := make([]ast.Expr, len(expr.Indices)) +- for i, idx := range expr.Indices { +- indices[i] = qualifyTypeExpr(idx, qf) +- } +- return &typeparams.IndexListExpr{ +- X: qualifyTypeExpr(expr.X, qf), +- Lbrack: expr.Lbrack, +- Indices: indices, +- Rbrack: expr.Rbrack, +- } - -- // Go is a normal go source file. -- Go -- // Mod is a go.mod file. -- Mod -- // Sum is a go.sum file. -- Sum -- // Tmpl is a template file. -- Tmpl -- // Work is a go.work file. -- Work --) +- case *ast.InterfaceType: +- return &ast.InterfaceType{ +- Interface: expr.Interface, +- Methods: qualifyFieldList(expr.Methods, qf), +- Incomplete: expr.Incomplete, +- } - --func (k FileKind) String() string { -- switch k { -- case Go: -- return "go" -- case Mod: -- return "go.mod" -- case Sum: -- return "go.sum" -- case Tmpl: -- return "tmpl" -- case Work: -- return "go.work" -- default: -- return fmt.Sprintf("internal error: unknown file kind %d", k) -- } --} +- case *ast.MapType: +- return &ast.MapType{ +- Map: expr.Map, +- Key: qualifyTypeExpr(expr.Key, qf), +- Value: qualifyTypeExpr(expr.Value, qf), +- } - --// Analyzer represents a go/analysis analyzer with some boolean properties --// that let the user know how to use the analyzer. --type Analyzer struct { -- Analyzer *analysis.Analyzer +- case *ast.ParenExpr: +- return &ast.ParenExpr{ +- Lparen: expr.Lparen, +- Rparen: expr.Rparen, +- X: qualifyTypeExpr(expr.X, qf), +- } - -- // Enabled reports whether the analyzer is enabled. This value can be -- // configured per-analysis in user settings. For staticcheck analyzers, -- // the value of the Staticcheck setting overrides this field. -- // -- // Most clients should use the IsEnabled method. -- Enabled bool +- case *ast.SelectorExpr: +- if id, ok := expr.X.(*ast.Ident); ok { +- // qualified type +- newName := qf(id.Name) +- if newName == "" { +- return expr.Sel +- } +- return &ast.SelectorExpr{ +- X: &ast.Ident{ +- NamePos: id.NamePos, +- Name: newName, +- }, +- Sel: expr.Sel, +- } +- } +- return expr - -- // Fix is the name of the suggested fix name used to invoke the suggested -- // fixes for the analyzer. It is non-empty if we expect this analyzer to -- // provide its fix separately from its diagnostics. That is, we should apply -- // the analyzer's suggested fixes through a Command, not a TextEdit. -- Fix string +- case *ast.StarExpr: +- return &ast.StarExpr{ +- Star: expr.Star, +- X: qualifyTypeExpr(expr.X, qf), +- } - -- // ActionKind is the kind of code action this analyzer produces. If -- // unspecified the type defaults to quickfix. -- ActionKind []protocol.CodeActionKind +- case *ast.StructType: +- return &ast.StructType{ +- Struct: expr.Struct, +- Fields: qualifyFieldList(expr.Fields, qf), +- Incomplete: expr.Incomplete, +- } - -- // Severity is the severity set for diagnostics reported by this -- // analyzer. If left unset it defaults to Warning. -- Severity protocol.DiagnosticSeverity +- default: +- return expr +- } -} - --func (a *Analyzer) String() string { return a.Analyzer.String() } -- --// IsEnabled reports whether this analyzer is enabled by the given options. --func (a Analyzer) IsEnabled(options *Options) bool { -- // Staticcheck analyzers can only be enabled when staticcheck is on. -- if _, ok := options.StaticcheckAnalyzers[a.Analyzer.Name]; ok { -- if !options.Staticcheck { -- return false +-func qualifyFieldList(fl *ast.FieldList, qf func(string) string) *ast.FieldList { +- if fl == nil { +- return nil +- } +- if fl.List == nil { +- return &ast.FieldList{ +- Closing: fl.Closing, +- Opening: fl.Opening, - } - } -- if enabled, ok := options.Analyses[a.Analyzer.Name]; ok { -- return enabled +- list := make([]*ast.Field, 0, len(fl.List)) +- for _, f := range fl.List { +- list = append(list, &ast.Field{ +- Comment: f.Comment, +- Doc: f.Doc, +- Names: f.Names, +- Tag: f.Tag, +- Type: qualifyTypeExpr(f.Type, qf), +- }) +- } +- return &ast.FieldList{ +- Closing: fl.Closing, +- Opening: fl.Opening, +- List: list, - } -- return a.Enabled -} +diff -urN a/gopls/internal/lsp/source/util.go b/gopls/internal/lsp/source/util.go +--- a/gopls/internal/lsp/source/util.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/util.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,533 +0,0 @@ +-// Copyright 2019 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --// Declare explicit types for package paths, names, and IDs to ensure that we --// never use an ID where a path belongs, and vice versa. If we confused these, --// it would result in confusing errors because package IDs often look like --// package paths. --type ( -- PackageID string // go list's unique identifier for a package (e.g. "vendor/example.com/foo [vendor/example.com/bar.test]") -- PackagePath string // name used to prefix linker symbols (e.g. "vendor/example.com/foo") -- PackageName string // identifier in 'package' declaration (e.g. "foo") -- ImportPath string // path that appears in an import declaration (e.g. "example.com/foo") --) -- --// Package represents a Go package that has been parsed and type-checked. --// --// By design, there is no way to reach from a Package to the Package --// representing one of its dependencies. --// --// Callers must not assume that two Packages share the same --// token.FileSet or types.Importer and thus have commensurable --// token.Pos values or types.Objects. Instead, use stable naming --// schemes, such as (URI, byte offset) for positions, or (PackagePath, --// objectpath.Path) for exported declarations. --type Package interface { -- Metadata() *Metadata -- -- // Results of parsing: -- FileSet() *token.FileSet -- ParseMode() ParseMode -- CompiledGoFiles() []*ParsedGoFile // (borrowed) -- File(uri span.URI) (*ParsedGoFile, error) -- GetSyntax() []*ast.File // (borrowed) -- HasParseErrors() bool -- -- // Results of type checking: -- GetTypes() *types.Package -- GetTypesInfo() *types.Info -- DependencyTypes(PackagePath) *types.Package // nil for indirect dependency of no consequence -- HasTypeErrors() bool -- DiagnosticsForFile(ctx context.Context, s Snapshot, uri span.URI) ([]*Diagnostic, error) --} +-package source - --type unit = struct{} +-import ( +- "context" +- "go/ast" +- "go/printer" +- "go/token" +- "go/types" +- "path/filepath" +- "regexp" +- "sort" +- "strconv" +- "strings" - --// A CriticalError is a workspace-wide error that generally prevents gopls from --// functioning correctly. In the presence of critical errors, other diagnostics --// in the workspace may not make sense. --type CriticalError struct { -- // MainError is the primary error. Must be non-nil. -- MainError error +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/tokeninternal" +- "golang.org/x/tools/internal/typeparams" +-) - -- // Diagnostics contains any supplemental (structured) diagnostics. -- Diagnostics []*Diagnostic +-// IsGenerated gets and reads the file denoted by uri and reports +-// whether it contains a "generated file" comment as described at +-// https://golang.org/s/generatedcode. +-// +-// TODO(adonovan): opt: this function does too much. +-// Move snapshot.ReadFile into the caller (most of which have already done it). +-func IsGenerated(ctx context.Context, snapshot Snapshot, uri span.URI) bool { +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return false +- } +- pgf, err := snapshot.ParseGo(ctx, fh, ParseHeader) +- if err != nil { +- return false +- } +- for _, commentGroup := range pgf.File.Comments { +- for _, comment := range commentGroup.List { +- if matched := generatedRx.MatchString(comment.Text); matched { +- // Check if comment is at the beginning of the line in source. +- if safetoken.Position(pgf.Tok, comment.Slash).Column == 1 { +- return true +- } +- } +- } +- } +- return false -} - --// An Diagnostic corresponds to an LSP Diagnostic. --// https://microsoft.github.io/language-server-protocol/specification#diagnostic --type Diagnostic struct { -- URI span.URI -- Range protocol.Range -- Severity protocol.DiagnosticSeverity -- Code string -- CodeHref string -- -- // Source is a human-readable description of the source of the error. -- // Diagnostics generated by an analysis.Analyzer set it to Analyzer.Name. -- Source DiagnosticSource -- -- Message string +-// adjustedObjEnd returns the end position of obj, possibly modified for +-// package names. +-// +-// TODO(rfindley): eliminate this function, by inlining it at callsites where +-// it makes sense. +-func adjustedObjEnd(obj types.Object) token.Pos { +- nameLen := len(obj.Name()) +- if pkgName, ok := obj.(*types.PkgName); ok { +- // An imported Go package has a package-local, unqualified name. +- // When the name matches the imported package name, there is no +- // identifier in the import spec with the local package name. +- // +- // For example: +- // import "go/ast" // name "ast" matches package name +- // import a "go/ast" // name "a" does not match package name +- // +- // When the identifier does not appear in the source, have the range +- // of the object be the import path, including quotes. +- if pkgName.Imported().Name() == pkgName.Name() { +- nameLen = len(pkgName.Imported().Path()) + len(`""`) +- } +- } +- return obj.Pos() + token.Pos(nameLen) +-} - -- Tags []protocol.DiagnosticTag -- Related []protocol.DiagnosticRelatedInformation +-// Matches cgo generated comment as well as the proposed standard: +-// +-// https://golang.org/s/generatedcode +-var generatedRx = regexp.MustCompile(`// .*DO NOT EDIT\.?`) - -- // Fields below are used internally to generate quick fixes. They aren't -- // part of the LSP spec and don't leave the server. -- SuggestedFixes []SuggestedFix +-// FileKindForLang returns the file kind associated with the given language ID, +-// or UnknownKind if the language ID is not recognized. +-func FileKindForLang(langID string) FileKind { +- switch langID { +- case "go": +- return Go +- case "go.mod": +- return Mod +- case "go.sum": +- return Sum +- case "tmpl", "gotmpl": +- return Tmpl +- case "go.work": +- return Work +- default: +- return UnknownKind +- } -} - --func (d *Diagnostic) String() string { -- return fmt.Sprintf("%v: %s", d.Range, d.Message) +-// nodeAtPos returns the index and the node whose position is contained inside +-// the node list. +-func nodeAtPos(nodes []ast.Node, pos token.Pos) (ast.Node, int) { +- if nodes == nil { +- return nil, -1 +- } +- for i, node := range nodes { +- if node.Pos() <= pos && pos <= node.End() { +- return node, i +- } +- } +- return nil, -1 -} - --type DiagnosticSource string -- --const ( -- UnknownError DiagnosticSource = "" -- ListError DiagnosticSource = "go list" -- ParseError DiagnosticSource = "syntax" -- TypeError DiagnosticSource = "compiler" -- ModTidyError DiagnosticSource = "go mod tidy" -- OptimizationDetailsError DiagnosticSource = "optimizer details" -- UpgradeNotification DiagnosticSource = "upgrade available" -- Vulncheck DiagnosticSource = "vulncheck imports" -- Govulncheck DiagnosticSource = "govulncheck" -- TemplateError DiagnosticSource = "template" -- WorkFileError DiagnosticSource = "go.work file" --) -- --func AnalyzerErrorKind(name string) DiagnosticSource { -- return DiagnosticSource(name) +-// FormatNode returns the "pretty-print" output for an ast node. +-func FormatNode(fset *token.FileSet, n ast.Node) string { +- var buf strings.Builder +- if err := printer.Fprint(&buf, fset, n); err != nil { +- return "" +- } +- return buf.String() -} -diff -urN a/gopls/internal/lsp/source/workspace_symbol.go b/gopls/internal/lsp/source/workspace_symbol.go ---- a/gopls/internal/lsp/source/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,632 +0,0 @@ --// Copyright 2020 The Go Authors. 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 +-// FormatNodeFile is like FormatNode, but requires only the token.File for the +-// syntax containing the given ast node. +-func FormatNodeFile(file *token.File, n ast.Node) string { +- fset := tokeninternal.FileSetFor(file) +- return FormatNode(fset, n) +-} - --import ( -- "context" -- "fmt" -- "go/types" -- "path" -- "path/filepath" -- "regexp" -- "runtime" -- "sort" -- "strings" -- "unicode" +-// Deref returns a pointer's element type, traversing as many levels as needed. +-// Otherwise it returns typ. +-// +-// It can return a pointer type for cyclic types (see golang/go#45510). +-func Deref(typ types.Type) types.Type { +- var seen map[types.Type]struct{} +- for { +- p, ok := typ.Underlying().(*types.Pointer) +- if !ok { +- return typ +- } +- if _, ok := seen[p.Elem()]; ok { +- return typ +- } - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/fuzzy" --) +- typ = p.Elem() - --// Symbol holds a precomputed symbol value. Note: we avoid using the --// protocol.SymbolInformation struct here in order to reduce the size of each --// symbol. --type Symbol struct { -- Name string -- Kind protocol.SymbolKind -- Range protocol.Range +- if seen == nil { +- seen = make(map[types.Type]struct{}) +- } +- seen[typ] = struct{}{} +- } -} - --// maxSymbols defines the maximum number of symbol results that should ever be --// sent in response to a client. --const maxSymbols = 100 +-func SortDiagnostics(d []*Diagnostic) { +- sort.Slice(d, func(i int, j int) bool { +- return CompareDiagnostic(d[i], d[j]) < 0 +- }) +-} - --// WorkspaceSymbols matches symbols across all views using the given query, --// according to the match semantics parameterized by matcherType and style. --// --// The workspace symbol method is defined in the spec as follows: --// --// The workspace symbol request is sent from the client to the server to --// list project-wide symbols matching the query string. --// --// It is unclear what "project-wide" means here, but given the parameters of --// workspace/symbol do not include any workspace identifier, then it has to be --// assumed that "project-wide" means "across all workspaces". Hence why --// WorkspaceSymbols receives the views []View. --// --// However, it then becomes unclear what it would mean to call WorkspaceSymbols --// with a different configured SymbolMatcher per View. Therefore we assume that --// Session level configuration will define the SymbolMatcher to be used for the --// WorkspaceSymbols method. --func WorkspaceSymbols(ctx context.Context, matcher SymbolMatcher, style SymbolStyle, views []View, query string) ([]protocol.SymbolInformation, error) { -- ctx, done := event.Start(ctx, "source.WorkspaceSymbols") -- defer done() -- if query == "" { -- return nil, nil +-func CompareDiagnostic(a, b *Diagnostic) int { +- if r := protocol.CompareRange(a.Range, b.Range); r != 0 { +- return r - } -- -- var s symbolizer -- switch style { -- case DynamicSymbols: -- s = dynamicSymbolMatch -- case FullyQualifiedSymbols: -- s = fullyQualifiedSymbolMatch -- case PackageQualifiedSymbols: -- s = packageSymbolMatch -- default: -- panic(fmt.Errorf("unknown symbol style: %v", style)) +- if a.Source < b.Source { +- return -1 - } -- -- return collectSymbols(ctx, views, matcher, s, query) +- if a.Source > b.Source { +- return +1 +- } +- if a.Message < b.Message { +- return -1 +- } +- if a.Message > b.Message { +- return +1 +- } +- return 0 -} - --// A matcherFunc returns the index and score of a symbol match. --// --// See the comment for symbolCollector for more information. --type matcherFunc func(chunks []string) (int, float64) -- --// A symbolizer returns the best symbol match for a name with pkg, according to --// some heuristic. The symbol name is passed as the slice nameParts of logical --// name pieces. For example, for myType.field the caller can pass either --// []string{"myType.field"} or []string{"myType.", "field"}. --// --// See the comment for symbolCollector for more information. +-// findFileInDeps finds package metadata containing URI in the transitive +-// dependencies of m. When using the Go command, the answer is unique. -// --// The space argument is an empty slice with spare capacity that may be used --// to allocate the result. --type symbolizer func(space []string, name string, pkg *Metadata, m matcherFunc) ([]string, float64) -- --func fullyQualifiedSymbolMatch(space []string, name string, pkg *Metadata, matcher matcherFunc) ([]string, float64) { -- if _, score := dynamicSymbolMatch(space, name, pkg, matcher); score > 0 { -- return append(space, string(pkg.PkgPath), ".", name), score +-// TODO(rfindley): refactor to share logic with findPackageInDeps? +-func findFileInDeps(s MetadataSource, m *Metadata, uri span.URI) *Metadata { +- seen := make(map[PackageID]bool) +- var search func(*Metadata) *Metadata +- search = func(m *Metadata) *Metadata { +- if seen[m.ID] { +- return nil +- } +- seen[m.ID] = true +- for _, cgf := range m.CompiledGoFiles { +- if cgf == uri { +- return m +- } +- } +- for _, dep := range m.DepsByPkgPath { +- m := s.Metadata(dep) +- if m == nil { +- bug.Reportf("nil metadata for %q", dep) +- continue +- } +- if found := search(m); found != nil { +- return found +- } +- } +- return nil - } -- return nil, 0 +- return search(m) -} - --func dynamicSymbolMatch(space []string, name string, pkg *Metadata, matcher matcherFunc) ([]string, float64) { -- if IsCommandLineArguments(pkg.ID) { -- // command-line-arguments packages have a non-sensical package path, so -- // just use their package name. -- return packageSymbolMatch(space, name, pkg, matcher) +-// UnquoteImportPath returns the unquoted import path of s, +-// or "" if the path is not properly quoted. +-func UnquoteImportPath(s *ast.ImportSpec) ImportPath { +- path, err := strconv.Unquote(s.Path.Value) +- if err != nil { +- return "" - } +- return ImportPath(path) +-} - -- var score float64 -- -- endsInPkgName := strings.HasSuffix(string(pkg.PkgPath), string(pkg.Name)) +-// NodeContains returns true if a node encloses a given position pos. +-func NodeContains(n ast.Node, pos token.Pos) bool { +- return n != nil && n.Pos() <= pos && pos <= n.End() +-} - -- // If the package path does not end in the package name, we need to check the -- // package-qualified symbol as an extra pass first. -- if !endsInPkgName { -- pkgQualified := append(space, string(pkg.Name), ".", name) -- idx, score := matcher(pkgQualified) -- nameStart := len(pkg.Name) + 1 -- if score > 0 { -- // If our match is contained entirely within the unqualified portion, -- // just return that. -- if idx >= nameStart { -- return append(space, name), score +-// CollectScopes returns all scopes in an ast path, ordered as innermost scope +-// first. +-func CollectScopes(info *types.Info, path []ast.Node, pos token.Pos) []*types.Scope { +- // scopes[i], where i= nameStart { -- return append(space, name), score +-// Qualifier returns a function that appropriately formats a types.PkgName +-// appearing in a *ast.File. +-func Qualifier(f *ast.File, pkg *types.Package, info *types.Info) types.Qualifier { +- // Construct mapping of import paths to their defined or implicit names. +- imports := make(map[*types.Package]string) +- for _, imp := range f.Imports { +- if pkgname, ok := ImportedPkgName(info, imp); ok { +- imports[pkgname.Imported()] = pkgname.Name() +- } - } -- -- // If our package path ends in the package name, we'll have skipped the -- // initial pass above, so check if we matched just the package-qualified -- // name. -- if endsInPkgName && idx >= 0 { -- pkgStart := len(pkg.PkgPath) - len(pkg.Name) -- if idx >= pkgStart { -- return append(space, string(pkg.Name), ".", name), score +- // Define qualifier to replace full package paths with names of the imports. +- return func(p *types.Package) string { +- if p == pkg { +- return "" +- } +- if name, ok := imports[p]; ok { +- if name == "." { +- return "" +- } +- return name - } +- return p.Name() - } -- -- // Our match was not contained within the unqualified or package qualified -- // symbol. Return the fully qualified symbol but discount the score. -- return fullyQualified, score * 0.6 -} - --func packageSymbolMatch(space []string, name string, pkg *Metadata, matcher matcherFunc) ([]string, float64) { -- qualified := append(space, string(pkg.Name), ".", name) -- if _, s := matcher(qualified); s > 0 { -- return qualified, s +-// requalifier returns a function that re-qualifies identifiers and qualified +-// identifiers contained in targetFile using the given metadata qualifier. +-func requalifier(s MetadataSource, targetFile *ast.File, targetMeta *Metadata, mq MetadataQualifier) func(string) string { +- qm := map[string]string{ +- "": mq(targetMeta.Name, "", targetMeta.PkgPath), - } -- return nil, 0 --} - --func buildMatcher(matcher SymbolMatcher, query string) matcherFunc { -- switch matcher { -- case SymbolFuzzy: -- return parseQuery(query, newFuzzyMatcher) -- case SymbolFastFuzzy: -- return parseQuery(query, func(query string) matcherFunc { -- return fuzzy.NewSymbolMatcher(query).Match -- }) -- case SymbolCaseSensitive: -- return matchExact(query) -- case SymbolCaseInsensitive: -- q := strings.ToLower(query) -- exact := matchExact(q) -- wrapper := []string{""} -- return func(chunks []string) (int, float64) { -- s := strings.Join(chunks, "") -- wrapper[0] = strings.ToLower(s) -- return exact(wrapper) -- } +- // Construct mapping of import paths to their defined or implicit names. +- for _, imp := range targetFile.Imports { +- name, pkgName, impPath, pkgPath := importInfo(s, imp, targetMeta) +- +- // Re-map the target name for the source file. +- qm[name] = mq(pkgName, impPath, pkgPath) - } -- panic(fmt.Errorf("unknown symbol matcher: %v", matcher)) --} - --func newFuzzyMatcher(query string) matcherFunc { -- fm := fuzzy.NewMatcher(query) -- return func(chunks []string) (int, float64) { -- score := float64(fm.ScoreChunks(chunks)) -- ranges := fm.MatchedRanges() -- if len(ranges) > 0 { -- return ranges[0], score +- return func(name string) string { +- if newName, ok := qm[name]; ok { +- return newName - } -- return -1, score +- return name - } -} - --// parseQuery parses a field-separated symbol query, extracting the special --// characters listed below, and returns a matcherFunc corresponding to the AND --// of all field queries. --// --// Special characters: --// --// ^ match exact prefix --// $ match exact suffix --// ' match exact +-// A MetadataQualifier is a function that qualifies an identifier declared in a +-// package with the given package name, import path, and package path. -// --// In all three of these special queries, matches are 'smart-cased', meaning --// they are case sensitive if the symbol query contains any upper-case --// characters, and case insensitive otherwise. --func parseQuery(q string, newMatcher func(string) matcherFunc) matcherFunc { -- fields := strings.Fields(q) -- if len(fields) == 0 { -- return func([]string) (int, float64) { return -1, 0 } +-// In scenarios where metadata is missing the provided PackageName and +-// PackagePath may be empty, but ImportPath must always be non-empty. +-type MetadataQualifier func(PackageName, ImportPath, PackagePath) string +- +-// MetadataQualifierForFile returns a metadata qualifier that chooses the best +-// qualification of an imported package relative to the file f in package with +-// metadata m. +-func MetadataQualifierForFile(s MetadataSource, f *ast.File, m *Metadata) MetadataQualifier { +- // Record local names for import paths. +- localNames := make(map[ImportPath]string) // local names for imports in f +- for _, imp := range f.Imports { +- name, _, impPath, _ := importInfo(s, imp, m) +- localNames[impPath] = name - } -- var funcs []matcherFunc -- for _, field := range fields { -- var f matcherFunc -- switch { -- case strings.HasPrefix(field, "^"): -- prefix := field[1:] -- f = smartCase(prefix, func(chunks []string) (int, float64) { -- s := strings.Join(chunks, "") -- if strings.HasPrefix(s, prefix) { -- return 0, 1 -- } -- return -1, 0 -- }) -- case strings.HasPrefix(field, "'"): -- exact := field[1:] -- f = smartCase(exact, matchExact(exact)) -- case strings.HasSuffix(field, "$"): -- suffix := field[0 : len(field)-1] -- f = smartCase(suffix, func(chunks []string) (int, float64) { -- s := strings.Join(chunks, "") -- if strings.HasSuffix(s, suffix) { -- return len(s) - len(suffix), 1 -- } -- return -1, 0 -- }) -- default: -- f = newMatcher(field) -- } -- funcs = append(funcs, f) +- +- // Record a package path -> import path mapping. +- inverseDeps := make(map[PackageID]PackagePath) +- for path, id := range m.DepsByPkgPath { +- inverseDeps[id] = path - } -- if len(funcs) == 1 { -- return funcs[0] +- importsByPkgPath := make(map[PackagePath]ImportPath) // best import paths by pkgPath +- for impPath, id := range m.DepsByImpPath { +- if id == "" { +- continue +- } +- pkgPath := inverseDeps[id] +- _, hasPath := importsByPkgPath[pkgPath] +- _, hasImp := localNames[impPath] +- // In rare cases, there may be multiple import paths with the same package +- // path. In such scenarios, prefer an import path that already exists in +- // the file. +- if !hasPath || hasImp { +- importsByPkgPath[pkgPath] = impPath +- } - } -- return comboMatcher(funcs).match --} - --func matchExact(exact string) matcherFunc { -- return func(chunks []string) (int, float64) { -- s := strings.Join(chunks, "") -- if idx := strings.LastIndex(s, exact); idx >= 0 { -- return idx, 1 +- return func(pkgName PackageName, impPath ImportPath, pkgPath PackagePath) string { +- // If supplied, translate the package path to an import path in the source +- // package. +- if pkgPath != "" { +- if srcImp := importsByPkgPath[pkgPath]; srcImp != "" { +- impPath = srcImp +- } +- if pkgPath == m.PkgPath { +- return "" +- } - } -- return -1, 0 +- if localName, ok := localNames[impPath]; ok && impPath != "" { +- return string(localName) +- } +- if pkgName != "" { +- return string(pkgName) +- } +- idx := strings.LastIndexByte(string(impPath), '/') +- return string(impPath[idx+1:]) - } -} - --// smartCase returns a matcherFunc that is case-sensitive if q contains any --// upper-case characters, and case-insensitive otherwise. --func smartCase(q string, m matcherFunc) matcherFunc { -- insensitive := strings.ToLower(q) == q -- wrapper := []string{""} -- return func(chunks []string) (int, float64) { -- s := strings.Join(chunks, "") -- if insensitive { -- s = strings.ToLower(s) +-// importInfo collects information about the import specified by imp, +-// extracting its file-local name, package name, import path, and package path. +-// +-// If metadata is missing for the import, the resulting package name and +-// package path may be empty, and the file local name may be guessed based on +-// the import path. +-// +-// Note: previous versions of this helper used a PackageID->PackagePath map +-// extracted from m, for extracting package path even in the case where +-// metadata for a dep was missing. This should not be necessary, as we should +-// always have metadata for IDs contained in DepsByPkgPath. +-func importInfo(s MetadataSource, imp *ast.ImportSpec, m *Metadata) (string, PackageName, ImportPath, PackagePath) { +- var ( +- name string // local name +- pkgName PackageName +- impPath = UnquoteImportPath(imp) +- pkgPath PackagePath +- ) +- +- // If the import has a local name, use it. +- if imp.Name != nil { +- name = imp.Name.Name +- } +- +- // Try to find metadata for the import. If successful and there is no local +- // name, the package name is the local name. +- if depID := m.DepsByImpPath[impPath]; depID != "" { +- if depm := s.Metadata(depID); depm != nil { +- if name == "" { +- name = string(depm.Name) +- } +- pkgName = depm.Name +- pkgPath = depm.PkgPath - } -- wrapper[0] = s -- return m(wrapper) - } +- +- // If the local name is still unknown, guess it based on the import path. +- if name == "" { +- idx := strings.LastIndexByte(string(impPath), '/') +- name = string(impPath[idx+1:]) +- } +- return name, pkgName, impPath, pkgPath -} - --type comboMatcher []matcherFunc +-// isDirective reports whether c is a comment directive. +-// +-// Copied and adapted from go/src/go/ast/ast.go. +-func isDirective(c string) bool { +- if len(c) < 3 { +- return false +- } +- if c[1] != '/' { +- return false +- } +- //-style comment (no newline at the end) +- c = c[2:] +- if len(c) == 0 { +- // empty line +- return false +- } +- // "//line " is a line directive. +- // (The // has been removed.) +- if strings.HasPrefix(c, "line ") { +- return true +- } - --func (c comboMatcher) match(chunks []string) (int, float64) { -- score := 1.0 -- first := 0 -- for _, f := range c { -- idx, s := f(chunks) -- if idx < first { -- first = idx +- // "//[a-z0-9]+:[a-z0-9]" +- // (The // has been removed.) +- colon := strings.Index(c, ":") +- if colon <= 0 || colon+1 >= len(c) { +- return false +- } +- for i := 0; i <= colon+1; i++ { +- if i == colon { +- continue +- } +- b := c[i] +- if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') { +- return false - } -- score *= s - } -- return first, score +- return true -} - --// collectSymbols calls snapshot.Symbols to walk the syntax trees of --// all files in the views' current snapshots, and returns a sorted, --// scored list of symbols that best match the parameters. +-// InDir checks whether path is in the file tree rooted at dir. +-// It checks only the lexical form of the file names. +-// It does not consider symbolic links. -// --// How it matches symbols is parameterized by two interfaces: --// - A matcherFunc determines how well a string symbol matches a query. It --// returns a non-negative score indicating the quality of the match. A score --// of zero indicates no match. --// - A symbolizer determines how we extract the symbol for an object. This --// enables the 'symbolStyle' configuration option. --func collectSymbols(ctx context.Context, views []View, matcherType SymbolMatcher, symbolizer symbolizer, query string) ([]protocol.SymbolInformation, error) { -- // Extract symbols from all files. -- var work []symbolFile -- var roots []string -- seen := make(map[span.URI]bool) -- // TODO(adonovan): opt: parallelize this loop? How often is len > 1? -- for _, v := range views { -- snapshot, release, err := v.Snapshot() -- if err != nil { -- continue // view is shut down; continue with others -- } -- defer release() -- -- // Use the root view URIs for determining (lexically) -- // whether a URI is in any open workspace. -- roots = append(roots, strings.TrimRight(string(v.Folder()), "/")) -- -- filters := v.Options().DirectoryFilters -- filterer := NewFilterer(filters) -- folder := filepath.ToSlash(v.Folder().Filename()) -- symbols, err := snapshot.Symbols(ctx) -- if err != nil { -- return nil, err +-// Copied from go/src/cmd/go/internal/search/search.go. +-func InDir(dir, path string) bool { +- pv := strings.ToUpper(filepath.VolumeName(path)) +- dv := strings.ToUpper(filepath.VolumeName(dir)) +- path = path[len(pv):] +- dir = dir[len(dv):] +- switch { +- default: +- return false +- case pv != dv: +- return false +- case len(path) == len(dir): +- if path == dir { +- return true - } -- for uri, syms := range symbols { -- norm := filepath.ToSlash(uri.Filename()) -- nm := strings.TrimPrefix(norm, folder) -- if filterer.Disallow(nm) { -- continue -- } -- // Only scan each file once. -- if seen[uri] { -- continue -- } -- mds, err := snapshot.MetadataForFile(ctx, uri) -- if err != nil { -- event.Error(ctx, fmt.Sprintf("missing metadata for %q", uri), err) -- continue +- return false +- case dir == "": +- return path != "" +- case len(path) > len(dir): +- if dir[len(dir)-1] == filepath.Separator { +- if path[:len(dir)] == dir { +- return path[len(dir):] != "" - } -- if len(mds) == 0 { -- // TODO: should use the bug reporting API -- continue +- return false +- } +- if path[len(dir)] == filepath.Separator && path[:len(dir)] == dir { +- if len(path) == len(dir)+1 { +- return true - } -- seen[uri] = true -- work = append(work, symbolFile{uri, mds[0], syms}) +- return path[len(dir)+1:] != "" - } +- return false - } +-} - -- // Match symbols in parallel. -- // Each worker has its own symbolStore, -- // which we merge at the end. -- nmatchers := runtime.GOMAXPROCS(-1) // matching is CPU bound -- results := make(chan *symbolStore) -- for i := 0; i < nmatchers; i++ { -- go func(i int) { -- matcher := buildMatcher(matcherType, query) -- store := new(symbolStore) -- // Assign files to workers in round-robin fashion. -- for j := i; j < len(work); j += nmatchers { -- matchFile(store, symbolizer, matcher, roots, work[j]) -- } -- results <- store -- }(i) +-// IsValidImport returns whether importPkgPath is importable +-// by pkgPath +-func IsValidImport(pkgPath, importPkgPath PackagePath) bool { +- i := strings.LastIndex(string(importPkgPath), "/internal/") +- if i == -1 { +- return true - } -- -- // Gather and merge results as they arrive. -- var unified symbolStore -- for i := 0; i < nmatchers; i++ { -- store := <-results -- for _, syms := range store.res { -- unified.store(syms) -- } +- // TODO(rfindley): this looks wrong: IsCommandLineArguments is meant to +- // operate on package IDs, not package paths. +- if IsCommandLineArguments(PackageID(pkgPath)) { +- return true - } -- return unified.results(), nil +- // TODO(rfindley): this is wrong. mod.testx/p should not be able to +- // import mod.test/internal: https://go.dev/play/p/-Ca6P-E4V4q +- return strings.HasPrefix(string(pkgPath), string(importPkgPath[:i])) -} - --type Filterer struct { -- // Whether a filter is excluded depends on the operator (first char of the raw filter). -- // Slices filters and excluded then should have the same length. -- filters []*regexp.Regexp -- excluded []bool +-// IsCommandLineArguments reports whether a given value denotes +-// "command-line-arguments" package, which is a package with an unknown ID +-// created by the go command. It can have a test variant, which is why callers +-// should not check that a value equals "command-line-arguments" directly. +-func IsCommandLineArguments(id PackageID) bool { +- return strings.Contains(string(id), "command-line-arguments") -} - --// NewFilterer computes regular expression form of all raw filters --func NewFilterer(rawFilters []string) *Filterer { -- var f Filterer -- for _, filter := range rawFilters { -- filter = path.Clean(filepath.ToSlash(filter)) -- // TODO(dungtuanle): fix: validate [+-] prefix. -- op, prefix := filter[0], filter[1:] -- // convertFilterToRegexp adds "/" at the end of prefix to handle cases where a filter is a prefix of another filter. -- // For example, it prevents [+foobar, -foo] from excluding "foobar". -- f.filters = append(f.filters, convertFilterToRegexp(filepath.ToSlash(prefix))) -- f.excluded = append(f.excluded, op == '-') +-// embeddedIdent returns the type name identifier for an embedding x, if x in a +-// valid embedding. Otherwise, it returns nil. +-// +-// Spec: An embedded field must be specified as a type name T or as a pointer +-// to a non-interface type name *T +-func embeddedIdent(x ast.Expr) *ast.Ident { +- if star, ok := x.(*ast.StarExpr); ok { +- x = star.X - } -- -- return &f --} -- --// Disallow return true if the path is excluded from the filterer's filters. --func (f *Filterer) Disallow(path string) bool { -- // Ensure trailing but not leading slash. -- path = strings.TrimPrefix(path, "/") -- if !strings.HasSuffix(path, "/") { -- path += "/" +- switch ix := x.(type) { // check for instantiated receivers +- case *ast.IndexExpr: +- x = ix.X +- case *typeparams.IndexListExpr: +- x = ix.X - } -- -- // TODO(adonovan): opt: iterate in reverse and break at first match. -- excluded := false -- for i, filter := range f.filters { -- if filter.MatchString(path) { -- excluded = f.excluded[i] // last match wins +- switch x := x.(type) { +- case *ast.Ident: +- return x +- case *ast.SelectorExpr: +- if _, ok := x.X.(*ast.Ident); ok { +- return x.Sel - } - } -- return excluded +- return nil -} +diff -urN a/gopls/internal/lsp/source/view.go b/gopls/internal/lsp/source/view.go +--- a/gopls/internal/lsp/source/view.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/view.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1033 +0,0 @@ +-// Copyright 2018 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --// convertFilterToRegexp replaces glob-like operator substrings in a string file path to their equivalent regex forms. --// Supporting glob-like operators: --// - **: match zero or more complete path segments --func convertFilterToRegexp(filter string) *regexp.Regexp { -- if filter == "" { -- return regexp.MustCompile(".*") -- } -- var ret strings.Builder -- ret.WriteString("^") -- segs := strings.Split(filter, "/") -- for _, seg := range segs { -- // Inv: seg != "" since path is clean. -- if seg == "**" { -- ret.WriteString(".*") -- } else { -- ret.WriteString(regexp.QuoteMeta(seg)) -- } -- ret.WriteString("/") -- } -- pattern := ret.String() +-package source - -- // Remove unnecessary "^.*" prefix, which increased -- // BenchmarkWorkspaceSymbols time by ~20% (even though -- // filter CPU time increased by only by ~2.5%) when the -- // default filter was changed to "**/node_modules". -- pattern = strings.TrimPrefix(pattern, "^.*") +-import ( +- "bytes" +- "context" +- "crypto/sha256" +- "encoding/json" +- "errors" +- "fmt" +- "go/ast" +- "go/parser" +- "go/scanner" +- "go/token" +- "go/types" +- "io" - -- return regexp.MustCompile(pattern) --} +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/go/analysis" +- "golang.org/x/tools/go/packages" +- "golang.org/x/tools/go/types/objectpath" +- "golang.org/x/tools/gopls/internal/govulncheck" +- "golang.org/x/tools/gopls/internal/lsp/progress" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +- "golang.org/x/tools/gopls/internal/lsp/source/methodsets" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event/label" +- "golang.org/x/tools/internal/event/tag" +- "golang.org/x/tools/internal/gocommand" +- "golang.org/x/tools/internal/imports" +- "golang.org/x/tools/internal/packagesinternal" +-) - --// symbolFile holds symbol information for a single file. --type symbolFile struct { -- uri span.URI -- md *Metadata -- syms []Symbol --} +-// A GlobalSnapshotID uniquely identifies a snapshot within this process and +-// increases monotonically with snapshot creation time. +-// +-// We use a distinct integral type for global IDs to help enforce correct +-// usage. +-type GlobalSnapshotID uint64 - --// matchFile scans a symbol file and adds matching symbols to the store. --func matchFile(store *symbolStore, symbolizer symbolizer, matcher matcherFunc, roots []string, i symbolFile) { -- space := make([]string, 0, 3) -- for _, sym := range i.syms { -- symbolParts, score := symbolizer(space, sym.Name, i.md, matcher) +-// Snapshot represents the current state for the given view. +-type Snapshot interface { +- // SequenceID is the sequence id of this snapshot within its containing +- // view. +- // +- // Relative to their view sequence ids are monotonically increasing, but this +- // does not hold globally: when new views are created their initial snapshot +- // has sequence ID 0. For operations that span multiple views, use global +- // IDs. +- SequenceID() uint64 - -- // Check if the score is too low before applying any downranking. -- if store.tooLow(score) { -- continue -- } +- // GlobalID is a globally unique identifier for this snapshot. Global IDs are +- // monotonic: subsequent snapshots will have higher global ID, though +- // subsequent snapshots in a view may not have adjacent global IDs. +- GlobalID() GlobalSnapshotID - -- // Factors to apply to the match score for the purpose of downranking -- // results. -- // -- // These numbers were crudely calibrated based on trial-and-error using a -- // small number of sample queries. Adjust as necessary. -- // -- // All factors are multiplicative, meaning if more than one applies they are -- // multiplied together. -- const ( -- // nonWorkspaceFactor is applied to symbols outside of any active -- // workspace. Developers are less likely to want to jump to code that they -- // are not actively working on. -- nonWorkspaceFactor = 0.5 -- // nonWorkspaceUnexportedFactor is applied to unexported symbols outside of -- // any active workspace. Since one wouldn't usually jump to unexported -- // symbols to understand a package API, they are particularly irrelevant. -- nonWorkspaceUnexportedFactor = 0.5 -- // every field or method nesting level to access the field decreases -- // the score by a factor of 1.0 - depth*depthFactor, up to a depth of -- // 3. -- depthFactor = 0.2 -- ) +- // FileKind returns the type of a file. +- // +- // We can't reliably deduce the kind from the file name alone, +- // as some editors can be told to interpret a buffer as +- // language different from the file name heuristic, e.g. that +- // an .html file actually contains Go "html/template" syntax, +- // or even that a .go file contains Python. +- FileKind(FileHandle) FileKind - -- startWord := true -- exported := true -- depth := 0.0 -- for _, r := range sym.Name { -- if startWord && !unicode.IsUpper(r) { -- exported = false -- } -- if r == '.' { -- startWord = true -- depth++ -- } else { -- startWord = false -- } -- } +- // Options returns the options associated with this snapshot. +- Options() *Options - -- inWorkspace := false -- for _, root := range roots { -- if strings.HasPrefix(string(i.uri), root) { -- inWorkspace = true -- break -- } -- } +- // View returns the View associated with this snapshot. +- View() View - -- // Apply downranking based on workspace position. -- if !inWorkspace { -- score *= nonWorkspaceFactor -- if !exported { -- score *= nonWorkspaceUnexportedFactor -- } -- } +- // BackgroundContext returns a context used for all background processing +- // on behalf of this snapshot. +- BackgroundContext() context.Context - -- // Apply downranking based on symbol depth. -- if depth > 3 { -- depth = 3 -- } -- score *= 1.0 - depth*depthFactor +- // A Snapshot is a caching implementation of FileSource whose +- // ReadFile method returns consistent information about the existence +- // and content of each file throughout its lifetime. +- FileSource - -- if store.tooLow(score) { -- continue -- } +- // FindFile returns the FileHandle for the given URI, if it is already +- // in the given snapshot. +- // TODO(adonovan): delete this operation; use ReadFile instead. +- FindFile(uri span.URI) FileHandle - -- si := symbolInformation{ -- score: score, -- symbol: strings.Join(symbolParts, ""), -- kind: sym.Kind, -- uri: i.uri, -- rng: sym.Range, -- container: string(i.md.PkgPath), -- } -- store.store(si) -- } --} +- // AwaitInitialized waits until the snapshot's view is initialized. +- AwaitInitialized(ctx context.Context) - --type symbolStore struct { -- res [maxSymbols]symbolInformation --} +- // IsOpen returns whether the editor currently has a file open. +- IsOpen(uri span.URI) bool - --// store inserts si into the sorted results, if si has a high enough score. --func (sc *symbolStore) store(si symbolInformation) { -- if sc.tooLow(si.score) { -- return -- } -- insertAt := sort.Search(len(sc.res), func(i int) bool { -- // Sort by score, then symbol length, and finally lexically. -- if sc.res[i].score != si.score { -- return sc.res[i].score < si.score -- } -- if len(sc.res[i].symbol) != len(si.symbol) { -- return len(sc.res[i].symbol) > len(si.symbol) -- } -- return sc.res[i].symbol > si.symbol -- }) -- if insertAt < len(sc.res)-1 { -- copy(sc.res[insertAt+1:], sc.res[insertAt:len(sc.res)-1]) -- } -- sc.res[insertAt] = si --} +- // IgnoredFile reports if a file would be ignored by a `go list` of the whole +- // workspace. +- IgnoredFile(uri span.URI) bool - --func (sc *symbolStore) tooLow(score float64) bool { -- return score <= sc.res[len(sc.res)-1].score --} +- // Templates returns the .tmpl files +- Templates() map[span.URI]FileHandle - --func (sc *symbolStore) results() []protocol.SymbolInformation { -- var res []protocol.SymbolInformation -- for _, si := range sc.res { -- if si.score <= 0 { -- return res -- } -- res = append(res, si.asProtocolSymbolInformation()) -- } -- return res --} +- // ParseGo returns the parsed AST for the file. +- // If the file is not available, returns nil and an error. +- // Position information is added to FileSet(). +- ParseGo(ctx context.Context, fh FileHandle, mode parser.Mode) (*ParsedGoFile, error) - --func typeToKind(typ types.Type) protocol.SymbolKind { -- switch typ := typ.Underlying().(type) { -- case *types.Interface: -- return protocol.Interface -- case *types.Struct: -- return protocol.Struct -- case *types.Signature: -- if typ.Recv() != nil { -- return protocol.Method -- } -- return protocol.Function -- case *types.Named: -- return typeToKind(typ.Underlying()) -- case *types.Basic: -- i := typ.Info() -- switch { -- case i&types.IsNumeric != 0: -- return protocol.Number -- case i&types.IsBoolean != 0: -- return protocol.Boolean -- case i&types.IsString != 0: -- return protocol.String -- } -- } -- return protocol.Variable --} +- // Analyze runs the specified analyzers on the given packages at this snapshot. +- // +- // If the provided tracker is non-nil, it may be used to report progress of +- // the analysis pass. +- Analyze(ctx context.Context, pkgIDs map[PackageID]unit, analyzers []*Analyzer, tracker *progress.Tracker) ([]*Diagnostic, error) - --// symbolInformation is a cut-down version of protocol.SymbolInformation that --// allows struct values of this type to be used as map keys. --type symbolInformation struct { -- score float64 -- symbol string -- container string -- kind protocol.SymbolKind -- uri span.URI -- rng protocol.Range --} -- --// asProtocolSymbolInformation converts s to a protocol.SymbolInformation value. --// --// TODO: work out how to handle tags if/when they are needed. --func (s symbolInformation) asProtocolSymbolInformation() protocol.SymbolInformation { -- return protocol.SymbolInformation{ -- Name: s.symbol, -- Kind: s.kind, -- Location: protocol.Location{ -- URI: protocol.URIFromSpanURI(s.uri), -- Range: s.rng, -- }, -- ContainerName: s.container, -- } --} -diff -urN a/gopls/internal/lsp/source/workspace_symbol_test.go b/gopls/internal/lsp/source/workspace_symbol_test.go ---- a/gopls/internal/lsp/source/workspace_symbol_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/workspace_symbol_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,136 +0,0 @@ --// Copyright 2020 The Go Authors. 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 ( -- "testing" --) +- // RunGoCommandPiped runs the given `go` command, writing its output +- // to stdout and stderr. Verb, Args, and WorkingDir must be specified. +- // +- // RunGoCommandPiped runs the command serially using gocommand.RunPiped, +- // enforcing that this command executes exclusively to other commands on the +- // server. +- RunGoCommandPiped(ctx context.Context, mode InvocationFlags, inv *gocommand.Invocation, stdout, stderr io.Writer) error - --func TestParseQuery(t *testing.T) { -- tests := []struct { -- query, s string -- wantMatch bool -- }{ -- {"", "anything", false}, -- {"any", "anything", true}, -- {"any$", "anything", false}, -- {"ing$", "anything", true}, -- {"ing$", "anythinG", true}, -- {"inG$", "anything", false}, -- {"^any", "anything", true}, -- {"^any", "Anything", true}, -- {"^Any", "anything", false}, -- {"at", "anything", true}, -- // TODO: this appears to be a bug in the fuzzy matching algorithm. 'At' -- // should cause a case-sensitive match. -- // {"At", "anything", false}, -- {"At", "Anything", true}, -- {"'yth", "Anything", true}, -- {"'yti", "Anything", false}, -- {"'any 'thing", "Anything", true}, -- {"anythn nythg", "Anything", true}, -- {"ntx", "Anything", false}, -- {"anythn", "anything", true}, -- {"ing", "anything", true}, -- {"anythn nythgx", "anything", false}, -- } +- // RunGoCommandDirect runs the given `go` command. Verb, Args, and +- // WorkingDir must be specified. +- RunGoCommandDirect(ctx context.Context, mode InvocationFlags, inv *gocommand.Invocation) (*bytes.Buffer, error) - -- for _, test := range tests { -- matcher := parseQuery(test.query, newFuzzyMatcher) -- if _, score := matcher([]string{test.s}); score > 0 != test.wantMatch { -- t.Errorf("parseQuery(%q) match for %q: %.2g, want match: %t", test.query, test.s, score, test.wantMatch) -- } -- } --} +- // RunGoCommands runs a series of `go` commands that updates the go.mod +- // and go.sum file for wd, and returns their updated contents. +- RunGoCommands(ctx context.Context, allowNetwork bool, wd string, run func(invoke func(...string) (*bytes.Buffer, error)) error) (bool, []byte, []byte, error) - --func TestFiltererDisallow(t *testing.T) { -- tests := []struct { -- filters []string -- included []string -- excluded []string -- }{ -- { -- []string{"+**/c.go"}, -- []string{"a/c.go", "a/b/c.go"}, -- []string{}, -- }, -- { -- []string{"+a/**/c.go"}, -- []string{"a/b/c.go", "a/b/d/c.go", "a/c.go"}, -- []string{}, -- }, -- { -- []string{"-a/c.go", "+a/**"}, -- []string{"a/c.go"}, -- []string{}, -- }, -- { -- []string{"+a/**/c.go", "-**/c.go"}, -- []string{}, -- []string{"a/b/c.go"}, -- }, -- { -- []string{"+a/**/c.go", "-a/**"}, -- []string{}, -- []string{"a/b/c.go"}, -- }, -- { -- []string{"+**/c.go", "-a/**/c.go"}, -- []string{}, -- []string{"a/b/c.go"}, -- }, -- { -- []string{"+foobar", "-foo"}, -- []string{"foobar", "foobar/a"}, -- []string{"foo", "foo/a"}, -- }, -- { -- []string{"+", "-"}, -- []string{}, -- []string{"foobar", "foobar/a", "foo", "foo/a"}, -- }, -- { -- []string{"-", "+"}, -- []string{"foobar", "foobar/a", "foo", "foo/a"}, -- []string{}, -- }, -- { -- []string{"-a/**/b/**/c.go"}, -- []string{}, -- []string{"a/x/y/z/b/f/g/h/c.go"}, -- }, -- // tests for unsupported glob operators -- { -- []string{"+**/c.go", "-a/*/c.go"}, -- []string{"a/b/c.go"}, -- []string{}, -- }, -- { -- []string{"+**/c.go", "-a/?/c.go"}, -- []string{"a/b/c.go"}, -- []string{}, -- }, -- { -- []string{"-b"}, // should only filter paths prefixed with the "b" directory -- []string{"a/b/c.go", "bb"}, -- []string{"b/c/d.go", "b"}, -- }, -- } +- // RunProcessEnvFunc runs fn with the process env for this snapshot's view. +- // Note: the process env contains cached module and filesystem state. +- RunProcessEnvFunc(ctx context.Context, fn func(context.Context, *imports.Options) error) error - -- for _, test := range tests { -- filterer := NewFilterer(test.filters) -- for _, inc := range test.included { -- if filterer.Disallow(inc) { -- t.Errorf("Filters %v excluded %v, wanted included", test.filters, inc) -- } -- } +- // ModFiles are the go.mod files enclosed in the snapshot's view and known +- // to the snapshot. +- ModFiles() []span.URI - -- for _, exc := range test.excluded { -- if !filterer.Disallow(exc) { -- t.Errorf("Filters %v included %v, wanted excluded", test.filters, exc) -- } -- } -- } --} -diff -urN a/gopls/internal/lsp/source/xrefs/xrefs.go b/gopls/internal/lsp/source/xrefs/xrefs.go ---- a/gopls/internal/lsp/source/xrefs/xrefs.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/source/xrefs/xrefs.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,216 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +- // ParseMod is used to parse go.mod files. +- ParseMod(ctx context.Context, fh FileHandle) (*ParsedModule, error) - --// Package xrefs defines the serializable index of cross-package --// references that is computed during type checking. --// --// See ../references2.go for the 'references' query. --package xrefs +- // ModWhy returns the results of `go mod why` for the module specified by +- // the given go.mod file. +- ModWhy(ctx context.Context, fh FileHandle) (map[string]string, error) - --import ( -- "bytes" -- "encoding/gob" -- "go/ast" -- "go/types" -- "log" -- "sort" +- // ModTidy returns the results of `go mod tidy` for the module specified by +- // the given go.mod file. +- ModTidy(ctx context.Context, pm *ParsedModule) (*TidiedModule, error) - -- "golang.org/x/tools/go/types/objectpath" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/typesinternal" --) +- // ModVuln returns import vulnerability analysis for the given go.mod URI. +- // Concurrent requests are combined into a single command. +- ModVuln(ctx context.Context, modURI span.URI) (*govulncheck.Result, error) - --// Index constructs a serializable index of outbound cross-references --// for the specified type-checked package. --func Index(files []*source.ParsedGoFile, pkg *types.Package, info *types.Info) []byte { -- // pkgObjects maps each referenced package Q to a mapping: -- // from each referenced symbol in Q to the ordered list -- // of references to that symbol from this package. -- // A nil types.Object indicates a reference -- // to the package as a whole: an import. -- pkgObjects := make(map[*types.Package]map[types.Object]*gobObject) +- // GoModForFile returns the URI of the go.mod file for the given URI. +- GoModForFile(uri span.URI) span.URI - -- // getObjects returns the object-to-references mapping for a package. -- getObjects := func(pkg *types.Package) map[types.Object]*gobObject { -- objects, ok := pkgObjects[pkg] -- if !ok { -- objects = make(map[types.Object]*gobObject) -- pkgObjects[pkg] = objects -- } -- return objects -- } +- // WorkFile, if non-empty, is the go.work file for the workspace. +- WorkFile() span.URI - -- objectpathFor := typesinternal.NewObjectpathFunc() +- // ParseWork is used to parse go.work files. +- ParseWork(ctx context.Context, fh FileHandle) (*ParsedWorkFile, error) - -- for fileIndex, pgf := range files { +- // BuiltinFile returns information about the special builtin package. +- BuiltinFile(ctx context.Context) (*ParsedGoFile, error) - -- nodeRange := func(n ast.Node) protocol.Range { -- rng, err := pgf.PosRange(n.Pos(), n.End()) -- if err != nil { -- panic(err) // can't fail -- } -- return rng -- } +- // IsBuiltin reports whether uri is part of the builtin package. +- IsBuiltin(uri span.URI) bool - -- ast.Inspect(pgf.File, func(n ast.Node) bool { -- switch n := n.(type) { -- case *ast.Ident: -- // Report a reference for each identifier that -- // uses a symbol exported from another package. -- // (The built-in error.Error method has no package.) -- if n.IsExported() { -- if obj, ok := info.Uses[n]; ok && -- obj.Pkg() != nil && -- obj.Pkg() != pkg { +- // CriticalError returns any critical errors in the workspace. +- // +- // A nil result may mean success, or context cancellation. +- CriticalError(ctx context.Context) *CriticalError - -- objects := getObjects(obj.Pkg()) -- gobObj, ok := objects[obj] -- if !ok { -- path, err := objectpathFor(obj) -- if err != nil { -- // Capitalized but not exported -- // (e.g. local const/var/type). -- return true -- } -- gobObj = &gobObject{Path: path} -- objects[obj] = gobObj -- } +- // Symbols returns all symbols in the snapshot. +- // +- // If workspaceOnly is set, this only includes symbols from files in a +- // workspace package. Otherwise, it returns symbols from all loaded packages. +- Symbols(ctx context.Context, workspaceOnly bool) (map[span.URI][]Symbol, error) - -- gobObj.Refs = append(gobObj.Refs, gobRef{ -- FileIndex: fileIndex, -- Range: nodeRange(n), -- }) -- } -- } +- // -- package metadata -- - -- case *ast.ImportSpec: -- // Report a reference from each import path -- // string to the imported package. -- var obj types.Object -- if n.Name != nil { -- obj = info.Defs[n.Name] -- } else { -- obj = info.Implicits[n] -- } -- if obj == nil { -- return true // missing import -- } -- objects := getObjects(obj.(*types.PkgName).Imported()) -- gobObj, ok := objects[nil] -- if !ok { -- gobObj = &gobObject{Path: ""} -- objects[nil] = gobObj -- } -- gobObj.Refs = append(gobObj.Refs, gobRef{ -- FileIndex: fileIndex, -- Range: nodeRange(n.Path), -- }) -- } -- return true -- }) -- } +- // ReverseDependencies returns a new mapping whose entries are +- // the ID and Metadata of each package in the workspace that +- // directly or transitively depend on the package denoted by id, +- // excluding id itself. +- ReverseDependencies(ctx context.Context, id PackageID, transitive bool) (map[PackageID]*Metadata, error) - -- // Flatten the maps into slices, and sort for determinism. -- var packages []*gobPackage -- for p := range pkgObjects { -- objects := pkgObjects[p] -- gp := &gobPackage{ -- PkgPath: source.PackagePath(p.Path()), -- Objects: make([]*gobObject, 0, len(objects)), -- } -- for _, gobObj := range objects { -- gp.Objects = append(gp.Objects, gobObj) -- } -- sort.Slice(gp.Objects, func(i, j int) bool { -- return gp.Objects[i].Path < gp.Objects[j].Path -- }) -- packages = append(packages, gp) -- } -- sort.Slice(packages, func(i, j int) bool { -- return packages[i].PkgPath < packages[j].PkgPath -- }) +- // WorkspaceMetadata returns a new, unordered slice containing +- // metadata for all ordinary and test packages (but not +- // intermediate test variants) in the workspace. +- // +- // The workspace is the set of modules typically defined by a +- // go.work file. It is not transitively closed: for example, +- // the standard library is not usually part of the workspace +- // even though every module in the workspace depends on it. +- // +- // Operations that must inspect all the dependencies of the +- // workspace packages should instead use AllMetadata. +- WorkspaceMetadata(ctx context.Context) ([]*Metadata, error) - -- return mustEncode(packages) --} +- // AllMetadata returns a new unordered array of metadata for +- // all packages known to this snapshot, which includes the +- // packages of all workspace modules plus their transitive +- // import dependencies. +- // +- // It may also contain ad-hoc packages for standalone files. +- // It includes all test variants. +- AllMetadata(ctx context.Context) ([]*Metadata, error) - --// Lookup searches a serialized index produced by an indexPackage --// operation on m, and returns the locations of all references from m --// to any object in the target set. Each object is denoted by a pair --// of (package path, object path). --func Lookup(m *source.Metadata, data []byte, targets map[source.PackagePath]map[objectpath.Path]struct{}) (locs []protocol.Location) { +- // Metadata returns the metadata for the specified package, +- // or nil if it was not found. +- Metadata(id PackageID) *Metadata - -- // TODO(adonovan): opt: evaluate whether it would be faster to decode -- // in two passes, first with struct { PkgPath string; Objects BLOB } -- // to find the relevant record without decoding the Objects slice, -- // then decode just the desired BLOB into a slice. BLOB would be a -- // type whose Unmarshal method just retains (a copy of) the bytes. -- var packages []gobPackage -- mustDecode(data, &packages) +- // MetadataForFile returns a new slice containing metadata for each +- // package containing the Go file identified by uri, ordered by the +- // number of CompiledGoFiles (i.e. "narrowest" to "widest" package), +- // and secondarily by IsIntermediateTestVariant (false < true). +- // The result may include tests and intermediate test variants of +- // importable packages. +- // It returns an error if the context was cancelled. +- MetadataForFile(ctx context.Context, uri span.URI) ([]*Metadata, error) - -- for _, gp := range packages { -- if objectSet, ok := targets[gp.PkgPath]; ok { -- for _, gobObj := range gp.Objects { -- if _, ok := objectSet[gobObj.Path]; ok { -- for _, ref := range gobObj.Refs { -- uri := m.CompiledGoFiles[ref.FileIndex] -- locs = append(locs, protocol.Location{ -- URI: protocol.URIFromSpanURI(uri), -- Range: ref.Range, -- }) -- } -- } -- } -- } -- } +- // OrphanedFileDiagnostics reports diagnostics for files that have no package +- // associations or which only have only command-line-arguments packages. +- // +- // The caller must not mutate the result. +- OrphanedFileDiagnostics(ctx context.Context) (map[span.URI]*Diagnostic, error) - -- return locs --} +- // -- package type-checking -- - --// -- serialized representation -- +- // TypeCheck parses and type-checks the specified packages, +- // and returns them in the same order as the ids. +- // The resulting packages' types may belong to different importers, +- // so types from different packages are incommensurable. +- // +- // In general, clients should never need to type-checked +- // syntax for an intermediate test variant (ITV) package. +- // Callers should apply RemoveIntermediateTestVariants (or +- // equivalent) before this method, or any of the potentially +- // type-checking methods below. +- TypeCheck(ctx context.Context, ids ...PackageID) ([]Package, error) - --// The cross-reference index records the location of all references --// from one package to symbols defined in other packages --// (dependencies). It does not record within-package references. --// The index for package P consists of a list of gopPackage records, --// each enumerating references to symbols defined a single dependency, Q. +- // PackageDiagnostics returns diagnostics for files contained in specified +- // packages. +- // +- // If these diagnostics cannot be loaded from cache, the requested packages +- // may be type-checked. +- PackageDiagnostics(ctx context.Context, ids ...PackageID) (map[span.URI][]*Diagnostic, error) - --// TODO(adonovan): opt: choose a more compact encoding. Gzip reduces --// the gob output to about one third its size, so clearly there's room --// to improve. The gobRef.Range field is the obvious place to begin. --// Even a zero-length slice gob-encodes to ~285 bytes. +- // References returns cross-references indexes for the specified packages. +- // +- // If these indexes cannot be loaded from cache, the requested packages may +- // be type-checked. +- References(ctx context.Context, ids ...PackageID) ([]XrefIndex, error) - --// A gobPackage records the set of outgoing references from the index --// package to symbols defined in a dependency package. --type gobPackage struct { -- PkgPath source.PackagePath // defining package (Q) -- Objects []*gobObject // set of Q objects referenced by P +- // MethodSets returns method-set indexes for the specified packages. +- // +- // If these indexes cannot be loaded from cache, the requested packages may +- // be type-checked. +- MethodSets(ctx context.Context, ids ...PackageID) ([]*methodsets.Index, error) -} - --// A gobObject records all references to a particular symbol. --type gobObject struct { -- Path objectpath.Path // symbol name within package; "" => import of package itself -- Refs []gobRef // locations of references within P, in lexical order +-// NarrowestMetadataForFile returns metadata for the narrowest package +-// (the one with the fewest files) that encloses the specified file. +-// The result may be a test variant, but never an intermediate test variant. +-func NarrowestMetadataForFile(ctx context.Context, snapshot Snapshot, uri span.URI) (*Metadata, error) { +- metas, err := snapshot.MetadataForFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- RemoveIntermediateTestVariants(&metas) +- if len(metas) == 0 { +- return nil, fmt.Errorf("no package metadata for file %s", uri) +- } +- return metas[0], nil -} - --type gobRef struct { -- FileIndex int // index of enclosing file within P's CompiledGoFiles -- Range protocol.Range // source range of reference +-type XrefIndex interface { +- Lookup(targets map[PackagePath]map[objectpath.Path]struct{}) (locs []protocol.Location) -} - --// -- duplicated from ../../cache/analysis.go -- -- --func mustEncode(x interface{}) []byte { -- var buf bytes.Buffer -- if err := gob.NewEncoder(&buf).Encode(x); err != nil { -- log.Fatalf("internal error encoding %T: %v", x, err) -- } -- return buf.Bytes() +-// SnapshotLabels returns a new slice of labels that should be used for events +-// related to a snapshot. +-func SnapshotLabels(snapshot Snapshot) []label.Label { +- return []label.Label{tag.Snapshot.Of(snapshot.SequenceID()), tag.Directory.Of(snapshot.View().Folder())} -} - --func mustDecode(data []byte, ptr interface{}) { -- if err := gob.NewDecoder(bytes.NewReader(data)).Decode(ptr); err != nil { -- log.Fatalf("internal error decoding %T: %v", ptr, err) +-// NarrowestPackageForFile is a convenience function that selects the +-// narrowest non-ITV package to which this file belongs, type-checks +-// it in the requested mode (full or workspace), and returns it, along +-// with the parse tree of that file. +-// +-// The "narrowest" package is the one with the fewest number of files +-// that includes the given file. This solves the problem of test +-// variants, as the test will have more files than the non-test package. +-// (Historically the preference was a parameter but widest was almost +-// never needed.) +-// +-// An intermediate test variant (ITV) package has identical source +-// to a regular package but resolves imports differently. +-// gopls should never need to type-check them. +-// +-// Type-checking is expensive. Call snapshot.ParseGo if all you need +-// is a parse tree, or snapshot.MetadataForFile if you only need metadata. +-func NarrowestPackageForFile(ctx context.Context, snapshot Snapshot, uri span.URI) (Package, *ParsedGoFile, error) { +- metas, err := snapshot.MetadataForFile(ctx, uri) +- if err != nil { +- return nil, nil, err +- } +- RemoveIntermediateTestVariants(&metas) +- if len(metas) == 0 { +- return nil, nil, fmt.Errorf("no package metadata for file %s", uri) +- } +- narrowest := metas[0] +- pkgs, err := snapshot.TypeCheck(ctx, narrowest.ID) +- if err != nil { +- return nil, nil, err +- } +- pkg := pkgs[0] +- pgf, err := pkg.File(uri) +- if err != nil { +- return nil, nil, err // "can't happen" - } +- return pkg, pgf, err -} -diff -urN a/gopls/internal/lsp/symbols.go b/gopls/internal/lsp/symbols.go ---- a/gopls/internal/lsp/symbols.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/symbols.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,60 +0,0 @@ --// Copyright 2019 The Go Authors. 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 +-// InvocationFlags represents the settings of a particular go command invocation. +-// It is a mode, plus a set of flag bits. +-type InvocationFlags int - --import ( -- "context" +-const ( +- // Normal is appropriate for commands that might be run by a user and don't +- // deliberately modify go.mod files, e.g. `go test`. +- Normal InvocationFlags = iota +- // WriteTemporaryModFile is for commands that need information from a +- // modified version of the user's go.mod file, e.g. `go mod tidy` used to +- // generate diagnostics. +- WriteTemporaryModFile +- // LoadWorkspace is for packages.Load, and other operations that should +- // consider the whole workspace at once. +- LoadWorkspace - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/template" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/event/tag" +- // AllowNetwork is a flag bit that indicates the invocation should be +- // allowed to access the network. +- AllowNetwork InvocationFlags = 1 << 10 -) - --func (s *Server) documentSymbol(ctx context.Context, params *protocol.DocumentSymbolParams) ([]interface{}, error) { -- ctx, done := event.Start(ctx, "lsp.Server.documentSymbol") -- defer done() +-func (m InvocationFlags) Mode() InvocationFlags { +- return m & (AllowNetwork - 1) +-} - -- snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) -- defer release() -- if !ok { -- return []interface{}{}, err -- } -- var docSymbols []protocol.DocumentSymbol -- switch snapshot.View().FileKind(fh) { -- case source.Tmpl: -- docSymbols, err = template.DocumentSymbols(snapshot, fh) -- case source.Go: -- docSymbols, err = source.DocumentSymbols(ctx, snapshot, fh) -- default: -- return []interface{}{}, nil -- } -- if err != nil { -- event.Error(ctx, "DocumentSymbols failed", err, tag.URI.Of(fh.URI())) -- return []interface{}{}, nil -- } -- // Convert the symbols to an interface array. -- // TODO: Remove this once the lsp deprecates SymbolInformation. -- symbols := make([]interface{}, len(docSymbols)) -- for i, s := range docSymbols { -- if snapshot.View().Options().HierarchicalDocumentSymbolSupport { -- symbols[i] = s -- continue -- } -- // If the client does not support hierarchical document symbols, then -- // we need to be backwards compatible for now and return SymbolInformation. -- symbols[i] = protocol.SymbolInformation{ -- Name: s.Name, -- Kind: s.Kind, -- Deprecated: s.Deprecated, -- Location: protocol.Location{ -- URI: params.TextDocument.URI, -- Range: s.Range, -- }, -- } -- } -- return symbols, nil +-func (m InvocationFlags) AllowNetwork() bool { +- return m&AllowNetwork != 0 -} -diff -urN a/gopls/internal/lsp/template/completion.go b/gopls/internal/lsp/template/completion.go ---- a/gopls/internal/lsp/template/completion.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/completion.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,287 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package template +-// View represents a single workspace. +-// This is the level at which we maintain configuration like working directory +-// and build tags. +-type View interface { +- // ID returns a globally unique identifier for this view. +- ID() string - --import ( -- "bytes" -- "context" -- "fmt" -- "go/scanner" -- "go/token" -- "strings" +- // Name returns the name this view was constructed with. +- Name() string - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" --) +- // Folder returns the folder with which this view was created. +- Folder() span.URI - --// information needed for completion --type completer struct { -- p *Parsed -- pos protocol.Position -- offset int // offset of the start of the Token -- ctx protocol.CompletionContext -- syms map[string]symbol --} +- // Snapshot returns the current snapshot for the view, and a +- // release function that must be called when the Snapshot is +- // no longer needed. +- // +- // If the view is shut down, the resulting error will be non-nil, and the +- // release function need not be called. +- Snapshot() (Snapshot, func(), error) - --func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, pos protocol.Position, context protocol.CompletionContext) (*protocol.CompletionList, error) { -- all := New(snapshot.Templates()) -- var start int // the beginning of the Token (completed or not) -- syms := make(map[string]symbol) -- var p *Parsed -- for fn, fc := range all.files { -- // collect symbols from all template files -- filterSyms(syms, fc.symbols) -- if fn.Filename() != fh.URI().Filename() { -- continue -- } -- if start = inTemplate(fc, pos); start == -1 { -- return nil, nil -- } -- p = fc -- } -- if p == nil { -- // this cannot happen unless the search missed a template file -- return nil, fmt.Errorf("%s not found", fh.FileIdentity().URI.Filename()) -- } -- c := completer{ -- p: p, -- pos: pos, -- offset: start + len(Left), -- ctx: context, -- syms: syms, -- } -- return c.complete() +- // IsGoPrivatePath reports whether target is a private import path, as identified +- // by the GOPRIVATE environment variable. +- IsGoPrivatePath(path string) bool +- +- // ModuleUpgrades returns known module upgrades for the dependencies of +- // modfile. +- ModuleUpgrades(modfile span.URI) map[string]string +- +- // RegisterModuleUpgrades registers that upgrades exist for the given modules +- // required by modfile. +- RegisterModuleUpgrades(modfile span.URI, upgrades map[string]string) +- +- // ClearModuleUpgrades clears all upgrades for the modules in modfile. +- ClearModuleUpgrades(modfile span.URI) +- +- // Vulnerabilities returns known vulnerabilities for the given modfile. +- // TODO(suzmue): replace command.Vuln with a different type, maybe +- // https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck/govulnchecklib#Summary? +- Vulnerabilities(modfile ...span.URI) map[span.URI]*govulncheck.Result +- +- // SetVulnerabilities resets the list of vulnerabilities that exists for the given modules +- // required by modfile. +- SetVulnerabilities(modfile span.URI, vulncheckResult *govulncheck.Result) +- +- // GoVersion returns the configured Go version for this view. +- GoVersion() int +- +- // GoVersionString returns the go version string configured for this view. +- // Unlike [GoVersion], this encodes the minor version and commit hash information. +- GoVersionString() string -} - --func filterSyms(syms map[string]symbol, ns []symbol) { -- for _, xsym := range ns { -- switch xsym.kind { -- case protocol.Method, protocol.Package, protocol.Boolean, protocol.Namespace, -- protocol.Function: -- syms[xsym.name] = xsym // we don't care which symbol we get -- case protocol.Variable: -- if xsym.name != "dot" { -- syms[xsym.name] = xsym -- } -- case protocol.Constant: -- if xsym.name == "nil" { -- syms[xsym.name] = xsym -- } -- } -- } +-// A FileSource maps URIs to FileHandles. +-type FileSource interface { +- // ReadFile returns the FileHandle for a given URI, either by +- // reading the content of the file or by obtaining it from a cache. +- ReadFile(ctx context.Context, uri span.URI) (FileHandle, error) -} - --// return the starting position of the enclosing token, or -1 if none --func inTemplate(fc *Parsed, pos protocol.Position) int { -- // pos is the pos-th character. if the cursor is at the beginning -- // of the file, pos is 0. That is, we've only seen characters before pos -- // 1. pos might be in a Token, return tk.Start -- // 2. pos might be after an elided but before a Token, return elided -- // 3. return -1 for false -- offset := fc.FromPosition(pos) -- // this could be a binary search, as the tokens are ordered -- for _, tk := range fc.tokens { -- if tk.Start < offset && offset <= tk.End { -- return tk.Start -- } -- } -- for _, x := range fc.elided { -- if x > offset { -- // fc.elided is sorted -- break -- } -- // If the interval [x,offset] does not contain Left or Right -- // then provide completions. (do we need the test for Right?) -- if !bytes.Contains(fc.buf[x:offset], []byte(Left)) && !bytes.Contains(fc.buf[x:offset], []byte(Right)) { -- return x -- } -- } -- return -1 +-// A MetadataSource maps package IDs to metadata. +-// +-// TODO(rfindley): replace this with a concrete metadata graph, once it is +-// exposed from the snapshot. +-type MetadataSource interface { +- // Metadata returns Metadata for the given package ID, or nil if it does not +- // exist. +- Metadata(PackageID) *Metadata -} - --var ( -- keywords = []string{"if", "with", "else", "block", "range", "template", "end}}", "end"} -- globals = []string{"and", "call", "html", "index", "slice", "js", "len", "not", "or", -- "urlquery", "printf", "println", "print", "eq", "ne", "le", "lt", "ge", "gt"} --) +-// A ParsedGoFile contains the results of parsing a Go file. +-type ParsedGoFile struct { +- URI span.URI +- Mode parser.Mode +- File *ast.File +- Tok *token.File +- // Source code used to build the AST. It may be different from the +- // actual content of the file if we have fixed the AST. +- Src []byte - --// find the completions. start is the offset of either the Token enclosing pos, or where --// the incomplete token starts. --// The error return is always nil. --func (c *completer) complete() (*protocol.CompletionList, error) { -- ans := &protocol.CompletionList{IsIncomplete: true, Items: []protocol.CompletionItem{}} -- start := c.p.FromPosition(c.pos) -- sofar := c.p.buf[c.offset:start] -- if len(sofar) == 0 || sofar[len(sofar)-1] == ' ' || sofar[len(sofar)-1] == '\t' { -- return ans, nil -- } -- // sofar could be parsed by either c.analyzer() or scan(). The latter is precise -- // and slower, but fast enough -- words := scan(sofar) -- // 1. if pattern starts $, show variables -- // 2. if pattern starts ., show methods (and . by itself?) -- // 3. if len(words) == 1, show firstWords (but if it were a |, show functions and globals) -- // 4. ...? (parenthetical expressions, arguments, ...) (packages, namespaces, nil?) -- if len(words) == 0 { -- return nil, nil // if this happens, why were we called? -- } -- pattern := string(words[len(words)-1]) -- if pattern[0] == '$' { -- // should we also return a raw "$"? -- for _, s := range c.syms { -- if s.kind == protocol.Variable && weakMatch(s.name, pattern) > 0 { -- ans.Items = append(ans.Items, protocol.CompletionItem{ -- Label: s.name, -- Kind: protocol.VariableCompletion, -- Detail: "Variable", -- }) -- } -- } -- return ans, nil -- } -- if pattern[0] == '.' { -- for _, s := range c.syms { -- if s.kind == protocol.Method && weakMatch("."+s.name, pattern) > 0 { -- ans.Items = append(ans.Items, protocol.CompletionItem{ -- Label: s.name, -- Kind: protocol.MethodCompletion, -- Detail: "Method/member", -- }) -- } -- } -- return ans, nil -- } -- // could we get completion attempts in strings or numbers, and if so, do we care? -- // globals -- for _, kw := range globals { -- if weakMatch(kw, string(pattern)) != 0 { -- ans.Items = append(ans.Items, protocol.CompletionItem{ -- Label: kw, -- Kind: protocol.KeywordCompletion, -- Detail: "Function", -- }) -- } -- } -- // and functions -- for _, s := range c.syms { -- if s.kind == protocol.Function && weakMatch(s.name, pattern) != 0 { -- ans.Items = append(ans.Items, protocol.CompletionItem{ -- Label: s.name, -- Kind: protocol.FunctionCompletion, -- Detail: "Function", -- }) -- } -- } -- // keywords if we're at the beginning -- if len(words) <= 1 || len(words[len(words)-2]) == 1 && words[len(words)-2][0] == '|' { -- for _, kw := range keywords { -- if weakMatch(kw, string(pattern)) != 0 { -- ans.Items = append(ans.Items, protocol.CompletionItem{ -- Label: kw, -- Kind: protocol.KeywordCompletion, -- Detail: "keyword", -- }) -- } -- } -- } -- return ans, nil +- // FixedSrc and Fixed AST report on "fixing" that occurred during parsing of +- // this file. +- // +- // If FixedSrc == true, the source contained in the Src field was modified +- // from the original source to improve parsing. +- // +- // If FixedAST == true, the ast was modified after parsing, and therefore +- // positions encoded in the AST may not accurately represent the content of +- // the Src field. +- // +- // TODO(rfindley): there are many places where we haphazardly use the Src or +- // positions without checking these fields. Audit these places and guard +- // accordingly. After doing so, we may find that we don't need to +- // differentiate FixedSrc and FixedAST. +- FixedSrc bool +- FixedAST bool +- Mapper *protocol.Mapper // may map fixed Src, not file content +- ParseErr scanner.ErrorList -} - --// someday think about comments, strings, backslashes, etc --// this would repeat some of the template parsing, but because the user is typing --// there may be no parse tree here. --// (go/scanner will report 2 tokens for $a, as $ is not a legal go identifier character) --// (go/scanner is about 2.7 times more expensive) --func (c *completer) analyze(buf []byte) [][]byte { -- // we want to split on whitespace and before dots -- var working []byte -- var ans [][]byte -- for _, ch := range buf { -- if ch == '.' && len(working) > 0 { -- ans = append(ans, working) -- working = []byte{'.'} -- continue -- } -- if ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' { -- if len(working) > 0 { -- ans = append(ans, working) -- working = []byte{} -- continue -- } -- } -- working = append(working, ch) -- } -- if len(working) > 0 { -- ans = append(ans, working) -- } -- ch := buf[len(buf)-1] -- if ch == ' ' || ch == '\t' { -- // avoid completing on whitespace -- ans = append(ans, []byte{ch}) -- } -- return ans +-// Fixed reports whether p was "Fixed", meaning that its source or positions +-// may not correlate with the original file. +-func (p ParsedGoFile) Fixed() bool { +- return p.FixedSrc || p.FixedAST -} - --// version of c.analyze that uses go/scanner. --func scan(buf []byte) []string { -- fset := token.NewFileSet() -- fp := fset.AddFile("", -1, len(buf)) -- var sc scanner.Scanner -- sc.Init(fp, buf, func(pos token.Position, msg string) {}, scanner.ScanComments) -- ans := make([]string, 0, 10) // preallocating gives a measurable savings -- for { -- _, tok, lit := sc.Scan() // tok is an int -- if tok == token.EOF { -- break // done -- } else if tok == token.SEMICOLON && lit == "\n" { -- continue // don't care, but probably can't happen -- } else if tok == token.PERIOD { -- ans = append(ans, ".") // lit is empty -- } else if tok == token.IDENT && len(ans) > 0 && ans[len(ans)-1] == "." { -- ans[len(ans)-1] = "." + lit -- } else if tok == token.IDENT && len(ans) > 0 && ans[len(ans)-1] == "$" { -- ans[len(ans)-1] = "$" + lit -- } else if lit != "" { -- ans = append(ans, lit) -- } +-// -- go/token domain convenience helpers -- +- +-// PositionPos returns the token.Pos of protocol position p within the file. +-func (pgf *ParsedGoFile) PositionPos(p protocol.Position) (token.Pos, error) { +- offset, err := pgf.Mapper.PositionOffset(p) +- if err != nil { +- return token.NoPos, err - } -- return ans +- return safetoken.Pos(pgf.Tok, offset) -} - --// pattern is what the user has typed --func weakMatch(choice, pattern string) float64 { -- lower := strings.ToLower(choice) -- // for now, use only lower-case everywhere -- pattern = strings.ToLower(pattern) -- // The first char has to match -- if pattern[0] != lower[0] { -- return 0 -- } -- // If they start with ., then the second char has to match -- from := 1 -- if pattern[0] == '.' { -- if len(pattern) < 2 { -- return 1 // pattern just a ., so it matches -- } -- if pattern[1] != lower[1] { -- return 0 -- } -- from = 2 -- } -- // check that all the characters of pattern occur as a subsequence of choice -- i, j := from, from -- for ; i < len(lower) && j < len(pattern); j++ { -- if pattern[j] == lower[i] { -- i++ -- if i >= len(lower) { -- return 0 -- } -- } -- } -- if j < len(pattern) { -- return 0 -- } -- return 1 +-// PosRange returns a protocol Range for the token.Pos interval in this file. +-func (pgf *ParsedGoFile) PosRange(start, end token.Pos) (protocol.Range, error) { +- return pgf.Mapper.PosRange(pgf.Tok, start, end) -} -diff -urN a/gopls/internal/lsp/template/completion_test.go b/gopls/internal/lsp/template/completion_test.go ---- a/gopls/internal/lsp/template/completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/completion_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,102 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package template +-// PosMappedRange returns a MappedRange for the token.Pos interval in this file. +-// A MappedRange can be converted to any other form. +-func (pgf *ParsedGoFile) PosMappedRange(start, end token.Pos) (protocol.MappedRange, error) { +- return pgf.Mapper.PosMappedRange(pgf.Tok, start, end) +-} - --import ( -- "log" -- "sort" -- "strings" -- "testing" +-// PosLocation returns a protocol Location for the token.Pos interval in this file. +-func (pgf *ParsedGoFile) PosLocation(start, end token.Pos) (protocol.Location, error) { +- return pgf.Mapper.PosLocation(pgf.Tok, start, end) +-} - -- "golang.org/x/tools/gopls/internal/lsp/protocol" --) +-// NodeRange returns a protocol Range for the ast.Node interval in this file. +-func (pgf *ParsedGoFile) NodeRange(node ast.Node) (protocol.Range, error) { +- return pgf.Mapper.NodeRange(pgf.Tok, node) +-} - --func init() { -- log.SetFlags(log.Lshortfile) +-// NodeMappedRange returns a MappedRange for the ast.Node interval in this file. +-// A MappedRange can be converted to any other form. +-func (pgf *ParsedGoFile) NodeMappedRange(node ast.Node) (protocol.MappedRange, error) { +- return pgf.Mapper.NodeMappedRange(pgf.Tok, node) -} - --type tparse struct { -- marked string // ^ shows where to ask for completions. (The user just typed the following character.) -- wanted []string // expected completions +-// NodeLocation returns a protocol Location for the ast.Node interval in this file. +-func (pgf *ParsedGoFile) NodeLocation(node ast.Node) (protocol.Location, error) { +- return pgf.Mapper.PosLocation(pgf.Tok, node.Pos(), node.End()) -} - --// Test completions in templates that parse enough (if completion needs symbols) --// Seen characters up to the ^ --func TestParsed(t *testing.T) { -- var tests = []tparse{ -- {"{{x}}{{12. xx^", nil}, // https://github.com/golang/go/issues/50430 -- {`
    Allocated bytes{{fuint64 .HeapAlloc}}
    `, nil}, -- {"{{i^f}}", []string{"index", "if"}}, -- {"{{if .}}{{e^ {{end}}", []string{"eq", "end}}", "else", "end"}}, -- {"{{foo}}{{f^", []string{"foo"}}, -- {"{{$^}}", []string{"$"}}, -- {"{{$x:=4}}{{$^", []string{"$x"}}, -- {"{{$x:=4}}{{$ ^ ", []string{}}, -- {"{{len .Modified}}{{.^Mo", []string{"Modified"}}, -- {"{{len .Modified}}{{.mf^", []string{"Modified"}}, -- {"{{$^ }}", []string{"$"}}, -- {"{{$a =3}}{{$^", []string{"$a"}}, -- // .two is not good here: fix someday -- {`{{.Modified}}{{.^{{if $.one.two}}xxx{{end}}`, []string{"Modified", "one", "two"}}, -- {`{{.Modified}}{{.o^{{if $.one.two}}xxx{{end}}`, []string{"one"}}, -- {"{{.Modiifed}}{{.one.t^{{if $.one.two}}xxx{{end}}", []string{"two"}}, -- {`{{block "foo" .}}{{i^`, []string{"index", "if"}}, -- {"{{in^{{Internal}}", []string{"index", "Internal", "if"}}, -- // simple number has no completions -- {"{{4^e", []string{}}, -- // simple string has no completions -- {"{{`e^", []string{}}, -- {"{{`No i^", []string{}}, // example of why go/scanner is used -- {"{{xavier}}{{12. x^", []string{"xavier"}}, -- } -- for _, tx := range tests { -- c := testCompleter(t, tx) -- var v []string -- if c != nil { -- ans, _ := c.complete() -- for _, a := range ans.Items { -- v = append(v, a.Label) -- } -- } -- if len(v) != len(tx.wanted) { -- t.Errorf("%q: got %q, wanted %q %d,%d", tx.marked, v, tx.wanted, len(v), len(tx.wanted)) -- continue -- } -- sort.Strings(tx.wanted) -- sort.Strings(v) -- for i := 0; i < len(v); i++ { -- if tx.wanted[i] != v[i] { -- t.Errorf("%q at %d: got %v, wanted %v", tx.marked, i, v, tx.wanted) -- break -- } -- } +-// RangePos parses a protocol Range back into the go/token domain. +-func (pgf *ParsedGoFile) RangePos(r protocol.Range) (token.Pos, token.Pos, error) { +- start, end, err := pgf.Mapper.RangeOffsets(r) +- if err != nil { +- return token.NoPos, token.NoPos, err - } +- return pgf.Tok.Pos(start), pgf.Tok.Pos(end), nil -} - --func testCompleter(t *testing.T, tx tparse) *completer { -- t.Helper() -- // seen chars up to ^ -- col := strings.Index(tx.marked, "^") -- buf := strings.Replace(tx.marked, "^", "", 1) -- p := parseBuffer([]byte(buf)) -- pos := protocol.Position{Line: 0, Character: uint32(col)} -- if p.ParseErr != nil { -- log.Printf("%q: %v", tx.marked, p.ParseErr) -- } -- offset := inTemplate(p, pos) -- if offset == -1 { -- return nil -- } -- syms := make(map[string]symbol) -- filterSyms(syms, p.symbols) -- c := &completer{ -- p: p, -- pos: protocol.Position{Line: 0, Character: uint32(col)}, -- offset: offset + len(Left), -- ctx: protocol.CompletionContext{TriggerKind: protocol.Invoked}, -- syms: syms, -- } -- return c +-// A ParsedModule contains the results of parsing a go.mod file. +-type ParsedModule struct { +- URI span.URI +- File *modfile.File +- Mapper *protocol.Mapper +- ParseErrors []*Diagnostic -} -diff -urN a/gopls/internal/lsp/template/highlight.go b/gopls/internal/lsp/template/highlight.go ---- a/gopls/internal/lsp/template/highlight.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/highlight.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,96 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package template +-// A ParsedWorkFile contains the results of parsing a go.work file. +-type ParsedWorkFile struct { +- URI span.URI +- File *modfile.WorkFile +- Mapper *protocol.Mapper +- ParseErrors []*Diagnostic +-} - --import ( -- "context" -- "fmt" -- "regexp" +-// A TidiedModule contains the results of running `go mod tidy` on a module. +-type TidiedModule struct { +- // Diagnostics representing changes made by `go mod tidy`. +- Diagnostics []*Diagnostic +- // The bytes of the go.mod file after it was tidied. +- TidiedContent []byte +-} - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" --) +-// Metadata represents package metadata retrieved from go/packages. +-// The Deps* maps do not contain self-import edges. +-// +-// An ad-hoc package (without go.mod or GOPATH) has its ID, PkgPath, +-// and LoadDir equal to the absolute path of its directory. +-type Metadata struct { +- ID PackageID +- PkgPath PackagePath +- Name PackageName - --func Highlight(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, loc protocol.Position) ([]protocol.DocumentHighlight, error) { -- buf, err := fh.Read() -- if err != nil { -- return nil, err -- } -- p := parseBuffer(buf) -- pos := p.FromPosition(loc) -- var ans []protocol.DocumentHighlight -- if p.ParseErr == nil { -- for _, s := range p.symbols { -- if s.start <= pos && pos < s.start+s.length { -- return markSymbols(p, s) -- } -- } -- } -- // these tokens exist whether or not there was a parse error -- // (symbols require a successful parse) -- for _, tok := range p.tokens { -- if tok.Start <= pos && pos < tok.End { -- wordAt := findWordAt(p, pos) -- if len(wordAt) > 0 { -- return markWordInToken(p, wordAt) -- } -- } -- } -- // find the 'word' at pos, etc: someday -- // until then we get the default action, which doesn't respect word boundaries -- return ans, nil +- // these three fields are as defined by go/packages.Package +- GoFiles []span.URI +- CompiledGoFiles []span.URI +- IgnoredFiles []span.URI +- +- ForTest PackagePath // q in a "p [q.test]" package, else "" +- TypesSizes types.Sizes +- Errors []packages.Error // must be set for packages in import cycles +- DepsByImpPath map[ImportPath]PackageID // may contain dups; empty ID => missing +- DepsByPkgPath map[PackagePath]PackageID // values are unique and non-empty +- Module *packages.Module +- DepsErrors []*packagesinternal.PackageError +- Diagnostics []*Diagnostic // processed diagnostics from 'go list' +- LoadDir string // directory from which go/packages was run +- Standalone bool // package synthesized for a standalone file (e.g. ignore-tagged) -} - --func markSymbols(p *Parsed, sym symbol) ([]protocol.DocumentHighlight, error) { -- var ans []protocol.DocumentHighlight -- for _, s := range p.symbols { -- if s.name == sym.name { -- kind := protocol.Read -- if s.vardef { -- kind = protocol.Write -- } -- ans = append(ans, protocol.DocumentHighlight{ -- Range: p.Range(s.start, s.length), -- Kind: kind, -- }) -- } -- } -- return ans, nil +-func (m *Metadata) String() string { return string(m.ID) } +- +-// IsIntermediateTestVariant reports whether the given package is an +-// intermediate test variant (ITV), e.g. "net/http [net/url.test]". +-// +-// An ITV has identical syntax to the regular variant, but different +-// import metadata (DepsBy{Imp,Pkg}Path). +-// +-// Such test variants arise when an x_test package (in this case net/url_test) +-// imports a package (in this case net/http) that itself imports the +-// non-x_test package (in this case net/url). +-// +-// This is done so that the forward transitive closure of net/url_test has +-// only one package for the "net/url" import. +-// The ITV exists to hold the test variant import: +-// +-// net/url_test [net/url.test] +-// +-// | "net/http" -> net/http [net/url.test] +-// | "net/url" -> net/url [net/url.test] +-// | ... +-// +-// net/http [net/url.test] +-// +-// | "net/url" -> net/url [net/url.test] +-// | ... +-// +-// This restriction propagates throughout the import graph of net/http: for +-// every package imported by net/http that imports net/url, there must be an +-// intermediate test variant that instead imports "net/url [net/url.test]". +-// +-// As one can see from the example of net/url and net/http, intermediate test +-// variants can result in many additional packages that are essentially (but +-// not quite) identical. For this reason, we filter these variants wherever +-// possible. +-// +-// # Why we mostly ignore intermediate test variants +-// +-// In projects with complicated tests, there may be a very large +-// number of ITVs--asymptotically more than the number of ordinary +-// variants. Since they have identical syntax, it is fine in most +-// cases to ignore them since the results of analyzing the ordinary +-// variant suffice. However, this is not entirely sound. +-// +-// Consider this package: +-// +-// // p/p.go -- in all variants of p +-// package p +-// type T struct { io.Closer } +-// +-// // p/p_test.go -- in test variant of p +-// package p +-// func (T) Close() error { ... } +-// +-// The ordinary variant "p" defines T with a Close method promoted +-// from io.Closer. But its test variant "p [p.test]" defines a type T +-// with a Close method from p_test.go. +-// +-// Now consider a package q that imports p, perhaps indirectly. Within +-// it, T.Close will resolve to the first Close method: +-// +-// // q/q.go -- in all variants of q +-// package q +-// import "p" +-// var _ = new(p.T).Close +-// +-// Let's assume p also contains this file defining an external test (xtest): +-// +-// // p/p_x_test.go -- external test of p +-// package p_test +-// import ( "q"; "testing" ) +-// func Test(t *testing.T) { ... } +-// +-// Note that q imports p, but p's xtest imports q. Now, in "q +-// [p.test]", the intermediate test variant of q built for p's +-// external test, T.Close resolves not to the io.Closer.Close +-// interface method, but to the concrete method of T.Close +-// declared in p_test.go. +-// +-// If we now request all references to the T.Close declaration in +-// p_test.go, the result should include the reference from q's ITV. +-// (It's not just methods that can be affected; fields can too, though +-// it requires bizarre code to achieve.) +-// +-// As a matter of policy, gopls mostly ignores this subtlety, +-// because to account for it would require that we type-check every +-// intermediate test variant of p, of which there could be many. +-// Good code doesn't rely on such trickery. +-// +-// Most callers of MetadataForFile call RemoveIntermediateTestVariants +-// to discard them before requesting type checking, or the products of +-// type-checking such as the cross-reference index or method set index. +-// +-// MetadataForFile doesn't do this filtering itself becaused in some +-// cases we need to make a reverse dependency query on the metadata +-// graph, and it's important to include the rdeps of ITVs in that +-// query. But the filtering of ITVs should be applied after that step, +-// before type checking. +-// +-// In general, we should never type check an ITV. +-func (m *Metadata) IsIntermediateTestVariant() bool { +- return m.ForTest != "" && m.ForTest != m.PkgPath && m.ForTest+"_test" != m.PkgPath -} - --// A token is {{...}}, and this marks words in the token that equal the give word --func markWordInToken(p *Parsed, wordAt string) ([]protocol.DocumentHighlight, error) { -- var ans []protocol.DocumentHighlight -- pat, err := regexp.Compile(fmt.Sprintf(`\b%s\b`, wordAt)) -- if err != nil { -- return nil, fmt.Errorf("%q: unmatchable word (%v)", wordAt, err) -- } -- for _, tok := range p.tokens { -- got := pat.FindAllIndex(p.buf[tok.Start:tok.End], -1) -- for i := 0; i < len(got); i++ { -- ans = append(ans, protocol.DocumentHighlight{ -- Range: p.Range(got[i][0], got[i][1]-got[i][0]), -- Kind: protocol.Text, -- }) +-// RemoveIntermediateTestVariants removes intermediate test variants, modifying the array. +-// We use a pointer to a slice make it impossible to forget to use the result. +-func RemoveIntermediateTestVariants(pmetas *[]*Metadata) { +- metas := *pmetas +- res := metas[:0] +- for _, m := range metas { +- if !m.IsIntermediateTestVariant() { +- res = append(res, m) - } - } -- return ans, nil +- *pmetas = res -} - --var wordRe = regexp.MustCompile(`[$]?\w+$`) --var moreRe = regexp.MustCompile(`^[$]?\w+`) +-var ErrViewExists = errors.New("view already exists for session") - --// findWordAt finds the word the cursor is in (meaning in or just before) --func findWordAt(p *Parsed, pos int) string { -- if pos >= len(p.buf) { -- return "" // can't happen, as we are called with pos < tok.End -- } -- after := moreRe.Find(p.buf[pos:]) -- if len(after) == 0 { -- return "" // end of the word +-// FileModification represents a modification to a file. +-type FileModification struct { +- URI span.URI +- Action FileAction +- +- // OnDisk is true if a watched file is changed on disk. +- // If true, Version will be -1 and Text will be nil. +- OnDisk bool +- +- // Version will be -1 and Text will be nil when they are not supplied, +- // specifically on textDocument/didClose and for on-disk changes. +- Version int32 +- Text []byte +- +- // LanguageID is only sent from the language client on textDocument/didOpen. +- LanguageID string +-} +- +-type FileAction int +- +-const ( +- UnknownFileAction = FileAction(iota) +- Open +- Change +- Close +- Save +- Create +- Delete +- InvalidateMetadata +-) +- +-func (a FileAction) String() string { +- switch a { +- case Open: +- return "Open" +- case Change: +- return "Change" +- case Close: +- return "Close" +- case Save: +- return "Save" +- case Create: +- return "Create" +- case Delete: +- return "Delete" +- case InvalidateMetadata: +- return "InvalidateMetadata" +- default: +- return "Unknown" - } -- got := wordRe.Find(p.buf[:pos+len(after)]) -- return string(got) -} -diff -urN a/gopls/internal/lsp/template/implementations.go b/gopls/internal/lsp/template/implementations.go ---- a/gopls/internal/lsp/template/implementations.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/implementations.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,189 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package template +-var ErrTmpModfileUnsupported = errors.New("-modfile is unsupported for this Go version") +-var ErrNoModOnDisk = errors.New("go.mod file is not on disk") - --import ( -- "context" -- "fmt" -- "regexp" -- "strconv" -- "time" +-func IsNonFatalGoModError(err error) bool { +- return err == ErrTmpModfileUnsupported || err == ErrNoModOnDisk +-} - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" +-// Common parse modes; these should be reused wherever possible to increase +-// cache hits. +-const ( +- // ParseHeader specifies that the main package declaration and imports are needed. +- // This is the mode used when attempting to examine the package graph structure. +- ParseHeader = parser.AllErrors | parser.ParseComments | parser.ImportsOnly | SkipObjectResolution +- +- // ParseFull specifies the full AST is needed. +- // This is used for files of direct interest where the entire contents must +- // be considered. +- ParseFull = parser.AllErrors | parser.ParseComments | SkipObjectResolution -) - --// line number (1-based) and message --var errRe = regexp.MustCompile(`template.*:(\d+): (.*)`) +-// A FileHandle represents the URI, content, hash, and optional +-// version of a file tracked by the LSP session. +-// +-// File content may be provided by the file system (for Saved files) +-// or from an overlay, for open files with unsaved edits. +-// A FileHandle may record an attempt to read a non-existent file, +-// in which case Content returns an error. +-type FileHandle interface { +- // URI is the URI for this file handle. +- // TODO(rfindley): this is not actually well-defined. In some cases, there +- // may be more than one URI that resolve to the same FileHandle. Which one is +- // this? +- URI() span.URI +- // FileIdentity returns a FileIdentity for the file, even if there was an +- // error reading it. +- FileIdentity() FileIdentity +- // Saved reports whether the file has the same content on disk: +- // it is false for files open on an editor with unsaved edits. +- Saved() bool +- // Version returns the file version, as defined by the LSP client. +- // For on-disk file handles, Version returns 0. +- Version() int32 +- // Content returns the contents of a file. +- // If the file is not available, returns a nil slice and an error. +- Content() ([]byte, error) +-} - --// Diagnose returns parse errors. There is only one. --// The errors are not always helpful. For instance { {end}} --// will likely point to the end of the file. --func Diagnose(f source.FileHandle) []*source.Diagnostic { -- // no need for skipTemplate check, as Diagnose is called on the -- // snapshot's template files -- buf, err := f.Read() -- if err != nil { -- // Is a Diagnostic with no Range useful? event.Error also? -- msg := fmt.Sprintf("failed to read %s (%v)", f.URI().Filename(), err) -- d := source.Diagnostic{Message: msg, Severity: protocol.SeverityError, URI: f.URI(), -- Source: source.TemplateError} -- return []*source.Diagnostic{&d} -- } -- p := parseBuffer(buf) -- if p.ParseErr == nil { -- return nil -- } -- unknownError := func(msg string) []*source.Diagnostic { -- s := fmt.Sprintf("malformed template error %q: %s", p.ParseErr.Error(), msg) -- d := source.Diagnostic{ -- Message: s, Severity: protocol.SeverityError, Range: p.Range(p.nls[0], 1), -- URI: f.URI(), Source: source.TemplateError} -- return []*source.Diagnostic{&d} -- } -- // errors look like `template: :40: unexpected "}" in operand` -- // so the string needs to be parsed -- matches := errRe.FindStringSubmatch(p.ParseErr.Error()) -- if len(matches) != 3 { -- msg := fmt.Sprintf("expected 3 matches, got %d (%v)", len(matches), matches) -- return unknownError(msg) -- } -- lineno, err := strconv.Atoi(matches[1]) -- if err != nil { -- msg := fmt.Sprintf("couldn't convert %q to int, %v", matches[1], err) -- return unknownError(msg) -- } -- msg := matches[2] -- d := source.Diagnostic{Message: msg, Severity: protocol.SeverityError, -- Source: source.TemplateError} -- start := p.nls[lineno-1] -- if lineno < len(p.nls) { -- size := p.nls[lineno] - start -- d.Range = p.Range(start, size) -- } else { -- d.Range = p.Range(start, 1) -- } -- return []*source.Diagnostic{&d} +-// A Hash is a cryptographic digest of the contents of a file. +-// (Although at 32B it is larger than a 16B string header, it is smaller +-// and has better locality than the string header + 64B of hex digits.) +-type Hash [sha256.Size]byte +- +-// HashOf returns the hash of some data. +-func HashOf(data []byte) Hash { +- return Hash(sha256.Sum256(data)) -} - --// Definition finds the definitions of the symbol at loc. It --// does not understand scoping (if any) in templates. This code is --// for definitions, type definitions, and implementations. --// Results only for variables and templates. --func Definition(snapshot source.Snapshot, fh source.FileHandle, loc protocol.Position) ([]protocol.Location, error) { -- x, _, err := symAtPosition(fh, loc) -- if err != nil { -- return nil, err -- } -- sym := x.name -- ans := []protocol.Location{} -- // PJW: this is probably a pattern to abstract -- a := New(snapshot.Templates()) -- for k, p := range a.files { -- for _, s := range p.symbols { -- if !s.vardef || s.name != sym { -- continue -- } -- ans = append(ans, protocol.Location{URI: protocol.DocumentURI(k), Range: p.Range(s.start, s.length)}) -- } -- } -- return ans, nil +-// Hashf returns the hash of a printf-formatted string. +-func Hashf(format string, args ...interface{}) Hash { +- // Although this looks alloc-heavy, it is faster than using +- // Fprintf on sha256.New() because the allocations don't escape. +- return HashOf([]byte(fmt.Sprintf(format, args...))) -} - --func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) { -- sym, p, err := symAtPosition(fh, position) -- if sym == nil || err != nil { -- return nil, err -- } -- ans := protocol.Hover{Range: p.Range(sym.start, sym.length), Contents: protocol.MarkupContent{Kind: protocol.Markdown}} -- switch sym.kind { -- case protocol.Function: -- ans.Contents.Value = fmt.Sprintf("function: %s", sym.name) -- case protocol.Variable: -- ans.Contents.Value = fmt.Sprintf("variable: %s", sym.name) -- case protocol.Constant: -- ans.Contents.Value = fmt.Sprintf("constant %s", sym.name) -- case protocol.Method: // field or method -- ans.Contents.Value = fmt.Sprintf("%s: field or method", sym.name) -- case protocol.Package: // template use, template def (PJW: do we want two?) -- ans.Contents.Value = fmt.Sprintf("template %s\n(add definition)", sym.name) -- case protocol.Namespace: -- ans.Contents.Value = fmt.Sprintf("template %s defined", sym.name) -- case protocol.Number: -- ans.Contents.Value = "number" -- case protocol.String: -- ans.Contents.Value = "string" -- case protocol.Boolean: -- ans.Contents.Value = "boolean" -- default: -- ans.Contents.Value = fmt.Sprintf("oops, sym=%#v", sym) -- } -- return &ans, nil +-// String returns the digest as a string of hex digits. +-func (h Hash) String() string { +- return fmt.Sprintf("%64x", [sha256.Size]byte(h)) -} - --func References(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, params *protocol.ReferenceParams) ([]protocol.Location, error) { -- sym, _, err := symAtPosition(fh, params.Position) -- if sym == nil || err != nil || sym.name == "" { -- return nil, err -- } -- ans := []protocol.Location{} +-// Less returns true if the given hash is less than the other. +-func (h Hash) Less(other Hash) bool { +- return bytes.Compare(h[:], other[:]) < 0 +-} - -- a := New(snapshot.Templates()) -- for k, p := range a.files { -- for _, s := range p.symbols { -- if s.name != sym.name { -- continue -- } -- if s.vardef && !params.Context.IncludeDeclaration { -- continue -- } -- ans = append(ans, protocol.Location{URI: protocol.DocumentURI(k), Range: p.Range(s.start, s.length)}) -- } +-// XORWith updates *h to *h XOR h2. +-func (h *Hash) XORWith(h2 Hash) { +- // Small enough that we don't need crypto/subtle.XORBytes. +- for i := range h { +- h[i] ^= h2[i] - } -- // do these need to be sorted? (a.files is a map) -- return ans, nil -} - --func SemanticTokens(ctx context.Context, snapshot source.Snapshot, spn span.URI, add func(line, start, len uint32), d func() []uint32) (*protocol.SemanticTokens, error) { -- fh, err := snapshot.GetFile(ctx, spn) -- if err != nil { -- return nil, err -- } -- buf, err := fh.Read() -- if err != nil { -- return nil, err -- } -- p := parseBuffer(buf) +-// FileIdentity uniquely identifies a file at a version from a FileSystem. +-type FileIdentity struct { +- URI span.URI +- Hash Hash // digest of file contents +-} - -- for _, t := range p.Tokens() { -- if t.Multiline { -- la, ca := p.LineCol(t.Start) -- lb, cb := p.LineCol(t.End) -- add(la, ca, p.RuneCount(la, ca, 0)) -- for l := la + 1; l < lb; l++ { -- add(l, 0, p.RuneCount(l, 0, 0)) -- } -- add(lb, 0, p.RuneCount(lb, 0, cb)) -- continue -- } -- sz, err := p.TokenSize(t) -- if err != nil { -- return nil, err -- } -- line, col := p.LineCol(t.Start) -- add(line, col, uint32(sz)) -- } -- data := d() -- ans := &protocol.SemanticTokens{ -- Data: data, -- // for small cache, some day. for now, the LSP client ignores this -- // (that is, when the LSP client starts returning these, we can cache) -- ResultID: fmt.Sprintf("%v", time.Now()), -- } -- return ans, nil +-func (id FileIdentity) String() string { +- return fmt.Sprintf("%s%s", id.URI, id.Hash) -} - --// still need to do rename, etc -diff -urN a/gopls/internal/lsp/template/parse.go b/gopls/internal/lsp/template/parse.go ---- a/gopls/internal/lsp/template/parse.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/parse.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,508 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-// FileKind describes the kind of the file in question. +-// It can be one of Go,mod, Sum, or Tmpl. +-type FileKind int - --// Package template contains code for dealing with templates --package template +-const ( +- // UnknownKind is a file type we don't know about. +- UnknownKind = FileKind(iota) - --// template files are small enough that the code reprocesses them each time --// this may be a bad choice for projects with lots of template files. +- // Go is a normal go source file. +- Go +- // Mod is a go.mod file. +- Mod +- // Sum is a go.sum file. +- Sum +- // Tmpl is a template file. +- Tmpl +- // Work is a go.work file. +- Work +-) - --// This file contains the parsing code, some debugging printing, and --// implementations for Diagnose, Definition, Hover, References +-func (k FileKind) String() string { +- switch k { +- case Go: +- return "go" +- case Mod: +- return "go.mod" +- case Sum: +- return "go.sum" +- case Tmpl: +- return "tmpl" +- case Work: +- return "go.work" +- default: +- return fmt.Sprintf("internal error: unknown file kind %d", k) +- } +-} - --import ( -- "bytes" -- "context" -- "fmt" -- "io" -- "log" -- "regexp" -- "runtime" -- "sort" -- "text/template" -- "text/template/parse" -- "unicode/utf8" +-// Analyzer represents a go/analysis analyzer with some boolean properties +-// that let the user know how to use the analyzer. +-type Analyzer struct { +- Analyzer *analysis.Analyzer - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event" --) +- // Enabled reports whether the analyzer is enabled. This value can be +- // configured per-analysis in user settings. For staticcheck analyzers, +- // the value of the Staticcheck setting overrides this field. +- // +- // Most clients should use the IsEnabled method. +- Enabled bool - --var ( -- Left = []byte("{{") -- Right = []byte("}}") --) +- // Fix is the name of the suggested fix name used to invoke the suggested +- // fixes for the analyzer. It is non-empty if we expect this analyzer to +- // provide its fix separately from its diagnostics. That is, we should apply +- // the analyzer's suggested fixes through a Command, not a TextEdit. +- Fix string - --type Parsed struct { -- buf []byte //contents -- lines [][]byte // needed?, other than for debugging? -- elided []int // offsets where Left was replaced by blanks +- // fixesDiagnostic reports if a diagnostic from the analyzer can be fixed by Fix. +- // If nil then all diagnostics from the analyzer are assumed to be fixable. +- fixesDiagnostic func(*Diagnostic) bool - -- // tokens are matched Left-Right pairs, computed before trying to parse -- tokens []Token +- // ActionKind is the kind of code action this analyzer produces. If +- // unspecified the type defaults to quickfix. +- ActionKind []protocol.CodeActionKind - -- // result of parsing -- named []*template.Template // the template and embedded templates -- ParseErr error -- symbols []symbol -- stack []parse.Node // used while computing symbols +- // Severity is the severity set for diagnostics reported by this +- // analyzer. If left unset it defaults to Warning. +- Severity protocol.DiagnosticSeverity - -- // for mapping from offsets in buf to LSP coordinates -- // See FromPosition() and LineCol() -- nls []int // offset of newlines before each line (nls[0]==-1) -- lastnl int // last line seen -- check int // used to decide whether to use lastnl or search through nls -- nonASCII bool // are there any non-ascii runes in buf? +- // Tag is extra tags (unnecessary, deprecated, etc) for diagnostics +- // reported by this analyzer. +- Tag []protocol.DiagnosticTag -} - --// Token is a single {{...}}. More precisely, Left...Right --type Token struct { -- Start, End int // offset from start of template -- Multiline bool --} +-func (a *Analyzer) String() string { return a.Analyzer.String() } - --// All contains the Parse of all the template files --type All struct { -- files map[span.URI]*Parsed --} -- --// New returns the Parses of the snapshot's tmpl files --// (maybe cache these, but then avoiding import cycles needs code rearrangements) --func New(tmpls map[span.URI]source.FileHandle) *All { -- all := make(map[span.URI]*Parsed) -- for k, v := range tmpls { -- buf, err := v.Read() -- if err != nil { // PJW: decide what to do with these errors -- log.Printf("failed to read %s (%v)", v.URI().Filename(), err) -- continue +-// IsEnabled reports whether this analyzer is enabled by the given options. +-func (a Analyzer) IsEnabled(options *Options) bool { +- // Staticcheck analyzers can only be enabled when staticcheck is on. +- if _, ok := options.StaticcheckAnalyzers[a.Analyzer.Name]; ok { +- if !options.Staticcheck { +- return false - } -- all[k] = parseBuffer(buf) - } -- return &All{files: all} +- if enabled, ok := options.Analyses[a.Analyzer.Name]; ok { +- return enabled +- } +- return a.Enabled -} - --func parseBuffer(buf []byte) *Parsed { -- ans := &Parsed{ -- buf: buf, -- check: -1, -- nls: []int{-1}, -- } -- if len(buf) == 0 { -- return ans -- } -- // how to compute allAscii... -- for _, b := range buf { -- if b >= utf8.RuneSelf { -- ans.nonASCII = true -- break -- } -- } -- if buf[len(buf)-1] != '\n' { -- ans.buf = append(buf, '\n') -- } -- for i, p := range ans.buf { -- if p == '\n' { -- ans.nls = append(ans.nls, i) -- } -- } -- ans.setTokens() // ans.buf may be a new []byte -- ans.lines = bytes.Split(ans.buf, []byte{'\n'}) -- t, err := template.New("").Parse(string(ans.buf)) -- if err != nil { -- funcs := make(template.FuncMap) -- for t == nil && ans.ParseErr == nil { -- // in 1.17 it may be possible to avoid getting this error -- // template: :2: function "foo" not defined -- matches := parseErrR.FindStringSubmatch(err.Error()) -- if len(matches) == 2 { -- // suppress the error by giving it a function with the right name -- funcs[matches[1]] = func() interface{} { return nil } -- t, err = template.New("").Funcs(funcs).Parse(string(ans.buf)) -- continue -- } -- ans.ParseErr = err // unfixed error -- return ans -- } -- } -- ans.named = t.Templates() -- // set the symbols -- for _, t := range ans.named { -- ans.stack = append(ans.stack, t.Root) -- ans.findSymbols() -- if t.Name() != "" { -- // defining a template. The pos is just after {{define...}} (or {{block...}}?) -- at, sz := ans.FindLiteralBefore(int(t.Root.Pos)) -- s := symbol{start: at, length: sz, name: t.Name(), kind: protocol.Namespace, vardef: true} -- ans.symbols = append(ans.symbols, s) -- } +-// FixesDiagnostic returns true if Analyzer.Fix can fix the Diagnostic. +-func (a Analyzer) FixesDiagnostic(d *Diagnostic) bool { +- if a.fixesDiagnostic == nil { +- return true - } +- return a.fixesDiagnostic(d) +-} - -- sort.Slice(ans.symbols, func(i, j int) bool { -- left, right := ans.symbols[i], ans.symbols[j] -- if left.start != right.start { -- return left.start < right.start -- } -- if left.vardef != right.vardef { -- return left.vardef -- } -- return left.kind < right.kind -- }) -- return ans +-// Declare explicit types for package paths, names, and IDs to ensure that we +-// never use an ID where a path belongs, and vice versa. If we confused these, +-// it would result in confusing errors because package IDs often look like +-// package paths. +-type ( +- PackageID string // go list's unique identifier for a package (e.g. "vendor/example.com/foo [vendor/example.com/bar.test]") +- PackagePath string // name used to prefix linker symbols (e.g. "vendor/example.com/foo") +- PackageName string // identifier in 'package' declaration (e.g. "foo") +- ImportPath string // path that appears in an import declaration (e.g. "example.com/foo") +-) +- +-// Package represents a Go package that has been parsed and type-checked. +-// +-// By design, there is no way to reach from a Package to the Package +-// representing one of its dependencies. +-// +-// Callers must not assume that two Packages share the same +-// token.FileSet or types.Importer and thus have commensurable +-// token.Pos values or types.Objects. Instead, use stable naming +-// schemes, such as (URI, byte offset) for positions, or (PackagePath, +-// objectpath.Path) for exported declarations. +-type Package interface { +- Metadata() *Metadata +- +- // Results of parsing: +- FileSet() *token.FileSet +- CompiledGoFiles() []*ParsedGoFile // (borrowed) +- File(uri span.URI) (*ParsedGoFile, error) +- GetSyntax() []*ast.File // (borrowed) +- GetParseErrors() []scanner.ErrorList +- +- // Results of type checking: +- GetTypes() *types.Package +- GetTypeErrors() []types.Error +- GetTypesInfo() *types.Info +- DependencyTypes(PackagePath) *types.Package // nil for indirect dependency of no consequence +- DiagnosticsForFile(ctx context.Context, s Snapshot, uri span.URI) ([]*Diagnostic, error) -} - --// FindLiteralBefore locates the first preceding string literal --// returning its position and length in buf --// or returns -1 if there is none. --// Assume double-quoted string rather than backquoted string for now. --func (p *Parsed) FindLiteralBefore(pos int) (int, int) { -- left, right := -1, -1 -- for i := pos - 1; i >= 0; i-- { -- if p.buf[i] != '"' { -- continue -- } -- if right == -1 { -- right = i -- continue -- } -- left = i -- break -- } -- if left == -1 { -- return -1, 0 -- } -- return left + 1, right - left - 1 +-type unit = struct{} +- +-// A CriticalError is a workspace-wide error that generally prevents gopls from +-// functioning correctly. In the presence of critical errors, other diagnostics +-// in the workspace may not make sense. +-type CriticalError struct { +- // MainError is the primary error. Must be non-nil. +- MainError error +- +- // Diagnostics contains any supplemental (structured) diagnostics. +- Diagnostics []*Diagnostic -} - --var ( -- parseErrR = regexp.MustCompile(`template:.*function "([^"]+)" not defined`) --) +-// An Diagnostic corresponds to an LSP Diagnostic. +-// https://microsoft.github.io/language-server-protocol/specification#diagnostic +-type Diagnostic struct { +- // TODO(adonovan): should be a protocol.URI, for symmetry. +- URI span.URI // of diagnosed file (not diagnostic documentation) +- Range protocol.Range +- Severity protocol.DiagnosticSeverity +- Code string +- CodeHref string - --func (p *Parsed) setTokens() { -- const ( -- // InRaw and InString only occur inside an action (SeenLeft) -- Start = iota -- InRaw -- InString -- SeenLeft -- ) -- state := Start -- var left, oldState int -- for n := 0; n < len(p.buf); n++ { -- c := p.buf[n] -- switch state { -- case InRaw: -- if c == '`' { -- state = oldState -- } -- case InString: -- if c == '"' && !isEscaped(p.buf[:n]) { -- state = oldState -- } -- case SeenLeft: -- if c == '`' { -- oldState = state // it's SeenLeft, but a little clearer this way -- state = InRaw -- continue -- } -- if c == '"' { -- oldState = state -- state = InString -- continue -- } -- if bytes.HasPrefix(p.buf[n:], Right) { -- right := n + len(Right) -- tok := Token{Start: left, -- End: right, -- Multiline: bytes.Contains(p.buf[left:right], []byte{'\n'}), -- } -- p.tokens = append(p.tokens, tok) -- state = Start -- } -- // If we see (unquoted) Left then the original left is probably the user -- // typing. Suppress the original left -- if bytes.HasPrefix(p.buf[n:], Left) { -- p.elideAt(left) -- left = n -- n += len(Left) - 1 // skip the rest -- } -- case Start: -- if bytes.HasPrefix(p.buf[n:], Left) { -- left = n -- state = SeenLeft -- n += len(Left) - 1 // skip the rest (avoids {{{ bug) -- } -- } -- } -- // this error occurs after typing {{ at the end of the file -- if state != Start { -- // Unclosed Left. remove the Left at left -- p.elideAt(left) -- } +- // Source is a human-readable description of the source of the error. +- // Diagnostics generated by an analysis.Analyzer set it to Analyzer.Name. +- Source DiagnosticSource +- +- Message string +- +- Tags []protocol.DiagnosticTag +- Related []protocol.DiagnosticRelatedInformation +- +- // Fields below are used internally to generate quick fixes. They aren't +- // part of the LSP spec and historically didn't leave the server. +- // +- // Update(2023-05): version 3.16 of the LSP spec included support for the +- // Diagnostic.data field, which holds arbitrary data preserved in the +- // diagnostic for codeAction requests. This field allows bundling additional +- // information for quick-fixes, and gopls can (and should) use this +- // information to avoid re-evaluating diagnostics in code-action handlers. +- // +- // In order to stage this transition incrementally, the 'BundledFixes' field +- // may store a 'bundled' (=json-serialized) form of the associated +- // SuggestedFixes. Not all diagnostics have their fixes bundled. +- BundledFixes *json.RawMessage +- SuggestedFixes []SuggestedFix -} - --func (p *Parsed) elideAt(left int) { -- if p.elided == nil { -- // p.buf is the same buffer that v.Read() returns, so copy it. -- // (otherwise the next time it's parsed, elided information is lost) -- b := make([]byte, len(p.buf)) -- copy(b, p.buf) -- p.buf = b -- } -- for i := 0; i < len(Left); i++ { -- p.buf[left+i] = ' ' -- } -- p.elided = append(p.elided, left) +-func (d *Diagnostic) String() string { +- return fmt.Sprintf("%v: %s", d.Range, d.Message) -} - --// isEscaped reports whether the byte after buf is escaped --func isEscaped(buf []byte) bool { -- backSlashes := 0 -- for j := len(buf) - 1; j >= 0 && buf[j] == '\\'; j-- { -- backSlashes++ -- } -- return backSlashes%2 == 1 +-type DiagnosticSource string +- +-const ( +- UnknownError DiagnosticSource = "" +- ListError DiagnosticSource = "go list" +- ParseError DiagnosticSource = "syntax" +- TypeError DiagnosticSource = "compiler" +- ModTidyError DiagnosticSource = "go mod tidy" +- OptimizationDetailsError DiagnosticSource = "optimizer details" +- UpgradeNotification DiagnosticSource = "upgrade available" +- Vulncheck DiagnosticSource = "vulncheck imports" +- Govulncheck DiagnosticSource = "govulncheck" +- TemplateError DiagnosticSource = "template" +- WorkFileError DiagnosticSource = "go.work file" +- ConsistencyInfo DiagnosticSource = "consistency" +-) +- +-func AnalyzerErrorKind(name string) DiagnosticSource { +- return DiagnosticSource(name) -} +diff -urN a/gopls/internal/lsp/source/workspace_symbol.go b/gopls/internal/lsp/source/workspace_symbol.go +--- a/gopls/internal/lsp/source/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,611 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func (p *Parsed) Tokens() []Token { -- return p.tokens +-package source +- +-import ( +- "context" +- "fmt" +- "path" +- "path/filepath" +- "regexp" +- "runtime" +- "sort" +- "strings" +- "unicode" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/fuzzy" +-) +- +-// Symbol holds a precomputed symbol value. Note: we avoid using the +-// protocol.SymbolInformation struct here in order to reduce the size of each +-// symbol. +-type Symbol struct { +- Name string +- Kind protocol.SymbolKind +- Range protocol.Range -} - --// TODO(adonovan): the next 100 lines could perhaps replaced by use of protocol.Mapper. +-// maxSymbols defines the maximum number of symbol results that should ever be +-// sent in response to a client. +-const maxSymbols = 100 - --func (p *Parsed) utf16len(buf []byte) int { -- cnt := 0 -- if !p.nonASCII { -- return len(buf) -- } -- // we need a utf16len(rune), but we don't have it -- for _, r := range string(buf) { -- cnt++ -- if r >= 1<<16 { -- cnt++ -- } +-// WorkspaceSymbols matches symbols across all views using the given query, +-// according to the match semantics parameterized by matcherType and style. +-// +-// The workspace symbol method is defined in the spec as follows: +-// +-// The workspace symbol request is sent from the client to the server to +-// list project-wide symbols matching the query string. +-// +-// It is unclear what "project-wide" means here, but given the parameters of +-// workspace/symbol do not include any workspace identifier, then it has to be +-// assumed that "project-wide" means "across all workspaces". Hence why +-// WorkspaceSymbols receives the views []View. +-// +-// However, it then becomes unclear what it would mean to call WorkspaceSymbols +-// with a different configured SymbolMatcher per View. Therefore we assume that +-// Session level configuration will define the SymbolMatcher to be used for the +-// WorkspaceSymbols method. +-func WorkspaceSymbols(ctx context.Context, matcher SymbolMatcher, style SymbolStyle, views []View, query string) ([]protocol.SymbolInformation, error) { +- ctx, done := event.Start(ctx, "source.WorkspaceSymbols") +- defer done() +- if query == "" { +- return nil, nil - } -- return cnt --} - --func (p *Parsed) TokenSize(t Token) (int, error) { -- if t.Multiline { -- return -1, fmt.Errorf("TokenSize called with Multiline token %#v", t) +- var s symbolizer +- switch style { +- case DynamicSymbols: +- s = dynamicSymbolMatch +- case FullyQualifiedSymbols: +- s = fullyQualifiedSymbolMatch +- case PackageQualifiedSymbols: +- s = packageSymbolMatch +- default: +- panic(fmt.Errorf("unknown symbol style: %v", style)) - } -- ans := p.utf16len(p.buf[t.Start:t.End]) -- return ans, nil +- +- return collectSymbols(ctx, views, matcher, s, query) -} - --// RuneCount counts runes in line l, from col s to e --// (e==0 for end of line. called only for multiline tokens) --func (p *Parsed) RuneCount(l, s, e uint32) uint32 { -- start := p.nls[l] + 1 + int(s) -- end := p.nls[l] + 1 + int(e) -- if e == 0 || end > p.nls[l+1] { -- end = p.nls[l+1] +-// A matcherFunc returns the index and score of a symbol match. +-// +-// See the comment for symbolCollector for more information. +-type matcherFunc func(chunks []string) (int, float64) +- +-// A symbolizer returns the best symbol match for a name with pkg, according to +-// some heuristic. The symbol name is passed as the slice nameParts of logical +-// name pieces. For example, for myType.field the caller can pass either +-// []string{"myType.field"} or []string{"myType.", "field"}. +-// +-// See the comment for symbolCollector for more information. +-// +-// The space argument is an empty slice with spare capacity that may be used +-// to allocate the result. +-type symbolizer func(space []string, name string, pkg *Metadata, m matcherFunc) ([]string, float64) +- +-func fullyQualifiedSymbolMatch(space []string, name string, pkg *Metadata, matcher matcherFunc) ([]string, float64) { +- if _, score := dynamicSymbolMatch(space, name, pkg, matcher); score > 0 { +- return append(space, string(pkg.PkgPath), ".", name), score - } -- return uint32(utf8.RuneCount(p.buf[start:end])) +- return nil, 0 -} - --// LineCol converts from a 0-based byte offset to 0-based line, col. col in runes --func (p *Parsed) LineCol(x int) (uint32, uint32) { -- if x < p.check { -- p.lastnl = 0 +-func dynamicSymbolMatch(space []string, name string, pkg *Metadata, matcher matcherFunc) ([]string, float64) { +- if IsCommandLineArguments(pkg.ID) { +- // command-line-arguments packages have a non-sensical package path, so +- // just use their package name. +- return packageSymbolMatch(space, name, pkg, matcher) - } -- p.check = x -- for i := p.lastnl; i < len(p.nls); i++ { -- if p.nls[i] <= x { -- continue -- } -- p.lastnl = i -- var count int -- if i > 0 && x == p.nls[i-1] { // \n -- count = 0 -- } else { -- count = p.utf16len(p.buf[p.nls[i-1]+1 : x]) +- +- var score float64 +- +- endsInPkgName := strings.HasSuffix(string(pkg.PkgPath), string(pkg.Name)) +- +- // If the package path does not end in the package name, we need to check the +- // package-qualified symbol as an extra pass first. +- if !endsInPkgName { +- pkgQualified := append(space, string(pkg.Name), ".", name) +- idx, score := matcher(pkgQualified) +- nameStart := len(pkg.Name) + 1 +- if score > 0 { +- // If our match is contained entirely within the unqualified portion, +- // just return that. +- if idx >= nameStart { +- return append(space, name), score +- } +- // Lower the score for matches that include the package name. +- return pkgQualified, score * 0.8 - } -- return uint32(i - 1), uint32(count) - } -- if x == len(p.buf)-1 { // trailing \n -- return uint32(len(p.nls) - 1), 0 +- +- // Now try matching the fully qualified symbol. +- fullyQualified := append(space, string(pkg.PkgPath), ".", name) +- idx, score := matcher(fullyQualified) +- +- // As above, check if we matched just the unqualified symbol name. +- nameStart := len(pkg.PkgPath) + 1 +- if idx >= nameStart { +- return append(space, name), score - } -- // shouldn't happen -- for i := 1; i < 4; i++ { -- _, f, l, ok := runtime.Caller(i) -- if !ok { -- break +- +- // If our package path ends in the package name, we'll have skipped the +- // initial pass above, so check if we matched just the package-qualified +- // name. +- if endsInPkgName && idx >= 0 { +- pkgStart := len(pkg.PkgPath) - len(pkg.Name) +- if idx >= pkgStart { +- return append(space, string(pkg.Name), ".", name), score - } -- log.Printf("%d: %s:%d", i, f, l) - } - -- msg := fmt.Errorf("LineCol off the end, %d of %d, nls=%v, %q", x, len(p.buf), p.nls, p.buf[x:]) -- event.Error(context.Background(), "internal error", msg) -- return 0, 0 +- // Our match was not contained within the unqualified or package qualified +- // symbol. Return the fully qualified symbol but discount the score. +- return fullyQualified, score * 0.6 -} - --// Position produces a protocol.Position from an offset in the template --func (p *Parsed) Position(pos int) protocol.Position { -- line, col := p.LineCol(pos) -- return protocol.Position{Line: line, Character: col} +-func packageSymbolMatch(space []string, name string, pkg *Metadata, matcher matcherFunc) ([]string, float64) { +- qualified := append(space, string(pkg.Name), ".", name) +- if _, s := matcher(qualified); s > 0 { +- return qualified, s +- } +- return nil, 0 -} - --func (p *Parsed) Range(x, length int) protocol.Range { -- line, col := p.LineCol(x) -- ans := protocol.Range{ -- Start: protocol.Position{Line: line, Character: col}, -- End: protocol.Position{Line: line, Character: col + uint32(length)}, +-func buildMatcher(matcher SymbolMatcher, query string) matcherFunc { +- switch matcher { +- case SymbolFuzzy: +- return parseQuery(query, newFuzzyMatcher) +- case SymbolFastFuzzy: +- return parseQuery(query, func(query string) matcherFunc { +- return fuzzy.NewSymbolMatcher(query).Match +- }) +- case SymbolCaseSensitive: +- return matchExact(query) +- case SymbolCaseInsensitive: +- q := strings.ToLower(query) +- exact := matchExact(q) +- wrapper := []string{""} +- return func(chunks []string) (int, float64) { +- s := strings.Join(chunks, "") +- wrapper[0] = strings.ToLower(s) +- return exact(wrapper) +- } - } -- return ans +- panic(fmt.Errorf("unknown symbol matcher: %v", matcher)) -} - --// FromPosition translates a protocol.Position into an offset into the template --func (p *Parsed) FromPosition(x protocol.Position) int { -- l, c := int(x.Line), int(x.Character) -- if l >= len(p.nls) || p.nls[l]+1 >= len(p.buf) { -- // paranoia to avoid panic. return the largest offset -- return len(p.buf) -- } -- line := p.buf[p.nls[l]+1:] -- cnt := 0 -- for w := range string(line) { -- if cnt >= c { -- return w + p.nls[l] + 1 +-func newFuzzyMatcher(query string) matcherFunc { +- fm := fuzzy.NewMatcher(query) +- return func(chunks []string) (int, float64) { +- score := float64(fm.ScoreChunks(chunks)) +- ranges := fm.MatchedRanges() +- if len(ranges) > 0 { +- return ranges[0], score - } -- cnt++ +- return -1, score - } -- // do we get here? NO -- pos := int(x.Character) + p.nls[int(x.Line)] + 1 -- event.Error(context.Background(), "internal error", fmt.Errorf("surprise %#v", x)) -- return pos -} - --func symAtPosition(fh source.FileHandle, loc protocol.Position) (*symbol, *Parsed, error) { -- buf, err := fh.Read() -- if err != nil { -- return nil, nil, err +-// parseQuery parses a field-separated symbol query, extracting the special +-// characters listed below, and returns a matcherFunc corresponding to the AND +-// of all field queries. +-// +-// Special characters: +-// +-// ^ match exact prefix +-// $ match exact suffix +-// ' match exact +-// +-// In all three of these special queries, matches are 'smart-cased', meaning +-// they are case sensitive if the symbol query contains any upper-case +-// characters, and case insensitive otherwise. +-func parseQuery(q string, newMatcher func(string) matcherFunc) matcherFunc { +- fields := strings.Fields(q) +- if len(fields) == 0 { +- return func([]string) (int, float64) { return -1, 0 } - } -- p := parseBuffer(buf) -- pos := p.FromPosition(loc) -- syms := p.SymsAtPos(pos) -- if len(syms) == 0 { -- return nil, p, fmt.Errorf("no symbol found") +- var funcs []matcherFunc +- for _, field := range fields { +- var f matcherFunc +- switch { +- case strings.HasPrefix(field, "^"): +- prefix := field[1:] +- f = smartCase(prefix, func(chunks []string) (int, float64) { +- s := strings.Join(chunks, "") +- if strings.HasPrefix(s, prefix) { +- return 0, 1 +- } +- return -1, 0 +- }) +- case strings.HasPrefix(field, "'"): +- exact := field[1:] +- f = smartCase(exact, matchExact(exact)) +- case strings.HasSuffix(field, "$"): +- suffix := field[0 : len(field)-1] +- f = smartCase(suffix, func(chunks []string) (int, float64) { +- s := strings.Join(chunks, "") +- if strings.HasSuffix(s, suffix) { +- return len(s) - len(suffix), 1 +- } +- return -1, 0 +- }) +- default: +- f = newMatcher(field) +- } +- funcs = append(funcs, f) - } -- if len(syms) > 1 { -- log.Printf("Hover: %d syms, not 1 %v", len(syms), syms) +- if len(funcs) == 1 { +- return funcs[0] - } -- sym := syms[0] -- return &sym, p, nil +- return comboMatcher(funcs).match -} - --func (p *Parsed) SymsAtPos(pos int) []symbol { -- ans := []symbol{} -- for _, s := range p.symbols { -- if s.start <= pos && pos < s.start+s.length { -- ans = append(ans, s) +-func matchExact(exact string) matcherFunc { +- return func(chunks []string) (int, float64) { +- s := strings.Join(chunks, "") +- if idx := strings.LastIndex(s, exact); idx >= 0 { +- return idx, 1 - } +- return -1, 0 - } -- return ans -} - --type wrNode struct { -- p *Parsed -- w io.Writer +-// smartCase returns a matcherFunc that is case-sensitive if q contains any +-// upper-case characters, and case-insensitive otherwise. +-func smartCase(q string, m matcherFunc) matcherFunc { +- insensitive := strings.ToLower(q) == q +- wrapper := []string{""} +- return func(chunks []string) (int, float64) { +- s := strings.Join(chunks, "") +- if insensitive { +- s = strings.ToLower(s) +- } +- wrapper[0] = s +- return m(wrapper) +- } -} - --// WriteNode is for debugging --func (p *Parsed) WriteNode(w io.Writer, n parse.Node) { -- wr := wrNode{p: p, w: w} -- wr.writeNode(n, "") --} +-type comboMatcher []matcherFunc - --func (wr wrNode) writeNode(n parse.Node, indent string) { -- if n == nil { -- return -- } -- at := func(pos parse.Pos) string { -- line, col := wr.p.LineCol(int(pos)) -- return fmt.Sprintf("(%d)%v:%v", pos, line, col) -- } -- switch x := n.(type) { -- case *parse.ActionNode: -- fmt.Fprintf(wr.w, "%sActionNode at %s\n", indent, at(x.Pos)) -- wr.writeNode(x.Pipe, indent+". ") -- case *parse.BoolNode: -- fmt.Fprintf(wr.w, "%sBoolNode at %s, %v\n", indent, at(x.Pos), x.True) -- case *parse.BranchNode: -- fmt.Fprintf(wr.w, "%sBranchNode at %s\n", indent, at(x.Pos)) -- wr.writeNode(x.Pipe, indent+"Pipe. ") -- wr.writeNode(x.List, indent+"List. ") -- wr.writeNode(x.ElseList, indent+"Else. ") -- case *parse.ChainNode: -- fmt.Fprintf(wr.w, "%sChainNode at %s, %v\n", indent, at(x.Pos), x.Field) -- case *parse.CommandNode: -- fmt.Fprintf(wr.w, "%sCommandNode at %s, %d children\n", indent, at(x.Pos), len(x.Args)) -- for _, a := range x.Args { -- wr.writeNode(a, indent+". ") -- } -- //case *parse.CommentNode: // 1.16 -- case *parse.DotNode: -- fmt.Fprintf(wr.w, "%sDotNode at %s\n", indent, at(x.Pos)) -- case *parse.FieldNode: -- fmt.Fprintf(wr.w, "%sFieldNode at %s, %v\n", indent, at(x.Pos), x.Ident) -- case *parse.IdentifierNode: -- fmt.Fprintf(wr.w, "%sIdentifierNode at %s, %v\n", indent, at(x.Pos), x.Ident) -- case *parse.IfNode: -- fmt.Fprintf(wr.w, "%sIfNode at %s\n", indent, at(x.Pos)) -- wr.writeNode(&x.BranchNode, indent+". ") -- case *parse.ListNode: -- if x == nil { -- return // nil BranchNode.ElseList +-func (c comboMatcher) match(chunks []string) (int, float64) { +- score := 1.0 +- first := 0 +- for _, f := range c { +- idx, s := f(chunks) +- if idx < first { +- first = idx - } -- fmt.Fprintf(wr.w, "%sListNode at %s, %d children\n", indent, at(x.Pos), len(x.Nodes)) -- for _, n := range x.Nodes { -- wr.writeNode(n, indent+". ") +- score *= s +- } +- return first, score +-} +- +-// collectSymbols calls snapshot.Symbols to walk the syntax trees of +-// all files in the views' current snapshots, and returns a sorted, +-// scored list of symbols that best match the parameters. +-// +-// How it matches symbols is parameterized by two interfaces: +-// - A matcherFunc determines how well a string symbol matches a query. It +-// returns a non-negative score indicating the quality of the match. A score +-// of zero indicates no match. +-// - A symbolizer determines how we extract the symbol for an object. This +-// enables the 'symbolStyle' configuration option. +-func collectSymbols(ctx context.Context, views []View, matcherType SymbolMatcher, symbolizer symbolizer, query string) ([]protocol.SymbolInformation, error) { +- // Extract symbols from all files. +- var work []symbolFile +- var roots []string +- seen := make(map[span.URI]bool) +- // TODO(adonovan): opt: parallelize this loop? How often is len > 1? +- for _, v := range views { +- snapshot, release, err := v.Snapshot() +- if err != nil { +- continue // view is shut down; continue with others - } -- case *parse.NilNode: -- fmt.Fprintf(wr.w, "%sNilNode at %s\n", indent, at(x.Pos)) -- case *parse.NumberNode: -- fmt.Fprintf(wr.w, "%sNumberNode at %s, %s\n", indent, at(x.Pos), x.Text) -- case *parse.PipeNode: -- if x == nil { -- return // {{template "xxx"}} +- defer release() +- +- // Use the root view URIs for determining (lexically) +- // whether a URI is in any open workspace. +- roots = append(roots, strings.TrimRight(string(v.Folder()), "/")) +- +- filters := snapshot.Options().DirectoryFilters +- filterer := NewFilterer(filters) +- folder := filepath.ToSlash(v.Folder().Filename()) +- +- workspaceOnly := true +- if snapshot.Options().SymbolScope == AllSymbolScope { +- workspaceOnly = false - } -- fmt.Fprintf(wr.w, "%sPipeNode at %s, %d vars, %d cmds, IsAssign:%v\n", -- indent, at(x.Pos), len(x.Decl), len(x.Cmds), x.IsAssign) -- for _, d := range x.Decl { -- wr.writeNode(d, indent+"Decl. ") +- symbols, err := snapshot.Symbols(ctx, workspaceOnly) +- if err != nil { +- return nil, err - } -- for _, c := range x.Cmds { -- wr.writeNode(c, indent+"Cmd. ") +- +- for uri, syms := range symbols { +- norm := filepath.ToSlash(uri.Filename()) +- nm := strings.TrimPrefix(norm, folder) +- if filterer.Disallow(nm) { +- continue +- } +- // Only scan each file once. +- if seen[uri] { +- continue +- } +- meta, err := NarrowestMetadataForFile(ctx, snapshot, uri) +- if err != nil { +- event.Error(ctx, fmt.Sprintf("missing metadata for %q", uri), err) +- continue +- } +- seen[uri] = true +- work = append(work, symbolFile{uri, meta, syms}) - } -- case *parse.RangeNode: -- fmt.Fprintf(wr.w, "%sRangeNode at %s\n", indent, at(x.Pos)) -- wr.writeNode(&x.BranchNode, indent+". ") -- case *parse.StringNode: -- fmt.Fprintf(wr.w, "%sStringNode at %s, %s\n", indent, at(x.Pos), x.Quoted) -- case *parse.TemplateNode: -- fmt.Fprintf(wr.w, "%sTemplateNode at %s, %s\n", indent, at(x.Pos), x.Name) -- wr.writeNode(x.Pipe, indent+". ") -- case *parse.TextNode: -- fmt.Fprintf(wr.w, "%sTextNode at %s, len %d\n", indent, at(x.Pos), len(x.Text)) -- case *parse.VariableNode: -- fmt.Fprintf(wr.w, "%sVariableNode at %s, %v\n", indent, at(x.Pos), x.Ident) -- case *parse.WithNode: -- fmt.Fprintf(wr.w, "%sWithNode at %s\n", indent, at(x.Pos)) -- wr.writeNode(&x.BranchNode, indent+". ") - } --} - --var kindNames = []string{"", "File", "Module", "Namespace", "Package", "Class", "Method", "Property", -- "Field", "Constructor", "Enum", "Interface", "Function", "Variable", "Constant", "String", -- "Number", "Boolean", "Array", "Object", "Key", "Null", "EnumMember", "Struct", "Event", -- "Operator", "TypeParameter"} +- // Match symbols in parallel. +- // Each worker has its own symbolStore, +- // which we merge at the end. +- nmatchers := runtime.GOMAXPROCS(-1) // matching is CPU bound +- results := make(chan *symbolStore) +- for i := 0; i < nmatchers; i++ { +- go func(i int) { +- matcher := buildMatcher(matcherType, query) +- store := new(symbolStore) +- // Assign files to workers in round-robin fashion. +- for j := i; j < len(work); j += nmatchers { +- matchFile(store, symbolizer, matcher, roots, work[j]) +- } +- results <- store +- }(i) +- } - --func kindStr(k protocol.SymbolKind) string { -- n := int(k) -- if n < 1 || n >= len(kindNames) { -- return fmt.Sprintf("?SymbolKind %d?", n) +- // Gather and merge results as they arrive. +- var unified symbolStore +- for i := 0; i < nmatchers; i++ { +- store := <-results +- for _, syms := range store.res { +- unified.store(syms) +- } - } -- return kindNames[n] +- return unified.results(), nil -} -diff -urN a/gopls/internal/lsp/template/parse_test.go b/gopls/internal/lsp/template/parse_test.go ---- a/gopls/internal/lsp/template/parse_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/parse_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,238 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --package template -- --import ( -- "strings" -- "testing" --) - --type datum struct { -- buf string -- cnt int -- syms []string // the symbols in the parse of buf +-type Filterer struct { +- // Whether a filter is excluded depends on the operator (first char of the raw filter). +- // Slices filters and excluded then should have the same length. +- filters []*regexp.Regexp +- excluded []bool -} - --var tmpl = []datum{{` --{{if (foo .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} --{{$A.X 12}} --{{foo (.X.Y) 23 ($A.Zü)}} --{{end}}`, 1, []string{"{7,3,foo,Function,false}", "{12,1,X,Method,false}", -- "{14,1,Y,Method,false}", "{21,2,$A,Variable,true}", "{26,2,,String,false}", -- "{35,1,Z,Method,false}", "{38,2,$A,Variable,false}", -- "{53,2,$A,Variable,false}", "{56,1,X,Method,false}", "{57,2,,Number,false}", -- "{64,3,foo,Function,false}", "{70,1,X,Method,false}", -- "{72,1,Y,Method,false}", "{75,2,,Number,false}", "{80,2,$A,Variable,false}", -- "{83,2,Zü,Method,false}", "{94,3,,Constant,false}"}}, -- -- {`{{define "zzz"}}{{.}}{{end}} --{{template "zzz"}}`, 2, []string{"{10,3,zzz,Namespace,true}", "{18,1,dot,Variable,false}", -- "{41,3,zzz,Package,false}"}}, +-// NewFilterer computes regular expression form of all raw filters +-func NewFilterer(rawFilters []string) *Filterer { +- var f Filterer +- for _, filter := range rawFilters { +- filter = path.Clean(filepath.ToSlash(filter)) +- // TODO(dungtuanle): fix: validate [+-] prefix. +- op, prefix := filter[0], filter[1:] +- // convertFilterToRegexp adds "/" at the end of prefix to handle cases where a filter is a prefix of another filter. +- // For example, it prevents [+foobar, -foo] from excluding "foobar". +- f.filters = append(f.filters, convertFilterToRegexp(filepath.ToSlash(prefix))) +- f.excluded = append(f.excluded, op == '-') +- } - -- {`{{block "aaa" foo}}b{{end}}`, 2, []string{"{9,3,aaa,Namespace,true}", -- "{9,3,aaa,Package,false}", "{14,3,foo,Function,false}", "{19,1,,Constant,false}"}}, -- {"", 0, nil}, +- return &f -} - --func TestSymbols(t *testing.T) { -- for i, x := range tmpl { -- got := parseBuffer([]byte(x.buf)) -- if got.ParseErr != nil { -- t.Errorf("error:%v", got.ParseErr) -- continue -- } -- if len(got.named) != x.cnt { -- t.Errorf("%d: got %d, expected %d", i, len(got.named), x.cnt) -- } -- for n, s := range got.symbols { -- if s.String() != x.syms[n] { -- t.Errorf("%d: got %s, expected %s", i, s.String(), x.syms[n]) -- } -- } +-// Disallow return true if the path is excluded from the filterer's filters. +-func (f *Filterer) Disallow(path string) bool { +- // Ensure trailing but not leading slash. +- path = strings.TrimPrefix(path, "/") +- if !strings.HasSuffix(path, "/") { +- path += "/" - } --} - --func TestWordAt(t *testing.T) { -- want := []string{"", "", "$A", "$A", "", "", "", "", "", "", -- "", "", "", "if", "if", "", "$A", "$A", "", "", -- "B", "", "", "end", "end", "end", "", "", ""} -- p := parseBuffer([]byte("{{$A := .}}{{if $A}}B{{end}}")) -- for i := 0; i < len(p.buf); i++ { -- got := findWordAt(p, i) -- if got != want[i] { -- t.Errorf("for %d, got %q, wanted %q", i, got, want[i]) +- // TODO(adonovan): opt: iterate in reverse and break at first match. +- excluded := false +- for i, filter := range f.filters { +- if filter.MatchString(path) { +- excluded = f.excluded[i] // last match wins - } - } +- return excluded -} - --func TestNLS(t *testing.T) { -- buf := `{{if (foÜx .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} -- {{$A.X 12}} -- {{foo (.X.Y) 23 ($A.Z)}} -- {{end}} -- ` -- p := parseBuffer([]byte(buf)) -- if p.ParseErr != nil { -- t.Fatal(p.ParseErr) +-// convertFilterToRegexp replaces glob-like operator substrings in a string file path to their equivalent regex forms. +-// Supporting glob-like operators: +-// - **: match zero or more complete path segments +-func convertFilterToRegexp(filter string) *regexp.Regexp { +- if filter == "" { +- return regexp.MustCompile(".*") - } -- // line 0 doesn't have a \n in front of it -- for i := 1; i < len(p.nls)-1; i++ { -- if buf[p.nls[i]] != '\n' { -- t.Errorf("line %d got %c", i, buf[p.nls[i]]) +- var ret strings.Builder +- ret.WriteString("^") +- segs := strings.Split(filter, "/") +- for _, seg := range segs { +- // Inv: seg != "" since path is clean. +- if seg == "**" { +- ret.WriteString(".*") +- } else { +- ret.WriteString(regexp.QuoteMeta(seg)) - } +- ret.WriteString("/") - } -- // fake line at end of file -- if p.nls[len(p.nls)-1] != len(buf) { -- t.Errorf("got %d expected %d", p.nls[len(p.nls)-1], len(buf)) -- } +- pattern := ret.String() +- +- // Remove unnecessary "^.*" prefix, which increased +- // BenchmarkWorkspaceSymbols time by ~20% (even though +- // filter CPU time increased by only by ~2.5%) when the +- // default filter was changed to "**/node_modules". +- pattern = strings.TrimPrefix(pattern, "^.*") +- +- return regexp.MustCompile(pattern) -} - --func TestLineCol(t *testing.T) { -- buf := `{{if (foÜx .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} -- {{$A.X 12}} -- {{foo (.X.Y) 23 ($A.Z)}} -- {{end}}` -- if false { -- t.Error(buf) -- } -- for n, cx := range tmpl { -- buf := cx.buf -- p := parseBuffer([]byte(buf)) -- if p.ParseErr != nil { -- t.Fatal(p.ParseErr) -- } -- type loc struct { -- offset int -- l, c uint32 +-// symbolFile holds symbol information for a single file. +-type symbolFile struct { +- uri span.URI +- md *Metadata +- syms []Symbol +-} +- +-// matchFile scans a symbol file and adds matching symbols to the store. +-func matchFile(store *symbolStore, symbolizer symbolizer, matcher matcherFunc, roots []string, i symbolFile) { +- space := make([]string, 0, 3) +- for _, sym := range i.syms { +- symbolParts, score := symbolizer(space, sym.Name, i.md, matcher) +- +- // Check if the score is too low before applying any downranking. +- if store.tooLow(score) { +- continue - } -- saved := []loc{} -- // forwards -- var lastl, lastc uint32 -- for offset := range buf { -- l, c := p.LineCol(offset) -- saved = append(saved, loc{offset, l, c}) -- if l > lastl { -- lastl = l -- if c != 0 { -- t.Errorf("line %d, got %d instead of 0", l, c) -- } +- +- // Factors to apply to the match score for the purpose of downranking +- // results. +- // +- // These numbers were crudely calibrated based on trial-and-error using a +- // small number of sample queries. Adjust as necessary. +- // +- // All factors are multiplicative, meaning if more than one applies they are +- // multiplied together. +- const ( +- // nonWorkspaceFactor is applied to symbols outside the workspace. +- // Developers are less likely to want to jump to code that they +- // are not actively working on. +- nonWorkspaceFactor = 0.5 +- // nonWorkspaceUnexportedFactor is applied to unexported symbols outside +- // the workspace. Since one wouldn't usually jump to unexported +- // symbols to understand a package API, they are particularly irrelevant. +- nonWorkspaceUnexportedFactor = 0.5 +- // every field or method nesting level to access the field decreases +- // the score by a factor of 1.0 - depth*depthFactor, up to a depth of +- // 3. +- // +- // Use a small constant here, as this exists mostly to break ties +- // (e.g. given a type Foo and a field x.Foo, prefer Foo). +- depthFactor = 0.01 +- ) +- +- startWord := true +- exported := true +- depth := 0.0 +- for _, r := range sym.Name { +- if startWord && !unicode.IsUpper(r) { +- exported = false - } -- if c > lastc { -- lastc = c +- if r == '.' { +- startWord = true +- depth++ +- } else { +- startWord = false - } - } -- lines := strings.Split(buf, "\n") -- mxlen := -1 -- for _, l := range lines { -- if len(l) > mxlen { -- mxlen = len(l) +- +- // TODO(rfindley): use metadata to determine if the file is in a workspace +- // package, rather than this heuristic. +- inWorkspace := false +- for _, root := range roots { +- if strings.HasPrefix(string(i.uri), root) { +- inWorkspace = true +- break - } - } -- if int(lastl) != len(lines)-1 && int(lastc) != mxlen { -- // lastl is 0 if there is only 1 line(?) -- t.Errorf("expected %d, %d, got %d, %d for case %d", len(lines)-1, mxlen, lastl, lastc, n) -- } -- // backwards -- for j := len(saved) - 1; j >= 0; j-- { -- s := saved[j] -- xl, xc := p.LineCol(s.offset) -- if xl != s.l || xc != s.c { -- t.Errorf("at offset %d(%d), got (%d,%d), expected (%d,%d)", s.offset, j, xl, xc, s.l, s.c) +- +- // Apply downranking based on workspace position. +- if !inWorkspace { +- score *= nonWorkspaceFactor +- if !exported { +- score *= nonWorkspaceUnexportedFactor - } - } -- } --} - --func TestLineColNL(t *testing.T) { -- buf := "\n\n\n\n\n" -- p := parseBuffer([]byte(buf)) -- if p.ParseErr != nil { -- t.Fatal(p.ParseErr) -- } -- for i := 0; i < len(buf); i++ { -- l, c := p.LineCol(i) -- if c != 0 || int(l) != i+1 { -- t.Errorf("got (%d,%d), expected (%d,0)", l, c, i) +- // Apply downranking based on symbol depth. +- if depth > 3 { +- depth = 3 +- } +- score *= 1.0 - depth*depthFactor +- +- if store.tooLow(score) { +- continue +- } +- +- si := symbolInformation{ +- score: score, +- symbol: strings.Join(symbolParts, ""), +- kind: sym.Kind, +- uri: i.uri, +- rng: sym.Range, +- container: string(i.md.PkgPath), - } +- store.store(si) - } -} - --func TestPos(t *testing.T) { -- buf := ` -- {{if (foÜx .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} -- {{$A.X 12}} -- {{foo (.X.Y) 23 ($A.Z)}} -- {{end}}` -- p := parseBuffer([]byte(buf)) -- if p.ParseErr != nil { -- t.Fatal(p.ParseErr) +-type symbolStore struct { +- res [maxSymbols]symbolInformation +-} +- +-// store inserts si into the sorted results, if si has a high enough score. +-func (sc *symbolStore) store(si symbolInformation) { +- if sc.tooLow(si.score) { +- return - } -- for pos, r := range buf { -- if r == '\n' { -- continue +- insertAt := sort.Search(len(sc.res), func(i int) bool { +- // Sort by score, then symbol length, and finally lexically. +- if sc.res[i].score != si.score { +- return sc.res[i].score < si.score - } -- x := p.Position(pos) -- n := p.FromPosition(x) -- if n != pos { -- // once it's wrong, it will be wrong forever -- t.Fatalf("at pos %d (rune %c) got %d {%#v]", pos, r, n, x) +- if len(sc.res[i].symbol) != len(si.symbol) { +- return len(sc.res[i].symbol) > len(si.symbol) - } -- +- return sc.res[i].symbol > si.symbol +- }) +- if insertAt < len(sc.res)-1 { +- copy(sc.res[insertAt+1:], sc.res[insertAt:len(sc.res)-1]) - } +- sc.res[insertAt] = si -} --func TestLen(t *testing.T) { -- data := []struct { -- cnt int -- v string -- }{{1, "a"}, {1, "膈"}, {4, "😆🥸"}, {7, "3😀4567"}} -- p := &Parsed{nonASCII: true} -- for _, d := range data { -- got := p.utf16len([]byte(d.v)) -- if got != d.cnt { -- t.Errorf("%v, got %d wanted %d", d, got, d.cnt) +- +-func (sc *symbolStore) tooLow(score float64) bool { +- return score <= sc.res[len(sc.res)-1].score +-} +- +-func (sc *symbolStore) results() []protocol.SymbolInformation { +- var res []protocol.SymbolInformation +- for _, si := range sc.res { +- if si.score <= 0 { +- return res - } +- res = append(res, si.asProtocolSymbolInformation()) - } +- return res -} - --func TestUtf16(t *testing.T) { -- buf := ` -- {{if (foÜx .X.Y)}}😀{{$A := "hi"}}{{.Z $A}}{{else}} -- {{$A.X 12}} -- {{foo (.X.Y) 23 ($A.Z)}} -- {{end}}` -- p := parseBuffer([]byte(buf)) -- if p.nonASCII == false { -- t.Error("expected nonASCII to be true") -- } +-// symbolInformation is a cut-down version of protocol.SymbolInformation that +-// allows struct values of this type to be used as map keys. +-type symbolInformation struct { +- score float64 +- symbol string +- container string +- kind protocol.SymbolKind +- uri span.URI +- rng protocol.Range -} - --type ttest struct { -- tmpl string -- tokCnt int -- elidedCnt int8 +-// asProtocolSymbolInformation converts s to a protocol.SymbolInformation value. +-// +-// TODO: work out how to handle tags if/when they are needed. +-func (s symbolInformation) asProtocolSymbolInformation() protocol.SymbolInformation { +- return protocol.SymbolInformation{ +- Name: s.symbol, +- Kind: s.kind, +- Location: protocol.Location{ +- URI: protocol.URIFromSpanURI(s.uri), +- Range: s.rng, +- }, +- ContainerName: s.container, +- } -} +diff -urN a/gopls/internal/lsp/source/workspace_symbol_test.go b/gopls/internal/lsp/source/workspace_symbol_test.go +--- a/gopls/internal/lsp/source/workspace_symbol_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/workspace_symbol_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,136 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func TestQuotes(t *testing.T) { -- tsts := []ttest{ -- {"{{- /*comment*/ -}}", 1, 0}, -- {"{{/*`\ncomment\n`*/}}", 1, 0}, -- //{"{{foo\nbar}}\n", 1, 0}, // this action spanning lines parses in 1.16 -- {"{{\"{{foo}}{{\"}}", 1, 0}, -- {"{{\n{{- when}}", 1, 1}, // corrected -- {"{{{{if .}}xx{{\n{{end}}", 2, 2}, // corrected +-package source +- +-import ( +- "testing" +-) +- +-func TestParseQuery(t *testing.T) { +- tests := []struct { +- query, s string +- wantMatch bool +- }{ +- {"", "anything", false}, +- {"any", "anything", true}, +- {"any$", "anything", false}, +- {"ing$", "anything", true}, +- {"ing$", "anythinG", true}, +- {"inG$", "anything", false}, +- {"^any", "anything", true}, +- {"^any", "Anything", true}, +- {"^Any", "anything", false}, +- {"at", "anything", true}, +- // TODO: this appears to be a bug in the fuzzy matching algorithm. 'At' +- // should cause a case-sensitive match. +- // {"At", "anything", false}, +- {"At", "Anything", true}, +- {"'yth", "Anything", true}, +- {"'yti", "Anything", false}, +- {"'any 'thing", "Anything", true}, +- {"anythn nythg", "Anything", true}, +- {"ntx", "Anything", false}, +- {"anythn", "anything", true}, +- {"ing", "anything", true}, +- {"anythn nythgx", "anything", false}, - } -- for _, s := range tsts { -- p := parseBuffer([]byte(s.tmpl)) -- if len(p.tokens) != s.tokCnt { -- t.Errorf("%q: got %d tokens, expected %d", s, len(p.tokens), s.tokCnt) +- +- for _, test := range tests { +- matcher := parseQuery(test.query, newFuzzyMatcher) +- if _, score := matcher([]string{test.s}); score > 0 != test.wantMatch { +- t.Errorf("parseQuery(%q) match for %q: %.2g, want match: %t", test.query, test.s, score, test.wantMatch) - } -- if p.ParseErr != nil { -- t.Errorf("%q: %v", string(p.buf), p.ParseErr) +- } +-} +- +-func TestFiltererDisallow(t *testing.T) { +- tests := []struct { +- filters []string +- included []string +- excluded []string +- }{ +- { +- []string{"+**/c.go"}, +- []string{"a/c.go", "a/b/c.go"}, +- []string{}, +- }, +- { +- []string{"+a/**/c.go"}, +- []string{"a/b/c.go", "a/b/d/c.go", "a/c.go"}, +- []string{}, +- }, +- { +- []string{"-a/c.go", "+a/**"}, +- []string{"a/c.go"}, +- []string{}, +- }, +- { +- []string{"+a/**/c.go", "-**/c.go"}, +- []string{}, +- []string{"a/b/c.go"}, +- }, +- { +- []string{"+a/**/c.go", "-a/**"}, +- []string{}, +- []string{"a/b/c.go"}, +- }, +- { +- []string{"+**/c.go", "-a/**/c.go"}, +- []string{}, +- []string{"a/b/c.go"}, +- }, +- { +- []string{"+foobar", "-foo"}, +- []string{"foobar", "foobar/a"}, +- []string{"foo", "foo/a"}, +- }, +- { +- []string{"+", "-"}, +- []string{}, +- []string{"foobar", "foobar/a", "foo", "foo/a"}, +- }, +- { +- []string{"-", "+"}, +- []string{"foobar", "foobar/a", "foo", "foo/a"}, +- []string{}, +- }, +- { +- []string{"-a/**/b/**/c.go"}, +- []string{}, +- []string{"a/x/y/z/b/f/g/h/c.go"}, +- }, +- // tests for unsupported glob operators +- { +- []string{"+**/c.go", "-a/*/c.go"}, +- []string{"a/b/c.go"}, +- []string{}, +- }, +- { +- []string{"+**/c.go", "-a/?/c.go"}, +- []string{"a/b/c.go"}, +- []string{}, +- }, +- { +- []string{"-b"}, // should only filter paths prefixed with the "b" directory +- []string{"a/b/c.go", "bb"}, +- []string{"b/c/d.go", "b"}, +- }, +- } +- +- for _, test := range tests { +- filterer := NewFilterer(test.filters) +- for _, inc := range test.included { +- if filterer.Disallow(inc) { +- t.Errorf("Filters %v excluded %v, wanted included", test.filters, inc) +- } - } -- if len(p.elided) != int(s.elidedCnt) { -- t.Errorf("%q: elided %d, expected %d", s, len(p.elided), s.elidedCnt) +- +- for _, exc := range test.excluded { +- if !filterer.Disallow(exc) { +- t.Errorf("Filters %v included %v, wanted excluded", test.filters, exc) +- } - } - } -} -diff -urN a/gopls/internal/lsp/template/symbols.go b/gopls/internal/lsp/template/symbols.go ---- a/gopls/internal/lsp/template/symbols.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/template/symbols.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,230 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/lsp/source/xrefs/xrefs.go b/gopls/internal/lsp/source/xrefs/xrefs.go +--- a/gopls/internal/lsp/source/xrefs/xrefs.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/source/xrefs/xrefs.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,193 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --package template +-// Package xrefs defines the serializable index of cross-package +-// references that is computed during type checking. +-// +-// See ../references.go for the 'references' query. +-package xrefs - -import ( -- "bytes" -- "context" -- "fmt" -- "text/template/parse" -- "unicode/utf8" +- "go/ast" +- "go/types" +- "sort" - -- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/go/types/objectpath" +- "golang.org/x/tools/gopls/internal/lsp/frob" - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/typeparams" -) - --// in local coordinates, to be translated to protocol.DocumentSymbol --type symbol struct { -- start int // for sorting -- length int // in runes (unicode code points) -- name string -- kind protocol.SymbolKind -- vardef bool // is this a variable definition? -- // do we care about selection range, or children? -- // no children yet, and selection range is the same as range --} -- --func (s symbol) String() string { -- return fmt.Sprintf("{%d,%d,%s,%s,%v}", s.start, s.length, s.name, s.kind, s.vardef) --} +-// Index constructs a serializable index of outbound cross-references +-// for the specified type-checked package. +-func Index(files []*source.ParsedGoFile, pkg *types.Package, info *types.Info) []byte { +- // pkgObjects maps each referenced package Q to a mapping: +- // from each referenced symbol in Q to the ordered list +- // of references to that symbol from this package. +- // A nil types.Object indicates a reference +- // to the package as a whole: an import. +- pkgObjects := make(map[*types.Package]map[types.Object]*gobObject) - --// for FieldNode or VariableNode (or ChainNode?) --func (p *Parsed) fields(flds []string, x parse.Node) []symbol { -- ans := []symbol{} -- // guessing that there are no embedded blanks allowed. The doc is unclear -- lookfor := "" -- switch x.(type) { -- case *parse.FieldNode: -- for _, f := range flds { -- lookfor += "." + f // quadratic, but probably ok -- } -- case *parse.VariableNode: -- lookfor = flds[0] -- for i := 1; i < len(flds); i++ { -- lookfor += "." + flds[i] -- } -- case *parse.ChainNode: // PJW, what are these? -- for _, f := range flds { -- lookfor += "." + f // quadratic, but probably ok +- // getObjects returns the object-to-references mapping for a package. +- getObjects := func(pkg *types.Package) map[types.Object]*gobObject { +- objects, ok := pkgObjects[pkg] +- if !ok { +- objects = make(map[types.Object]*gobObject) +- pkgObjects[pkg] = objects - } -- default: -- // If these happen they will happen even if gopls is restarted -- // and the users does the same thing, so it is better not to panic. -- // context.Background() is used because we don't have access -- // to any other context. [we could, but it would be complicated] -- event.Log(context.Background(), fmt.Sprintf("%T unexpected in fields()", x)) -- return nil -- } -- if len(lookfor) == 0 { -- event.Log(context.Background(), fmt.Sprintf("no strings in fields() %#v", x)) -- return nil +- return objects - } -- startsAt := int(x.Position()) -- ix := bytes.Index(p.buf[startsAt:], []byte(lookfor)) // HasPrefix? PJW? -- if ix < 0 || ix > len(lookfor) { // lookfor expected to be at start (or so) -- // probably golang.go/#43388, so back up -- startsAt -= len(flds[0]) + 1 -- ix = bytes.Index(p.buf[startsAt:], []byte(lookfor)) // ix might be 1? PJW -- if ix < 0 { -- return ans +- +- objectpathFor := new(objectpath.Encoder).For +- +- for fileIndex, pgf := range files { +- +- nodeRange := func(n ast.Node) protocol.Range { +- rng, err := pgf.PosRange(n.Pos(), n.End()) +- if err != nil { +- panic(err) // can't fail +- } +- return rng - } +- +- ast.Inspect(pgf.File, func(n ast.Node) bool { +- switch n := n.(type) { +- case *ast.Ident: +- // Report a reference for each identifier that +- // uses a symbol exported from another package. +- // (The built-in error.Error method has no package.) +- if n.IsExported() { +- if obj, ok := info.Uses[n]; ok && +- obj.Pkg() != nil && +- obj.Pkg() != pkg { +- +- // For instantiations of generic methods, +- // use the generic object (see issue #60622). +- if fn, ok := obj.(*types.Func); ok { +- obj = typeparams.OriginMethod(fn) +- } +- +- objects := getObjects(obj.Pkg()) +- gobObj, ok := objects[obj] +- if !ok { +- path, err := objectpathFor(obj) +- if err != nil { +- // Capitalized but not exported +- // (e.g. local const/var/type). +- return true +- } +- gobObj = &gobObject{Path: path} +- objects[obj] = gobObj +- } +- +- gobObj.Refs = append(gobObj.Refs, gobRef{ +- FileIndex: fileIndex, +- Range: nodeRange(n), +- }) +- } +- } +- +- case *ast.ImportSpec: +- // Report a reference from each import path +- // string to the imported package. +- pkgname, ok := source.ImportedPkgName(info, n) +- if !ok { +- return true // missing import +- } +- objects := getObjects(pkgname.Imported()) +- gobObj, ok := objects[nil] +- if !ok { +- gobObj = &gobObject{Path: ""} +- objects[nil] = gobObj +- } +- gobObj.Refs = append(gobObj.Refs, gobRef{ +- FileIndex: fileIndex, +- Range: nodeRange(n.Path), +- }) +- } +- return true +- }) - } -- at := ix + startsAt -- for _, f := range flds { -- at += 1 // . -- kind := protocol.Method -- if f[0] == '$' { -- kind = protocol.Variable +- +- // Flatten the maps into slices, and sort for determinism. +- var packages []*gobPackage +- for p := range pkgObjects { +- objects := pkgObjects[p] +- gp := &gobPackage{ +- PkgPath: source.PackagePath(p.Path()), +- Objects: make([]*gobObject, 0, len(objects)), - } -- sym := symbol{name: f, kind: kind, start: at, length: utf8.RuneCount([]byte(f))} -- if kind == protocol.Variable && len(p.stack) > 1 { -- if pipe, ok := p.stack[len(p.stack)-2].(*parse.PipeNode); ok { -- for _, y := range pipe.Decl { -- if x == y { -- sym.vardef = true +- for _, gobObj := range objects { +- gp.Objects = append(gp.Objects, gobObj) +- } +- sort.Slice(gp.Objects, func(i, j int) bool { +- return gp.Objects[i].Path < gp.Objects[j].Path +- }) +- packages = append(packages, gp) +- } +- sort.Slice(packages, func(i, j int) bool { +- return packages[i].PkgPath < packages[j].PkgPath +- }) +- +- return packageCodec.Encode(packages) +-} +- +-// Lookup searches a serialized index produced by an indexPackage +-// operation on m, and returns the locations of all references from m +-// to any object in the target set. Each object is denoted by a pair +-// of (package path, object path). +-func Lookup(m *source.Metadata, data []byte, targets map[source.PackagePath]map[objectpath.Path]struct{}) (locs []protocol.Location) { +- var packages []*gobPackage +- packageCodec.Decode(data, &packages) +- for _, gp := range packages { +- if objectSet, ok := targets[gp.PkgPath]; ok { +- for _, gobObj := range gp.Objects { +- if _, ok := objectSet[gobObj.Path]; ok { +- for _, ref := range gobObj.Refs { +- uri := m.CompiledGoFiles[ref.FileIndex] +- locs = append(locs, protocol.Location{ +- URI: protocol.URIFromSpanURI(uri), +- Range: ref.Range, +- }) - } - } - } - } -- ans = append(ans, sym) -- at += len(f) - } -- return ans +- +- return locs -} - --func (p *Parsed) findSymbols() { -- if len(p.stack) == 0 { -- return -- } -- n := p.stack[len(p.stack)-1] -- pop := func() { -- p.stack = p.stack[:len(p.stack)-1] -- } -- if n == nil { // allowing nil simplifies the code -- pop() -- return -- } -- nxt := func(nd parse.Node) { -- p.stack = append(p.stack, nd) -- p.findSymbols() -- } -- switch x := n.(type) { -- case *parse.ActionNode: -- nxt(x.Pipe) -- case *parse.BoolNode: -- // need to compute the length from the value -- msg := fmt.Sprintf("%v", x.True) -- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: len(msg), kind: protocol.Boolean}) -- case *parse.BranchNode: -- nxt(x.Pipe) -- nxt(x.List) -- nxt(x.ElseList) -- case *parse.ChainNode: -- p.symbols = append(p.symbols, p.fields(x.Field, x)...) -- nxt(x.Node) -- case *parse.CommandNode: -- for _, a := range x.Args { -- nxt(a) +-// -- serialized representation -- +- +-// The cross-reference index records the location of all references +-// from one package to symbols defined in other packages +-// (dependencies). It does not record within-package references. +-// The index for package P consists of a list of gopPackage records, +-// each enumerating references to symbols defined a single dependency, Q. +- +-// TODO(adonovan): opt: choose a more compact encoding. +-// The gobRef.Range field is the obvious place to begin. +- +-// (The name says gob but in fact we use frob.) +-var packageCodec = frob.CodecFor[[]*gobPackage]() +- +-// A gobPackage records the set of outgoing references from the index +-// package to symbols defined in a dependency package. +-type gobPackage struct { +- PkgPath source.PackagePath // defining package (Q) +- Objects []*gobObject // set of Q objects referenced by P +-} +- +-// A gobObject records all references to a particular symbol. +-type gobObject struct { +- Path objectpath.Path // symbol name within package; "" => import of package itself +- Refs []gobRef // locations of references within P, in lexical order +-} +- +-type gobRef struct { +- FileIndex int // index of enclosing file within P's CompiledGoFiles +- Range protocol.Range // source range of reference +-} +diff -urN a/gopls/internal/lsp/symbols.go b/gopls/internal/lsp/symbols.go +--- a/gopls/internal/lsp/symbols.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/symbols.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,60 +0,0 @@ +-// Copyright 2019 The Go Authors. 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 +- +-import ( +- "context" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/template" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" +-) +- +-func (s *Server) documentSymbol(ctx context.Context, params *protocol.DocumentSymbolParams) ([]interface{}, error) { +- ctx, done := event.Start(ctx, "lsp.Server.documentSymbol", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- +- snapshot, fh, ok, release, err := s.beginFileRequest(ctx, params.TextDocument.URI, source.UnknownKind) +- defer release() +- if !ok { +- return []interface{}{}, err +- } +- var docSymbols []protocol.DocumentSymbol +- switch snapshot.FileKind(fh) { +- case source.Tmpl: +- docSymbols, err = template.DocumentSymbols(snapshot, fh) +- case source.Go: +- docSymbols, err = source.DocumentSymbols(ctx, snapshot, fh) +- default: +- return []interface{}{}, nil +- } +- if err != nil { +- event.Error(ctx, "DocumentSymbols failed", err) +- return []interface{}{}, nil +- } +- // Convert the symbols to an interface array. +- // TODO: Remove this once the lsp deprecates SymbolInformation. +- symbols := make([]interface{}, len(docSymbols)) +- for i, s := range docSymbols { +- if snapshot.Options().HierarchicalDocumentSymbolSupport { +- symbols[i] = s +- continue - } -- //case *parse.CommentNode: // go 1.16 -- // log.Printf("implement %d", x.Type()) -- case *parse.DotNode: -- sym := symbol{name: "dot", kind: protocol.Variable, start: int(x.Pos), length: 1} -- p.symbols = append(p.symbols, sym) -- case *parse.FieldNode: -- p.symbols = append(p.symbols, p.fields(x.Ident, x)...) -- case *parse.IdentifierNode: -- sym := symbol{name: x.Ident, kind: protocol.Function, start: int(x.Pos), -- length: utf8.RuneCount([]byte(x.Ident))} -- p.symbols = append(p.symbols, sym) -- case *parse.IfNode: -- nxt(&x.BranchNode) -- case *parse.ListNode: -- if x != nil { // wretched typed nils. Node should have an IfNil -- for _, nd := range x.Nodes { -- nxt(nd) -- } +- // If the client does not support hierarchical document symbols, then +- // we need to be backwards compatible for now and return SymbolInformation. +- symbols[i] = protocol.SymbolInformation{ +- Name: s.Name, +- Kind: s.Kind, +- Deprecated: s.Deprecated, +- Location: protocol.Location{ +- URI: params.TextDocument.URI, +- Range: s.Range, +- }, - } -- case *parse.NilNode: -- sym := symbol{name: "nil", kind: protocol.Constant, start: int(x.Pos), length: 3} -- p.symbols = append(p.symbols, sym) -- case *parse.NumberNode: -- // no name; ascii -- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: len(x.Text), kind: protocol.Number}) -- case *parse.PipeNode: -- if x == nil { // {{template "foo"}} -- return +- } +- return symbols, nil +-} +diff -urN a/gopls/internal/lsp/template/completion.go b/gopls/internal/lsp/template/completion.go +--- a/gopls/internal/lsp/template/completion.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/template/completion.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,287 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package template +- +-import ( +- "bytes" +- "context" +- "fmt" +- "go/scanner" +- "go/token" +- "strings" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +-) +- +-// information needed for completion +-type completer struct { +- p *Parsed +- pos protocol.Position +- offset int // offset of the start of the Token +- ctx protocol.CompletionContext +- syms map[string]symbol +-} +- +-func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, pos protocol.Position, context protocol.CompletionContext) (*protocol.CompletionList, error) { +- all := New(snapshot.Templates()) +- var start int // the beginning of the Token (completed or not) +- syms := make(map[string]symbol) +- var p *Parsed +- for fn, fc := range all.files { +- // collect symbols from all template files +- filterSyms(syms, fc.symbols) +- if fn.Filename() != fh.URI().Filename() { +- continue - } -- for _, d := range x.Decl { -- nxt(d) +- if start = inTemplate(fc, pos); start == -1 { +- return nil, nil - } -- for _, c := range x.Cmds { -- nxt(c) +- p = fc +- } +- if p == nil { +- // this cannot happen unless the search missed a template file +- return nil, fmt.Errorf("%s not found", fh.FileIdentity().URI.Filename()) +- } +- c := completer{ +- p: p, +- pos: pos, +- offset: start + len(Left), +- ctx: context, +- syms: syms, +- } +- return c.complete() +-} +- +-func filterSyms(syms map[string]symbol, ns []symbol) { +- for _, xsym := range ns { +- switch xsym.kind { +- case protocol.Method, protocol.Package, protocol.Boolean, protocol.Namespace, +- protocol.Function: +- syms[xsym.name] = xsym // we don't care which symbol we get +- case protocol.Variable: +- if xsym.name != "dot" { +- syms[xsym.name] = xsym +- } +- case protocol.Constant: +- if xsym.name == "nil" { +- syms[xsym.name] = xsym +- } - } -- case *parse.RangeNode: -- nxt(&x.BranchNode) -- case *parse.StringNode: -- // no name -- sz := utf8.RuneCount([]byte(x.Text)) -- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: sz, kind: protocol.String}) -- case *parse.TemplateNode: // invoking a template -- // x.Pos points to the quote before the name -- p.symbols = append(p.symbols, symbol{name: x.Name, kind: protocol.Package, start: int(x.Pos) + 1, -- length: utf8.RuneCount([]byte(x.Name))}) -- nxt(x.Pipe) -- case *parse.TextNode: -- if len(x.Text) == 1 && x.Text[0] == '\n' { +- } +-} +- +-// return the starting position of the enclosing token, or -1 if none +-func inTemplate(fc *Parsed, pos protocol.Position) int { +- // pos is the pos-th character. if the cursor is at the beginning +- // of the file, pos is 0. That is, we've only seen characters before pos +- // 1. pos might be in a Token, return tk.Start +- // 2. pos might be after an elided but before a Token, return elided +- // 3. return -1 for false +- offset := fc.FromPosition(pos) +- // this could be a binary search, as the tokens are ordered +- for _, tk := range fc.tokens { +- if tk.Start < offset && offset <= tk.End { +- return tk.Start +- } +- } +- for _, x := range fc.elided { +- if x > offset { +- // fc.elided is sorted - break - } -- // nothing to report, but build one for hover -- sz := utf8.RuneCount([]byte(x.Text)) -- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: sz, kind: protocol.Constant}) -- case *parse.VariableNode: -- p.symbols = append(p.symbols, p.fields(x.Ident, x)...) -- case *parse.WithNode: -- nxt(&x.BranchNode) -- +- // If the interval [x,offset] does not contain Left or Right +- // then provide completions. (do we need the test for Right?) +- if !bytes.Contains(fc.buf[x:offset], []byte(Left)) && !bytes.Contains(fc.buf[x:offset], []byte(Right)) { +- return x +- } - } -- pop() +- return -1 -} - --// DocumentSymbols returns a hierarchy of the symbols defined in a template file. --// (The hierarchy is flat. SymbolInformation might be better.) --func DocumentSymbols(snapshot source.Snapshot, fh source.FileHandle) ([]protocol.DocumentSymbol, error) { -- buf, err := fh.Read() -- if err != nil { -- return nil, err +-var ( +- keywords = []string{"if", "with", "else", "block", "range", "template", "end}}", "end"} +- globals = []string{"and", "call", "html", "index", "slice", "js", "len", "not", "or", +- "urlquery", "printf", "println", "print", "eq", "ne", "le", "lt", "ge", "gt"} +-) +- +-// find the completions. start is the offset of either the Token enclosing pos, or where +-// the incomplete token starts. +-// The error return is always nil. +-func (c *completer) complete() (*protocol.CompletionList, error) { +- ans := &protocol.CompletionList{IsIncomplete: true, Items: []protocol.CompletionItem{}} +- start := c.p.FromPosition(c.pos) +- sofar := c.p.buf[c.offset:start] +- if len(sofar) == 0 || sofar[len(sofar)-1] == ' ' || sofar[len(sofar)-1] == '\t' { +- return ans, nil - } -- p := parseBuffer(buf) -- if p.ParseErr != nil { -- return nil, p.ParseErr +- // sofar could be parsed by either c.analyzer() or scan(). The latter is precise +- // and slower, but fast enough +- words := scan(sofar) +- // 1. if pattern starts $, show variables +- // 2. if pattern starts ., show methods (and . by itself?) +- // 3. if len(words) == 1, show firstWords (but if it were a |, show functions and globals) +- // 4. ...? (parenthetical expressions, arguments, ...) (packages, namespaces, nil?) +- if len(words) == 0 { +- return nil, nil // if this happens, why were we called? - } -- var ans []protocol.DocumentSymbol -- for _, s := range p.symbols { -- if s.kind == protocol.Constant { -- continue +- pattern := string(words[len(words)-1]) +- if pattern[0] == '$' { +- // should we also return a raw "$"? +- for _, s := range c.syms { +- if s.kind == protocol.Variable && weakMatch(s.name, pattern) > 0 { +- ans.Items = append(ans.Items, protocol.CompletionItem{ +- Label: s.name, +- Kind: protocol.VariableCompletion, +- Detail: "Variable", +- }) +- } - } -- d := kindStr(s.kind) -- if d == "Namespace" { -- d = "Template" +- return ans, nil +- } +- if pattern[0] == '.' { +- for _, s := range c.syms { +- if s.kind == protocol.Method && weakMatch("."+s.name, pattern) > 0 { +- ans.Items = append(ans.Items, protocol.CompletionItem{ +- Label: s.name, +- Kind: protocol.MethodCompletion, +- Detail: "Method/member", +- }) +- } - } -- if s.vardef { -- d += "(def)" -- } else { -- d += "(use)" +- return ans, nil +- } +- // could we get completion attempts in strings or numbers, and if so, do we care? +- // globals +- for _, kw := range globals { +- if weakMatch(kw, string(pattern)) != 0 { +- ans.Items = append(ans.Items, protocol.CompletionItem{ +- Label: kw, +- Kind: protocol.KeywordCompletion, +- Detail: "Function", +- }) - } -- r := p.Range(s.start, s.length) -- y := protocol.DocumentSymbol{ -- Name: s.name, -- Detail: d, -- Kind: s.kind, -- Range: r, -- SelectionRange: r, // or should this be the entire {{...}}? +- } +- // and functions +- for _, s := range c.syms { +- if s.kind == protocol.Function && weakMatch(s.name, pattern) != 0 { +- ans.Items = append(ans.Items, protocol.CompletionItem{ +- Label: s.name, +- Kind: protocol.FunctionCompletion, +- Detail: "Function", +- }) +- } +- } +- // keywords if we're at the beginning +- if len(words) <= 1 || len(words[len(words)-2]) == 1 && words[len(words)-2][0] == '|' { +- for _, kw := range keywords { +- if weakMatch(kw, string(pattern)) != 0 { +- ans.Items = append(ans.Items, protocol.CompletionItem{ +- Label: kw, +- Kind: protocol.KeywordCompletion, +- Detail: "keyword", +- }) +- } - } -- ans = append(ans, y) - } - return ans, nil -} -diff -urN a/gopls/internal/lsp/testdata/addimport/addimport.go.golden b/gopls/internal/lsp/testdata/addimport/addimport.go.golden ---- a/gopls/internal/lsp/testdata/addimport/addimport.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/addimport/addimport.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ ---- addimport -- --package addimport //@addimport("", "bytes") - --import "bytes" +-// someday think about comments, strings, backslashes, etc +-// this would repeat some of the template parsing, but because the user is typing +-// there may be no parse tree here. +-// (go/scanner will report 2 tokens for $a, as $ is not a legal go identifier character) +-// (go/scanner is about 2.7 times more expensive) +-func (c *completer) analyze(buf []byte) [][]byte { +- // we want to split on whitespace and before dots +- var working []byte +- var ans [][]byte +- for _, ch := range buf { +- if ch == '.' && len(working) > 0 { +- ans = append(ans, working) +- working = []byte{'.'} +- continue +- } +- if ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' { +- if len(working) > 0 { +- ans = append(ans, working) +- working = []byte{} +- continue +- } +- } +- working = append(working, ch) +- } +- if len(working) > 0 { +- ans = append(ans, working) +- } +- ch := buf[len(buf)-1] +- if ch == ' ' || ch == '\t' { +- // avoid completing on whitespace +- ans = append(ans, []byte{ch}) +- } +- return ans +-} - --func main() {} +-// version of c.analyze that uses go/scanner. +-func scan(buf []byte) []string { +- fset := token.NewFileSet() +- fp := fset.AddFile("", -1, len(buf)) +- var sc scanner.Scanner +- sc.Init(fp, buf, func(pos token.Position, msg string) {}, scanner.ScanComments) +- ans := make([]string, 0, 10) // preallocating gives a measurable savings +- for { +- _, tok, lit := sc.Scan() // tok is an int +- if tok == token.EOF { +- break // done +- } else if tok == token.SEMICOLON && lit == "\n" { +- continue // don't care, but probably can't happen +- } else if tok == token.PERIOD { +- ans = append(ans, ".") // lit is empty +- } else if tok == token.IDENT && len(ans) > 0 && ans[len(ans)-1] == "." { +- ans[len(ans)-1] = "." + lit +- } else if tok == token.IDENT && len(ans) > 0 && ans[len(ans)-1] == "$" { +- ans[len(ans)-1] = "$" + lit +- } else if lit != "" { +- ans = append(ans, lit) +- } +- } +- return ans +-} - -diff -urN a/gopls/internal/lsp/testdata/addimport/addimport.go.in b/gopls/internal/lsp/testdata/addimport/addimport.go.in ---- a/gopls/internal/lsp/testdata/addimport/addimport.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/addimport/addimport.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ --package addimport //@addimport("", "bytes") +-// pattern is what the user has typed +-func weakMatch(choice, pattern string) float64 { +- lower := strings.ToLower(choice) +- // for now, use only lower-case everywhere +- pattern = strings.ToLower(pattern) +- // The first char has to match +- if pattern[0] != lower[0] { +- return 0 +- } +- // If they start with ., then the second char has to match +- from := 1 +- if pattern[0] == '.' { +- if len(pattern) < 2 { +- return 1 // pattern just a ., so it matches +- } +- if pattern[1] != lower[1] { +- return 0 +- } +- from = 2 +- } +- // check that all the characters of pattern occur as a subsequence of choice +- i, j := from, from +- for ; i < len(lower) && j < len(pattern); j++ { +- if pattern[j] == lower[i] { +- i++ +- if i >= len(lower) { +- return 0 +- } +- } +- } +- if j < len(pattern) { +- return 0 +- } +- return 1 +-} +diff -urN a/gopls/internal/lsp/template/completion_test.go b/gopls/internal/lsp/template/completion_test.go +--- a/gopls/internal/lsp/template/completion_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/template/completion_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,102 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package template +- +-import ( +- "log" +- "sort" +- "strings" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +-) +- +-func init() { +- log.SetFlags(log.Lshortfile) +-} +- +-type tparse struct { +- marked string // ^ shows where to ask for completions. (The user just typed the following character.) +- wanted []string // expected completions +-} +- +-// Test completions in templates that parse enough (if completion needs symbols) +-// Seen characters up to the ^ +-func TestParsed(t *testing.T) { +- var tests = []tparse{ +- {"{{x}}{{12. xx^", nil}, // https://github.com/golang/go/issues/50430 +- {`
    `, nil}, +- {"{{i^f}}", []string{"index", "if"}}, +- {"{{if .}}{{e^ {{end}}", []string{"eq", "end}}", "else", "end"}}, +- {"{{foo}}{{f^", []string{"foo"}}, +- {"{{$^}}", []string{"$"}}, +- {"{{$x:=4}}{{$^", []string{"$x"}}, +- {"{{$x:=4}}{{$ ^ ", []string{}}, +- {"{{len .Modified}}{{.^Mo", []string{"Modified"}}, +- {"{{len .Modified}}{{.mf^", []string{"Modified"}}, +- {"{{$^ }}", []string{"$"}}, +- {"{{$a =3}}{{$^", []string{"$a"}}, +- // .two is not good here: fix someday +- {`{{.Modified}}{{.^{{if $.one.two}}xxx{{end}}`, []string{"Modified", "one", "two"}}, +- {`{{.Modified}}{{.o^{{if $.one.two}}xxx{{end}}`, []string{"one"}}, +- {"{{.Modiifed}}{{.one.t^{{if $.one.two}}xxx{{end}}", []string{"two"}}, +- {`{{block "foo" .}}{{i^`, []string{"index", "if"}}, +- {"{{in^{{Internal}}", []string{"index", "Internal", "if"}}, +- // simple number has no completions +- {"{{4^e", []string{}}, +- // simple string has no completions +- {"{{`e^", []string{}}, +- {"{{`No i^", []string{}}, // example of why go/scanner is used +- {"{{xavier}}{{12. x^", []string{"xavier"}}, +- } +- for _, tx := range tests { +- c := testCompleter(t, tx) +- var v []string +- if c != nil { +- ans, _ := c.complete() +- for _, a := range ans.Items { +- v = append(v, a.Label) +- } +- } +- if len(v) != len(tx.wanted) { +- t.Errorf("%q: got %q, wanted %q %d,%d", tx.marked, v, tx.wanted, len(v), len(tx.wanted)) +- continue +- } +- sort.Strings(tx.wanted) +- sort.Strings(v) +- for i := 0; i < len(v); i++ { +- if tx.wanted[i] != v[i] { +- t.Errorf("%q at %d: got %v, wanted %v", tx.marked, i, v, tx.wanted) +- break +- } +- } +- } +-} +- +-func testCompleter(t *testing.T, tx tparse) *completer { +- t.Helper() +- // seen chars up to ^ +- col := strings.Index(tx.marked, "^") +- buf := strings.Replace(tx.marked, "^", "", 1) +- p := parseBuffer([]byte(buf)) +- pos := protocol.Position{Line: 0, Character: uint32(col)} +- if p.ParseErr != nil { +- log.Printf("%q: %v", tx.marked, p.ParseErr) +- } +- offset := inTemplate(p, pos) +- if offset == -1 { +- return nil +- } +- syms := make(map[string]symbol) +- filterSyms(syms, p.symbols) +- c := &completer{ +- p: p, +- pos: protocol.Position{Line: 0, Character: uint32(col)}, +- offset: offset + len(Left), +- ctx: protocol.CompletionContext{TriggerKind: protocol.Invoked}, +- syms: syms, +- } +- return c +-} +diff -urN a/gopls/internal/lsp/template/highlight.go b/gopls/internal/lsp/template/highlight.go +--- a/gopls/internal/lsp/template/highlight.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/template/highlight.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,96 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package template +- +-import ( +- "context" +- "fmt" +- "regexp" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +-) +- +-func Highlight(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, loc protocol.Position) ([]protocol.DocumentHighlight, error) { +- buf, err := fh.Content() +- if err != nil { +- return nil, err +- } +- p := parseBuffer(buf) +- pos := p.FromPosition(loc) +- var ans []protocol.DocumentHighlight +- if p.ParseErr == nil { +- for _, s := range p.symbols { +- if s.start <= pos && pos < s.start+s.length { +- return markSymbols(p, s) +- } +- } +- } +- // these tokens exist whether or not there was a parse error +- // (symbols require a successful parse) +- for _, tok := range p.tokens { +- if tok.Start <= pos && pos < tok.End { +- wordAt := findWordAt(p, pos) +- if len(wordAt) > 0 { +- return markWordInToken(p, wordAt) +- } +- } +- } +- // find the 'word' at pos, etc: someday +- // until then we get the default action, which doesn't respect word boundaries +- return ans, nil +-} +- +-func markSymbols(p *Parsed, sym symbol) ([]protocol.DocumentHighlight, error) { +- var ans []protocol.DocumentHighlight +- for _, s := range p.symbols { +- if s.name == sym.name { +- kind := protocol.Read +- if s.vardef { +- kind = protocol.Write +- } +- ans = append(ans, protocol.DocumentHighlight{ +- Range: p.Range(s.start, s.length), +- Kind: kind, +- }) +- } +- } +- return ans, nil +-} +- +-// A token is {{...}}, and this marks words in the token that equal the give word +-func markWordInToken(p *Parsed, wordAt string) ([]protocol.DocumentHighlight, error) { +- var ans []protocol.DocumentHighlight +- pat, err := regexp.Compile(fmt.Sprintf(`\b%s\b`, wordAt)) +- if err != nil { +- return nil, fmt.Errorf("%q: unmatchable word (%v)", wordAt, err) +- } +- for _, tok := range p.tokens { +- got := pat.FindAllIndex(p.buf[tok.Start:tok.End], -1) +- for i := 0; i < len(got); i++ { +- ans = append(ans, protocol.DocumentHighlight{ +- Range: p.Range(got[i][0], got[i][1]-got[i][0]), +- Kind: protocol.Text, +- }) +- } +- } +- return ans, nil +-} +- +-var wordRe = regexp.MustCompile(`[$]?\w+$`) +-var moreRe = regexp.MustCompile(`^[$]?\w+`) +- +-// findWordAt finds the word the cursor is in (meaning in or just before) +-func findWordAt(p *Parsed, pos int) string { +- if pos >= len(p.buf) { +- return "" // can't happen, as we are called with pos < tok.End +- } +- after := moreRe.Find(p.buf[pos:]) +- if len(after) == 0 { +- return "" // end of the word +- } +- got := wordRe.Find(p.buf[:pos+len(after)]) +- return string(got) +-} +diff -urN a/gopls/internal/lsp/template/implementations.go b/gopls/internal/lsp/template/implementations.go +--- a/gopls/internal/lsp/template/implementations.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/template/implementations.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,189 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package template +- +-import ( +- "context" +- "fmt" +- "regexp" +- "strconv" +- "time" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +-) +- +-// line number (1-based) and message +-var errRe = regexp.MustCompile(`template.*:(\d+): (.*)`) +- +-// Diagnose returns parse errors. There is only one. +-// The errors are not always helpful. For instance { {end}} +-// will likely point to the end of the file. +-func Diagnose(f source.FileHandle) []*source.Diagnostic { +- // no need for skipTemplate check, as Diagnose is called on the +- // snapshot's template files +- buf, err := f.Content() +- if err != nil { +- // Is a Diagnostic with no Range useful? event.Error also? +- msg := fmt.Sprintf("failed to read %s (%v)", f.URI().Filename(), err) +- d := source.Diagnostic{Message: msg, Severity: protocol.SeverityError, URI: f.URI(), +- Source: source.TemplateError} +- return []*source.Diagnostic{&d} +- } +- p := parseBuffer(buf) +- if p.ParseErr == nil { +- return nil +- } +- unknownError := func(msg string) []*source.Diagnostic { +- s := fmt.Sprintf("malformed template error %q: %s", p.ParseErr.Error(), msg) +- d := source.Diagnostic{ +- Message: s, Severity: protocol.SeverityError, Range: p.Range(p.nls[0], 1), +- URI: f.URI(), Source: source.TemplateError} +- return []*source.Diagnostic{&d} +- } +- // errors look like `template: :40: unexpected "}" in operand` +- // so the string needs to be parsed +- matches := errRe.FindStringSubmatch(p.ParseErr.Error()) +- if len(matches) != 3 { +- msg := fmt.Sprintf("expected 3 matches, got %d (%v)", len(matches), matches) +- return unknownError(msg) +- } +- lineno, err := strconv.Atoi(matches[1]) +- if err != nil { +- msg := fmt.Sprintf("couldn't convert %q to int, %v", matches[1], err) +- return unknownError(msg) +- } +- msg := matches[2] +- d := source.Diagnostic{Message: msg, Severity: protocol.SeverityError, +- Source: source.TemplateError} +- start := p.nls[lineno-1] +- if lineno < len(p.nls) { +- size := p.nls[lineno] - start +- d.Range = p.Range(start, size) +- } else { +- d.Range = p.Range(start, 1) +- } +- return []*source.Diagnostic{&d} +-} +- +-// Definition finds the definitions of the symbol at loc. It +-// does not understand scoping (if any) in templates. This code is +-// for definitions, type definitions, and implementations. +-// Results only for variables and templates. +-func Definition(snapshot source.Snapshot, fh source.FileHandle, loc protocol.Position) ([]protocol.Location, error) { +- x, _, err := symAtPosition(fh, loc) +- if err != nil { +- return nil, err +- } +- sym := x.name +- ans := []protocol.Location{} +- // PJW: this is probably a pattern to abstract +- a := New(snapshot.Templates()) +- for k, p := range a.files { +- for _, s := range p.symbols { +- if !s.vardef || s.name != sym { +- continue +- } +- ans = append(ans, protocol.Location{URI: protocol.DocumentURI(k), Range: p.Range(s.start, s.length)}) +- } +- } +- return ans, nil +-} +- +-func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) { +- sym, p, err := symAtPosition(fh, position) +- if sym == nil || err != nil { +- return nil, err +- } +- ans := protocol.Hover{Range: p.Range(sym.start, sym.length), Contents: protocol.MarkupContent{Kind: protocol.Markdown}} +- switch sym.kind { +- case protocol.Function: +- ans.Contents.Value = fmt.Sprintf("function: %s", sym.name) +- case protocol.Variable: +- ans.Contents.Value = fmt.Sprintf("variable: %s", sym.name) +- case protocol.Constant: +- ans.Contents.Value = fmt.Sprintf("constant %s", sym.name) +- case protocol.Method: // field or method +- ans.Contents.Value = fmt.Sprintf("%s: field or method", sym.name) +- case protocol.Package: // template use, template def (PJW: do we want two?) +- ans.Contents.Value = fmt.Sprintf("template %s\n(add definition)", sym.name) +- case protocol.Namespace: +- ans.Contents.Value = fmt.Sprintf("template %s defined", sym.name) +- case protocol.Number: +- ans.Contents.Value = "number" +- case protocol.String: +- ans.Contents.Value = "string" +- case protocol.Boolean: +- ans.Contents.Value = "boolean" +- default: +- ans.Contents.Value = fmt.Sprintf("oops, sym=%#v", sym) +- } +- return &ans, nil +-} +- +-func References(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, params *protocol.ReferenceParams) ([]protocol.Location, error) { +- sym, _, err := symAtPosition(fh, params.Position) +- if sym == nil || err != nil || sym.name == "" { +- return nil, err +- } +- ans := []protocol.Location{} +- +- a := New(snapshot.Templates()) +- for k, p := range a.files { +- for _, s := range p.symbols { +- if s.name != sym.name { +- continue +- } +- if s.vardef && !params.Context.IncludeDeclaration { +- continue +- } +- ans = append(ans, protocol.Location{URI: protocol.DocumentURI(k), Range: p.Range(s.start, s.length)}) +- } +- } +- // do these need to be sorted? (a.files is a map) +- return ans, nil +-} +- +-func SemanticTokens(ctx context.Context, snapshot source.Snapshot, spn span.URI, add func(line, start, len uint32), d func() []uint32) (*protocol.SemanticTokens, error) { +- fh, err := snapshot.ReadFile(ctx, spn) +- if err != nil { +- return nil, err +- } +- buf, err := fh.Content() +- if err != nil { +- return nil, err +- } +- p := parseBuffer(buf) +- +- for _, t := range p.Tokens() { +- if t.Multiline { +- la, ca := p.LineCol(t.Start) +- lb, cb := p.LineCol(t.End) +- add(la, ca, p.RuneCount(la, ca, 0)) +- for l := la + 1; l < lb; l++ { +- add(l, 0, p.RuneCount(l, 0, 0)) +- } +- add(lb, 0, p.RuneCount(lb, 0, cb)) +- continue +- } +- sz, err := p.TokenSize(t) +- if err != nil { +- return nil, err +- } +- line, col := p.LineCol(t.Start) +- add(line, col, uint32(sz)) +- } +- data := d() +- ans := &protocol.SemanticTokens{ +- Data: data, +- // for small cache, some day. for now, the LSP client ignores this +- // (that is, when the LSP client starts returning these, we can cache) +- ResultID: fmt.Sprintf("%v", time.Now()), +- } +- return ans, nil +-} +- +-// still need to do rename, etc +diff -urN a/gopls/internal/lsp/template/parse.go b/gopls/internal/lsp/template/parse.go +--- a/gopls/internal/lsp/template/parse.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/template/parse.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,508 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-// Package template contains code for dealing with templates +-package template +- +-// template files are small enough that the code reprocesses them each time +-// this may be a bad choice for projects with lots of template files. +- +-// This file contains the parsing code, some debugging printing, and +-// implementations for Diagnose, Definition, Hover, References +- +-import ( +- "bytes" +- "context" +- "fmt" +- "io" +- "log" +- "regexp" +- "runtime" +- "sort" +- "text/template" +- "text/template/parse" +- "unicode/utf8" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" +-) +- +-var ( +- Left = []byte("{{") +- Right = []byte("}}") +-) +- +-type Parsed struct { +- buf []byte //contents +- lines [][]byte // needed?, other than for debugging? +- elided []int // offsets where Left was replaced by blanks +- +- // tokens are matched Left-Right pairs, computed before trying to parse +- tokens []Token +- +- // result of parsing +- named []*template.Template // the template and embedded templates +- ParseErr error +- symbols []symbol +- stack []parse.Node // used while computing symbols +- +- // for mapping from offsets in buf to LSP coordinates +- // See FromPosition() and LineCol() +- nls []int // offset of newlines before each line (nls[0]==-1) +- lastnl int // last line seen +- check int // used to decide whether to use lastnl or search through nls +- nonASCII bool // are there any non-ascii runes in buf? +-} +- +-// Token is a single {{...}}. More precisely, Left...Right +-type Token struct { +- Start, End int // offset from start of template +- Multiline bool +-} +- +-// All contains the Parse of all the template files +-type All struct { +- files map[span.URI]*Parsed +-} +- +-// New returns the Parses of the snapshot's tmpl files +-// (maybe cache these, but then avoiding import cycles needs code rearrangements) +-func New(tmpls map[span.URI]source.FileHandle) *All { +- all := make(map[span.URI]*Parsed) +- for k, v := range tmpls { +- buf, err := v.Content() +- if err != nil { // PJW: decide what to do with these errors +- log.Printf("failed to read %s (%v)", v.URI().Filename(), err) +- continue +- } +- all[k] = parseBuffer(buf) +- } +- return &All{files: all} +-} +- +-func parseBuffer(buf []byte) *Parsed { +- ans := &Parsed{ +- buf: buf, +- check: -1, +- nls: []int{-1}, +- } +- if len(buf) == 0 { +- return ans +- } +- // how to compute allAscii... +- for _, b := range buf { +- if b >= utf8.RuneSelf { +- ans.nonASCII = true +- break +- } +- } +- if buf[len(buf)-1] != '\n' { +- ans.buf = append(buf, '\n') +- } +- for i, p := range ans.buf { +- if p == '\n' { +- ans.nls = append(ans.nls, i) +- } +- } +- ans.setTokens() // ans.buf may be a new []byte +- ans.lines = bytes.Split(ans.buf, []byte{'\n'}) +- t, err := template.New("").Parse(string(ans.buf)) +- if err != nil { +- funcs := make(template.FuncMap) +- for t == nil && ans.ParseErr == nil { +- // in 1.17 it may be possible to avoid getting this error +- // template: :2: function "foo" not defined +- matches := parseErrR.FindStringSubmatch(err.Error()) +- if len(matches) == 2 { +- // suppress the error by giving it a function with the right name +- funcs[matches[1]] = func() interface{} { return nil } +- t, err = template.New("").Funcs(funcs).Parse(string(ans.buf)) +- continue +- } +- ans.ParseErr = err // unfixed error +- return ans +- } +- } +- ans.named = t.Templates() +- // set the symbols +- for _, t := range ans.named { +- ans.stack = append(ans.stack, t.Root) +- ans.findSymbols() +- if t.Name() != "" { +- // defining a template. The pos is just after {{define...}} (or {{block...}}?) +- at, sz := ans.FindLiteralBefore(int(t.Root.Pos)) +- s := symbol{start: at, length: sz, name: t.Name(), kind: protocol.Namespace, vardef: true} +- ans.symbols = append(ans.symbols, s) +- } +- } +- +- sort.Slice(ans.symbols, func(i, j int) bool { +- left, right := ans.symbols[i], ans.symbols[j] +- if left.start != right.start { +- return left.start < right.start +- } +- if left.vardef != right.vardef { +- return left.vardef +- } +- return left.kind < right.kind +- }) +- return ans +-} +- +-// FindLiteralBefore locates the first preceding string literal +-// returning its position and length in buf +-// or returns -1 if there is none. +-// Assume double-quoted string rather than backquoted string for now. +-func (p *Parsed) FindLiteralBefore(pos int) (int, int) { +- left, right := -1, -1 +- for i := pos - 1; i >= 0; i-- { +- if p.buf[i] != '"' { +- continue +- } +- if right == -1 { +- right = i +- continue +- } +- left = i +- break +- } +- if left == -1 { +- return -1, 0 +- } +- return left + 1, right - left - 1 +-} +- +-var ( +- parseErrR = regexp.MustCompile(`template:.*function "([^"]+)" not defined`) +-) +- +-func (p *Parsed) setTokens() { +- const ( +- // InRaw and InString only occur inside an action (SeenLeft) +- Start = iota +- InRaw +- InString +- SeenLeft +- ) +- state := Start +- var left, oldState int +- for n := 0; n < len(p.buf); n++ { +- c := p.buf[n] +- switch state { +- case InRaw: +- if c == '`' { +- state = oldState +- } +- case InString: +- if c == '"' && !isEscaped(p.buf[:n]) { +- state = oldState +- } +- case SeenLeft: +- if c == '`' { +- oldState = state // it's SeenLeft, but a little clearer this way +- state = InRaw +- continue +- } +- if c == '"' { +- oldState = state +- state = InString +- continue +- } +- if bytes.HasPrefix(p.buf[n:], Right) { +- right := n + len(Right) +- tok := Token{Start: left, +- End: right, +- Multiline: bytes.Contains(p.buf[left:right], []byte{'\n'}), +- } +- p.tokens = append(p.tokens, tok) +- state = Start +- } +- // If we see (unquoted) Left then the original left is probably the user +- // typing. Suppress the original left +- if bytes.HasPrefix(p.buf[n:], Left) { +- p.elideAt(left) +- left = n +- n += len(Left) - 1 // skip the rest +- } +- case Start: +- if bytes.HasPrefix(p.buf[n:], Left) { +- left = n +- state = SeenLeft +- n += len(Left) - 1 // skip the rest (avoids {{{ bug) +- } +- } +- } +- // this error occurs after typing {{ at the end of the file +- if state != Start { +- // Unclosed Left. remove the Left at left +- p.elideAt(left) +- } +-} +- +-func (p *Parsed) elideAt(left int) { +- if p.elided == nil { +- // p.buf is the same buffer that v.Read() returns, so copy it. +- // (otherwise the next time it's parsed, elided information is lost) +- b := make([]byte, len(p.buf)) +- copy(b, p.buf) +- p.buf = b +- } +- for i := 0; i < len(Left); i++ { +- p.buf[left+i] = ' ' +- } +- p.elided = append(p.elided, left) +-} +- +-// isEscaped reports whether the byte after buf is escaped +-func isEscaped(buf []byte) bool { +- backSlashes := 0 +- for j := len(buf) - 1; j >= 0 && buf[j] == '\\'; j-- { +- backSlashes++ +- } +- return backSlashes%2 == 1 +-} +- +-func (p *Parsed) Tokens() []Token { +- return p.tokens +-} +- +-// TODO(adonovan): the next 100 lines could perhaps replaced by use of protocol.Mapper. +- +-func (p *Parsed) utf16len(buf []byte) int { +- cnt := 0 +- if !p.nonASCII { +- return len(buf) +- } +- // we need a utf16len(rune), but we don't have it +- for _, r := range string(buf) { +- cnt++ +- if r >= 1<<16 { +- cnt++ +- } +- } +- return cnt +-} +- +-func (p *Parsed) TokenSize(t Token) (int, error) { +- if t.Multiline { +- return -1, fmt.Errorf("TokenSize called with Multiline token %#v", t) +- } +- ans := p.utf16len(p.buf[t.Start:t.End]) +- return ans, nil +-} +- +-// RuneCount counts runes in line l, from col s to e +-// (e==0 for end of line. called only for multiline tokens) +-func (p *Parsed) RuneCount(l, s, e uint32) uint32 { +- start := p.nls[l] + 1 + int(s) +- end := p.nls[l] + 1 + int(e) +- if e == 0 || end > p.nls[l+1] { +- end = p.nls[l+1] +- } +- return uint32(utf8.RuneCount(p.buf[start:end])) +-} +- +-// LineCol converts from a 0-based byte offset to 0-based line, col. col in runes +-func (p *Parsed) LineCol(x int) (uint32, uint32) { +- if x < p.check { +- p.lastnl = 0 +- } +- p.check = x +- for i := p.lastnl; i < len(p.nls); i++ { +- if p.nls[i] <= x { +- continue +- } +- p.lastnl = i +- var count int +- if i > 0 && x == p.nls[i-1] { // \n +- count = 0 +- } else { +- count = p.utf16len(p.buf[p.nls[i-1]+1 : x]) +- } +- return uint32(i - 1), uint32(count) +- } +- if x == len(p.buf)-1 { // trailing \n +- return uint32(len(p.nls) - 1), 0 +- } +- // shouldn't happen +- for i := 1; i < 4; i++ { +- _, f, l, ok := runtime.Caller(i) +- if !ok { +- break +- } +- log.Printf("%d: %s:%d", i, f, l) +- } +- +- msg := fmt.Errorf("LineCol off the end, %d of %d, nls=%v, %q", x, len(p.buf), p.nls, p.buf[x:]) +- event.Error(context.Background(), "internal error", msg) +- return 0, 0 +-} +- +-// Position produces a protocol.Position from an offset in the template +-func (p *Parsed) Position(pos int) protocol.Position { +- line, col := p.LineCol(pos) +- return protocol.Position{Line: line, Character: col} +-} +- +-func (p *Parsed) Range(x, length int) protocol.Range { +- line, col := p.LineCol(x) +- ans := protocol.Range{ +- Start: protocol.Position{Line: line, Character: col}, +- End: protocol.Position{Line: line, Character: col + uint32(length)}, +- } +- return ans +-} +- +-// FromPosition translates a protocol.Position into an offset into the template +-func (p *Parsed) FromPosition(x protocol.Position) int { +- l, c := int(x.Line), int(x.Character) +- if l >= len(p.nls) || p.nls[l]+1 >= len(p.buf) { +- // paranoia to avoid panic. return the largest offset +- return len(p.buf) +- } +- line := p.buf[p.nls[l]+1:] +- cnt := 0 +- for w := range string(line) { +- if cnt >= c { +- return w + p.nls[l] + 1 +- } +- cnt++ +- } +- // do we get here? NO +- pos := int(x.Character) + p.nls[int(x.Line)] + 1 +- event.Error(context.Background(), "internal error", fmt.Errorf("surprise %#v", x)) +- return pos +-} +- +-func symAtPosition(fh source.FileHandle, loc protocol.Position) (*symbol, *Parsed, error) { +- buf, err := fh.Content() +- if err != nil { +- return nil, nil, err +- } +- p := parseBuffer(buf) +- pos := p.FromPosition(loc) +- syms := p.SymsAtPos(pos) +- if len(syms) == 0 { +- return nil, p, fmt.Errorf("no symbol found") +- } +- if len(syms) > 1 { +- log.Printf("Hover: %d syms, not 1 %v", len(syms), syms) +- } +- sym := syms[0] +- return &sym, p, nil +-} +- +-func (p *Parsed) SymsAtPos(pos int) []symbol { +- ans := []symbol{} +- for _, s := range p.symbols { +- if s.start <= pos && pos < s.start+s.length { +- ans = append(ans, s) +- } +- } +- return ans +-} +- +-type wrNode struct { +- p *Parsed +- w io.Writer +-} +- +-// WriteNode is for debugging +-func (p *Parsed) WriteNode(w io.Writer, n parse.Node) { +- wr := wrNode{p: p, w: w} +- wr.writeNode(n, "") +-} +- +-func (wr wrNode) writeNode(n parse.Node, indent string) { +- if n == nil { +- return +- } +- at := func(pos parse.Pos) string { +- line, col := wr.p.LineCol(int(pos)) +- return fmt.Sprintf("(%d)%v:%v", pos, line, col) +- } +- switch x := n.(type) { +- case *parse.ActionNode: +- fmt.Fprintf(wr.w, "%sActionNode at %s\n", indent, at(x.Pos)) +- wr.writeNode(x.Pipe, indent+". ") +- case *parse.BoolNode: +- fmt.Fprintf(wr.w, "%sBoolNode at %s, %v\n", indent, at(x.Pos), x.True) +- case *parse.BranchNode: +- fmt.Fprintf(wr.w, "%sBranchNode at %s\n", indent, at(x.Pos)) +- wr.writeNode(x.Pipe, indent+"Pipe. ") +- wr.writeNode(x.List, indent+"List. ") +- wr.writeNode(x.ElseList, indent+"Else. ") +- case *parse.ChainNode: +- fmt.Fprintf(wr.w, "%sChainNode at %s, %v\n", indent, at(x.Pos), x.Field) +- case *parse.CommandNode: +- fmt.Fprintf(wr.w, "%sCommandNode at %s, %d children\n", indent, at(x.Pos), len(x.Args)) +- for _, a := range x.Args { +- wr.writeNode(a, indent+". ") +- } +- //case *parse.CommentNode: // 1.16 +- case *parse.DotNode: +- fmt.Fprintf(wr.w, "%sDotNode at %s\n", indent, at(x.Pos)) +- case *parse.FieldNode: +- fmt.Fprintf(wr.w, "%sFieldNode at %s, %v\n", indent, at(x.Pos), x.Ident) +- case *parse.IdentifierNode: +- fmt.Fprintf(wr.w, "%sIdentifierNode at %s, %v\n", indent, at(x.Pos), x.Ident) +- case *parse.IfNode: +- fmt.Fprintf(wr.w, "%sIfNode at %s\n", indent, at(x.Pos)) +- wr.writeNode(&x.BranchNode, indent+". ") +- case *parse.ListNode: +- if x == nil { +- return // nil BranchNode.ElseList +- } +- fmt.Fprintf(wr.w, "%sListNode at %s, %d children\n", indent, at(x.Pos), len(x.Nodes)) +- for _, n := range x.Nodes { +- wr.writeNode(n, indent+". ") +- } +- case *parse.NilNode: +- fmt.Fprintf(wr.w, "%sNilNode at %s\n", indent, at(x.Pos)) +- case *parse.NumberNode: +- fmt.Fprintf(wr.w, "%sNumberNode at %s, %s\n", indent, at(x.Pos), x.Text) +- case *parse.PipeNode: +- if x == nil { +- return // {{template "xxx"}} +- } +- fmt.Fprintf(wr.w, "%sPipeNode at %s, %d vars, %d cmds, IsAssign:%v\n", +- indent, at(x.Pos), len(x.Decl), len(x.Cmds), x.IsAssign) +- for _, d := range x.Decl { +- wr.writeNode(d, indent+"Decl. ") +- } +- for _, c := range x.Cmds { +- wr.writeNode(c, indent+"Cmd. ") +- } +- case *parse.RangeNode: +- fmt.Fprintf(wr.w, "%sRangeNode at %s\n", indent, at(x.Pos)) +- wr.writeNode(&x.BranchNode, indent+". ") +- case *parse.StringNode: +- fmt.Fprintf(wr.w, "%sStringNode at %s, %s\n", indent, at(x.Pos), x.Quoted) +- case *parse.TemplateNode: +- fmt.Fprintf(wr.w, "%sTemplateNode at %s, %s\n", indent, at(x.Pos), x.Name) +- wr.writeNode(x.Pipe, indent+". ") +- case *parse.TextNode: +- fmt.Fprintf(wr.w, "%sTextNode at %s, len %d\n", indent, at(x.Pos), len(x.Text)) +- case *parse.VariableNode: +- fmt.Fprintf(wr.w, "%sVariableNode at %s, %v\n", indent, at(x.Pos), x.Ident) +- case *parse.WithNode: +- fmt.Fprintf(wr.w, "%sWithNode at %s\n", indent, at(x.Pos)) +- wr.writeNode(&x.BranchNode, indent+". ") +- } +-} +- +-var kindNames = []string{"", "File", "Module", "Namespace", "Package", "Class", "Method", "Property", +- "Field", "Constructor", "Enum", "Interface", "Function", "Variable", "Constant", "String", +- "Number", "Boolean", "Array", "Object", "Key", "Null", "EnumMember", "Struct", "Event", +- "Operator", "TypeParameter"} +- +-func kindStr(k protocol.SymbolKind) string { +- n := int(k) +- if n < 1 || n >= len(kindNames) { +- return fmt.Sprintf("?SymbolKind %d?", n) +- } +- return kindNames[n] +-} +diff -urN a/gopls/internal/lsp/template/parse_test.go b/gopls/internal/lsp/template/parse_test.go +--- a/gopls/internal/lsp/template/parse_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/template/parse_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,238 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package template +- +-import ( +- "strings" +- "testing" +-) +- +-type datum struct { +- buf string +- cnt int +- syms []string // the symbols in the parse of buf +-} +- +-var tmpl = []datum{{` +-{{if (foo .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} +-{{$A.X 12}} +-{{foo (.X.Y) 23 ($A.Zü)}} +-{{end}}`, 1, []string{"{7,3,foo,Function,false}", "{12,1,X,Method,false}", +- "{14,1,Y,Method,false}", "{21,2,$A,Variable,true}", "{26,2,,String,false}", +- "{35,1,Z,Method,false}", "{38,2,$A,Variable,false}", +- "{53,2,$A,Variable,false}", "{56,1,X,Method,false}", "{57,2,,Number,false}", +- "{64,3,foo,Function,false}", "{70,1,X,Method,false}", +- "{72,1,Y,Method,false}", "{75,2,,Number,false}", "{80,2,$A,Variable,false}", +- "{83,2,Zü,Method,false}", "{94,3,,Constant,false}"}}, +- +- {`{{define "zzz"}}{{.}}{{end}} +-{{template "zzz"}}`, 2, []string{"{10,3,zzz,Namespace,true}", "{18,1,dot,Variable,false}", +- "{41,3,zzz,Package,false}"}}, +- +- {`{{block "aaa" foo}}b{{end}}`, 2, []string{"{9,3,aaa,Namespace,true}", +- "{9,3,aaa,Package,false}", "{14,3,foo,Function,false}", "{19,1,,Constant,false}"}}, +- {"", 0, nil}, +-} +- +-func TestSymbols(t *testing.T) { +- for i, x := range tmpl { +- got := parseBuffer([]byte(x.buf)) +- if got.ParseErr != nil { +- t.Errorf("error:%v", got.ParseErr) +- continue +- } +- if len(got.named) != x.cnt { +- t.Errorf("%d: got %d, expected %d", i, len(got.named), x.cnt) +- } +- for n, s := range got.symbols { +- if s.String() != x.syms[n] { +- t.Errorf("%d: got %s, expected %s", i, s.String(), x.syms[n]) +- } +- } +- } +-} +- +-func TestWordAt(t *testing.T) { +- want := []string{"", "", "$A", "$A", "", "", "", "", "", "", +- "", "", "", "if", "if", "", "$A", "$A", "", "", +- "B", "", "", "end", "end", "end", "", "", ""} +- p := parseBuffer([]byte("{{$A := .}}{{if $A}}B{{end}}")) +- for i := 0; i < len(p.buf); i++ { +- got := findWordAt(p, i) +- if got != want[i] { +- t.Errorf("for %d, got %q, wanted %q", i, got, want[i]) +- } +- } +-} +- +-func TestNLS(t *testing.T) { +- buf := `{{if (foÜx .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} +- {{$A.X 12}} +- {{foo (.X.Y) 23 ($A.Z)}} +- {{end}} +- ` +- p := parseBuffer([]byte(buf)) +- if p.ParseErr != nil { +- t.Fatal(p.ParseErr) +- } +- // line 0 doesn't have a \n in front of it +- for i := 1; i < len(p.nls)-1; i++ { +- if buf[p.nls[i]] != '\n' { +- t.Errorf("line %d got %c", i, buf[p.nls[i]]) +- } +- } +- // fake line at end of file +- if p.nls[len(p.nls)-1] != len(buf) { +- t.Errorf("got %d expected %d", p.nls[len(p.nls)-1], len(buf)) +- } +-} +- +-func TestLineCol(t *testing.T) { +- buf := `{{if (foÜx .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} +- {{$A.X 12}} +- {{foo (.X.Y) 23 ($A.Z)}} +- {{end}}` +- if false { +- t.Error(buf) +- } +- for n, cx := range tmpl { +- buf := cx.buf +- p := parseBuffer([]byte(buf)) +- if p.ParseErr != nil { +- t.Fatal(p.ParseErr) +- } +- type loc struct { +- offset int +- l, c uint32 +- } +- saved := []loc{} +- // forwards +- var lastl, lastc uint32 +- for offset := range buf { +- l, c := p.LineCol(offset) +- saved = append(saved, loc{offset, l, c}) +- if l > lastl { +- lastl = l +- if c != 0 { +- t.Errorf("line %d, got %d instead of 0", l, c) +- } +- } +- if c > lastc { +- lastc = c +- } +- } +- lines := strings.Split(buf, "\n") +- mxlen := -1 +- for _, l := range lines { +- if len(l) > mxlen { +- mxlen = len(l) +- } +- } +- if int(lastl) != len(lines)-1 && int(lastc) != mxlen { +- // lastl is 0 if there is only 1 line(?) +- t.Errorf("expected %d, %d, got %d, %d for case %d", len(lines)-1, mxlen, lastl, lastc, n) +- } +- // backwards +- for j := len(saved) - 1; j >= 0; j-- { +- s := saved[j] +- xl, xc := p.LineCol(s.offset) +- if xl != s.l || xc != s.c { +- t.Errorf("at offset %d(%d), got (%d,%d), expected (%d,%d)", s.offset, j, xl, xc, s.l, s.c) +- } +- } +- } +-} +- +-func TestLineColNL(t *testing.T) { +- buf := "\n\n\n\n\n" +- p := parseBuffer([]byte(buf)) +- if p.ParseErr != nil { +- t.Fatal(p.ParseErr) +- } +- for i := 0; i < len(buf); i++ { +- l, c := p.LineCol(i) +- if c != 0 || int(l) != i+1 { +- t.Errorf("got (%d,%d), expected (%d,0)", l, c, i) +- } +- } +-} +- +-func TestPos(t *testing.T) { +- buf := ` +- {{if (foÜx .X.Y)}}{{$A := "hi"}}{{.Z $A}}{{else}} +- {{$A.X 12}} +- {{foo (.X.Y) 23 ($A.Z)}} +- {{end}}` +- p := parseBuffer([]byte(buf)) +- if p.ParseErr != nil { +- t.Fatal(p.ParseErr) +- } +- for pos, r := range buf { +- if r == '\n' { +- continue +- } +- x := p.Position(pos) +- n := p.FromPosition(x) +- if n != pos { +- // once it's wrong, it will be wrong forever +- t.Fatalf("at pos %d (rune %c) got %d {%#v]", pos, r, n, x) +- } +- +- } +-} +-func TestLen(t *testing.T) { +- data := []struct { +- cnt int +- v string +- }{{1, "a"}, {1, "膈"}, {4, "😆🥸"}, {7, "3😀4567"}} +- p := &Parsed{nonASCII: true} +- for _, d := range data { +- got := p.utf16len([]byte(d.v)) +- if got != d.cnt { +- t.Errorf("%v, got %d wanted %d", d, got, d.cnt) +- } +- } +-} +- +-func TestUtf16(t *testing.T) { +- buf := ` +- {{if (foÜx .X.Y)}}😀{{$A := "hi"}}{{.Z $A}}{{else}} +- {{$A.X 12}} +- {{foo (.X.Y) 23 ($A.Z)}} +- {{end}}` +- p := parseBuffer([]byte(buf)) +- if p.nonASCII == false { +- t.Error("expected nonASCII to be true") +- } +-} +- +-type ttest struct { +- tmpl string +- tokCnt int +- elidedCnt int8 +-} +- +-func TestQuotes(t *testing.T) { +- tsts := []ttest{ +- {"{{- /*comment*/ -}}", 1, 0}, +- {"{{/*`\ncomment\n`*/}}", 1, 0}, +- //{"{{foo\nbar}}\n", 1, 0}, // this action spanning lines parses in 1.16 +- {"{{\"{{foo}}{{\"}}", 1, 0}, +- {"{{\n{{- when}}", 1, 1}, // corrected +- {"{{{{if .}}xx{{\n{{end}}", 2, 2}, // corrected +- } +- for _, s := range tsts { +- p := parseBuffer([]byte(s.tmpl)) +- if len(p.tokens) != s.tokCnt { +- t.Errorf("%q: got %d tokens, expected %d", s, len(p.tokens), s.tokCnt) +- } +- if p.ParseErr != nil { +- t.Errorf("%q: %v", string(p.buf), p.ParseErr) +- } +- if len(p.elided) != int(s.elidedCnt) { +- t.Errorf("%q: elided %d, expected %d", s, len(p.elided), s.elidedCnt) +- } +- } +-} +diff -urN a/gopls/internal/lsp/template/symbols.go b/gopls/internal/lsp/template/symbols.go +--- a/gopls/internal/lsp/template/symbols.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/template/symbols.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,230 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package template +- +-import ( +- "bytes" +- "context" +- "fmt" +- "text/template/parse" +- "unicode/utf8" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +-) +- +-// in local coordinates, to be translated to protocol.DocumentSymbol +-type symbol struct { +- start int // for sorting +- length int // in runes (unicode code points) +- name string +- kind protocol.SymbolKind +- vardef bool // is this a variable definition? +- // do we care about selection range, or children? +- // no children yet, and selection range is the same as range +-} +- +-func (s symbol) String() string { +- return fmt.Sprintf("{%d,%d,%s,%s,%v}", s.start, s.length, s.name, s.kind, s.vardef) +-} +- +-// for FieldNode or VariableNode (or ChainNode?) +-func (p *Parsed) fields(flds []string, x parse.Node) []symbol { +- ans := []symbol{} +- // guessing that there are no embedded blanks allowed. The doc is unclear +- lookfor := "" +- switch x.(type) { +- case *parse.FieldNode: +- for _, f := range flds { +- lookfor += "." + f // quadratic, but probably ok +- } +- case *parse.VariableNode: +- lookfor = flds[0] +- for i := 1; i < len(flds); i++ { +- lookfor += "." + flds[i] +- } +- case *parse.ChainNode: // PJW, what are these? +- for _, f := range flds { +- lookfor += "." + f // quadratic, but probably ok +- } +- default: +- // If these happen they will happen even if gopls is restarted +- // and the users does the same thing, so it is better not to panic. +- // context.Background() is used because we don't have access +- // to any other context. [we could, but it would be complicated] +- event.Log(context.Background(), fmt.Sprintf("%T unexpected in fields()", x)) +- return nil +- } +- if len(lookfor) == 0 { +- event.Log(context.Background(), fmt.Sprintf("no strings in fields() %#v", x)) +- return nil +- } +- startsAt := int(x.Position()) +- ix := bytes.Index(p.buf[startsAt:], []byte(lookfor)) // HasPrefix? PJW? +- if ix < 0 || ix > len(lookfor) { // lookfor expected to be at start (or so) +- // probably golang.go/#43388, so back up +- startsAt -= len(flds[0]) + 1 +- ix = bytes.Index(p.buf[startsAt:], []byte(lookfor)) // ix might be 1? PJW +- if ix < 0 { +- return ans +- } +- } +- at := ix + startsAt +- for _, f := range flds { +- at += 1 // . +- kind := protocol.Method +- if f[0] == '$' { +- kind = protocol.Variable +- } +- sym := symbol{name: f, kind: kind, start: at, length: utf8.RuneCount([]byte(f))} +- if kind == protocol.Variable && len(p.stack) > 1 { +- if pipe, ok := p.stack[len(p.stack)-2].(*parse.PipeNode); ok { +- for _, y := range pipe.Decl { +- if x == y { +- sym.vardef = true +- } +- } +- } +- } +- ans = append(ans, sym) +- at += len(f) +- } +- return ans +-} +- +-func (p *Parsed) findSymbols() { +- if len(p.stack) == 0 { +- return +- } +- n := p.stack[len(p.stack)-1] +- pop := func() { +- p.stack = p.stack[:len(p.stack)-1] +- } +- if n == nil { // allowing nil simplifies the code +- pop() +- return +- } +- nxt := func(nd parse.Node) { +- p.stack = append(p.stack, nd) +- p.findSymbols() +- } +- switch x := n.(type) { +- case *parse.ActionNode: +- nxt(x.Pipe) +- case *parse.BoolNode: +- // need to compute the length from the value +- msg := fmt.Sprintf("%v", x.True) +- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: len(msg), kind: protocol.Boolean}) +- case *parse.BranchNode: +- nxt(x.Pipe) +- nxt(x.List) +- nxt(x.ElseList) +- case *parse.ChainNode: +- p.symbols = append(p.symbols, p.fields(x.Field, x)...) +- nxt(x.Node) +- case *parse.CommandNode: +- for _, a := range x.Args { +- nxt(a) +- } +- //case *parse.CommentNode: // go 1.16 +- // log.Printf("implement %d", x.Type()) +- case *parse.DotNode: +- sym := symbol{name: "dot", kind: protocol.Variable, start: int(x.Pos), length: 1} +- p.symbols = append(p.symbols, sym) +- case *parse.FieldNode: +- p.symbols = append(p.symbols, p.fields(x.Ident, x)...) +- case *parse.IdentifierNode: +- sym := symbol{name: x.Ident, kind: protocol.Function, start: int(x.Pos), +- length: utf8.RuneCount([]byte(x.Ident))} +- p.symbols = append(p.symbols, sym) +- case *parse.IfNode: +- nxt(&x.BranchNode) +- case *parse.ListNode: +- if x != nil { // wretched typed nils. Node should have an IfNil +- for _, nd := range x.Nodes { +- nxt(nd) +- } +- } +- case *parse.NilNode: +- sym := symbol{name: "nil", kind: protocol.Constant, start: int(x.Pos), length: 3} +- p.symbols = append(p.symbols, sym) +- case *parse.NumberNode: +- // no name; ascii +- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: len(x.Text), kind: protocol.Number}) +- case *parse.PipeNode: +- if x == nil { // {{template "foo"}} +- return +- } +- for _, d := range x.Decl { +- nxt(d) +- } +- for _, c := range x.Cmds { +- nxt(c) +- } +- case *parse.RangeNode: +- nxt(&x.BranchNode) +- case *parse.StringNode: +- // no name +- sz := utf8.RuneCount([]byte(x.Text)) +- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: sz, kind: protocol.String}) +- case *parse.TemplateNode: // invoking a template +- // x.Pos points to the quote before the name +- p.symbols = append(p.symbols, symbol{name: x.Name, kind: protocol.Package, start: int(x.Pos) + 1, +- length: utf8.RuneCount([]byte(x.Name))}) +- nxt(x.Pipe) +- case *parse.TextNode: +- if len(x.Text) == 1 && x.Text[0] == '\n' { +- break +- } +- // nothing to report, but build one for hover +- sz := utf8.RuneCount([]byte(x.Text)) +- p.symbols = append(p.symbols, symbol{start: int(x.Pos), length: sz, kind: protocol.Constant}) +- case *parse.VariableNode: +- p.symbols = append(p.symbols, p.fields(x.Ident, x)...) +- case *parse.WithNode: +- nxt(&x.BranchNode) +- +- } +- pop() +-} +- +-// DocumentSymbols returns a hierarchy of the symbols defined in a template file. +-// (The hierarchy is flat. SymbolInformation might be better.) +-func DocumentSymbols(snapshot source.Snapshot, fh source.FileHandle) ([]protocol.DocumentSymbol, error) { +- buf, err := fh.Content() +- if err != nil { +- return nil, err +- } +- p := parseBuffer(buf) +- if p.ParseErr != nil { +- return nil, p.ParseErr +- } +- var ans []protocol.DocumentSymbol +- for _, s := range p.symbols { +- if s.kind == protocol.Constant { +- continue +- } +- d := kindStr(s.kind) +- if d == "Namespace" { +- d = "Template" +- } +- if s.vardef { +- d += "(def)" +- } else { +- d += "(use)" +- } +- r := p.Range(s.start, s.length) +- y := protocol.DocumentSymbol{ +- Name: s.name, +- Detail: d, +- Kind: s.kind, +- Range: r, +- SelectionRange: r, // or should this be the entire {{...}}? +- } +- ans = append(ans, y) +- } +- return ans, nil +-} +diff -urN a/gopls/internal/lsp/testdata/addimport/addimport.go.golden b/gopls/internal/lsp/testdata/addimport/addimport.go.golden +--- a/gopls/internal/lsp/testdata/addimport/addimport.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/addimport/addimport.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +--- addimport -- +-package addimport //@addimport("", "bytes") +- +-import "bytes" +- +-func main() {} +- +diff -urN a/gopls/internal/lsp/testdata/addimport/addimport.go.in b/gopls/internal/lsp/testdata/addimport/addimport.go.in +--- a/gopls/internal/lsp/testdata/addimport/addimport.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/addimport/addimport.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +-package addimport //@addimport("", "bytes") +- +-func main() {} +diff -urN a/gopls/internal/lsp/testdata/address/address.go b/gopls/internal/lsp/testdata/address/address.go +--- a/gopls/internal/lsp/testdata/address/address.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/address/address.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,78 +0,0 @@ +-package address +- +-func wantsPtr(*int) {} +-func wantsVariadicPtr(...*int) {} +- +-func wantsVariadic(...int) {} +- +-type foo struct{ c int } //@item(addrFieldC, "c", "int", "field") +- +-func _() { +- var ( +- a string //@item(addrA, "a", "string", "var") +- b int //@item(addrB, "b", "int", "var") +- ) +- +- wantsPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b", "&b") +- wantsPtr(&b) //@snippet(")", addrB, "b", "b") +- +- wantsVariadicPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b", "&b") +- +- var s foo +- s.c //@item(addrDeepC, "s.c", "int", "field") +- wantsPtr() //@snippet(")", addrDeepC, "&s.c", "&s.c") +- wantsPtr(s) //@snippet(")", addrDeepC, "&s.c", "&s.c") +- wantsPtr(&s) //@snippet(")", addrDeepC, "s.c", "s.c") +- +- // don't add "&" in item (it gets added as an additional edit) +- wantsPtr(&s.c) //@snippet(")", addrFieldC, "c", "c") +- +- // check dereferencing as well +- var c *int //@item(addrCPtr, "c", "*int", "var") +- var _ int = _ //@rank("_ //", addrCPtr, addrA),snippet("_ //", addrCPtr, "*c", "*c") +- +- wantsVariadic() //@rank(")", addrCPtr, addrA),snippet(")", addrCPtr, "*c", "*c") +- +- var d **int //@item(addrDPtr, "d", "**int", "var") +- var _ int = _ //@rank("_ //", addrDPtr, addrA),snippet("_ //", addrDPtr, "**d", "**d") +- +- type namedPtr *int +- var np namedPtr //@item(addrNamedPtr, "np", "namedPtr", "var") +- +- var _ int = _ //@rank("_ //", addrNamedPtr, addrA) +- +- // don't get tripped up by recursive pointer type +- type dontMessUp *dontMessUp +- var dmu *dontMessUp //@item(addrDMU, "dmu", "*dontMessUp", "var") +- +- var _ int = dmu //@complete(" //", addrDMU) +-} +- +-func (f foo) ptr() *foo { return &f } +- +-func _() { +- getFoo := func() foo { return foo{} } +- +- // not addressable +- getFoo().c //@item(addrGetFooC, "getFoo().c", "int", "field") +- +- // addressable +- getFoo().ptr().c //@item(addrGetFooPtrC, "getFoo().ptr().c", "int", "field") +- +- wantsPtr() //@rank(addrGetFooPtrC, addrGetFooC),snippet(")", addrGetFooPtrC, "&getFoo().ptr().c", "&getFoo().ptr().c") +- wantsPtr(&g) //@rank(addrGetFooPtrC, addrGetFooC),snippet(")", addrGetFooPtrC, "getFoo().ptr().c", "getFoo().ptr().c") +-} +- +-type nested struct { +- f foo +-} +- +-func _() { +- getNested := func() nested { return nested{} } +- +- getNested().f.c //@item(addrNestedC, "getNested().f.c", "int", "field") +- getNested().f.ptr().c //@item(addrNestedPtrC, "getNested().f.ptr().c", "int", "field") +- +- // addrNestedC is not addressable, so rank lower +- wantsPtr(getNestedfc) //@fuzzy(")", addrNestedPtrC, addrNestedC) +-} +diff -urN a/gopls/internal/lsp/testdata/anon/anon.go.in b/gopls/internal/lsp/testdata/anon/anon.go.in +--- a/gopls/internal/lsp/testdata/anon/anon.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/anon/anon.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,23 +0,0 @@ +-package anon +- +-func _() { +- for _, _ := range []struct { +- i, j int //@item(anonI, "i", "int", "field"),item(anonJ, "j", "int", "field") +- }{ +- { +- i: 1, +- //@complete("", anonJ) +- }, +- { +- //@complete("", anonI, anonJ) +- }, +- } { +- continue +- } +- +- s := struct{ f int }{ } //@item(anonF, "f", "int", "field"),item(structS, "s", "struct{...}", "var"),complete(" }", anonF) +- +- _ = map[struct{ x int }]int{ //@item(anonX, "x", "int", "field") +- struct{ x int }{ }: 1, //@complete(" }", anonX, structS) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/append/append2.go.in b/gopls/internal/lsp/testdata/append/append2.go.in +--- a/gopls/internal/lsp/testdata/append/append2.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/append/append2.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +-package append +- +-func _() { +- _ = append(a, struct) //@complete(")") +-} +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/append/append.go b/gopls/internal/lsp/testdata/append/append.go +--- a/gopls/internal/lsp/testdata/append/append.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/append/append.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-package append +- +-func foo([]string) {} +-func bar(...string) {} +- +-func _() { +- var ( +- aInt []int //@item(appendInt, "aInt", "[]int", "var") +- aStrings []string //@item(appendStrings, "aStrings", "[]string", "var") +- aString string //@item(appendString, "aString", "string", "var") +- ) +- +- append(aStrings, a) //@rank(")", appendString, appendInt) +- var _ interface{} = append(aStrings, a) //@rank(")", appendString, appendInt) +- var _ []string = append(oops, a) //@rank(")", appendString, appendInt) +- +- foo(append()) //@rank("))", appendStrings, appendInt),rank("))", appendStrings, appendString) +- foo(append([]string{}, a)) //@rank("))", appendStrings, appendInt),rank("))", appendString, appendInt),snippet("))", appendStrings, "aStrings...", "aStrings...") +- foo(append([]string{}, "", a)) //@rank("))", appendString, appendInt),rank("))", appendString, appendStrings) +- +- // Don't add "..." to append() argument. +- bar(append()) //@snippet("))", appendStrings, "aStrings", "aStrings") +- +- type baz struct{} +- baz{} //@item(appendBazLiteral, "baz{}", "", "var") +- var bazzes []baz //@item(appendBazzes, "bazzes", "[]baz", "var") +- var bazzy baz //@item(appendBazzy, "bazzy", "baz", "var") +- bazzes = append(bazzes, ba) //@rank(")", appendBazzy, appendBazLiteral, appendBazzes) +- +- var b struct{ b []baz } +- b.b //@item(appendNestedBaz, "b.b", "[]baz", "field") +- b.b = append(b.b, b) //@rank(")", appendBazzy, appendBazLiteral, appendNestedBaz) +- +- var aStringsPtr *[]string //@item(appendStringsPtr, "aStringsPtr", "*[]string", "var") +- foo(append([]string{}, a)) //@snippet("))", appendStringsPtr, "*aStringsPtr...", "*aStringsPtr...") +- +- foo(append([]string{}, *a)) //@snippet("))", appendStringsPtr, "aStringsPtr...", "aStringsPtr...") +-} +diff -urN a/gopls/internal/lsp/testdata/arraytype/array_type.go.in b/gopls/internal/lsp/testdata/arraytype/array_type.go.in +--- a/gopls/internal/lsp/testdata/arraytype/array_type.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/arraytype/array_type.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,50 +0,0 @@ +-package arraytype +- +-import ( +- "golang.org/lsptests/foo" +-) +- +-func _() { +- var ( +- val string //@item(atVal, "val", "string", "var") +- ) +- +- // disabled - see issue #54822 +- [] // complete(" //", PackageFoo) +- +- []val //@complete(" //") +- +- []foo.StructFoo //@complete(" //", StructFoo) +- +- []foo.StructFoo(nil) //@complete("(", StructFoo) +- +- []*foo.StructFoo //@complete(" //", StructFoo) +- +- [...]foo.StructFoo //@complete(" //", StructFoo) +- +- [2][][4]foo.StructFoo //@complete(" //", StructFoo) +- +- []struct { f []foo.StructFoo } //@complete(" }", StructFoo) +-} +- +-func _() { +- type myInt int //@item(atMyInt, "myInt", "int", "type") +- +- var mark []myInt //@item(atMark, "mark", "[]myInt", "var") +- +- var s []myInt //@item(atS, "s", "[]myInt", "var") +- s = []m //@complete(" //", atMyInt) +- // disabled - see issue #54822 +- s = [] // complete(" //", atMyInt, PackageFoo) +- +- var a [1]myInt +- a = [1]m //@complete(" //", atMyInt) +- +- var ds [][]myInt +- ds = [][]m //@complete(" //", atMyInt) +-} +- +-func _() { +- var b [0]byte //@item(atByte, "b", "[0]byte", "var") +- var _ []byte = b //@snippet(" //", atByte, "b[:]", "b[:]") +-} +diff -urN a/gopls/internal/lsp/testdata/assign/assign.go.in b/gopls/internal/lsp/testdata/assign/assign.go.in +--- a/gopls/internal/lsp/testdata/assign/assign.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/assign/assign.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +-package assign +- +-import "golang.org/lsptests/assign/internal/secret" +- +-func _() { +- secret.Hello() +- var ( +- myInt int //@item(assignInt, "myInt", "int", "var") +- myStr string //@item(assignStr, "myStr", "string", "var") +- ) +- +- var _ string = my //@rank(" //", assignStr, assignInt) +- var _ string = //@rank(" //", assignStr, assignInt) +-} +- +-func _() { +- var a string = a //@complete(" //") +-} +- +-func _() { +- fooBar := fooBa //@complete(" //"),item(assignFooBar, "fooBar", "", "var") +- abc, fooBar := 123, fooBa //@complete(" //", assignFooBar) +- { +- fooBar := fooBa //@complete(" //", assignFooBar) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/assign/internal/secret/secret.go b/gopls/internal/lsp/testdata/assign/internal/secret/secret.go +--- a/gopls/internal/lsp/testdata/assign/internal/secret/secret.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/assign/internal/secret/secret.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +-package secret +- +-func Hello() {} +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/bad/bad0_go120.go b/gopls/internal/lsp/testdata/bad/bad0_go120.go +--- a/gopls/internal/lsp/testdata/bad/bad0_go120.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/bad/bad0_go120.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-//go:build go1.11 && !go1.21 +-// +build go1.11,!go1.21 +- +-package bad +- +-import _ "golang.org/lsptests/assign/internal/secret" //@diag("\"golang.org/lsptests/assign/internal/secret\"", "compiler", "could not import golang.org/lsptests/assign/internal/secret \\(invalid use of internal package \"golang.org/lsptests/assign/internal/secret\"\\)", "error") +- +-func stuff() { //@item(stuff, "stuff", "func()", "func") +- x := "heeeeyyyy" +- random2(x) //@diag("x", "compiler", "cannot use x \\(variable of type string\\) as int value in argument to random2", "error") +- random2(1) //@complete("dom", random, random2, random3) +- y := 3 //@diag("y", "compiler", "y declared (and|but) not used", "error") +-} +- +-type bob struct { //@item(bob, "bob", "struct{...}", "struct") +- x int +-} +- +-func _() { +- var q int +- _ = &bob{ +- f: q, //@diag("f: q", "compiler", "unknown field f in struct literal", "error") +- } +-} +diff -urN a/gopls/internal/lsp/testdata/bad/bad0_go121.go b/gopls/internal/lsp/testdata/bad/bad0_go121.go +--- a/gopls/internal/lsp/testdata/bad/bad0_go121.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/bad/bad0_go121.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +-//go:build go1.21 +-// +build go1.21 +- +-package bad +- +-// TODO(matloob): uncomment this and remove the space between the // and the @diag +-// once the changes that produce the new go list error are submitted. +-import _ "golang.org/lsptests/assign/internal/secret" //@diag("\"golang.org/lsptests/assign/internal/secret\"", "compiler", "could not import golang.org/lsptests/assign/internal/secret \\(invalid use of internal package \"golang.org/lsptests/assign/internal/secret\"\\)", "error"),diag("_", "go list", "use of internal package golang.org/lsptests/assign/internal/secret not allowed", "error") +- +-func stuff() { //@item(stuff, "stuff", "func()", "func") +- x := "heeeeyyyy" +- random2(x) //@diag("x", "compiler", "cannot use x \\(variable of type string\\) as int value in argument to random2", "error") +- random2(1) //@complete("dom", random, random2, random3) +- y := 3 //@diag("y", "compiler", "y declared (and|but) not used", "error") +-} +- +-type bob struct { //@item(bob, "bob", "struct{...}", "struct") +- x int +-} +- +-func _() { +- var q int +- _ = &bob{ +- f: q, //@diag("f: q", "compiler", "unknown field f in struct literal", "error") +- } +-} +diff -urN a/gopls/internal/lsp/testdata/bad/bad1.go b/gopls/internal/lsp/testdata/bad/bad1.go +--- a/gopls/internal/lsp/testdata/bad/bad1.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/bad/bad1.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,34 +0,0 @@ +-//go:build go1.11 +-// +build go1.11 +- +-package bad +- +-// See #36637 +-type stateFunc func() stateFunc //@item(stateFunc, "stateFunc", "func() stateFunc", "type") +- +-var a unknown //@item(global_a, "a", "unknown", "var"),diag("unknown", "compiler", "(undeclared name|undefined): unknown", "error") +- +-func random() int { //@item(random, "random", "func() int", "func") +- //@complete("", global_a, bob, random, random2, random3, stateFunc, stuff) +- return 0 +-} +- +-func random2(y int) int { //@item(random2, "random2", "func(y int) int", "func"),item(bad_y_param, "y", "int", "var") +- x := 6 //@item(x, "x", "int", "var"),diag("x", "compiler", "x declared (and|but) not used", "error") +- var q blah //@item(q, "q", "blah", "var"),diag("q", "compiler", "q declared (and|but) not used", "error"),diag("blah", "compiler", "(undeclared name|undefined): blah", "error") +- var t **blob //@item(t, "t", "**blob", "var"),diag("t", "compiler", "t declared (and|but) not used", "error"),diag("blob", "compiler", "(undeclared name|undefined): blob", "error") +- //@complete("", q, t, x, bad_y_param, global_a, bob, random, random2, random3, stateFunc, stuff) +- +- return y +-} +- +-func random3(y ...int) { //@item(random3, "random3", "func(y ...int)", "func"),item(y_variadic_param, "y", "[]int", "var") +- //@complete("", y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) +- +- var ch chan (favType1) //@item(ch, "ch", "chan (favType1)", "var"),diag("ch", "compiler", "ch declared (and|but) not used", "error"),diag("favType1", "compiler", "(undeclared name|undefined): favType1", "error") +- var m map[keyType]int //@item(m, "m", "map[keyType]int", "var"),diag("m", "compiler", "m declared (and|but) not used", "error"),diag("keyType", "compiler", "(undeclared name|undefined): keyType", "error") +- var arr []favType2 //@item(arr, "arr", "[]favType2", "var"),diag("arr", "compiler", "arr declared (and|but) not used", "error"),diag("favType2", "compiler", "(undeclared name|undefined): favType2", "error") +- var fn1 func() badResult //@item(fn1, "fn1", "func() badResult", "var"),diag("fn1", "compiler", "fn1 declared (and|but) not used", "error"),diag("badResult", "compiler", "(undeclared name|undefined): badResult", "error") +- var fn2 func(badParam) //@item(fn2, "fn2", "func(badParam)", "var"),diag("fn2", "compiler", "fn2 declared (and|but) not used", "error"),diag("badParam", "compiler", "(undeclared name|undefined): badParam", "error") +- //@complete("", arr, ch, fn1, fn2, m, y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) +-} +diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in +--- a/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package badstmt +- +-import ( +- "golang.org/lsptests/foo" +-) +- +-func _() { +- defer func() { foo. } //@rank(" }", Foo) +-} +diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in +--- a/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package badstmt +- +-import ( +- "golang.org/lsptests/foo" +-) +- +-func _() { +- go foo. //@rank(" //", Foo, IntFoo),snippet(" //", Foo, "Foo()", "Foo()") +-} +diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in +--- a/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package badstmt +- +-import ( +- "golang.org/lsptests/foo" +-) +- +-func _() { +- go func() { +- defer foo. //@rank(" //", Foo, IntFoo) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt.go.in +--- a/gopls/internal/lsp/testdata/badstmt/badstmt.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/badstmt/badstmt.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,28 +0,0 @@ +-package badstmt +- +-import ( +- "golang.org/lsptests/foo" +-) +- +-// (The syntax error causes suppression of diagnostics for type errors. +-// See issue #59888.) +- +-func _(x int) { +- defer foo.F //@complete(" //", Foo),diag(" //", "syntax", "function must be invoked in defer statement|expression in defer must be function call", "error") +- defer foo.F //@complete(" //", Foo) +-} +- +-func _() { +- switch true { +- case true: +- go foo.F //@complete(" //", Foo) +- } +-} +- +-func _() { +- defer func() { +- foo.F //@complete(" //", Foo),snippet(" //", Foo, "Foo()", "Foo()") +- +- foo. //@rank(" //", Foo) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/bar/bar.go.in b/gopls/internal/lsp/testdata/bar/bar.go.in +--- a/gopls/internal/lsp/testdata/bar/bar.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/bar/bar.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +-// +build go1.11 +- +-package bar +- +-import ( +- "golang.org/lsptests/foo" //@item(foo, "foo", "\"golang.org/lsptests/foo\"", "package") +-) +- +-func helper(i foo.IntFoo) {} //@item(helper, "helper", "func(i foo.IntFoo)", "func") +- +-func _() { +- help //@complete("l", helper) +- _ = foo.StructFoo{} //@complete("S", IntFoo, StructFoo) +-} +- +-// Bar is a function. +-func Bar() { //@item(Bar, "Bar", "func()", "func", "Bar is a function.") +- foo.Foo() //@complete("F", Foo, IntFoo, StructFoo) +- var _ foo.IntFoo //@complete("I", IntFoo, StructFoo) +- foo.() //@complete("(", Foo, IntFoo, StructFoo) +-} +- +-func _() { +- var Valentine int //@item(Valentine, "Valentine", "int", "var") +- +- _ = foo.StructFoo{ +- Valu //@complete(" //", Value) +- } +- _ = foo.StructFoo{ +- Va //@complete("a", Value, Valentine) +- } +- _ = foo.StructFoo{ +- Value: 5, //@complete("a", Value) +- } +- _ = foo.StructFoo{ +- //@complete("", Value, Valentine, foo, helper, Bar) +- } +- _ = foo.StructFoo{ +- Value: Valen //@complete("le", Valentine) +- } +- _ = foo.StructFoo{ +- Value: //@complete(" //", Valentine, foo, helper, Bar) +- } +- _ = foo.StructFoo{ +- Value: //@complete(" ", Valentine, foo, helper, Bar) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/basiclit/basiclit.go b/gopls/internal/lsp/testdata/basiclit/basiclit.go +--- a/gopls/internal/lsp/testdata/basiclit/basiclit.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/basiclit/basiclit.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package basiclit +- +-func _() { +- var a int // something for lexical completions +- +- _ = "hello." //@complete(".") +- +- _ = 1 //@complete(" //") +- +- _ = 1. //@complete(".") +- +- _ = 'a' //@complete("' ") +-} +diff -urN a/gopls/internal/lsp/testdata/baz/baz.go.in b/gopls/internal/lsp/testdata/baz/baz.go.in +--- a/gopls/internal/lsp/testdata/baz/baz.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/baz/baz.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-// +build go1.11 +- +-package baz +- +-import ( +- "golang.org/lsptests/bar" +- +- f "golang.org/lsptests/foo" +-) +- +-var FooStruct f.StructFoo +- +-func Baz() { +- defer bar.Bar() //@complete("B", Bar) +- // TODO(rstambler): Test completion here. +- defer bar.B +- var x f.IntFoo //@complete("n", IntFoo),typdef("x", IntFoo) +- bar.Bar() //@complete("B", Bar) +-} +- +-func _() { +- bob := f.StructFoo{Value: 5} +- if x := bob. //@complete(" //", Value) +- switch true == false { +- case true: +- if x := bob. //@complete(" //", Value) +- case false: +- } +- if x := bob.Va //@complete("a", Value) +- switch true == true { +- default: +- } +-} +diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_args.go b/gopls/internal/lsp/testdata/builtins/builtin_args.go +--- a/gopls/internal/lsp/testdata/builtins/builtin_args.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/builtin_args.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,62 +0,0 @@ +-package builtins +- +-func _() { +- var ( +- aSlice []int //@item(builtinSlice, "aSlice", "[]int", "var") +- aMap map[string]int //@item(builtinMap, "aMap", "map[string]int", "var") +- aString string //@item(builtinString, "aString", "string", "var") +- aArray [0]int //@item(builtinArray, "aArray", "[0]int", "var") +- aArrayPtr *[0]int //@item(builtinArrayPtr, "aArrayPtr", "*[0]int", "var") +- aChan chan int //@item(builtinChan, "aChan", "chan int", "var") +- aPtr *int //@item(builtinPtr, "aPtr", "*int", "var") +- aInt int //@item(builtinInt, "aInt", "int", "var") +- ) +- +- type ( +- aSliceType []int //@item(builtinSliceType, "aSliceType", "[]int", "type") +- aChanType chan int //@item(builtinChanType, "aChanType", "chan int", "type") +- aMapType map[string]int //@item(builtinMapType, "aMapType", "map[string]int", "type") +- ) +- +- close() //@rank(")", builtinChan, builtinSlice) +- +- append() //@rank(")", builtinSlice, builtinChan) +- +- var _ []byte = append([]byte(nil), ""...) //@rank(") //") +- +- copy() //@rank(")", builtinSlice, builtinChan) +- copy(aSlice, aS) //@rank(")", builtinSlice, builtinString) +- copy(aS, aSlice) //@rank(",", builtinSlice, builtinString) +- +- delete() //@rank(")", builtinMap, builtinChan) +- delete(aMap, aS) //@rank(")", builtinString, builtinSlice) +- +- aMapFunc := func() map[int]int { //@item(builtinMapFunc, "aMapFunc", "func() map[int]int", "var") +- return nil +- } +- delete() //@rank(")", builtinMapFunc, builtinSlice) +- +- len() //@rank(")", builtinSlice, builtinInt),rank(")", builtinMap, builtinInt),rank(")", builtinString, builtinInt),rank(")", builtinArray, builtinInt),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) +- +- cap() //@rank(")", builtinSlice, builtinMap),rank(")", builtinArray, builtinString),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) +- +- make() //@rank(")", builtinMapType, int),rank(")", builtinChanType, int),rank(")", builtinSliceType, int),rank(")", builtinMapType, int) +- make(aSliceType, a) //@rank(")", builtinInt, builtinSlice) +- +- type myInt int +- var mi myInt //@item(builtinMyInt, "mi", "myInt", "var") +- make(aSliceType, m) //@snippet(")", builtinMyInt, "mi", "mi") +- +- var _ []int = make() //@rank(")", builtinSliceType, builtinMapType) +- +- type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct") +- var _ *myStruct = new() //@rank(")", builtinStructType, int) +- +- for k := range a { //@rank(" {", builtinSlice, builtinInt),rank(" {", builtinString, builtinInt),rank(" {", builtinChan, builtinInt),rank(" {", builtinArray, builtinInt),rank(" {", builtinArrayPtr, builtinInt),rank(" {", builtinMap, builtinInt), +- } +- +- for k, v := range a { //@rank(" {", builtinSlice, builtinChan) +- } +- +- <-a //@rank(" //", builtinChan, builtinInt) +-} +diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_go117.go b/gopls/internal/lsp/testdata/builtins/builtin_go117.go +--- a/gopls/internal/lsp/testdata/builtins/builtin_go117.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/builtin_go117.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-//go:build !go1.18 +-// +build !go1.18 +- +-package builtins +- +-func _() { +- //@complete("", append, bool, byte, cap, close, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, _nil) +-} +diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_go118.go b/gopls/internal/lsp/testdata/builtins/builtin_go118.go +--- a/gopls/internal/lsp/testdata/builtins/builtin_go118.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/builtin_go118.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-//go:build go1.18 && !go1.21 +-// +build go1.18,!go1.21 +- +-package builtins +- +-func _() { +- //@complete("", any, append, bool, byte, cap, close, comparable, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, _nil) +-} +diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_go121.go b/gopls/internal/lsp/testdata/builtins/builtin_go121.go +--- a/gopls/internal/lsp/testdata/builtins/builtin_go121.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/builtin_go121.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-//go:build go1.21 && !go1.22 && ignore +-// +build go1.21,!go1.22,ignore +- +-package builtins +- +-func _() { +- //@complete("", any, append, bool, byte, cap, clear, close, comparable, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, max, min, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, _nil) +-} +diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_go122.go b/gopls/internal/lsp/testdata/builtins/builtin_go122.go +--- a/gopls/internal/lsp/testdata/builtins/builtin_go122.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/builtin_go122.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-//go:build go1.22 && ignore +-// +build go1.22,ignore +- +-package builtins +- +-func _() { +- //@complete("", any, append, bool, byte, cap, clear, close, comparable, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, max, min, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, zero, _nil) +-} +diff -urN a/gopls/internal/lsp/testdata/builtins/builtins.go b/gopls/internal/lsp/testdata/builtins/builtins.go +--- a/gopls/internal/lsp/testdata/builtins/builtins.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/builtins.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,50 +0,0 @@ +-package builtins +- +-// Definitions of builtin completion items. +- +-/* any */ //@item(any, "any", "", "interface") +-/* Create markers for builtin types. Only for use by this test. +-/* append(slice []Type, elems ...Type) []Type */ //@item(append, "append", "func(slice []Type, elems ...Type) []Type", "func") +-/* bool */ //@item(bool, "bool", "", "type") +-/* byte */ //@item(byte, "byte", "", "type") +-/* cap(v Type) int */ //@item(cap, "cap", "func(v Type) int", "func") +-/* clear[T interface{ ~[]Type | ~map[Type]Type1 }](t T) */ //@item(clear, "clear", "func(t T)", "func") +-/* close(c chan<- Type) */ //@item(close, "close", "func(c chan<- Type)", "func") +-/* comparable */ //@item(comparable, "comparable", "", "interface") +-/* complex(r float64, i float64) */ //@item(complex, "complex", "func(r float64, i float64) complex128", "func") +-/* complex128 */ //@item(complex128, "complex128", "", "type") +-/* complex64 */ //@item(complex64, "complex64", "", "type") +-/* copy(dst []Type, src []Type) int */ //@item(copy, "copy", "func(dst []Type, src []Type) int", "func") +-/* delete(m map[Type]Type1, key Type) */ //@item(delete, "delete", "func(m map[Type]Type1, key Type)", "func") +-/* error */ //@item(error, "error", "", "interface") +-/* false */ //@item(_false, "false", "", "const") +-/* float32 */ //@item(float32, "float32", "", "type") +-/* float64 */ //@item(float64, "float64", "", "type") +-/* imag(c complex128) float64 */ //@item(imag, "imag", "func(c complex128) float64", "func") +-/* int */ //@item(int, "int", "", "type") +-/* int16 */ //@item(int16, "int16", "", "type") +-/* int32 */ //@item(int32, "int32", "", "type") +-/* int64 */ //@item(int64, "int64", "", "type") +-/* int8 */ //@item(int8, "int8", "", "type") +-/* iota */ //@item(iota, "iota", "", "const") +-/* len(v Type) int */ //@item(len, "len", "func(v Type) int", "func") +-/* max(x T, y ...T) T */ //@item(max, "max", "func(x T, y ...T) T", "func") +-/* min(y T, y ...T) T */ //@item(min, "min", "func(x T, y ...T) T", "func") +-/* make(t Type, size ...int) Type */ //@item(make, "make", "func(t Type, size ...int) Type", "func") +-/* new(Type) *Type */ //@item(new, "new", "func(Type) *Type", "func") +-/* nil */ //@item(_nil, "nil", "", "var") +-/* panic(v interface{}) */ //@item(panic, "panic", "func(v interface{})", "func") +-/* print(args ...Type) */ //@item(print, "print", "func(args ...Type)", "func") +-/* println(args ...Type) */ //@item(println, "println", "func(args ...Type)", "func") +-/* real(c complex128) float64 */ //@item(real, "real", "func(c complex128) float64", "func") +-/* recover() interface{} */ //@item(recover, "recover", "func() interface{}", "func") +-/* rune */ //@item(rune, "rune", "", "type") +-/* string */ //@item(string, "string", "", "type") +-/* true */ //@item(_true, "true", "", "const") +-/* uint */ //@item(uint, "uint", "", "type") +-/* uint16 */ //@item(uint16, "uint16", "", "type") +-/* uint32 */ //@item(uint32, "uint32", "", "type") +-/* uint64 */ //@item(uint64, "uint64", "", "type") +-/* uint8 */ //@item(uint8, "uint8", "", "type") +-/* uintptr */ //@item(uintptr, "uintptr", "", "type") +-/* zero */ //@item(zero, "zero", "", "var") +diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_types.go b/gopls/internal/lsp/testdata/builtins/builtin_types.go +--- a/gopls/internal/lsp/testdata/builtins/builtin_types.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/builtin_types.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package builtins +- +-func _() { +- var _ []bool //@item(builtinBoolSliceType, "[]bool", "[]bool", "type") +- +- var _ []bool = make() //@rank(")", builtinBoolSliceType, int) +- +- var _ []bool = make([], 0) //@rank(",", bool, int) +- +- var _ [][]bool = make([][], 0) //@rank(",", bool, int) +-} +diff -urN a/gopls/internal/lsp/testdata/builtins/constants.go b/gopls/internal/lsp/testdata/builtins/constants.go +--- a/gopls/internal/lsp/testdata/builtins/constants.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/builtins/constants.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +-package builtins +- +-func _() { +- const ( +- foo = iota //@complete(" //", iota) +- ) +- +- iota //@complete(" //") +- +- var iota int //@item(iotaVar, "iota", "int", "var") +- +- iota //@complete(" //", iotaVar) +-} +- +-func _() { +- var twoRedUpEnd bool //@item(TRUEVar, "twoRedUpEnd", "bool", "var") +- +- var _ bool = true //@rank(" //", _true, TRUEVar) +-} +diff -urN a/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go b/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go +--- a/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,70 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package callhierarchy +- +-import "golang.org/lsptests/callhierarchy/outgoing" +- +-func a() { //@mark(hierarchyA, "a") +- D() +-} +- +-func b() { //@mark(hierarchyB, "b") +- D() +-} +- +-// C is an exported function +-func C() { //@mark(hierarchyC, "C") +- D() +- D() +-} +- +-// To test hierarchy across function literals +-var x = func() { //@mark(hierarchyLiteral, "func"),mark(hierarchyLiteralOut, "x") +- D() +-} +- +-// D is exported to test incoming/outgoing calls across packages +-func D() { //@mark(hierarchyD, "D"),incomingcalls(hierarchyD, hierarchyA, hierarchyB, hierarchyC, hierarchyLiteral, incomingA),outgoingcalls(hierarchyD, hierarchyE, hierarchyF, hierarchyG, hierarchyLiteralOut, outgoingB, hierarchyFoo, hierarchyH, hierarchyI, hierarchyJ, hierarchyK) +- e() +- x() +- F() +- outgoing.B() +- foo := func() {} //@mark(hierarchyFoo, "foo"),incomingcalls(hierarchyFoo, hierarchyD),outgoingcalls(hierarchyFoo) +- foo() +- +- func() { +- g() +- }() +- +- var i Interface = impl{} +- i.H() +- i.I() +- +- s := Struct{} +- s.J() +- s.K() +-} +- +-func e() {} //@mark(hierarchyE, "e") +- +-// F is an exported function +-func F() {} //@mark(hierarchyF, "F") +- +-func g() {} //@mark(hierarchyG, "g") +- +-type Interface interface { +- H() //@mark(hierarchyH, "H") +- I() //@mark(hierarchyI, "I") +-} +- +-type impl struct{} +- +-func (i impl) H() {} +-func (i impl) I() {} +- +-type Struct struct { +- J func() //@mark(hierarchyJ, "J") +- K func() //@mark(hierarchyK, "K") +-} +diff -urN a/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go b/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go +--- a/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package incoming +- +-import "golang.org/lsptests/callhierarchy" +- +-// A is exported to test incoming calls across packages +-func A() { //@mark(incomingA, "A") +- callhierarchy.D() +-} +diff -urN a/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go b/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go +--- a/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package outgoing +- +-// B is exported to test outgoing calls across packages +-func B() { //@mark(outgoingB, "B") +-} +diff -urN a/gopls/internal/lsp/testdata/casesensitive/casesensitive.go b/gopls/internal/lsp/testdata/casesensitive/casesensitive.go +--- a/gopls/internal/lsp/testdata/casesensitive/casesensitive.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/casesensitive/casesensitive.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-// Copyright 2019 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package casesensitive +- +-func _() { +- var lower int //@item(lower, "lower", "int", "var") +- var Upper int //@item(upper, "Upper", "int", "var") +- +- l //@casesensitive(" //", lower) +- U //@casesensitive(" //", upper) +- +- L //@casesensitive(" //") +- u //@casesensitive(" //") +-} +diff -urN a/gopls/internal/lsp/testdata/cast/cast.go.in b/gopls/internal/lsp/testdata/cast/cast.go.in +--- a/gopls/internal/lsp/testdata/cast/cast.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/cast/cast.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package cast +- +-func _() { +- foo := struct{x int}{x: 1} //@item(x_field, "x", "int", "field") +- _ = float64(foo.x) //@complete("x", x_field) +-} +- +-func _() { +- foo := struct{x int}{x: 1} +- _ = float64(foo. //@complete(" /", x_field) +-} +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/cgo/declarecgo.go b/gopls/internal/lsp/testdata/cgo/declarecgo.go +--- a/gopls/internal/lsp/testdata/cgo/declarecgo.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/cgo/declarecgo.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package cgo +- +-/* +-#include +-#include +- +-void myprint(char* s) { +- printf("%s\n", s); +-} +-*/ +-import "C" +- +-import ( +- "fmt" +- "unsafe" +-) +- +-func Example() { //@mark(funccgoexample, "Example"),item(funccgoexample, "Example", "func()", "func") +- fmt.Println() +- cs := C.CString("Hello from stdio\n") +- C.myprint(cs) +- C.free(unsafe.Pointer(cs)) +-} +- +-func _() { +- Example() //@godef("ample", funccgoexample),complete("ample", funccgoexample) +-} +diff -urN a/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden b/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden +--- a/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +--- funccgoexample-definition -- +-cgo/declarecgo.go:18:6-13: defined here as ```go +-func Example() +-``` +- +-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) +--- funccgoexample-definition-json -- +-{ +- "span": { +- "uri": "file://cgo/declarecgo.go", +- "start": { +- "line": 18, +- "column": 6, +- "offset": 151 +- }, +- "end": { +- "line": 18, +- "column": 13, +- "offset": 158 +- } +- }, +- "description": "```go\nfunc Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)" +-} +- +--- funccgoexample-hoverdef -- +-```go +-func Example() +-``` +- +-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) +diff -urN a/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go b/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go +--- a/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-//+build !cgo +- +-package cgo +- +-// Set a dummy marker to keep the test framework happy. The tests should be skipped. +-var _ = "Example" //@mark(funccgoexample, "Example"),godef("ample", funccgoexample),complete("ample", funccgoexample) +diff -urN a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden +--- a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +--- funccgoexample-definition -- +-cgo/declarecgo.go:18:6-13: defined here as ```go +-func cgo.Example() +-``` +- +-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) +--- funccgoexample-definition-json -- +-{ +- "span": { +- "uri": "file://cgo/declarecgo.go", +- "start": { +- "line": 18, +- "column": 6, +- "offset": 151 +- }, +- "end": { +- "line": 18, +- "column": 13, +- "offset": 158 +- } +- }, +- "description": "```go\nfunc cgo.Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)" +-} - --func main() {} -diff -urN a/gopls/internal/lsp/testdata/address/address.go b/gopls/internal/lsp/testdata/address/address.go ---- a/gopls/internal/lsp/testdata/address/address.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/address/address.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,78 +0,0 @@ --package address +--- funccgoexample-hoverdef -- +-```go +-func cgo.Example() +-``` - --func wantsPtr(*int) {} --func wantsVariadicPtr(...*int) {} +-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) +diff -urN a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in +--- a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package cgoimport - --func wantsVariadic(...int) {} +-import ( +- "golang.org/lsptests/cgo" +-) - --type foo struct{ c int } //@item(addrFieldC, "c", "int", "field") +-func _() { +- cgo.Example() //@godef("ample", funccgoexample),complete("ample", funccgoexample) +-} +diff -urN a/gopls/internal/lsp/testdata/channel/channel.go b/gopls/internal/lsp/testdata/channel/channel.go +--- a/gopls/internal/lsp/testdata/channel/channel.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/channel/channel.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +-package channel - -func _() { - var ( -- a string //@item(addrA, "a", "string", "var") -- b int //@item(addrB, "b", "int", "var") +- aa = "123" //@item(channelAA, "aa", "string", "var") +- ab = 123 //@item(channelAB, "ab", "int", "var") - ) - -- wantsPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b", "&b") -- wantsPtr(&b) //@snippet(")", addrB, "b", "b") -- -- wantsVariadicPtr() //@rank(")", addrB, addrA),snippet(")", addrB, "&b", "&b") +- { +- type myChan chan int +- var mc myChan +- mc <- a //@complete(" //", channelAB, channelAA) +- } - -- var s foo -- s.c //@item(addrDeepC, "s.c", "int", "field") -- wantsPtr() //@snippet(")", addrDeepC, "&s.c", "&s.c") -- wantsPtr(s) //@snippet(")", addrDeepC, "&s.c", "&s.c") -- wantsPtr(&s) //@snippet(")", addrDeepC, "s.c", "s.c") +- { +- var ac chan int //@item(channelAC, "ac", "chan int", "var") +- a <- a //@complete(" <-", channelAC, channelAA, channelAB) +- } - -- // don't add "&" in item (it gets added as an additional edit) -- wantsPtr(&s.c) //@snippet(")", addrFieldC, "c", "c") +- { +- var foo chan int //@item(channelFoo, "foo", "chan int", "var") +- wantsInt := func(int) {} //@item(channelWantsInt, "wantsInt", "func(int)", "var") +- wantsInt(<-) //@rank(")", channelFoo, channelAB) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/codelens/codelens_test.go b/gopls/internal/lsp/testdata/codelens/codelens_test.go +--- a/gopls/internal/lsp/testdata/codelens/codelens_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/codelens/codelens_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-package codelens //@codelens("package codelens", "run file benchmarks", "test") - -- // check dereferencing as well -- var c *int //@item(addrCPtr, "c", "*int", "var") -- var _ int = _ //@rank("_ //", addrCPtr, addrA),snippet("_ //", addrCPtr, "*c", "*c") +-import "testing" - -- wantsVariadic() //@rank(")", addrCPtr, addrA),snippet(")", addrCPtr, "*c", "*c") +-func TestMain(m *testing.M) {} // no code lens for TestMain - -- var d **int //@item(addrDPtr, "d", "**int", "var") -- var _ int = _ //@rank("_ //", addrDPtr, addrA),snippet("_ //", addrDPtr, "**d", "**d") +-func TestFuncWithCodeLens(t *testing.T) { //@codelens("func", "run test", "test") +-} - -- type namedPtr *int -- var np namedPtr //@item(addrNamedPtr, "np", "namedPtr", "var") +-func thisShouldNotHaveACodeLens(t *testing.T) { +-} - -- var _ int = _ //@rank("_ //", addrNamedPtr, addrA) +-func BenchmarkFuncWithCodeLens(b *testing.B) { //@codelens("func", "run benchmark", "test") +-} - -- // don't get tripped up by recursive pointer type -- type dontMessUp *dontMessUp -- var dmu *dontMessUp //@item(addrDMU, "dmu", "*dontMessUp", "var") +-func helper() {} // expect no code lens +diff -urN a/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in b/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in +--- a/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,70 +0,0 @@ +-package comment_completion - -- var _ int = dmu //@complete(" //", addrDMU) --} +-var p bool - --func (f foo) ptr() *foo { return &f } +-//@complete(re"$") - -func _() { -- getFoo := func() foo { return foo{} } -- -- // not addressable -- getFoo().c //@item(addrGetFooC, "getFoo().c", "int", "field") +- var a int - -- // addressable -- getFoo().ptr().c //@item(addrGetFooPtrC, "getFoo().ptr().c", "int", "field") +- switch a { +- case 1: +- //@complete(re"$") +- _ = a +- } - -- wantsPtr() //@rank(addrGetFooPtrC, addrGetFooC),snippet(")", addrGetFooPtrC, "&getFoo().ptr().c", "&getFoo().ptr().c") -- wantsPtr(&g) //@rank(addrGetFooPtrC, addrGetFooC),snippet(")", addrGetFooPtrC, "getFoo().ptr().c", "getFoo().ptr().c") --} +- var b chan int +- select { +- case <-b: +- //@complete(re"$") +- _ = b +- } - --type nested struct { -- f foo +- var ( +- //@complete(re"$") +- _ = a +- ) -} - --func _() { -- getNested := func() nested { return nested{} } +-// //@complete(" ", variableC) +-var C string //@item(variableC, "C", "string", "var") //@complete(" ", variableC) - -- getNested().f.c //@item(addrNestedC, "getNested().f.c", "int", "field") -- getNested().f.ptr().c //@item(addrNestedPtrC, "getNested().f.ptr().c", "int", "field") +-// //@complete(" ", constant) +-const Constant = "example" //@item(constant, "Constant", "string", "const") //@complete(" ", constant) - -- // addrNestedC is not addressable, so rank lower -- wantsPtr(getNestedfc) //@fuzzy(")", addrNestedPtrC, addrNestedC) +-// //@complete(" ", structType, fieldB, fieldA) +-type StructType struct { //@item(structType, "StructType", "struct{...}", "struct") //@complete(" ", structType, fieldA, fieldB) +- // //@complete(" ", fieldA, structType, fieldB) +- A string //@item(fieldA, "A", "string", "field") //@complete(" ", fieldA, structType, fieldB) +- b int //@item(fieldB, "b", "int", "field") //@complete(" ", fieldB, structType, fieldA) -} -diff -urN a/gopls/internal/lsp/testdata/analyzer/bad_test.go b/gopls/internal/lsp/testdata/analyzer/bad_test.go ---- a/gopls/internal/lsp/testdata/analyzer/bad_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/analyzer/bad_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ --package analyzer - --import ( -- "fmt" -- "sync" -- "testing" -- "time" --) +-// //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) +-func (structType *StructType) Method(X int) (Y int) { //@item(structRecv, "structType", "*StructType", "var"),item(method, "Method", "func(X int) (Y int)", "method"),item(paramX, "X", "int", "var"),item(resultY, "Y", "int", "var") +- // //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) +- return +-} - --func Testbad(t *testing.T) { //@diag("", "tests", "Testbad has malformed name: first letter after 'Test' must not be lowercase", "warning") -- var x sync.Mutex -- _ = x //@diag("x", "copylocks", "assignment copies lock value to _: sync.Mutex", "warning") +-// //@complete(" ", newType) +-type NewType string //@item(newType, "NewType", "string", "type") //@complete(" ", newType) - -- printfWrapper("%s") //@diag(re`printfWrapper\(.*\)`, "printf", "golang.org/lsptests/analyzer.printfWrapper format %s reads arg #1, but call has 0 args", "warning") +-// //@complete(" ", testInterface, testA, testB) +-type TestInterface interface { //@item(testInterface, "TestInterface", "interface{...}", "interface") +- // //@complete(" ", testA, testInterface, testB) +- TestA(L string) (M int) //@item(testA, "TestA", "func(L string) (M int)", "method"),item(paramL, "L", "var", "string"),item(resM, "M", "var", "int") //@complete(" ", testA, testInterface, testB) +- TestB(N int) bool //@item(testB, "TestB", "func(N int) bool", "method"),item(paramN, "N", "var", "int") //@complete(" ", testB, testInterface, testA) -} - --func printfWrapper(format string, args ...interface{}) { -- fmt.Printf(format, args...) +-// //@complete(" ", function) +-func Function() int { //@item(function, "Function", "func() int", "func") //@complete(" ", function) +- // //@complete(" ", function) +- return 0 -} - --func _() { -- now := time.Now() -- fmt.Println(now.Format("2006-02-01")) //@diag("2006-02-01", "timeformat", "2006-02-01 should be 2006-01-02", "warning") +-// This tests multiline block comments and completion with prefix +-// Lorem Ipsum Multili//@complete("Multi", multiline) +-// Lorem ipsum dolor sit ametom +-func Multiline() int { //@item(multiline, "Multiline", "func() int", "func") +- // //@complete(" ", multiline) +- return 0 -} -diff -urN a/gopls/internal/lsp/testdata/anon/anon.go.in b/gopls/internal/lsp/testdata/anon/anon.go.in ---- a/gopls/internal/lsp/testdata/anon/anon.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/anon/anon.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,23 +0,0 @@ --package anon -- --func _() { -- for _, _ := range []struct { -- i, j int //@item(anonI, "i", "int", "field"),item(anonJ, "j", "int", "field") -- }{ -- { -- i: 1, -- //@complete("", anonJ) -- }, -- { -- //@complete("", anonI, anonJ) -- }, -- } { -- continue -- } +diff -urN a/gopls/internal/lsp/testdata/complit/complit.go.in b/gopls/internal/lsp/testdata/complit/complit.go.in +--- a/gopls/internal/lsp/testdata/complit/complit.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/complit/complit.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,90 +0,0 @@ +-package complit - -- s := struct{ f int }{ } //@item(anonF, "f", "int", "field"),item(structS, "s", "struct{...}", "var"),complete(" }", anonF) +-// general completions - -- _ = map[struct{ x int }]int{ //@item(anonX, "x", "int", "field") -- struct{ x int }{ }: 1, //@complete(" }", anonX, structS) -- } +-type position struct { //@item(structPosition, "position", "struct{...}", "struct") +- X, Y int //@item(fieldX, "X", "int", "field"),item(fieldY, "Y", "int", "field") -} -diff -urN a/gopls/internal/lsp/testdata/append/append2.go.in b/gopls/internal/lsp/testdata/append/append2.go.in ---- a/gopls/internal/lsp/testdata/append/append2.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/append/append2.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package append - -func _() { -- _ = append(a, struct) //@complete(")") +- _ = position{ +- //@complete("", fieldX, fieldY, structPosition) +- } +- _ = position{ +- X: 1, +- //@complete("", fieldY) +- } +- _ = position{ +- //@complete("", fieldX) +- Y: 1, +- } +- _ = []*position{ +- { +- //@complete("", fieldX, fieldY, structPosition) +- }, +- } -} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/append/append.go b/gopls/internal/lsp/testdata/append/append.go ---- a/gopls/internal/lsp/testdata/append/append.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/append/append.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,38 +0,0 @@ --package append -- --func foo([]string) {} --func bar(...string) {} - -func _() { - var ( -- aInt []int //@item(appendInt, "aInt", "[]int", "var") -- aStrings []string //@item(appendStrings, "aStrings", "[]string", "var") -- aString string //@item(appendString, "aString", "string", "var") +- aa string //@item(aaVar, "aa", "string", "var") +- ab int //@item(abVar, "ab", "int", "var") - ) - -- append(aStrings, a) //@rank(")", appendString, appendInt) -- var _ interface{} = append(aStrings, a) //@rank(")", appendString, appendInt) -- var _ []string = append(oops, a) //@rank(")", appendString, appendInt) -- -- foo(append()) //@rank("))", appendStrings, appendInt),rank("))", appendStrings, appendString) -- foo(append([]string{}, a)) //@rank("))", appendStrings, appendInt),rank("))", appendString, appendInt),snippet("))", appendStrings, "aStrings...", "aStrings...") -- foo(append([]string{}, "", a)) //@rank("))", appendString, appendInt),rank("))", appendString, appendStrings) -- -- // Don't add "..." to append() argument. -- bar(append()) //@snippet("))", appendStrings, "aStrings", "aStrings") -- -- type baz struct{} -- baz{} //@item(appendBazLiteral, "baz{}", "", "var") -- var bazzes []baz //@item(appendBazzes, "bazzes", "[]baz", "var") -- var bazzy baz //@item(appendBazzy, "bazzy", "baz", "var") -- bazzes = append(bazzes, ba) //@rank(")", appendBazzy, appendBazLiteral, appendBazzes) +- _ = map[int]int{ +- a: a, //@complete(":", abVar, aaVar),complete(",", abVar, aaVar) +- } - -- var b struct{ b []baz } -- b.b //@item(appendNestedBaz, "b.b", "[]baz", "field") -- b.b = append(b.b, b) //@rank(")", appendBazzy, appendBazLiteral, appendNestedBaz) +- _ = map[int]int{ +- //@complete("", abVar, aaVar, structPosition) +- } - -- var aStringsPtr *[]string //@item(appendStringsPtr, "aStringsPtr", "*[]string", "var") -- foo(append([]string{}, a)) //@snippet("))", appendStringsPtr, "*aStringsPtr...", "*aStringsPtr...") +- _ = []string{a: ""} //@complete(":", abVar, aaVar) +- _ = [1]string{a: ""} //@complete(":", abVar, aaVar) - -- foo(append([]string{}, *a)) //@snippet("))", appendStringsPtr, "aStringsPtr...", "aStringsPtr...") --} -diff -urN a/gopls/internal/lsp/testdata/arraytype/array_type.go.in b/gopls/internal/lsp/testdata/arraytype/array_type.go.in ---- a/gopls/internal/lsp/testdata/arraytype/array_type.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/arraytype/array_type.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,50 +0,0 @@ --package arraytype +- _ = position{X: a} //@complete("}", abVar, aaVar) +- _ = position{a} //@complete("}", abVar, aaVar) +- _ = position{a, } //@complete("}", abVar, aaVar, structPosition) - --import ( -- "golang.org/lsptests/foo" --) +- _ = []int{a} //@complete("}", abVar, aaVar) +- _ = [1]int{a} //@complete("}", abVar, aaVar) - --func _() { -- var ( -- val string //@item(atVal, "val", "string", "var") -- ) +- type myStruct struct { +- AA int //@item(fieldAA, "AA", "int", "field") +- AB string //@item(fieldAB, "AB", "string", "field") +- } - -- // disabled - see issue #54822 -- [] // complete(" //", PackageFoo) +- _ = myStruct{ +- AB: a, //@complete(",", aaVar, abVar) +- } - -- []val //@complete(" //") +- var s myStruct - -- []foo.StructFoo //@complete(" //", StructFoo) +- _ = map[int]string{1: "" + s.A} //@complete("}", fieldAB, fieldAA) +- _ = map[int]string{1: (func(i int) string { return "" })(s.A)} //@complete(")}", fieldAA, fieldAB) +- _ = map[int]string{1: func() string { s.A }} //@complete(" }", fieldAA, fieldAB) - -- []foo.StructFoo(nil) //@complete("(", StructFoo) +- _ = position{s.A} //@complete("}", fieldAA, fieldAB) - -- []*foo.StructFoo //@complete(" //", StructFoo) +- var X int //@item(varX, "X", "int", "var") +- _ = position{X} //@complete("}", fieldX, varX) +-} - -- [...]foo.StructFoo //@complete(" //", StructFoo) +-func _() { +- type foo struct{} //@item(complitFoo, "foo", "struct{...}", "struct") - -- [2][][4]foo.StructFoo //@complete(" //", StructFoo) +- var _ *foo = &fo{} //@snippet("{", complitFoo, "foo", "foo") +- var _ *foo = fo{} //@snippet("{", complitFoo, "&foo", "&foo") - -- []struct { f []foo.StructFoo } //@complete(" }", StructFoo) +- struct { a, b *foo }{ +- a: &fo{}, //@rank("{", complitFoo) +- b: fo{}, //@snippet("{", complitFoo, "&foo", "&foo") +- } -} - -func _() { -- type myInt int //@item(atMyInt, "myInt", "int", "type") -- -- var mark []myInt //@item(atMark, "mark", "[]myInt", "var") +- _ := position{ +- X: 1, //@complete("X", fieldX),complete(" 1", structPosition) +- Y: , //@complete(":", fieldY),complete(" ,", structPosition) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/constant/constant.go b/gopls/internal/lsp/testdata/constant/constant.go +--- a/gopls/internal/lsp/testdata/constant/constant.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/constant/constant.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package constant - -- var s []myInt //@item(atS, "s", "[]myInt", "var") -- s = []m //@complete(" //", atMyInt) -- // disabled - see issue #54822 -- s = [] // complete(" //", atMyInt, PackageFoo) +-const x = 1 //@item(constX, "x", "int", "const") - -- var a [1]myInt -- a = [1]m //@complete(" //", atMyInt) +-const ( +- a int = iota << 2 //@item(constA, "a", "int", "const") +- b //@item(constB, "b", "int", "const") +- c //@item(constC, "c", "int", "const") +-) - -- var ds [][]myInt -- ds = [][]m //@complete(" //", atMyInt) +-func _() { +- const y = "hi" //@item(constY, "y", "string", "const") +- //@complete("", constY, constA, constB, constC, constX) -} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - -func _() { -- var b [0]byte //@item(atByte, "b", "[0]byte", "var") -- var _ []byte = b //@snippet(" //", atByte, "b[:]", "b[:]") +- for bar //@rank(" //", danglingBar) -} -diff -urN a/gopls/internal/lsp/testdata/assign/assign.go.in b/gopls/internal/lsp/testdata/assign/assign.go.in ---- a/gopls/internal/lsp/testdata/assign/assign.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/assign/assign.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,26 +0,0 @@ --package assign - --import "golang.org/lsptests/assign/internal/secret" +-func bar() bool { //@item(danglingBar, "bar", "func() bool", "func") +- return true +-} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - -func _() { -- secret.Hello() -- var ( -- myInt int //@item(assignInt, "myInt", "int", "var") -- myStr string //@item(assignStr, "myStr", "string", "var") -- ) +- for i := bar3(); i > bar //@rank(" //", danglingBar3) +-} - -- var _ string = my //@rank(" //", assignStr, assignInt) -- var _ string = //@rank(" //", assignStr, assignInt) +-func bar3() int { //@item(danglingBar3, "bar3", "func() int", "func") +- return 0 -} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - -func _() { -- var a string = a //@complete(" //") +- for i := bar4(); i > bar4(); i += bar //@rank(" //", danglingBar4) +-} +- +-func bar4() int { //@item(danglingBar4, "bar4", "func() int", "func") +- return 0 -} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - -func _() { -- fooBar := fooBa //@complete(" //"),item(assignFooBar, "fooBar", "", "var") -- abc, fooBar := 123, fooBa //@complete(" //", assignFooBar) -- { -- fooBar := fooBa //@complete(" //", assignFooBar) -- } +- for i := bar //@rank(" //", danglingBar2) -} -diff -urN a/gopls/internal/lsp/testdata/assign/internal/secret/secret.go b/gopls/internal/lsp/testdata/assign/internal/secret/secret.go ---- a/gopls/internal/lsp/testdata/assign/internal/secret/secret.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/assign/internal/secret/secret.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ --package secret - --func Hello() {} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/bad/bad0.go b/gopls/internal/lsp/testdata/bad/bad0.go ---- a/gopls/internal/lsp/testdata/bad/bad0.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/bad/bad0.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ --//go:build go1.11 --// +build go1.11 +-func bar2() int { //@item(danglingBar2, "bar2", "func() int", "func") +- return 0 +-} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package danglingstmt - --package bad +-func bar5() bool { //@item(danglingBar5, "bar5", "func() bool", "func") +- return true +-} - --import _ "golang.org/lsptests/assign/internal/secret" //@diag("\"golang.org/lsptests/assign/internal/secret\"", "compiler", "could not import golang.org/lsptests/assign/internal/secret \\(invalid use of internal package \"golang.org/lsptests/assign/internal/secret\"\\)", "error") +-func _() { +- if b //@rank(" //", danglingBar5) +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - --func stuff() { //@item(stuff, "stuff", "func()", "func") -- x := "heeeeyyyy" -- random2(x) //@diag("x", "compiler", "cannot use x \\(variable of type string\\) as int value in argument to random2", "error") -- random2(1) //@complete("dom", random, random2, random3) -- y := 3 //@diag("y", "compiler", "y declared (and|but) not used", "error") +-func _() { +- if foo //@rank(" //", danglingFoo) -} - --type bob struct { //@item(bob, "bob", "struct{...}", "struct") -- x int +-func foo() bool { //@item(danglingFoo, "foo", "func() bool", "func") +- return true -} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - -func _() { -- var q int -- _ = &bob{ -- f: q, //@diag("f: q", "compiler", "unknown field f in struct literal", "error") -- } +- if i := 123; foo //@rank(" //", danglingFoo3) -} -diff -urN a/gopls/internal/lsp/testdata/bad/bad1.go b/gopls/internal/lsp/testdata/bad/bad1.go ---- a/gopls/internal/lsp/testdata/bad/bad1.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/bad/bad1.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,34 +0,0 @@ --//go:build go1.11 --// +build go1.11 - --package bad +-func foo3() bool { //@item(danglingFoo3, "foo3", "func() bool", "func") +- return true +-} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - --// See #36637 --type stateFunc func() stateFunc //@item(stateFunc, "stateFunc", "func() stateFunc", "type") +-func _() { +- if i := foo //@rank(" //", danglingFoo2) +-} - --var a unknown //@item(global_a, "a", "unknown", "var"),diag("unknown", "compiler", "(undeclared name|undefined): unknown", "error") +-func foo2() bool { //@item(danglingFoo2, "foo2", "func() bool", "func") +- return true +-} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-package danglingstmt - --func random() int { //@item(random, "random", "func() int", "func") -- //@complete("", global_a, bob, random, random2, random3, stateFunc, stuff) -- return 0 +-func walrus() bool { //@item(danglingWalrus, "walrus", "func() bool", "func") +- return true -} - --func random2(y int) int { //@item(random2, "random2", "func(y int) int", "func"),item(bad_y_param, "y", "int", "var") -- x := 6 //@item(x, "x", "int", "var"),diag("x", "compiler", "x declared (and|but) not used", "error") -- var q blah //@item(q, "q", "blah", "var"),diag("q", "compiler", "q declared (and|but) not used", "error"),diag("blah", "compiler", "(undeclared name|undefined): blah", "error") -- var t **blob //@item(t, "t", "**blob", "var"),diag("t", "compiler", "t declared (and|but) not used", "error"),diag("blob", "compiler", "(undeclared name|undefined): blob", "error") -- //@complete("", q, t, x, bad_y_param, global_a, bob, random, random2, random3, stateFunc, stuff) +-func _() { +- if true && +- walrus //@complete(" //", danglingWalrus) +-} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package danglingstmt - -- return y +-func _() { +- x. //@rank(" //", danglingI) -} - --func random3(y ...int) { //@item(random3, "random3", "func(y ...int)", "func"),item(y_variadic_param, "y", "[]int", "var") -- //@complete("", y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) -- -- var ch chan (favType1) //@item(ch, "ch", "chan (favType1)", "var"),diag("ch", "compiler", "ch declared (and|but) not used", "error"),diag("favType1", "compiler", "(undeclared name|undefined): favType1", "error") -- var m map[keyType]int //@item(m, "m", "map[keyType]int", "var"),diag("m", "compiler", "m declared (and|but) not used", "error"),diag("keyType", "compiler", "(undeclared name|undefined): keyType", "error") -- var arr []favType2 //@item(arr, "arr", "[]favType2", "var"),diag("arr", "compiler", "arr declared (and|but) not used", "error"),diag("favType2", "compiler", "(undeclared name|undefined): favType2", "error") -- var fn1 func() badResult //@item(fn1, "fn1", "func() badResult", "var"),diag("fn1", "compiler", "fn1 declared (and|but) not used", "error"),diag("badResult", "compiler", "(undeclared name|undefined): badResult", "error") -- var fn2 func(badParam) //@item(fn2, "fn2", "func(badParam)", "var"),diag("fn2", "compiler", "fn2 declared (and|but) not used", "error"),diag("badParam", "compiler", "(undeclared name|undefined): badParam", "error") -- //@complete("", arr, ch, fn1, fn2, m, y_variadic_param, global_a, bob, random, random2, random3, stateFunc, stuff) --} -diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in ---- a/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package badstmt +-var x struct { i int } //@item(danglingI, "i", "int", "field") +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package danglingstmt - --import ( -- "golang.org/lsptests/foo" --) +-import "golang.org/lsptests/foo" - -func _() { -- defer func() { foo. } //@rank(" }", Foo) +- foo. //@rank(" //", Foo) +- var _ = []string{foo.} //@rank("}", Foo) -} -diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in ---- a/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in 1970-01-01 00:00:00.000000000 +0000 +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ --package badstmt -- --import ( -- "golang.org/lsptests/foo" --) +-package danglingstmt - -func _() { -- go foo. //@rank(" //", Foo, IntFoo),snippet(" //", Foo, "Foo()", "Foo()") +- switch i := baz //@rank(" //", danglingBaz) -} -diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in ---- a/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package badstmt - --import ( -- "golang.org/lsptests/foo" --) +-func baz() int { //@item(danglingBaz, "baz", "func() int", "func") +- return 0 +-} +diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go +--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package danglingstmt - -func _() { -- go func() { -- defer foo. //@rank(" //", Foo, IntFoo) -- } +- switch i := 0; baz //@rank(" //", danglingBaz2) -} -diff -urN a/gopls/internal/lsp/testdata/badstmt/badstmt.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt.go.in ---- a/gopls/internal/lsp/testdata/badstmt/badstmt.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/badstmt/badstmt.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ --package badstmt - --import ( -- "golang.org/lsptests/foo" --) +-func baz2() int { //@item(danglingBaz2, "baz2", "func() int", "func") +- return 0 +-} +diff -urN a/gopls/internal/lsp/testdata/deep/deep.go b/gopls/internal/lsp/testdata/deep/deep.go +--- a/gopls/internal/lsp/testdata/deep/deep.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/deep/deep.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,142 +0,0 @@ +-package deep - --// The nonewvars expectation asserts that the go/analysis framework ran. --// See comments in noparse. +-import "context" - --func _(x int) { -- defer foo.F //@complete(" //", Foo),diag(" //", "syntax", "function must be invoked in defer statement|expression in defer must be function call", "error") -- defer foo.F //@complete(" //", Foo) -- x := 123 //@diag(":=", "nonewvars", "no new variables", "warning") +-type deepA struct { +- b deepB //@item(deepBField, "b", "deepB", "field") -} - --func _() { -- switch true { -- case true: -- go foo.F //@complete(" //", Foo) -- } +-type deepB struct { -} - +-func wantsDeepB(deepB) {} +- -func _() { -- defer func() { -- foo.F //@complete(" //", Foo),snippet(" //", Foo, "Foo()", "Foo()") +- var a deepA //@item(deepAVar, "a", "deepA", "var") +- a.b //@item(deepABField, "a.b", "deepB", "field") +- wantsDeepB(a) //@deep(")", deepABField, deepAVar) - -- foo. //@rank(" //", Foo) -- } +- deepA{a} //@snippet("}", deepABField, "a.b", "a.b") -} -diff -urN a/gopls/internal/lsp/testdata/bar/bar.go.in b/gopls/internal/lsp/testdata/bar/bar.go.in ---- a/gopls/internal/lsp/testdata/bar/bar.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/bar/bar.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,47 +0,0 @@ --// +build go1.11 - --package bar +-func wantsContext(context.Context) {} - --import ( -- "golang.org/lsptests/foo" //@item(foo, "foo", "\"golang.org/lsptests/foo\"", "package") --) +-func _() { +- context.Background() //@item(ctxBackground, "context.Background", "func() context.Context", "func", "Background returns a non-nil, empty Context.") +- context.TODO() //@item(ctxTODO, "context.TODO", "func() context.Context", "func", "TODO returns a non-nil, empty Context.") - --func helper(i foo.IntFoo) {} //@item(helper, "helper", "func(i foo.IntFoo)", "func") +- wantsContext(c) //@rank(")", ctxBackground),rank(")", ctxTODO) +-} - -func _() { -- help //@complete("l", helper) -- _ = foo.StructFoo{} //@complete("S", IntFoo, StructFoo) +- var cork struct{ err error } +- cork.err //@item(deepCorkErr, "cork.err", "error", "field") +- context //@item(deepContextPkg, "context", "\"context\"", "package") +- var _ error = co //@rank(" //", deepCorkErr, deepContextPkg) -} - --// Bar is a function. --func Bar() { //@item(Bar, "Bar", "func()", "func", "Bar is a function.") -- foo.Foo() //@complete("F", Foo, IntFoo, StructFoo) -- var _ foo.IntFoo //@complete("I", IntFoo, StructFoo) -- foo.() //@complete("(", Foo, IntFoo, StructFoo) +-func _() { +- // deepCircle is circular. +- type deepCircle struct { +- *deepCircle +- } +- var circle deepCircle //@item(deepCircle, "circle", "deepCircle", "var") +- circle.deepCircle //@item(deepCircleField, "circle.deepCircle", "*deepCircle", "field") +- var _ deepCircle = circ //@deep(" //", deepCircle, deepCircleField),snippet(" //", deepCircleField, "*circle.deepCircle", "*circle.deepCircle") -} - -func _() { -- var Valentine int //@item(Valentine, "Valentine", "int", "var") -- -- _ = foo.StructFoo{ -- Valu //@complete(" //", Value) -- } -- _ = foo.StructFoo{ -- Va //@complete("a", Value, Valentine) -- } -- _ = foo.StructFoo{ -- Value: 5, //@complete("a", Value) -- } -- _ = foo.StructFoo{ -- //@complete("", Value, Valentine, foo, helper, Bar) -- } -- _ = foo.StructFoo{ -- Value: Valen //@complete("le", Valentine) +- type deepEmbedC struct { - } -- _ = foo.StructFoo{ -- Value: //@complete(" //", Valentine, foo, helper, Bar) +- type deepEmbedB struct { +- deepEmbedC - } -- _ = foo.StructFoo{ -- Value: //@complete(" ", Valentine, foo, helper, Bar) +- type deepEmbedA struct { +- deepEmbedB - } +- +- wantsC := func(deepEmbedC) {} +- +- var a deepEmbedA //@item(deepEmbedA, "a", "deepEmbedA", "var") +- a.deepEmbedB //@item(deepEmbedB, "a.deepEmbedB", "deepEmbedB", "field") +- a.deepEmbedC //@item(deepEmbedC, "a.deepEmbedC", "deepEmbedC", "field") +- wantsC(a) //@deep(")", deepEmbedC, deepEmbedA, deepEmbedB) -} -diff -urN a/gopls/internal/lsp/testdata/basiclit/basiclit.go b/gopls/internal/lsp/testdata/basiclit/basiclit.go ---- a/gopls/internal/lsp/testdata/basiclit/basiclit.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/basiclit/basiclit.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package basiclit - -func _() { -- var a int // something for lexical completions +- type nested struct { +- a int +- n *nested //@item(deepNestedField, "n", "*nested", "field") +- } - -- _ = "hello." //@complete(".") +- nested{ +- a: 123, //@deep(" //", deepNestedField) +- } +-} - -- _ = 1 //@complete(" //") +-func _() { +- var a struct { +- b struct { +- c int +- } +- d int +- } - -- _ = 1. //@complete(".") +- a.d //@item(deepAD, "a.d", "int", "field") +- a.b.c //@item(deepABC, "a.b.c", "int", "field") +- a.b //@item(deepAB, "a.b", "struct{...}", "field") +- a //@item(deepA, "a", "struct{...}", "var") - -- _ = 'a' //@complete("' ") +- // "a.d" should be ranked above the deeper "a.b.c" +- var i int +- i = a //@deep(" //", deepAD, deepABC, deepA, deepAB) -} -diff -urN a/gopls/internal/lsp/testdata/baz/baz.go.in b/gopls/internal/lsp/testdata/baz/baz.go.in ---- a/gopls/internal/lsp/testdata/baz/baz.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/baz/baz.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,33 +0,0 @@ --// +build go1.11 - --package baz +-type foo struct { +- b bar +-} - --import ( -- "golang.org/lsptests/bar" +-func (f foo) bar() bar { +- return f.b +-} - -- f "golang.org/lsptests/foo" --) +-func (f foo) barPtr() *bar { +- return &f.b +-} - --var FooStruct f.StructFoo +-type bar struct{} - --func Baz() { -- defer bar.Bar() //@complete("B", Bar) -- // TODO(rstambler): Test completion here. -- defer bar.B -- var x f.IntFoo //@complete("n", IntFoo),typdef("x", IntFoo) -- bar.Bar() //@complete("B", Bar) +-func (b bar) valueReceiver() int { +- return 0 -} - --func _() { -- bob := f.StructFoo{Value: 5} -- if x := bob. //@complete(" //", Value) -- switch true == false { -- case true: -- if x := bob. //@complete(" //", Value) -- case false: -- } -- if x := bob.Va //@complete("a", Value) -- switch true == true { -- default: -- } +-func (b *bar) ptrReceiver() int { +- return 0 -} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_args.go b/gopls/internal/lsp/testdata/builtins/builtin_args.go ---- a/gopls/internal/lsp/testdata/builtins/builtin_args.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtin_args.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,62 +0,0 @@ --package builtins - -func _() { - var ( -- aSlice []int //@item(builtinSlice, "aSlice", "[]int", "var") -- aMap map[string]int //@item(builtinMap, "aMap", "map[string]int", "var") -- aString string //@item(builtinString, "aString", "string", "var") -- aArray [0]int //@item(builtinArray, "aArray", "[0]int", "var") -- aArrayPtr *[0]int //@item(builtinArrayPtr, "aArrayPtr", "*[0]int", "var") -- aChan chan int //@item(builtinChan, "aChan", "chan int", "var") -- aPtr *int //@item(builtinPtr, "aPtr", "*int", "var") -- aInt int //@item(builtinInt, "aInt", "int", "var") -- ) -- -- type ( -- aSliceType []int //@item(builtinSliceType, "aSliceType", "[]int", "type") -- aChanType chan int //@item(builtinChanType, "aChanType", "chan int", "type") -- aMapType map[string]int //@item(builtinMapType, "aMapType", "map[string]int", "type") +- i int +- f foo - ) - -- close() //@rank(")", builtinChan, builtinSlice) -- -- append() //@rank(")", builtinSlice, builtinChan) -- -- var _ []byte = append([]byte(nil), ""...) //@rank(") //") +- f.bar().valueReceiver //@item(deepBarValue, "f.bar().valueReceiver", "func() int", "method") +- f.barPtr().ptrReceiver //@item(deepBarPtrPtr, "f.barPtr().ptrReceiver", "func() int", "method") +- f.barPtr().valueReceiver //@item(deepBarPtrValue, "f.barPtr().valueReceiver", "func() int", "method") - -- copy() //@rank(")", builtinSlice, builtinChan) -- copy(aSlice, aS) //@rank(")", builtinSlice, builtinString) -- copy(aS, aSlice) //@rank(",", builtinSlice, builtinString) +- i = fbar //@fuzzy(" //", deepBarValue, deepBarPtrPtr, deepBarPtrValue) +-} - -- delete() //@rank(")", builtinMap, builtinChan) -- delete(aMap, aS) //@rank(")", builtinString, builtinSlice) +-func (b baz) Thing() struct{ val int } { +- return b.thing +-} - -- aMapFunc := func() map[int]int { //@item(builtinMapFunc, "aMapFunc", "func() map[int]int", "var") -- return nil -- } -- delete() //@rank(")", builtinMapFunc, builtinSlice) +-type baz struct { +- thing struct{ val int } +-} - -- len() //@rank(")", builtinSlice, builtinInt),rank(")", builtinMap, builtinInt),rank(")", builtinString, builtinInt),rank(")", builtinArray, builtinInt),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) +-func (b baz) _() { +- b.Thing().val //@item(deepBazMethVal, "b.Thing().val", "int", "field") +- b.thing.val //@item(deepBazFieldVal, "b.thing.val", "int", "field") +- var _ int = bval //@rank(" //", deepBazFieldVal, deepBazMethVal) +-} +diff -urN a/gopls/internal/lsp/testdata/embeddirective/embed.txt b/gopls/internal/lsp/testdata/embeddirective/embed.txt +--- a/gopls/internal/lsp/testdata/embeddirective/embed.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/embeddirective/embed.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-text +diff -urN a/gopls/internal/lsp/testdata/embeddirective/fix_import.go b/gopls/internal/lsp/testdata/embeddirective/fix_import.go +--- a/gopls/internal/lsp/testdata/embeddirective/fix_import.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/embeddirective/fix_import.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- cap() //@rank(")", builtinSlice, builtinMap),rank(")", builtinArray, builtinString),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt) +-package embeddirective - -- make() //@rank(")", builtinMapType, int),rank(")", builtinChanType, int),rank(")", builtinSliceType, int),rank(")", builtinMapType, int) -- make(aSliceType, a) //@rank(")", builtinInt, builtinSlice) +-import ( +- "io" +- "os" +-) - -- type myInt int -- var mi myInt //@item(builtinMyInt, "mi", "myInt", "var") -- make(aSliceType, m) //@snippet(")", builtinMyInt, "mi", "mi") +-//go:embed embed.txt //@suggestedfix("//go:embed", "quickfix", "") +-var t string - -- var _ []int = make() //@rank(")", builtinSliceType, builtinMapType) +-func unused() { +- _ = os.Stdin +- _ = io.EOF +-} +diff -urN a/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden b/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden +--- a/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/embeddirective/fix_import.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +--- suggestedfix_fix_import_12_1 -- +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct") -- var _ *myStruct = new() //@rank(")", builtinStructType, int) +-package embeddirective - -- for k := range a { //@rank(" {", builtinSlice, builtinInt),rank(" {", builtinString, builtinInt),rank(" {", builtinChan, builtinInt),rank(" {", builtinArray, builtinInt),rank(" {", builtinArrayPtr, builtinInt),rank(" {", builtinMap, builtinInt), -- } +-import ( +- _ "embed" +- "io" +- "os" +-) - -- for k, v := range a { //@rank(" {", builtinSlice, builtinChan) -- } +-//go:embed embed.txt //@suggestedfix("//go:embed", "quickfix", "") +-var t string - -- <-a //@rank(" //", builtinChan, builtinInt) +-func unused() { +- _ = os.Stdin +- _ = io.EOF -} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_go117.go b/gopls/internal/lsp/testdata/builtins/builtin_go117.go ---- a/gopls/internal/lsp/testdata/builtins/builtin_go117.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtin_go117.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --//go:build !go1.18 --// +build !go1.18 - --package builtins +diff -urN a/gopls/internal/lsp/testdata/errors/errors.go b/gopls/internal/lsp/testdata/errors/errors.go +--- a/gopls/internal/lsp/testdata/errors/errors.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/errors/errors.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-package errors +- +-import ( +- "golang.org/lsptests/types" +-) - -func _() { -- //@complete("", append, bool, byte, cap, close, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, _nil) +- bob.Bob() //@complete(".") +- types.b //@complete(" //", Bob_interface) -} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_go118.go b/gopls/internal/lsp/testdata/builtins/builtin_go118.go ---- a/gopls/internal/lsp/testdata/builtins/builtin_go118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtin_go118.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --//go:build go1.18 && !go1.21 --// +build go1.18,!go1.21 +diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go +--- a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-package extract - --package builtins +-type A struct { +- x int +- y int +-} - --func _() { -- //@complete("", any, append, bool, byte, cap, close, comparable, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, _nil) +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_go121.go b/gopls/internal/lsp/testdata/builtins/builtin_go121.go ---- a/gopls/internal/lsp/testdata/builtins/builtin_go121.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtin_go121.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --//go:build go1.21 --// +build go1.21 - --package builtins +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - --func _() { -- //@complete("", any, append, bool, byte, cap, clear, close, comparable, complex, complex128, complex64, copy, delete, error, _false, float32, float64, imag, int, int16, int32, int64, int8, len, make, new, panic, print, println, real, recover, rune, string, _true, uint, uint16, uint32, uint64, uint8, uintptr, _nil) +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} -diff -urN a/gopls/internal/lsp/testdata/builtins/builtins.go b/gopls/internal/lsp/testdata/builtins/builtins.go ---- a/gopls/internal/lsp/testdata/builtins/builtins.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtins.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,47 +0,0 @@ --package builtins - --// Definitions of builtin completion items. +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} +diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden +--- a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,364 +0,0 @@ +--- functionextraction_extract_basic_13_2 -- +-package extract - --/* any */ //@item(any, "any", "", "interface") --/* Create markers for builtin types. Only for use by this test. --/* append(slice []Type, elems ...Type) []Type */ //@item(append, "append", "func(slice []Type, elems ...Type) []Type", "func") --/* bool */ //@item(bool, "bool", "", "type") --/* byte */ //@item(byte, "byte", "", "type") --/* cap(v Type) int */ //@item(cap, "cap", "func(v Type) int", "func") --/* clear[T interface{ ~[]Type | ~map[Type]Type1 }](t T) */ //@item(clear, "clear", "func(t T)", "func") --/* close(c chan<- Type) */ //@item(close, "close", "func(c chan<- Type)", "func") --/* comparable */ //@item(comparable, "comparable", "", "interface") --/* complex(r float64, i float64) */ //@item(complex, "complex", "func(r float64, i float64) complex128", "func") --/* complex128 */ //@item(complex128, "complex128", "", "type") --/* complex64 */ //@item(complex64, "complex64", "", "type") --/* copy(dst []Type, src []Type) int */ //@item(copy, "copy", "func(dst []Type, src []Type) int", "func") --/* delete(m map[Type]Type1, key Type) */ //@item(delete, "delete", "func(m map[Type]Type1, key Type)", "func") --/* error */ //@item(error, "error", "", "interface") --/* false */ //@item(_false, "false", "", "const") --/* float32 */ //@item(float32, "float32", "", "type") --/* float64 */ //@item(float64, "float64", "", "type") --/* imag(c complex128) float64 */ //@item(imag, "imag", "func(c complex128) float64", "func") --/* int */ //@item(int, "int", "", "type") --/* int16 */ //@item(int16, "int16", "", "type") --/* int32 */ //@item(int32, "int32", "", "type") --/* int64 */ //@item(int64, "int64", "", "type") --/* int8 */ //@item(int8, "int8", "", "type") --/* iota */ //@item(iota, "iota", "", "const") --/* len(v Type) int */ //@item(len, "len", "func(v Type) int", "func") --/* make(t Type, size ...int) Type */ //@item(make, "make", "func(t Type, size ...int) Type", "func") --/* new(Type) *Type */ //@item(new, "new", "func(Type) *Type", "func") --/* nil */ //@item(_nil, "nil", "", "var") --/* panic(v interface{}) */ //@item(panic, "panic", "func(v interface{})", "func") --/* print(args ...Type) */ //@item(print, "print", "func(args ...Type)", "func") --/* println(args ...Type) */ //@item(println, "println", "func(args ...Type)", "func") --/* real(c complex128) float64 */ //@item(real, "real", "func(c complex128) float64", "func") --/* recover() interface{} */ //@item(recover, "recover", "func() interface{}", "func") --/* rune */ //@item(rune, "rune", "", "type") --/* string */ //@item(string, "string", "", "type") --/* true */ //@item(_true, "true", "", "const") --/* uint */ //@item(uint, "uint", "", "type") --/* uint16 */ //@item(uint16, "uint16", "", "type") --/* uint32 */ //@item(uint32, "uint32", "", "type") --/* uint64 */ //@item(uint64, "uint64", "", "type") --/* uint8 */ //@item(uint8, "uint8", "", "type") --/* uintptr */ //@item(uintptr, "uintptr", "", "type") -diff -urN a/gopls/internal/lsp/testdata/builtins/builtin_types.go b/gopls/internal/lsp/testdata/builtins/builtin_types.go ---- a/gopls/internal/lsp/testdata/builtins/builtin_types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/builtin_types.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package builtins +-type A struct { +- x int +- y int +-} - --func _() { -- var _ []bool //@item(builtinBoolSliceType, "[]bool", "[]bool", "type") +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - -- var _ []bool = make() //@rank(")", builtinBoolSliceType, int) +-func (a *A) AddP() int { +- sum := newFunction(a) //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - -- var _ []bool = make([], 0) //@rank(",", bool, int) +-func newFunction(a *A) int { +- sum := a.x + a.y +- return sum +-} - -- var _ [][]bool = make([][], 0) //@rank(",", bool, int) +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} -diff -urN a/gopls/internal/lsp/testdata/builtins/constants.go b/gopls/internal/lsp/testdata/builtins/constants.go ---- a/gopls/internal/lsp/testdata/builtins/constants.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/builtins/constants.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ --package builtins - --func _() { -- const ( -- foo = iota //@complete(" //", iota) -- ) +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - -- iota //@complete(" //") +--- functionextraction_extract_basic_14_2 -- +-package extract - -- var iota int //@item(iotaVar, "iota", "int", "var") +-type A struct { +- x int +- y int +-} - -- iota //@complete(" //", iotaVar) +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} - --func _() { -- var twoRedUpEnd bool //@item(TRUEVar, "twoRedUpEnd", "bool", "var") +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return newFunction(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - -- var _ bool = true //@rank(" //", _true, TRUEVar) +-func newFunction(sum int) int { +- return sum -} -diff -urN a/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go b/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go ---- a/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/callhierarchy/callhierarchy.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,70 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package callhierarchy +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --import "golang.org/lsptests/callhierarchy/outgoing" +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - --func a() { //@mark(hierarchyA, "a") -- D() +--- functionextraction_extract_basic_18_2 -- +-package extract +- +-type A struct { +- x int +- y int -} - --func b() { //@mark(hierarchyB, "b") -- D() +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} - --// C is an exported function --func C() { //@mark(hierarchyC, "C") -- D() -- D() +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} - --// To test hierarchy across function literals --var x = func() { //@mark(hierarchyLiteral, "func"),mark(hierarchyLiteralOut, "x") -- D() +-func (a A) XLessThanY() bool { +- return newFunction(a) //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} - --// D is exported to test incoming/outgoing calls across packages --func D() { //@mark(hierarchyD, "D"),incomingcalls(hierarchyD, hierarchyA, hierarchyB, hierarchyC, hierarchyLiteral, incomingA),outgoingcalls(hierarchyD, hierarchyE, hierarchyF, hierarchyG, hierarchyLiteralOut, outgoingB, hierarchyFoo, hierarchyH, hierarchyI, hierarchyJ, hierarchyK) -- e() -- x() -- F() -- outgoing.B() -- foo := func() {} //@mark(hierarchyFoo, "foo"),incomingcalls(hierarchyFoo, hierarchyD),outgoingcalls(hierarchyFoo) -- foo() +-func newFunction(a A) bool { +- return a.x < a.y +-} - -- func() { -- g() -- }() +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - -- var i Interface = impl{} -- i.H() -- i.I() +--- functionextraction_extract_basic_22_2 -- +-package extract - -- s := Struct{} -- s.J() -- s.K() +-type A struct { +- x int +- y int -} - --func e() {} //@mark(hierarchyE, "e") +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --// F is an exported function --func F() {} //@mark(hierarchyF, "F") +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - --func g() {} //@mark(hierarchyG, "g") +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --type Interface interface { -- H() //@mark(hierarchyH, "H") -- I() //@mark(hierarchyI, "I") +-func (a A) Add() int { +- sum := newFunction(a) //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} - --type impl struct{} +-func newFunction(a A) int { +- sum := a.x + a.y +- return sum +-} - --func (i impl) H() {} --func (i impl) I() {} +--- functionextraction_extract_basic_23_2 -- +-package extract - --type Struct struct { -- J func() //@mark(hierarchyJ, "J") -- K func() //@mark(hierarchyK, "K") +-type A struct { +- x int +- y int -} -diff -urN a/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go b/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go ---- a/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/callhierarchy/incoming/incoming.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package incoming -- --import "golang.org/lsptests/callhierarchy" +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --// A is exported to test incoming calls across packages --func A() { //@mark(incomingA, "A") -- callhierarchy.D() +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} -diff -urN a/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go b/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go ---- a/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/callhierarchy/outgoing/outgoing.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package outgoing +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --// B is exported to test outgoing calls across packages --func B() { //@mark(outgoingB, "B") +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return newFunction(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") -} -diff -urN a/gopls/internal/lsp/testdata/casesensitive/casesensitive.go b/gopls/internal/lsp/testdata/casesensitive/casesensitive.go ---- a/gopls/internal/lsp/testdata/casesensitive/casesensitive.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/casesensitive/casesensitive.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package casesensitive +-func newFunction(sum int) int { +- return sum +-} - --func _() { -- var lower int //@item(lower, "lower", "int", "var") -- var Upper int //@item(upper, "Upper", "int", "var") +--- functionextraction_extract_basic_9_2 -- +-package extract - -- l //@casesensitive(" //", lower) -- U //@casesensitive(" //", upper) +-type A struct { +- x int +- y int +-} - -- L //@casesensitive(" //") -- u //@casesensitive(" //") +-func (a *A) XLessThanYP() bool { +- return newFunction(a) //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} -diff -urN a/gopls/internal/lsp/testdata/cast/cast.go.in b/gopls/internal/lsp/testdata/cast/cast.go.in ---- a/gopls/internal/lsp/testdata/cast/cast.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/cast/cast.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package cast - --func _() { -- foo := struct{x int}{x: 1} //@item(x_field, "x", "int", "field") -- _ = float64(foo.x) //@complete("x", x_field) +-func newFunction(a *A) bool { +- return a.x < a.y -} - --func _() { -- foo := struct{x int}{x: 1} -- _ = float64(foo. //@complete(" /", x_field) +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/cgo/declarecgo.go b/gopls/internal/lsp/testdata/cgo/declarecgo.go ---- a/gopls/internal/lsp/testdata/cgo/declarecgo.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/cgo/declarecgo.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package cgo - --/* --#include --#include +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --void myprint(char* s) { -- printf("%s\n", s); +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} --*/ --import "C" - --import ( -- "fmt" -- "unsafe" --) +--- methodextraction_extract_basic_13_2 -- +-package extract - --func Example() { //@mark(funccgoexample, "Example"),item(funccgoexample, "Example", "func()", "func") -- fmt.Println() -- cs := C.CString("Hello from stdio\n") -- C.myprint(cs) -- C.free(unsafe.Pointer(cs)) +-type A struct { +- x int +- y int -} - --func _() { -- Example() //@godef("ample", funccgoexample),complete("ample", funccgoexample) +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} -diff -urN a/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden b/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden ---- a/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,30 +0,0 @@ ---- funccgoexample-definition -- --cgo/declarecgo.go:18:6-13: defined here as ```go --func Example() --``` - --[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) ---- funccgoexample-definition-json -- --{ -- "span": { -- "uri": "file://cgo/declarecgo.go", -- "start": { -- "line": 18, -- "column": 6, -- "offset": 151 -- }, -- "end": { -- "line": 18, -- "column": 13, -- "offset": 158 -- } -- }, -- "description": "```go\nfunc Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)" +-func (a *A) AddP() int { +- sum := a.newMethod() //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} - ---- funccgoexample-hoverdef -- --```go --func Example() --``` +-func (a *A) newMethod() int { +- sum := a.x + a.y +- return sum +-} - --[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) -diff -urN a/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go b/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go ---- a/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --//+build !cgo +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --package cgo +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - --// Set a dummy marker to keep the test framework happy. The tests should be skipped. --var _ = "Example" //@mark(funccgoexample, "Example"),godef("ample", funccgoexample),complete("ample", funccgoexample) -diff -urN a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden ---- a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,30 +0,0 @@ ---- funccgoexample-definition -- --cgo/declarecgo.go:18:6-13: defined here as ```go --func cgo.Example() --``` +--- methodextraction_extract_basic_14_2 -- +-package extract - --[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) ---- funccgoexample-definition-json -- --{ -- "span": { -- "uri": "file://cgo/declarecgo.go", -- "start": { -- "line": 18, -- "column": 6, -- "offset": 151 -- }, -- "end": { -- "line": 18, -- "column": 13, -- "offset": 158 -- } -- }, -- "description": "```go\nfunc cgo.Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)" +-type A struct { +- x int +- y int -} - ---- funccgoexample-hoverdef -- --```go --func cgo.Example() --``` -- --[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example) -diff -urN a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in ---- a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package cgoimport +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --import ( -- "golang.org/lsptests/cgo" --) +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return a.newMethod(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - --func _() { -- cgo.Example() //@godef("ample", funccgoexample),complete("ample", funccgoexample) +-func (*A) newMethod(sum int) int { +- return sum -} -diff -urN a/gopls/internal/lsp/testdata/channel/channel.go b/gopls/internal/lsp/testdata/channel/channel.go ---- a/gopls/internal/lsp/testdata/channel/channel.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/channel/channel.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,25 +0,0 @@ --package channel - --func _() { -- var ( -- aa = "123" //@item(channelAA, "aa", "string", "var") -- ab = 123 //@item(channelAB, "ab", "int", "var") -- ) +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - -- { -- type myChan chan int -- var mc myChan -- mc <- a //@complete(" //", channelAB, channelAA) -- } +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - -- { -- var ac chan int //@item(channelAC, "ac", "chan int", "var") -- a <- a //@complete(" <-", channelAC, channelAA, channelAB) -- } +--- methodextraction_extract_basic_18_2 -- +-package extract - -- { -- var foo chan int //@item(channelFoo, "foo", "chan int", "var") -- wantsInt := func(int) {} //@item(channelWantsInt, "wantsInt", "func(int)", "var") -- wantsInt(<-) //@rank(")", channelFoo, channelAB) -- } +-type A struct { +- x int +- y int -} -diff -urN a/gopls/internal/lsp/testdata/codelens/codelens_test.go b/gopls/internal/lsp/testdata/codelens/codelens_test.go ---- a/gopls/internal/lsp/testdata/codelens/codelens_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/codelens/codelens_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ --package codelens //@codelens("package codelens", "run file benchmarks", "test") -- --import "testing" - --func TestMain(m *testing.M) {} // no code lens for TestMain +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - --func TestFuncWithCodeLens(t *testing.T) { //@codelens("func", "run test", "test") +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} - --func thisShouldNotHaveACodeLens(t *testing.T) { +-func (a A) XLessThanY() bool { +- return a.newMethod() //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} - --func BenchmarkFuncWithCodeLens(b *testing.B) { //@codelens("func", "run benchmark", "test") +-func (a A) newMethod() bool { +- return a.x < a.y -} - --func helper() {} // expect no code lens -diff -urN a/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in b/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in ---- a/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/comment_completion/comment_completion.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,70 +0,0 @@ --package comment_completion +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - --var p bool +--- methodextraction_extract_basic_22_2 -- +-package extract - --//@complete(re"$") +-type A struct { +- x int +- y int +-} - --func _() { -- var a int +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - -- switch a { -- case 1: -- //@complete(re"$") -- _ = a -- } +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - -- var b chan int -- select { -- case <-b: -- //@complete(re"$") -- _ = b -- } +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - -- var ( -- //@complete(re"$") -- _ = a -- ) +-func (a A) Add() int { +- sum := a.newMethod() //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} - --// //@complete(" ", variableC) --var C string //@item(variableC, "C", "string", "var") //@complete(" ", variableC) +-func (a A) newMethod() int { +- sum := a.x + a.y +- return sum +-} - --// //@complete(" ", constant) --const Constant = "example" //@item(constant, "Constant", "string", "const") //@complete(" ", constant) +--- methodextraction_extract_basic_23_2 -- +-package extract - --// //@complete(" ", structType, fieldB, fieldA) --type StructType struct { //@item(structType, "StructType", "struct{...}", "struct") //@complete(" ", structType, fieldA, fieldB) -- // //@complete(" ", fieldA, structType, fieldB) -- A string //@item(fieldA, "A", "string", "field") //@complete(" ", fieldA, structType, fieldB) -- b int //@item(fieldB, "b", "int", "field") //@complete(" ", fieldB, structType, fieldA) +-type A struct { +- x int +- y int -} - --// //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) --func (structType *StructType) Method(X int) (Y int) { //@item(structRecv, "structType", "*StructType", "var"),item(method, "Method", "func(X int) (Y int)", "method"),item(paramX, "X", "int", "var"),item(resultY, "Y", "int", "var") -- // //@complete(" ", method, structRecv, paramX, resultY, fieldB, fieldA) -- return +-func (a *A) XLessThanYP() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} - --// //@complete(" ", newType) --type NewType string //@item(newType, "NewType", "string", "type") //@complete(" ", newType) +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - --// //@complete(" ", testInterface, testA, testB) --type TestInterface interface { //@item(testInterface, "TestInterface", "interface{...}", "interface") -- // //@complete(" ", testA, testInterface, testB) -- TestA(L string) (M int) //@item(testA, "TestA", "func(L string) (M int)", "method"),item(paramL, "L", "var", "string"),item(resM, "M", "var", "int") //@complete(" ", testA, testInterface, testB) -- TestB(N int) bool //@item(testB, "TestB", "func(N int) bool", "method"),item(paramN, "N", "var", "int") //@complete(" ", testB, testInterface, testA) +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") -} - --// //@complete(" ", function) --func Function() int { //@item(function, "Function", "func() int", "func") //@complete(" ", function) -- // //@complete(" ", function) -- return 0 +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return a.newMethod(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") -} - --// This tests multiline block comments and completion with prefix --// Lorem Ipsum Multili//@complete("Multi", multiline) --// Lorem ipsum dolor sit ametom --func Multiline() int { //@item(multiline, "Multiline", "func() int", "func") -- // //@complete(" ", multiline) -- return 0 +-func (A) newMethod(sum int) int { +- return sum -} -diff -urN a/gopls/internal/lsp/testdata/complit/complit.go.in b/gopls/internal/lsp/testdata/complit/complit.go.in ---- a/gopls/internal/lsp/testdata/complit/complit.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/complit/complit.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,90 +0,0 @@ --package complit - --// general completions +--- methodextraction_extract_basic_9_2 -- +-package extract - --type position struct { //@item(structPosition, "position", "struct{...}", "struct") -- X, Y int //@item(fieldX, "X", "int", "field"),item(fieldY, "Y", "int", "field") +-type A struct { +- x int +- y int -} - --func _() { -- _ = position{ -- //@complete("", fieldX, fieldY, structPosition) -- } -- _ = position{ -- X: 1, -- //@complete("", fieldY) -- } -- _ = position{ -- //@complete("", fieldX) -- Y: 1, -- } -- _ = []*position{ -- { -- //@complete("", fieldX, fieldY, structPosition) -- }, -- } +-func (a *A) XLessThanYP() bool { +- return a.newMethod() //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} +- +-func (a *A) newMethod() bool { +- return a.x < a.y +-} +- +-func (a *A) AddP() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") -} - --func _() { -- var ( -- aa string //@item(aaVar, "aa", "string", "var") -- ab int //@item(abVar, "ab", "int", "var") -- ) +-func (a A) XLessThanY() bool { +- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-} - -- _ = map[int]int{ -- a: a, //@complete(":", abVar, aaVar),complete(",", abVar, aaVar) -- } +-func (a A) Add() int { +- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") +- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-} - -- _ = map[int]int{ -- //@complete("", abVar, aaVar, structPosition) -- } +diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go +--- a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package extract - -- _ = []string{a: ""} //@complete(":", abVar, aaVar) -- _ = [1]string{a: ""} //@complete(":", abVar, aaVar) +-import "context" - -- _ = position{X: a} //@complete("}", abVar, aaVar) -- _ = position{a} //@complete("}", abVar, aaVar) -- _ = position{a, } //@complete("}", abVar, aaVar, structPosition) +-type B struct { +- x int +- y int +-} - -- _ = []int{a} //@complete("}", abVar, aaVar) -- _ = [1]int{a} //@complete("}", abVar, aaVar) +-func (b *B) AddP(ctx context.Context) (int, error) { +- sum := b.x + b.y +- return sum, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-} - -- type myStruct struct { -- AA int //@item(fieldAA, "AA", "int", "field") -- AB string //@item(fieldAB, "AB", "string", "field") -- } +-func (b *B) LongList(ctx context.Context) (int, error) { +- p1 := 1 +- p2 := 1 +- p3 := 1 +- return p1 + p2 + p3, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-} +diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden +--- a/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_context.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,52 +0,0 @@ +--- methodextraction_extract_context_12_2 -- +-package extract - -- _ = myStruct{ -- AB: a, //@complete(",", aaVar, abVar) -- } +-import "context" - -- var s myStruct +-type B struct { +- x int +- y int +-} - -- _ = map[int]string{1: "" + s.A} //@complete("}", fieldAB, fieldAA) -- _ = map[int]string{1: (func(i int) string { return "" })(s.A)} //@complete(")}", fieldAA, fieldAB) -- _ = map[int]string{1: func() string { s.A }} //@complete(" }", fieldAA, fieldAB) +-func (b *B) AddP(ctx context.Context) (int, error) { +- sum := b.x + b.y +- return b.newMethod(ctx, sum) //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-} - -- _ = position{s.A} //@complete("}", fieldAA, fieldAB) +-func (*B) newMethod(ctx context.Context, sum int) (int, error) { +- return sum, ctx.Err() +-} - -- var X int //@item(varX, "X", "int", "var") -- _ = position{X} //@complete("}", fieldX, varX) +-func (b *B) LongList(ctx context.Context) (int, error) { +- p1 := 1 +- p2 := 1 +- p3 := 1 +- return p1 + p2 + p3, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") -} - --func _() { -- type foo struct{} //@item(complitFoo, "foo", "struct{...}", "struct") +--- methodextraction_extract_context_19_2 -- +-package extract - -- var _ *foo = &fo{} //@snippet("{", complitFoo, "foo", "foo") -- var _ *foo = fo{} //@snippet("{", complitFoo, "&foo", "&foo") +-import "context" - -- struct { a, b *foo }{ -- a: &fo{}, //@rank("{", complitFoo) -- b: fo{}, //@snippet("{", complitFoo, "&foo", "&foo") -- } +-type B struct { +- x int +- y int -} - --func _() { -- _ := position{ -- X: 1, //@complete("X", fieldX),complete(" 1", structPosition) -- Y: , //@complete(":", fieldY),complete(" ,", structPosition) -- } +-func (b *B) AddP(ctx context.Context) (int, error) { +- sum := b.x + b.y +- return sum, ctx.Err() //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") -} -diff -urN a/gopls/internal/lsp/testdata/constant/constant.go b/gopls/internal/lsp/testdata/constant/constant.go ---- a/gopls/internal/lsp/testdata/constant/constant.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/constant/constant.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ --package constant - --const x = 1 //@item(constX, "x", "int", "const") +-func (b *B) LongList(ctx context.Context) (int, error) { +- p1 := 1 +- p2 := 1 +- p3 := 1 +- return b.newMethod(ctx, p1, p2, p3) //@extractmethod("return", "ctx.Err()"),extractfunc("return", "ctx.Err()") +-} - --const ( -- a int = iota << 2 //@item(constA, "a", "int", "const") -- b //@item(constB, "b", "int", "const") -- c //@item(constC, "c", "int", "const") --) +-func (*B) newMethod(ctx context.Context, p1 int, p2 int, p3 int) (int, error) { +- return p1 + p2 + p3, ctx.Err() +-} +- +diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go +--- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package extract - -func _() { -- const y = "hi" //@item(constY, "y", "string", "const") -- //@complete("", constY, constA, constB, constC, constX) +- var _ = 1 + 2 //@suggestedfix("1", "refactor.extract", "") +- var _ = 3 + 4 //@suggestedfix("3 + 4", "refactor.extract", "") -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt +diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden +--- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_extract_basic_lit_4_10 -- +-package extract - -func _() { -- for bar //@rank(" //", danglingBar) +- x := 1 +- var _ = x + 2 //@suggestedfix("1", "refactor.extract", "") +- var _ = 3 + 4 //@suggestedfix("3 + 4", "refactor.extract", "") -} - --func bar() bool { //@item(danglingBar, "bar", "func() bool", "func") -- return true --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt +--- suggestedfix_extract_basic_lit_5_10 -- +-package extract - -func _() { -- for i := bar3(); i > bar //@rank(" //", danglingBar3) +- var _ = 1 + 2 //@suggestedfix("1", "refactor.extract", "") +- x := 3 + 4 +- var _ = x //@suggestedfix("3 + 4", "refactor.extract", "") -} - --func bar3() int { //@item(danglingBar3, "bar3", "func() int", "func") -- return 0 --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init_cond_post.go 1970-01-01 00:00:00.000000000 +0000 +diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go +--- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ --package danglingstmt +-package extract +- +-import "strconv" - -func _() { -- for i := bar4(); i > bar4(); i += bar //@rank(" //", danglingBar4) +- x0 := append([]int{}, 1) //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") +- str := "1" +- b, err := strconv.Atoi(str) //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") -} +diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden +--- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +--- suggestedfix_extract_func_call_6_8 -- +-package extract - --func bar4() int { //@item(danglingBar4, "bar4", "func() int", "func") -- return 0 --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_for_init.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt +-import "strconv" - -func _() { -- for i := bar //@rank(" //", danglingBar2) --} -- --func bar2() int { //@item(danglingBar2, "bar2", "func() int", "func") -- return 0 +- x := append([]int{}, 1) +- x0 := x //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") +- str := "1" +- b, err := strconv.Atoi(str) //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_eof.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package danglingstmt - --func bar5() bool { //@item(danglingBar5, "bar5", "func() bool", "func") -- return true --} +--- suggestedfix_extract_func_call_8_12 -- +-package extract - --func _() { -- if b //@rank(" //", danglingBar5) -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt +-import "strconv" - -func _() { -- if foo //@rank(" //", danglingFoo) +- x0 := append([]int{}, 1) //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") +- str := "1" +- x, x1 := strconv.Atoi(str) +- b, err := x, x1 //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") -} - --func foo() bool { //@item(danglingFoo, "foo", "func() bool", "func") -- return true --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init_cond.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt +diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go +--- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package extract +- +-import "go/ast" - -func _() { -- if i := 123; foo //@rank(" //", danglingFoo3) +- x0 := 0 +- if true { +- y := ast.CompositeLit{} //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") +- } +- if true { +- x1 := !false //@suggestedfix("!false", "refactor.extract", "") +- } -} +diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden +--- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,32 +0,0 @@ +--- suggestedfix_extract_scope_11_9 -- +-package extract - --func foo3() bool { //@item(danglingFoo3, "foo3", "func() bool", "func") -- return true --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_if_init.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt +-import "go/ast" - -func _() { -- if i := foo //@rank(" //", danglingFoo2) +- x0 := 0 +- if true { +- y := ast.CompositeLit{} //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") +- } +- if true { +- x := !false +- x1 := x //@suggestedfix("!false", "refactor.extract", "") +- } -} - --func foo2() bool { //@item(danglingFoo2, "foo2", "func() bool", "func") -- return true --} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_multiline_if.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package danglingstmt +--- suggestedfix_extract_scope_8_8 -- +-package extract - --func walrus() bool { //@item(danglingWalrus, "walrus", "func() bool", "func") -- return true --} +-import "go/ast" - -func _() { -- if true && -- walrus //@complete(" //", danglingWalrus) +- x0 := 0 +- if true { +- x := ast.CompositeLit{} +- y := x //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") +- } +- if true { +- x1 := !false //@suggestedfix("!false", "refactor.extract", "") +- } -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_1.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package danglingstmt - --func _() { -- x. //@rank(" //", danglingI) --} +diff -urN a/gopls/internal/lsp/testdata/fieldlist/field_list.go b/gopls/internal/lsp/testdata/fieldlist/field_list.go +--- a/gopls/internal/lsp/testdata/fieldlist/field_list.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fieldlist/field_list.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package fieldlist - --var x struct { i int } //@item(danglingI, "i", "int", "field") -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package danglingstmt +-var myInt int //@item(flVar, "myInt", "int", "var") +-type myType int //@item(flType, "myType", "int", "type") - --import "golang.org/lsptests/foo" +-func (my) _() {} //@complete(") _", flType) +-func (my my) _() {} //@complete(" my)"),complete(") _", flType) +- +-func (myType) _() {} //@complete(") {", flType) +- +-func (myType) _(my my) {} //@complete(" my)"),complete(") {", flType) +- +-func (myType) _() my {} //@complete(" {", flType) +- +-func (myType) _() (my my) {} //@complete(" my"),complete(") {", flType) - -func _() { -- foo. //@rank(" //", Foo) -- var _ = []string{foo.} //@rank("}", Foo) +- var _ struct { +- //@complete("", flType) +- m my //@complete(" my"),complete(" //", flType) +- } +- +- var _ interface { +- //@complete("", flType) +- m() my //@complete("("),complete(" //", flType) +- } -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a2.go b/gopls/internal/lsp/testdata/fillstruct/a2.go +--- a/gopls/internal/lsp/testdata/fillstruct/a2.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a2.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-package fillstruct - --func _() { -- switch i := baz //@rank(" //", danglingBaz) +-type typedStruct struct { +- m map[string]int +- s []int +- c chan int +- c1 <-chan int +- a [2]string -} - --func baz() int { //@item(danglingBaz, "baz", "func() int", "func") -- return 0 +-var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStruct struct { +- fn func(i int) int -} -diff -urN a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go ---- a/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_switch_init_tag.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package danglingstmt - --func _() { -- switch i := 0; baz //@rank(" //", danglingBaz2) +-var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStructCompex struct { +- fn func(i int, s string) (string, int) -} - --func baz2() int { //@item(danglingBaz2, "baz2", "func() int", "func") -- return 0 +-var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStructEmpty struct { +- fn func() -} -diff -urN a/gopls/internal/lsp/testdata/deep/deep.go b/gopls/internal/lsp/testdata/deep/deep.go ---- a/gopls/internal/lsp/testdata/deep/deep.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/deep/deep.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,142 +0,0 @@ --package deep - --import "context" +-var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a2.go.golden b/gopls/internal/lsp/testdata/fillstruct/a2.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/a2.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a2.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,139 +0,0 @@ +--- suggestedfix_a2_11_21 -- +-package fillstruct - --type deepA struct { -- b deepB //@item(deepBField, "b", "deepB", "field") +-type typedStruct struct { +- m map[string]int +- s []int +- c chan int +- c1 <-chan int +- a [2]string -} - --type deepB struct { +-var _ = typedStruct{ +- m: map[string]int{}, +- s: []int{}, +- c: make(chan int), +- c1: make(<-chan int), +- a: [2]string{}, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStruct struct { +- fn func(i int) int -} - --func wantsDeepB(deepB) {} +-var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- var a deepA //@item(deepAVar, "a", "deepA", "var") -- a.b //@item(deepABField, "a.b", "deepB", "field") -- wantsDeepB(a) //@deep(")", deepABField, deepAVar) +-type funStructCompex struct { +- fn func(i int, s string) (string, int) +-} - -- deepA{a} //@snippet("}", deepABField, "a.b", "a.b") +-var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStructEmpty struct { +- fn func() -} - --func wantsContext(context.Context) {} +-var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- context.Background() //@item(ctxBackground, "context.Background", "func() context.Context", "func", "Background returns a non-nil, empty Context.") -- context.TODO() //@item(ctxTODO, "context.TODO", "func() context.Context", "func", "TODO returns a non-nil, empty Context.") +--- suggestedfix_a2_17_19 -- +-package fillstruct - -- wantsContext(c) //@rank(")", ctxBackground),rank(")", ctxTODO) +-type typedStruct struct { +- m map[string]int +- s []int +- c chan int +- c1 <-chan int +- a [2]string -} - --func _() { -- var cork struct{ err error } -- cork.err //@item(deepCorkErr, "cork.err", "error", "field") -- context //@item(deepContextPkg, "context", "\"context\"", "package") -- var _ error = co //@rank(" //", deepCorkErr, deepContextPkg) +-var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStruct struct { +- fn func(i int) int -} - --func _() { -- // deepCircle is circular. -- type deepCircle struct { -- *deepCircle -- } -- var circle deepCircle //@item(deepCircle, "circle", "deepCircle", "var") -- circle.deepCircle //@item(deepCircleField, "circle.deepCircle", "*deepCircle", "field") -- var _ deepCircle = circ //@deep(" //", deepCircle, deepCircleField),snippet(" //", deepCircleField, "*circle.deepCircle", "*circle.deepCircle") +-var _ = funStruct{ +- fn: func(i int) int { +- }, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStructCompex struct { +- fn func(i int, s string) (string, int) -} - --func _() { -- type deepEmbedC struct { -- } -- type deepEmbedB struct { -- deepEmbedC -- } -- type deepEmbedA struct { -- deepEmbedB -- } +-var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- wantsC := func(deepEmbedC) {} +-type funStructEmpty struct { +- fn func() +-} - -- var a deepEmbedA //@item(deepEmbedA, "a", "deepEmbedA", "var") -- a.deepEmbedB //@item(deepEmbedB, "a.deepEmbedB", "deepEmbedB", "field") -- a.deepEmbedC //@item(deepEmbedC, "a.deepEmbedC", "deepEmbedC", "field") -- wantsC(a) //@deep(")", deepEmbedC, deepEmbedA, deepEmbedB) +-var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +--- suggestedfix_a2_23_25 -- +-package fillstruct +- +-type typedStruct struct { +- m map[string]int +- s []int +- c chan int +- c1 <-chan int +- a [2]string -} - --func _() { -- type nested struct { -- a int -- n *nested //@item(deepNestedField, "n", "*nested", "field") -- } +-var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- nested{ -- a: 123, //@deep(" //", deepNestedField) -- } +-type funStruct struct { +- fn func(i int) int -} - --func _() { -- var a struct { -- b struct { -- c int -- } -- d int -- } +-var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- a.d //@item(deepAD, "a.d", "int", "field") -- a.b.c //@item(deepABC, "a.b.c", "int", "field") -- a.b //@item(deepAB, "a.b", "struct{...}", "field") -- a //@item(deepA, "a", "struct{...}", "var") +-type funStructCompex struct { +- fn func(i int, s string) (string, int) +-} - -- // "a.d" should be ranked above the deeper "a.b.c" -- var i int -- i = a //@deep(" //", deepAD, deepABC, deepA, deepAB) +-var _ = funStructCompex{ +- fn: func(i int, s string) (string, int) { +- }, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStructEmpty struct { +- fn func() -} - --type foo struct { -- b bar +-var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +--- suggestedfix_a2_29_24 -- +-package fillstruct +- +-type typedStruct struct { +- m map[string]int +- s []int +- c chan int +- c1 <-chan int +- a [2]string -} - --func (f foo) bar() bar { -- return f.b --} +-var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (f foo) barPtr() *bar { -- return &f.b +-type funStruct struct { +- fn func(i int) int -} - --type bar struct{} +-var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (b bar) valueReceiver() int { -- return 0 +-type funStructCompex struct { +- fn func(i int, s string) (string, int) -} - --func (b *bar) ptrReceiver() int { -- return 0 +-var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type funStructEmpty struct { +- fn func() -} - --func _() { -- var ( -- i int -- f foo -- ) +-var _ = funStructEmpty{ +- fn: func() { +- }, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- f.bar().valueReceiver //@item(deepBarValue, "f.bar().valueReceiver", "func() int", "method") -- f.barPtr().ptrReceiver //@item(deepBarPtrPtr, "f.barPtr().ptrReceiver", "func() int", "method") -- f.barPtr().valueReceiver //@item(deepBarPtrValue, "f.barPtr().valueReceiver", "func() int", "method") +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a3.go b/gopls/internal/lsp/testdata/fillstruct/a3.go +--- a/gopls/internal/lsp/testdata/fillstruct/a3.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a3.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-package fillstruct - -- i = fbar //@fuzzy(" //", deepBarValue, deepBarPtrPtr, deepBarPtrValue) +-import ( +- "go/ast" +- "go/token" +-) +- +-type Foo struct { +- A int -} - --func (b baz) Thing() struct{ val int } { -- return b.thing +-type Bar struct { +- X *Foo +- Y *Foo -} - --type baz struct { -- thing struct{ val int } +-var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type importedStruct struct { +- m map[*ast.CompositeLit]ast.Field +- s []ast.BadExpr +- a [3]token.Token +- c chan ast.EmptyStmt +- fn func(ast_decl ast.DeclStmt) ast.Ellipsis +- st ast.CompositeLit -} - --func (b baz) _() { -- b.Thing().val //@item(deepBazMethVal, "b.Thing().val", "int", "field") -- b.thing.val //@item(deepBazFieldVal, "b.thing.val", "int", "field") -- var _ int = bval //@rank(" //", deepBazFieldVal, deepBazMethVal) +-var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type pointerBuiltinStruct struct { +- b *bool +- s *string +- i *int -} -diff -urN a/gopls/internal/lsp/testdata/errors/errors.go b/gopls/internal/lsp/testdata/errors/errors.go ---- a/gopls/internal/lsp/testdata/errors/errors.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/errors/errors.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package errors +- +-var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-var _ = []ast.BasicLit{ +- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +-} +- +-var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a3.go.golden b/gopls/internal/lsp/testdata/fillstruct/a3.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/a3.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a3.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,243 +0,0 @@ +--- suggestedfix_a3_17_13 -- +-package fillstruct - -import ( -- "golang.org/lsptests/types" +- "go/ast" +- "go/token" -) - --func _() { -- bob.Bob() //@complete(".") -- types.b //@complete(" //", Bob_interface) +-type Foo struct { +- A int -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package extract -- --func _() { -- a := 1 -- a = 5 //@mark(exSt0, "a") -- a = a + 2 //@mark(exEn0, "2") -- //@extractfunc(exSt0, exEn0) -- b := a * 2 //@mark(exB, " b") -- _ = 3 + 4 //@mark(exEnd, "4") -- //@extractfunc(exB, exEnd) --} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_args_returns.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,37 +0,0 @@ ---- functionextraction_extract_args_returns_5_2 -- --package extract - --func _() { -- a := 1 -- //@mark(exSt0, "a") -- a = newFunction(a) //@mark(exEn0, "2") -- //@extractfunc(exSt0, exEn0) -- b := a * 2 //@mark(exB, " b") -- _ = 3 + 4 //@mark(exEnd, "4") -- //@extractfunc(exB, exEnd) +-type Bar struct { +- X *Foo +- Y *Foo -} - --func newFunction(a int) int { -- a = 5 -- a = a + 2 -- return a +-var _ = Bar{ +- X: &Foo{}, +- Y: &Foo{}, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type importedStruct struct { +- m map[*ast.CompositeLit]ast.Field +- s []ast.BadExpr +- a [3]token.Token +- c chan ast.EmptyStmt +- fn func(ast_decl ast.DeclStmt) ast.Ellipsis +- st ast.CompositeLit -} - ---- functionextraction_extract_args_returns_8_1 -- --package extract +-var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- a := 1 -- a = 5 //@mark(exSt0, "a") -- a = a + 2 //@mark(exEn0, "2") -- //@extractfunc(exSt0, exEn0) -- //@mark(exB, " b") -- newFunction(a) //@mark(exEnd, "4") -- //@extractfunc(exB, exEnd) +-type pointerBuiltinStruct struct { +- b *bool +- s *string +- i *int -} - --func newFunction(a int) { -- b := a * 2 -- _ = 3 + 4 +-var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-var _ = []ast.BasicLit{ +- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package extract +-var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- a := /* comment in the middle of a line */ 1 //@mark(exSt18, "a") -- // Comment on its own line //@mark(exSt19, "Comment") -- _ = 3 + 4 //@mark(exEn18, "4"),mark(exEn19, "4"),mark(exSt20, "_") -- // Comment right after 3 + 4 +--- suggestedfix_a3_28_24 -- +-package fillstruct - -- // Comment after with space //@mark(exEn20, "Comment") +-import ( +- "go/ast" +- "go/token" +-) - -- //@extractfunc(exSt18, exEn18),extractfunc(exSt19, exEn19),extractfunc(exSt20, exEn20) +-type Foo struct { +- A int -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic_comment.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,57 +0,0 @@ ---- functionextraction_extract_basic_comment_4_2 -- --package extract - --func _() { -- /* comment in the middle of a line */ -- //@mark(exSt18, "a") -- // Comment on its own line //@mark(exSt19, "Comment") -- newFunction() //@mark(exEn18, "4"),mark(exEn19, "4"),mark(exSt20, "_") -- // Comment right after 3 + 4 +-type Bar struct { +- X *Foo +- Y *Foo +-} - -- // Comment after with space //@mark(exEn20, "Comment") +-var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- //@extractfunc(exSt18, exEn18),extractfunc(exSt19, exEn19),extractfunc(exSt20, exEn20) +-type importedStruct struct { +- m map[*ast.CompositeLit]ast.Field +- s []ast.BadExpr +- a [3]token.Token +- c chan ast.EmptyStmt +- fn func(ast_decl ast.DeclStmt) ast.Ellipsis +- st ast.CompositeLit -} - --func newFunction() { -- a := 1 +-var _ = importedStruct{ +- m: map[*ast.CompositeLit]ast.Field{}, +- s: []ast.BadExpr{}, +- a: [3]token.Token{}, +- c: make(chan ast.EmptyStmt), +- fn: func(ast_decl ast.DeclStmt) ast.Ellipsis { +- }, +- st: ast.CompositeLit{}, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- _ = 3 + 4 +-type pointerBuiltinStruct struct { +- b *bool +- s *string +- i *int -} - ---- functionextraction_extract_basic_comment_5_5 -- --package extract +-var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- a := /* comment in the middle of a line */ 1 //@mark(exSt18, "a") -- // Comment on its own line //@mark(exSt19, "Comment") -- newFunction() //@mark(exEn18, "4"),mark(exEn19, "4"),mark(exSt20, "_") -- // Comment right after 3 + 4 +-var _ = []ast.BasicLit{ +- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +-} - -- // Comment after with space //@mark(exEn20, "Comment") +-var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +--- suggestedfix_a3_36_30 -- +-package fillstruct +- +-import ( +- "go/ast" +- "go/token" +-) - -- //@extractfunc(exSt18, exEn18),extractfunc(exSt19, exEn19),extractfunc(exSt20, exEn20) +-type Foo struct { +- A int -} - --func newFunction() { -- _ = 3 + 4 +-type Bar struct { +- X *Foo +- Y *Foo -} - ---- functionextraction_extract_basic_comment_6_2 -- --package extract +-var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- a := /* comment in the middle of a line */ 1 //@mark(exSt18, "a") -- // Comment on its own line //@mark(exSt19, "Comment") -- newFunction() //@mark(exEn18, "4"),mark(exEn19, "4"),mark(exSt20, "_") -- // Comment right after 3 + 4 +-type importedStruct struct { +- m map[*ast.CompositeLit]ast.Field +- s []ast.BadExpr +- a [3]token.Token +- c chan ast.EmptyStmt +- fn func(ast_decl ast.DeclStmt) ast.Ellipsis +- st ast.CompositeLit +-} - -- // Comment after with space //@mark(exEn20, "Comment") +-var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- //@extractfunc(exSt18, exEn18),extractfunc(exSt19, exEn19),extractfunc(exSt20, exEn20) +-type pointerBuiltinStruct struct { +- b *bool +- s *string +- i *int -} - --func newFunction() { -- _ = 3 + 4 +-var _ = pointerBuiltinStruct{ +- b: new(bool), +- s: new(string), +- i: new(int), +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-var _ = []ast.BasicLit{ +- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package extract +-var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { //@mark(exSt25, "{") -- a := 1 //@mark(exSt1, "a") -- _ = 3 + 4 //@mark(exEn1, "4") -- //@extractfunc(exSt1, exEn1) -- //@extractfunc(exSt25, exEn25) --} //@mark(exEn25, "}") -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_basic.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,30 +0,0 @@ ---- functionextraction_extract_basic_3_10 -- --package extract +--- suggestedfix_a3_39_3 -- +-package fillstruct - --func _() { //@mark(exSt25, "{") -- //@mark(exSt1, "a") -- newFunction() //@mark(exEn1, "4") -- //@extractfunc(exSt1, exEn1) -- //@extractfunc(exSt25, exEn25) +-import ( +- "go/ast" +- "go/token" +-) +- +-type Foo struct { +- A int -} - --func newFunction() { -- a := 1 -- _ = 3 + 4 --} //@mark(exEn25, "}") +-type Bar struct { +- X *Foo +- Y *Foo +-} - ---- functionextraction_extract_basic_4_2 -- --package extract +-var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { //@mark(exSt25, "{") -- //@mark(exSt1, "a") -- newFunction() //@mark(exEn1, "4") -- //@extractfunc(exSt1, exEn1) -- //@extractfunc(exSt25, exEn25) +-type importedStruct struct { +- m map[*ast.CompositeLit]ast.Field +- s []ast.BadExpr +- a [3]token.Token +- c chan ast.EmptyStmt +- fn func(ast_decl ast.DeclStmt) ast.Ellipsis +- st ast.CompositeLit -} - --func newFunction() { -- a := 1 -- _ = 3 + 4 --} //@mark(exEn25, "}") +-var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package extract +-type pointerBuiltinStruct struct { +- b *bool +- s *string +- i *int +-} - --import "fmt" +-var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func main() { -- x := []rune{} //@mark(exSt9, "x") -- s := "HELLO" -- for _, c := range s { -- x = append(x, c) -- } //@mark(exEn9, "}") -- //@extractfunc(exSt9, exEn9) -- fmt.Printf("%x\n", x) +-var _ = []ast.BasicLit{ +- { +- ValuePos: 0, +- Kind: 0, +- Value: "", +- }, //@suggestedfix("}", "refactor.rewrite", "Fill") -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ ---- functionextraction_extract_issue_44813_6_2 -- --package extract - --import "fmt" +-var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func main() { -- //@mark(exSt9, "x") -- x := newFunction() //@mark(exEn9, "}") -- //@extractfunc(exSt9, exEn9) -- fmt.Printf("%x\n", x) --} +--- suggestedfix_a3_42_25 -- +-package fillstruct - --func newFunction() []rune { -- x := []rune{} -- s := "HELLO" -- for _, c := range s { -- x = append(x, c) -- } -- return x +-import ( +- "go/ast" +- "go/token" +-) +- +-type Foo struct { +- A int -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package extract +-type Bar struct { +- X *Foo +- Y *Foo +-} - --import "strconv" +-var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- i, err := strconv.Atoi("1") -- u, err := strconv.Atoi("2") //@extractfunc("u", ")") -- if i == u || err == nil { -- return -- } +-type importedStruct struct { +- m map[*ast.CompositeLit]ast.Field +- s []ast.BadExpr +- a [3]token.Token +- c chan ast.EmptyStmt +- fn func(ast_decl ast.DeclStmt) ast.Ellipsis +- st ast.CompositeLit -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_redefine.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ ---- functionextraction_extract_redefine_7_2 -- --package extract - --import "strconv" +-var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- i, err := strconv.Atoi("1") -- u, err := newFunction() //@extractfunc("u", ")") -- if i == u || err == nil { -- return -- } +-type pointerBuiltinStruct struct { +- b *bool +- s *string +- i *int -} - --func newFunction() (int, error) { -- u, err := strconv.Atoi("2") -- return u, err +-var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-var _ = []ast.BasicLit{ +- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package extract +-var _ = []ast.BasicLit{{ +- ValuePos: 0, +- Kind: 0, +- Value: "", +-}} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() bool { -- x := 1 -- if x == 0 { //@mark(exSt2, "if") -- return true -- } //@mark(exEn2, "}") -- return false -- //@extractfunc(exSt2, exEn2) --} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ ---- functionextraction_extract_return_basic_5_2 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a4.go b/gopls/internal/lsp/testdata/fillstruct/a4.go +--- a/gopls/internal/lsp/testdata/fillstruct/a4.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a4.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,39 +0,0 @@ +-package fillstruct - --func _() bool { -- x := 1 -- //@mark(exSt2, "if") -- shouldReturn, returnValue := newFunction(x) -- if shouldReturn { -- return returnValue -- } //@mark(exEn2, "}") -- return false -- //@extractfunc(exSt2, exEn2) --} +-import "go/ast" - --func newFunction(x int) (bool, bool) { -- if x == 0 { -- return true, true -- } -- return false, false +-type iStruct struct { +- X int -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package extract -- --func _() bool { -- x := 1 //@mark(exSt13, "x") -- if x == 0 { -- return true -- } -- return false //@mark(exEn13, "false") -- //@extractfunc(exSt13, exEn13) +-type sStruct struct { +- str string -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_basic_nonnested.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,17 +0,0 @@ ---- functionextraction_extract_return_basic_nonnested_4_2 -- --package extract - --func _() bool { -- //@mark(exSt13, "x") -- return newFunction() //@mark(exEn13, "false") -- //@extractfunc(exSt13, exEn13) +-type multiFill struct { +- num int +- strin string +- arr []int -} - --func newFunction() bool { -- x := 1 -- if x == 0 { -- return true -- } -- return false +-type assignStruct struct { +- n ast.Node -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,17 +0,0 @@ --package extract +-func fill() { +- var x int +- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --import "fmt" +- var s string +- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- z := "bye" //@mark(exSt3, "z") -- if y == z { -- return x, y, fmt.Errorf("same") -- } else { -- z = "hi" -- return x, z, nil -- } //@mark(exEn3, "}") -- return x, z, nil -- //@extractfunc(exSt3, exEn3) +- var n int +- _ = []int{} +- if true { +- arr := []int{1, 2} +- } +- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +- var node *ast.CompositeLit +- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,28 +0,0 @@ ---- functionextraction_extract_return_complex_8_2 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a4.go.golden b/gopls/internal/lsp/testdata/fillstruct/a4.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/a4.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a4.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,174 +0,0 @@ +--- suggestedfix_a4_25_18 -- +-package fillstruct - --import "fmt" +-import "go/ast" - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- //@mark(exSt3, "z") -- z, shouldReturn, returnValue, returnValue1, returnValue2 := newFunction(y, x) -- if shouldReturn { -- return returnValue, returnValue1, returnValue2 -- } //@mark(exEn3, "}") -- return x, z, nil -- //@extractfunc(exSt3, exEn3) +-type iStruct struct { +- X int -} - --func newFunction(y string, x int) (string, bool, int, string, error) { -- z := "bye" -- if y == z { -- return "", true, x, y, fmt.Errorf("same") -- } else { -- z = "hi" -- return "", true, x, z, nil -- } -- return z, false, 0, "", nil +-type sStruct struct { +- str string -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,17 +0,0 @@ --package extract -- --import "fmt" +-type multiFill struct { +- num int +- strin string +- arr []int +-} - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- z := "bye" //@mark(exSt10, "z") -- if y == z { -- return x, y, fmt.Errorf("same") -- } else { -- z = "hi" -- return x, z, nil -- } -- return x, z, nil //@mark(exEn10, "nil") -- //@extractfunc(exSt10, exEn10) +-type assignStruct struct { +- n ast.Node -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_complex_nonnested.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ ---- functionextraction_extract_return_complex_nonnested_8_2 -- --package extract - --import "fmt" +-func fill() { +- var x int +- var _ = iStruct{ +- X: x, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() (int, string, error) { -- x := 1 -- y := "hello" -- //@mark(exSt10, "z") -- return newFunction(y, x) //@mark(exEn10, "nil") -- //@extractfunc(exSt10, exEn10) --} +- var s string +- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func newFunction(y string, x int) (int, string, error) { -- z := "bye" -- if y == z { -- return x, y, fmt.Errorf("same") -- } else { -- z = "hi" -- return x, z, nil +- var n int +- _ = []int{} +- if true { +- arr := []int{1, 2} - } -- return x, z, nil +- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +- var node *ast.CompositeLit +- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package extract +--- suggestedfix_a4_28_18 -- +-package fillstruct - -import "go/ast" - --func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- if n == nil { //@mark(exSt4, "if") -- return true -- } //@mark(exEn4, "}") -- return false -- }) -- //@extractfunc(exSt4, exEn4) +-type iStruct struct { +- X int -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ ---- functionextraction_extract_return_func_lit_7_3 -- --package extract - --import "go/ast" +-type sStruct struct { +- str string +-} - --func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- //@mark(exSt4, "if") -- shouldReturn, returnValue := newFunction(n) -- if shouldReturn { -- return returnValue -- } //@mark(exEn4, "}") -- return false -- }) -- //@extractfunc(exSt4, exEn4) +-type multiFill struct { +- num int +- strin string +- arr []int -} - --func newFunction(n ast.Node) (bool, bool) { -- if n == nil { -- return true, true -- } -- return false, false +-type assignStruct struct { +- n ast.Node -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package extract +-func fill() { +- var x int +- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --import "go/ast" +- var s string +- var _ = sStruct{ +- str: s, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- if n == nil { //@mark(exSt11, "if") -- return true -- } -- return false //@mark(exEn11, "false") -- }) -- //@extractfunc(exSt11, exEn11) +- var n int +- _ = []int{} +- if true { +- arr := []int{1, 2} +- } +- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +- var node *ast.CompositeLit +- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_func_lit_nonnested.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ ---- functionextraction_extract_return_func_lit_nonnested_7_3 -- --package extract +- +--- suggestedfix_a4_35_20 -- +-package fillstruct - -import "go/ast" - --func _() { -- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { -- //@mark(exSt11, "if") -- return newFunction(n) //@mark(exEn11, "false") -- }) -- //@extractfunc(exSt11, exEn11) +-type iStruct struct { +- X int -} - --func newFunction(n ast.Node) bool { -- if n == nil { -- return true -- } -- return false +-type sStruct struct { +- str string -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package extract -- --func _() string { -- x := 1 -- if x == 0 { //@mark(exSt5, "if") -- x = 3 -- return "a" -- } //@mark(exEn5, "}") -- x = 2 -- return "b" -- //@extractfunc(exSt5, exEn5) +-type multiFill struct { +- num int +- strin string +- arr []int -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,23 +0,0 @@ ---- functionextraction_extract_return_init_5_2 -- --package extract - --func _() string { -- x := 1 -- //@mark(exSt5, "if") -- shouldReturn, returnValue := newFunction(x) -- if shouldReturn { -- return returnValue -- } //@mark(exEn5, "}") -- x = 2 -- return "b" -- //@extractfunc(exSt5, exEn5) +-type assignStruct struct { +- n ast.Node -} - --func newFunction(x int) (bool, string) { -- if x == 0 { -- x = 3 -- return true, "a" -- } -- return false, "" --} +-func fill() { +- var x int +- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package extract +- var s string +- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() string { -- x := 1 -- if x == 0 { //@mark(exSt12, "if") -- x = 3 -- return "a" +- var n int +- _ = []int{} +- if true { +- arr := []int{1, 2} - } -- x = 2 -- return "b" //@mark(exEn12, "\"b\"") -- //@extractfunc(exSt12, exEn12) --} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_return_init_nonnested.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ ---- functionextraction_extract_return_init_nonnested_5_2 -- --package extract +- var _ = multiFill{ +- num: n, +- strin: s, +- arr: []int{}, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() string { -- x := 1 -- //@mark(exSt12, "if") -- return newFunction(x) //@mark(exEn12, "\"b\"") -- //@extractfunc(exSt12, exEn12) +- var node *ast.CompositeLit +- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - --func newFunction(x int) string { -- if x == 0 { -- x = 3 -- return "a" -- } -- x = 2 -- return "b" --} +--- suggestedfix_a4_38_23 -- +-package fillstruct - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package extract +-import "go/ast" - --func _() { -- newFunction := 1 -- a := newFunction //@extractfunc("a", "newFunction") +-type iStruct struct { +- X int -} - --func newFunction1() int { -- return 1 +-type sStruct struct { +- str string -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_scope.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ ---- functionextraction_extract_scope_5_2 -- --package extract - --func _() { -- newFunction := 1 -- newFunction2(newFunction) //@extractfunc("a", "newFunction") +-type multiFill struct { +- num int +- strin string +- arr []int -} - --func newFunction2(newFunction int) { -- a := newFunction +-type assignStruct struct { +- n ast.Node -} - --func newFunction1() int { -- return 1 --} +-func fill() { +- var x int +- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package extract +- var s string +- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- var a []int -- a = append(a, 2) //@mark(exSt6, "a") -- b := 4 //@mark(exEn6, "4") -- //@extractfunc(exSt6, exEn6) -- a = append(a, b) --} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_initialization.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,17 +0,0 @@ ---- functionextraction_extract_smart_initialization_5_2 -- --package extract +- var n int +- _ = []int{} +- if true { +- arr := []int{1, 2} +- } +- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- var a []int -- //@mark(exSt6, "a") -- a, b := newFunction(a) //@mark(exEn6, "4") -- //@extractfunc(exSt6, exEn6) -- a = append(a, b) +- var node *ast.CompositeLit +- var _ = assignStruct{ +- n: node, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} - --func newFunction(a []int) ([]int, int) { -- a = append(a, 2) -- b := 4 -- return a, b --} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a.go b/gopls/internal/lsp/testdata/fillstruct/a.go +--- a/gopls/internal/lsp/testdata/fillstruct/a.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package fillstruct - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package extract +-import ( +- "golang.org/lsptests/fillstruct/data" +-) - --func _() { -- var b []int -- var a int -- a = 2 //@mark(exSt7, "a") -- b = []int{} -- b = append(b, a) //@mark(exEn7, ")") -- b[0] = 1 -- //@extractfunc(exSt7, exEn7) +-type basicStruct struct { +- foo int -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_smart_return.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ ---- functionextraction_extract_smart_return_6_2 -- --package extract - --func _() { -- var b []int -- var a int -- //@mark(exSt7, "a") -- b = newFunction(a, b) //@mark(exEn7, ")") -- b[0] = 1 -- //@extractfunc(exSt7, exEn7) --} +-var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func newFunction(a int, b []int) []int { -- a = 2 -- b = []int{} -- b = append(b, a) -- return b +-type twoArgStruct struct { +- foo int +- bar string -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go b/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ --package extract -- --func _() { -- var b []int -- var a int -- a := 2 //@mark(exSt8, "a") -- b = []int{} -- b = append(b, a) //@mark(exEn8, ")") -- b[0] = 1 -- if a == 2 { -- return -- } -- //@extractfunc(exSt8, exEn8) --} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go.golden b/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_function/extract_unnecessary_param.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ ---- functionextraction_extract_unnecessary_param_6_2 -- --package extract +-var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func _() { -- var b []int -- var a int -- //@mark(exSt8, "a") -- a, b = newFunction(b) //@mark(exEn8, ")") -- b[0] = 1 -- if a == 2 { -- return -- } -- //@extractfunc(exSt8, exEn8) +-type nestedStruct struct { +- bar string +- basic basicStruct -} - --func newFunction(b []int) (int, []int) { -- a := 2 -- b = []int{} -- b = append(b, a) -- return a, b --} +-var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go ---- a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ --package extract +-var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") +diff -urN a/gopls/internal/lsp/testdata/fillstruct/a.go.golden b/gopls/internal/lsp/testdata/fillstruct/a.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/a.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/a.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,126 +0,0 @@ +--- suggestedfix_a_11_21 -- +-package fillstruct - --type A struct { -- x int -- y int --} +-import ( +- "golang.org/lsptests/fillstruct/data" +-) - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type basicStruct struct { +- foo int -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-var _ = basicStruct{ +- foo: 0, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type twoArgStruct struct { +- foo int +- bar string -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_method/extract_basic.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,364 +0,0 @@ ---- functionextraction_extract_basic_13_2 -- --package extract +-var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type A struct { -- x int -- y int +-type nestedStruct struct { +- bar string +- basic basicStruct -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a *A) AddP() int { -- sum := newFunction(a) //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func newFunction(a *A) int { -- sum := a.x + a.y -- return sum --} +--- suggestedfix_a_18_22 -- +-package fillstruct - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "golang.org/lsptests/fillstruct/data" +-) - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type basicStruct struct { +- foo int -} - ---- functionextraction_extract_basic_14_2 -- --package extract +-var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type A struct { -- x int -- y int +-type twoArgStruct struct { +- foo int +- bar string -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-var _ = twoArgStruct{ +- foo: 0, +- bar: "", +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return newFunction(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type nestedStruct struct { +- bar string +- basic basicStruct -} - --func newFunction(sum int) int { -- return sum --} +-var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +--- suggestedfix_a_25_22 -- +-package fillstruct - ---- functionextraction_extract_basic_18_2 -- --package extract +-import ( +- "golang.org/lsptests/fillstruct/data" +-) - --type A struct { -- x int -- y int +-type basicStruct struct { +- foo int -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type twoArgStruct struct { +- foo int +- bar string -} - --func (a A) XLessThanY() bool { -- return newFunction(a) //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func newFunction(a A) bool { -- return a.x < a.y +-type nestedStruct struct { +- bar string +- basic basicStruct -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-var _ = nestedStruct{ +- bar: "", +- basic: basicStruct{}, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - ---- functionextraction_extract_basic_22_2 -- --package extract +-var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type A struct { -- x int -- y int --} +--- suggestedfix_a_27_16 -- +-package fillstruct - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-import ( +- "golang.org/lsptests/fillstruct/data" +-) - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type basicStruct struct { +- foo int -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +-var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a A) Add() int { -- sum := newFunction(a) //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type twoArgStruct struct { +- foo int +- bar string -} - --func newFunction(a A) int { -- sum := a.x + a.y -- return sum +-var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type nestedStruct struct { +- bar string +- basic basicStruct -} - ---- functionextraction_extract_basic_23_2 -- --package extract +-var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type A struct { -- x int -- y int --} +-var _ = data.B{ +- ExportedInt: 0, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/data/a.go b/gopls/internal/lsp/testdata/fillstruct/data/a.go +--- a/gopls/internal/lsp/testdata/fillstruct/data/a.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/data/a.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package data +- +-type B struct { +- ExportedInt int +- unexportedInt int +-} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package fillstruct - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructAnon struct { +- a struct{} +- b map[string]interface{} +- c map[string]struct { +- d int +- e bool +- } -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func fill() { +- _ := StructAnon{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +--- suggestedfix_fill_struct_anon_13_18 -- +-package fillstruct - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return newFunction(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructAnon struct { +- a struct{} +- b map[string]interface{} +- c map[string]struct { +- d int +- e bool +- } -} - --func newFunction(sum int) int { -- return sum +-func fill() { +- _ := StructAnon{ +- a: struct{}{}, +- b: map[string]interface{}{}, +- c: map[string]struct{d int; e bool}{}, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} - ---- functionextraction_extract_basic_9_2 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +-package fillstruct - --type A struct { -- x int -- y int +-type StructA struct { +- unexportedIntField int +- ExportedIntField int +- MapA map[int]string +- Array []int +- StructB -} - --func (a *A) XLessThanYP() bool { -- return newFunction(a) //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructA2 struct { +- B *StructB -} - --func newFunction(a *A) bool { -- return a.x < a.y +-type StructA3 struct { +- B StructB -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func fill() { +- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- if true { +- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- } -} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,124 +0,0 @@ +--- suggestedfix_fill_struct_20_15 -- +-package fillstruct - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructA struct { +- unexportedIntField int +- ExportedIntField int +- MapA map[int]string +- Array []int +- StructB -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructA2 struct { +- B *StructB -} - ---- methodextraction_extract_basic_13_2 -- --package extract -- --type A struct { -- x int -- y int +-type StructA3 struct { +- B StructB -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func fill() { +- a := StructA{ +- unexportedIntField: 0, +- ExportedIntField: 0, +- MapA: map[int]string{}, +- Array: []int{}, +- StructB: StructB{}, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- if true { +- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- } -} - --func (a *A) AddP() int { -- sum := a.newMethod() //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +--- suggestedfix_fill_struct_21_16 -- +-package fillstruct - --func (a *A) newMethod() int { -- sum := a.x + a.y -- return sum +-type StructA struct { +- unexportedIntField int +- ExportedIntField int +- MapA map[int]string +- Array []int +- StructB -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructA2 struct { +- B *StructB -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructA3 struct { +- B StructB -} - ---- methodextraction_extract_basic_14_2 -- --package extract -- --type A struct { -- x int -- y int +-func fill() { +- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructA2{ +- B: &StructB{}, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- if true { +- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- } -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +--- suggestedfix_fill_struct_22_16 -- +-package fillstruct - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return a.newMethod(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructA struct { +- unexportedIntField int +- ExportedIntField int +- MapA map[int]string +- Array []int +- StructB -} - --func (*A) newMethod(sum int) int { -- return sum +-type StructA2 struct { +- B *StructB -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructA3 struct { +- B StructB -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func fill() { +- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- c := StructA3{ +- B: StructB{}, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- if true { +- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- } -} - ---- methodextraction_extract_basic_18_2 -- --package extract +--- suggestedfix_fill_struct_24_16 -- +-package fillstruct - --type A struct { -- x int -- y int +-type StructA struct { +- unexportedIntField int +- ExportedIntField int +- MapA map[int]string +- Array []int +- StructB -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructA2 struct { +- B *StructB -} - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructA3 struct { +- B StructB -} - --func (a A) XLessThanY() bool { -- return a.newMethod() //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func fill() { +- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- if true { +- _ = StructA3{ +- B: StructB{}, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- } -} - --func (a A) newMethod() bool { -- return a.x < a.y --} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-package fillstruct - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructB struct { +- StructC -} - ---- methodextraction_extract_basic_22_2 -- --package extract -- --type A struct { -- x int -- y int +-type StructC struct { +- unexportedInt int -} - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func nested() { +- c := StructB{ +- StructC: StructC{}, //@suggestedfix("}", "refactor.rewrite", "Fill") +- } -} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +--- suggestedfix_fill_struct_nested_13_20 -- +-package fillstruct - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructB struct { +- StructC -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructC struct { +- unexportedInt int -} - --func (a A) Add() int { -- sum := a.newMethod() //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func nested() { +- c := StructB{ +- StructC: StructC{ +- unexportedInt: 0, +- }, //@suggestedfix("}", "refactor.rewrite", "Fill") +- } -} - --func (a A) newMethod() int { -- sum := a.x + a.y -- return sum --} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-package fillstruct - ---- methodextraction_extract_basic_23_2 -- --package extract +-import ( +- h2 "net/http" - --type A struct { -- x int -- y int --} +- "golang.org/lsptests/fillstruct/data" +-) - --func (a *A) XLessThanYP() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-func unexported() { +- a := data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- _ = h2.Client{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,36 +0,0 @@ +--- suggestedfix_fill_struct_package_10_14 -- +-package fillstruct - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") --} +-import ( +- h2 "net/http" - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") --} +- "golang.org/lsptests/fillstruct/data" +-) - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return a.newMethod(sum) //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func unexported() { +- a := data.B{ +- ExportedInt: 0, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- _ = h2.Client{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - --func (A) newMethod(sum int) int { -- return sum +--- suggestedfix_fill_struct_package_11_16 -- +-package fillstruct +- +-import ( +- h2 "net/http" +- +- "golang.org/lsptests/fillstruct/data" +-) +- +-func unexported() { +- a := data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- _ = h2.Client{ +- Transport: nil, +- CheckRedirect: func(req *h2.Request, via []*h2.Request) error { +- }, +- Jar: nil, +- Timeout: 0, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} - ---- methodextraction_extract_basic_9_2 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-package fillstruct - --type A struct { -- x int -- y int +-type StructPartialA struct { +- PrefilledInt int +- UnfilledInt int +- StructPartialB -} - --func (a *A) XLessThanYP() bool { -- return a.newMethod() //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructPartialB struct { +- PrefilledInt int +- UnfilledInt int -} - --func (a *A) newMethod() bool { -- return a.x < a.y +-func fill() { +- a := StructPartialA{ +- PrefilledInt: 5, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructPartialB{ +- /* this comment should disappear */ +- PrefilledInt: 7, // This comment should be blown away. +- /* As should +- this one */ +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,52 +0,0 @@ +--- suggestedfix_fill_struct_partial_17_2 -- +-package fillstruct - --func (a *A) AddP() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-type StructPartialA struct { +- PrefilledInt int +- UnfilledInt int +- StructPartialB -} - --func (a A) XLessThanY() bool { -- return a.x < a.y //@extractmethod("return", "a.y"),extractfunc("return", "a.y") +-type StructPartialB struct { +- PrefilledInt int +- UnfilledInt int -} - --func (a A) Add() int { -- sum := a.x + a.y //@extractmethod("sum", "a.y"),extractfunc("sum", "a.y") -- return sum //@extractmethod("return", "sum"),extractfunc("return", "sum") +-func fill() { +- a := StructPartialA{ +- PrefilledInt: 5, +- UnfilledInt: 0, +- StructPartialB: StructPartialB{}, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructPartialB{ +- /* this comment should disappear */ +- PrefilledInt: 7, // This comment should be blown away. +- /* As should +- this one */ +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package extract +--- suggestedfix_fill_struct_partial_23_2 -- +-package fillstruct - --func _() { -- var _ = 1 + 2 //@suggestedfix("1", "refactor.extract", "") -- var _ = 3 + 4 //@suggestedfix("3 + 4", "refactor.extract", "") +-type StructPartialA struct { +- PrefilledInt int +- UnfilledInt int +- StructPartialB -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_basic_lit.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ ---- suggestedfix_extract_basic_lit_4_10 -- --package extract - --func _() { -- x := 1 -- var _ = x + 2 //@suggestedfix("1", "refactor.extract", "") -- var _ = 3 + 4 //@suggestedfix("3 + 4", "refactor.extract", "") +-type StructPartialB struct { +- PrefilledInt int +- UnfilledInt int -} - ---- suggestedfix_extract_basic_lit_5_10 -- --package extract -- --func _() { -- var _ = 1 + 2 //@suggestedfix("1", "refactor.extract", "") -- x := 3 + 4 -- var _ = x //@suggestedfix("3 + 4", "refactor.extract", "") +-func fill() { +- a := StructPartialA{ +- PrefilledInt: 5, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- b := StructPartialB{ +- PrefilledInt: 7, +- UnfilledInt: 0, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go 1970-01-01 00:00:00.000000000 +0000 +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ --package extract +-package fillstruct - --import "strconv" +-type StructD struct { +- ExportedIntField int +-} - --func _() { -- x0 := append([]int{}, 1) //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") -- str := "1" -- b, err := strconv.Atoi(str) //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") +-func spaces() { +- d := StructD{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_func_call.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ ---- suggestedfix_extract_func_call_6_8 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_fill_struct_spaces_8_15 -- +-package fillstruct - --import "strconv" +-type StructD struct { +- ExportedIntField int +-} - --func _() { -- x := append([]int{}, 1) -- x0 := x //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") -- str := "1" -- b, err := strconv.Atoi(str) //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") +-func spaces() { +- d := StructD{ +- ExportedIntField: 0, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} - ---- suggestedfix_extract_func_call_8_12 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-package fillstruct - --import "strconv" +-import "unsafe" - --func _() { -- x0 := append([]int{}, 1) //@suggestedfix("append([]int{}, 1)", "refactor.extract", "") -- str := "1" -- x, x1 := strconv.Atoi(str) -- b, err := x, x1 //@suggestedfix("strconv.Atoi(str)", "refactor.extract", "") +-type unsafeStruct struct { +- x int +- p unsafe.Pointer -} - -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package extract -- --import "go/ast" -- --func _() { -- x0 := 0 -- if true { -- y := ast.CompositeLit{} //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") -- } -- if true { -- x1 := !false //@suggestedfix("!false", "refactor.extract", "") -- } +-func fill() { +- _ := unsafeStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} -diff -urN a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden ---- a/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/extract/extract_variable/extract_scope.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,32 +0,0 @@ ---- suggestedfix_extract_scope_11_9 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +--- suggestedfix_fill_struct_unsafe_11_20 -- +-package fillstruct - --import "go/ast" +-import "unsafe" +- +-type unsafeStruct struct { +- x int +- p unsafe.Pointer +-} - --func _() { -- x0 := 0 -- if true { -- y := ast.CompositeLit{} //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") -- } -- if true { -- x := !false -- x1 := x //@suggestedfix("!false", "refactor.extract", "") -- } +-func fill() { +- _ := unsafeStruct{ +- x: 0, +- p: nil, +- } //@suggestedfix("}", "refactor.rewrite", "Fill") -} - ---- suggestedfix_extract_scope_8_8 -- --package extract +diff -urN a/gopls/internal/lsp/testdata/fillstruct/typeparams.go b/gopls/internal/lsp/testdata/fillstruct/typeparams.go +--- a/gopls/internal/lsp/testdata/fillstruct/typeparams.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/typeparams.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,37 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --import "go/ast" +-package fillstruct - --func _() { -- x0 := 0 -- if true { -- x := ast.CompositeLit{} -- y := x //@suggestedfix("ast.CompositeLit{}", "refactor.extract", "") -- } -- if true { -- x1 := !false //@suggestedfix("!false", "refactor.extract", "") -- } --} +-type emptyStructWithTypeParams[A any] struct{} - -diff -urN a/gopls/internal/lsp/testdata/fieldlist/field_list.go b/gopls/internal/lsp/testdata/fieldlist/field_list.go ---- a/gopls/internal/lsp/testdata/fieldlist/field_list.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fieldlist/field_list.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package fieldlist +-var _ = emptyStructWithTypeParams[int]{} // no suggested fix - --var myInt int //@item(flVar, "myInt", "int", "var") --type myType int //@item(flType, "myType", "int", "type") +-type basicStructWithTypeParams[T any] struct { +- foo T +-} - --func (my) _() {} //@complete(") _", flType) --func (my my) _() {} //@complete(" my)"),complete(") _", flType) +-var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (myType) _() {} //@complete(") {", flType) +-type twoArgStructWithTypeParams[F, B any] struct { +- foo F +- bar B +-} - --func (myType) _(my my) {} //@complete(" my)"),complete(") {", flType) +-var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (myType) _() my {} //@complete(" {", flType) +-var _ = twoArgStructWithTypeParams[int, string]{ +- bar: "bar", +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - --func (myType) _() (my my) {} //@complete(" my"),complete(") {", flType) +-type nestedStructWithTypeParams struct { +- bar string +- basic basicStructWithTypeParams[int] +-} - --func _() { -- var _ struct { -- //@complete("", flType) -- m my //@complete(" my"),complete(" //", flType) -- } +-var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -- var _ interface { -- //@complete("", flType) -- m() my //@complete("("),complete(" //", flType) -- } +-func _[T any]() { +- type S struct{ t T } +- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a2.go b/gopls/internal/lsp/testdata/fillstruct/a2.go ---- a/gopls/internal/lsp/testdata/fillstruct/a2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a2.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ +diff -urN a/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden b/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden +--- a/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,206 +0,0 @@ +--- suggestedfix_typeparams_14_40 -- +-//go:build go1.18 +-// +build go1.18 +- -package fillstruct - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-type emptyStructWithTypeParams[A any] struct{} +- +-var _ = emptyStructWithTypeParams[int]{} // no suggested fix +- +-type basicStructWithTypeParams[T any] struct { +- foo T -} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = basicStructWithTypeParams[int]{ +- foo: 0, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStruct struct { -- fn func(i int) int +-type twoArgStructWithTypeParams[F, B any] struct { +- foo F +- bar B -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-var _ = twoArgStructWithTypeParams[int, string]{ +- bar: "bar", +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type nestedStructWithTypeParams struct { +- bar string +- basic basicStructWithTypeParams[int] -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructEmpty struct { -- fn func() +-func _[T any]() { +- type S struct{ t T } +- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a2.go.golden b/gopls/internal/lsp/testdata/fillstruct/a2.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a2.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,139 +0,0 @@ ---- suggestedfix_a2_11_21 -- +--- suggestedfix_typeparams_21_49 -- +-//go:build go1.18 +-// +build go1.18 +- -package fillstruct - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-type emptyStructWithTypeParams[A any] struct{} +- +-var _ = emptyStructWithTypeParams[int]{} // no suggested fix +- +-type basicStructWithTypeParams[T any] struct { +- foo T -} - --var _ = typedStruct{ -- m: map[string]int{}, -- s: []int{}, -- c: make(chan int), -- c1: make(<-chan int), -- a: [2]string{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStruct struct { -- fn func(i int) int +-type twoArgStructWithTypeParams[F, B any] struct { +- foo F +- bar B -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = twoArgStructWithTypeParams[string, int]{ +- foo: "", +- bar: 0, +-} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-var _ = twoArgStructWithTypeParams[int, string]{ +- bar: "bar", +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type nestedStructWithTypeParams struct { +- bar string +- basic basicStructWithTypeParams[int] -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructEmpty struct { -- fn func() +-func _[T any]() { +- type S struct{ t T } +- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- suggestedfix_typeparams_25_1 -- +-//go:build go1.18 +-// +build go1.18 - ---- suggestedfix_a2_17_19 -- -package fillstruct - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-type emptyStructWithTypeParams[A any] struct{} +- +-var _ = emptyStructWithTypeParams[int]{} // no suggested fix +- +-type basicStructWithTypeParams[T any] struct { +- foo T -} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStruct struct { -- fn func(i int) int +-type twoArgStructWithTypeParams[F, B any] struct { +- foo F +- bar B -} - --var _ = funStruct{ -- fn: func(i int) int { -- }, +-var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-var _ = twoArgStructWithTypeParams[int, string]{ +- foo: 0, +- bar: "bar", -} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-type nestedStructWithTypeParams struct { +- bar string +- basic basicStructWithTypeParams[int] -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructEmpty struct { -- fn func() +-func _[T any]() { +- type S struct{ t T } +- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- suggestedfix_typeparams_32_36 -- +-//go:build go1.18 +-// +build go1.18 - ---- suggestedfix_a2_23_25 -- -package fillstruct - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string +-type emptyStructWithTypeParams[A any] struct{} +- +-var _ = emptyStructWithTypeParams[int]{} // no suggested fix +- +-type basicStructWithTypeParams[T any] struct { +- foo T -} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStruct struct { -- fn func(i int) int +-type twoArgStructWithTypeParams[F, B any] struct { +- foo F +- bar B -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-var _ = twoArgStructWithTypeParams[int, string]{ +- bar: "bar", +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type nestedStructWithTypeParams struct { +- bar string +- basic basicStructWithTypeParams[int] -} - --var _ = funStructCompex{ -- fn: func(i int, s string) (string, int) { -- }, +-var _ = nestedStructWithTypeParams{ +- bar: "", +- basic: basicStructWithTypeParams{}, -} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructEmpty struct { -- fn func() +-func _[T any]() { +- type S struct{ t T } +- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") -} - --var _ = funStructEmpty{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- suggestedfix_typeparams_36_8 -- +-//go:build go1.18 +-// +build go1.18 - ---- suggestedfix_a2_29_24 -- -package fillstruct - --type typedStruct struct { -- m map[string]int -- s []int -- c chan int -- c1 <-chan int -- a [2]string --} +-type emptyStructWithTypeParams[A any] struct{} - --var _ = typedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = emptyStructWithTypeParams[int]{} // no suggested fix - --type funStruct struct { -- fn func(i int) int +-type basicStructWithTypeParams[T any] struct { +- foo T -} - --var _ = funStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructCompex struct { -- fn func(i int, s string) (string, int) +-type twoArgStructWithTypeParams[F, B any] struct { +- foo F +- bar B -} - --var _ = funStructCompex{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type funStructEmpty struct { -- fn func() +-var _ = twoArgStructWithTypeParams[int, string]{ +- bar: "bar", +-} //@suggestedfix("}", "refactor.rewrite", "Fill") +- +-type nestedStructWithTypeParams struct { +- bar string +- basic basicStructWithTypeParams[int] -} - --var _ = funStructEmpty{ -- fn: func() { -- }, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a3.go b/gopls/internal/lsp/testdata/fillstruct/a3.go ---- a/gopls/internal/lsp/testdata/fillstruct/a3.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a3.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,42 +0,0 @@ --package fillstruct +-func _[T any]() { +- type S struct{ t T } +- _ = S{ +- t: *new(T), +- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-} +- +diff -urN a/gopls/internal/lsp/testdata/folding/a.go b/gopls/internal/lsp/testdata/folding/a.go +--- a/gopls/internal/lsp/testdata/folding/a.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/folding/a.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,75 +0,0 @@ +-package folding //@fold("package") - -import ( -- "go/ast" -- "go/token" +- "fmt" +- _ "log" -) - --type Foo struct { -- A int --} +-import _ "os" - --type Bar struct { -- X *Foo -- Y *Foo +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true { +- fmt.Println("true") +- } else { +- fmt.Println("false") +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline +- block +- comment */ +- +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val { +- fmt.Println("true from x") +- } else { +- fmt.Println("false from x") +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` -} +diff -urN a/gopls/internal/lsp/testdata/folding/a.go.golden b/gopls/internal/lsp/testdata/folding/a.go.golden +--- a/gopls/internal/lsp/testdata/folding/a.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/folding/a.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,722 +0,0 @@ +--- foldingRange-0 -- +-package folding //@fold("package") - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import (<>) - --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit --} +-import _ "os" - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-// bar is a function.<> +-func bar(<>) string {<>} - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int +--- foldingRange-1 -- +-package folding //@fold("package") +- +-import ( +- "fmt" +- _ "log" +-) +- +-import _ "os" +- +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch {<>} +- /* This is a multiline<> +- +- /* This is a multiline<> +- _ = []int{<>} +- _ = [2]string{<>} +- _ = map[string]int{<>} +- type T struct {<>} +- _ = T{<>} +- x, y := make(<>), make(<>) +- select {<>} +- // This is a multiline comment<> +- return <> -} - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- foldingRange-2 -- +-package folding //@fold("package") - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( +- "fmt" +- _ "log" +-) +- +-import _ "os" +- +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true:<> +- case false:<> +- default:<> +- } +- /* This is a multiline +- block +- comment */ +- +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x:<> +- case <-y:<> +- default:<> +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` -} - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a3.go.golden b/gopls/internal/lsp/testdata/fillstruct/a3.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a3.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a3.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,243 +0,0 @@ ---- suggestedfix_a3_17_13 -- --package fillstruct +--- foldingRange-3 -- +-package folding //@fold("package") - -import ( -- "go/ast" -- "go/token" +- "fmt" +- _ "log" -) - --type Foo struct { -- A int --} -- --type Bar struct { -- X *Foo -- Y *Foo --} +-import _ "os" - --var _ = Bar{ -- X: &Foo{}, -- Y: &Foo{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true {<>} else {<>} +- case false: +- fmt.Println(<>) +- default: +- fmt.Println(<>) +- } +- /* This is a multiline +- block +- comment */ - --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val {<>} else {<>} +- case <-y: +- fmt.Println(<>) +- default: +- fmt.Println(<>) +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` -} - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- foldingRange-4 -- +-package folding //@fold("package") - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int --} +-import ( +- "fmt" +- _ "log" +-) - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import _ "os" - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") --} +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true { +- fmt.Println(<>) +- } else { +- fmt.Println(<>) +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline +- block +- comment */ - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val { +- fmt.Println(<>) +- } else { +- fmt.Println(<>) +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` +-} - ---- suggestedfix_a3_28_24 -- --package fillstruct +--- foldingRange-comment-0 -- +-package folding //@fold("package") - -import ( -- "go/ast" -- "go/token" +- "fmt" +- _ "log" -) - --type Foo struct { -- A int --} -- --type Bar struct { -- X *Foo -- Y *Foo --} +-import _ "os" - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-// bar is a function.<> +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true { +- fmt.Println("true") +- } else { +- fmt.Println("false") +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline<> - --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +- /* This is a multiline<> +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val { +- fmt.Println("true from x") +- } else { +- fmt.Println("false from x") +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment<> +- return ` +-this string +-is not indented` -} - --var _ = importedStruct{ -- m: map[*ast.CompositeLit]ast.Field{}, -- s: []ast.BadExpr{}, -- a: [3]token.Token{}, -- c: make(chan ast.EmptyStmt), -- fn: func(ast_decl ast.DeclStmt) ast.Ellipsis { -- }, -- st: ast.CompositeLit{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- foldingRange-imports-0 -- +-package folding //@fold("package") - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int --} +-import (<>) - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import _ "os" - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") --} +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true { +- fmt.Println("true") +- } else { +- fmt.Println("false") +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline +- block +- comment */ - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val { +- fmt.Println("true from x") +- } else { +- fmt.Println("false from x") +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` +-} - ---- suggestedfix_a3_36_30 -- --package fillstruct +--- foldingRange-lineFolding-0 -- +-package folding //@fold("package") - --import ( -- "go/ast" -- "go/token" +-import (<> -) - --type Foo struct { -- A int --} +-import _ "os" - --type Bar struct { -- X *Foo -- Y *Foo +-// bar is a function.<> +-func bar() string {<> -} - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit --} +--- foldingRange-lineFolding-1 -- +-package folding //@fold("package") - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( +- "fmt" +- _ "log" +-) - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int --} +-import _ "os" - --var _ = pointerBuiltinStruct{ -- b: new(bool), -- s: new(string), -- i: new(int), --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch {<> +- } +- /* This is a multiline<> - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +- /* This is a multiline<> +- _ = []int{<>, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{<>, +- } +- type T struct {<> +- } +- _ = T{<>, +- } +- x, y := make(chan bool), make(chan bool) +- select {<> +- } +- // This is a multiline comment<> +- return <> -} - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") -- ---- suggestedfix_a3_39_3 -- --package fillstruct +--- foldingRange-lineFolding-2 -- +-package folding //@fold("package") - -import ( -- "go/ast" -- "go/token" +- "fmt" +- _ "log" -) - --type Foo struct { -- A int --} -- --type Bar struct { -- X *Foo -- Y *Foo --} -- --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit --} -- --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int --} +-import _ "os" - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true:<> +- case false:<> +- default:<> +- } +- /* This is a multiline +- block +- comment */ - --var _ = []ast.BasicLit{ -- { -- ValuePos: 0, -- Kind: 0, -- Value: "", -- }, //@suggestedfix("}", "refactor.rewrite", "Fill") +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x:<> +- case <-y:<> +- default:<> +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` -} - --var _ = []ast.BasicLit{{}} //@suggestedfix("}", "refactor.rewrite", "Fill") -- ---- suggestedfix_a3_42_25 -- --package fillstruct +--- foldingRange-lineFolding-3 -- +-package folding //@fold("package") - -import ( -- "go/ast" -- "go/token" +- "fmt" +- _ "log" -) - --type Foo struct { -- A int --} -- --type Bar struct { -- X *Foo -- Y *Foo --} +-import _ "os" - --var _ = Bar{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true {<> +- } else {<> +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline +- block +- comment */ - --type importedStruct struct { -- m map[*ast.CompositeLit]ast.Field -- s []ast.BadExpr -- a [3]token.Token -- c chan ast.EmptyStmt -- fn func(ast_decl ast.DeclStmt) ast.Ellipsis -- st ast.CompositeLit +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val {<> +- } else {<> +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` -} - --var _ = importedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- foldingRange-lineFolding-comment-0 -- +-package folding //@fold("package") - --type pointerBuiltinStruct struct { -- b *bool -- s *string -- i *int --} +-import ( +- "fmt" +- _ "log" +-) - --var _ = pointerBuiltinStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import _ "os" - --var _ = []ast.BasicLit{ -- {}, //@suggestedfix("}", "refactor.rewrite", "Fill") +-// bar is a function.<> +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true { +- fmt.Println("true") +- } else { +- fmt.Println("false") +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline<> +- +- /* This is a multiline<> +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val { +- fmt.Println("true from x") +- } else { +- fmt.Println("false from x") +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment<> +- return ` +-this string +-is not indented` -} - --var _ = []ast.BasicLit{{ -- ValuePos: 0, -- Kind: 0, -- Value: "", --}} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- foldingRange-lineFolding-imports-0 -- +-package folding //@fold("package") - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a4.go b/gopls/internal/lsp/testdata/fillstruct/a4.go ---- a/gopls/internal/lsp/testdata/fillstruct/a4.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a4.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,39 +0,0 @@ --package fillstruct +-import (<> +-) - --import "go/ast" +-import _ "os" - --type iStruct struct { -- X int --} +-// bar is a function. +-// With a multiline doc comment. +-func bar() string { +- /* This is a single line comment */ +- switch { +- case true: +- if true { +- fmt.Println("true") +- } else { +- fmt.Println("false") +- } +- case false: +- fmt.Println("false") +- default: +- fmt.Println("default") +- } +- /* This is a multiline +- block +- comment */ - --type sStruct struct { -- str string +- /* This is a multiline +- block +- comment */ +- // Followed by another comment. +- _ = []int{ +- 1, +- 2, +- 3, +- } +- _ = [2]string{"d", +- "e", +- } +- _ = map[string]int{ +- "a": 1, +- "b": 2, +- "c": 3, +- } +- type T struct { +- f string +- g int +- h string +- } +- _ = T{ +- f: "j", +- g: 4, +- h: "i", +- } +- x, y := make(chan bool), make(chan bool) +- select { +- case val := <-x: +- if val { +- fmt.Println("true from x") +- } else { +- fmt.Println("false from x") +- } +- case <-y: +- fmt.Println("y") +- default: +- fmt.Println("default") +- } +- // This is a multiline comment +- // that is not a doc comment. +- return ` +-this string +-is not indented` -} - --type multiFill struct { -- num int -- strin string -- arr []int --} +diff -urN a/gopls/internal/lsp/testdata/folding/bad.go.golden b/gopls/internal/lsp/testdata/folding/bad.go.golden +--- a/gopls/internal/lsp/testdata/folding/bad.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/folding/bad.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,81 +0,0 @@ +--- foldingRange-0 -- +-package folding //@fold("package") - --type assignStruct struct { -- n ast.Node --} +-import (<>) - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import (<>) +- +-// badBar is a function. +-func badBar(<>) string {<>} - -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- foldingRange-1 -- +-package folding //@fold("package") - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( "fmt" +- _ "log" +-) - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( +- _ "os" ) +- +-// badBar is a function. +-func badBar() string { x := true +- if x {<>} else {<>} +- return -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a4.go.golden b/gopls/internal/lsp/testdata/fillstruct/a4.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a4.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a4.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,174 +0,0 @@ ---- suggestedfix_a4_25_18 -- --package fillstruct - --import "go/ast" +--- foldingRange-2 -- +-package folding //@fold("package") - --type iStruct struct { -- X int --} +-import ( "fmt" +- _ "log" +-) - --type sStruct struct { -- str string +-import ( +- _ "os" ) +- +-// badBar is a function. +-func badBar() string { x := true +- if x { +- // This is the only foldable thing in this file when lineFoldingOnly +- fmt.Println(<>) +- } else { +- fmt.Println(<>) } +- return -} - --type multiFill struct { -- num int -- strin string -- arr []int --} +--- foldingRange-imports-0 -- +-package folding //@fold("package") - --type assignStruct struct { -- n ast.Node --} +-import (<>) - --func fill() { -- var x int -- var _ = iStruct{ -- X: x, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-import (<>) +- +-// badBar is a function. +-func badBar() string { x := true +- if x { +- // This is the only foldable thing in this file when lineFoldingOnly +- fmt.Println("true") +- } else { +- fmt.Println("false") } +- return +-} - -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- foldingRange-lineFolding-0 -- +-package folding //@fold("package") - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( "fmt" +- _ "log" +-) - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( +- _ "os" ) +- +-// badBar is a function. +-func badBar() string { x := true +- if x {<> +- } else { +- fmt.Println("false") } +- return -} - ---- suggestedfix_a4_28_18 -- --package fillstruct +diff -urN a/gopls/internal/lsp/testdata/folding/bad.go.in b/gopls/internal/lsp/testdata/folding/bad.go.in +--- a/gopls/internal/lsp/testdata/folding/bad.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/folding/bad.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-package folding //@fold("package") - --import "go/ast" +-import ( "fmt" +- _ "log" +-) - --type iStruct struct { -- X int +-import ( +- _ "os" ) +- +-// badBar is a function. +-func badBar() string { x := true +- if x { +- // This is the only foldable thing in this file when lineFoldingOnly +- fmt.Println("true") +- } else { +- fmt.Println("false") } +- return -} +diff -urN a/gopls/internal/lsp/testdata/foo/foo.go b/gopls/internal/lsp/testdata/foo/foo.go +--- a/gopls/internal/lsp/testdata/foo/foo.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/foo/foo.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +-package foo //@mark(PackageFoo, "foo"),item(PackageFoo, "foo", "\"golang.org/lsptests/foo\"", "package") - --type sStruct struct { -- str string +-type StructFoo struct { //@item(StructFoo, "StructFoo", "struct{...}", "struct") +- Value int //@item(Value, "Value", "int", "field") -} - --type multiFill struct { -- num int -- strin string -- arr []int --} +-// Pre-set this marker, as we don't have a "source" for it in this package. +-/* Error() */ //@item(Error, "Error", "func() string", "method") - --type assignStruct struct { -- n ast.Node +-func Foo() { //@item(Foo, "Foo", "func()", "func") +- var err error +- err.Error() //@complete("E", Error) -} - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- -- var s string -- var _ = sStruct{ -- str: s, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} +-func _() { +- var sFoo StructFoo //@complete("t", StructFoo) +- if x := sFoo; x.Value == 1 { //@complete("V", Value),typdef("sFoo", StructFoo) +- return - } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-} - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- shadowed := 123 +- { +- shadowed := "hi" //@item(shadowed, "shadowed", "string", "var") +- sha //@complete("a", shadowed) +- } -} - ---- suggestedfix_a4_35_20 -- --package fillstruct +-type IntFoo int //@item(IntFoo, "IntFoo", "int", "type") +diff -urN a/gopls/internal/lsp/testdata/func_rank/func_rank.go.in b/gopls/internal/lsp/testdata/func_rank/func_rank.go.in +--- a/gopls/internal/lsp/testdata/func_rank/func_rank.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/func_rank/func_rank.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,70 +0,0 @@ +-package func_rank - --import "go/ast" +-import "net/http" - --type iStruct struct { -- X int --} +-var stringAVar = "var" //@item(stringAVar, "stringAVar", "string", "var") +-func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc", "func() string", "func") +-type stringer struct{} //@item(stringer, "stringer", "struct{...}", "struct") - --type sStruct struct { -- str string --} +-func _() stringer //@complete("tr", stringer) - --type multiFill struct { -- num int -- strin string -- arr []int --} +-func _(val stringer) {} //@complete("tr", stringer) - --type assignStruct struct { -- n ast.Node --} +-func (stringer) _() {} //@complete("tr", stringer) - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- var s struct { +- AA int //@item(rankAA, "AA", "int", "field") +- AB string //@item(rankAB, "AB", "string", "field") +- AC int //@item(rankAC, "AC", "int", "field") +- } +- fnStr := func(string) {} +- fnStr(s.A) //@complete(")", rankAB, rankAA, rankAC) +- fnStr("" + s.A) //@complete(")", rankAB, rankAA, rankAC) - -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- fnInt := func(int) {} +- fnInt(-s.A) //@complete(")", rankAA, rankAC, rankAB) - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{ -- num: n, -- strin: s, -- arr: []int{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- // no expected type +- fnInt(func() int { s.A }) //@complete(" }", rankAA, rankAB, rankAC) +- fnInt(s.A()) //@complete("()", rankAA, rankAC, rankAB) +- fnInt([]int{}[s.A]) //@complete("])", rankAA, rankAC, rankAB) +- fnInt([]int{}[:s.A]) //@complete("])", rankAA, rankAC, rankAB) - -- var node *ast.CompositeLit -- var _ = assignStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} +- fnInt(s.A.(int)) //@complete(".(", rankAA, rankAC, rankAB) - ---- suggestedfix_a4_38_23 -- --package fillstruct +- fnPtr := func(*string) {} +- fnPtr(&s.A) //@complete(")", rankAB, rankAA, rankAC) - --import "go/ast" +- var aaPtr *string //@item(rankAAPtr, "aaPtr", "*string", "var") +- var abPtr *int //@item(rankABPtr, "abPtr", "*int", "var") +- fnInt(*a) //@complete(")", rankABPtr, rankAAPtr) - --type iStruct struct { -- X int +- _ = func() string { +- return s.A //@complete(" //", rankAB, rankAA, rankAC) +- } -} - --type sStruct struct { -- str string +-type foo struct { +- fooPrivateField int //@item(rankFooPrivField, "fooPrivateField", "int", "field") +- FooPublicField int //@item(rankFooPubField, "FooPublicField", "int", "field") -} - --type multiFill struct { -- num int -- strin string -- arr []int +-func (foo) fooPrivateMethod() int { //@item(rankFooPrivMeth, "fooPrivateMethod", "func() int", "method") +- return 0 -} - --type assignStruct struct { -- n ast.Node +-func (foo) FooPublicMethod() int { //@item(rankFooPubMeth, "FooPublicMethod", "func() int", "method") +- return 0 -} - --func fill() { -- var x int -- var _ = iStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- -- var s string -- var _ = sStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- var _ int = foo{}. //@rank(" //", rankFooPrivField, rankFooPubField),rank(" //", rankFooPrivMeth, rankFooPubMeth),rank(" //", rankFooPrivField, rankFooPrivMeth) +-} - -- var n int -- _ = []int{} -- if true { -- arr := []int{1, 2} -- } -- var _ = multiFill{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- HandleFunc //@item(httpHandleFunc, "HandleFunc", "func(pattern string, handler func(http.ResponseWriter, *http.Request))", "func") +- HandlerFunc //@item(httpHandlerFunc, "HandlerFunc", "func(http.ResponseWriter, *http.Request)", "type") - -- var node *ast.CompositeLit -- var _ = assignStruct{ -- n: node, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- http.HandleFunc //@rank(" //", httpHandleFunc, httpHandlerFunc) -} +diff -urN a/gopls/internal/lsp/testdata/funcsig/func_sig.go b/gopls/internal/lsp/testdata/funcsig/func_sig.go +--- a/gopls/internal/lsp/testdata/funcsig/func_sig.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/funcsig/func_sig.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package funcsig - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a.go b/gopls/internal/lsp/testdata/fillstruct/a.go ---- a/gopls/internal/lsp/testdata/fillstruct/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package fillstruct +-type someType int //@item(sigSomeType, "someType", "int", "type") - --import ( -- "golang.org/lsptests/fillstruct/data" --) +-// Don't complete "foo" in signature. +-func (foo someType) _() { //@item(sigFoo, "foo", "someType", "var"),complete(") {", sigSomeType) - --type basicStruct struct { -- foo int +- //@complete("", sigFoo, sigSomeType) -} +diff -urN a/gopls/internal/lsp/testdata/funcvalue/func_value.go b/gopls/internal/lsp/testdata/funcvalue/func_value.go +--- a/gopls/internal/lsp/testdata/funcvalue/func_value.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/funcvalue/func_value.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package funcvalue - --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type twoArgStruct struct { -- foo int -- bar string +-func fooFunc() int { //@item(fvFooFunc, "fooFunc", "func() int", "func") +- return 0 -} - --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = fooFunc() //@item(fvFooFuncCall, "fooFunc", "func() int", "func") - --type nestedStruct struct { -- bar string -- basic basicStruct +-var fooVar = func() int { //@item(fvFooVar, "fooVar", "func() int", "var") +- return 0 -} - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var _ = fooVar() //@item(fvFooVarCall, "fooVar", "func() int", "var") - --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -diff -urN a/gopls/internal/lsp/testdata/fillstruct/a.go.golden b/gopls/internal/lsp/testdata/fillstruct/a.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/a.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,126 +0,0 @@ ---- suggestedfix_a_11_21 -- --package fillstruct +-type myFunc func() int - --import ( -- "golang.org/lsptests/fillstruct/data" --) +-var fooType myFunc = fooVar //@item(fvFooType, "fooType", "myFunc", "var") - --type basicStruct struct { -- foo int --} +-var _ = fooType() //@item(fvFooTypeCall, "fooType", "func() int", "var") - --var _ = basicStruct{ -- foo: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- var f func() int +- f = foo //@complete(" //", fvFooFunc, fvFooType, fvFooVar) - --type twoArgStruct struct { -- foo int -- bar string +- var i int +- i = foo //@complete(" //", fvFooFuncCall, fvFooTypeCall, fvFooVarCall) -} +diff -urN a/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go b/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go +--- a/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,48 +0,0 @@ +-// Copyright 2019 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type nestedStruct struct { -- bar string -- basic basicStruct --} +-package fuzzy - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func _() { +- var a struct { +- fabar int +- fooBar string +- } - --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- a.fabar //@item(fuzzFabarField, "a.fabar", "int", "field") +- a.fooBar //@item(fuzzFooBarField, "a.fooBar", "string", "field") - ---- suggestedfix_a_18_22 -- --package fillstruct +- afa //@fuzzy(" //", fuzzFabarField, fuzzFooBarField) +- afb //@fuzzy(" //", fuzzFooBarField, fuzzFabarField) - --import ( -- "golang.org/lsptests/fillstruct/data" --) +- fab //@fuzzy(" //", fuzzFabarField) - --type basicStruct struct { -- foo int --} +- var myString string +- myString = af //@fuzzy(" //", fuzzFooBarField, fuzzFabarField) - --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- var b struct { +- c struct { +- d struct { +- e struct { +- abc string +- } +- abc float32 +- } +- abc bool +- } +- abc int +- } - --type twoArgStruct struct { -- foo int -- bar string --} +- b.abc //@item(fuzzABCInt, "b.abc", "int", "field") +- b.c.abc //@item(fuzzABCbool, "b.c.abc", "bool", "field") +- b.c.d.abc //@item(fuzzABCfloat, "b.c.d.abc", "float32", "field") +- b.c.d.e.abc //@item(fuzzABCstring, "b.c.d.e.abc", "string", "field") - --var _ = twoArgStruct{ -- foo: 0, -- bar: "", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +- // in depth order by default +- abc //@fuzzy(" //", fuzzABCInt, fuzzABCbool, fuzzABCfloat) - --type nestedStruct struct { -- bar string -- basic basicStruct +- // deep candidate that matches expected type should still ranked first +- var s string +- s = abc //@fuzzy(" //", fuzzABCstring, fuzzABCInt, fuzzABCbool) -} +diff -urN a/gopls/internal/lsp/testdata/generate/generate.go b/gopls/internal/lsp/testdata/generate/generate.go +--- a/gopls/internal/lsp/testdata/generate/generate.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/generate/generate.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,4 +0,0 @@ +-package generate - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- ---- suggestedfix_a_25_22 -- --package fillstruct +-//go:generate echo Hi //@ codelens("//go:generate", "run go generate", "generate"), codelens("//go:generate", "run go generate ./...", "generate") +-//go:generate echo I shall have no CodeLens +diff -urN a/gopls/internal/lsp/testdata/godef/a/a_x_test.go b/gopls/internal/lsp/testdata/godef/a/a_x_test.go +--- a/gopls/internal/lsp/testdata/godef/a/a_x_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/a_x_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package a_test - -import ( -- "golang.org/lsptests/fillstruct/data" +- "testing" -) - --type basicStruct struct { -- foo int --} -- --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type twoArgStruct struct { -- foo int -- bar string +-func TestA2(t *testing.T) { //@TestA2,godef(TestA2, TestA2) +- Nonexistant() //@diag("Nonexistant", "compiler", "(undeclared name|undefined): Nonexistant", "error") -} -- --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type nestedStruct struct { -- bar string -- basic basicStruct +diff -urN a/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden b/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden +--- a/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +--- TestA2-definition -- +-godef/a/a_x_test.go:7:6-12: defined here as ```go +-func TestA2(t *testing.T) +-``` +--- TestA2-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/a_x_test.go", +- "start": { +- "line": 7, +- "column": 6, +- "offset": 44 +- }, +- "end": { +- "line": 7, +- "column": 12, +- "offset": 50 +- } +- }, +- "description": "```go\nfunc TestA2(t *testing.T)\n```" -} - --var _ = nestedStruct{ -- bar: "", -- basic: basicStruct{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --var _ = data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- ---- suggestedfix_a_27_16 -- --package fillstruct +--- TestA2-hoverdef -- +-```go +-func TestA2(t *testing.T) +-``` +diff -urN a/gopls/internal/lsp/testdata/godef/a/d.go b/gopls/internal/lsp/testdata/godef/a/d.go +--- a/gopls/internal/lsp/testdata/godef/a/d.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/d.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-package a //@mark(a, "a "),hoverdef("a ", a) - --import ( -- "golang.org/lsptests/fillstruct/data" --) +-import "fmt" - --type basicStruct struct { -- foo int +-type Thing struct { //@Thing +- Member string //@Member -} - --var _ = basicStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var Other Thing //@Other - --type twoArgStruct struct { -- foo int -- bar string +-func Things(val []string) []Thing { //@Things +- return nil -} - --var _ = twoArgStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type nestedStruct struct { -- bar string -- basic basicStruct +-func (t Thing) Method(i int) string { //@Method +- return t.Member -} - --var _ = nestedStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (t Thing) Method3() { +-} - --var _ = data.B{ -- ExportedInt: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (t *Thing) Method2(i int, j int) (error, string) { +- return nil, t.Member +-} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/data/a.go b/gopls/internal/lsp/testdata/fillstruct/data/a.go ---- a/gopls/internal/lsp/testdata/fillstruct/data/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/data/a.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package data -- --type B struct { -- ExportedInt int -- unexportedInt int --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ --package fillstruct +-func (t *Thing) private() { +-} - --type StructAnon struct { -- a struct{} -- b map[string]interface{} -- c map[string]struct { -- d int -- e bool +-func useThings() { +- t := Thing{ //@mark(aStructType, "ing") +- Member: "string", //@mark(fMember, "ember") - } +- fmt.Print(t.Member) //@mark(aMember, "ember") +- fmt.Print(Other) //@mark(aVar, "ther") +- Things() //@mark(aFunc, "ings") +- t.Method() //@mark(aMethod, "eth") -} - --func fill() { -- _ := StructAnon{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-type NextThing struct { //@NextThing +- Thing +- Value int -} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_anon.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ ---- suggestedfix_fill_struct_anon_13_18 -- --package fillstruct - --type StructAnon struct { -- a struct{} -- b map[string]interface{} -- c map[string]struct { -- d int -- e bool -- } +-func (n NextThing) another() string { +- return n.Member -} - --func fill() { -- _ := StructAnon{ -- a: struct{}{}, -- b: map[string]interface{}{}, -- c: map[string]struct{d int; e bool}{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-// Shadows Thing.Method3 +-func (n *NextThing) Method3() int { +- return n.Value -} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,26 +0,0 @@ --package fillstruct +-var nextThing NextThing //@hoverdef("NextThing", NextThing) - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB --} +-/*@ +-godef(aStructType, Thing) +-godef(aMember, Member) +-godef(aVar, Other) +-godef(aFunc, Things) +-godef(aMethod, Method) +-godef(fMember, Member) +-godef(Member, Member) - --type StructA2 struct { -- B *StructB --} +-//param +-//package name +-//const +-//anon field - --type StructA3 struct { -- B StructB --} +-*/ +diff -urN a/gopls/internal/lsp/testdata/godef/a/d.go.golden b/gopls/internal/lsp/testdata/godef/a/d.go.golden +--- a/gopls/internal/lsp/testdata/godef/a/d.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/d.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,191 +0,0 @@ +--- Member-definition -- +-godef/a/d.go:6:2-8: defined here as ```go +-field Member string +-``` - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,124 +0,0 @@ ---- suggestedfix_fill_struct_20_15 -- --package fillstruct +-@Member - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB --} - --type StructA2 struct { -- B *StructB +-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) +--- Member-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 6, +- "column": 2, +- "offset": 90 +- }, +- "end": { +- "line": 6, +- "column": 8, +- "offset": 96 +- } +- }, +- "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)" -} - --type StructA3 struct { -- B StructB --} +--- Member-hoverdef -- +-```go +-field Member string +-``` - --func fill() { -- a := StructA{ -- unexportedIntField: 0, -- ExportedIntField: 0, -- MapA: map[int]string{}, -- Array: []int{}, -- StructB: StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } +-@Member +- +- +-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) +--- Method-definition -- +-godef/a/d.go:15:16-22: defined here as ```go +-func (Thing).Method(i int) string +-``` +- +-[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method) +--- Method-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 15, +- "column": 16, +- "offset": 219 +- }, +- "end": { +- "line": 15, +- "column": 22, +- "offset": 225 +- } +- }, +- "description": "```go\nfunc (Thing).Method(i int) string\n```\n\n[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method)" -} - ---- suggestedfix_fill_struct_21_16 -- --package fillstruct +--- Method-hoverdef -- +-```go +-func (Thing).Method(i int) string +-``` - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB +-[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method) +--- NextThing-hoverdef -- +-```go +-type NextThing struct { +- Thing +- Value int -} - --type StructA2 struct { -- B *StructB --} +-func (*NextThing).Method3() int +-func (NextThing).another() string +-``` +- +-[`a.NextThing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#NextThing) +--- Other-definition -- +-godef/a/d.go:9:5-10: defined here as ```go +-var Other Thing +-``` +- +-@Other - --type StructA3 struct { -- B StructB --} - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{ -- B: &StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } +-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) +--- Other-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 9, +- "column": 5, +- "offset": 121 +- }, +- "end": { +- "line": 9, +- "column": 10, +- "offset": 126 +- } +- }, +- "description": "```go\nvar Other Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)" -} - ---- suggestedfix_fill_struct_22_16 -- --package fillstruct +--- Other-hoverdef -- +-```go +-var Other Thing +-``` - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB --} +-@Other - --type StructA2 struct { -- B *StructB +- +-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) +--- Thing-definition -- +-godef/a/d.go:5:6-11: defined here as ```go +-type Thing struct { +- Member string //@Member -} - --type StructA3 struct { -- B StructB +-func (Thing).Method(i int) string +-func (*Thing).Method2(i int, j int) (error, string) +-func (Thing).Method3() +-func (*Thing).private() +-``` +- +-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) +--- Thing-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 5, +- "column": 6, +- "offset": 65 +- }, +- "end": { +- "line": 5, +- "column": 11, +- "offset": 70 +- } +- }, +- "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n\nfunc (Thing).Method(i int) string\nfunc (*Thing).Method2(i int, j int) (error, string)\nfunc (Thing).Method3()\nfunc (*Thing).private()\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)" -} - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{ -- B: StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- } +--- Thing-hoverdef -- +-```go +-type Thing struct { +- Member string //@Member -} - ---- suggestedfix_fill_struct_24_16 -- --package fillstruct +-func (Thing).Method(i int) string +-func (*Thing).Method2(i int, j int) (error, string) +-func (Thing).Method3() +-func (*Thing).private() +-``` - --type StructA struct { -- unexportedIntField int -- ExportedIntField int -- MapA map[int]string -- Array []int -- StructB --} +-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) +--- Things-definition -- +-godef/a/d.go:11:6-12: defined here as ```go +-func Things(val []string) []Thing +-``` - --type StructA2 struct { -- B *StructB +-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) +--- Things-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 11, +- "column": 6, +- "offset": 148 +- }, +- "end": { +- "line": 11, +- "column": 12, +- "offset": 154 +- } +- }, +- "description": "```go\nfunc Things(val []string) []Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)" -} - --type StructA3 struct { -- B StructB --} +--- Things-hoverdef -- +-```go +-func Things(val []string) []Thing +-``` - --func fill() { -- a := StructA{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructA2{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- c := StructA3{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- if true { -- _ = StructA3{ -- B: StructB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- } --} +-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) +--- a-hoverdef -- +-Package a is a package for testing go to definition. - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ --package fillstruct +diff -urN a/gopls/internal/lsp/testdata/godef/a/f.go b/gopls/internal/lsp/testdata/godef/a/f.go +--- a/gopls/internal/lsp/testdata/godef/a/f.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/f.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-// Package a is a package for testing go to definition. +-package a - --type StructB struct { -- StructC --} +-import "fmt" - --type StructC struct { -- unexportedInt int --} +-func TypeStuff() { //@Stuff +- var x string - --func nested() { -- c := StructB{ -- StructC: StructC{}, //@suggestedfix("}", "refactor.rewrite", "Fill") +- switch y := interface{}(x).(type) { //@mark(switchY, "y"),godef("y", switchY) +- case int: //@mark(intY, "int") +- fmt.Printf("%v", y) //@hoverdef("y", intY) +- case string: //@mark(stringY, "string") +- fmt.Printf("%v", y) //@hoverdef("y", stringY) - } --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_nested.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ ---- suggestedfix_fill_struct_nested_13_20 -- --package fillstruct - --type StructB struct { -- StructC -} -- --type StructC struct { -- unexportedInt int +diff -urN a/gopls/internal/lsp/testdata/godef/a/f.go.golden b/gopls/internal/lsp/testdata/godef/a/f.go.golden +--- a/gopls/internal/lsp/testdata/godef/a/f.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/f.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,34 +0,0 @@ +--- intY-hoverdef -- +-```go +-var y int +-``` +--- stringY-hoverdef -- +-```go +-var y string +-``` +--- switchY-definition -- +-godef/a/f.go:8:9-10: defined here as ```go +-var y interface{} +-``` +--- switchY-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/f.go", +- "start": { +- "line": 8, +- "column": 9, +- "offset": 76 +- }, +- "end": { +- "line": 8, +- "column": 10, +- "offset": 77 +- } +- }, +- "description": "```go\nvar y interface{}\n```" -} - --func nested() { -- c := StructB{ -- StructC: StructC{ -- unexportedInt: 0, -- }, //@suggestedfix("}", "refactor.rewrite", "Fill") +--- switchY-hoverdef -- +-```go +-var y interface{} +-``` +diff -urN a/gopls/internal/lsp/testdata/godef/a/h.go b/gopls/internal/lsp/testdata/godef/a/h.go +--- a/gopls/internal/lsp/testdata/godef/a/h.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/h.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,147 +0,0 @@ +-package a +- +-func _() { +- type s struct { +- nested struct { +- // nested number +- number int64 //@mark(nestedNumber, "number") +- } +- nested2 []struct { +- // nested string +- str string //@mark(nestedString, "str") +- } +- x struct { +- x struct { +- x struct { +- x struct { +- x struct { +- // nested map +- m map[string]float64 //@mark(nestedMap, "m") +- } +- } +- } +- } +- } - } --} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package fillstruct +- var t s +- _ = t.nested.number //@hoverdef("number", nestedNumber) +- _ = t.nested2[0].str //@hoverdef("str", nestedString) +- _ = t.x.x.x.x.x.m //@hoverdef("m", nestedMap) +-} - --import ( -- h2 "net/http" +-func _() { +- var s struct { +- // a field +- a int //@mark(structA, "a") +- // b nested struct +- b struct { //@mark(structB, "b") +- // c field of nested struct +- c int //@mark(structC, "c") +- } +- } +- _ = s.a //@hoverdef("a", structA) +- _ = s.b //@hoverdef("b", structB) +- _ = s.b.c //@hoverdef("c", structC) - -- "golang.org/lsptests/fillstruct/data" --) +- var arr []struct { +- // d field +- d int //@mark(arrD, "d") +- // e nested struct +- e struct { //@mark(arrE, "e") +- // f field of nested struct +- f int //@mark(arrF, "f") +- } +- } +- _ = arr[0].d //@hoverdef("d", arrD) +- _ = arr[0].e //@hoverdef("e", arrE) +- _ = arr[0].e.f //@hoverdef("f", arrF) - --func unexported() { -- a := data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- _ = h2.Client{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_package.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,36 +0,0 @@ ---- suggestedfix_fill_struct_package_10_14 -- --package fillstruct +- var complex []struct { +- c <-chan map[string][]struct { +- // h field +- h int //@mark(complexH, "h") +- // i nested struct +- i struct { //@mark(complexI, "i") +- // j field of nested struct +- j int //@mark(complexJ, "j") +- } +- } +- } +- _ = (<-complex[0].c)["0"][0].h //@hoverdef("h", complexH) +- _ = (<-complex[0].c)["0"][0].i //@hoverdef("i", complexI) +- _ = (<-complex[0].c)["0"][0].i.j //@hoverdef("j", complexJ) - --import ( -- h2 "net/http" +- var mapWithStructKey map[struct { +- // X key field +- x []string //@mark(mapStructKeyX, "x") +- }]int +- for k := range mapWithStructKey { +- _ = k.x //@hoverdef("x", mapStructKeyX) +- } - -- "golang.org/lsptests/fillstruct/data" --) +- var mapWithStructKeyAndValue map[struct { +- // Y key field +- y string //@mark(mapStructKeyY, "y") +- }]struct { +- // X value field +- x string //@mark(mapStructValueX, "x") +- } +- for k, v := range mapWithStructKeyAndValue { +- // TODO: we don't show docs for y field because both map key and value +- // are structs. And in this case, we parse only map value +- _ = k.y //@hoverdef("y", mapStructKeyY) +- _ = v.x //@hoverdef("x", mapStructValueX) +- } - --func unexported() { -- a := data.B{ -- ExportedInt: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- _ = h2.Client{} //@suggestedfix("}", "refactor.rewrite", "Fill") +- var i []map[string]interface { +- // open method comment +- open() error //@mark(openMethod, "open") +- } +- i[0]["1"].open() //@hoverdef("open", openMethod) -} - ---- suggestedfix_fill_struct_package_11_16 -- --package fillstruct -- --import ( -- h2 "net/http" +-func _() { +- test := struct { +- // test description +- desc string //@mark(testDescription, "desc") +- }{} +- _ = test.desc //@hoverdef("desc", testDescription) - -- "golang.org/lsptests/fillstruct/data" --) +- for _, tt := range []struct { +- // test input +- in map[string][]struct { //@mark(testInput, "in") +- // test key +- key string //@mark(testInputKey, "key") +- // test value +- value interface{} //@mark(testInputValue, "value") +- } +- result struct { +- v <-chan struct { +- // expected test value +- value int //@mark(testResultValue, "value") +- } +- } +- }{} { +- _ = tt.in //@hoverdef("in", testInput) +- _ = tt.in["0"][0].key //@hoverdef("key", testInputKey) +- _ = tt.in["0"][0].value //@hoverdef("value", testInputValue) - --func unexported() { -- a := data.B{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- _ = h2.Client{ -- Transport: nil, -- CheckRedirect: func(req *h2.Request, via []*h2.Request) error { -- }, -- Jar: nil, -- Timeout: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +- _ = (<-tt.result.v).value //@hoverdef("value", testResultValue) +- } -} - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ --package fillstruct -- --type StructPartialA struct { -- PrefilledInt int -- UnfilledInt int -- StructPartialB --} +-func _() { +- getPoints := func() []struct { +- // X coord +- x int //@mark(returnX, "x") +- // Y coord +- y int //@mark(returnY, "y") +- } { +- return nil +- } - --type StructPartialB struct { -- PrefilledInt int -- UnfilledInt int +- r := getPoints() +- r[0].x //@hoverdef("x", returnX) +- r[0].y //@hoverdef("y", returnY) -} +diff -urN a/gopls/internal/lsp/testdata/godef/a/h.go.golden b/gopls/internal/lsp/testdata/godef/a/h.go.golden +--- a/gopls/internal/lsp/testdata/godef/a/h.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/a/h.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,161 +0,0 @@ +--- arrD-hoverdef -- +-```go +-field d int +-``` - --func fill() { -- a := StructPartialA{ -- PrefilledInt: 5, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructPartialB{ -- /* this comment should disappear */ -- PrefilledInt: 7, // This comment should be blown away. -- /* As should -- this one */ -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_partial.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,52 +0,0 @@ ---- suggestedfix_fill_struct_partial_17_2 -- --package fillstruct +-d field - --type StructPartialA struct { -- PrefilledInt int -- UnfilledInt int -- StructPartialB --} +--- arrE-hoverdef -- +-```go +-field e struct{f int} +-``` - --type StructPartialB struct { -- PrefilledInt int -- UnfilledInt int --} +-e nested struct - --func fill() { -- a := StructPartialA{ -- PrefilledInt: 5, -- UnfilledInt: 0, -- StructPartialB: StructPartialB{}, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructPartialB{ -- /* this comment should disappear */ -- PrefilledInt: 7, // This comment should be blown away. -- /* As should -- this one */ -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} +--- arrF-hoverdef -- +-```go +-field f int +-``` - ---- suggestedfix_fill_struct_partial_23_2 -- --package fillstruct +-f field of nested struct - --type StructPartialA struct { -- PrefilledInt int -- UnfilledInt int -- StructPartialB --} +--- complexH-hoverdef -- +-```go +-field h int +-``` - --type StructPartialB struct { -- PrefilledInt int -- UnfilledInt int --} +-h field - --func fill() { -- a := StructPartialA{ -- PrefilledInt: 5, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") -- b := StructPartialB{ -- PrefilledInt: 7, -- UnfilledInt: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} +--- complexI-hoverdef -- +-```go +-field i struct{j int} +-``` - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package fillstruct +-i nested struct - --type StructD struct { -- ExportedIntField int --} +--- complexJ-hoverdef -- +-```go +-field j int +-``` - --func spaces() { -- d := StructD{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_spaces.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- suggestedfix_fill_struct_spaces_8_15 -- --package fillstruct +-j field of nested struct - --type StructD struct { -- ExportedIntField int --} +--- mapStructKeyX-hoverdef -- +-```go +-field x []string +-``` - --func spaces() { -- d := StructD{ -- ExportedIntField: 0, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} +-X key field - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package fillstruct +--- mapStructKeyY-hoverdef -- +-```go +-field y string +-``` - --import "unsafe" +-Y key field - --type unsafeStruct struct { -- x int -- p unsafe.Pointer --} +--- mapStructValueX-hoverdef -- +-```go +-field x string +-``` - --func fill() { -- _ := unsafeStruct{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/fill_struct_unsafe.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,17 +0,0 @@ ---- suggestedfix_fill_struct_unsafe_11_20 -- --package fillstruct +-X value field - --import "unsafe" +--- nestedMap-hoverdef -- +-```go +-field m map[string]float64 +-``` - --type unsafeStruct struct { -- x int -- p unsafe.Pointer --} +-nested map - --func fill() { -- _ := unsafeStruct{ -- x: 0, -- p: nil, -- } //@suggestedfix("}", "refactor.rewrite", "Fill") --} +--- nestedNumber-hoverdef -- +-```go +-field number int64 +-``` - -diff -urN a/gopls/internal/lsp/testdata/fillstruct/typeparams.go b/gopls/internal/lsp/testdata/fillstruct/typeparams.go ---- a/gopls/internal/lsp/testdata/fillstruct/typeparams.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/typeparams.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,37 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-nested number - --package fillstruct +--- nestedString-hoverdef -- +-```go +-field str string +-``` - --type emptyStructWithTypeParams[A any] struct{} +-nested string - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +--- openMethod-hoverdef -- +-```go +-func (interface).open() error +-``` - --type basicStructWithTypeParams[T any] struct { -- foo T --} +-open method comment - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- returnX-hoverdef -- +-```go +-field x int +-``` - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B --} +-X coord - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- returnY-hoverdef -- +-```go +-field y int +-``` - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-Y coord - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] --} +--- structA-hoverdef -- +-```go +-field a int +-``` - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-a field - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} -diff -urN a/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden b/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden ---- a/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fillstruct/typeparams.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,206 +0,0 @@ ---- suggestedfix_typeparams_14_40 -- --//go:build go1.18 --// +build go1.18 +--- structB-hoverdef -- +-```go +-field b struct{c int} +-``` - --package fillstruct +-b nested struct - --type emptyStructWithTypeParams[A any] struct{} +--- structC-hoverdef -- +-```go +-field c int +-``` - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +-c field of nested struct - --type basicStructWithTypeParams[T any] struct { -- foo T --} +--- testDescription-hoverdef -- +-```go +-field desc string +-``` - --var _ = basicStructWithTypeParams[int]{ -- foo: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-test description - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B --} +--- testInput-hoverdef -- +-```go +-field in map[string][]struct{key string; value interface{}} +-``` - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-test input - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- testInputKey-hoverdef -- +-```go +-field key string +-``` - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] --} +-test key - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- testInputValue-hoverdef -- +-```go +-field value interface{} +-``` - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} +-test value - ---- suggestedfix_typeparams_21_49 -- --//go:build go1.18 --// +build go1.18 +--- testResultValue-hoverdef -- +-```go +-field value int +-``` - --package fillstruct +-expected test value - --type emptyStructWithTypeParams[A any] struct{} +diff -urN a/gopls/internal/lsp/testdata/godef/b/e.go b/gopls/internal/lsp/testdata/godef/b/e.go +--- a/gopls/internal/lsp/testdata/godef/b/e.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/b/e.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,31 +0,0 @@ +-package b - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +-import ( +- "fmt" - --type basicStructWithTypeParams[T any] struct { -- foo T +- "golang.org/lsptests/godef/a" +-) +- +-func useThings() { +- t := a.Thing{} //@mark(bStructType, "ing") +- fmt.Print(t.Member) //@mark(bMember, "ember") +- fmt.Print(a.Other) //@mark(bVar, "ther") +- a.Things() //@mark(bFunc, "ings") -} - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-/*@ +-godef(bStructType, Thing) +-godef(bMember, Member) +-godef(bVar, Other) +-godef(bFunc, Things) +-*/ - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +-func _() { +- var x interface{} //@mark(eInterface, "interface{}") +- switch x := x.(type) { //@hoverdef("x", eInterface) +- case string: //@mark(eString, "string") +- fmt.Println(x) //@hoverdef("x", eString) +- case int: //@mark(eInt, "int") +- fmt.Println(x) //@hoverdef("x", eInt) +- } -} +diff -urN a/gopls/internal/lsp/testdata/godef/b/e.go.golden b/gopls/internal/lsp/testdata/godef/b/e.go.golden +--- a/gopls/internal/lsp/testdata/godef/b/e.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/b/e.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,156 +0,0 @@ +--- Member-definition -- +-godef/a/d.go:6:2-8: defined here as ```go +-field Member string +-``` - --var _ = twoArgStructWithTypeParams[string, int]{ -- foo: "", -- bar: 0, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-@Member - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) +--- Member-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 6, +- "column": 2, +- "offset": 90 +- }, +- "end": { +- "line": 6, +- "column": 8, +- "offset": 96 +- } +- }, +- "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)" -} - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- Member-hoverdef -- +-```go +-field Member string +-``` - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") --} +-@Member - ---- suggestedfix_typeparams_25_1 -- --//go:build go1.18 --// +build go1.18 - --package fillstruct +-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) +--- Other-definition -- +-godef/a/d.go:9:5-10: defined here as ```go +-var a.Other a.Thing +-``` - --type emptyStructWithTypeParams[A any] struct{} +-@Other - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix - --type basicStructWithTypeParams[T any] struct { -- foo T +-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) +--- Other-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 9, +- "column": 5, +- "offset": 121 +- }, +- "end": { +- "line": 9, +- "column": 10, +- "offset": 126 +- } +- }, +- "description": "```go\nvar a.Other a.Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)" -} - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") -- --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B --} +--- Other-hoverdef -- +-```go +-var a.Other a.Thing +-``` - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-@Other - --var _ = twoArgStructWithTypeParams[int, string]{ -- foo: 0, -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) +--- Thing-definition -- +-godef/a/d.go:5:6-11: defined here as ```go +-type Thing struct { +- Member string //@Member -} - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func (a.Thing).Method(i int) string +-func (*a.Thing).Method2(i int, j int) (error, string) +-func (a.Thing).Method3() +-``` - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) +--- Thing-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 5, +- "column": 6, +- "offset": 65 +- }, +- "end": { +- "line": 5, +- "column": 11, +- "offset": 70 +- } +- }, +- "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n\nfunc (a.Thing).Method(i int) string\nfunc (*a.Thing).Method2(i int, j int) (error, string)\nfunc (a.Thing).Method3()\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)" -} - ---- suggestedfix_typeparams_32_36 -- --//go:build go1.18 --// +build go1.18 -- --package fillstruct +--- Thing-hoverdef -- +-```go +-type Thing struct { +- Member string //@Member +-} - --type emptyStructWithTypeParams[A any] struct{} +-func (a.Thing).Method(i int) string +-func (*a.Thing).Method2(i int, j int) (error, string) +-func (a.Thing).Method3() +-``` - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) +--- Things-definition -- +-godef/a/d.go:11:6-12: defined here as ```go +-func a.Things(val []string) []a.Thing +-``` - --type basicStructWithTypeParams[T any] struct { -- foo T +-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) +--- Things-definition-json -- +-{ +- "span": { +- "uri": "file://godef/a/d.go", +- "start": { +- "line": 11, +- "column": 6, +- "offset": 148 +- }, +- "end": { +- "line": 11, +- "column": 12, +- "offset": 154 +- } +- }, +- "description": "```go\nfunc a.Things(val []string) []a.Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)" -} - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- Things-hoverdef -- +-```go +-func a.Things(val []string) []a.Thing +-``` - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) +--- eInt-hoverdef -- +-```go +-var x int +-``` +--- eInterface-hoverdef -- +-```go +-var x interface{} +-``` +--- eString-hoverdef -- +-```go +-var x string +-``` +diff -urN a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden +--- a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,31 +0,0 @@ +--- myUnclosedIf-definition -- +-godef/broken/unclosedIf.go:7:7-19: defined here as ```go +-var myUnclosedIf string +-``` +- +-@myUnclosedIf +--- myUnclosedIf-definition-json -- +-{ +- "span": { +- "uri": "file://godef/broken/unclosedIf.go", +- "start": { +- "line": 7, +- "column": 7, +- "offset": 68 +- }, +- "end": { +- "line": 7, +- "column": 19, +- "offset": 80 +- } +- }, +- "description": "```go\nvar myUnclosedIf string\n```\n\n@myUnclosedIf" -} - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +--- myUnclosedIf-hoverdef -- +-```go +-var myUnclosedIf string +-``` - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-@myUnclosedIf - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] --} +diff -urN a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in +--- a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package broken - --var _ = nestedStructWithTypeParams{ -- bar: "", -- basic: basicStructWithTypeParams{}, --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import "fmt" - --func _[T any]() { -- type S struct{ t T } -- _ = S{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func unclosedIf() { +- if false { +- var myUnclosedIf string //@myUnclosedIf +- fmt.Printf("s = %v\n", myUnclosedIf) //@godef("my", myUnclosedIf) -} +diff -urN a/gopls/internal/lsp/testdata/good/good0.go b/gopls/internal/lsp/testdata/good/good0.go +--- a/gopls/internal/lsp/testdata/good/good0.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/good/good0.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package good - ---- suggestedfix_typeparams_36_8 -- --//go:build go1.18 --// +build go1.18 -- --package fillstruct -- --type emptyStructWithTypeParams[A any] struct{} +-func stuff() { //@item(good_stuff, "stuff", "func()", "func"),prepare("stu", "stuff", "stuff") +- x := 5 +- random2(x) //@prepare("dom", "random2", "random2") +-} +diff -urN a/gopls/internal/lsp/testdata/good/good1.go b/gopls/internal/lsp/testdata/good/good1.go +--- a/gopls/internal/lsp/testdata/good/good1.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/good/good1.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +-package good - --var _ = emptyStructWithTypeParams[int]{} // no suggested fix +-import ( +- "golang.org/lsptests/types" //@item(types_import, "types", "\"golang.org/lsptests/types\"", "package") +-) - --type basicStructWithTypeParams[T any] struct { -- foo T +-func random() int { //@item(good_random, "random", "func() int", "func") +- _ = "random() int" //@prepare("random", "", "") +- y := 6 + 7 //@prepare("7", "", "") +- return y //@prepare("return", "","") -} - --var _ = basicStructWithTypeParams[int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-func random2(y int) int { //@item(good_random2, "random2", "func(y int) int", "func"),item(good_y_param, "y", "int", "var") +- //@complete("", good_y_param, types_import, good_random, good_random2, good_stuff) +- var b types.Bob = &types.X{} //@prepare("ypes","types", "types") +- if _, ok := b.(*types.X); ok { //@complete("X", X_struct, Y_struct, Bob_interface, CoolAlias) +- _ = 0 // suppress "empty branch" diagnostic +- } - --type twoArgStructWithTypeParams[F, B any] struct { -- foo F -- bar B +- return y -} +diff -urN a/gopls/internal/lsp/testdata/highlights/highlights.go b/gopls/internal/lsp/testdata/highlights/highlights.go +--- a/gopls/internal/lsp/testdata/highlights/highlights.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/highlights/highlights.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,151 +0,0 @@ +-package highlights - --var _ = twoArgStructWithTypeParams[string, int]{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-import ( +- "fmt" //@mark(fmtImp, "\"fmt\""),highlight(fmtImp, fmtImp, fmt1, fmt2, fmt3, fmt4) +- h2 "net/http" //@mark(hImp, "h2"),highlight(hImp, hImp, hUse) +- "sort" +-) - --var _ = twoArgStructWithTypeParams[int, string]{ -- bar: "bar", --} //@suggestedfix("}", "refactor.rewrite", "Fill") +-type F struct{ bar int } //@mark(barDeclaration, "bar"),highlight(barDeclaration, barDeclaration, bar1, bar2, bar3) - --type nestedStructWithTypeParams struct { -- bar string -- basic basicStructWithTypeParams[int] +-func _() F { +- return F{ +- bar: 123, //@mark(bar1, "bar"),highlight(bar1, barDeclaration, bar1, bar2, bar3) +- } -} - --var _ = nestedStructWithTypeParams{} //@suggestedfix("}", "refactor.rewrite", "Fill") +-var foo = F{bar: 52} //@mark(fooDeclaration, "foo"),mark(bar2, "bar"),highlight(fooDeclaration, fooDeclaration, fooUse),highlight(bar2, barDeclaration, bar1, bar2, bar3) - --func _[T any]() { -- type S struct{ t T } -- _ = S{ -- t: *new(T), -- } //@suggestedfix("}", "refactor.rewrite", "Fill") +-func Print() { //@mark(printFunc, "Print"),highlight(printFunc, printFunc, printTest) +- _ = h2.Client{} //@mark(hUse, "h2"),highlight(hUse, hImp, hUse) +- +- fmt.Println(foo) //@mark(fooUse, "foo"),highlight(fooUse, fooDeclaration, fooUse),mark(fmt1, "fmt"),highlight(fmt1, fmtImp, fmt1, fmt2, fmt3, fmt4) +- fmt.Print("yo") //@mark(printSep, "Print"),highlight(printSep, printSep, print1, print2),mark(fmt2, "fmt"),highlight(fmt2, fmtImp, fmt1, fmt2, fmt3, fmt4) -} - -diff -urN a/gopls/internal/lsp/testdata/folding/a.go b/gopls/internal/lsp/testdata/folding/a.go ---- a/gopls/internal/lsp/testdata/folding/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/folding/a.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,75 +0,0 @@ --package folding //@fold("package") +-func (x *F) Inc() { //@mark(xRightDecl, "x"),mark(xLeftDecl, " *"),highlight(xRightDecl, xRightDecl, xUse),highlight(xLeftDecl, xRightDecl, xUse) +- x.bar++ //@mark(xUse, "x"),mark(bar3, "bar"),highlight(xUse, xRightDecl, xUse),highlight(bar3, barDeclaration, bar1, bar2, bar3) +-} - --import ( -- "fmt" -- _ "log" --) +-func testFunctions() { +- fmt.Print("main start") //@mark(print1, "Print"),highlight(print1, printSep, print1, print2),mark(fmt3, "fmt"),highlight(fmt3, fmtImp, fmt1, fmt2, fmt3, fmt4) +- fmt.Print("ok") //@mark(print2, "Print"),highlight(print2, printSep, print1, print2),mark(fmt4, "fmt"),highlight(fmt4, fmtImp, fmt1, fmt2, fmt3, fmt4) +- Print() //@mark(printTest, "Print"),highlight(printTest, printFunc, printTest) +-} - --import _ "os" +-func toProtocolHighlight(rngs []int) []DocumentHighlight { //@mark(doc1, "DocumentHighlight"),mark(docRet1, "[]DocumentHighlight"),highlight(doc1, docRet1, doc1, doc2, doc3, result) +- result := make([]DocumentHighlight, 0, len(rngs)) //@mark(doc2, "DocumentHighlight"),highlight(doc2, doc1, doc2, doc3) +- for _, rng := range rngs { +- result = append(result, DocumentHighlight{ //@mark(doc3, "DocumentHighlight"),highlight(doc3, doc1, doc2, doc3) +- Range: rng, +- }) +- } +- return result //@mark(result, "result") +-} - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true { -- fmt.Println("true") -- } else { -- fmt.Println("false") +-func testForLoops() { +- for i := 0; i < 10; i++ { //@mark(forDecl1, "for"),highlight(forDecl1, forDecl1, brk1, cont1) +- if i > 8 { +- break //@mark(brk1, "break"),highlight(brk1, forDecl1, brk1, cont1) +- } +- if i < 2 { +- for j := 1; j < 10; j++ { //@mark(forDecl2, "for"),highlight(forDecl2, forDecl2, cont2) +- if j < 3 { +- for k := 1; k < 10; k++ { //@mark(forDecl3, "for"),highlight(forDecl3, forDecl3, cont3) +- if k < 3 { +- continue //@mark(cont3, "continue"),highlight(cont3, forDecl3, cont3) +- } +- } +- continue //@mark(cont2, "continue"),highlight(cont2, forDecl2, cont2) +- } +- } +- continue //@mark(cont1, "continue"),highlight(cont1, forDecl1, brk1, cont1) - } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") - } -- /* This is a multiline -- block -- comment */ - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string +- arr := []int{} +- for i := range arr { //@mark(forDecl4, "for"),highlight(forDecl4, forDecl4, brk4, cont4) +- if i > 8 { +- break //@mark(brk4, "break"),highlight(brk4, forDecl4, brk4, cont4) +- } +- if i < 4 { +- continue //@mark(cont4, "continue"),highlight(cont4, forDecl4, brk4, cont4) +- } - } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", +- +-Outer: +- for i := 0; i < 10; i++ { //@mark(forDecl5, "for"),highlight(forDecl5, forDecl5, brk5, brk6, brk8) +- break //@mark(brk5, "break"),highlight(brk5, forDecl5, brk5, brk6, brk8) +- for { //@mark(forDecl6, "for"),highlight(forDecl6, forDecl6, cont5) +- if i == 1 { +- break Outer //@mark(brk6, "break Outer"),highlight(brk6, forDecl5, brk5, brk6, brk8) +- } +- switch i { //@mark(switch1, "switch"),highlight(switch1, switch1, brk7) +- case 5: +- break //@mark(brk7, "break"),highlight(brk7, switch1, brk7) +- case 6: +- continue //@mark(cont5, "continue"),highlight(cont5, forDecl6, cont5) +- case 7: +- break Outer //@mark(brk8, "break Outer"),highlight(brk8, forDecl5, brk5, brk6, brk8) +- } +- } - } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val { -- fmt.Println("true from x") -- } else { -- fmt.Println("false from x") +-} +- +-func testSwitch() { +- var i, j int +- +-L1: +- for { //@mark(forDecl7, "for"),highlight(forDecl7, forDecl7, brk10, cont6) +- L2: +- switch i { //@mark(switch2, "switch"),highlight(switch2, switch2, brk11, brk12, brk13) +- case 1: +- switch j { //@mark(switch3, "switch"),highlight(switch3, switch3, brk9) +- case 1: +- break //@mark(brk9, "break"),highlight(brk9, switch3, brk9) +- case 2: +- break L1 //@mark(brk10, "break L1"),highlight(brk10, forDecl7, brk10, cont6) +- case 3: +- break L2 //@mark(brk11, "break L2"),highlight(brk11, switch2, brk11, brk12, brk13) +- default: +- continue //@mark(cont6, "continue"),highlight(cont6, forDecl7, brk10, cont6) +- } +- case 2: +- break //@mark(brk12, "break"),highlight(brk12, switch2, brk11, brk12, brk13) +- default: +- break L2 //@mark(brk13, "break L2"),highlight(brk13, switch2, brk11, brk12, brk13) - } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") - } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` -} -diff -urN a/gopls/internal/lsp/testdata/folding/a.go.golden b/gopls/internal/lsp/testdata/folding/a.go.golden ---- a/gopls/internal/lsp/testdata/folding/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/folding/a.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,722 +0,0 @@ ---- foldingRange-0 -- --package folding //@fold("package") - --import (<>) +-func testReturn() bool { //@mark(func1, "func"),mark(bool1, "bool"),highlight(func1, func1, fullRet11, fullRet12),highlight(bool1, bool1, false1, bool2, true1) +- if 1 < 2 { +- return false //@mark(ret11, "return"),mark(fullRet11, "return false"),mark(false1, "false"),highlight(ret11, func1, fullRet11, fullRet12) +- } +- candidates := []int{} +- sort.SliceStable(candidates, func(i, j int) bool { //@mark(func2, "func"),mark(bool2, "bool"),highlight(func2, func2, fullRet2) +- return candidates[i] > candidates[j] //@mark(ret2, "return"),mark(fullRet2, "return candidates[i] > candidates[j]"),highlight(ret2, func2, fullRet2) +- }) +- return true //@mark(ret12, "return"),mark(fullRet12, "return true"),mark(true1, "true"),highlight(ret12, func1, fullRet11, fullRet12) +-} - --import _ "os" +-func testReturnFields() float64 { //@mark(retVal1, "float64"),highlight(retVal1, retVal1, retVal11, retVal21) +- if 1 < 2 { +- return 20.1 //@mark(retVal11, "20.1"),highlight(retVal11, retVal1, retVal11, retVal21) +- } +- z := 4.3 //@mark(zDecl, "z") +- return z //@mark(retVal21, "z"),highlight(retVal21, retVal1, retVal11, zDecl, retVal21) +-} - --// bar is a function.<> --func bar(<>) string {<>} +-func testReturnMultipleFields() (float32, string) { //@mark(retVal31, "float32"),mark(retVal32, "string"),highlight(retVal31, retVal31, retVal41, retVal51),highlight(retVal32, retVal32, retVal42, retVal52) +- y := "im a var" //@mark(yDecl, "y"), +- if 1 < 2 { +- return 20.1, y //@mark(retVal41, "20.1"),mark(retVal42, "y"),highlight(retVal41, retVal31, retVal41, retVal51),highlight(retVal42, retVal32, yDecl, retVal42, retVal52) +- } +- return 4.9, "test" //@mark(retVal51, "4.9"),mark(retVal52, "\"test\""),highlight(retVal51, retVal31, retVal41, retVal51),highlight(retVal52, retVal32, retVal42, retVal52) +-} - ---- foldingRange-1 -- --package folding //@fold("package") +-func testReturnFunc() int32 { //@mark(retCall, "int32") +- mulch := 1 //@mark(mulchDec, "mulch"),highlight(mulchDec, mulchDec, mulchRet) +- return int32(mulch) //@mark(mulchRet, "mulch"),mark(retFunc, "int32"),mark(retTotal, "int32(mulch)"),highlight(mulchRet, mulchDec, mulchRet),highlight(retFunc, retCall, retFunc, retTotal) +-} +diff -urN a/gopls/internal/lsp/testdata/highlights/issue60435.go b/gopls/internal/lsp/testdata/highlights/issue60435.go +--- a/gopls/internal/lsp/testdata/highlights/issue60435.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/highlights/issue60435.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package highlights - -import ( -- "fmt" -- _ "log" +- "net/http" //@mark(httpImp, `"net/http"`) +- "net/http/httptest" //@mark(httptestImp, `"net/http/httptest"`) -) - --import _ "os" -- --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch {<>} -- /* This is a multiline<> -- -- /* This is a multiline<> -- _ = []int{<>} -- _ = [2]string{<>} -- _ = map[string]int{<>} -- type T struct {<>} -- _ = T{<>} -- x, y := make(<>), make(<>) -- select {<>} -- // This is a multiline comment<> -- return <> --} +-// This is a regression test for issue 60435: +-// Highlighting "net/http" shouldn't have any effect +-// on an import path that contains it as a substring, +-// such as httptest. - ---- foldingRange-2 -- --package folding //@fold("package") +-var _ = httptest.NewRequest +-var _ = http.NewRequest //@mark(here, "http"), highlight(here, here, httpImp) +diff -urN a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in +--- a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-package importedcomplit - -import ( -- "fmt" -- _ "log" --) -- --import _ "os" +- "golang.org/lsptests/foo" - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true:<> -- case false:<> -- default:<> -- } -- /* This is a multiline -- block -- comment */ +- // import completions +- "fm" //@complete("\" //", fmtImport) +- "go/pars" //@complete("\" //", parserImport) +- "golang.org/lsptests/signa" //@complete("na\" //", signatureImport) +- "golang.org/lspte" //@complete("\" //", lsptestsImport) +- "crypto/elli" //@complete("\" //", cryptoImport) +- "golang.org/lsptests/sign" //@complete("\" //", signatureImport) +- "golang.org/lsptests/sign" //@complete("ests", lsptestsImport) +- namedParser "go/pars" //@complete("\" //", parserImport) +-) - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", -- } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x:<> -- case <-y:<> -- default:<> -- } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` +-func _() { +- var V int //@item(icVVar, "V", "int", "var") +- _ = foo.StructFoo{V} //@complete("}", Value, icVVar) -} - ---- foldingRange-3 -- --package folding //@fold("package") -- --import ( -- "fmt" -- _ "log" --) +-func _() { +- var ( +- aa string //@item(icAAVar, "aa", "string", "var") +- ab int //@item(icABVar, "ab", "int", "var") +- ) - --import _ "os" +- _ = foo.StructFoo{a} //@complete("}", abVar, aaVar) - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true {<>} else {<>} -- case false: -- fmt.Println(<>) -- default: -- fmt.Println(<>) +- var s struct { +- AA string //@item(icFieldAA, "AA", "string", "field") +- AB int //@item(icFieldAB, "AB", "int", "field") - } -- /* This is a multiline -- block -- comment */ - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", -- } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val {<>} else {<>} -- case <-y: -- fmt.Println(<>) -- default: -- fmt.Println(<>) -- } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` +- _ = foo.StructFoo{s.} //@complete("}", icFieldAB, icFieldAA) -} - ---- foldingRange-4 -- --package folding //@fold("package") -- --import ( -- "fmt" -- _ "log" --) -- --import _ "os" +-/* "fmt" */ //@item(fmtImport, "fmt", "\"fmt\"", "package") +-/* "go/parser" */ //@item(parserImport, "parser", "\"go/parser\"", "package") +-/* "golang.org/lsptests/signature" */ //@item(signatureImport, "signature", "\"golang.org/lsptests/signature\"", "package") +-/* "golang.org/lsptests/" */ //@item(lsptestsImport, "lsptests/", "\"golang.org/lsptests/\"", "package") +-/* "crypto/elliptic" */ //@item(cryptoImport, "elliptic", "\"crypto/elliptic\"", "package") +diff -urN a/gopls/internal/lsp/testdata/index/index.go b/gopls/internal/lsp/testdata/index/index.go +--- a/gopls/internal/lsp/testdata/index/index.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/index/index.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +-package index - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true { -- fmt.Println(<>) -- } else { -- fmt.Println(<>) -- } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") -- } -- /* This is a multiline -- block -- comment */ +-func _() { +- var ( +- aa = "123" //@item(indexAA, "aa", "string", "var") +- ab = 123 //@item(indexAB, "ab", "int", "var") +- ) - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", -- } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val { -- fmt.Println(<>) -- } else { -- fmt.Println(<>) -- } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") -- } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` --} +- var foo [1]int +- foo[a] //@complete("]", indexAB, indexAA) +- foo[:a] //@complete("]", indexAB, indexAA) +- a[:a] //@complete("[", indexAA, indexAB) +- a[a] //@complete("[", indexAA, indexAB) - ---- foldingRange-comment-0 -- --package folding //@fold("package") +- var bar map[string]int +- bar[a] //@complete("]", indexAA, indexAB) - --import ( -- "fmt" -- _ "log" --) +- type myMap map[string]int +- var baz myMap +- baz[a] //@complete("]", indexAA, indexAB) - --import _ "os" +- type myInt int +- var mi myInt //@item(indexMyInt, "mi", "myInt", "var") +- foo[m] //@snippet("]", indexMyInt, "mi", "mi") +-} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go +--- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package inlayHint //@inlayHint("package") - --// bar is a function.<> --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true { -- fmt.Println("true") -- } else { -- fmt.Println("false") -- } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") -- } -- /* This is a multiline<> +-import "fmt" - -- /* This is a multiline<> -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, +-func fieldNames() { +- for _, c := range []struct { +- in, want string +- }{ +- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- {"Hello, 世界", "界世 ,olleH"}, +- {"", ""}, +- } { +- fmt.Println(c.in == c.want) - } -- type T struct { -- f string -- g int -- h string +-} +- +-func fieldNamesPointers() { +- for _, c := range []*struct { +- in, want string +- }{ +- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- {"Hello, 世界", "界世 ,olleH"}, +- {"", ""}, +- } { +- fmt.Println(c.in == c.want) - } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", +-} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") +- +-import "fmt" +- +-func fieldNames() { +- for _< int>, c< struct{in string; want string}> := range []struct { +- in, want string +- }{ +- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- {"Hello, 世界", "界世 ,olleH"}, +- {"", ""}, +- } { +- fmt.Println(c.in == c.want) - } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val { -- fmt.Println("true from x") -- } else { -- fmt.Println("false from x") -- } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") +-} +- +-func fieldNamesPointers() { +- for _< int>, c< *struct{in string; want string}> := range []*struct { +- in, want string +- }{ +- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, +- <&struct{in string; want string}>{"Hello, 世界", "界世 ,olleH"}, +- <&struct{in string; want string}>{"", ""}, +- } { +- fmt.Println(c.in == c.want) - } -- // This is a multiline comment<> -- return ` --this string --is not indented` -} - ---- foldingRange-imports-0 -- --package folding //@fold("package") +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go +--- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,45 +0,0 @@ +-package inlayHint //@inlayHint("package") - --import (<>) +-const True = true - --import _ "os" +-type Kind int - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true { -- fmt.Println("true") -- } else { -- fmt.Println("false") -- } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") -- } -- /* This is a multiline -- block -- comment */ +-const ( +- KindNone Kind = iota +- KindPrint +- KindPrintf +- KindErrorf +-) - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", -- } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val { -- fmt.Println("true from x") -- } else { -- fmt.Println("false from x") -- } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") -- } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` --} +-const ( +- u = iota * 4 +- v float64 = iota * 42 +- w = iota * 42 +-) - ---- foldingRange-lineFolding-0 -- --package folding //@fold("package") +-const ( +- a, b = 1, 2 +- c, d +- e, f = 5 * 5, "hello" + "world" +- g, h +- i, j = true, f +-) - --import (<> +-// No hint +-const ( +- Int = 3 +- Float = 3.14 +- Bool = true +- Rune = '3' +- Complex = 2.7i +- String = "Hello, world!" -) - --import _ "os" +-var ( +- varInt = 3 +- varFloat = 3.14 +- varBool = true +- varRune = '3' + '4' +- varComplex = 2.7i +- varString = "Hello, world!" +-) +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") - --// bar is a function.<> --func bar() string {<> --} +-const True = true - ---- foldingRange-lineFolding-1 -- --package folding //@fold("package") +-type Kind int - --import ( -- "fmt" -- _ "log" +-const ( +- KindNone Kind = iota< = 0> +- KindPrint< = 1> +- KindPrintf< = 2> +- KindErrorf< = 3> -) - --import _ "os" +-const ( +- u = iota * 4< = 0> +- v float64 = iota * 42< = 42> +- w = iota * 42< = 84> +-) - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch {<> -- } -- /* This is a multiline<> +-const ( +- a, b = 1, 2 +- c, d< = 1, 2> +- e, f = 5 * 5, "hello" + "world"< = 25, "helloworld"> +- g, h< = 25, "helloworld"> +- i, j = true, f< = true, "helloworld"> +-) - -- /* This is a multiline<> -- _ = []int{<>, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{<>, -- } -- type T struct {<> -- } -- _ = T{<>, -- } -- x, y := make(chan bool), make(chan bool) -- select {<> +-// No hint +-const ( +- Int = 3 +- Float = 3.14 +- Bool = true +- Rune = '3' +- Complex = 2.7i +- String = "Hello, world!" +-) +- +-var ( +- varInt = 3 +- varFloat = 3.14 +- varBool = true +- varRune = '3' + '4' +- varComplex = 2.7i +- varString = "Hello, world!" +-) +- +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go +--- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,50 +0,0 @@ +-package inlayHint //@inlayHint("package") +- +-import "fmt" +- +-func hello(name string) string { +- return "Hello " + name +-} +- +-func helloWorld() string { +- return hello("World") +-} +- +-type foo struct{} +- +-func (*foo) bar(baz string, qux int) int { +- if baz != "" { +- return qux + 1 - } -- // This is a multiline comment<> -- return <> +- return qux -} - ---- foldingRange-lineFolding-2 -- --package folding //@fold("package") +-func kase(foo int, bar bool, baz ...string) { +- fmt.Println(foo, bar, baz) +-} - --import ( -- "fmt" -- _ "log" --) +-func kipp(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) +-} - --import _ "os" +-func plex(foo, bar string, baz string) { +- fmt.Println(foo, bar, baz) +-} - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true:<> -- case false:<> -- default:<> -- } -- /* This is a multiline -- block -- comment */ +-func tars(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) +-} +- +-func foobar() { +- var x foo +- x.bar("", 1) +- kase(0, true, "c", "d", "e") +- kipp("a", "b", "c") +- plex("a", "b", "c") +- tars("a", "b", "c") +- foo, bar, baz := "a", "b", "c" +- kipp(foo, bar, baz) +- plex("a", bar, baz) +- tars(foo+foo, (bar), "c") - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", -- } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x:<> -- case <-y:<> -- default:<> -- } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` -} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,52 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") - ---- foldingRange-lineFolding-3 -- --package folding //@fold("package") +-import "fmt" - --import ( -- "fmt" -- _ "log" --) +-func hello(name string) string { +- return "Hello " + name +-} - --import _ "os" +-func helloWorld() string { +- return hello("World") +-} - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true {<> -- } else {<> -- } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") -- } -- /* This is a multiline -- block -- comment */ +-type foo struct{} - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", -- } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val {<> -- } else {<> -- } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") +-func (*foo) bar(baz string, qux int) int { +- if baz != "" { +- return qux + 1 - } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` +- return qux +-} +- +-func kase(foo int, bar bool, baz ...string) { +- fmt.Println(foo, bar, baz) +-} +- +-func kipp(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) -} - ---- foldingRange-lineFolding-comment-0 -- --package folding //@fold("package") +-func plex(foo, bar string, baz string) { +- fmt.Println(foo, bar, baz) +-} - --import ( -- "fmt" -- _ "log" --) +-func tars(foo string, bar, baz string) { +- fmt.Println(foo, bar, baz) +-} - --import _ "os" +-func foobar() { +- var x foo +- x.bar("", 1) +- kase(0, true, "c", "d", "e") +- kipp("a", "b", "c") +- plex("a", "b", "c") +- tars("a", "b", "c") +- foo< string>, bar< string>, baz< string> := "a", "b", "c" +- kipp(foo, bar, baz) +- plex("a", bar, baz) +- tars(foo+foo, (bar), "c") - --// bar is a function.<> --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true { -- fmt.Println("true") -- } else { -- fmt.Println("false") -- } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") -- } -- /* This is a multiline<> +-} - -- /* This is a multiline<> -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go b/gopls/internal/lsp/testdata/inlay_hint/type_params.go +--- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,45 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 +- +-package inlayHint //@inlayHint("package") +- +-func main() { +- ints := map[string]int64{ +- "first": 34, +- "second": 12, - } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val { -- fmt.Println("true from x") -- } else { -- fmt.Println("false from x") -- } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") +- +- floats := map[string]float64{ +- "first": 35.98, +- "second": 26.99, - } -- // This is a multiline comment<> -- return ` --this string --is not indented` --} - ---- foldingRange-lineFolding-imports-0 -- --package folding //@fold("package") +- SumIntsOrFloats[string, int64](ints) +- SumIntsOrFloats[string, float64](floats) - --import (<> --) +- SumIntsOrFloats(ints) +- SumIntsOrFloats(floats) - --import _ "os" +- SumNumbers(ints) +- SumNumbers(floats) +-} - --// bar is a function. --// With a multiline doc comment. --func bar() string { -- /* This is a single line comment */ -- switch { -- case true: -- if true { -- fmt.Println("true") -- } else { -- fmt.Println("false") -- } -- case false: -- fmt.Println("false") -- default: -- fmt.Println("default") -- } -- /* This is a multiline -- block -- comment */ +-type Number interface { +- int64 | float64 +-} - -- /* This is a multiline -- block -- comment */ -- // Followed by another comment. -- _ = []int{ -- 1, -- 2, -- 3, -- } -- _ = [2]string{"d", -- "e", -- } -- _ = map[string]int{ -- "a": 1, -- "b": 2, -- "c": 3, -- } -- type T struct { -- f string -- g int -- h string -- } -- _ = T{ -- f: "j", -- g: 4, -- h: "i", +-func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { +- var s V +- for _, v := range m { +- s += v - } -- x, y := make(chan bool), make(chan bool) -- select { -- case val := <-x: -- if val { -- fmt.Println("true from x") -- } else { -- fmt.Println("false from x") -- } -- case <-y: -- fmt.Println("y") -- default: -- fmt.Println("default") +- return s +-} +- +-func SumNumbers[K comparable, V Number](m map[K]V) V { +- var s V +- for _, v := range m { +- s += v - } -- // This is a multiline comment -- // that is not a doc comment. -- return ` --this string --is not indented` +- return s -} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +--- inlayHint -- +-//go:build go1.18 +-// +build go1.18 - -diff -urN a/gopls/internal/lsp/testdata/folding/bad.go.golden b/gopls/internal/lsp/testdata/folding/bad.go.golden ---- a/gopls/internal/lsp/testdata/folding/bad.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/folding/bad.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,81 +0,0 @@ ---- foldingRange-0 -- --package folding //@fold("package") +-package inlayHint //@inlayHint("package") - --import (<>) +-func main() { +- ints< map[string]int64> := map[string]int64{ +- "first": 34, +- "second": 12, +- } - --import (<>) -- --// badBar is a function. --func badBar(<>) string {<>} +- floats< map[string]float64> := map[string]float64{ +- "first": 35.98, +- "second": 26.99, +- } - ---- foldingRange-1 -- --package folding //@fold("package") +- SumIntsOrFloats[string, int64](ints) +- SumIntsOrFloats[string, float64](floats) - --import ( "fmt" -- _ "log" --) +- SumIntsOrFloats<[string, int64]>(ints) +- SumIntsOrFloats<[string, float64]>(floats) - --import ( -- _ "os" ) -- --// badBar is a function. --func badBar() string { x := true -- if x {<>} else {<>} -- return +- SumNumbers<[string, int64]>(ints) +- SumNumbers<[string, float64]>(floats) -} - ---- foldingRange-2 -- --package folding //@fold("package") -- --import ( "fmt" -- _ "log" --) +-type Number interface { +- int64 | float64 +-} - --import ( -- _ "os" ) -- --// badBar is a function. --func badBar() string { x := true -- if x { -- // This is the only foldable thing in this file when lineFoldingOnly -- fmt.Println(<>) -- } else { -- fmt.Println(<>) } -- return +-func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { +- var s V +- for _< K>, v< V> := range m { +- s += v +- } +- return s -} - ---- foldingRange-imports-0 -- --package folding //@fold("package") +-func SumNumbers[K comparable, V Number](m map[K]V) V { +- var s V +- for _< K>, v< V> := range m { +- s += v +- } +- return s +-} - --import (<>) +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go +--- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package inlayHint //@inlayHint("package") - --import (<>) -- --// badBar is a function. --func badBar() string { x := true -- if x { -- // This is the only foldable thing in this file when lineFoldingOnly -- fmt.Println("true") -- } else { -- fmt.Println("false") } -- return +-func assignTypes() { +- i, j := 0, len([]string{})-1 +- println(i, j) -} - ---- foldingRange-lineFolding-0 -- --package folding //@fold("package") +-func rangeTypes() { +- for k, v := range []string{} { +- println(k, v) +- } +-} - --import ( "fmt" -- _ "log" --) +-func funcLitType() { +- myFunc := func(a string) string { return "" } +-} - --import ( -- _ "os" ) -- --// badBar is a function. --func badBar() string { x := true -- if x {<> -- } else { -- fmt.Println("false") } -- return +-func compositeLitType() { +- foo := map[string]interface{}{"": ""} -} +diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden +--- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +--- inlayHint -- +-package inlayHint //@inlayHint("package") - -diff -urN a/gopls/internal/lsp/testdata/folding/bad.go.in b/gopls/internal/lsp/testdata/folding/bad.go.in ---- a/gopls/internal/lsp/testdata/folding/bad.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/folding/bad.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ --package folding //@fold("package") +-func assignTypes() { +- i< int>, j< int> := 0, len([]string{})-1 +- println(i, j) +-} - --import ( "fmt" -- _ "log" --) +-func rangeTypes() { +- for k< int>, v< string> := range []string{} { +- println(k, v) +- } +-} - --import ( -- _ "os" ) -- --// badBar is a function. --func badBar() string { x := true -- if x { -- // This is the only foldable thing in this file when lineFoldingOnly -- fmt.Println("true") -- } else { -- fmt.Println("false") } -- return +-func funcLitType() { +- myFunc< func(a string) string> := func(a string) string { return "" } -} -diff -urN a/gopls/internal/lsp/testdata/foo/foo.go b/gopls/internal/lsp/testdata/foo/foo.go ---- a/gopls/internal/lsp/testdata/foo/foo.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/foo/foo.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,30 +0,0 @@ --package foo //@mark(PackageFoo, "foo"),item(PackageFoo, "foo", "\"golang.org/lsptests/foo\"", "package") - --type StructFoo struct { //@item(StructFoo, "StructFoo", "struct{...}", "struct") -- Value int //@item(Value, "Value", "int", "field") +-func compositeLitType() { +- foo< map[string]interface{}> := map[string]interface{}{"": ""} -} - --// Pre-set this marker, as we don't have a "source" for it in this package. --/* Error() */ //@item(Error, "Error", "func() string", "method") +diff -urN a/gopls/internal/lsp/testdata/interfacerank/interface_rank.go b/gopls/internal/lsp/testdata/interfacerank/interface_rank.go +--- a/gopls/internal/lsp/testdata/interfacerank/interface_rank.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/interfacerank/interface_rank.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,23 +0,0 @@ +-package interfacerank - --func Foo() { //@item(Foo, "Foo", "func()", "func") -- var err error -- err.Error() //@complete("E", Error) +-type foo interface { +- foo() -} - --func _() { -- var sFoo StructFoo //@mark(sFoo1, "sFoo"),complete("t", StructFoo) -- if x := sFoo; x.Value == 1 { //@mark(sFoo2, "sFoo"),complete("V", Value),typdef("sFoo", StructFoo),refs("sFo", sFoo1, sFoo2) -- return -- } --} +-type fooImpl int +- +-func (*fooImpl) foo() {} +- +-func wantsFoo(foo) {} - -func _() { -- shadowed := 123 -- { -- shadowed := "hi" //@item(shadowed, "shadowed", "string", "var"),refs("shadowed", shadowed) -- sha //@complete("a", shadowed) -- } --} +- var ( +- aa string //@item(irAA, "aa", "string", "var") +- ab *fooImpl //@item(irAB, "ab", "*fooImpl", "var") +- ) - --type IntFoo int //@item(IntFoo, "IntFoo", "int", "type") -diff -urN a/gopls/internal/lsp/testdata/format/bad_format.go.golden b/gopls/internal/lsp/testdata/format/bad_format.go.golden ---- a/gopls/internal/lsp/testdata/format/bad_format.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/bad_format.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ ---- gofmt -- --package format //@format("package") +- wantsFoo(a) //@complete(")", irAB, irAA) +- +- var ac fooImpl //@item(irAC, "ac", "fooImpl", "var") +- wantsFoo(&a) //@complete(")", irAC, irAA, irAB) +-} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - -import ( - "fmt" -- "log" -- "runtime" +- "os" -) - --func hello() { -- -- var x int //@diag("x", "compiler", "x declared (and|but) not used", "error") +-func BooleanFn() { +- if os.IsPathSeparator('X') { //@suggestedfix("if os.IsPathSeparator('X')", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean_fn.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_boolean_fn_9_2 -- +-package invertifcondition - --func hi() { -- runtime.GOROOT() -- fmt.Printf("") +-import ( +- "fmt" +- "os" +-) - -- log.Printf("") +-func BooleanFn() { +- if !os.IsPathSeparator('X') { +- fmt.Println("B") +- } else { //@suggestedfix("if os.IsPathSeparator('X')", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - -diff -urN a/gopls/internal/lsp/testdata/format/bad_format.go.in b/gopls/internal/lsp/testdata/format/bad_format.go.in ---- a/gopls/internal/lsp/testdata/format/bad_format.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/bad_format.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ --package format //@format("package") +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean.go b/gopls/internal/lsp/testdata/invertifcondition/boolean.go +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - -import ( -- "runtime" - "fmt" -- "log" -) - --func hello() { -- -- -- -- -- var x int //@diag("x", "compiler", "x declared (and|but) not used", "error") +-func Boolean() { +- b := true +- if b { //@suggestedfix("if b", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden b/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/boolean.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_boolean_9_2 -- +-package invertifcondition - --func hi() { -- runtime.GOROOT() -- fmt.Printf("") +-import ( +- "fmt" +-) - -- log.Printf("") +-func Boolean() { +- b := true +- if !b { +- fmt.Println("B") +- } else { //@suggestedfix("if b", "refactor.rewrite", "") +- fmt.Println("A") +- } -} -diff -urN a/gopls/internal/lsp/testdata/format/good_format.go b/gopls/internal/lsp/testdata/format/good_format.go ---- a/gopls/internal/lsp/testdata/format/good_format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/good_format.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package format //@format("package") +- +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go +--- a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-package invertifcondition - -import ( -- "log" +- "fmt" -) - --func goodbye() { -- log.Printf("byeeeee") +-func DontRemoveParens() { +- a := false +- b := true +- if !(a || +- b) { //@suggestedfix("b", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} -diff -urN a/gopls/internal/lsp/testdata/format/good_format.go.golden b/gopls/internal/lsp/testdata/format/good_format.go.golden ---- a/gopls/internal/lsp/testdata/format/good_format.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/good_format.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ ---- gofmt -- --package format //@format("package") +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/dont_remove_parens.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_dont_remove_parens_11_3 -- +-package invertifcondition - -import ( -- "log" +- "fmt" -) - --func goodbye() { -- log.Printf("byeeeee") +-func DontRemoveParens() { +- a := false +- b := true +- if (a || +- b) { +- fmt.Println("B") +- } else { //@suggestedfix("b", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - -diff -urN a/gopls/internal/lsp/testdata/format/newline_format.go.golden b/gopls/internal/lsp/testdata/format/newline_format.go.golden ---- a/gopls/internal/lsp/testdata/format/newline_format.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/newline_format.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,4 +0,0 @@ ---- gofmt -- --package format //@format("package") --func _() {} -- -diff -urN a/gopls/internal/lsp/testdata/format/newline_format.go.in b/gopls/internal/lsp/testdata/format/newline_format.go.in ---- a/gopls/internal/lsp/testdata/format/newline_format.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/newline_format.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,2 +0,0 @@ --package format //@format("package") --func _() {} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/format/one_line.go.golden b/gopls/internal/lsp/testdata/format/one_line.go.golden ---- a/gopls/internal/lsp/testdata/format/one_line.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/one_line.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ ---- gofmt -- --package format //@format("package") -- -diff -urN a/gopls/internal/lsp/testdata/format/one_line.go.in b/gopls/internal/lsp/testdata/format/one_line.go.in ---- a/gopls/internal/lsp/testdata/format/one_line.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/format/one_line.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1 +0,0 @@ --package format //@format("package") -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/func_rank/func_rank.go.in b/gopls/internal/lsp/testdata/func_rank/func_rank.go.in ---- a/gopls/internal/lsp/testdata/func_rank/func_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/func_rank/func_rank.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,70 +0,0 @@ --package func_rank -- --import "net/http" -- --var stringAVar = "var" //@item(stringAVar, "stringAVar", "string", "var") --func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc", "func() string", "func") --type stringer struct{} //@item(stringer, "stringer", "struct{...}", "struct") -- --func _() stringer //@complete("tr", stringer) +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/else_if.go b/gopls/internal/lsp/testdata/invertifcondition/else_if.go +--- a/gopls/internal/lsp/testdata/invertifcondition/else_if.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/else_if.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-package invertifcondition - --func _(val stringer) {} //@complete("tr", stringer) +-import ( +- "fmt" +- "os" +-) - --func (stringer) _() {} //@complete("tr", stringer) +-func ElseIf() { +- // No inversion expected when there's not else clause +- if len(os.Args) > 2 { +- fmt.Println("A") +- } - --func _() { -- var s struct { -- AA int //@item(rankAA, "AA", "int", "field") -- AB string //@item(rankAB, "AB", "string", "field") -- AC int //@item(rankAC, "AC", "int", "field") +- // No inversion expected for else-if, that would become unreadable +- if len(os.Args) > 2 { +- fmt.Println("A") +- } else if os.Args[0] == "X" { //@suggestedfix(re"if os.Args.0. == .X.", "refactor.rewrite", "") +- fmt.Println("B") +- } else { +- fmt.Println("C") - } -- fnStr := func(string) {} -- fnStr(s.A) //@complete(")", rankAB, rankAA, rankAC) -- fnStr("" + s.A) //@complete(")", rankAB, rankAA, rankAC) +-} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden b/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/else_if.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +--- suggestedfix_else_if_17_9 -- +-package invertifcondition - -- fnInt := func(int) {} -- fnInt(-s.A) //@complete(")", rankAA, rankAC, rankAB) +-import ( +- "fmt" +- "os" +-) - -- // no expected type -- fnInt(func() int { s.A }) //@complete(" }", rankAA, rankAB, rankAC) -- fnInt(s.A()) //@complete("()", rankAA, rankAC, rankAB) -- fnInt([]int{}[s.A]) //@complete("])", rankAA, rankAC, rankAB) -- fnInt([]int{}[:s.A]) //@complete("])", rankAA, rankAC, rankAB) +-func ElseIf() { +- // No inversion expected when there's not else clause +- if len(os.Args) > 2 { +- fmt.Println("A") +- } - -- fnInt(s.A.(int)) //@complete(".(", rankAA, rankAC, rankAB) +- // No inversion expected for else-if, that would become unreadable +- if len(os.Args) > 2 { +- fmt.Println("A") +- } else if os.Args[0] != "X" { +- fmt.Println("C") +- } else { //@suggestedfix(re"if os.Args.0. == .X.", "refactor.rewrite", "") +- fmt.Println("B") +- } +-} - -- fnPtr := func(*string) {} -- fnPtr(&s.A) //@complete(")", rankAB, rankAA, rankAC) +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go +--- a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - -- var aaPtr *string //@item(rankAAPtr, "aaPtr", "*string", "var") -- var abPtr *int //@item(rankABPtr, "abPtr", "*int", "var") -- fnInt(*a) //@complete(")", rankABPtr, rankAAPtr) +-import ( +- "fmt" +- "os" +-) - -- _ = func() string { -- return s.A //@complete(" //", rankAB, rankAA, rankAC) +-func GreaterThan() { +- if len(os.Args) > 2 { //@suggestedfix("i", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") - } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/greater_than.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_greater_than_9_2 -- +-package invertifcondition - --type foo struct { -- fooPrivateField int //@item(rankFooPrivField, "fooPrivateField", "int", "field") -- FooPublicField int //@item(rankFooPubField, "FooPublicField", "int", "field") --} +-import ( +- "fmt" +- "os" +-) - --func (foo) fooPrivateMethod() int { //@item(rankFooPrivMeth, "fooPrivateMethod", "func() int", "method") -- return 0 +-func GreaterThan() { +- if len(os.Args) <= 2 { +- fmt.Println("B") +- } else { //@suggestedfix("i", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --func (foo) FooPublicMethod() int { //@item(rankFooPubMeth, "FooPublicMethod", "func() int", "method") -- return 0 --} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go +--- a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - --func _() { -- var _ int = foo{}. //@rank(" //", rankFooPrivField, rankFooPubField),rank(" //", rankFooPrivMeth, rankFooPubMeth),rank(" //", rankFooPrivField, rankFooPrivMeth) +-import ( +- "fmt" +-) +- +-func NotBoolean() { +- b := true +- if !b { //@suggestedfix("if !b", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/not_boolean.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_not_boolean_9_2 -- +-package invertifcondition - --func _() { -- HandleFunc //@item(httpHandleFunc, "HandleFunc", "func(pattern string, handler func(http.ResponseWriter, *http.Request))", "func") -- HandlerFunc //@item(httpHandlerFunc, "HandlerFunc", "func(http.ResponseWriter, *http.Request)", "type") +-import ( +- "fmt" +-) - -- http.HandleFunc //@rank(" //", httpHandleFunc, httpHandlerFunc) +-func NotBoolean() { +- b := true +- if b { +- fmt.Println("B") +- } else { //@suggestedfix("if !b", "refactor.rewrite", "") +- fmt.Println("A") +- } -} -diff -urN a/gopls/internal/lsp/testdata/funcsig/func_sig.go b/gopls/internal/lsp/testdata/funcsig/func_sig.go ---- a/gopls/internal/lsp/testdata/funcsig/func_sig.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/funcsig/func_sig.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package funcsig - --type someType int //@item(sigSomeType, "someType", "int", "type") +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-package invertifcondition - --// Don't complete "foo" in signature. --func (foo someType) _() { //@item(sigFoo, "foo", "someType", "var"),complete(") {", sigSomeType) +-import ( +- "fmt" +-) - -- //@complete("", sigFoo, sigSomeType) --} -diff -urN a/gopls/internal/lsp/testdata/funcvalue/func_value.go b/gopls/internal/lsp/testdata/funcvalue/func_value.go ---- a/gopls/internal/lsp/testdata/funcvalue/func_value.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/funcvalue/func_value.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package funcvalue +-func RemoveElse() { +- if true { //@suggestedfix("if true", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- return +- } - --func fooFunc() int { //@item(fvFooFunc, "fooFunc", "func() int", "func") -- return 0 +- fmt.Println("C") -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_else.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +--- suggestedfix_remove_else_8_2 -- +-package invertifcondition - --var _ = fooFunc() //@item(fvFooFuncCall, "fooFunc", "func() int", "func") -- --var fooVar = func() int { //@item(fvFooVar, "fooVar", "func() int", "var") -- return 0 --} +-import ( +- "fmt" +-) - --var _ = fooVar() //@item(fvFooVarCall, "fooVar", "func() int", "var") +-func RemoveElse() { +- if false { +- fmt.Println("B") +- return +- } - --type myFunc func() int +- //@suggestedfix("if true", "refactor.rewrite", "") +- fmt.Println("A") - --var fooType myFunc = fooVar //@item(fvFooType, "fooType", "myFunc", "var") +- fmt.Println("C") +-} - --var _ = fooType() //@item(fvFooTypeCall, "fooType", "func() int", "var") +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-package invertifcondition - --func _() { -- var f func() int -- f = foo //@complete(" //", fvFooFunc, fvFooType, fvFooVar) +-import ( +- "fmt" +-) - -- var i int -- i = foo //@complete(" //", fvFooFuncCall, fvFooTypeCall, fvFooVarCall) +-func RemoveParens() { +- b := true +- if !(b) { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} -diff -urN a/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go b/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go ---- a/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/fuzzymatch/fuzzymatch.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,48 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/remove_parens.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_remove_parens_9_2 -- +-package invertifcondition - --package fuzzy +-import ( +- "fmt" +-) - --func _() { -- var a struct { -- fabar int -- fooBar string +-func RemoveParens() { +- b := true +- if b { +- fmt.Println("B") +- } else { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") - } +-} - -- a.fabar //@item(fuzzFabarField, "a.fabar", "int", "field") -- a.fooBar //@item(fuzzFooBarField, "a.fooBar", "string", "field") +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package invertifcondition - -- afa //@fuzzy(" //", fuzzFabarField, fuzzFooBarField) -- afb //@fuzzy(" //", fuzzFooBarField, fuzzFabarField) +-import ( +- "fmt" +-) - -- fab //@fuzzy(" //", fuzzFabarField) +-func SemicolonAnd() { +- if n, err := fmt.Println("x"); err != nil && n > 0 { //@suggestedfix("f", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } +-} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_and.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_semicolon_and_8_3 -- +-package invertifcondition - -- var myString string -- myString = af //@fuzzy(" //", fuzzFooBarField, fuzzFabarField) +-import ( +- "fmt" +-) - -- var b struct { -- c struct { -- d struct { -- e struct { -- abc string -- } -- abc float32 -- } -- abc bool -- } -- abc int +-func SemicolonAnd() { +- if n, err := fmt.Println("x"); err == nil || n <= 0 { +- fmt.Println("B") +- } else { //@suggestedfix("f", "refactor.rewrite", "") +- fmt.Println("A") - } +-} - -- b.abc //@item(fuzzABCInt, "b.abc", "int", "field") -- b.c.abc //@item(fuzzABCbool, "b.c.abc", "bool", "field") -- b.c.d.abc //@item(fuzzABCfloat, "b.c.d.abc", "float32", "field") -- b.c.d.e.abc //@item(fuzzABCstring, "b.c.d.e.abc", "string", "field") +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package invertifcondition - -- // in depth order by default -- abc //@fuzzy(" //", fuzzABCInt, fuzzABCbool, fuzzABCfloat) +-import ( +- "fmt" +-) - -- // deep candidate that matches expected type should still ranked first -- var s string -- s = abc //@fuzzy(" //", fuzzABCstring, fuzzABCInt, fuzzABCbool) +-func Semicolon() { +- if _, err := fmt.Println("x"); err != nil { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} -diff -urN a/gopls/internal/lsp/testdata/generate/generate.go b/gopls/internal/lsp/testdata/generate/generate.go ---- a/gopls/internal/lsp/testdata/generate/generate.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/generate/generate.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,4 +0,0 @@ --package generate -- --//go:generate echo Hi //@ codelens("//go:generate", "run go generate", "generate"), codelens("//go:generate", "run go generate ./...", "generate") --//go:generate echo I shall have no CodeLens -diff -urN a/gopls/internal/lsp/testdata/generated/generated.go b/gopls/internal/lsp/testdata/generated/generated.go ---- a/gopls/internal/lsp/testdata/generated/generated.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/generated/generated.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package generated +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_semicolon_8_2 -- +-package invertifcondition - --// Code generated by generator.go. DO NOT EDIT. +-import ( +- "fmt" +-) - --func _() { -- var y int //@diag("y", "compiler", "y declared (and|but) not used", "error") +-func Semicolon() { +- if _, err := fmt.Println("x"); err == nil { +- fmt.Println("B") +- } else { //@suggestedfix("if", "refactor.rewrite", "") +- fmt.Println("A") +- } -} -diff -urN a/gopls/internal/lsp/testdata/generated/generator.go b/gopls/internal/lsp/testdata/generated/generator.go ---- a/gopls/internal/lsp/testdata/generated/generator.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/generated/generator.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package generated - --func _() { -- var x int //@diag("x", "compiler", "x declared (and|but) not used", "error") --} -diff -urN a/gopls/internal/lsp/testdata/godef/a/a_x_test.go b/gopls/internal/lsp/testdata/godef/a/a_x_test.go ---- a/gopls/internal/lsp/testdata/godef/a/a_x_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/a_x_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package a_test +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package invertifcondition - -import ( -- "testing" +- "fmt" -) - --func TestA2(t *testing.T) { //@TestA2,godef(TestA2, TestA2) -- Nonexistant() //@diag("Nonexistant", "compiler", "(undeclared name|undefined): Nonexistant", "error") --} -diff -urN a/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden b/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden ---- a/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,26 +0,0 @@ ---- TestA2-definition -- --godef/a/a_x_test.go:7:6-12: defined here as ```go --func TestA2(t *testing.T) --``` ---- TestA2-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/a_x_test.go", -- "start": { -- "line": 7, -- "column": 6, -- "offset": 44 -- }, -- "end": { -- "line": 7, -- "column": 12, -- "offset": 50 -- } -- }, -- "description": "```go\nfunc TestA2(t *testing.T)\n```" +-func SemicolonOr() { +- if n, err := fmt.Println("x"); err != nil || n < 5 { //@suggestedfix(re"if n, err := fmt.Println..x..; err != nil .. n < 5", "refactor.rewrite", "") +- fmt.Println("A") +- } else { +- fmt.Println("B") +- } -} +diff -urN a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden +--- a/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/invertifcondition/semicolon_or.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_semicolon_or_8_2 -- +-package invertifcondition - ---- TestA2-hoverdef -- --```go --func TestA2(t *testing.T) --``` -diff -urN a/gopls/internal/lsp/testdata/godef/a/d.go b/gopls/internal/lsp/testdata/godef/a/d.go ---- a/gopls/internal/lsp/testdata/godef/a/d.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/d.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,69 +0,0 @@ --package a //@mark(a, "a "),hoverdef("a ", a) -- --import "fmt" +-import ( +- "fmt" +-) - --type Thing struct { //@Thing -- Member string //@Member +-func SemicolonOr() { +- if n, err := fmt.Println("x"); err == nil && n >= 5 { +- fmt.Println("B") +- } else { //@suggestedfix(re"if n, err := fmt.Println..x..; err != nil .. n < 5", "refactor.rewrite", "") +- fmt.Println("A") +- } -} - --var Other Thing //@Other +diff -urN a/gopls/internal/lsp/testdata/issues/issue56505.go b/gopls/internal/lsp/testdata/issues/issue56505.go +--- a/gopls/internal/lsp/testdata/issues/issue56505.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/issues/issue56505.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package issues - --func Things(val []string) []Thing { //@Things -- return nil +-// Test for golang/go#56505: completion on variables of type *error should not +-// panic. +-func _() { +- var e *error +- e.x //@complete(" //") -} +diff -urN a/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in b/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in +--- a/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,31 +0,0 @@ +-package keywords - --func (t Thing) Method(i int) string { //@Method -- return t.Member +-// non-matching candidate - shouldn't show up as completion +-var apple = "apple" +- +-func _() { +- foo.bar() // insert some extra statements to exercise our AST surgery +- variance := 123 //@item(kwVariance, "variance", "int", "var") +- foo.bar() +- println(var) //@complete(")", kwVariance) -} - --func (t Thing) Method3() { +-func _() { +- foo.bar() +- var s struct { variance int } //@item(kwVarianceField, "variance", "int", "field") +- foo.bar() +- s.var //@complete(" //", kwVarianceField) -} - --func (t *Thing) Method2(i int, j int) (error, string) { -- return nil, t.Member +-func _() { +- channel := 123 //@item(kwChannel, "channel", "int", "var") +- chan //@complete(" //", kwChannel) +- foo.bar() -} - --func (t *Thing) private() { +-func _() { +- foo.bar() +- var typeName string //@item(kwTypeName, "typeName", "string", "var") +- foo.bar() +- type //@complete(" //", kwTypeName) -} +diff -urN a/gopls/internal/lsp/testdata/keywords/empty_select.go b/gopls/internal/lsp/testdata/keywords/empty_select.go +--- a/gopls/internal/lsp/testdata/keywords/empty_select.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/keywords/empty_select.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package keywords - --func useThings() { -- t := Thing{ //@mark(aStructType, "ing") -- Member: "string", //@mark(fMember, "ember") +-func _() { +- select { +- c //@complete(" //", case) - } -- fmt.Print(t.Member) //@mark(aMember, "ember") -- fmt.Print(Other) //@mark(aVar, "ther") -- Things() //@mark(aFunc, "ings") -- t.Method() //@mark(aMethod, "eth") -} +diff -urN a/gopls/internal/lsp/testdata/keywords/empty_switch.go b/gopls/internal/lsp/testdata/keywords/empty_switch.go +--- a/gopls/internal/lsp/testdata/keywords/empty_switch.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/keywords/empty_switch.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package keywords - --type NextThing struct { //@NextThing -- Thing -- Value int --} +-func _() { +- switch { +- //@complete("", case, default) +- } - --func (n NextThing) another() string { -- return n.Member +- switch test.(type) { +- d //@complete(" //", default) +- } -} +diff -urN a/gopls/internal/lsp/testdata/keywords/keywords.go b/gopls/internal/lsp/testdata/keywords/keywords.go +--- a/gopls/internal/lsp/testdata/keywords/keywords.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/keywords/keywords.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,100 +0,0 @@ +-package keywords - --// Shadows Thing.Method3 --func (n *NextThing) Method3() int { -- return n.Value --} +-//@rank("", type),rank("", func),rank("", var),rank("", const),rank("", import) - --var nextThing NextThing //@hoverdef("NextThing", NextThing) +-func _() { +- var test int //@rank(" //", int, interface) +- var tChan chan int +- var _ m //@complete(" //", map) +- var _ f //@complete(" //", func) +- var _ c //@complete(" //", chan) - --/*@ --godef(aStructType, Thing) --godef(aMember, Member) --godef(aVar, Other) --godef(aFunc, Things) --godef(aMethod, Method) --godef(fMember, Member) --godef(Member, Member) +- var _ str //@rank(" //", string, struct) - --//param --//package name --//const --//anon field +- type _ int //@rank(" //", interface, int) - --*/ -diff -urN a/gopls/internal/lsp/testdata/godef/a/d.go.golden b/gopls/internal/lsp/testdata/godef/a/d.go.golden ---- a/gopls/internal/lsp/testdata/godef/a/d.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/d.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,191 +0,0 @@ ---- Member-definition -- --godef/a/d.go:6:2-8: defined here as ```go --field Member string --``` +- type _ str //@rank(" //", struct, string) - --@Member +- switch test { +- case 1: // TODO: trying to complete case here will break because the parser won't return *ast.Ident +- b //@complete(" //", break) +- case 2: +- f //@complete(" //", fallthrough, for) +- r //@complete(" //", return) +- d //@complete(" //", default, defer) +- c //@complete(" //", case, const) +- } - +- switch test.(type) { +- case fo: //@complete(":") +- case int: +- b //@complete(" //", break) +- case int32: +- f //@complete(" //", for) +- d //@complete(" //", default, defer) +- r //@complete(" //", return) +- c //@complete(" //", case, const) +- } - --[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) ---- Member-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 6, -- "column": 2, -- "offset": 90 -- }, -- "end": { -- "line": 6, -- "column": 8, -- "offset": 96 -- } -- }, -- "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)" --} +- select { +- case <-tChan: +- b //@complete(" //", break) +- c //@complete(" //", case, const) +- } - ---- Member-hoverdef -- --```go --field Member string --``` +- for index := 0; index < test; index++ { +- c //@complete(" //", const, continue) +- b //@complete(" //", break) +- } - --@Member +- for range []int{} { +- c //@complete(" //", const, continue) +- b //@complete(" //", break) +- } - +- // Test function level keywords - --[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) ---- Method-definition -- --godef/a/d.go:15:16-22: defined here as ```go --func (Thing).Method(i int) string --``` +- //Using 2 characters to test because map output order is random +- sw //@complete(" //", switch) +- se //@complete(" //", select) - --[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method) ---- Method-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 15, -- "column": 16, -- "offset": 219 -- }, -- "end": { -- "line": 15, -- "column": 22, -- "offset": 225 -- } -- }, -- "description": "```go\nfunc (Thing).Method(i int) string\n```\n\n[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method)" +- f //@complete(" //", for) +- d //@complete(" //", defer) +- g //@rank(" //", go),rank(" //", goto) +- r //@complete(" //", return) +- i //@complete(" //", if) +- e //@complete(" //", else) +- v //@complete(" //", var) +- c //@complete(" //", const) +- +- for i := r //@complete(" //", range) -} - ---- Method-hoverdef -- --```go --func (Thing).Method(i int) string --``` +-/* package */ //@item(package, "package", "", "keyword") +-/* import */ //@item(import, "import", "", "keyword") +-/* func */ //@item(func, "func", "", "keyword") +-/* type */ //@item(type, "type", "", "keyword") +-/* var */ //@item(var, "var", "", "keyword") +-/* const */ //@item(const, "const", "", "keyword") +-/* break */ //@item(break, "break", "", "keyword") +-/* default */ //@item(default, "default", "", "keyword") +-/* case */ //@item(case, "case", "", "keyword") +-/* defer */ //@item(defer, "defer", "", "keyword") +-/* go */ //@item(go, "go", "", "keyword") +-/* for */ //@item(for, "for", "", "keyword") +-/* if */ //@item(if, "if", "", "keyword") +-/* else */ //@item(else, "else", "", "keyword") +-/* switch */ //@item(switch, "switch", "", "keyword") +-/* select */ //@item(select, "select", "", "keyword") +-/* fallthrough */ //@item(fallthrough, "fallthrough", "", "keyword") +-/* continue */ //@item(continue, "continue", "", "keyword") +-/* return */ //@item(return, "return", "", "keyword") +-/* var */ //@item(var, "var", "", "keyword") +-/* const */ //@item(const, "const", "", "keyword") +-/* goto */ //@item(goto, "goto", "", "keyword") +-/* struct */ //@item(struct, "struct", "", "keyword") +-/* interface */ //@item(interface, "interface", "", "keyword") +-/* map */ //@item(map, "map", "", "keyword") +-/* func */ //@item(func, "func", "", "keyword") +-/* chan */ //@item(chan, "chan", "", "keyword") +-/* range */ //@item(range, "range", "", "keyword") +diff -urN a/gopls/internal/lsp/testdata/labels/labels.go b/gopls/internal/lsp/testdata/labels/labels.go +--- a/gopls/internal/lsp/testdata/labels/labels.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/labels/labels.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,49 +0,0 @@ +-package labels - --[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method) ---- NextThing-hoverdef -- --```go --type NextThing struct { -- Thing -- Value int --} +-func _() { +- goto F //@complete(" //", label1, label5) - --func (*NextThing).Method3() int --func (NextThing).another() string --``` +-Foo1: //@item(label1, "Foo1", "label", "const") +- for a, b := range []int{} { +- Foo2: //@item(label2, "Foo2", "label", "const") +- switch { +- case true: +- break F //@complete(" //", label2, label1) - --[`a.NextThing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#NextThing) ---- Other-definition -- --godef/a/d.go:9:5-10: defined here as ```go --var Other Thing --``` +- continue F //@complete(" //", label1) +- +- { +- FooUnjumpable: +- } +- +- goto F //@complete(" //", label1, label2, label4, label5) +- +- func() { +- goto F //@complete(" //", label3) +- +- break F //@complete(" //") - --@Other +- continue F //@complete(" //") - +- Foo3: //@item(label3, "Foo3", "label", "const") +- }() +- } - --[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) ---- Other-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 9, -- "column": 5, -- "offset": 121 -- }, -- "end": { -- "line": 9, -- "column": 10, -- "offset": 126 +- Foo4: //@item(label4, "Foo4", "label", "const") +- switch interface{}(a).(type) { +- case int: +- break F //@complete(" //", label4, label1) - } -- }, -- "description": "```go\nvar Other Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)" --} +- } - ---- Other-hoverdef -- --```go --var Other Thing --``` +- break F //@complete(" //") - --@Other +- continue F //@complete(" //") - +-Foo5: //@item(label5, "Foo5", "label", "const") +- for { +- break F //@complete(" //", label5) +- } - --[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) ---- Thing-definition -- --godef/a/d.go:5:6-11: defined here as ```go --type Thing struct { -- Member string //@Member +- return -} +diff -urN a/gopls/internal/lsp/testdata/links/links.go b/gopls/internal/lsp/testdata/links/links.go +--- a/gopls/internal/lsp/testdata/links/links.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/links/links.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +-package links - --func (Thing).Method(i int) string --func (*Thing).Method2(i int, j int) (error, string) --func (Thing).Method3() --func (*Thing).private() --``` +-import ( +- "fmt" //@link(`fmt`,"https://pkg.go.dev/fmt") - --[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) ---- Thing-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 5, -- "column": 6, -- "offset": 65 -- }, -- "end": { -- "line": 5, -- "column": 11, -- "offset": 70 -- } -- }, -- "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n\nfunc (Thing).Method(i int) string\nfunc (*Thing).Method2(i int, j int) (error, string)\nfunc (Thing).Method3()\nfunc (*Thing).private()\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)" --} +- "golang.org/lsptests/foo" //@link(`golang.org/lsptests/foo`,`https://pkg.go.dev/golang.org/lsptests/foo`) - ---- Thing-hoverdef -- --```go --type Thing struct { -- Member string //@Member --} +- _ "database/sql" //@link(`database/sql`, `https://pkg.go.dev/database/sql`) +-) - --func (Thing).Method(i int) string --func (*Thing).Method2(i int, j int) (error, string) --func (Thing).Method3() --func (*Thing).private() --``` +-var ( +- _ fmt.Formatter +- _ foo.StructFoo +- _ errors.Formatter +-) - --[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) ---- Things-definition -- --godef/a/d.go:11:6-12: defined here as ```go --func Things(val []string) []Thing --``` +-// Foo function +-func Foo() string { +- /*https://example.com/comment */ //@link("https://example.com/comment","https://example.com/comment") - --[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) ---- Things-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 11, -- "column": 6, -- "offset": 148 -- }, -- "end": { -- "line": 11, -- "column": 12, -- "offset": 154 -- } -- }, -- "description": "```go\nfunc Things(val []string) []Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)" +- url := "https://example.com/string_literal" //@link("https://example.com/string_literal","https://example.com/string_literal") +- return url +- +- // TODO(golang/go#1234): Link the relevant issue. //@link("golang/go#1234", "https://github.com/golang/go/issues/1234") +- // TODO(microsoft/vscode-go#12): Another issue. //@link("microsoft/vscode-go#12", "https://github.com/microsoft/vscode-go/issues/12") -} +diff -urN a/gopls/internal/lsp/testdata/maps/maps.go.in b/gopls/internal/lsp/testdata/maps/maps.go.in +--- a/gopls/internal/lsp/testdata/maps/maps.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/maps/maps.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-package maps - ---- Things-hoverdef -- --```go --func Things(val []string) []Thing --``` +-func _() { +- var aVar int //@item(mapVar, "aVar", "int", "var") - --[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) ---- a-hoverdef -- --Package a is a package for testing go to definition. +- // not comparabale +- type aSlice []int //@item(mapSliceType, "aSlice", "[]int", "type") - -diff -urN a/gopls/internal/lsp/testdata/godef/a/f.go b/gopls/internal/lsp/testdata/godef/a/f.go ---- a/gopls/internal/lsp/testdata/godef/a/f.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/f.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ --// Package a is a package for testing go to definition. --package a +- *aSlice //@item(mapSliceTypePtr, "*aSlice", "[]int", "type") - --import "fmt" +- // comparable +- type aStruct struct{} //@item(mapStructType, "aStruct", "struct{...}", "struct") - --func TypeStuff() { //@Stuff -- var x string +- map[]a{} //@complete("]", mapSliceType, mapStructType),snippet("]", mapSliceType, "*aSlice", "*aSlice") - -- switch y := interface{}(x).(type) { //@mark(switchY, "y"),godef("y", switchY) -- case int: //@mark(intY, "int") -- fmt.Printf("%v", y) //@hoverdef("y", intY) -- case string: //@mark(stringY, "string") -- fmt.Printf("%v", y) //@hoverdef("y", stringY) -- } +- map[a]a{} //@complete("]", mapSliceType, mapStructType) +- map[a]a{} //@complete("{", mapSliceType, mapStructType) +-} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go b/gopls/internal/lsp/testdata/missingfunction/channels.go +--- a/gopls/internal/lsp/testdata/missingfunction/channels.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/channels.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package missingfunction - +-func channels(s string) { +- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") -} -diff -urN a/gopls/internal/lsp/testdata/godef/a/f.go.golden b/gopls/internal/lsp/testdata/godef/a/f.go.golden ---- a/gopls/internal/lsp/testdata/godef/a/f.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/f.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,34 +0,0 @@ ---- intY-hoverdef -- --```go --var y int --``` ---- stringY-hoverdef -- --```go --var y string --``` ---- switchY-definition -- --godef/a/f.go:8:9-10: defined here as ```go --var y interface{} --``` ---- switchY-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/f.go", -- "start": { -- "line": 8, -- "column": 9, -- "offset": 76 -- }, -- "end": { -- "line": 8, -- "column": 10, -- "offset": 77 -- } -- }, -- "description": "```go\nvar y interface{}\n```" +- +-func c() (<-chan string, chan string) { +- return make(<-chan string), make(chan string) -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_channels_4_2 -- +-package missingfunction - ---- switchY-hoverdef -- --```go --var y interface{} --``` -diff -urN a/gopls/internal/lsp/testdata/godef/a/g.go b/gopls/internal/lsp/testdata/godef/a/g.go ---- a/gopls/internal/lsp/testdata/godef/a/g.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/g.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package a +-func channels(s string) { +- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") +-} - --import "time" +-func undefinedChannels(ch1 <-chan string, ch2 chan string) { +- panic("unimplemented") +-} - --// dur is a constant of type time.Duration. --const dur = 15*time.Minute + 10*time.Second + 350*time.Millisecond //@dur,hoverdef("dur", dur) -diff -urN a/gopls/internal/lsp/testdata/godef/a/g.go.golden b/gopls/internal/lsp/testdata/godef/a/g.go.golden ---- a/gopls/internal/lsp/testdata/godef/a/g.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/g.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ ---- dur-hoverdef -- --```go --const dur time.Duration = 910350000000 // 15m10.35s --``` +-func c() (<-chan string, chan string) { +- return make(<-chan string), make(chan string) +-} - --dur is a constant of type time.Duration. +diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go +--- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package missingfunction - -diff -urN a/gopls/internal/lsp/testdata/godef/a/h.go b/gopls/internal/lsp/testdata/godef/a/h.go ---- a/gopls/internal/lsp/testdata/godef/a/h.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/h.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,147 +0,0 @@ --package a +-func consecutiveParams() { +- var s string +- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") +-} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- suggestedfix_consecutive_params_5_2 -- +-package missingfunction - --func _() { -- type s struct { -- nested struct { -- // nested number -- number int64 //@mark(nestedNumber, "number") -- } -- nested2 []struct { -- // nested string -- str string //@mark(nestedString, "str") -- } -- x struct { -- x struct { -- x struct { -- x struct { -- x struct { -- // nested map -- m map[string]float64 //@mark(nestedMap, "m") -- } -- } -- } -- } -- } -- } +-func consecutiveParams() { +- var s string +- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") +-} - -- var t s -- _ = t.nested.number //@hoverdef("number", nestedNumber) -- _ = t.nested2[0].str //@hoverdef("str", nestedString) -- _ = t.x.x.x.x.x.m //@hoverdef("m", nestedMap) +-func undefinedConsecutiveParams(s1, s2 string) { +- panic("unimplemented") -} - --func _() { -- var s struct { -- // a field -- a int //@mark(structA, "a") -- // b nested struct -- b struct { //@mark(structB, "b") -- // c field of nested struct -- c int //@mark(structC, "c") -- } -- } -- _ = s.a //@hoverdef("a", structA) -- _ = s.b //@hoverdef("b", structB) -- _ = s.b.c //@hoverdef("c", structC) +diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go b/gopls/internal/lsp/testdata/missingfunction/error_param.go +--- a/gopls/internal/lsp/testdata/missingfunction/error_param.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package missingfunction - -- var arr []struct { -- // d field -- d int //@mark(arrD, "d") -- // e nested struct -- e struct { //@mark(arrE, "e") -- // f field of nested struct -- f int //@mark(arrF, "f") -- } -- } -- _ = arr[0].d //@hoverdef("d", arrD) -- _ = arr[0].e //@hoverdef("e", arrE) -- _ = arr[0].e.f //@hoverdef("f", arrF) +-func errorParam() { +- var err error +- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") +-} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- suggestedfix_error_param_5_2 -- +-package missingfunction - -- var complex []struct { -- c <-chan map[string][]struct { -- // h field -- h int //@mark(complexH, "h") -- // i nested struct -- i struct { //@mark(complexI, "i") -- // j field of nested struct -- j int //@mark(complexJ, "j") -- } -- } -- } -- _ = (<-complex[0].c)["0"][0].h //@hoverdef("h", complexH) -- _ = (<-complex[0].c)["0"][0].i //@hoverdef("i", complexI) -- _ = (<-complex[0].c)["0"][0].i.j //@hoverdef("j", complexJ) +-func errorParam() { +- var err error +- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") +-} - -- var mapWithStructKey map[struct { -- // X key field -- x []string //@mark(mapStructKeyX, "x") -- }]int -- for k := range mapWithStructKey { -- _ = k.x //@hoverdef("x", mapStructKeyX) -- } +-func undefinedErrorParam(err error) { +- panic("unimplemented") +-} - -- var mapWithStructKeyAndValue map[struct { -- // Y key field -- y string //@mark(mapStructKeyY, "y") -- }]struct { -- // X value field -- x string //@mark(mapStructValueX, "x") -- } -- for k, v := range mapWithStructKeyAndValue { -- // TODO: we don't show docs for y field because both map key and value -- // are structs. And in this case, we parse only map value -- _ = k.y //@hoverdef("y", mapStructKeyY) -- _ = v.x //@hoverdef("x", mapStructValueX) -- } +diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go b/gopls/internal/lsp/testdata/missingfunction/literals.go +--- a/gopls/internal/lsp/testdata/missingfunction/literals.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/literals.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package missingfunction - -- var i []map[string]interface { -- // open method comment -- open() error //@mark(openMethod, "open") -- } -- i[0]["1"].open() //@hoverdef("open", openMethod) +-type T struct{} +- +-func literals() { +- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") -} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_literals_6_2 -- +-package missingfunction - --func _() { -- test := struct { -- // test description -- desc string //@mark(testDescription, "desc") -- }{} -- _ = test.desc //@hoverdef("desc", testDescription) +-type T struct{} - -- for _, tt := range []struct { -- // test input -- in map[string][]struct { //@mark(testInput, "in") -- // test key -- key string //@mark(testInputKey, "key") -- // test value -- value interface{} //@mark(testInputValue, "value") -- } -- result struct { -- v <-chan struct { -- // expected test value -- value int //@mark(testResultValue, "value") -- } -- } -- }{} { -- _ = tt.in //@hoverdef("in", testInput) -- _ = tt.in["0"][0].key //@hoverdef("key", testInputKey) -- _ = tt.in["0"][0].value //@hoverdef("value", testInputValue) +-func literals() { +- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") +-} - -- _ = (<-tt.result.v).value //@hoverdef("value", testResultValue) -- } +-func undefinedLiterals(s string, t1 T, t2 *T) { +- panic("unimplemented") -} - --func _() { -- getPoints := func() []struct { -- // X coord -- x int //@mark(returnX, "x") -- // Y coord -- y int //@mark(returnY, "y") -- } { -- return nil -- } +diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go b/gopls/internal/lsp/testdata/missingfunction/operation.go +--- a/gopls/internal/lsp/testdata/missingfunction/operation.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/operation.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package missingfunction - -- r := getPoints() -- r[0].x //@hoverdef("x", returnX) -- r[0].y //@hoverdef("y", returnY) +-import "time" +- +-func operation() { +- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") -} -diff -urN a/gopls/internal/lsp/testdata/godef/a/h.go.golden b/gopls/internal/lsp/testdata/godef/a/h.go.golden ---- a/gopls/internal/lsp/testdata/godef/a/h.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/a/h.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,161 +0,0 @@ ---- arrD-hoverdef -- --```go --field d int --``` +diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_operation_6_2 -- +-package missingfunction - --d field +-import "time" - ---- arrE-hoverdef -- --```go --field e struct{f int} --``` +-func operation() { +- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") +-} - --e nested struct +-func undefinedOperation(duration time.Duration) { +- panic("unimplemented") +-} - ---- arrF-hoverdef -- --```go --field f int --``` +diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go b/gopls/internal/lsp/testdata/missingfunction/selector.go +--- a/gopls/internal/lsp/testdata/missingfunction/selector.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/selector.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package missingfunction - --f field of nested struct +-func selector() { +- m := map[int]bool{} +- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") +-} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- suggestedfix_selector_5_2 -- +-package missingfunction - ---- complexH-hoverdef -- --```go --field h int --``` +-func selector() { +- m := map[int]bool{} +- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") +-} - --h field +-func undefinedSelector(b bool) { +- panic("unimplemented") +-} - ---- complexI-hoverdef -- --```go --field i struct{j int} --``` +diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go b/gopls/internal/lsp/testdata/missingfunction/slice.go +--- a/gopls/internal/lsp/testdata/missingfunction/slice.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/slice.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +-package missingfunction +- +-func slice() { +- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") +-} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +--- suggestedfix_slice_4_2 -- +-package missingfunction - --i nested struct +-func slice() { +- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") +-} - ---- complexJ-hoverdef -- --```go --field j int --``` +-func undefinedSlice(i []int) { +- panic("unimplemented") +-} - --j field of nested struct +diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go b/gopls/internal/lsp/testdata/missingfunction/tuple.go +--- a/gopls/internal/lsp/testdata/missingfunction/tuple.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package missingfunction - ---- mapStructKeyX-hoverdef -- --```go --field x []string --``` +-func tuple() { +- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") +-} - --X key field +-func b() (string, error) { +- return "", nil +-} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- suggestedfix_tuple_4_2 -- +-package missingfunction - ---- mapStructKeyY-hoverdef -- --```go --field y string --``` +-func tuple() { +- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") +-} - --Y key field +-func undefinedTuple(s string, err error) { +- panic("unimplemented") +-} - ---- mapStructValueX-hoverdef -- --```go --field x string --``` +-func b() (string, error) { +- return "", nil +-} - --X value field +diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go b/gopls/internal/lsp/testdata/missingfunction/unique_params.go +--- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package missingfunction - ---- nestedMap-hoverdef -- --```go --field m map[string]float64 --``` +-func uniqueArguments() { +- var s string +- var i int +- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") +-} +diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden +--- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_unique_params_6_2 -- +-package missingfunction - --nested map +-func uniqueArguments() { +- var s string +- var i int +- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") +-} - ---- nestedNumber-hoverdef -- --```go --field number int64 --``` +-func undefinedUniqueArguments(s1 string, i int, s2 string) { +- panic("unimplemented") +-} - --nested number +diff -urN a/gopls/internal/lsp/testdata/multireturn/multi_return.go.in b/gopls/internal/lsp/testdata/multireturn/multi_return.go.in +--- a/gopls/internal/lsp/testdata/multireturn/multi_return.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/multireturn/multi_return.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,48 +0,0 @@ +-package multireturn - ---- nestedString-hoverdef -- --```go --field str string --``` +-func f0() {} //@item(multiF0, "f0", "func()", "func") - --nested string +-func f1(int) int { return 0 } //@item(multiF1, "f1", "func(int) int", "func") - ---- openMethod-hoverdef -- --```go --func (interface).open() error --``` +-func f2(int, int) (int, int) { return 0, 0 } //@item(multiF2, "f2", "func(int, int) (int, int)", "func") - --open method comment +-func f2Str(string, string) (string, string) { return "", "" } //@item(multiF2Str, "f2Str", "func(string, string) (string, string)", "func") - ---- returnX-hoverdef -- --```go --field x int --``` +-func f3(int, int, int) (int, int, int) { return 0, 0, 0 } //@item(multiF3, "f3", "func(int, int, int) (int, int, int)", "func") - --X coord +-func _() { +- _ := f //@rank(" //", multiF1, multiF2) - ---- returnY-hoverdef -- --```go --field y int --``` +- _, _ := f //@rank(" //", multiF2, multiF0),rank(" //", multiF1, multiF0) - --Y coord +- _, _ := _, f //@rank(" //", multiF1, multiF2),rank(" //", multiF1, multiF0) - ---- structA-hoverdef -- --```go --field a int --``` +- _, _ := f, abc //@rank(", abc", multiF1, multiF2) - --a field +- f1() //@rank(")", multiF1, multiF0) +- f1(f) //@rank(")", multiF1, multiF2) +- f2(f) //@rank(")", multiF2, multiF3),rank(")", multiF1, multiF3) +- f2(1, f) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) +- f2(1, ) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) +- f2Str() //@rank(")", multiF2Str, multiF2) - ---- structB-hoverdef -- --```go --field b struct{c int} --``` +- var i int +- i, _ := f //@rank(" //", multiF2, multiF2Str) - --b nested struct +- var s string +- _, s := f //@rank(" //", multiF2Str, multiF2) - ---- structC-hoverdef -- --```go --field c int --``` +- banana, s = f //@rank(" //", multiF2, multiF3) - --c field of nested struct +- var variadic func(int, ...int) +- variadic() //@rank(")", multiF1, multiF0),rank(")", multiF2, multiF0),rank(")", multiF3, multiF0) +-} - ---- testDescription-hoverdef -- --```go --field desc string --``` +-func _() { +- var baz func(...interface{}) - --test description +- var otterNap func() (int, int) //@item(multiTwo, "otterNap", "func() (int, int)", "var") +- var one int //@item(multiOne, "one", "int", "var") - ---- testInput-hoverdef -- --```go --field in map[string][]struct{key string; value interface{}} --``` +- baz(on) //@rank(")", multiOne, multiTwo) +-} +diff -urN a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in +--- a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-package nested_complit - --test input +-type ncFoo struct {} //@item(structNCFoo, "ncFoo", "struct{...}", "struct") - ---- testInputKey-hoverdef -- --```go --field key string --``` +-type ncBar struct { //@item(structNCBar, "ncBar", "struct{...}", "struct") +- baz []ncFoo +-} - --test key +-func _() { +- []ncFoo{} //@item(litNCFoo, "[]ncFoo{}", "", "var") +- _ := ncBar{ +- // disabled - see issue #54822 +- baz: [] // complete(" //", structNCFoo, structNCBar) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/nodisk/empty b/gopls/internal/lsp/testdata/nodisk/empty +--- a/gopls/internal/lsp/testdata/nodisk/empty 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/nodisk/empty 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-an empty file so that this directory exists +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go b/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go +--- a/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package nodisk - ---- testInputValue-hoverdef -- --```go --field value interface{} --``` +-import ( +- "golang.org/lsptests/foo" +-) - --test value +-func _() { +- foo.Foo() //@complete("F", Foo, IntFoo, StructFoo) +-} +diff -urN a/gopls/internal/lsp/testdata/%percent/perc%ent.go b/gopls/internal/lsp/testdata/%percent/perc%ent.go +--- a/gopls/internal/lsp/testdata/%percent/perc%ent.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/%percent/perc%ent.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-package percent +diff -urN a/gopls/internal/lsp/testdata/printf/printf.go b/gopls/internal/lsp/testdata/printf/printf.go +--- a/gopls/internal/lsp/testdata/printf/printf.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/printf/printf.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-package printf - ---- testResultValue-hoverdef -- --```go --field value int --``` +-import "fmt" - --expected test value +-func myPrintf(string, ...interface{}) {} - -diff -urN a/gopls/internal/lsp/testdata/godef/b/e.go b/gopls/internal/lsp/testdata/godef/b/e.go ---- a/gopls/internal/lsp/testdata/godef/b/e.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/b/e.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ --package b +-func _() { +- var ( +- aInt int //@item(printfInt, "aInt", "int", "var") +- aFloat float64 //@item(printfFloat, "aFloat", "float64", "var") +- aString string //@item(printfString, "aString", "string", "var") +- aBytes []byte //@item(printfBytes, "aBytes", "[]byte", "var") +- aStringer fmt.Stringer //@item(printfStringer, "aStringer", "fmt.Stringer", "var") +- aError error //@item(printfError, "aError", "error", "var") +- aBool bool //@item(printfBool, "aBool", "bool", "var") +- ) - --import ( -- "fmt" +- myPrintf("%d", a) //@rank(")", printfInt, printfFloat) +- myPrintf("%s", a) //@rank(")", printfString, printfInt),rank(")", printfBytes, printfInt),rank(")", printfStringer, printfInt),rank(")", printfError, printfInt) +- myPrintf("%w", a) //@rank(")", printfError, printfInt) +- myPrintf("%x %[1]b", a) //@rank(")", printfInt, printfString) - -- "golang.org/lsptests/godef/a" --) +- fmt.Printf("%t", a) //@rank(")", printfBool, printfInt) - --func useThings() { -- t := a.Thing{} //@mark(bStructType, "ing") -- fmt.Print(t.Member) //@mark(bMember, "ember") -- fmt.Print(a.Other) //@mark(bVar, "ther") -- a.Things() //@mark(bFunc, "ings") +- fmt.Fprintf(nil, "%f", a) //@rank(")", printfFloat, printfInt) +- +- fmt.Sprintf("%[2]q %[1]*.[3]*[4]f", +- a, //@rank(",", printfInt, printfFloat) +- a, //@rank(",", printfString, printfFloat) +- a, //@rank(",", printfInt, printfFloat) +- a, //@rank(",", printfFloat, printfInt) +- ) -} +diff -urN a/gopls/internal/lsp/testdata/rank/assign_rank.go.in b/gopls/internal/lsp/testdata/rank/assign_rank.go.in +--- a/gopls/internal/lsp/testdata/rank/assign_rank.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/assign_rank.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +-package rank - --/*@ --godef(bStructType, Thing) --godef(bMember, Member) --godef(bVar, Other) --godef(bFunc, Things) --*/ +-var ( +- apple int = 3 //@item(apple, "apple", "int", "var") +- pear string = "hello" //@item(pear, "pear", "string", "var") +-) - -func _() { -- var x interface{} //@mark(eInterface, "interface{}") -- switch x := x.(type) { //@hoverdef("x", eInterface) -- case string: //@mark(eString, "string") -- fmt.Println(x) //@hoverdef("x", eString) -- case int: //@mark(eInt, "int") -- fmt.Println(x) //@hoverdef("x", eInt) -- } +- orange := 1 //@item(orange, "orange", "int", "var") +- grape := "hello" //@item(grape, "grape", "string", "var") +- orange, grape = 2, "hello" //@complete(" \"", grape, pear, orange, apple) -} -diff -urN a/gopls/internal/lsp/testdata/godef/b/e.go.golden b/gopls/internal/lsp/testdata/godef/b/e.go.golden ---- a/gopls/internal/lsp/testdata/godef/b/e.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/b/e.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,156 +0,0 @@ ---- Member-definition -- --godef/a/d.go:6:2-8: defined here as ```go --field Member string --``` -- --@Member - +-func _() { +- var pineapple int //@item(pineapple, "pineapple", "int", "var") +- pineapple = 1 //@complete(" 1", pineapple, apple, pear) - --[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) ---- Member-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 6, -- "column": 2, -- "offset": 90 -- }, -- "end": { -- "line": 6, -- "column": 8, -- "offset": 96 -- } -- }, -- "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)" +- y := //@complete(" /", pineapple, apple, pear) -} +diff -urN a/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in b/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in +--- a/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package rank - ---- Member-hoverdef -- --```go --field Member string --``` +-func _() { +- _ = 5 + ; //@complete(" ;", apple, pear) +- y := + 5; //@complete(" +", apple, pear) - --@Member +- if 6 == {} //@complete(" {", apple, pear) +-} +diff -urN a/gopls/internal/lsp/testdata/rank/boolexpr_rank.go b/gopls/internal/lsp/testdata/rank/boolexpr_rank.go +--- a/gopls/internal/lsp/testdata/rank/boolexpr_rank.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/boolexpr_rank.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package rank - +-func _() { +- someRandomBoolFunc := func() bool { //@item(boolExprFunc, "someRandomBoolFunc", "func() bool", "var") +- return true +- } - --[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member) ---- Other-definition -- --godef/a/d.go:9:5-10: defined here as ```go --var a.Other a.Thing --``` +- var foo, bar int //@item(boolExprBar, "bar", "int", "var") +- if foo == 123 && b { //@rank(" {", boolExprBar, boolExprFunc) +- } +-} +diff -urN a/gopls/internal/lsp/testdata/rank/convert_rank.go.in b/gopls/internal/lsp/testdata/rank/convert_rank.go.in +--- a/gopls/internal/lsp/testdata/rank/convert_rank.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/convert_rank.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,54 +0,0 @@ +-package rank - --@Other +-import "time" - +-func _() { +- type strList []string +- wantsStrList := func(strList) {} - --[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) ---- Other-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 9, -- "column": 5, -- "offset": 121 -- }, -- "end": { -- "line": 9, -- "column": 10, -- "offset": 126 -- } -- }, -- "description": "```go\nvar a.Other a.Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)" +- var ( +- convA string //@item(convertA, "convA", "string", "var") +- convB []string //@item(convertB, "convB", "[]string", "var") +- ) +- wantsStrList(strList(conv)) //@complete("))", convertB, convertA) -} - ---- Other-hoverdef -- --```go --var a.Other a.Thing --``` +-func _() { +- type myInt int - --@Other +- const ( +- convC = "hi" //@item(convertC, "convC", "string", "const") +- convD = 123 //@item(convertD, "convD", "int", "const") +- convE int = 123 //@item(convertE, "convE", "int", "const") +- convF string = "there" //@item(convertF, "convF", "string", "const") +- convG myInt = 123 //@item(convertG, "convG", "myInt", "const") +- ) - +- var foo int +- foo = conv //@rank(" //", convertE, convertD) - --[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other) ---- Thing-definition -- --godef/a/d.go:5:6-11: defined here as ```go --type Thing struct { -- Member string //@Member --} +- var mi myInt +- mi = conv //@rank(" //", convertG, convertD, convertE) +- mi + conv //@rank(" //", convertG, convertD, convertE) - --func (a.Thing).Method(i int) string --func (*a.Thing).Method2(i int, j int) (error, string) --func (a.Thing).Method3() --``` +- 1 + conv //@rank(" //", convertD, convertC),rank(" //", convertE, convertC),rank(" //", convertG, convertC) - --[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) ---- Thing-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 5, -- "column": 6, -- "offset": 65 -- }, -- "end": { -- "line": 5, -- "column": 11, -- "offset": 70 -- } -- }, -- "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n\nfunc (a.Thing).Method(i int) string\nfunc (*a.Thing).Method2(i int, j int) (error, string)\nfunc (a.Thing).Method3()\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)" --} +- type myString string +- var ms myString +- ms = conv //@rank(" //", convertC, convertF) - ---- Thing-hoverdef -- --```go --type Thing struct { -- Member string //@Member --} +- type myUint uint32 +- var mu myUint +- mu = conv //@rank(" //", convertD, convertE) - --func (a.Thing).Method(i int) string --func (*a.Thing).Method2(i int, j int) (error, string) --func (a.Thing).Method3() --``` +- // don't downrank constants when assigning to interface{} +- var _ interface{} = c //@rank(" //", convertD, complex) - --[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing) ---- Things-definition -- --godef/a/d.go:11:6-12: defined here as ```go --func a.Things(val []string) []a.Thing --``` +- var _ time.Duration = conv //@rank(" //", convertD, convertE),snippet(" //", convertE, "time.Duration(convE)", "time.Duration(convE)") - --[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) ---- Things-definition-json -- --{ -- "span": { -- "uri": "file://godef/a/d.go", -- "start": { -- "line": 11, -- "column": 6, -- "offset": 148 -- }, -- "end": { -- "line": 11, -- "column": 12, -- "offset": 154 -- } -- }, -- "description": "```go\nfunc a.Things(val []string) []a.Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)" --} +- var convP myInt //@item(convertP, "convP", "myInt", "var") +- var _ *int = conv //@snippet(" //", convertP, "(*int)(&convP)", "(*int)(&convP)") - ---- Things-hoverdef -- --```go --func a.Things(val []string) []a.Thing --``` +- var ff float64 //@item(convertFloat, "ff", "float64", "var") +- f == convD //@snippet(" =", convertFloat, "ff", "ff") +-} +diff -urN a/gopls/internal/lsp/testdata/rank/struct/struct_rank.go b/gopls/internal/lsp/testdata/rank/struct/struct_rank.go +--- a/gopls/internal/lsp/testdata/rank/struct/struct_rank.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/struct/struct_rank.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package struct_rank - --[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things) ---- eInt-hoverdef -- --```go --var x int --``` ---- eInterface-hoverdef -- --```go --var x interface{} --``` ---- eString-hoverdef -- --```go --var x string --``` -diff -urN a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden ---- a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ ---- myUnclosedIf-definition -- --godef/broken/unclosedIf.go:7:7-19: defined here as ```go --var myUnclosedIf string --``` +-type foo struct { +- c int //@item(c_rank, "c", "int", "field") +- b int //@item(b_rank, "b", "int", "field") +- a int //@item(a_rank, "a", "int", "field") +-} - --@myUnclosedIf ---- myUnclosedIf-definition-json -- --{ -- "span": { -- "uri": "file://godef/broken/unclosedIf.go", -- "start": { -- "line": 7, -- "column": 7, -- "offset": 68 -- }, -- "end": { -- "line": 7, -- "column": 19, -- "offset": 80 -- } -- }, -- "description": "```go\nvar myUnclosedIf string\n```\n\n@myUnclosedIf" +-func f() { +- foo := foo{} //@rank("}", c_rank, b_rank, a_rank) -} +diff -urN a/gopls/internal/lsp/testdata/rank/switch_rank.go.in b/gopls/internal/lsp/testdata/rank/switch_rank.go.in +--- a/gopls/internal/lsp/testdata/rank/switch_rank.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/switch_rank.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-package rank - ---- myUnclosedIf-hoverdef -- --```go --var myUnclosedIf string --``` +-import "time" - --@myUnclosedIf +-func _() { +- switch pear { +- case _: //@rank("_", pear, apple) +- } - -diff -urN a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in ---- a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package broken +- time.Monday //@item(timeMonday, "time.Monday", "time.Weekday", "const"),item(monday ,"Monday", "time.Weekday", "const") +- time.Friday //@item(timeFriday, "time.Friday", "time.Weekday", "const"),item(friday ,"Friday", "time.Weekday", "const") - --import "fmt" +- now := time.Now() +- now.Weekday //@item(nowWeekday, "now.Weekday", "func() time.Weekday", "method") - --func unclosedIf() { -- if false { -- var myUnclosedIf string //@myUnclosedIf -- fmt.Printf("s = %v\n", myUnclosedIf) //@godef("my", myUnclosedIf) +- then := time.Now() +- then.Weekday //@item(thenWeekday, "then.Weekday", "func() time.Weekday", "method") +- +- switch time.Weekday(0) { +- case time.Monday, time.Tuesday: +- case time.Wednesday, time.Thursday: +- case time.Saturday, time.Sunday: +- case t: //@rank(":", timeFriday, timeMonday) +- case time.: //@rank(":", friday, monday) +- +- case now.Weekday(): +- case week: //@rank(":", thenWeekday, nowWeekday) +- } -} -diff -urN a/gopls/internal/lsp/testdata/good/good0.go b/gopls/internal/lsp/testdata/good/good0.go ---- a/gopls/internal/lsp/testdata/good/good0.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/good/good0.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package good //@diag("package", "no_diagnostics", "", "error") +diff -urN a/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in b/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in +--- a/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package rank - --func stuff() { //@item(good_stuff, "stuff", "func()", "func"),prepare("stu", "stuff", "stuff") -- x := 5 -- random2(x) //@prepare("dom", "random2", "random2") +-func _() { +- type flower int //@item(flower, "flower", "int", "type") +- var fig string //@item(fig, "fig", "string", "var") +- +- _ = interface{}(nil).(f) //@complete(") //", flower) -} -diff -urN a/gopls/internal/lsp/testdata/good/good1.go b/gopls/internal/lsp/testdata/good/good1.go ---- a/gopls/internal/lsp/testdata/good/good1.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/good/good1.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ --package good //@diag("package", "no_diagnostics", "", "error") +diff -urN a/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in b/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in +--- a/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,31 +0,0 @@ +-package rank - -import ( -- "golang.org/lsptests/types" //@item(types_import, "types", "\"golang.org/lsptests/types\"", "package") +- "fmt" +- "go/ast" -) - --func random() int { //@item(good_random, "random", "func() int", "func") -- _ = "random() int" //@prepare("random", "", "") -- y := 6 + 7 //@prepare("7", "", "") -- return y //@prepare("return", "","") --} +-func _() { +- type basket int //@item(basket, "basket", "int", "type") +- var banana string //@item(banana, "banana", "string", "var") - --func random2(y int) int { //@item(good_random2, "random2", "func(y int) int", "func"),item(good_y_param, "y", "int", "var") -- //@complete("", good_y_param, types_import, good_random, good_random2, good_stuff) -- var b types.Bob = &types.X{} //@prepare("ypes","types", "types") -- if _, ok := b.(*types.X); ok { //@complete("X", X_struct, Y_struct, Bob_interface, CoolAlias) -- _ = 0 // suppress "empty branch" diagnostic +- switch interface{}(pear).(type) { +- case b: //@complete(":", basket) +- b //@complete(" //", banana, basket) - } - -- return y --} -diff -urN a/gopls/internal/lsp/testdata/highlights/highlights.go b/gopls/internal/lsp/testdata/highlights/highlights.go ---- a/gopls/internal/lsp/testdata/highlights/highlights.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/highlights/highlights.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,151 +0,0 @@ --package highlights +- Ident //@item(astIdent, "Ident", "struct{...}", "struct") +- IfStmt //@item(astIfStmt, "IfStmt", "struct{...}", "struct") - --import ( -- "fmt" //@mark(fmtImp, "\"fmt\""),highlight(fmtImp, fmtImp, fmt1, fmt2, fmt3, fmt4) -- h2 "net/http" //@mark(hImp, "h2"),highlight(hImp, hImp, hUse) -- "sort" --) +- switch ast.Node(nil).(type) { +- case *ast.Ident: +- case *ast.I: //@rank(":", astIfStmt, astIdent) +- } - --type F struct{ bar int } //@mark(barDeclaration, "bar"),highlight(barDeclaration, barDeclaration, bar1, bar2, bar3) +- Stringer //@item(fmtStringer, "Stringer", "interface{...}", "interface") +- GoStringer //@item(fmtGoStringer, "GoStringer", "interface{...}", "interface") - --func _() F { -- return F{ -- bar: 123, //@mark(bar1, "bar"),highlight(bar1, barDeclaration, bar1, bar2, bar3) +- switch interface{}(nil).(type) { +- case fmt.Stringer: //@rank(":", fmtStringer, fmtGoStringer) - } -} +diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.golden b/gopls/internal/lsp/testdata/rename/a/random.go.golden +--- a/gopls/internal/lsp/testdata/rename/a/random.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/a/random.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,616 +0,0 @@ +--- GetSum-rename -- +-package a - --var foo = F{bar: 52} //@mark(fooDeclaration, "foo"),mark(bar2, "bar"),highlight(fooDeclaration, fooDeclaration, fooUse),highlight(bar2, barDeclaration, bar1, bar2, bar3) -- --func Print() { //@mark(printFunc, "Print"),highlight(printFunc, printFunc, printTest) -- _ = h2.Client{} //@mark(hUse, "h2"),highlight(hUse, hImp, hUse) +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - -- fmt.Println(foo) //@mark(fooUse, "foo"),highlight(fooUse, fooDeclaration, fooUse),mark(fmt1, "fmt"),highlight(fmt1, fmtImp, fmt1, fmt2, fmt3, fmt4) -- fmt.Print("yo") //@mark(printSep, "Print"),highlight(printSep, printSep, print1, print2),mark(fmt2, "fmt"),highlight(fmt2, fmtImp, fmt1, fmt2, fmt3, fmt4) +-func Random() int { +- y := 6 + 7 +- return y -} - --func (x *F) Inc() { //@mark(xRightDecl, "x"),mark(xLeftDecl, " *"),highlight(xRightDecl, xRightDecl, xUse),highlight(xLeftDecl, xRightDecl, xUse) -- x.bar++ //@mark(xUse, "x"),mark(bar3, "bar"),highlight(xUse, xRightDecl, xUse),highlight(bar3, barDeclaration, bar1, bar2, bar3) +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --func testFunctions() { -- fmt.Print("main start") //@mark(print1, "Print"),highlight(print1, printSep, print1, print2),mark(fmt3, "fmt"),highlight(fmt3, fmtImp, fmt1, fmt2, fmt3, fmt4) -- fmt.Print("ok") //@mark(print2, "Print"),highlight(print2, printSep, print1, print2),mark(fmt4, "fmt"),highlight(fmt4, fmtImp, fmt1, fmt2, fmt3, fmt4) -- Print() //@mark(printTest, "Print"),highlight(printTest, printFunc, printTest) +-type Pos struct { +- x, y int -} - --func toProtocolHighlight(rngs []int) []DocumentHighlight { //@mark(doc1, "DocumentHighlight"),mark(docRet1, "[]DocumentHighlight"),highlight(doc1, docRet1, doc1, doc2, doc3, result) -- result := make([]DocumentHighlight, 0, len(rngs)) //@mark(doc2, "DocumentHighlight"),highlight(doc2, doc1, doc2, doc3) -- for _, rng := range rngs { -- result = append(result, DocumentHighlight{ //@mark(doc3, "DocumentHighlight"),highlight(doc3, doc1, doc2, doc3) -- Range: rng, -- }) -- } -- return result //@mark(result, "result") +-func (p *Pos) GetSum() int { +- return p.x + p.y //@rename("x", "myX") -} - --func testForLoops() { -- for i := 0; i < 10; i++ { //@mark(forDecl1, "for"),highlight(forDecl1, forDecl1, brk1, cont1) -- if i > 8 { -- break //@mark(brk1, "break"),highlight(brk1, forDecl1, brk1, cont1) -- } -- if i < 2 { -- for j := 1; j < 10; j++ { //@mark(forDecl2, "for"),highlight(forDecl2, forDecl2, cont2) -- if j < 3 { -- for k := 1; k < 10; k++ { //@mark(forDecl3, "for"),highlight(forDecl3, forDecl3, cont3) -- if k < 3 { -- continue //@mark(cont3, "continue"),highlight(cont3, forDecl3, cont3) -- } -- } -- continue //@mark(cont2, "continue"),highlight(cont2, forDecl2, cont2) -- } -- } -- continue //@mark(cont1, "continue"),highlight(cont1, forDecl1, brk1, cont1) -- } -- } +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.GetSum() //@rename("Sum", "GetSum") +-} - -- arr := []int{} -- for i := range arr { //@mark(forDecl4, "for"),highlight(forDecl4, forDecl4, brk4, cont4) -- if i > 8 { -- break //@mark(brk4, "break"),highlight(brk4, forDecl4, brk4, cont4) -- } -- if i < 4 { -- continue //@mark(cont4, "continue"),highlight(cont4, forDecl4, brk4, cont4) -- } -- } +-func sw() { +- var x interface{} - --Outer: -- for i := 0; i < 10; i++ { //@mark(forDecl5, "for"),highlight(forDecl5, forDecl5, brk5, brk6, brk8) -- break //@mark(brk5, "break"),highlight(brk5, forDecl5, brk5, brk6, brk8) -- for { //@mark(forDecl6, "for"),highlight(forDecl6, forDecl6, cont5) -- if i == 1 { -- break Outer //@mark(brk6, "break Outer"),highlight(brk6, forDecl5, brk5, brk6, brk8) -- } -- switch i { //@mark(switch1, "switch"),highlight(switch1, switch1, brk7) -- case 5: -- break //@mark(brk7, "break"),highlight(brk7, switch1, brk7) -- case 6: -- continue //@mark(cont5, "continue"),highlight(cont5, forDecl6, cont5) -- case 7: -- break Outer //@mark(brk8, "break Outer"),highlight(brk8, forDecl5, brk5, brk6, brk8) -- } -- } +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") - } -} - --func testSwitch() { -- var i, j int +--- f2name-rename -- +-package a - --L1: -- for { //@mark(forDecl7, "for"),highlight(forDecl7, forDecl7, brk10, cont6) -- L2: -- switch i { //@mark(switch2, "switch"),highlight(switch2, switch2, brk11, brk12, brk13) -- case 1: -- switch j { //@mark(switch3, "switch"),highlight(switch3, switch3, brk9) -- case 1: -- break //@mark(brk9, "break"),highlight(brk9, switch3, brk9) -- case 2: -- break L1 //@mark(brk10, "break L1"),highlight(brk10, forDecl7, brk10, cont6) -- case 3: -- break L2 //@mark(brk11, "break L2"),highlight(brk11, switch2, brk11, brk12, brk13) -- default: -- continue //@mark(cont6, "continue"),highlight(cont6, forDecl7, brk10, cont6) -- } -- case 2: -- break //@mark(brk12, "break"),highlight(brk12, switch2, brk11, brk12, brk13) -- default: -- break L2 //@mark(brk13, "break L2"),highlight(brk13, switch2, brk11, brk12, brk13) -- } -- } --} +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2name "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --func testReturn() bool { //@mark(func1, "func"),mark(bool1, "bool"),highlight(func1, func1, fullRet11, fullRet12),highlight(bool1, bool1, false1, bool2, true1) -- if 1 < 2 { -- return false //@mark(ret11, "return"),mark(fullRet11, "return false"),mark(false1, "false"),highlight(ret11, func1, fullRet11, fullRet12) -- } -- candidates := []int{} -- sort.SliceStable(candidates, func(i, j int) bool { //@mark(func2, "func"),mark(bool2, "bool"),highlight(func2, func2, fullRet2) -- return candidates[i] > candidates[j] //@mark(ret2, "return"),mark(fullRet2, "return candidates[i] > candidates[j]"),highlight(ret2, func2, fullRet2) -- }) -- return true //@mark(ret12, "return"),mark(fullRet12, "return true"),mark(true1, "true"),highlight(ret12, func1, fullRet11, fullRet12) +-func Random() int { +- y := 6 + 7 +- return y -} - --func testReturnFields() float64 { //@mark(retVal1, "float64"),highlight(retVal1, retVal1, retVal11, retVal21) -- if 1 < 2 { -- return 20.1 //@mark(retVal11, "20.1"),highlight(retVal11, retVal1, retVal11, retVal21) -- } -- z := 4.3 //@mark(zDecl, "z") -- return z //@mark(retVal21, "z"),highlight(retVal21, retVal1, retVal11, zDecl, retVal21) +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --func testReturnMultipleFields() (float32, string) { //@mark(retVal31, "float32"),mark(retVal32, "string"),highlight(retVal31, retVal31, retVal41, retVal51),highlight(retVal32, retVal32, retVal42, retVal52) -- y := "im a var" //@mark(yDecl, "y"), -- if 1 < 2 { -- return 20.1, y //@mark(retVal41, "20.1"),mark(retVal42, "y"),highlight(retVal41, retVal31, retVal41, retVal51),highlight(retVal42, retVal32, yDecl, retVal42, retVal52) -- } -- return 4.9, "test" //@mark(retVal51, "4.9"),mark(retVal52, "\"test\""),highlight(retVal51, retVal31, retVal41, retVal51),highlight(retVal52, retVal32, retVal42, retVal52) +-type Pos struct { +- x, y int -} - --func testReturnFunc() int32 { //@mark(retCall, "int32") -- mulch := 1 //@mark(mulchDec, "mulch"),highlight(mulchDec, mulchDec, mulchRet) -- return int32(mulch) //@mark(mulchRet, "mulch"),mark(retFunc, "int32"),mark(retTotal, "int32(mulch)"),highlight(mulchRet, mulchDec, mulchRet),highlight(retFunc, retCall, retFunc, retTotal) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") -} -diff -urN a/gopls/internal/lsp/testdata/implementation/implementation_generics.go b/gopls/internal/lsp/testdata/implementation/implementation_generics.go ---- a/gopls/internal/lsp/testdata/implementation/implementation_generics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/implementation/implementation_generics.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ --//go:build go1.18 --// +build go1.18 - --package implementation -- --// -- generics -- -- --type GenIface[T any] interface { //@mark(GenIface, "GenIface"),implementations("GenIface", GC) -- F(int, string, T) //@mark(GenIfaceF, "F"),implementations("F", GCF) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --type GenConc[U any] int //@mark(GenConc, "GenConc"),implementations("GenConc", GI) -- --func (GenConc[V]) F(int, string, V) {} //@mark(GenConcF, "F"),implementations("F", GIF) +-func sw() { +- var x interface{} - --type GenConcString struct{ GenConc[string] } //@mark(GenConcString, "GenConcString"),implementations(GenConcString, GIString) -diff -urN a/gopls/internal/lsp/testdata/implementation/implementation.go b/gopls/internal/lsp/testdata/implementation/implementation.go ---- a/gopls/internal/lsp/testdata/implementation/implementation.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/implementation/implementation.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,37 +0,0 @@ --package implementation +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2name.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - --import "golang.org/lsptests/implementation/other" +--- f2y-rename -- +-package a - --type ImpP struct{} //@ImpP,implementations("ImpP", Laugher, OtherLaugher) +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2y "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --func (*ImpP) Laugh() { //@mark(LaughP, "Laugh"),implementations("Laugh", Laugh, OtherLaugh) +-func Random() int { +- y := 6 + 7 +- return y -} - --type ImpS struct{} //@ImpS,implementations("ImpS", Laugher, OtherLaugher) -- --func (ImpS) Laugh() { //@mark(LaughS, "Laugh"),implementations("Laugh", Laugh, OtherLaugh) +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --type Laugher interface { //@Laugher,implementations("Laugher", ImpP, OtherImpP, ImpS, OtherImpS, embedsImpP) -- Laugh() //@Laugh,implementations("Laugh", LaughP, OtherLaughP, LaughS, OtherLaughS) +-type Pos struct { +- x, y int -} - --type Foo struct { //@implementations("Foo", Joker) -- other.Foo +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") -} - --type Joker interface { //@Joker -- Joke() //@Joke,implementations("Joke", ImpJoker) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --type cryer int //@implementations("cryer", Cryer) +-func sw() { +- var x interface{} - --func (cryer) Cry(other.CryType) {} //@mark(CryImpl, "Cry"),implementations("Cry", Cry) +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2y.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - --type Empty interface{} //@implementations("Empty") +--- fmt2-rename -- +-package a - --var _ interface{ Joke() } //@implementations("Joke", ImpJoker) +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- fmt2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --type embedsImpP struct { //@embedsImpP -- ImpP //@implementations("ImpP", Laugher, OtherLaugher) +-func Random() int { +- y := 6 + 7 +- return y -} -diff -urN a/gopls/internal/lsp/testdata/implementation/other/other_generics.go b/gopls/internal/lsp/testdata/implementation/other/other_generics.go ---- a/gopls/internal/lsp/testdata/implementation/other/other_generics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/implementation/other/other_generics.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ --//go:build go1.18 --// +build go1.18 - --package other +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --// -- generics (limited support) -- +-type Pos struct { +- x, y int +-} - --type GI[T any] interface { //@mark(GI, "GI"),implementations("GI", GenConc) -- F(int, string, T) //@mark(GIF, "F"),implementations("F", GenConcF) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") -} - --type GIString GI[string] //@mark(GIString, "GIString"),implementations("GIString", GenConcString) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") +-} - --type GC[U any] int //@mark(GC, "GC"),implementations("GC", GenIface) +-func sw() { +- var x interface{} - --func (GC[V]) F(int, string, V) {} //@mark(GCF, "F"),implementations("F", GenIfaceF) -diff -urN a/gopls/internal/lsp/testdata/implementation/other/other.go b/gopls/internal/lsp/testdata/implementation/other/other.go ---- a/gopls/internal/lsp/testdata/implementation/other/other.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/implementation/other/other.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package other +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- fmt2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - --type ImpP struct{} //@mark(OtherImpP, "ImpP") +--- fmty-rename -- +-package a - --func (*ImpP) Laugh() { //@mark(OtherLaughP, "Laugh") --} +-import ( +- lg "log" +- fmty "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --type ImpS struct{} //@mark(OtherImpS, "ImpS") +-func Random() int { +- y := 6 + 7 +- return y +-} - --func (ImpS) Laugh() { //@mark(OtherLaughS, "Laugh") +-func Random2(y int) int { //@rename("y", "z") +- return y -} - --type ImpI interface { //@mark(OtherLaugher, "ImpI") -- Laugh() //@mark(OtherLaugh, "Laugh") +-type Pos struct { +- x, y int -} - --type Foo struct { //@implementations("Foo", Joker) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") -} - --func (Foo) Joke() { //@mark(ImpJoker, "Joke"),implementations("Joke", Joke) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - --type CryType int +-func sw() { +- var x interface{} - --type Cryer interface { //@Cryer -- Cry(CryType) //@Cry,implementations("Cry", CryImpl) +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmty.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } -} -diff -urN a/gopls/internal/lsp/testdata/implementation/other/other_test.go b/gopls/internal/lsp/testdata/implementation/other/other_test.go ---- a/gopls/internal/lsp/testdata/implementation/other/other_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/implementation/other/other_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package other +- +--- format-rename -- +-package a - -import ( -- "testing" +- lg "log" +- format "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --// This exists so the other.test package comes into existence. -- --func TestOther(t *testing.T) { +-func Random() int { +- y := 6 + 7 +- return y -} -diff -urN a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in ---- a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,42 +0,0 @@ --package importedcomplit - --import ( -- "golang.org/lsptests/foo" +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - -- // import completions -- "fm" //@complete("\" //", fmtImport) -- "go/pars" //@complete("\" //", parserImport) -- "golang.org/lsptests/signa" //@complete("na\" //", signatureImport) -- "golang.org/lspte" //@complete("\" //", lsptestsImport) -- "crypto/elli" //@complete("\" //", cryptoImport) -- "golang.org/lsptests/sign" //@complete("\" //", signatureImport) -- "golang.org/lsptests/sign" //@complete("ests", lsptestsImport) -- namedParser "go/pars" //@complete("\" //", parserImport) --) +-type Pos struct { +- x, y int +-} - --func _() { -- var V int //@item(icVVar, "V", "int", "var") -- _ = foo.StructFoo{V} //@complete("}", Value, icVVar) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") -} - -func _() { -- var ( -- aa string //@item(icAAVar, "aa", "string", "var") -- ab int //@item(icABVar, "ab", "int", "var") -- ) +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") +-} - -- _ = foo.StructFoo{a} //@complete("}", abVar, aaVar) +-func sw() { +- var x interface{} - -- var s struct { -- AA string //@item(icFieldAA, "AA", "string", "field") -- AB int //@item(icFieldAB, "AB", "int", "field") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- format.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") - } -- -- _ = foo.StructFoo{s.} //@complete("}", icFieldAB, icFieldAA) -} - --/* "fmt" */ //@item(fmtImport, "fmt", "\"fmt\"", "package") --/* "go/parser" */ //@item(parserImport, "parser", "\"go/parser\"", "package") --/* "golang.org/lsptests/signature" */ //@item(signatureImport, "signature", "\"golang.org/lsptests/signature\"", "package") --/* "golang.org/lsptests/" */ //@item(lsptestsImport, "lsptests/", "\"golang.org/lsptests/\"", "package") --/* "crypto/elliptic" */ //@item(cryptoImport, "elliptic", "\"crypto/elliptic\"", "package") -diff -urN a/gopls/internal/lsp/testdata/imports/add_import.go.golden b/gopls/internal/lsp/testdata/imports/add_import.go.golden ---- a/gopls/internal/lsp/testdata/imports/add_import.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/add_import.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- goimports -- --package imports //@import("package") +--- log-rename -- +-package a - -import ( -- "bytes" -- "fmt" +- "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --func _() { -- fmt.Println("") -- bytes.NewBuffer(nil) +-func Random() int { +- y := 6 + 7 +- return y +-} +- +-func Random2(y int) int { //@rename("y", "z") +- return y +-} +- +-type Pos struct { +- x, y int -} - -diff -urN a/gopls/internal/lsp/testdata/imports/add_import.go.in b/gopls/internal/lsp/testdata/imports/add_import.go.in ---- a/gopls/internal/lsp/testdata/imports/add_import.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/add_import.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package imports //@import("package") -- --import ( -- "fmt" --) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - -func _() { -- fmt.Println("") -- bytes.NewBuffer(nil) +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} -diff -urN a/gopls/internal/lsp/testdata/imports/good_imports.go.golden b/gopls/internal/lsp/testdata/imports/good_imports.go.golden ---- a/gopls/internal/lsp/testdata/imports/good_imports.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/good_imports.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ ---- goimports -- --package imports //@import("package") - --import "fmt" +-func sw() { +- var x interface{} - --func _() { --fmt.Println("") +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- log.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } -} - -diff -urN a/gopls/internal/lsp/testdata/imports/good_imports.go.in b/gopls/internal/lsp/testdata/imports/good_imports.go.in ---- a/gopls/internal/lsp/testdata/imports/good_imports.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/good_imports.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package imports //@import("package") +--- myX-rename -- +-package a - --import "fmt" +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - --func _() { --fmt.Println("") +-func Random() int { +- y := 6 + 7 +- return y -} -diff -urN a/gopls/internal/lsp/testdata/imports/issue35458.go.golden b/gopls/internal/lsp/testdata/imports/issue35458.go.golden ---- a/gopls/internal/lsp/testdata/imports/issue35458.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/issue35458.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ ---- goimports -- --// package doc --package imports //@import("package") -- -- - +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - +-type Pos struct { +- myX, y int +-} - +-func (p *Pos) Sum() int { +- return p.myX + p.y //@rename("x", "myX") +-} - -func _() { -- println("Hello, world!") +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - +-func sw() { +- var x interface{} - +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - +--- pos-rename -- +-package a - +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - +-func Random() int { +- y := 6 + 7 +- return y +-} - +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - +-type Pos struct { +- x, y int +-} - -diff -urN a/gopls/internal/lsp/testdata/imports/issue35458.go.in b/gopls/internal/lsp/testdata/imports/issue35458.go.in ---- a/gopls/internal/lsp/testdata/imports/issue35458.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/issue35458.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,23 +0,0 @@ -- +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - +-func _() { +- var pos Pos //@rename("p", "pos") +- _ = pos.Sum() //@rename("Sum", "GetSum") +-} - +-func sw() { +- var x interface{} - +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - --// package doc --package imports //@import("package") +--- y0-rename -- +-package a - +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - +-func Random() int { +- y := 6 + 7 +- return y +-} - +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - +-type Pos struct { +- x, y int +-} - +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - -func _() { -- println("Hello, world!") +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - +-func sw() { +- var x interface{} - +- switch y0 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y0) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y0) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y0) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - +--- y1-rename -- +-package a - +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - +-func Random() int { +- y := 6 + 7 +- return y +-} - +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - -diff -urN a/gopls/internal/lsp/testdata/imports/multiple_blocks.go.golden b/gopls/internal/lsp/testdata/imports/multiple_blocks.go.golden ---- a/gopls/internal/lsp/testdata/imports/multiple_blocks.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/multiple_blocks.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ ---- goimports -- --package imports //@import("package") +-type Pos struct { +- x, y int +-} - --import "fmt" +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - -func _() { -- fmt.Println("") +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - -diff -urN a/gopls/internal/lsp/testdata/imports/multiple_blocks.go.in b/gopls/internal/lsp/testdata/imports/multiple_blocks.go.in ---- a/gopls/internal/lsp/testdata/imports/multiple_blocks.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/multiple_blocks.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package imports //@import("package") -- --import "fmt" -- --import "bytes" +-func sw() { +- var x interface{} - --func _() { -- fmt.Println("") +- switch y1 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y1) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y1) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y1) //@rename("y", "y3"),rename("f2","fmt2") +- } -} -diff -urN a/gopls/internal/lsp/testdata/imports/needs_imports.go.golden b/gopls/internal/lsp/testdata/imports/needs_imports.go.golden ---- a/gopls/internal/lsp/testdata/imports/needs_imports.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/needs_imports.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- goimports -- --package imports //@import("package") +- +--- y2-rename -- +-package a - -import ( -- "fmt" -- "log" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --func goodbye() { -- fmt.Printf("HI") -- log.Printf("byeeeee") +-func Random() int { +- y := 6 + 7 +- return y -} - -diff -urN a/gopls/internal/lsp/testdata/imports/needs_imports.go.in b/gopls/internal/lsp/testdata/imports/needs_imports.go.in ---- a/gopls/internal/lsp/testdata/imports/needs_imports.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/needs_imports.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package imports //@import("package") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --func goodbye() { -- fmt.Printf("HI") -- log.Printf("byeeeee") +-type Pos struct { +- x, y int -} -diff -urN a/gopls/internal/lsp/testdata/imports/remove_import.go.golden b/gopls/internal/lsp/testdata/imports/remove_import.go.golden ---- a/gopls/internal/lsp/testdata/imports/remove_import.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/remove_import.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ ---- goimports -- --package imports //@import("package") - --import ( -- "fmt" --) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - -func _() { -- fmt.Println("") +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - -diff -urN a/gopls/internal/lsp/testdata/imports/remove_import.go.in b/gopls/internal/lsp/testdata/imports/remove_import.go.in ---- a/gopls/internal/lsp/testdata/imports/remove_import.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/remove_import.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package imports //@import("package") +-func sw() { +- var x interface{} +- +- switch y2 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y2) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y2) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y2) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} +- +--- y3-rename -- +-package a - -import ( -- "bytes" -- "fmt" +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --func _() { -- fmt.Println("") +-func Random() int { +- y := 6 + 7 +- return y -} -diff -urN a/gopls/internal/lsp/testdata/imports/remove_imports.go.golden b/gopls/internal/lsp/testdata/imports/remove_imports.go.golden ---- a/gopls/internal/lsp/testdata/imports/remove_imports.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/remove_imports.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ ---- goimports -- --package imports //@import("package") - --func _() { +-func Random2(y int) int { //@rename("y", "z") +- return y -} - -diff -urN a/gopls/internal/lsp/testdata/imports/remove_imports.go.in b/gopls/internal/lsp/testdata/imports/remove_imports.go.in ---- a/gopls/internal/lsp/testdata/imports/remove_imports.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/remove_imports.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package imports //@import("package") +-type Pos struct { +- x, y int +-} - --import ( -- "bytes" -- "fmt" --) +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - -func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} -diff -urN a/gopls/internal/lsp/testdata/imports/two_lines.go.golden b/gopls/internal/lsp/testdata/imports/two_lines.go.golden ---- a/gopls/internal/lsp/testdata/imports/two_lines.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/two_lines.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,4 +0,0 @@ ---- goimports -- --package main --func main() {} //@import("main") -- -diff -urN a/gopls/internal/lsp/testdata/imports/two_lines.go.in b/gopls/internal/lsp/testdata/imports/two_lines.go.in ---- a/gopls/internal/lsp/testdata/imports/two_lines.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/imports/two_lines.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,2 +0,0 @@ --package main --func main() {} //@import("main") -diff -urN a/gopls/internal/lsp/testdata/index/index.go b/gopls/internal/lsp/testdata/index/index.go ---- a/gopls/internal/lsp/testdata/index/index.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/index/index.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,25 +0,0 @@ --package index - --func _() { -- var ( -- aa = "123" //@item(indexAA, "aa", "string", "var") -- ab = 123 //@item(indexAB, "ab", "int", "var") -- ) +-func sw() { +- var x interface{} - -- var foo [1]int -- foo[a] //@complete("]", indexAB, indexAA) -- foo[:a] //@complete("]", indexAB, indexAA) -- a[:a] //@complete("[", indexAA, indexAB) -- a[a] //@complete("[", indexAA, indexAB) +- switch y3 := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y3) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y3) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y3) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - -- var bar map[string]int -- bar[a] //@complete("]", indexAA, indexAB) +--- z-rename -- +-package a - -- type myMap map[string]int -- var baz myMap -- baz[a] //@complete("]", indexAA, indexAB) +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +-) - -- type myInt int -- var mi myInt //@item(indexMyInt, "mi", "myInt", "var") -- foo[m] //@snippet("]", indexMyInt, "mi", "mi") +-func Random() int { +- y := 6 + 7 +- return y -} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go ---- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package inlayHint //@inlayHint("package") -- --import "fmt" - --func fieldNames() { -- for _, c := range []struct { -- in, want string -- }{ -- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- {"Hello, 世界", "界世 ,olleH"}, -- {"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +-func Random2(z int) int { //@rename("y", "z") +- return z -} - --func fieldNamesPointers() { -- for _, c := range []*struct { -- in, want string -- }{ -- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- {"Hello, 世界", "界世 ,olleH"}, -- {"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +-type Pos struct { +- x, y int -} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/composite_literals.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") -- --import "fmt" - --func fieldNames() { -- for _< int>, c< struct{in string; want string}> := range []struct { -- in, want string -- }{ -- struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- {"Hello, 世界", "界世 ,olleH"}, -- {"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") -} - --func fieldNamesPointers() { -- for _< int>, c< *struct{in string; want string}> := range []*struct { -- in, want string -- }{ -- &struct{ in, want string }{"Hello, world", "dlrow ,olleH"}, -- <&struct{in string; want string}>{"Hello, 世界", "界世 ,olleH"}, -- <&struct{in string; want string}>{"", ""}, -- } { -- fmt.Println(c.in == c.want) -- } +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") -} - -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go ---- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,45 +0,0 @@ --package inlayHint //@inlayHint("package") -- --const True = true -- --type Kind int +-func sw() { +- var x interface{} - --const ( -- KindNone Kind = iota -- KindPrint -- KindPrintf -- KindErrorf --) +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} - --const ( -- u = iota * 4 -- v float64 = iota * 42 -- w = iota * 42 --) +diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.in b/gopls/internal/lsp/testdata/rename/a/random.go.in +--- a/gopls/internal/lsp/testdata/rename/a/random.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/a/random.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-package a - --const ( -- a, b = 1, 2 -- c, d -- e, f = 5 * 5, "hello" + "world" -- g, h -- i, j = true, f +-import ( +- lg "log" +- "fmt" //@rename("fmt", "fmty") +- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") -) - --// No hint --const ( -- Int = 3 -- Float = 3.14 -- Bool = true -- Rune = '3' -- Complex = 2.7i -- String = "Hello, world!" --) +-func Random() int { +- y := 6 + 7 +- return y +-} - --var ( -- varInt = 3 -- varFloat = 3.14 -- varBool = true -- varRune = '3' + '4' -- varComplex = 2.7i -- varString = "Hello, world!" --) -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/constant_values.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,47 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") +-func Random2(y int) int { //@rename("y", "z") +- return y +-} - --const True = true +-type Pos struct { +- x, y int +-} - --type Kind int +-func (p *Pos) Sum() int { +- return p.x + p.y //@rename("x", "myX") +-} - --const ( -- KindNone Kind = iota< = 0> -- KindPrint< = 1> -- KindPrintf< = 2> -- KindErrorf< = 3> --) +-func _() { +- var p Pos //@rename("p", "pos") +- _ = p.Sum() //@rename("Sum", "GetSum") +-} - --const ( -- u = iota * 4< = 0> -- v float64 = iota * 42< = 42> -- w = iota * 42< = 84> --) +-func sw() { +- var x interface{} - --const ( -- a, b = 1, 2 -- c, d< = 1, 2> -- e, f = 5 * 5, "hello" + "world"< = 25, "helloworld"> -- g, h< = 25, "helloworld"> -- i, j = true, f< = true, "helloworld"> --) +- switch y := x.(type) { //@rename("y", "y0") +- case int: +- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") +- case string: +- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") +- default: +- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- } +-} +diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go b/gopls/internal/lsp/testdata/rename/b/b.go +--- a/gopls/internal/lsp/testdata/rename/b/b.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/b/b.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package b - --// No hint --const ( -- Int = 3 -- Float = 3.14 -- Bool = true -- Rune = '3' -- Complex = 2.7i -- String = "Hello, world!" --) +-var c int //@rename("int", "uint") - --var ( -- varInt = 3 -- varFloat = 3.14 -- varBool = true -- varRune = '3' + '4' -- varComplex = 2.7i -- varString = "Hello, world!" +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a +-} +- +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") -) - -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go ---- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,50 +0,0 @@ --package inlayHint //@inlayHint("package") +-/* +-Hello description +-*/ +-func Hello() {} //@rename("Hello", "Goodbye") +diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go.golden b/gopls/internal/lsp/testdata/rename/b/b.go.golden +--- a/gopls/internal/lsp/testdata/rename/b/b.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/b/b.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,78 +0,0 @@ +--- Bob-rename -- +-package b - --import "fmt" +-var c int //@rename("int", "uint") - --func hello(name string) string { -- return "Hello " + name +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a -} - --func helloWorld() string { -- return hello("World") --} +-var ( +- // Hello there. +- // Bob does the thing. +- Bob int //@rename("Foo", "Bob") +-) - --type foo struct{} +-/* +-Hello description +-*/ +-func Hello() {} //@rename("Hello", "Goodbye") - --func (*foo) bar(baz string, qux int) int { -- if baz != "" { -- return qux + 1 -- } -- return qux --} +--- Goodbye-rename -- +-b.go: +-package b - --func kase(foo int, bar bool, baz ...string) { -- fmt.Println(foo, bar, baz) --} +-var c int //@rename("int", "uint") - --func kipp(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a -} - --func plex(foo, bar string, baz string) { -- fmt.Println(foo, bar, baz) --} +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") +-) - --func tars(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) --} +-/* +-Goodbye description +-*/ +-func Goodbye() {} //@rename("Hello", "Goodbye") - --func foobar() { -- var x foo -- x.bar("", 1) -- kase(0, true, "c", "d", "e") -- kipp("a", "b", "c") -- plex("a", "b", "c") -- tars("a", "b", "c") -- foo, bar, baz := "a", "b", "c" -- kipp(foo, bar, baz) -- plex("a", bar, baz) -- tars(foo+foo, (bar), "c") +-c.go: +-package c - +-import "golang.org/lsptests/rename/b" +- +-func _() { +- b.Goodbye() //@rename("Hello", "Goodbye") -} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/parameter_names.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,52 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") - --import "fmt" +--- error-rename -- +-package b - --func hello(name string) string { -- return "Hello " + name --} +-var c int //@rename("int", "uint") - --func helloWorld() string { -- return hello("World") +-func _() { +- error := 1 //@rename("a", "error") +- error = 2 +- _ = error -} - --type foo struct{} +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") +-) - --func (*foo) bar(baz string, qux int) int { -- if baz != "" { -- return qux + 1 -- } -- return qux --} +-/* +-Hello description +-*/ +-func Hello() {} //@rename("Hello", "Goodbye") - --func kase(foo int, bar bool, baz ...string) { -- fmt.Println(foo, bar, baz) --} +--- uint-rename -- +-int is built in and cannot be renamed +diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden +--- a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2 +0,0 @@ +--- rFunc-rename -- +-renaming "sFunc" to "rFunc" not possible because "golang.org/lsptests/rename/bad" has errors +diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.in b/gopls/internal/lsp/testdata/rename/bad/bad.go.in +--- a/gopls/internal/lsp/testdata/rename/bad/bad.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package bad - --func kipp(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) +-type myStruct struct { -} - --func plex(foo, bar string, baz string) { -- fmt.Println(foo, bar, baz) +-func (s *myStruct) sFunc() bool { //@rename("sFunc", "rFunc") +- return s.Bad -} +diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in +--- a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1 +0,0 @@ +-package bad +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go b/gopls/internal/lsp/testdata/rename/c/c2.go +--- a/gopls/internal/lsp/testdata/rename/c/c2.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c2.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,4 +0,0 @@ +-package c - --func tars(foo string, bar, baz string) { -- fmt.Println(foo, bar, baz) --} +-//go:embed Static/* +-var Static embed.FS //@rename("Static", "static") +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go.golden b/gopls/internal/lsp/testdata/rename/c/c2.go.golden +--- a/gopls/internal/lsp/testdata/rename/c/c2.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c2.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +--- static-rename -- +-package c - --func foobar() { -- var x foo -- x.bar("", 1) -- kase(0, true, "c", "d", "e") -- kipp("a", "b", "c") -- plex("a", "b", "c") -- tars("a", "b", "c") -- foo< string>, bar< string>, baz< string> := "a", "b", "c" -- kipp(foo, bar, baz) -- plex("a", bar, baz) -- tars(foo+foo, (bar), "c") +-//go:embed Static/* +-var static embed.FS //@rename("Static", "static") +diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go b/gopls/internal/lsp/testdata/rename/c/c.go +--- a/gopls/internal/lsp/testdata/rename/c/c.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package c +- +-import "golang.org/lsptests/rename/b" - +-func _() { +- b.Hello() //@rename("Hello", "Goodbye") -} +diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go.golden b/gopls/internal/lsp/testdata/rename/c/c.go.golden +--- a/gopls/internal/lsp/testdata/rename/c/c.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/c/c.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,32 +0,0 @@ +--- Goodbye-rename -- +-b.go: +-package b - -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go b/gopls/internal/lsp/testdata/inlay_hint/type_params.go ---- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,45 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-var c int //@rename("int", "uint") - --package inlayHint //@inlayHint("package") +-func _() { +- a := 1 //@rename("a", "error") +- a = 2 +- _ = a +-} - --func main() { -- ints := map[string]int64{ -- "first": 34, -- "second": 12, -- } +-var ( +- // Hello there. +- // Foo does the thing. +- Foo int //@rename("Foo", "Bob") +-) - -- floats := map[string]float64{ -- "first": 35.98, -- "second": 26.99, -- } +-/* +-Goodbye description +-*/ +-func Goodbye() {} //@rename("Hello", "Goodbye") - -- SumIntsOrFloats[string, int64](ints) -- SumIntsOrFloats[string, float64](floats) +-c.go: +-package c - -- SumIntsOrFloats(ints) -- SumIntsOrFloats(floats) +-import "golang.org/lsptests/rename/b" - -- SumNumbers(ints) -- SumNumbers(floats) +-func _() { +- b.Goodbye() //@rename("Hello", "Goodbye") -} - --type Number interface { -- int64 | float64 --} +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go +--- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package another - --func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { -- var s V -- for _, v := range m { -- s += v -- } -- return s --} +-type ( +- I interface{ F() } +- C struct{ I } +-) - --func SumNumbers[K comparable, V Number](m map[K]V) V { -- var s V -- for _, v := range m { -- s += v -- } -- return s +-func (C) g() +- +-func _() { +- var x I = C{} +- x.F() //@rename("F", "G") -} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/type_params.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,47 +0,0 @@ ---- inlayHint -- --//go:build go1.18 --// +build go1.18 +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden +--- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +--- G-rename -- +-package another - --package inlayHint //@inlayHint("package") +-type ( +- I interface{ G() } +- C struct{ I } +-) - --func main() { -- ints< map[string]int64> := map[string]int64{ -- "first": 34, -- "second": 12, -- } +-func (C) g() - -- floats< map[string]float64> := map[string]float64{ -- "first": 35.98, -- "second": 26.99, -- } +-func _() { +- var x I = C{} +- x.G() //@rename("F", "G") +-} - -- SumIntsOrFloats[string, int64](ints) -- SumIntsOrFloats[string, float64](floats) +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go +--- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package crosspkg - -- SumIntsOrFloats<[string, int64]>(ints) -- SumIntsOrFloats<[string, float64]>(floats) +-func Foo() { //@rename("Foo", "Dolphin") - -- SumNumbers<[string, int64]>(ints) -- SumNumbers<[string, float64]>(floats) -} - --type Number interface { -- int64 | float64 --} +-var Bar int //@rename("Bar", "Tomato") +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden +--- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,40 +0,0 @@ +--- Dolphin-rename -- +-crosspkg.go: +-package crosspkg - --func SumIntsOrFloats[K comparable, V int64 | float64](m map[K]V) V { -- var s V -- for _< K>, v< V> := range m { -- s += v -- } -- return s --} +-func Dolphin() { //@rename("Foo", "Dolphin") - --func SumNumbers[K comparable, V Number](m map[K]V) V { -- var s V -- for _< K>, v< V> := range m { -- s += v -- } -- return s -} - -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go ---- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ --package inlayHint //@inlayHint("package") +-var Bar int //@rename("Bar", "Tomato") - --func assignTypes() { -- i, j := 0, len([]string{})-1 -- println(i, j) --} +-other.go: +-package other - --func rangeTypes() { -- for k, v := range []string{} { -- println(k, v) -- } --} +-import "golang.org/lsptests/rename/crosspkg" - --func funcLitType() { -- myFunc := func(a string) string { return "" } +-func Other() { +- crosspkg.Bar +- crosspkg.Dolphin() //@rename("Foo", "Flamingo") -} - --func compositeLitType() { -- foo := map[string]interface{}{"": ""} --} -diff -urN a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden ---- a/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/inlay_hint/variable_types.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ ---- inlayHint -- --package inlayHint //@inlayHint("package") +--- Tomato-rename -- +-crosspkg.go: +-package crosspkg - --func assignTypes() { -- i< int>, j< int> := 0, len([]string{})-1 -- println(i, j) --} +-func Foo() { //@rename("Foo", "Dolphin") - --func rangeTypes() { -- for k< int>, v< string> := range []string{} { -- println(k, v) -- } -} - --func funcLitType() { -- myFunc< func(a string) string> := func(a string) string { return "" } --} +-var Tomato int //@rename("Bar", "Tomato") - --func compositeLitType() { -- foo< map[string]interface{}> := map[string]interface{}{"": ""} --} +-other.go: +-package other - -diff -urN a/gopls/internal/lsp/testdata/interfacerank/interface_rank.go b/gopls/internal/lsp/testdata/interfacerank/interface_rank.go ---- a/gopls/internal/lsp/testdata/interfacerank/interface_rank.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/interfacerank/interface_rank.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,23 +0,0 @@ --package interfacerank +-import "golang.org/lsptests/rename/crosspkg" - --type foo interface { -- foo() +-func Other() { +- crosspkg.Tomato +- crosspkg.Foo() //@rename("Foo", "Flamingo") -} - --type fooImpl int -- --func (*fooImpl) foo() {} -- --func wantsFoo(foo) {} -- --func _() { -- var ( -- aa string //@item(irAA, "aa", "string", "var") -- ab *fooImpl //@item(irAB, "ab", "*fooImpl", "var") -- ) +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go +--- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package other - -- wantsFoo(a) //@complete(")", irAB, irAA) +-import "golang.org/lsptests/rename/crosspkg" - -- var ac fooImpl //@item(irAC, "ac", "fooImpl", "var") -- wantsFoo(&a) //@complete(")", irAC, irAA, irAB) +-func Other() { +- crosspkg.Bar +- crosspkg.Foo() //@rename("Foo", "Flamingo") -} -diff -urN a/gopls/internal/lsp/testdata/issues/issue56505.go b/gopls/internal/lsp/testdata/issues/issue56505.go ---- a/gopls/internal/lsp/testdata/issues/issue56505.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/issues/issue56505.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package issues +diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden +--- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +--- Flamingo-rename -- +-crosspkg.go: +-package crosspkg +- +-func Flamingo() { //@rename("Foo", "Dolphin") - --// Test for golang/go#56505: completion on variables of type *error should not --// panic. --func _() { -- var e *error -- e.x //@complete(" //") -} -diff -urN a/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in b/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in ---- a/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/accidental_keywords.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ --package keywords - --// non-matching candidate - shouldn't show up as completion --var apple = "apple" +-var Bar int //@rename("Bar", "Tomato") - --func _() { -- foo.bar() // insert some extra statements to exercise our AST surgery -- variance := 123 //@item(kwVariance, "variance", "int", "var") -- foo.bar() -- println(var) //@complete(")", kwVariance) --} +-other.go: +-package other - --func _() { -- foo.bar() -- var s struct { variance int } //@item(kwVarianceField, "variance", "int", "field") -- foo.bar() -- s.var //@complete(" //", kwVarianceField) --} +-import "golang.org/lsptests/rename/crosspkg" - --func _() { -- channel := 123 //@item(kwChannel, "channel", "int", "var") -- chan //@complete(" //", kwChannel) -- foo.bar() +-func Other() { +- crosspkg.Bar +- crosspkg.Flamingo() //@rename("Foo", "Flamingo") -} - --func _() { -- foo.bar() -- var typeName string //@item(kwTypeName, "typeName", "string", "var") -- foo.bar() -- type //@complete(" //", kwTypeName) --} -diff -urN a/gopls/internal/lsp/testdata/keywords/empty_select.go b/gopls/internal/lsp/testdata/keywords/empty_select.go ---- a/gopls/internal/lsp/testdata/keywords/empty_select.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/empty_select.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package keywords +diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go b/gopls/internal/lsp/testdata/rename/generics/embedded.go +--- a/gopls/internal/lsp/testdata/rename/generics/embedded.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --func _() { -- select { -- c //@complete(" //", case) -- } --} -diff -urN a/gopls/internal/lsp/testdata/keywords/empty_switch.go b/gopls/internal/lsp/testdata/keywords/empty_switch.go ---- a/gopls/internal/lsp/testdata/keywords/empty_switch.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/empty_switch.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package keywords +-package generics - --func _() { -- switch { -- //@complete("", case, default) -- } +-type foo[P any] int //@rename("foo","bar") - -- switch test.(type) { -- d //@complete(" //", default) -- } --} -diff -urN a/gopls/internal/lsp/testdata/keywords/keywords.go b/gopls/internal/lsp/testdata/keywords/keywords.go ---- a/gopls/internal/lsp/testdata/keywords/keywords.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/keywords/keywords.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,100 +0,0 @@ --package keywords +-var x struct{ foo[int] } - --//@rank("", type),rank("", func),rank("", var),rank("", const),rank("", import) +-var _ = x.foo +diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden +--- a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +--- bar-rename -- +-//go:build go1.18 +-// +build go1.18 - --func _() { -- var test int //@rank(" //", int, interface) -- var tChan chan int -- var _ m //@complete(" //", map) -- var _ f //@complete(" //", func) -- var _ c //@complete(" //", chan) +-package generics - -- var _ str //@rank(" //", string, struct) +-type bar[P any] int //@rename("foo","bar") - -- type _ int //@rank(" //", interface, int) +-var x struct{ bar[int] } - -- type _ str //@rank(" //", struct, string) +-var _ = x.bar - -- switch test { -- case 1: // TODO: trying to complete case here will break because the parser won't return *ast.Ident -- b //@complete(" //", break) -- case 2: -- f //@complete(" //", fallthrough, for) -- r //@complete(" //", return) -- d //@complete(" //", default, defer) -- c //@complete(" //", case, const) -- } +diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go b/gopls/internal/lsp/testdata/rename/generics/generics.go +--- a/gopls/internal/lsp/testdata/rename/generics/generics.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/generics.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - -- switch test.(type) { -- case fo: //@complete(":") -- case int: -- b //@complete(" //", break) -- case int32: -- f //@complete(" //", for) -- d //@complete(" //", default, defer) -- r //@complete(" //", return) -- c //@complete(" //", case, const) -- } +-package generics - -- select { -- case <-tChan: -- b //@complete(" //", break) -- c //@complete(" //", case, const) -- } +-type G[P any] struct { +- F int +-} - -- for index := 0; index < test; index++ { -- c //@complete(" //", const, continue) -- b //@complete(" //", break) -- } +-func (G[_]) M() {} - -- for range []int{} { -- c //@complete(" //", const, continue) -- b //@complete(" //", break) -- } +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p +-} - -- // Test function level keywords +-func _() { +- var x G[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.M() //@rename("M", "N") - -- //Using 2 characters to test because map output order is random -- sw //@complete(" //", switch) -- se //@complete(" //", select) +- var y G[string] +- _ = y.F +- y.M() +-} +diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden +--- a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,108 +0,0 @@ +--- H-rename -- +-//go:build go1.18 +-// +build go1.18 - -- f //@complete(" //", for) -- d //@complete(" //", defer) -- g //@rank(" //", go),rank(" //", goto) -- r //@complete(" //", return) -- i //@complete(" //", if) -- e //@complete(" //", else) -- v //@complete(" //", var) -- c //@complete(" //", const) +-package generics - -- for i := r //@complete(" //", range) +-type H[P any] struct { +- F int -} - --/* package */ //@item(package, "package", "", "keyword") --/* import */ //@item(import, "import", "", "keyword") --/* func */ //@item(func, "func", "", "keyword") --/* type */ //@item(type, "type", "", "keyword") --/* var */ //@item(var, "var", "", "keyword") --/* const */ //@item(const, "const", "", "keyword") --/* break */ //@item(break, "break", "", "keyword") --/* default */ //@item(default, "default", "", "keyword") --/* case */ //@item(case, "case", "", "keyword") --/* defer */ //@item(defer, "defer", "", "keyword") --/* go */ //@item(go, "go", "", "keyword") --/* for */ //@item(for, "for", "", "keyword") --/* if */ //@item(if, "if", "", "keyword") --/* else */ //@item(else, "else", "", "keyword") --/* switch */ //@item(switch, "switch", "", "keyword") --/* select */ //@item(select, "select", "", "keyword") --/* fallthrough */ //@item(fallthrough, "fallthrough", "", "keyword") --/* continue */ //@item(continue, "continue", "", "keyword") --/* return */ //@item(return, "return", "", "keyword") --/* var */ //@item(var, "var", "", "keyword") --/* const */ //@item(const, "const", "", "keyword") --/* goto */ //@item(goto, "goto", "", "keyword") --/* struct */ //@item(struct, "struct", "", "keyword") --/* interface */ //@item(interface, "interface", "", "keyword") --/* map */ //@item(map, "map", "", "keyword") --/* func */ //@item(func, "func", "", "keyword") --/* chan */ //@item(chan, "chan", "", "keyword") --/* range */ //@item(range, "range", "", "keyword") -diff -urN a/gopls/internal/lsp/testdata/labels/labels.go b/gopls/internal/lsp/testdata/labels/labels.go ---- a/gopls/internal/lsp/testdata/labels/labels.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/labels/labels.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,49 +0,0 @@ --package labels +-func (H[_]) M() {} +- +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p +-} - -func _() { -- goto F //@complete(" //", label1, label5) +- var x H[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.M() //@rename("M", "N") - --Foo1: //@item(label1, "Foo1", "label", "const") -- for a, b := range []int{} { -- Foo2: //@item(label2, "Foo2", "label", "const") -- switch { -- case true: -- break F //@complete(" //", label2, label1) +- var y H[string] +- _ = y.F +- y.M() +-} - -- continue F //@complete(" //", label1) +--- K-rename -- +-//go:build go1.18 +-// +build go1.18 - -- { -- FooUnjumpable: -- } +-package generics - -- goto F //@complete(" //", label1, label2, label4, label5) +-type G[P any] struct { +- K int +-} - -- func() { -- goto F //@complete(" //", label3) +-func (G[_]) M() {} - -- break F //@complete(" //") +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p +-} - -- continue F //@complete(" //") +-func _() { +- var x G[int] //@rename("G", "H") +- _ = x.K //@rename("F", "K") +- x.M() //@rename("M", "N") - -- Foo3: //@item(label3, "Foo3", "label", "const") -- }() -- } +- var y G[string] +- _ = y.K +- y.M() +-} - -- Foo4: //@item(label4, "Foo4", "label", "const") -- switch interface{}(a).(type) { -- case int: -- break F //@complete(" //", label4, label1) -- } -- } +--- N-rename -- +-//go:build go1.18 +-// +build go1.18 - -- break F //@complete(" //") +-package generics - -- continue F //@complete(" //") +-type G[P any] struct { +- F int +-} - --Foo5: //@item(label5, "Foo5", "label", "const") -- for { -- break F //@complete(" //", label5) -- } +-func (G[_]) N() {} - -- return +-func F[P any](P) { +- var p P //@rename("P", "Q") +- _ = p -} -diff -urN a/gopls/internal/lsp/testdata/links/links.go b/gopls/internal/lsp/testdata/links/links.go ---- a/gopls/internal/lsp/testdata/links/links.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/links/links.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,26 +0,0 @@ --package links - --import ( -- "fmt" //@link(`fmt`,"https://pkg.go.dev/fmt") +-func _() { +- var x G[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.N() //@rename("M", "N") - -- "golang.org/lsptests/foo" //@link(`golang.org/lsptests/foo`,`https://pkg.go.dev/golang.org/lsptests/foo`) +- var y G[string] +- _ = y.F +- y.N() +-} - -- _ "database/sql" //@link(`database/sql`, `https://pkg.go.dev/database/sql`) --) +--- Q-rename -- +-//go:build go1.18 +-// +build go1.18 - --var ( -- _ fmt.Formatter -- _ foo.StructFoo -- _ errors.Formatter --) +-package generics - --// Foo function --func Foo() string { -- /*https://example.com/comment */ //@link("https://example.com/comment","https://example.com/comment") +-type G[P any] struct { +- F int +-} - -- url := "https://example.com/string_literal" //@link("https://example.com/string_literal","https://example.com/string_literal") -- return url +-func (G[_]) M() {} - -- // TODO(golang/go#1234): Link the relevant issue. //@link("golang/go#1234", "https://github.com/golang/go/issues/1234") -- // TODO(microsoft/vscode-go#12): Another issue. //@link("microsoft/vscode-go#12", "https://github.com/microsoft/vscode-go/issues/12") +-func F[Q any](Q) { +- var p Q //@rename("P", "Q") +- _ = p -} -diff -urN a/gopls/internal/lsp/testdata/maps/maps.go.in b/gopls/internal/lsp/testdata/maps/maps.go.in ---- a/gopls/internal/lsp/testdata/maps/maps.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/maps/maps.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ --package maps - -func _() { -- var aVar int //@item(mapVar, "aVar", "int", "var") +- var x G[int] //@rename("G", "H") +- _ = x.F //@rename("F", "K") +- x.M() //@rename("M", "N") - -- // not comparabale -- type aSlice []int //@item(mapSliceType, "aSlice", "[]int", "type") +- var y G[string] +- _ = y.F +- y.M() +-} - -- *aSlice //@item(mapSliceTypePtr, "*aSlice", "[]int", "type") +diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go b/gopls/internal/lsp/testdata/rename/generics/unions.go +--- a/gopls/internal/lsp/testdata/rename/generics/unions.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/unions.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - -- // comparable -- type aStruct struct{} //@item(mapStructType, "aStruct", "struct{...}", "struct") +-package generics - -- map[]a{} //@complete("]", mapSliceType, mapStructType),snippet("]", mapSliceType, "*aSlice", "*aSlice") +-type T string //@rename("T", "R") - -- map[a]a{} //@complete("]", mapSliceType, mapStructType) -- map[a]a{} //@complete("{", mapSliceType, mapStructType) +-type C interface { +- T | ~int //@rename("T", "S") -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go b/gopls/internal/lsp/testdata/missingfunction/channels.go ---- a/gopls/internal/lsp/testdata/missingfunction/channels.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/channels.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package missingfunction +diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden +--- a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +--- R-rename -- +-//go:build go1.18 +-// +build go1.18 - --func channels(s string) { -- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") +-package generics +- +-type R string //@rename("T", "R") +- +-type C interface { +- R | ~int //@rename("T", "S") -} - --func c() (<-chan string, chan string) { -- return make(<-chan string), make(chan string) +--- S-rename -- +-//go:build go1.18 +-// +build go1.18 +- +-package generics +- +-type S string //@rename("T", "R") +- +-type C interface { +- S | ~int //@rename("T", "S") -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/channels.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ ---- suggestedfix_channels_4_2 -- --package missingfunction - --func channels(s string) { -- undefinedChannels(c()) //@suggestedfix("undefinedChannels", "quickfix", "") +diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +--- bar-rename -- +-package issue39614 +- +-func fn() { +- var bar bool //@rename("foo","bar") +- make(map[string]bool +- if true { +- } -} - --func undefinedChannels(ch1 <-chan string, ch2 chan string) { -- panic("unimplemented") +diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in +--- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package issue39614 +- +-func fn() { +- var foo bool //@rename("foo","bar") +- make(map[string]bool +- if true { +- } -} +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go b/gopls/internal/lsp/testdata/rename/issue42134/1.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/1.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package issue42134 - --func c() (<-chan string, chan string) { -- return make(<-chan string), make(chan string) +-func _() { +- // foo computes things. +- foo := func() {} +- +- foo() //@rename("foo", "bar") -} +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +--- bar-rename -- +-package issue42134 - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go ---- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package missingfunction +-func _() { +- // bar computes things. +- bar := func() {} - --func consecutiveParams() { -- var s string -- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") +- bar() //@rename("foo", "bar") -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/consecutive_params.go.golden 1970-01-01 00:00:00.000000000 +0000 +- +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go b/gopls/internal/lsp/testdata/rename/issue42134/2.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/2.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,12 +0,0 @@ ---- suggestedfix_consecutive_params_5_2 -- --package missingfunction +-package issue42134 - --func consecutiveParams() { -- var s string -- undefinedConsecutiveParams(s, s) //@suggestedfix("undefinedConsecutiveParams", "quickfix", "") --} +-import "fmt" - --func undefinedConsecutiveParams(s1, s2 string) { -- panic("unimplemented") +-func _() { +- // minNumber is a min number. +- // Second line. +- minNumber := min(1, 2) +- fmt.Println(minNumber) //@rename("minNumber", "res") -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go b/gopls/internal/lsp/testdata/missingfunction/error_param.go ---- a/gopls/internal/lsp/testdata/missingfunction/error_param.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package missingfunction +-func min(a, b int) int { return a } +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +--- res-rename -- +-package issue42134 - --func errorParam() { -- var err error -- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") +-import "fmt" +- +-func _() { +- // res is a min number. +- // Second line. +- res := min(1, 2) +- fmt.Println(res) //@rename("minNumber", "res") -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/error_param.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ ---- suggestedfix_error_param_5_2 -- --package missingfunction - --func errorParam() { -- var err error -- undefinedErrorParam(err) //@suggestedfix("undefinedErrorParam", "quickfix", "") +-func min(a, b int) int { return a } +- +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go b/gopls/internal/lsp/testdata/rename/issue42134/3.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/3.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package issue42134 +- +-func _() { +- /* +- tests contains test cases +- */ +- tests := []struct { //@rename("tests", "testCases") +- in, out string +- }{} +- _ = tests -} +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- testCases-rename -- +-package issue42134 - --func undefinedErrorParam(err error) { -- panic("unimplemented") +-func _() { +- /* +- testCases contains test cases +- */ +- testCases := []struct { //@rename("tests", "testCases") +- in, out string +- }{} +- _ = testCases -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go b/gopls/internal/lsp/testdata/missingfunction/literals.go ---- a/gopls/internal/lsp/testdata/missingfunction/literals.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/literals.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package missingfunction +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go b/gopls/internal/lsp/testdata/rename/issue42134/4.go +--- a/gopls/internal/lsp/testdata/rename/issue42134/4.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package issue42134 - --type T struct{} +-func _() { +- // a is equal to 5. Comment must stay the same - --func literals() { -- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") +- a := 5 +- _ = a //@rename("a", "b") -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/literals.go.golden 1970-01-01 00:00:00.000000000 +0000 +diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +--- b-rename -- +-package issue42134 +- +-func _() { +- // a is equal to 5. Comment must stay the same +- +- b := 5 +- _ = b //@rename("a", "b") +-} +- +diff -urN a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden +--- a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ ---- suggestedfix_literals_6_2 -- --package missingfunction +--- bar-rename -- +-package issue43616 - --type T struct{} +-type bar int //@rename("foo","bar"),prepare("oo","foo","foo") - --func literals() { -- undefinedLiterals("hey compiler", T{}, &T{}) //@suggestedfix("undefinedLiterals", "quickfix", "") --} +-var x struct{ bar } //@rename("foo","baz") - --func undefinedLiterals(s string, t1 T, t2 *T) { -- panic("unimplemented") --} +-var _ = x.bar //@rename("foo","quux") - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go b/gopls/internal/lsp/testdata/missingfunction/operation.go ---- a/gopls/internal/lsp/testdata/missingfunction/operation.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/operation.go 1970-01-01 00:00:00.000000000 +0000 +--- baz-rename -- +-can't rename embedded fields: rename the type directly or name the field +--- quux-rename -- +-can't rename embedded fields: rename the type directly or name the field +diff -urN a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in +--- a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ --package missingfunction +-package issue43616 - --import "time" +-type foo int //@rename("foo","bar"),prepare("oo","foo","foo") - --func operation() { -- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") --} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/operation.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- suggestedfix_operation_6_2 -- --package missingfunction +-var x struct{ foo } //@rename("foo","baz") - --import "time" +-var _ = x.foo //@rename("foo","quux") +diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go b/gopls/internal/lsp/testdata/rename/shadow/shadow.go +--- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package shadow - --func operation() { -- undefinedOperation(10 * time.Second) //@suggestedfix("undefinedOperation", "quickfix", "") +-func _() { +- a := true +- b, c, _ := A(), B(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") +- d := false +- _, _, _, _ = a, b, c, d -} - --func undefinedOperation(duration time.Duration) { -- panic("unimplemented") +-func A() int { +- return 0 -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go b/gopls/internal/lsp/testdata/missingfunction/selector.go ---- a/gopls/internal/lsp/testdata/missingfunction/selector.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/selector.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package missingfunction -- --func selector() { -- m := map[int]bool{} -- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") +-func B() int { +- return 0 -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/selector.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ ---- suggestedfix_selector_5_2 -- --package missingfunction - --func selector() { -- m := map[int]bool{} -- undefinedSelector(m[1]) //@suggestedfix("undefinedSelector", "quickfix", "") +-func D() int { +- return 0 -} +diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden +--- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,51 +0,0 @@ +--- a-rename -- +-shadow/shadow.go:10:6: renaming this func "A" to "a" +-shadow/shadow.go:5:13: would cause this reference to become shadowed +-shadow/shadow.go:4:2: by this intervening var definition +--- b-rename -- +-package shadow - --func undefinedSelector(b bool) { -- panic("unimplemented") +-func _() { +- a := true +- b, c, _ := A(), b(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") +- d := false +- _, _, _, _ = a, b, c, d -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go b/gopls/internal/lsp/testdata/missingfunction/slice.go ---- a/gopls/internal/lsp/testdata/missingfunction/slice.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/slice.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package missingfunction -- --func slice() { -- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") +-func A() int { +- return 0 -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/slice.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ ---- suggestedfix_slice_4_2 -- --package missingfunction - --func slice() { -- undefinedSlice([]int{1, 2}) //@suggestedfix("undefinedSlice", "quickfix", "") +-func b() int { +- return 0 -} - --func undefinedSlice(i []int) { -- panic("unimplemented") +-func D() int { +- return 0 -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go b/gopls/internal/lsp/testdata/missingfunction/tuple.go ---- a/gopls/internal/lsp/testdata/missingfunction/tuple.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package missingfunction -- --func tuple() { -- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") --} +--- c-rename -- +-shadow/shadow.go:5:2: renaming this var "b" to "c" +-shadow/shadow.go:5:5: conflicts with var in same block +--- d-rename -- +-package shadow - --func b() (string, error) { -- return "", nil +-func _() { +- a := true +- b, c, _ := A(), B(), d() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") +- d := false +- _, _, _, _ = a, b, c, d -} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/tuple.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ ---- suggestedfix_tuple_4_2 -- --package missingfunction - --func tuple() { -- undefinedTuple(b()) //@suggestedfix("undefinedTuple", "quickfix", "") +-func A() int { +- return 0 -} - --func undefinedTuple(s string, err error) { -- panic("unimplemented") +-func B() int { +- return 0 -} - --func b() (string, error) { -- return "", nil +-func d() int { +- return 0 -} - -diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go b/gopls/internal/lsp/testdata/missingfunction/unique_params.go ---- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go 1970-01-01 00:00:00.000000000 +0000 +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go b/gopls/internal/lsp/testdata/rename/testy/testy.go +--- a/gopls/internal/lsp/testdata/rename/testy/testy.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ --package missingfunction +-package testy - --func uniqueArguments() { -- var s string -- var i int -- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") --} -diff -urN a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden ---- a/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/missingfunction/unique_params.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- suggestedfix_unique_params_6_2 -- --package missingfunction +-type tt int //@rename("tt", "testyType") - --func uniqueArguments() { -- var s string -- var i int -- undefinedUniqueArguments(s, i, s) //@suggestedfix("undefinedUniqueArguments", "quickfix", "") +-func a() { +- foo := 42 //@rename("foo", "bar") -} +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden +--- a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- bar-rename -- +-package testy - --func undefinedUniqueArguments(s1 string, i int, s2 string) { -- panic("unimplemented") --} +-type tt int //@rename("tt", "testyType") - -diff -urN a/gopls/internal/lsp/testdata/multireturn/multi_return.go.in b/gopls/internal/lsp/testdata/multireturn/multi_return.go.in ---- a/gopls/internal/lsp/testdata/multireturn/multi_return.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/multireturn/multi_return.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,48 +0,0 @@ --package multireturn +-func a() { +- bar := 42 //@rename("foo", "bar") +-} - --func f0() {} //@item(multiF0, "f0", "func()", "func") +--- testyType-rename -- +-package testy - --func f1(int) int { return 0 } //@item(multiF1, "f1", "func(int) int", "func") +-type testyType int //@rename("tt", "testyType") - --func f2(int, int) (int, int) { return 0, 0 } //@item(multiF2, "f2", "func(int, int) (int, int)", "func") +-func a() { +- foo := 42 //@rename("foo", "bar") +-} - --func f2Str(string, string) (string, string) { return "", "" } //@item(multiF2Str, "f2Str", "func(string, string) (string, string)", "func") +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go b/gopls/internal/lsp/testdata/rename/testy/testy_test.go +--- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,8 +0,0 @@ +-package testy - --func f3(int, int, int) (int, int, int) { return 0, 0, 0 } //@item(multiF3, "f3", "func(int, int, int) (int, int, int)", "func") +-import "testing" - --func _() { -- _ := f //@rank(" //", multiF1, multiF2) +-func TestSomething(t *testing.T) { +- var x int //@rename("x", "testyX") +- a() //@rename("a", "b") +-} +diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden +--- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +--- b-rename -- +-testy.go: +-package testy - -- _, _ := f //@rank(" //", multiF2, multiF0),rank(" //", multiF1, multiF0) +-type tt int //@rename("tt", "testyType") - -- _, _ := _, f //@rank(" //", multiF1, multiF2),rank(" //", multiF1, multiF0) +-func b() { +- foo := 42 //@rename("foo", "bar") +-} - -- _, _ := f, abc //@rank(", abc", multiF1, multiF2) +-testy_test.go: +-package testy - -- f1() //@rank(")", multiF1, multiF0) -- f1(f) //@rank(")", multiF1, multiF2) -- f2(f) //@rank(")", multiF2, multiF3),rank(")", multiF1, multiF3) -- f2(1, f) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) -- f2(1, ) //@rank(")", multiF1, multiF2),rank(")", multiF1, multiF0) -- f2Str() //@rank(")", multiF2Str, multiF2) +-import "testing" - -- var i int -- i, _ := f //@rank(" //", multiF2, multiF2Str) +-func TestSomething(t *testing.T) { +- var x int //@rename("x", "testyX") +- b() //@rename("a", "b") +-} - -- var s string -- _, s := f //@rank(" //", multiF2Str, multiF2) +--- testyX-rename -- +-package testy - -- banana, s = f //@rank(" //", multiF2, multiF3) +-import "testing" - -- var variadic func(int, ...int) -- variadic() //@rank(")", multiF1, multiF0),rank(")", multiF2, multiF0),rank(")", multiF3, multiF0) +-func TestSomething(t *testing.T) { +- var testyX int //@rename("x", "testyX") +- a() //@rename("a", "b") -} - --func _() { -- var baz func(...interface{}) +diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go b/gopls/internal/lsp/testdata/selectionrange/foo.go +--- a/gopls/internal/lsp/testdata/selectionrange/foo.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/selectionrange/foo.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package foo - -- var otterNap func() (int, int) //@item(multiTwo, "otterNap", "func() (int, int)", "var") -- var one int //@item(multiOne, "one", "int", "var") +-import "time" - -- baz(on) //@rank(")", multiOne, multiTwo) --} -diff -urN a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in ---- a/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/nested_complit/nested_complit.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ --package nested_complit +-func Bar(x, y int, t time.Time) int { +- zs := []int{1, 2, 3} //@selectionrange("1") - --type ncFoo struct {} //@item(structNCFoo, "ncFoo", "struct{...}", "struct") +- for _, z := range zs { +- x = x + z + y + zs[1] //@selectionrange("1") +- } - --type ncBar struct { //@item(structNCBar, "ncBar", "struct{...}", "struct") -- baz []ncFoo +- return x + y //@selectionrange("+") -} +diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden +--- a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +--- selectionrange_foo_12_11 -- +-Ranges 0: +- 11:8-11:13 "x + y" +- 11:1-11:13 "return x + y" +- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" +- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" +- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" - --func _() { -- []ncFoo{} //@item(litNCFoo, "[]ncFoo{}", "", "var") -- _ := ncBar{ -- // disabled - see issue #54822 -- baz: [] // complete(" //", structNCFoo, structNCBar) -- } --} -diff -urN a/gopls/internal/lsp/testdata/nodisk/empty b/gopls/internal/lsp/testdata/nodisk/empty ---- a/gopls/internal/lsp/testdata/nodisk/empty 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/nodisk/empty 1970-01-01 00:00:00.000000000 +0000 -@@ -1 +0,0 @@ --an empty file so that this directory exists -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go b/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go ---- a/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package nodisk +--- selectionrange_foo_6_14 -- +-Ranges 0: +- 5:13-5:14 "1" +- 5:7-5:21 "[]int{1, 2, 3}" +- 5:1-5:21 "zs := []int{1, 2, 3}" +- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" +- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" +- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" +- +--- selectionrange_foo_9_22 -- +-Ranges 0: +- 8:21-8:22 "1" +- 8:18-8:23 "zs[1]" +- 8:6-8:23 "x + z + y + zs[1]" +- 8:2-8:23 "x = x + z + y + zs[1]" +- 7:22-9:2 "{\\n\t\tx = x + z +...onrange(\"1\")\\n\t}" +- 7:1-9:2 "for _, z := ran...onrange(\"1\")\\n\t}" +- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" +- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" +- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" +- +diff -urN a/gopls/internal/lsp/testdata/selector/selector.go.in b/gopls/internal/lsp/testdata/selector/selector.go.in +--- a/gopls/internal/lsp/testdata/selector/selector.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/selector/selector.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,66 +0,0 @@ +-// +build go1.11 +- +-package selector - -import ( -- "golang.org/lsptests/foo" +- "golang.org/lsptests/bar" -) - +-type S struct { +- B, A, C int //@item(Bf, "B", "int", "field"),item(Af, "A", "int", "field"),item(Cf, "C", "int", "field") +-} +- -func _() { -- foo.Foo() //@complete("F", Foo, IntFoo, StructFoo) +- _ = S{}.; //@complete(";", Af, Bf, Cf) -} -diff -urN a/gopls/internal/lsp/testdata/noparse/noparse.go.in b/gopls/internal/lsp/testdata/noparse/noparse.go.in ---- a/gopls/internal/lsp/testdata/noparse/noparse.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/noparse/noparse.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ --package noparse - --// The type error was chosen carefully to exercise a type-error analyzer. --// We use the 'nonewvars' analyzer because the other candidates are tricky: --// --// - The 'unusedvariable' analyzer is disabled by default, so it is not --// consistently enabled across Test{LSP,CommandLine} tests, which --// both process this file. --// - The 'undeclaredname' analyzer depends on the text of the go/types --// "undeclared name" error, which changed in go1.20. --// - The 'noresultvalues' analyzer produces a diagnostic containing newlines, --// which breaks the parser used by TestCommandLine. --// --// This comment is all that remains of my afternoon. +-type bob struct { a int } //@item(a, "a", "int", "field") +-type george struct { b int } +-type jack struct { c int } //@item(c, "c", "int", "field") +-type jill struct { d int } - --func bye(x int) { -- x := 123 //@diag(":=", "nonewvars", "no new variables", "warning") --} +-func (b *bob) george() *george {} //@item(george, "george", "func() *george", "method") +-func (g *george) jack() *jack {} +-func (j *jack) jill() *jill {} //@item(jill, "jill", "func() *jill", "method") - --func stuff() { -- +-func _() { +- b := &bob{} +- y := b.george(). +- jack(); +- y.; //@complete(";", c, jill) -} - --func .() {} //@diag(".", "syntax", "expected 'IDENT', found '.'", "error") -diff -urN a/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.golden b/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.golden ---- a/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,2 +0,0 @@ ---- gofmt -- +-func _() { +- bar. //@complete(" /", Bar) +- x := 5 - -diff -urN a/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.in b/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.in ---- a/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/noparse_format/noparse_format.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ --// +build go1.11 +- var b *bob +- b. //@complete(" /", a, george) +- y, z := 5, 6 - --package noparse_format //@format("package") +- b. //@complete(" /", a, george) +- y, z, a, b, c := 5, 6 +-} - --// The nonewvars expectation asserts that the go/analysis framework ran. --// See comments in badstmt. +-func _() { +- bar. //@complete(" /", Bar) +- bar.Bar() - --func what() { -- var hi func() -- if { hi() //@diag("{", "syntax", "missing condition in if statement", "error") -- } -- hi := nil //@diag(":=", "nonewvars", "no new variables", "warning") +- bar. //@complete(" /", Bar) +- go f() -} - -diff -urN a/gopls/internal/lsp/testdata/noparse_format/parse_format.go.golden b/gopls/internal/lsp/testdata/noparse_format/parse_format.go.golden ---- a/gopls/internal/lsp/testdata/noparse_format/parse_format.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/noparse_format/parse_format.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ ---- gofmt -- --package noparse_format //@format("package") -- -func _() { -- f() --} +- var b *bob +- if y != b. //@complete(" /", a, george) +- z := 5 - -diff -urN a/gopls/internal/lsp/testdata/noparse_format/parse_format.go.in b/gopls/internal/lsp/testdata/noparse_format/parse_format.go.in ---- a/gopls/internal/lsp/testdata/noparse_format/parse_format.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/noparse_format/parse_format.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package noparse_format //@format("package") +- if z + y + 1 + b. //@complete(" /", a, george) +- r, s, t := 4, 5 - --func _() { --f() +- if y != b. //@complete(" /", a, george) +- z = 5 +- +- if z + y + 1 + b. //@complete(" /", a, george) +- r = 4 -} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/%percent/perc%ent.go b/gopls/internal/lsp/testdata/%percent/perc%ent.go ---- a/gopls/internal/lsp/testdata/%percent/perc%ent.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/%percent/perc%ent.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1 +0,0 @@ --package percent -diff -urN a/gopls/internal/lsp/testdata/printf/printf.go b/gopls/internal/lsp/testdata/printf/printf.go ---- a/gopls/internal/lsp/testdata/printf/printf.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/printf/printf.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,33 +0,0 @@ --package printf +diff -urN a/gopls/internal/lsp/testdata/semantic/a.go b/gopls/internal/lsp/testdata/semantic/a.go +--- a/gopls/internal/lsp/testdata/semantic/a.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/a.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,81 +0,0 @@ +-package semantictokens //@ semantic("") - --import "fmt" +-import ( +- _ "encoding/utf8" +- utf "encoding/utf8" +- "fmt" //@ semantic("fmt") +- . "fmt" +- "unicode/utf8" +-) - --func myPrintf(string, ...interface{}) {} +-var ( +- a = fmt.Print +- b []string = []string{"foo"} +- c1 chan int +- c2 <-chan int +- c3 = make([]chan<- int) +- b = A{X: 23} +- m map[bool][3]*float64 +-) - --func _() { -- var ( -- aInt int //@item(printfInt, "aInt", "int", "var") -- aFloat float64 //@item(printfFloat, "aFloat", "float64", "var") -- aString string //@item(printfString, "aString", "string", "var") -- aBytes []byte //@item(printfBytes, "aBytes", "[]byte", "var") -- aStringer fmt.Stringer //@item(printfStringer, "aStringer", "fmt.Stringer", "var") -- aError error //@item(printfError, "aError", "error", "var") -- aBool bool //@item(printfBool, "aBool", "bool", "var") -- ) +-const ( +- xx F = iota +- yy = xx + 3 +- zz = "" +- ww = "not " + zz +-) - -- myPrintf("%d", a) //@rank(")", printfInt, printfFloat) -- myPrintf("%s", a) //@rank(")", printfString, printfInt),rank(")", printfBytes, printfInt),rank(")", printfStringer, printfInt),rank(")", printfError, printfInt) -- myPrintf("%w", a) //@rank(")", printfError, printfInt) -- myPrintf("%x %[1]b", a) //@rank(")", printfInt, printfString) +-type A struct { +- X int `foof` +-} +-type B interface { +- A +- sad(int) bool +-} - -- fmt.Printf("%t", a) //@rank(")", printfBool, printfInt) +-type F int - -- fmt.Fprintf(nil, "%f", a) //@rank(")", printfFloat, printfInt) +-func (a *A) f() bool { +- var z string +- x := "foo" +- a(x) +- y := "bar" + x +- switch z { +- case "xx": +- default: +- } +- select { +- case z := <-c3[0]: +- default: +- } +- for k, v := range m { +- return (!k) && v[0] == nil +- } +- c2 <- A.X +- w := b[4:] +- j := len(x) +- j-- +- q := []interface{}{j, 23i, &y} +- g(q...) +- return true +-} - -- fmt.Sprintf("%[2]q %[1]*.[3]*[4]f", -- a, //@rank(",", printfInt, printfFloat) -- a, //@rank(",", printfString, printfFloat) -- a, //@rank(",", printfInt, printfFloat) -- a, //@rank(",", printfFloat, printfInt) -- ) +-func g(vv ...interface{}) { +- ff := func() {} +- defer ff() +- go utf.RuneCount("") +- go utf8.RuneCount(vv.(string)) +- if true { +- } else { +- } +-Never: +- for i := 0; i < 10; { +- break Never +- } +- _, ok := vv[0].(A) +- if !ok { +- switch x := vv[0].(type) { +- } +- goto Never +- } -} -diff -urN a/gopls/internal/lsp/testdata/rank/assign_rank.go.in b/gopls/internal/lsp/testdata/rank/assign_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/assign_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/assign_rank.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ --package rank +diff -urN a/gopls/internal/lsp/testdata/semantic/a.go.golden b/gopls/internal/lsp/testdata/semantic/a.go.golden +--- a/gopls/internal/lsp/testdata/semantic/a.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/a.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,83 +0,0 @@ +--- semantic -- +-/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") - --var ( -- apple int = 3 //@item(apple, "apple", "int", "var") -- pear string = "hello" //@item(pear, "pear", "string", "var") +-/*⇒6,keyword,[]*/import ( +- _ "encoding/utf8" +- /*⇒3,namespace,[]*/utf "encoding/utf8" +- "fmt"/*⇐3,namespace,[]*/ /*⇒19,comment,[]*///@ semantic("fmt") +- . "fmt" +- "unicode/utf8"/*⇐4,namespace,[]*/ -) - --func _() { -- orange := 1 //@item(orange, "orange", "int", "var") -- grape := "hello" //@item(grape, "grape", "string", "var") -- orange, grape = 2, "hello" //@complete(" \"", grape, pear, orange, apple) --} +-/*⇒3,keyword,[]*/var ( +- /*⇒1,variable,[definition]*/a = /*⇒3,namespace,[]*/fmt./*⇒5,function,[]*/Print +- /*⇒1,variable,[definition]*/b []/*⇒6,type,[defaultLibrary]*/string = []/*⇒6,type,[defaultLibrary]*/string{/*⇒5,string,[]*/"foo"} +- /*⇒2,variable,[definition]*/c1 /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +- /*⇒2,variable,[definition]*/c2 /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +- /*⇒2,variable,[definition]*/c3 = /*⇒4,function,[defaultLibrary]*/make([]/*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒3,type,[defaultLibrary]*/int) +- /*⇒1,variable,[definition]*/b = /*⇒1,type,[]*/A{/*⇒1,variable,[]*/X: /*⇒2,number,[]*/23} +- /*⇒1,variable,[definition]*/m /*⇒3,keyword,[]*/map[/*⇒4,type,[defaultLibrary]*/bool][/*⇒1,number,[]*/3]/*⇒1,operator,[]*/*/*⇒7,type,[defaultLibrary]*/float64 +-) - --func _() { -- var pineapple int //@item(pineapple, "pineapple", "int", "var") -- pineapple = 1 //@complete(" 1", pineapple, apple, pear) +-/*⇒5,keyword,[]*/const ( +- /*⇒2,variable,[definition readonly]*/xx /*⇒1,type,[]*/F = /*⇒4,variable,[readonly]*/iota +- /*⇒2,variable,[definition readonly]*/yy = /*⇒2,variable,[readonly]*/xx /*⇒1,operator,[]*/+ /*⇒1,number,[]*/3 +- /*⇒2,variable,[definition readonly]*/zz = /*⇒2,string,[]*/"" +- /*⇒2,variable,[definition readonly]*/ww = /*⇒6,string,[]*/"not " /*⇒1,operator,[]*/+ /*⇒2,variable,[readonly]*/zz +-) - -- y := //@complete(" /", pineapple, apple, pear) +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/A /*⇒6,keyword,[]*/struct { +- /*⇒1,variable,[definition]*/X /*⇒3,type,[defaultLibrary]*/int /*⇒6,string,[]*/`foof` +-} +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/B /*⇒9,keyword,[]*/interface { +- /*⇒1,type,[]*/A +- /*⇒3,method,[definition]*/sad(/*⇒3,type,[defaultLibrary]*/int) /*⇒4,type,[defaultLibrary]*/bool -} -diff -urN a/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in b/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/binexpr_rank.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package rank - --func _() { -- _ = 5 + ; //@complete(" ;", apple, pear) -- y := + 5; //@complete(" +", apple, pear) +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/F /*⇒3,type,[defaultLibrary]*/int - -- if 6 == {} //@complete(" {", apple, pear) +-/*⇒4,keyword,[]*/func (/*⇒1,variable,[]*/a /*⇒1,operator,[]*/*/*⇒1,type,[]*/A) /*⇒1,method,[definition]*/f() /*⇒4,type,[defaultLibrary]*/bool { +- /*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/z /*⇒6,type,[defaultLibrary]*/string +- /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"foo" +- /*⇒1,variable,[]*/a(/*⇒1,variable,[]*/x) +- /*⇒1,variable,[definition]*/y /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"bar" /*⇒1,operator,[]*/+ /*⇒1,variable,[]*/x +- /*⇒6,keyword,[]*/switch /*⇒1,variable,[]*/z { +- /*⇒4,keyword,[]*/case /*⇒4,string,[]*/"xx": +- /*⇒7,keyword,[]*/default: +- } +- /*⇒6,keyword,[]*/select { +- /*⇒4,keyword,[]*/case /*⇒1,variable,[definition]*/z /*⇒2,operator,[]*/:= /*⇒2,operator,[]*/<-/*⇒2,variable,[]*/c3[/*⇒1,number,[]*/0]: +- /*⇒7,keyword,[]*/default: +- } +- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/k, /*⇒1,variable,[definition]*/v := /*⇒5,keyword,[]*/range /*⇒1,variable,[]*/m { +- /*⇒6,keyword,[]*/return (/*⇒1,operator,[]*/!/*⇒1,variable,[]*/k) /*⇒2,operator,[]*/&& /*⇒1,variable,[]*/v[/*⇒1,number,[]*/0] /*⇒2,operator,[]*/== /*⇒3,variable,[readonly defaultLibrary]*/nil +- } +- /*⇒2,variable,[]*/c2 /*⇒2,operator,[]*/<- /*⇒1,type,[]*/A./*⇒1,variable,[]*/X +- /*⇒1,variable,[definition]*/w /*⇒2,operator,[]*/:= /*⇒1,variable,[]*/b[/*⇒1,number,[]*/4:] +- /*⇒1,variable,[definition]*/j /*⇒2,operator,[]*/:= /*⇒3,function,[defaultLibrary]*/len(/*⇒1,variable,[]*/x) +- /*⇒1,variable,[]*/j/*⇒2,operator,[]*/-- +- /*⇒1,variable,[definition]*/q /*⇒2,operator,[]*/:= []/*⇒9,keyword,[]*/interface{}{/*⇒1,variable,[]*/j, /*⇒3,number,[]*/23i, /*⇒1,operator,[]*/&/*⇒1,variable,[]*/y} +- /*⇒1,function,[]*/g(/*⇒1,variable,[]*/q/*⇒3,operator,[]*/...) +- /*⇒6,keyword,[]*/return /*⇒4,variable,[readonly]*/true -} -diff -urN a/gopls/internal/lsp/testdata/rank/boolexpr_rank.go b/gopls/internal/lsp/testdata/rank/boolexpr_rank.go ---- a/gopls/internal/lsp/testdata/rank/boolexpr_rank.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/boolexpr_rank.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package rank - --func _() { -- someRandomBoolFunc := func() bool { //@item(boolExprFunc, "someRandomBoolFunc", "func() bool", "var") -- return true +-/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/g(/*⇒2,parameter,[definition]*/vv /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { +- /*⇒2,variable,[definition]*/ff /*⇒2,operator,[]*/:= /*⇒4,keyword,[]*/func() {} +- /*⇒5,keyword,[]*/defer /*⇒2,function,[]*/ff() +- /*⇒2,keyword,[]*/go /*⇒3,namespace,[]*/utf./*⇒9,function,[]*/RuneCount(/*⇒2,string,[]*/"") +- /*⇒2,keyword,[]*/go /*⇒4,namespace,[]*/utf8./*⇒9,function,[]*/RuneCount(/*⇒2,parameter,[]*/vv.(/*⇒6,type,[]*/string)) +- /*⇒2,keyword,[]*/if /*⇒4,variable,[readonly]*/true { +- } /*⇒4,keyword,[]*/else { - } -- -- var foo, bar int //@item(boolExprBar, "bar", "int", "var") -- if foo == 123 && b { //@rank(" {", boolExprBar, boolExprFunc) +-/*⇒5,parameter,[definition]*/Never: +- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/i /*⇒2,operator,[]*/:= /*⇒1,number,[]*/0; /*⇒1,variable,[]*/i /*⇒1,operator,[]*/< /*⇒2,number,[]*/10; { +- /*⇒5,keyword,[]*/break Never +- } +- _, /*⇒2,variable,[definition]*/ok /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒1,type,[]*/A) +- /*⇒2,keyword,[]*/if /*⇒1,operator,[]*/!/*⇒2,variable,[]*/ok { +- /*⇒6,keyword,[]*/switch /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒4,keyword,[]*/type) { +- } +- /*⇒4,keyword,[]*/goto Never - } -} -diff -urN a/gopls/internal/lsp/testdata/rank/convert_rank.go.in b/gopls/internal/lsp/testdata/rank/convert_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/convert_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/convert_rank.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,54 +0,0 @@ --package rank -- --import "time" - --func _() { -- type strList []string -- wantsStrList := func(strList) {} +diff -urN a/gopls/internal/lsp/testdata/semantic/b.go b/gopls/internal/lsp/testdata/semantic/b.go +--- a/gopls/internal/lsp/testdata/semantic/b.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/b.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-package semantictokens //@ semantic("") - -- var ( -- convA string //@item(convertA, "convA", "string", "var") -- convB []string //@item(convertB, "convB", "[]string", "var") -- ) -- wantsStrList(strList(conv)) //@complete("))", convertB, convertA) +-func f(x ...interface{}) { -} - --func _() { -- type myInt int -- +-func weirⰀd() { /*😀*/ // comment - const ( -- convC = "hi" //@item(convertC, "convC", "string", "const") -- convD = 123 //@item(convertD, "convD", "int", "const") -- convE int = 123 //@item(convertE, "convE", "int", "const") -- convF string = "there" //@item(convertF, "convF", "string", "const") -- convG myInt = 123 //@item(convertG, "convG", "myInt", "const") +- snil = nil +- nil = true +- true = false +- false = snil +- cmd = `foof` +- double = iota +- iota = copy +- four = (len(cmd)/2 < 5) +- five = four - ) +- f(cmd, nil, double, iota) +-} - -- var foo int -- foo = conv //@rank(" //", convertE, convertD) -- -- var mi myInt -- mi = conv //@rank(" //", convertG, convertD, convertE) -- mi + conv //@rank(" //", convertG, convertD, convertE) -- -- 1 + conv //@rank(" //", convertD, convertC),rank(" //", convertE, convertC),rank(" //", convertG, convertC) -- -- type myString string -- var ms myString -- ms = conv //@rank(" //", convertC, convertF) -- -- type myUint uint32 -- var mu myUint -- mu = conv //@rank(" //", convertD, convertE) -- -- // don't downrank constants when assigning to interface{} -- var _ interface{} = c //@rank(" //", convertD, complex) +-/* - -- var _ time.Duration = conv //@rank(" //", convertD, convertE),snippet(" //", convertE, "time.Duration(convE)", "time.Duration(convE)") +-multiline */ /* +-multiline +-*/ +-type AA int +-type BB struct { +- AA +-} +-type CC struct { +- AA int +-} +-type D func(aa AA) (BB error) +-type E func(AA) BB - -- var convP myInt //@item(convertP, "convP", "myInt", "var") -- var _ *int = conv //@snippet(" //", convertP, "(*int)(&convP)", "(*int)(&convP)") +-var a chan<- chan int +-var b chan<- <-chan int +-var c <-chan <-chan int +diff -urN a/gopls/internal/lsp/testdata/semantic/b.go.golden b/gopls/internal/lsp/testdata/semantic/b.go.golden +--- a/gopls/internal/lsp/testdata/semantic/b.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/b.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,40 +0,0 @@ +--- semantic -- +-/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") - -- var ff float64 //@item(convertFloat, "ff", "float64", "var") -- f == convD //@snippet(" =", convertFloat, "ff", "ff") +-/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/f(/*⇒1,parameter,[definition]*/x /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { -} -diff -urN a/gopls/internal/lsp/testdata/rank/struct/struct_rank.go b/gopls/internal/lsp/testdata/rank/struct/struct_rank.go ---- a/gopls/internal/lsp/testdata/rank/struct/struct_rank.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/struct/struct_rank.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package struct_rank - --type foo struct { -- c int //@item(c_rank, "c", "int", "field") -- b int //@item(b_rank, "b", "int", "field") -- a int //@item(a_rank, "a", "int", "field") +-/*⇒4,keyword,[]*/func /*⇒6,function,[definition]*/weirⰀd() { /*⇒5,comment,[]*//*😀*/ /*⇒10,comment,[]*/// comment +- /*⇒5,keyword,[]*/const ( +- /*⇒4,variable,[definition readonly]*/snil = /*⇒3,variable,[readonly defaultLibrary]*/nil +- /*⇒3,variable,[definition readonly]*/nil = /*⇒4,variable,[readonly]*/true +- /*⇒4,variable,[definition readonly]*/true = /*⇒5,variable,[readonly]*/false +- /*⇒5,variable,[definition readonly]*/false = /*⇒4,variable,[readonly]*/snil +- /*⇒3,variable,[definition readonly]*/cmd = /*⇒6,string,[]*/`foof` +- /*⇒6,variable,[definition readonly]*/double = /*⇒4,variable,[readonly]*/iota +- /*⇒4,variable,[definition readonly]*/iota = /*⇒4,function,[defaultLibrary]*/copy +- /*⇒4,variable,[definition readonly]*/four = (/*⇒3,function,[defaultLibrary]*/len(/*⇒3,variable,[readonly]*/cmd)/*⇒1,operator,[]*// /*⇒1,number,[]*/2 /*⇒1,operator,[]*/< /*⇒1,number,[]*/5) +- /*⇒4,variable,[definition readonly]*/five = /*⇒4,variable,[readonly]*/four +- ) +- /*⇒1,function,[]*/f(/*⇒3,variable,[readonly]*/cmd, /*⇒3,variable,[readonly]*/nil, /*⇒6,variable,[readonly]*/double, /*⇒4,variable,[readonly]*/iota) -} - --func f() { -- foo := foo{} //@rank("}", c_rank, b_rank, a_rank) +-/*⇒2,comment,[]*//* +-/*⇒0,comment,[]*/ +-/*⇒12,comment,[]*/multiline */ /*⇒2,comment,[]*//* +-/*⇒9,comment,[]*/multiline +-/*⇒2,comment,[]*/*/ +-/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int +-/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/BB /*⇒6,keyword,[]*/struct { +- /*⇒2,type,[]*/AA -} -diff -urN a/gopls/internal/lsp/testdata/rank/switch_rank.go.in b/gopls/internal/lsp/testdata/rank/switch_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/switch_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/switch_rank.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ --package rank -- --import "time" -- --func _() { -- switch pear { -- case _: //@rank("_", pear, apple) -- } -- -- time.Monday //@item(timeMonday, "time.Monday", "time.Weekday", "const"),item(monday ,"Monday", "time.Weekday", "const") -- time.Friday //@item(timeFriday, "time.Friday", "time.Weekday", "const"),item(friday ,"Friday", "time.Weekday", "const") -- -- now := time.Now() -- now.Weekday //@item(nowWeekday, "now.Weekday", "func() time.Weekday", "method") -- -- then := time.Now() -- then.Weekday //@item(thenWeekday, "then.Weekday", "func() time.Weekday", "method") -- -- switch time.Weekday(0) { -- case time.Monday, time.Tuesday: -- case time.Wednesday, time.Thursday: -- case time.Saturday, time.Sunday: -- case t: //@rank(":", timeFriday, timeMonday) -- case time.: //@rank(":", friday, monday) -- -- case now.Weekday(): -- case week: //@rank(":", thenWeekday, nowWeekday) -- } +-/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/CC /*⇒6,keyword,[]*/struct { +- /*⇒2,variable,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int -} -diff -urN a/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in b/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/type_assert_rank.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package rank +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/D /*⇒4,keyword,[]*/func(/*⇒2,parameter,[definition]*/aa /*⇒2,type,[]*/AA) (/*⇒2,parameter,[definition]*/BB /*⇒5,type,[]*/error) +-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/E /*⇒4,keyword,[]*/func(/*⇒2,type,[]*/AA) /*⇒2,type,[]*/BB - --func _() { -- type flower int //@item(flower, "flower", "int", "type") -- var fig string //@item(fig, "fig", "string", "var") +-/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/a /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +-/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/b /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +-/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/c /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int - -- _ = interface{}(nil).(f) //@complete(") //", flower) --} -diff -urN a/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in b/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in ---- a/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rank/type_switch_rank.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,31 +0,0 @@ --package rank +diff -urN a/gopls/internal/lsp/testdata/semantic/README.md b/gopls/internal/lsp/testdata/semantic/README.md +--- a/gopls/internal/lsp/testdata/semantic/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2 +0,0 @@ +-The golden files are the output of `gopls semtok `, with `-- semantic --` +-inserted as the first line (the spaces are mandatory) and an extra newline at the end. +diff -urN a/gopls/internal/lsp/testdata/semantic/semantic_test.go b/gopls/internal/lsp/testdata/semantic/semantic_test.go +--- a/gopls/internal/lsp/testdata/semantic/semantic_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/semantic/semantic_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package semantictokens - -import ( -- "fmt" -- "go/ast" +- "os" +- "testing" -) - --func _() { -- type basket int //@item(basket, "basket", "int", "type") -- var banana string //@item(banana, "banana", "string", "var") +-func TestSemanticTokens(t *testing.T) { +- a, _ := os.Getwd() +- // climb up to find internal/lsp +- // find all the .go files - -- switch interface{}(pear).(type) { -- case b: //@complete(":", basket) -- b //@complete(" //", banana, basket) -- } +-} +diff -urN a/gopls/internal/lsp/testdata/signature/signature2.go.golden b/gopls/internal/lsp/testdata/signature/signature2.go.golden +--- a/gopls/internal/lsp/testdata/signature/signature2.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature2.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +--- Foo(a string, b int) (c bool)-signature -- +-Foo(a string, b int) (c bool) - -- Ident //@item(astIdent, "Ident", "struct{...}", "struct") -- IfStmt //@item(astIfStmt, "IfStmt", "struct{...}", "struct") +diff -urN a/gopls/internal/lsp/testdata/signature/signature2.go.in b/gopls/internal/lsp/testdata/signature/signature2.go.in +--- a/gopls/internal/lsp/testdata/signature/signature2.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature2.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +-package signature - -- switch ast.Node(nil).(type) { -- case *ast.Ident: -- case *ast.I: //@rank(":", astIfStmt, astIdent) -- } +-func _() { +- Foo(//@signature("//", "Foo(a string, b int) (c bool)", 0) +-} +diff -urN a/gopls/internal/lsp/testdata/signature/signature3.go.golden b/gopls/internal/lsp/testdata/signature/signature3.go.golden +--- a/gopls/internal/lsp/testdata/signature/signature3.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature3.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +--- Foo(a string, b int) (c bool)-signature -- +-Foo(a string, b int) (c bool) - -- Stringer //@item(fmtStringer, "Stringer", "interface{...}", "interface") -- GoStringer //@item(fmtGoStringer, "GoStringer", "interface{...}", "interface") +diff -urN a/gopls/internal/lsp/testdata/signature/signature3.go.in b/gopls/internal/lsp/testdata/signature/signature3.go.in +--- a/gopls/internal/lsp/testdata/signature/signature3.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature3.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +-package signature - -- switch interface{}(nil).(type) { -- case fmt.Stringer: //@rank(":", fmtStringer, fmtGoStringer) -- } +-func _() { +- Foo("hello",//@signature("//", "Foo(a string, b int) (c bool)", 1) -} -diff -urN a/gopls/internal/lsp/testdata/references/another/another.go b/gopls/internal/lsp/testdata/references/another/another.go ---- a/gopls/internal/lsp/testdata/references/another/another.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/references/another/another.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --// Package another has another type. --package another +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/signature/signature.go b/gopls/internal/lsp/testdata/signature/signature.go +--- a/gopls/internal/lsp/testdata/signature/signature.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,85 +0,0 @@ +-// Package signature has tests for signature help. +-package signature - -import ( -- other "golang.org/lsptests/references/other" +- "bytes" +- "encoding/json" +- "math/big" -) - --func _() { -- xes := other.GetXes() -- for _, x := range xes { //@mark(defX, "x") -- _ = x.Y //@mark(useX, "x"),mark(anotherXY, "Y"),refs("Y", typeXY, anotherXY, GetXesY),refs(".", defX, useX),refs("x", defX, useX) -- } +-func Foo(a string, b int) (c bool) { +- return -} -diff -urN a/gopls/internal/lsp/testdata/references/interfaces/interfaces.go b/gopls/internal/lsp/testdata/references/interfaces/interfaces.go ---- a/gopls/internal/lsp/testdata/references/interfaces/interfaces.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/references/interfaces/interfaces.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,34 +0,0 @@ --package interfaces - --type first interface { -- common() //@mark(firCommon, "common"),refs("common", firCommon, xCommon, zCommon) -- firstMethod() //@mark(firMethod, "firstMethod"),refs("firstMethod", firMethod, xfMethod, zfMethod) +-func Bar(float64, ...byte) { -} - --type second interface { -- common() //@mark(secCommon, "common"),refs("common", secCommon, yCommon, zCommon) -- secondMethod() //@mark(secMethod, "secondMethod"),refs("secondMethod", secMethod, ysMethod, zsMethod) +-type myStruct struct{} +- +-func (*myStruct) foo(e *json.Decoder) (*big.Int, error) { +- return nil, nil -} - --type s struct {} +-type MyType struct{} +- +-type MyFunc func(foo int) string +- +-type Alias = int +-type OtherAlias = int +-type StringAlias = string - --func (*s) common() {} //@mark(sCommon, "common"),refs("common", sCommon, xCommon, yCommon, zCommon) +-func AliasSlice(a []*Alias) (b Alias) { return 0 } +-func AliasMap(a map[*Alias]StringAlias) (b, c map[*Alias]StringAlias) { return nil, nil } +-func OtherAliasMap(a, b map[Alias]OtherAlias) map[Alias]OtherAlias { return nil } - --func (*s) firstMethod() {} //@mark(sfMethod, "firstMethod"),refs("firstMethod", sfMethod, xfMethod, zfMethod) +-func Qux() { +- Foo("foo", 123) //@signature("(", "Foo(a string, b int) (c bool)", 0) +- Foo("foo", 123) //@signature("123", "Foo(a string, b int) (c bool)", 1) +- Foo("foo", 123) //@signature(",", "Foo(a string, b int) (c bool)", 0) +- Foo("foo", 123) //@signature(" 1", "Foo(a string, b int) (c bool)", 1) +- Foo("foo", 123) //@signature(")", "Foo(a string, b int) (c bool)", 1) - --func (*s) secondMethod() {} //@mark(ssMethod, "secondMethod"),refs("secondMethod", ssMethod, ysMethod, zsMethod) +- Bar(13.37, 0x13) //@signature("13.37", "Bar(float64, ...byte)", 0) +- Bar(13.37, 0x37) //@signature("0x37", "Bar(float64, ...byte)", 1) +- Bar(13.37, 1, 2, 3, 4) //@signature("4", "Bar(float64, ...byte)", 1) - --func main() { -- var x first = &s{} -- var y second = &s{} +- fn := func(hi, there string) func(i int) rune { +- return func(int) rune { return 0 } +- } - -- x.common() //@mark(xCommon, "common"),refs("common", firCommon, xCommon, zCommon) -- x.firstMethod() //@mark(xfMethod, "firstMethod"),refs("firstMethod", firMethod, xfMethod, zfMethod) -- y.common() //@mark(yCommon, "common"),refs("common", secCommon, yCommon, zCommon) -- y.secondMethod() //@mark(ysMethod, "secondMethod"),refs("secondMethod", secMethod, ysMethod, zsMethod) +- fn("hi", "there") //@signature("hi", "", 0) +- fn("hi", "there") //@signature(",", "fn(hi string, there string) func(i int) rune", 0) +- fn("hi", "there")(1) //@signature("1", "func(i int) rune", 0) - -- var z *s = &s{} -- z.firstMethod() //@mark(zfMethod, "firstMethod"),refs("firstMethod", sfMethod, xfMethod, zfMethod) -- z.secondMethod() //@mark(zsMethod, "secondMethod"),refs("secondMethod", ssMethod, ysMethod, zsMethod) -- z.common() //@mark(zCommon, "common"),refs("common", sCommon, xCommon, yCommon, zCommon) --} -diff -urN a/gopls/internal/lsp/testdata/references/other/other.go b/gopls/internal/lsp/testdata/references/other/other.go ---- a/gopls/internal/lsp/testdata/references/other/other.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/references/other/other.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ --package other +- fnPtr := &fn +- (*fnPtr)("hi", "there") //@signature(",", "func(hi string, there string) func(i int) rune", 0) - --import ( -- references "golang.org/lsptests/references" --) +- var fnIntf interface{} = Foo +- fnIntf.(func(string, int) bool)("hi", 123) //@signature("123", "func(string, int) bool", 1) - --func GetXes() []references.X { -- return []references.X{ -- { -- Y: 1, //@mark(GetXesY, "Y"),refs("Y", typeXY, GetXesY, anotherXY) -- }, -- } --} +- (&bytes.Buffer{}).Next(2) //@signature("2", "Next(n int) []byte", 0) - --func _() { -- references.Q = "hello" //@mark(assignExpQ, "Q") -- bob := func(_ string) {} -- bob(references.Q) //@mark(bobExpQ, "Q") --} -diff -urN a/gopls/internal/lsp/testdata/references/refs.go b/gopls/internal/lsp/testdata/references/refs.go ---- a/gopls/internal/lsp/testdata/references/refs.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/references/refs.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,53 +0,0 @@ --// Package refs is a package used to test find references. --package refs +- myFunc := MyFunc(func(n int) string { return "" }) +- myFunc(123) //@signature("123", "myFunc(foo int) string", 0) +- +- var ms myStruct +- ms.foo(nil) //@signature("nil", "foo(e *json.Decoder) (*big.Int, error)", 0) - --import "os" //@mark(osDecl, `"os"`),refs("os", osDecl, osUse) +- _ = make([]int, 1, 2) //@signature("2", "make(t Type, size ...int) Type", 1) - --type i int //@mark(typeI, "i"),refs("i", typeI, argI, returnI, embeddedI) +- Foo(myFunc(123), 456) //@signature("myFunc", "Foo(a string, b int) (c bool)", 0) +- Foo(myFunc(123), 456) //@signature("123", "myFunc(foo int) string", 0) - --type X struct { -- Y int //@mark(typeXY, "Y") --} +- panic("oops!") //@signature(")", "panic(v interface{})", 0) +- println("hello", "world") //@signature(",", "println(args ...Type)", 0) - --func _(_ i) []bool { //@mark(argI, "i") -- return nil --} +- Hello(func() { +- //@signature("//", "", 0) +- }) - --func _(_ []byte) i { //@mark(returnI, "i") -- return 0 +- AliasSlice() //@signature(")", "AliasSlice(a []*Alias) (b Alias)", 0) +- AliasMap() //@signature(")", "AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias)", 0) +- OtherAliasMap() //@signature(")", "OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias", 0) -} - --var q string //@mark(declQ, "q"),refs("q", declQ, assignQ, bobQ) +-func Hello(func()) {} +diff -urN a/gopls/internal/lsp/testdata/signature/signature.go.golden b/gopls/internal/lsp/testdata/signature/signature.go.golden +--- a/gopls/internal/lsp/testdata/signature/signature.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,53 +0,0 @@ +--- AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias)-signature -- +-AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias) - --var Q string //@mark(declExpQ, "Q"),refs("Q", declExpQ, assignExpQ, bobExpQ) +--- AliasSlice(a []*Alias) (b Alias)-signature -- +-AliasSlice(a []*Alias) (b Alias) - --func _() { -- q = "hello" //@mark(assignQ, "q") -- bob := func(_ string) {} -- bob(q) //@mark(bobQ, "q") --} +--- Bar(float64, ...byte)-signature -- +-Bar(float64, ...byte) - --type e struct { -- i //@mark(embeddedI, "i"),refs("i", embeddedI, embeddedIUse) --} +--- Foo(a string, b int) (c bool)-signature -- +-Foo(a string, b int) (c bool) - --func _() { -- _ = e{}.i //@mark(embeddedIUse, "i") --} +--- Next(n int) []byte-signature -- +-Next(n int) []byte - --const ( -- foo = iota //@refs("iota") --) +-Next returns a slice containing the next n bytes from the buffer, advancing the buffer as if the bytes had been returned by Read. - --func _(x interface{}) { -- // We use the _ prefix because the markers inhabit a single -- // namespace and yDecl is already used in ../highlights/highlights.go. -- switch _y := x.(type) { //@mark(_yDecl, "_y"),refs("_y", _yDecl, _yInt, _yDefault) -- case int: -- println(_y) //@mark(_yInt, "_y"),refs("_y", _yDecl, _yInt, _yDefault) -- default: -- println(_y) //@mark(_yDefault, "_y") -- } +--- OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias-signature -- +-OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias - -- os.Getwd() //@mark(osUse, "os") --} -diff -urN a/gopls/internal/lsp/testdata/references/refs_test.go b/gopls/internal/lsp/testdata/references/refs_test.go ---- a/gopls/internal/lsp/testdata/references/refs_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/references/refs_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package references +--- fn(hi string, there string) func(i int) rune-signature -- +-fn(hi string, there string) func(i int) rune - --import ( -- "testing" --) +--- foo(e *json.Decoder) (*big.Int, error)-signature -- +-foo(e *json.Decoder) (*big.Int, error) - --// This test exists to bring the test package into existence. +--- func(hi string, there string) func(i int) rune-signature -- +-func(hi string, there string) func(i int) rune - --func TestReferences(t *testing.T) { --} -diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.golden b/gopls/internal/lsp/testdata/rename/a/random.go.golden ---- a/gopls/internal/lsp/testdata/rename/a/random.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/a/random.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,616 +0,0 @@ ---- GetSum-rename -- --package a +--- func(i int) rune-signature -- +-func(i int) rune - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +--- func(string, int) bool-signature -- +-func(string, int) bool - --func Random() int { -- y := 6 + 7 -- return y --} +--- make(t Type, size ...int) Type-signature -- +-make(t Type, size ...int) Type - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-The make built-in function allocates and initializes an object of type slice, map, or chan (only). - --type Pos struct { -- x, y int --} +--- myFunc(foo int) string-signature -- +-myFunc(foo int) string - --func (p *Pos) GetSum() int { -- return p.x + p.y //@rename("x", "myX") --} +--- panic(v interface{})-signature -- +-panic(v any) - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.GetSum() //@rename("Sum", "GetSum") --} +-The panic built-in function stops normal execution of the current goroutine. - --func sw() { -- var x interface{} +--- println(args ...Type)-signature -- +-println(args ...Type) - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } --} +-The println built-in function formats its arguments in an implementation-specific way and writes the result to standard error. - ---- f2name-rename -- --package a +diff -urN a/gopls/internal/lsp/testdata/signature/signature_test.go b/gopls/internal/lsp/testdata/signature/signature_test.go +--- a/gopls/internal/lsp/testdata/signature/signature_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package signature_test - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2name "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +- "testing" +- +- sig "golang.org/lsptests/signature" -) - --func Random() int { -- y := 6 + 7 -- return y +-func TestSignature(t *testing.T) { +- sig.AliasSlice() //@signature(")", "AliasSlice(a []*sig.Alias) (b sig.Alias)", 0) +- sig.AliasMap() //@signature(")", "AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias)", 0) +- sig.OtherAliasMap() //@signature(")", "OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias", 0) -} +diff -urN a/gopls/internal/lsp/testdata/signature/signature_test.go.golden b/gopls/internal/lsp/testdata/signature/signature_test.go.golden +--- a/gopls/internal/lsp/testdata/signature/signature_test.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/signature/signature_test.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +--- AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias)-signature -- +-AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias) - --func Random2(y int) int { //@rename("y", "z") -- return y --} +--- AliasSlice(a []*sig.Alias) (b sig.Alias)-signature -- +-AliasSlice(a []*sig.Alias) (b sig.Alias) - --type Pos struct { -- x, y int --} +--- OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias-signature -- +-OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +diff -urN a/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in b/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in +--- a/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +-// +build go1.18 +-//go:build go1.18 - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +-package snippets - --func sw() { -- var x interface{} +-type SyncMap[K comparable, V any] struct{} - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2name.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } +-func NewSyncMap[K comparable, V any]() (result *SyncMap[K, V]) { //@item(NewSyncMap, "NewSyncMap", "", "") +- return -} - ---- f2y-rename -- --package a +-func Identity[P ~int](p P) P { //@item(Identity, "Identity", "", "") +- return p +-} +- +-func _() { +- _ = NewSyncM //@snippet(" //", NewSyncMap, "NewSyncMap[${1:}]()", "NewSyncMap[${1:K comparable}, ${2:V any}]()") +- _ = Identi //@snippet(" //", Identity, "Identity[${1:}](${2:})", "Identity[${1:P ~int}](${2:p P})") +-} +diff -urN a/gopls/internal/lsp/testdata/snippets/literal.go b/gopls/internal/lsp/testdata/snippets/literal.go +--- a/gopls/internal/lsp/testdata/snippets/literal.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/literal.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-package snippets - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2y "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") +- "golang.org/lsptests/signature" +- t "golang.org/lsptests/types" -) - --func Random() int { -- y := 6 + 7 -- return y +-type structy struct { +- x signature.MyType -} - --func Random2(y int) int { //@rename("y", "z") -- return y +-func X(_ map[signature.Alias]t.CoolAlias) (map[signature.Alias]t.CoolAlias) { +- return nil -} - --type Pos struct { -- x, y int +-func _() { +- X() //@signature(")", "X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias", 0) +- _ = signature.MyType{} //@item(literalMyType, "signature.MyType{}", "", "var") +- s := structy{ +- x: //@snippet(" //", literalMyType, "signature.MyType{\\}", "signature.MyType{\\}") +- } -} +\ No newline at end of file +diff -urN a/gopls/internal/lsp/testdata/snippets/literal.go.golden b/gopls/internal/lsp/testdata/snippets/literal.go.golden +--- a/gopls/internal/lsp/testdata/snippets/literal.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/literal.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +--- X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias-signature -- +-X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +diff -urN a/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in b/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in +--- a/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +-// +build go1.18 +-//go:build go1.18 - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +-package snippets - --func sw() { -- var x interface{} +-type Tree[T any] struct{} - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2y.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } --} +-func (tree Tree[T]) Do(f func(s T)) {} - ---- fmt2-rename -- --package a +-func _() { +- _ = "func(...) {}" //@item(litFunc, "func(...) {}", "", "var") +- var t Tree[string] +- t.Do(fun) //@complete(")", litFunc),snippet(")", litFunc, "func(s string) {$0\\}", "func(s string) {$0\\}") +-} +diff -urN a/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in b/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in +--- a/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,233 +0,0 @@ +-package snippets - -import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- fmt2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- "bytes" +- "context" +- "go/ast" +- "net/http" +- "sort" - --func Random() int { -- y := 6 + 7 -- return y --} +- "golang.org/lsptests/foo" +-) - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-func _() { +- []int{} //@item(litIntSlice, "[]int{}", "", "var") +- &[]int{} //@item(litIntSliceAddr, "&[]int{}", "", "var") +- make([]int, 0) //@item(makeIntSlice, "make([]int, 0)", "", "func") - --type Pos struct { -- x, y int --} +- var _ *[]int = in //@snippet(" //", litIntSliceAddr, "&[]int{$0\\}", "&[]int{$0\\}") +- var _ **[]int = in //@complete(" //") - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- var slice []int +- slice = i //@snippet(" //", litIntSlice, "[]int{$0\\}", "[]int{$0\\}") +- slice = m //@snippet(" //", makeIntSlice, "make([]int, ${1:})", "make([]int, ${1:0})") -} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- type namedInt []int - --func sw() { -- var x interface{} +- namedInt{} //@item(litNamedSlice, "namedInt{}", "", "var") +- make(namedInt, 0) //@item(makeNamedSlice, "make(namedInt, 0)", "", "func") - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- fmt2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } +- var namedSlice namedInt +- namedSlice = n //@snippet(" //", litNamedSlice, "namedInt{$0\\}", "namedInt{$0\\}") +- namedSlice = m //@snippet(" //", makeNamedSlice, "make(namedInt, ${1:})", "make(namedInt, ${1:0})") -} - ---- fmty-rename -- --package a -- --import ( -- lg "log" -- fmty "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +-func _() { +- make(chan int) //@item(makeChan, "make(chan int)", "", "func") - --func Random() int { -- y := 6 + 7 -- return y +- var ch chan int +- ch = m //@snippet(" //", makeChan, "make(chan int)", "make(chan int)") -} - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-func _() { +- map[string]struct{}{} //@item(litMap, "map[string]struct{}{}", "", "var") +- make(map[string]struct{}) //@item(makeMap, "make(map[string]struct{})", "", "func") - --type Pos struct { -- x, y int --} +- var m map[string]struct{} +- m = m //@snippet(" //", litMap, "map[string]struct{\\}{$0\\}", "map[string]struct{\\}{$0\\}") +- m = m //@snippet(" //", makeMap, "make(map[string]struct{\\})", "make(map[string]struct{\\})") - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- struct{}{} //@item(litEmptyStruct, "struct{}{}", "", "var") +- +- m["hi"] = s //@snippet(" //", litEmptyStruct, "struct{\\}{\\}", "struct{\\}{\\}") -} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- type myStruct struct{ i int } //@item(myStructType, "myStruct", "struct{...}", "struct") - --func sw() { -- var x interface{} +- myStruct{} //@item(litStruct, "myStruct{}", "", "var") +- &myStruct{} //@item(litStructPtr, "&myStruct{}", "", "var") - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmty.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } --} +- var ms myStruct +- ms = m //@snippet(" //", litStruct, "myStruct{$0\\}", "myStruct{$0\\}") - ---- format-rename -- --package a +- var msPtr *myStruct +- msPtr = m //@snippet(" //", litStructPtr, "&myStruct{$0\\}", "&myStruct{$0\\}") - --import ( -- lg "log" -- format "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- msPtr = &m //@snippet(" //", litStruct, "myStruct{$0\\}", "myStruct{$0\\}") - --func Random() int { -- y := 6 + 7 -- return y --} +- type myStructCopy struct { i int } //@item(myStructCopyType, "myStructCopy", "struct{...}", "struct") - --func Random2(y int) int { //@rename("y", "z") -- return y +- // Don't offer literal completion for convertible structs. +- ms = myStruct //@complete(" //", litStruct, myStructType, myStructCopyType) -} - --type Pos struct { -- x, y int --} +-type myImpl struct{} - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +-func (myImpl) foo() {} - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +-func (*myImpl) bar() {} - --func sw() { -- var x interface{} +-type myBasicImpl string - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- format.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +-func (myBasicImpl) foo() {} +- +-func _() { +- type myIntf interface { +- foo() - } --} - ---- log-rename -- --package a +- myImpl{} //@item(litImpl, "myImpl{}", "", "var") - --import ( -- "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- var mi myIntf +- mi = m //@snippet(" //", litImpl, "myImpl{\\}", "myImpl{\\}") - --func Random() int { -- y := 6 + 7 -- return y --} +- myBasicImpl() //@item(litBasicImpl, "myBasicImpl()", "string", "var") - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- mi = m //@snippet(" //", litBasicImpl, "myBasicImpl($0)", "myBasicImpl($0)") - --type Pos struct { -- x, y int --} +- // only satisfied by pointer to myImpl +- type myPtrIntf interface { +- bar() +- } - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- &myImpl{} //@item(litImplPtr, "&myImpl{}", "", "var") +- +- var mpi myPtrIntf +- mpi = m //@snippet(" //", litImplPtr, "&myImpl{\\}", "&myImpl{\\}") -} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +- var s struct{ i []int } //@item(litSliceField, "i", "[]int", "field") +- var foo []int +- // no literal completions after selector +- foo = s.i //@complete(" //", litSliceField) -} - --func sw() { -- var x interface{} +-func _() { +- type myStruct struct{ i int } //@item(litMyStructType, "myStruct", "struct{...}", "struct") +- myStruct{} //@item(litMyStruct, "myStruct{}", "", "var") - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- log.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } +- foo := func(s string, args ...myStruct) {} +- // Don't give literal slice candidate for variadic arg. +- // Do give literal candidates for variadic element. +- foo("", myStruct) //@complete(")", litMyStruct, litMyStructType) -} - ---- myX-rename -- --package a -- --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +-func _() { +- Buffer{} //@item(litBuffer, "Buffer{}", "", "var") - --func Random() int { -- y := 6 + 7 -- return y +- var b *bytes.Buffer +- b = bytes.Bu //@snippet(" //", litBuffer, "Buffer{\\}", "Buffer{\\}") -} - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-func _() { +- _ = "func(...) {}" //@item(litFunc, "func(...) {}", "", "var") - --type Pos struct { -- myX, y int --} +- sort.Slice(nil, fun) //@complete(")", litFunc),snippet(")", litFunc, "func(i, j int) bool {$0\\}", "func(i, j int) bool {$0\\}") - --func (p *Pos) Sum() int { -- return p.myX + p.y //@rename("x", "myX") --} +- http.HandleFunc("", f) //@snippet(")", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}", "func(${1:w} http.ResponseWriter, ${2:r} *http.Request) {$0\\}") - --func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- // no literal "func" completions +- http.Handle("", fun) //@complete(")") - --func sw() { -- var x interface{} +- http.HandlerFunc() //@item(handlerFunc, "http.HandlerFunc()", "", "var") +- http.Handle("", h) //@snippet(")", handlerFunc, "http.HandlerFunc($0)", "http.HandlerFunc($0)") +- http.Handle("", http.HandlerFunc()) //@snippet("))", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}", "func(${1:w} http.ResponseWriter, ${2:r} *http.Request) {$0\\}") - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } --} +- var namedReturn func(s string) (b bool) +- namedReturn = f //@snippet(" //", litFunc, "func(s string) (b bool) {$0\\}", "func(s string) (b bool) {$0\\}") - ---- pos-rename -- --package a +- var multiReturn func() (bool, int) +- multiReturn = f //@snippet(" //", litFunc, "func() (bool, int) {$0\\}", "func() (bool, int) {$0\\}") - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- var multiNamedReturn func() (b bool, i int) +- multiNamedReturn = f //@snippet(" //", litFunc, "func() (b bool, i int) {$0\\}", "func() (b bool, i int) {$0\\}") - --func Random() int { -- y := 6 + 7 -- return y --} +- var duplicateParams func(myImpl, int, myImpl) +- duplicateParams = f //@snippet(" //", litFunc, "func(mi1 myImpl, i int, mi2 myImpl) {$0\\}", "func(${1:mi1} myImpl, ${2:i} int, ${3:mi2} myImpl) {$0\\}") - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- type aliasImpl = myImpl +- var aliasParams func(aliasImpl) aliasImpl +- aliasParams = f //@snippet(" //", litFunc, "func(ai aliasImpl) aliasImpl {$0\\}", "func(${1:ai} aliasImpl) aliasImpl {$0\\}") - --type Pos struct { -- x, y int --} +- const two = 2 +- var builtinTypes func([]int, [two]bool, map[string]string, struct{ i int }, interface{ foo() }, <-chan int) +- builtinTypes = f //@snippet(" //", litFunc, "func(i1 []int, b [two]bool, m map[string]string, s struct{ i int \\}, i2 interface{ foo() \\}, c <-chan int) {$0\\}", "func(${1:i1} []int, ${2:b} [two]bool, ${3:m} map[string]string, ${4:s} struct{ i int \\}, ${5:i2} interface{ foo() \\}, ${6:c} <-chan int) {$0\\}") - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- var _ func(ast.Node) = f //@snippet(" //", litFunc, "func(n ast.Node) {$0\\}", "func(${1:n} ast.Node) {$0\\}") +- var _ func(error) = f //@snippet(" //", litFunc, "func(err error) {$0\\}", "func(${1:err} error) {$0\\}") +- var _ func(context.Context) = f //@snippet(" //", litFunc, "func(ctx context.Context) {$0\\}", "func(${1:ctx} context.Context) {$0\\}") +- +- type context struct {} +- var _ func(context) = f //@snippet(" //", litFunc, "func(ctx context) {$0\\}", "func(${1:ctx} context) {$0\\}") -} - -func _() { -- var pos Pos //@rename("p", "pos") -- _ = pos.Sum() //@rename("Sum", "GetSum") --} +- StructFoo{} //@item(litStructFoo, "StructFoo{}", "struct{...}", "struct") - --func sw() { -- var x interface{} +- var sfp *foo.StructFoo +- // Don't insert the "&" before "StructFoo{}". +- sfp = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}") - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } +- var sf foo.StructFoo +- sf = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}") +- sf = foo. //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}") -} - ---- y0-rename -- --package a -- --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +-func _() { +- float64() //@item(litFloat64, "float64()", "float64", "var") - --func Random() int { -- y := 6 + 7 -- return y --} +- // don't complete to "&float64()" +- var _ *float64 = float64 //@complete(" //") - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- var f float64 +- f = fl //@complete(" //", litFloat64),snippet(" //", litFloat64, "float64($0)", "float64($0)") - --type Pos struct { -- x, y int --} +- type myInt int +- myInt() //@item(litMyInt, "myInt()", "", "var") - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- var mi myInt +- mi = my //@snippet(" //", litMyInt, "myInt($0)", "myInt($0)") -} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} -- --func sw() { -- var x interface{} -- -- switch y0 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y0) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y0) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y0) //@rename("y", "y3"),rename("f2","fmt2") +- type ptrStruct struct { +- p *ptrStruct - } --} - ---- y1-rename -- --package a +- ptrStruct{} //@item(litPtrStruct, "ptrStruct{}", "", "var") - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- ptrStruct{ +- p: &ptrSt, //@rank(",", litPtrStruct) +- } - --func Random() int { -- y := 6 + 7 -- return y --} +- &ptrStruct{} //@item(litPtrStructPtr, "&ptrStruct{}", "", "var") - --func Random2(y int) int { //@rename("y", "z") -- return y +- &ptrStruct{ +- p: ptrSt, //@rank(",", litPtrStructPtr) +- } -} - --type Pos struct { -- x, y int +-func _() { +- f := func(...[]int) {} +- f() //@snippet(")", litIntSlice, "[]int{$0\\}", "[]int{$0\\}") -} - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") +- // don't complete to "untyped int()" +- []int{}[untyped] //@complete("] //") -} +diff -urN a/gopls/internal/lsp/testdata/snippets/postfix.go b/gopls/internal/lsp/testdata/snippets/postfix.go +--- a/gopls/internal/lsp/testdata/snippets/postfix.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/postfix.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,43 +0,0 @@ +-package snippets - --func sw() { -- var x interface{} +-// These tests check that postfix completions do and do not show up in +-// certain cases. Tests for the postfix completion contents are under +-// regtest. - -- switch y1 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y1) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y1) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y1) //@rename("y", "y3"),rename("f2","fmt2") -- } --} +-func _() { +- /* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet") +- var foo []int +- foo.append //@rank(" //", postfixAppend) - ---- y2-rename -- --package a +- []int{}.append //@complete(" //") - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- []int{}.last //@complete(" //") - --func Random() int { -- y := 6 + 7 -- return y --} +- /* copy! */ //@item(postfixCopy, "copy!", "duplicate slice", "snippet") - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- foo.copy //@rank(" //", postfixCopy) - --type Pos struct { -- x, y int --} +- var s struct{ i []int } +- s.i.copy //@rank(" //", postfixCopy) - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- var _ []int = s.i.copy //@complete(" //") +- +- var blah func() []int +- blah().append //@complete(" //") -} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- /* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet") +- /* last! */ //@item(postfixLast, "last!", "s[len(s)-1]", "snippet") +- /* print! */ //@item(postfixPrint, "print!", "print to stdout", "snippet") +- /* range! */ //@item(postfixRange, "range!", "range over slice", "snippet") +- /* reverse! */ //@item(postfixReverse, "reverse!", "reverse slice", "snippet") +- /* sort! */ //@item(postfixSort, "sort!", "sort.Slice()", "snippet") +- /* var! */ //@item(postfixVar, "var!", "assign to variable", "snippet") +- /* ifnotnil! */ //@item(postfixIfNotNil, "ifnotnil!", "if expr != nil", "snippet") - --func sw() { -- var x interface{} +- var foo []int +- foo. //@complete(" //", postfixAppend, postfixCopy, postfixIfNotNil, postfixLast, postfixPrint, postfixRange, postfixReverse, postfixSort, postfixVar) - -- switch y2 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y2) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y2) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y2) //@rename("y", "y3"),rename("f2","fmt2") -- } +- foo = nil -} +diff -urN a/gopls/internal/lsp/testdata/snippets/snippets.go.golden b/gopls/internal/lsp/testdata/snippets/snippets.go.golden +--- a/gopls/internal/lsp/testdata/snippets/snippets.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/snippets.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +--- baz(at AliasType, b bool)-signature -- +-baz(at AliasType, b bool) - ---- y3-rename -- --package a -- --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +diff -urN a/gopls/internal/lsp/testdata/snippets/snippets.go.in b/gopls/internal/lsp/testdata/snippets/snippets.go.in +--- a/gopls/internal/lsp/testdata/snippets/snippets.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/snippets/snippets.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,61 +0,0 @@ +-package snippets - --func Random() int { -- y := 6 + 7 -- return y --} +-type AliasType = int //@item(sigAliasType, "AliasType", "AliasType", "type") - --func Random2(y int) int { //@rename("y", "z") -- return y --} +-func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func") +-func bar(fn func()) func() {} //@item(snipBar, "bar", "func(fn func())", "func") +-func baz(at AliasType, b bool) {} //@item(snipBaz, "baz", "func(at AliasType, b bool)", "func") - --type Pos struct { -- x, y int +-type Foo struct { +- Bar int //@item(snipFieldBar, "Bar", "int", "field") +- Func func(at AliasType) error //@item(snipFieldFunc, "Func", "func(at AliasType) error", "field") -} - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") --} +-func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz", "func() func()", "method") +-func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar", "func() func()", "method") +-func (Foo) BazBaz(at AliasType) func() {} //@item(snipMethodBazBaz, "BazBaz", "func(at AliasType) func()", "method") - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- f //@snippet(" //", snipFoo, "foo(${1:})", "foo(${1:i int}, ${2:b bool})") - --func sw() { -- var x interface{} +- bar //@snippet(" //", snipBar, "bar(${1:})", "bar(${1:fn func()})") - -- switch y3 := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y3) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y3) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y3) //@rename("y", "y3"),rename("f2","fmt2") +- baz //@snippet(" //", snipBaz, "baz(${1:})", "baz(${1:at AliasType}, ${2:b bool})") +- baz() //@signature("(", "baz(at AliasType, b bool)", 0) +- +- bar(nil) //@snippet("(", snipBar, "bar", "bar") +- bar(ba) //@snippet(")", snipBar, "bar(${1:})", "bar(${1:fn func()})") +- var f Foo +- bar(f.Ba) //@snippet(")", snipMethodBaz, "Baz()", "Baz()") +- (bar)(nil) //@snippet(")", snipBar, "bar(${1:})", "bar(${1:fn func()})") +- (f.Ba)() //@snippet(")", snipMethodBaz, "Baz()", "Baz()") +- +- Foo{ +- B //@snippet(" //", snipFieldBar, "Bar: ${1:},", "Bar: ${1:int},") - } --} - ---- z-rename -- --package a +- Foo{ +- F //@snippet(" //", snipFieldFunc, "Func: ${1:},", "Func: ${1:func(at AliasType) error},") +- } - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +- Foo{B} //@snippet("}", snipFieldBar, "Bar: ${1:}", "Bar: ${1:int}") +- Foo{} //@snippet("}", snipFieldBar, "Bar: ${1:}", "Bar: ${1:int}") - --func Random() int { -- y := 6 + 7 -- return y --} +- Foo{Foo{}.B} //@snippet("} ", snipFieldBar, "Bar", "Bar") - --func Random2(z int) int { //@rename("y", "z") -- return z --} +- var err error +- err.Error() //@snippet("E", Error, "Error()", "Error()") +- f.Baz() //@snippet("B", snipMethodBaz, "Baz()", "Baz()") - --type Pos struct { -- x, y int --} +- f.Baz() //@snippet("(", snipMethodBazBar, "BazBar", "BazBar") - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- f.Baz() //@snippet("B", snipMethodBazBaz, "BazBaz(${1:})", "BazBaz(${1:at AliasType})") -} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} -- --func sw() { -- var x interface{} -- -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") +- type bar struct { +- a int +- b float64 //@item(snipBarB, "b", "float64", "field") - } +- bar{b} //@snippet("}", snipBarB, "b: ${1:}", "b: ${1:float64}") -} -- -diff -urN a/gopls/internal/lsp/testdata/rename/a/random.go.in b/gopls/internal/lsp/testdata/rename/a/random.go.in ---- a/gopls/internal/lsp/testdata/rename/a/random.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/a/random.go.in 1970-01-01 00:00:00.000000000 +0000 +diff -urN a/gopls/internal/lsp/testdata/statements/append.go b/gopls/internal/lsp/testdata/statements/append.go +--- a/gopls/internal/lsp/testdata/statements/append.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/statements/append.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,42 +0,0 @@ --package a +-package statements - --import ( -- lg "log" -- "fmt" //@rename("fmt", "fmty") -- f2 "fmt" //@rename("f2", "f2name"),rename("fmt","f2y") --) +-func _() { +- type mySlice []int - --func Random() int { -- y := 6 + 7 -- return y --} +- var ( +- abc []int //@item(stmtABC, "abc", "[]int", "var") +- abcdef mySlice //@item(stmtABCDEF, "abcdef", "mySlice", "var") +- ) - --func Random2(y int) int { //@rename("y", "z") -- return y --} +- /* abcdef = append(abcdef, ) */ //@item(stmtABCDEFAssignAppend, "abcdef = append(abcdef, )", "", "func") - --type Pos struct { -- x, y int --} +- // don't offer "abc = append(abc, )" because "abc" isn't necessarily +- // better than "abcdef". +- abc //@complete(" //", stmtABC, stmtABCDEF) - --func (p *Pos) Sum() int { -- return p.x + p.y //@rename("x", "myX") +- abcdef //@complete(" //", stmtABCDEF, stmtABCDEFAssignAppend) +- +- /* append(abc, ) */ //@item(stmtABCAppend, "append(abc, )", "", "func") +- +- abc = app //@snippet(" //", stmtABCAppend, "append(abc, ${1:})", "append(abc, ${1:})") -} - -func _() { -- var p Pos //@rename("p", "pos") -- _ = p.Sum() //@rename("Sum", "GetSum") --} +- var s struct{ xyz []int } - --func sw() { -- var x interface{} +- /* xyz = append(s.xyz, ) */ //@item(stmtXYZAppend, "xyz = append(s.xyz, )", "", "func") - -- switch y := x.(type) { //@rename("y", "y0") -- case int: -- fmt.Printf("%d", y) //@rename("y", "y1"),rename("fmt", "format") -- case string: -- lg.Printf("%s", y) //@rename("y", "y2"),rename("lg","log") -- default: -- f2.Printf("%v", y) //@rename("y", "y3"),rename("f2","fmt2") -- } --} -diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go b/gopls/internal/lsp/testdata/rename/b/b.go ---- a/gopls/internal/lsp/testdata/rename/b/b.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/b/b.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ --package b +- s.x //@snippet(" //", stmtXYZAppend, "xyz = append(s.xyz, ${1:})", "xyz = append(s.xyz, ${1:})") - --var c int //@rename("int", "uint") +- /* s.xyz = append(s.xyz, ) */ //@item(stmtDeepXYZAppend, "s.xyz = append(s.xyz, )", "", "func") - --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a +- sx //@snippet(" //", stmtDeepXYZAppend, "s.xyz = append(s.xyz, ${1:})", "s.xyz = append(s.xyz, ${1:})") -} - --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") --) -- --/* --Hello description --*/ --func Hello() {} //@rename("Hello", "Goodbye") -diff -urN a/gopls/internal/lsp/testdata/rename/b/b.go.golden b/gopls/internal/lsp/testdata/rename/b/b.go.golden ---- a/gopls/internal/lsp/testdata/rename/b/b.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/b/b.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,78 +0,0 @@ ---- Bob-rename -- --package b +-func _() { +- var foo [][]int - --var c int //@rename("int", "uint") +- /* append(foo[0], ) */ //@item(stmtFooAppend, "append(foo[0], )", "", "func") - --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a +- foo[0] = app //@complete(" //"),snippet(" //", stmtFooAppend, "append(foo[0], ${1:})", "append(foo[0], ${1:})") -} +diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go b/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go +--- a/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-package statements - --var ( -- // Hello there. -- // Bob does the thing. -- Bob int //@rename("Foo", "Bob") --) -- --/* --Hello description --*/ --func Hello() {} //@rename("Hello", "Goodbye") +-import "os" - ---- Goodbye-rename -- --b.go: --package b +-func two() error { +- var s struct{ err error } - --var c int //@rename("int", "uint") +- /* if s.err != nil { return s.err } */ //@item(stmtTwoIfErrReturn, "if s.err != nil { return s.err }", "", "") - --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a +- _, s.err = os.Open("foo") +- //@snippet("", stmtTwoIfErrReturn, "", "if s.err != nil {\n\treturn ${1:s.err}\n\\}") -} +diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_return.go b/gopls/internal/lsp/testdata/statements/if_err_check_return.go +--- a/gopls/internal/lsp/testdata/statements/if_err_check_return.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/statements/if_err_check_return.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package statements - --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") +-import ( +- "bytes" +- "io" +- "os" -) - --/* --Goodbye description --*/ --func Goodbye() {} //@rename("Hello", "Goodbye") -- --c.go: --package c +-func one() (int, float32, io.Writer, *int, []int, bytes.Buffer, error) { +- /* if err != nil { return err } */ //@item(stmtOneIfErrReturn, "if err != nil { return err }", "", "") +- /* err != nil { return err } */ //@item(stmtOneErrReturn, "err != nil { return err }", "", "") - --import "golang.org/lsptests/rename/b" +- _, err := os.Open("foo") +- //@snippet("", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") - --func _() { -- b.Goodbye() //@rename("Hello", "Goodbye") --} +- _, err = os.Open("foo") +- i //@snippet(" //", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") - ---- error-rename -- --package b +- _, err = os.Open("foo") +- if er //@snippet(" //", stmtOneErrReturn, "", "err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") - --var c int //@rename("int", "uint") +- _, err = os.Open("foo") +- if //@snippet(" //", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") - --func _() { -- error := 1 //@rename("a", "error") -- error = 2 -- _ = error +- _, err = os.Open("foo") +- if //@snippet("//", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") -} +diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_test.go b/gopls/internal/lsp/testdata/statements/if_err_check_test.go +--- a/gopls/internal/lsp/testdata/statements/if_err_check_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/statements/if_err_check_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-package statements - --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") +-import ( +- "os" +- "testing" -) - --/* --Hello description --*/ --func Hello() {} //@rename("Hello", "Goodbye") +-func TestErr(t *testing.T) { +- /* if err != nil { t.Fatal(err) } */ //@item(stmtOneIfErrTFatal, "if err != nil { t.Fatal(err) }", "", "") - ---- uint-rename -- --int is built in and cannot be renamed -diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden ---- a/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,2 +0,0 @@ ---- rFunc-rename -- --renaming "sFunc" to "rFunc" not possible because "golang.org/lsptests/rename/bad" has errors -diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad.go.in b/gopls/internal/lsp/testdata/rename/bad/bad.go.in ---- a/gopls/internal/lsp/testdata/rename/bad/bad.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/bad/bad.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package bad +- _, err := os.Open("foo") +- //@snippet("", stmtOneIfErrTFatal, "", "if err != nil {\n\tt.Fatal(err)\n\\}") +-} - --type myStruct struct { +-func BenchmarkErr(b *testing.B) { +- /* if err != nil { b.Fatal(err) } */ //@item(stmtOneIfErrBFatal, "if err != nil { b.Fatal(err) }", "", "") +- +- _, err := os.Open("foo") +- //@snippet("", stmtOneIfErrBFatal, "", "if err != nil {\n\tb.Fatal(err)\n\\}") -} +diff -urN a/gopls/internal/lsp/testdata/stub/other/other.go b/gopls/internal/lsp/testdata/stub/other/other.go +--- a/gopls/internal/lsp/testdata/stub/other/other.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/other/other.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-package other - --func (s *myStruct) sFunc() bool { //@rename("sFunc", "rFunc") -- return s.Bad +-import ( +- "bytes" +- renamed_context "context" +-) +- +-type Interface interface { +- Get(renamed_context.Context) *bytes.Buffer -} -diff -urN a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in ---- a/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/bad/bad_test.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1 +0,0 @@ --package bad -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go b/gopls/internal/lsp/testdata/rename/c/c2.go ---- a/gopls/internal/lsp/testdata/rename/c/c2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c2.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,4 +0,0 @@ --package c +diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go b/gopls/internal/lsp/testdata/stub/stub_add_selector.go +--- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-package stub - --//go:embed Static/* --var Static embed.FS //@rename("Static", "static") -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/rename/c/c2.go.golden b/gopls/internal/lsp/testdata/rename/c/c2.go.golden ---- a/gopls/internal/lsp/testdata/rename/c/c2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c2.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ ---- static-rename -- --package c +-import "io" +- +-// This file tests that if an interface +-// method references a type from its own package +-// then our implementation must add the import/package selector +-// in the concrete method if the concrete type is outside of the interface +-// package +-var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "quickfix", "") +- +-type readerFrom struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +--- suggestedfix_stub_add_selector_10_23 -- +-package stub - --//go:embed Static/* --var static embed.FS //@rename("Static", "static") -diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go b/gopls/internal/lsp/testdata/rename/c/c.go ---- a/gopls/internal/lsp/testdata/rename/c/c.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package c +-import "io" - --import "golang.org/lsptests/rename/b" +-// This file tests that if an interface +-// method references a type from its own package +-// then our implementation must add the import/package selector +-// in the concrete method if the concrete type is outside of the interface +-// package +-var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "quickfix", "") - --func _() { -- b.Hello() //@rename("Hello", "Goodbye") +-type readerFrom struct{} +- +-// ReadFrom implements io.ReaderFrom. +-func (*readerFrom) ReadFrom(r io.Reader) (n int64, err error) { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/rename/c/c.go.golden b/gopls/internal/lsp/testdata/rename/c/c.go.golden ---- a/gopls/internal/lsp/testdata/rename/c/c.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/c/c.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,32 +0,0 @@ ---- Goodbye-rename -- --b.go: --package b - --var c int //@rename("int", "uint") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go b/gopls/internal/lsp/testdata/stub/stub_assign.go +--- a/gopls/internal/lsp/testdata/stub/stub_assign.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,10 +0,0 @@ +-package stub - --func _() { -- a := 1 //@rename("a", "error") -- a = 2 -- _ = a +-import "io" +- +-func main() { +- var br io.ByteWriter +- br = &byteWriter{} //@suggestedfix("&", "quickfix", "") -} - --var ( -- // Hello there. -- // Foo does the thing. -- Foo int //@rename("Foo", "Bob") --) +-type byteWriter struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +--- suggestedfix_stub_assign_7_7 -- +-package stub - --/* --Goodbye description --*/ --func Goodbye() {} //@rename("Hello", "Goodbye") +-import "io" - --c.go: --package c +-func main() { +- var br io.ByteWriter +- br = &byteWriter{} //@suggestedfix("&", "quickfix", "") +-} - --import "golang.org/lsptests/rename/b" +-type byteWriter struct{} - --func _() { -- b.Goodbye() //@rename("Hello", "Goodbye") +-// WriteByte implements io.ByteWriter. +-func (*byteWriter) WriteByte(c byte) error { +- panic("unimplemented") -} - -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go ---- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package another -- --type ( -- I interface{ F() } -- C struct{ I } --) +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go +--- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --func (C) g() +-import "io" - --func _() { -- var x I = C{} -- x.F() //@rename("F", "G") +-func main() { +- var br io.ByteWriter +- var i int +- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "quickfix", "") -} -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden ---- a/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/another/another.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ ---- G-rename -- --package another - --type ( -- I interface{ G() } -- C struct{ I } --) +-type multiByteWriter struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_assign_multivars_8_13 -- +-package stub - --func (C) g() +-import "io" - --func _() { -- var x I = C{} -- x.G() //@rename("F", "G") +-func main() { +- var br io.ByteWriter +- var i int +- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "quickfix", "") -} - -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go ---- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package crosspkg -- --func Foo() { //@rename("Foo", "Dolphin") +-type multiByteWriter struct{} - +-// WriteByte implements io.ByteWriter. +-func (*multiByteWriter) WriteByte(c byte) error { +- panic("unimplemented") -} - --var Bar int //@rename("Bar", "Tomato") -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden ---- a/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,40 +0,0 @@ ---- Dolphin-rename -- --crosspkg.go: --package crosspkg -- --func Dolphin() { //@rename("Foo", "Dolphin") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go b/gopls/internal/lsp/testdata/stub/stub_call_expr.go +--- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package stub - +-func main() { +- check(&callExpr{}) //@suggestedfix("&", "quickfix", "") -} - --var Bar int //@rename("Bar", "Tomato") -- --other.go: --package other +-func check(err error) { +- if err != nil { +- panic(err) +- } +-} - --import "golang.org/lsptests/rename/crosspkg" +-type callExpr struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +--- suggestedfix_stub_call_expr_4_8 -- +-package stub - --func Other() { -- crosspkg.Bar -- crosspkg.Dolphin() //@rename("Foo", "Flamingo") +-func main() { +- check(&callExpr{}) //@suggestedfix("&", "quickfix", "") -} - ---- Tomato-rename -- --crosspkg.go: --package crosspkg +-func check(err error) { +- if err != nil { +- panic(err) +- } +-} - --func Foo() { //@rename("Foo", "Dolphin") +-type callExpr struct{} - +-// Error implements error. +-func (*callExpr) Error() string { +- panic("unimplemented") -} - --var Tomato int //@rename("Bar", "Tomato") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go b/gopls/internal/lsp/testdata/stub/stub_embedded.go +--- a/gopls/internal/lsp/testdata/stub/stub_embedded.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-package stub - --other.go: --package other +-import ( +- "io" +- "sort" +-) - --import "golang.org/lsptests/rename/crosspkg" +-var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "quickfix", "") - --func Other() { -- crosspkg.Tomato -- crosspkg.Foo() //@rename("Foo", "Flamingo") +-type embeddedConcrete struct{} +- +-type embeddedInterface interface { +- sort.Interface +- io.Reader -} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,37 +0,0 @@ +--- suggestedfix_stub_embedded_8_27 -- +-package stub - -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go ---- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package other +-import ( +- "io" +- "sort" +-) - --import "golang.org/lsptests/rename/crosspkg" +-var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "quickfix", "") - --func Other() { -- crosspkg.Bar -- crosspkg.Foo() //@rename("Foo", "Flamingo") +-type embeddedConcrete struct{} +- +-// Len implements embeddedInterface. +-func (*embeddedConcrete) Len() int { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden ---- a/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/crosspkg/other/other.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ ---- Flamingo-rename -- --crosspkg.go: --package crosspkg - --func Flamingo() { //@rename("Foo", "Dolphin") +-// Less implements embeddedInterface. +-func (*embeddedConcrete) Less(i int, j int) bool { +- panic("unimplemented") +-} - +-// Read implements embeddedInterface. +-func (*embeddedConcrete) Read(p []byte) (n int, err error) { +- panic("unimplemented") -} - --var Bar int //@rename("Bar", "Tomato") +-// Swap implements embeddedInterface. +-func (*embeddedConcrete) Swap(i int, j int) { +- panic("unimplemented") +-} - --other.go: --package other +-type embeddedInterface interface { +- sort.Interface +- io.Reader +-} - --import "golang.org/lsptests/rename/crosspkg" +diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go b/gopls/internal/lsp/testdata/stub/stub_err.go +--- a/gopls/internal/lsp/testdata/stub/stub_err.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_err.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package stub - --func Other() { -- crosspkg.Bar -- crosspkg.Flamingo() //@rename("Foo", "Flamingo") +-func main() { +- var br error = &customErr{} //@suggestedfix("&", "quickfix", "") -} - -diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go b/gopls/internal/lsp/testdata/rename/generics/embedded.go ---- a/gopls/internal/lsp/testdata/rename/generics/embedded.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-type customErr struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go.golden b/gopls/internal/lsp/testdata/stub/stub_err.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_err.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_err.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +--- suggestedfix_stub_err_4_17 -- +-package stub - --package generics +-func main() { +- var br error = &customErr{} //@suggestedfix("&", "quickfix", "") +-} - --type foo[P any] int //@rename("foo","bar") +-type customErr struct{} - --var x struct{ foo[int] } +-// Error implements error. +-func (*customErr) Error() string { +- panic("unimplemented") +-} - --var _ = x.foo -diff -urN a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden ---- a/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/embedded.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ ---- bar-rename -- --//go:build go1.18 --// +build go1.18 +diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go b/gopls/internal/lsp/testdata/stub/stub_function_return.go +--- a/gopls/internal/lsp/testdata/stub/stub_function_return.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --package generics +-import ( +- "io" +-) - --type bar[P any] int //@rename("foo","bar") +-func newCloser() io.Closer { +- return closer{} //@suggestedfix("c", "quickfix", "") +-} - --var x struct{ bar[int] } +-type closer struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_function_return_8_9 -- +-package stub - --var _ = x.bar +-import ( +- "io" +-) - -diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go b/gopls/internal/lsp/testdata/rename/generics/generics.go ---- a/gopls/internal/lsp/testdata/rename/generics/generics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/generics.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,25 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-func newCloser() io.Closer { +- return closer{} //@suggestedfix("c", "quickfix", "") +-} - --package generics +-type closer struct{} - --type G[P any] struct { -- F int +-// Close implements io.Closer. +-func (closer) Close() error { +- panic("unimplemented") -} - --func (G[_]) M() {} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go +--- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,15 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p --} +-package stub - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.M() //@rename("M", "N") +-import "io" - -- var y G[string] -- _ = y.F -- y.M() +-// This file tests that that the stub method generator accounts for concrete +-// types that have type parameters defined. +-var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "quickfix", "Implement io.ReaderFrom") +- +-type genReader[T, Y any] struct { +- T T +- Y Y -} -diff -urN a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden ---- a/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/generics.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,108 +0,0 @@ ---- H-rename -- +diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +--- suggestedfix_stub_generic_receiver_10_23 -- -//go:build go1.18 -// +build go1.18 - --package generics +-package stub - --type H[P any] struct { -- F int --} +-import "io" - --func (H[_]) M() {} +-// This file tests that that the stub method generator accounts for concrete +-// types that have type parameters defined. +-var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "quickfix", "Implement io.ReaderFrom") - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p +-type genReader[T, Y any] struct { +- T T +- Y Y -} - --func _() { -- var x H[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.M() //@rename("M", "N") -- -- var y H[string] -- _ = y.F -- y.M() +-// ReadFrom implements io.ReaderFrom. +-func (*genReader[T, Y]) ReadFrom(r io.Reader) (n int64, err error) { +- panic("unimplemented") -} - ---- K-rename -- --//go:build go1.18 --// +build go1.18 +diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go +--- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-package stub - --package generics +-import ( +- "compress/zlib" +- . "io" +- _ "io" +-) - --type G[P any] struct { -- K int --} +-// This file tests that dot-imports and underscore imports +-// are properly ignored and that a new import is added to +-// reference method types - --func (G[_]) M() {} +-var ( +- _ Reader +- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "quickfix", "") +-) - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p --} +-type ignoredResetter struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +--- suggestedfix_stub_ignored_imports_15_20 -- +-package stub - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.K //@rename("F", "K") -- x.M() //@rename("M", "N") +-import ( +- "compress/zlib" +- . "io" +- _ "io" +-) - -- var y G[string] -- _ = y.K -- y.M() --} +-// This file tests that dot-imports and underscore imports +-// are properly ignored and that a new import is added to +-// reference method types - ---- N-rename -- --//go:build go1.18 --// +build go1.18 +-var ( +- _ Reader +- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "quickfix", "") +-) - --package generics +-type ignoredResetter struct{} - --type G[P any] struct { -- F int +-// Reset implements zlib.Resetter. +-func (*ignoredResetter) Reset(r Reader, dict []byte) error { +- panic("unimplemented") -} - --func (G[_]) N() {} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go b/gopls/internal/lsp/testdata/stub/stub_issue2606.go +--- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,7 +0,0 @@ +-package stub - --func F[P any](P) { -- var p P //@rename("P", "Q") -- _ = p --} +-type I interface{ error } - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.N() //@rename("M", "N") +-type C int - -- var y G[string] -- _ = y.F -- y.N() --} +-var _ I = C(0) //@suggestedfix("C", "quickfix", "") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,14 +0,0 @@ +--- suggestedfix_stub_issue2606_7_11 -- +-package stub - ---- Q-rename -- --//go:build go1.18 --// +build go1.18 +-type I interface{ error } - --package generics +-type C int - --type G[P any] struct { -- F int +-// Error implements I. +-func (C) Error() string { +- panic("unimplemented") -} - --func (G[_]) M() {} +-var _ I = C(0) //@suggestedfix("C", "quickfix", "") - --func F[Q any](Q) { -- var p Q //@rename("P", "Q") -- _ = p --} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go b/gopls/internal/lsp/testdata/stub/stub_multi_var.go +--- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --func _() { -- var x G[int] //@rename("G", "H") -- _ = x.F //@rename("F", "K") -- x.M() //@rename("M", "N") +-import "io" - -- var y G[string] -- _ = y.F -- y.M() --} +-// This test ensures that a variable declaration that +-// has multiple values on the same line can still be +-// analyzed correctly to target the interface implementation +-// diagnostic. +-var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "quickfix", "") +- +-type multiVar struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_multi_var_9_38 -- +-package stub - -diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go b/gopls/internal/lsp/testdata/rename/generics/unions.go ---- a/gopls/internal/lsp/testdata/rename/generics/unions.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/unions.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-import "io" - --package generics +-// This test ensures that a variable declaration that +-// has multiple values on the same line can still be +-// analyzed correctly to target the interface implementation +-// diagnostic. +-var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "quickfix", "") - --type T string //@rename("T", "R") +-type multiVar struct{} - --type C interface { -- T | ~int //@rename("T", "S") +-// Read implements io.Reader. +-func (*multiVar) Read(p []byte) (n int, err error) { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden ---- a/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/generics/unions.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ ---- R-rename -- --//go:build go1.18 --// +build go1.18 - --package generics +diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go b/gopls/internal/lsp/testdata/stub/stub_pointer.go +--- a/gopls/internal/lsp/testdata/stub/stub_pointer.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package stub - --type R string //@rename("T", "R") +-import "io" - --type C interface { -- R | ~int //@rename("T", "S") +-func getReaderFrom() io.ReaderFrom { +- return &pointerImpl{} //@suggestedfix("&", "quickfix", "") -} - ---- S-rename -- --//go:build go1.18 --// +build go1.18 -- --package generics +-type pointerImpl struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_stub_pointer_6_9 -- +-package stub - --type S string //@rename("T", "R") +-import "io" - --type C interface { -- S | ~int //@rename("T", "S") +-func getReaderFrom() io.ReaderFrom { +- return &pointerImpl{} //@suggestedfix("&", "quickfix", "") -} - -diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ ---- bar-rename -- --package issue39614 +-type pointerImpl struct{} - --func fn() { -- var bar bool //@rename("foo","bar") -- make(map[string]bool -- if true { -- } +-// ReadFrom implements io.ReaderFrom. +-func (*pointerImpl) ReadFrom(r io.Reader) (n int64, err error) { +- panic("unimplemented") -} - -diff -urN a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in ---- a/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue39614/issue39614.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package issue39614 -- --func fn() { -- var foo bool //@rename("foo","bar") -- make(map[string]bool -- if true { -- } --} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go b/gopls/internal/lsp/testdata/rename/issue42134/1.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/1.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package issue42134 +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package stub - --func _() { -- // foo computes things. -- foo := func() {} +-import ( +- "compress/zlib" +- myio "io" +-) - -- foo() //@rename("foo", "bar") --} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/1.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ ---- bar-rename -- --package issue42134 +-var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "quickfix", "") +-var _ myio.Reader - --func _() { -- // bar computes things. -- bar := func() {} +-type myIO struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +--- suggestedfix_stub_renamed_import_8_23 -- +-package stub - -- bar() //@rename("foo", "bar") --} +-import ( +- "compress/zlib" +- myio "io" +-) - -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go b/gopls/internal/lsp/testdata/rename/issue42134/2.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package issue42134 +-var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "quickfix", "") +-var _ myio.Reader - --import "fmt" +-type myIO struct{} - --func _() { -- // minNumber is a min number. -- // Second line. -- minNumber := min(1, 2) -- fmt.Println(minNumber) //@rename("minNumber", "res") +-// Reset implements zlib.Resetter. +-func (*myIO) Reset(r myio.Reader, dict []byte) error { +- panic("unimplemented") -} - --func min(a, b int) int { return a } -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/2.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ ---- res-rename -- --package issue42134 +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package stub - --import "fmt" +-import ( +- "golang.org/lsptests/stub/other" +-) - --func _() { -- // res is a min number. -- // Second line. -- res := min(1, 2) -- fmt.Println(res) //@rename("minNumber", "res") --} +-// This file tests that if an interface +-// method references an import from its own package +-// that the concrete type does not yet import, and that import happens +-// to be renamed, then we prefer the renaming of the interface. +-var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "quickfix", "") - --func min(a, b int) int { return a } +-type otherInterfaceImpl struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +--- suggestedfix_stub_renamed_import_iface_11_25 -- +-package stub - -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go b/gopls/internal/lsp/testdata/rename/issue42134/3.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/3.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package issue42134 +-import ( +- "bytes" +- "context" +- "golang.org/lsptests/stub/other" +-) - --func _() { -- /* -- tests contains test cases -- */ -- tests := []struct { //@rename("tests", "testCases") -- in, out string -- }{} -- _ = tests --} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/3.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- testCases-rename -- --package issue42134 +-// This file tests that if an interface +-// method references an import from its own package +-// that the concrete type does not yet import, and that import happens +-// to be renamed, then we prefer the renaming of the interface. +-var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "quickfix", "") - --func _() { -- /* -- testCases contains test cases -- */ -- testCases := []struct { //@rename("tests", "testCases") -- in, out string -- }{} -- _ = testCases +-type otherInterfaceImpl struct{} +- +-// Get implements other.Interface. +-func (*otherInterfaceImpl) Get(context.Context) *bytes.Buffer { +- panic("unimplemented") -} - -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go b/gopls/internal/lsp/testdata/rename/issue42134/4.go ---- a/gopls/internal/lsp/testdata/rename/issue42134/4.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package issue42134 +diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go b/gopls/internal/lsp/testdata/stub/stub_stdlib.go +--- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package stub - --func _() { -- // a is equal to 5. Comment must stay the same +-import ( +- "io" +-) - -- a := 5 -- _ = a //@rename("a", "b") --} -diff -urN a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue42134/4.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ ---- b-rename -- --package issue42134 +-var _ io.Writer = writer{} //@suggestedfix("w", "quickfix", "") - --func _() { -- // a is equal to 5. Comment must stay the same +-type writer struct{} +diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +--- suggestedfix_stub_stdlib_7_19 -- +-package stub - -- b := 5 -- _ = b //@rename("a", "b") --} +-import ( +- "io" +-) - -diff -urN a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden ---- a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- bar-rename -- --package issue43616 +-var _ io.Writer = writer{} //@suggestedfix("w", "quickfix", "") - --type bar int //@rename("foo","bar"),prepare("oo","foo","foo") +-type writer struct{} - --var x struct{ bar } //@rename("foo","baz") +-// Write implements io.Writer. +-func (writer) Write(p []byte) (n int, err error) { +- panic("unimplemented") +-} - --var _ = x.bar //@rename("foo","quux") +diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go +--- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-package stub - ---- baz-rename -- --can't rename embedded fields: rename the type directly or name the field ---- quux-rename -- --can't rename embedded fields: rename the type directly or name the field -diff -urN a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in ---- a/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/issue43616/issue43616.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package issue43616 +-// Regression test for Issue #56825: file corrupted by insertion of +-// methods after TypeSpec in a parenthesized TypeDecl. - --type foo int //@rename("foo","bar"),prepare("oo","foo","foo") +-import "io" - --var x struct{ foo } //@rename("foo","baz") +-func newReadCloser() io.ReadCloser { +- return rdcloser{} //@suggestedfix("rd", "quickfix", "") +-} - --var _ = x.foo //@rename("foo","quux") -diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go b/gopls/internal/lsp/testdata/rename/shadow/shadow.go ---- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ --package shadow +-type ( +- A int +- rdcloser struct{} +- B int +-) - -func _() { -- a := true -- b, c, _ := A(), B(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") -- d := false -- _, _, _, _ = a, b, c, d +- // Local types can't be stubbed as there's nowhere to put the methods. +- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. +- type local struct{} +- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` -} - --func A() int { -- return 0 +-type ( +- C int +-) +diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden +--- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,39 +0,0 @@ +--- suggestedfix_stub_typedecl_group_9_9 -- +-package stub +- +-// Regression test for Issue #56825: file corrupted by insertion of +-// methods after TypeSpec in a parenthesized TypeDecl. +- +-import "io" +- +-func newReadCloser() io.ReadCloser { +- return rdcloser{} //@suggestedfix("rd", "quickfix", "") -} - --func B() int { -- return 0 +-type ( +- A int +- rdcloser struct{} +- B int +-) +- +-// Close implements io.ReadCloser. +-func (rdcloser) Close() error { +- panic("unimplemented") -} - --func D() int { -- return 0 +-// Read implements io.ReadCloser. +-func (rdcloser) Read(p []byte) (n int, err error) { +- panic("unimplemented") -} -diff -urN a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden ---- a/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/shadow/shadow.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,51 +0,0 @@ ---- a-rename -- --shadow/shadow.go:10:6: renaming this func "A" to "a" --shadow/shadow.go:5:13: would cause this reference to become shadowed --shadow/shadow.go:4:2: by this intervening var definition ---- b-rename -- --package shadow - -func _() { -- a := true -- b, c, _ := A(), b(), D() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") -- d := false -- _, _, _, _ = a, b, c, d +- // Local types can't be stubbed as there's nowhere to put the methods. +- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. +- type local struct{} +- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` -} - --func A() int { -- return 0 --} +-type ( +- C int +-) - --func b() int { -- return 0 --} +diff -urN a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go +--- a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,11 +0,0 @@ +-package suggestedfix - --func D() int { -- return 0 +-import ( +- "log" +-) +- +-func goodbye() { +- s := "hiiiiiii" +- s = s //@suggestedfix("s = s", "quickfix", "") +- log.Print(s) -} +diff -urN a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden +--- a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +--- suggestedfix_has_suggested_fix_9_2 -- +-package suggestedfix - ---- c-rename -- --shadow/shadow.go:5:2: renaming this var "b" to "c" --shadow/shadow.go:5:5: conflicts with var in same block ---- d-rename -- --package shadow +-import ( +- "log" +-) - --func _() { -- a := true -- b, c, _ := A(), B(), d() //@rename("A", "a"),rename("B", "b"),rename("b", "c"),rename("D", "d") -- d := false -- _, _, _, _ = a, b, c, d +-func goodbye() { +- s := "hiiiiiii" +- //@suggestedfix("s = s", "quickfix", "") +- log.Print(s) -} - --func A() int { -- return 0 --} +diff -urN a/gopls/internal/lsp/testdata/summary_go1.18.txt.golden b/gopls/internal/lsp/testdata/summary_go1.18.txt.golden +--- a/gopls/internal/lsp/testdata/summary_go1.18.txt.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/summary_go1.18.txt.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +--- summary -- +-CallHierarchyCount = 2 +-CodeLensCount = 5 +-CompletionsCount = 264 +-CompletionSnippetCount = 115 +-UnimportedCompletionsCount = 5 +-DeepCompletionsCount = 5 +-FuzzyCompletionsCount = 8 +-RankedCompletionsCount = 174 +-CaseSensitiveCompletionsCount = 4 +-DiagnosticsCount = 23 +-FoldingRangesCount = 2 +-SemanticTokenCount = 3 +-SuggestedFixCount = 80 +-MethodExtractionCount = 8 +-DefinitionsCount = 46 +-TypeDefinitionsCount = 18 +-HighlightsCount = 70 +-InlayHintsCount = 5 +-RenamesCount = 48 +-PrepareRenamesCount = 7 +-SignaturesCount = 33 +-LinksCount = 7 +-SelectionRangesCount = 3 - --func B() int { -- return 0 --} +diff -urN a/gopls/internal/lsp/testdata/summary_go1.21.txt.golden b/gopls/internal/lsp/testdata/summary_go1.21.txt.golden +--- a/gopls/internal/lsp/testdata/summary_go1.21.txt.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/summary_go1.21.txt.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +--- summary -- +-CallHierarchyCount = 2 +-CodeLensCount = 5 +-CompletionsCount = 263 +-CompletionSnippetCount = 115 +-UnimportedCompletionsCount = 5 +-DeepCompletionsCount = 5 +-FuzzyCompletionsCount = 8 +-RankedCompletionsCount = 174 +-CaseSensitiveCompletionsCount = 4 +-DiagnosticsCount = 24 +-FoldingRangesCount = 2 +-SemanticTokenCount = 3 +-SuggestedFixCount = 80 +-MethodExtractionCount = 8 +-DefinitionsCount = 46 +-TypeDefinitionsCount = 18 +-HighlightsCount = 70 +-InlayHintsCount = 5 +-RenamesCount = 48 +-PrepareRenamesCount = 7 +-SignaturesCount = 33 +-LinksCount = 7 +-SelectionRangesCount = 3 - --func d() int { -- return 0 --} +diff -urN a/gopls/internal/lsp/testdata/summary.txt.golden b/gopls/internal/lsp/testdata/summary.txt.golden +--- a/gopls/internal/lsp/testdata/summary.txt.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/summary.txt.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +--- summary -- +-CallHierarchyCount = 2 +-CodeLensCount = 5 +-CompletionsCount = 263 +-CompletionSnippetCount = 106 +-UnimportedCompletionsCount = 5 +-DeepCompletionsCount = 5 +-FuzzyCompletionsCount = 8 +-RankedCompletionsCount = 164 +-CaseSensitiveCompletionsCount = 4 +-DiagnosticsCount = 23 +-FoldingRangesCount = 2 +-SemanticTokenCount = 3 +-SuggestedFixCount = 74 +-MethodExtractionCount = 8 +-DefinitionsCount = 46 +-TypeDefinitionsCount = 18 +-HighlightsCount = 70 +-InlayHintsCount = 4 +-RenamesCount = 41 +-PrepareRenamesCount = 7 +-SignaturesCount = 33 +-LinksCount = 7 +-SelectionRangesCount = 3 - -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go b/gopls/internal/lsp/testdata/rename/testy/testy.go ---- a/gopls/internal/lsp/testdata/rename/testy/testy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ +diff -urN a/gopls/internal/lsp/testdata/testy/testy.go b/gopls/internal/lsp/testdata/testy/testy.go +--- a/gopls/internal/lsp/testdata/testy/testy.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/testy/testy.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ -package testy - --type tt int //@rename("tt", "testyType") -- --func a() { -- foo := 42 //@rename("foo", "bar") +-func a() { //@item(funcA, "a", "func()", "func") +- //@complete("", funcA) -} -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden ---- a/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy.go.golden 1970-01-01 00:00:00.000000000 +0000 +diff -urN a/gopls/internal/lsp/testdata/testy/testy_test.go b/gopls/internal/lsp/testdata/testy/testy_test.go +--- a/gopls/internal/lsp/testdata/testy/testy_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/testy/testy_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ ---- bar-rename -- -package testy - --type tt int //@rename("tt", "testyType") +-import ( +- "testing" +- +- sig "golang.org/lsptests/signature" +- "golang.org/lsptests/snippets" +-) +- +-func TestSomething(t *testing.T) { //@item(TestSomething, "TestSomething(t *testing.T)", "", "func") +- var x int //@mark(testyX, "x"),diag("x", "compiler", "x declared (and|but) not used", "error") +- a() //@mark(testyA, "a") +-} +- +-func _() { +- _ = snippets.X(nil) //@signature("nil", "X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias", 0) +- var _ sig.Alias +-} +diff -urN a/gopls/internal/lsp/testdata/testy/testy_test.go.golden b/gopls/internal/lsp/testdata/testy/testy_test.go.golden +--- a/gopls/internal/lsp/testdata/testy/testy_test.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/testy/testy_test.go.golden 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +--- X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias-signature -- +-X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias +- +diff -urN a/gopls/internal/lsp/testdata/typdef/typdef.go b/gopls/internal/lsp/testdata/typdef/typdef.go +--- a/gopls/internal/lsp/testdata/typdef/typdef.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typdef/typdef.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,65 +0,0 @@ +-package typdef - --func a() { -- bar := 42 //@rename("foo", "bar") +-type Struct struct { //@item(Struct, "Struct", "struct{...}", "struct") +- Field string -} - ---- testyType-rename -- --package testy +-type Int int //@item(Int, "Int", "int", "type") - --type testyType int //@rename("tt", "testyType") +-func _() { +- var ( +- value Struct +- point *Struct +- ) +- _ = value //@typdef("value", Struct) +- _ = point //@typdef("point", Struct) - --func a() { -- foo := 42 //@rename("foo", "bar") +- var ( +- array [3]Struct +- slice []Struct +- ch chan Struct +- complex [3]chan *[5][]Int +- ) +- _ = array //@typdef("array", Struct) +- _ = slice //@typdef("slice", Struct) +- _ = ch //@typdef("ch", Struct) +- _ = complex //@typdef("complex", Int) +- +- var s struct { +- x struct { +- xx struct { +- field1 []Struct +- field2 []Int +- } +- } +- } +- s.x.xx.field1 //@typdef("field1", Struct) +- s.x.xx.field2 //@typdef("field2", Int) -} - -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go b/gopls/internal/lsp/testdata/rename/testy/testy_test.go ---- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,8 +0,0 @@ --package testy +-func F1() Int { return 0 } +-func F2() (Int, float64) { return 0, 0 } +-func F3() (Struct, int, bool, error) { return Struct{}, 0, false, nil } +-func F4() (**int, Int, bool, *error) { return nil, Struct{}, false, nil } +-func F5() (int, float64, error, Struct) { return 0, 0, nil, Struct{} } +-func F6() (int, float64, ***Struct, error) { return 0, 0, nil, nil } - --import "testing" +-func _() { +- F1() //@typdef("F1", Int) +- F2() //@typdef("F2", Int) +- F3() //@typdef("F3", Struct) +- F4() //@typdef("F4", Int) +- F5() //@typdef("F5", Struct) +- F6() //@typdef("F6", Struct) - --func TestSomething(t *testing.T) { -- var x int //@rename("x", "testyX") -- a() //@rename("a", "b") +- f := func() Int { return 0 } +- f() //@typdef("f", Int) -} -diff -urN a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden ---- a/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rename/testy/testy_test.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,30 +0,0 @@ ---- b-rename -- --testy.go: --package testy - --type tt int //@rename("tt", "testyType") +-// https://github.com/golang/go/issues/38589#issuecomment-620350922 +-func _() { +- type myFunc func(int) Int //@item(myFunc, "myFunc", "func", "type") - --func b() { -- foo := 42 //@rename("foo", "bar") +- var foo myFunc +- bar := foo() //@typdef("foo", myFunc) -} +diff -urN a/gopls/internal/lsp/testdata/typeassert/type_assert.go b/gopls/internal/lsp/testdata/typeassert/type_assert.go +--- a/gopls/internal/lsp/testdata/typeassert/type_assert.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typeassert/type_assert.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-package typeassert - --testy_test.go: --package testy +-type abc interface { //@item(abcIntf, "abc", "interface{...}", "interface") +- abc() +-} - --import "testing" +-type abcImpl struct{} //@item(abcImpl, "abcImpl", "struct{...}", "struct") +-func (abcImpl) abc() - --func TestSomething(t *testing.T) { -- var x int //@rename("x", "testyX") -- b() //@rename("a", "b") --} +-type abcPtrImpl struct{} //@item(abcPtrImpl, "abcPtrImpl", "struct{...}", "struct") +-func (*abcPtrImpl) abc() - ---- testyX-rename -- --package testy +-type abcNotImpl struct{} //@item(abcNotImpl, "abcNotImpl", "struct{...}", "struct") - --import "testing" +-func _() { +- var a abc +- switch a.(type) { +- case ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +- case *ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +- } - --func TestSomething(t *testing.T) { -- var testyX int //@rename("x", "testyX") -- a() //@rename("a", "b") +- a.(ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +- a.(*ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) -} +diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go +--- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,5 +0,0 @@ +-package typeerrors +- +-func x() { return nil } //@suggestedfix("nil", "quickfix", "") - -diff -urN a/gopls/internal/lsp/testdata/rundespiteerrors/rundespiteerrors.go b/gopls/internal/lsp/testdata/rundespiteerrors/rundespiteerrors.go ---- a/gopls/internal/lsp/testdata/rundespiteerrors/rundespiteerrors.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/rundespiteerrors/rundespiteerrors.go 1970-01-01 00:00:00.000000000 +0000 +-func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") +diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden +--- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ --package rundespiteerrors +--- suggestedfix_noresultvalues_3_19 -- +-package typeerrors - --// This test verifies that analyzers without RunDespiteErrors are not --// executed on a package containing type errors (see issue #54762). --func _() { -- // A type error. -- _ = 1 + "" //@diag("1", "compiler", "mismatched types|cannot convert", "error") +-func x() { return } //@suggestedfix("nil", "quickfix", "") - -- // A violation of an analyzer for which RunDespiteErrors=false: -- // no diagnostic is produced; the diag comment is merely illustrative. -- for _ = range "" { //diag("for _", "simplifyrange", "simplify range expression", "warning") +-func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") - -- } --} -diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go b/gopls/internal/lsp/testdata/selectionrange/foo.go ---- a/gopls/internal/lsp/testdata/selectionrange/foo.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/selectionrange/foo.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package foo +--- suggestedfix_noresultvalues_5_19 -- +-package typeerrors - --import "time" +-func x() { return nil } //@suggestedfix("nil", "quickfix", "") - --func Bar(x, y int, t time.Time) int { -- zs := []int{1, 2, 3} //@selectionrange("1") +-func y() { return } //@suggestedfix("nil", "quickfix", "") - -- for _, z := range zs { -- x = x + z + y + zs[1] //@selectionrange("1") +diff -urN a/gopls/internal/lsp/testdata/typemods/type_mods.go b/gopls/internal/lsp/testdata/typemods/type_mods.go +--- a/gopls/internal/lsp/testdata/typemods/type_mods.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typemods/type_mods.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +-package typemods +- +-func fooFunc() func() int { //@item(modFooFunc, "fooFunc", "func() func() int", "func") +- return func() int { +- return 0 - } +-} - -- return x + y //@selectionrange("+") +-func fooPtr() *int { //@item(modFooPtr, "fooPtr", "func() *int", "func") +- return nil -} -diff -urN a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden ---- a/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/selectionrange/foo.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ ---- selectionrange_foo_12_11 -- --Ranges 0: -- 11:8-11:13 "x + y" -- 11:1-11:13 "return x + y" -- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" -- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" -- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" - ---- selectionrange_foo_6_14 -- --Ranges 0: -- 5:13-5:14 "1" -- 5:7-5:21 "[]int{1, 2, 3}" -- 5:1-5:21 "zs := []int{1, 2, 3}" -- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" -- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" -- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" +-func _() { +- var _ int = foo //@snippet(" //", modFooFunc, "fooFunc()()", "fooFunc()()"),snippet(" //", modFooPtr, "*fooPtr()", "*fooPtr()") +-} - ---- selectionrange_foo_9_22 -- --Ranges 0: -- 8:21-8:22 "1" -- 8:18-8:23 "zs[1]" -- 8:6-8:23 "x + z + y + zs[1]" -- 8:2-8:23 "x = x + z + y + zs[1]" -- 7:22-9:2 "{\\n\t\tx = x + z +...onrange(\"1\")\\n\t}" -- 7:1-9:2 "for _, z := ran...onrange(\"1\")\\n\t}" -- 4:36-12:1 "{\\n\tzs := []int{...ionrange(\"+\")\\n}" -- 4:0-12:1 "func Bar(x, y i...ionrange(\"+\")\\n}" -- 0:0-12:1 "package foo\\n\\nim...ionrange(\"+\")\\n}" +-func _() { +- var m map[int][]chan int //@item(modMapChanPtr, "m", "map[int]chan *int", "var") - -diff -urN a/gopls/internal/lsp/testdata/selector/selector.go.in b/gopls/internal/lsp/testdata/selector/selector.go.in ---- a/gopls/internal/lsp/testdata/selector/selector.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/selector/selector.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,66 +0,0 @@ --// +build go1.11 +- var _ int = m //@snippet(" //", modMapChanPtr, "<-m[${1:}][${2:}]", "<-m[${1:}][${2:}]") +-} +diff -urN a/gopls/internal/lsp/testdata/typeparams/type_params.go b/gopls/internal/lsp/testdata/typeparams/type_params.go +--- a/gopls/internal/lsp/testdata/typeparams/type_params.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/typeparams/type_params.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,61 +0,0 @@ +-//go:build go1.18 +-// +build go1.18 - --package selector +-package typeparams - --import ( -- "golang.org/lsptests/bar" --) +-func one[a int | string]() {} +-func two[a int | string, b float64 | int]() {} - --type S struct { -- B, A, C int //@item(Bf, "B", "int", "field"),item(Af, "A", "int", "field"),item(Cf, "C", "int", "field") +-func _() { +- one[]() //@rank("]", string, float64) +- two[]() //@rank("]", int, float64) +- two[int, f]() //@rank("]", float64, float32) -} - +-func slices[a []int | []float64]() {} //@item(tpInts, "[]int", "[]int", "type"),item(tpFloats, "[]float64", "[]float64", "type") +- -func _() { -- _ = S{}.; //@complete(";", Af, Bf, Cf) +- slices[]() //@rank("]", tpInts),rank("]", tpFloats) -} - --type bob struct { a int } //@item(a, "a", "int", "field") --type george struct { b int } --type jack struct { c int } //@item(c, "c", "int", "field") --type jill struct { d int } -- --func (b *bob) george() *george {} //@item(george, "george", "func() *george", "method") --func (g *george) jack() *jack {} --func (j *jack) jill() *jill {} //@item(jill, "jill", "func() *jill", "method") +-type s[a int | string] struct{} - -func _() { -- b := &bob{} -- y := b.george(). -- jack(); -- y.; //@complete(";", c, jill) +- s[]{} //@rank("]", int, float64) +-} +- +-func takesGeneric[a int | string](s[a]) { +- "s[a]{}" //@item(tpInScopeLit, "s[a]{}", "", "var") +- takesGeneric() //@rank(")", tpInScopeLit),snippet(")", tpInScopeLit, "s[a]{\\}", "s[a]{\\}") -} - -func _() { -- bar. //@complete(" /", Bar) -- x := 5 +- s[int]{} //@item(tpInstLit, "s[int]{}", "", "var") +- takesGeneric[int]() //@rank(")", tpInstLit),snippet(")", tpInstLit, "s[int]{\\}", "s[int]{\\}") - -- var b *bob -- b. //@complete(" /", a, george) -- y, z := 5, 6 +- "s[...]{}" //@item(tpUninstLit, "s[...]{}", "", "var") +- takesGeneric() //@rank(")", tpUninstLit),snippet(")", tpUninstLit, "s[${1:}]{\\}", "s[${1:a}]{\\}") +-} - -- b. //@complete(" /", a, george) -- y, z, a, b, c := 5, 6 +-func returnTP[A int | float64](a A) A { //@item(returnTP, "returnTP", "something", "func") +- return a -} - -func _() { -- bar. //@complete(" /", Bar) -- bar.Bar() +- // disabled - see issue #54822 +- var _ int = returnTP // snippet(" //", returnTP, "returnTP[${1:}](${2:})", "returnTP[${1:A int|float64}](${2:a A})") - -- bar. //@complete(" /", Bar) -- go f() +- var aa int //@item(tpInt, "aa", "int", "var") +- var ab float64 //@item(tpFloat, "ab", "float64", "var") +- returnTP[int](a) //@rank(")", tpInt, tpFloat) +-} +- +-func takesFunc[T any](func(T) T) { +- var _ func(t T) T = f //@snippet(" //", tpLitFunc, "func(t T) T {$0\\}", "func(t T) T {$0\\}") -} - -func _() { -- var b *bob -- if y != b. //@complete(" /", a, george) -- z := 5 +- _ = "func(...) {}" //@item(tpLitFunc, "func(...) {}", "", "var") +- takesFunc() //@snippet(")", tpLitFunc, "func(${1:}) ${2:} {$0\\}", "func(${1:t} ${2:T}) ${3:T} {$0\\}") +- takesFunc[int]() //@snippet(")", tpLitFunc, "func(i int) int {$0\\}", "func(${1:i} int) int {$0\\}") +-} +diff -urN a/gopls/internal/lsp/testdata/types/types.go b/gopls/internal/lsp/testdata/types/types.go +--- a/gopls/internal/lsp/testdata/types/types.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/types/types.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-package types - -- if z + y + 1 + b. //@complete(" /", a, george) -- r, s, t := 4, 5 +-type CoolAlias = int //@item(CoolAlias, "CoolAlias", "int", "type") - -- if y != b. //@complete(" /", a, george) -- z = 5 +-type X struct { //@item(X_struct, "X", "struct{...}", "struct") +- x int +-} - -- if z + y + 1 + b. //@complete(" /", a, george) -- r = 4 +-type Y struct { //@item(Y_struct, "Y", "struct{...}", "struct") +- y int -} -diff -urN a/gopls/internal/lsp/testdata/semantic/a.go b/gopls/internal/lsp/testdata/semantic/a.go ---- a/gopls/internal/lsp/testdata/semantic/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/a.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,81 +0,0 @@ --package semantictokens //@ semantic("") +- +-type Bob interface { //@item(Bob_interface, "Bob", "interface{...}", "interface") +- Bobby() +-} +- +-func (*X) Bobby() {} +-func (*Y) Bobby() {} +diff -urN a/gopls/internal/lsp/testdata/unimported/export_test.go b/gopls/internal/lsp/testdata/unimported/export_test.go +--- a/gopls/internal/lsp/testdata/unimported/export_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/unimported/export_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,3 +0,0 @@ +-package unimported +- +-var TestExport int //@item(testexport, "TestExport", "var (from \"golang.org/lsptests/unimported\")", "var") +diff -urN a/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go b/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go +--- a/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,16 +0,0 @@ +-package unimported - -import ( -- _ "encoding/utf8" -- utf "encoding/utf8" -- "fmt" //@ semantic("fmt") -- . "fmt" -- "unicode/utf8" --) +- _ "context" - --var ( -- a = fmt.Print -- b []string = []string{"foo"} -- c1 chan int -- c2 <-chan int -- c3 = make([]chan<- int) -- b = A{X: 23} -- m map[bool][3]*float64 +- "golang.org/lsptests/baz" +- _ "golang.org/lsptests/signature" // provide type information for unimported completions in the other file -) - --const ( -- xx F = iota -- yy = xx + 3 -- zz = "" -- ww = "not " + zz --) +-func _() { +- foo.StructFoo{} //@item(litFooStructFoo, "foo.StructFoo{}", "struct{...}", "struct") - --type A struct { -- X int `foof` --} --type B interface { -- A -- sad(int) bool +- // We get the literal completion for "foo.StructFoo{}" even though we haven't +- // imported "foo" yet. +- baz.FooStruct = f //@snippet(" //", litFooStructFoo, "foo.StructFoo{$0\\}", "foo.StructFoo{$0\\}") -} +diff -urN a/gopls/internal/lsp/testdata/unimported/unimported.go.in b/gopls/internal/lsp/testdata/unimported/unimported.go.in +--- a/gopls/internal/lsp/testdata/unimported/unimported.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/unimported/unimported.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,23 +0,0 @@ +-package unimported - --type F int -- --func (a *A) f() bool { -- var z string -- x := "foo" -- a(x) -- y := "bar" + x -- switch z { -- case "xx": -- default: -- } -- select { -- case z := <-c3[0]: -- default: -- } -- for k, v := range m { -- return (!k) && v[0] == nil -- } -- c2 <- A.X -- w := b[4:] -- j := len(x) -- j-- -- q := []interface{}{j, 23i, &y} -- g(q...) -- return true --} +-func _() { +- http //@unimported("p", nethttp) +- // container/ring is extremely unlikely to be imported by anything, so shouldn't have type information. +- ring.Ring //@unimported("Ring", ringring) +- signature.Foo //@unimported("Foo", signaturefoo) - --func g(vv ...interface{}) { -- ff := func() {} -- defer ff() -- go utf.RuneCount("") -- go utf8.RuneCount(vv.(string)) -- if true { -- } else { -- } --Never: -- for i := 0; i < 10; { -- break Never -- } -- _, ok := vv[0].(A) -- if !ok { -- switch x := vv[0].(type) { -- } -- goto Never -- } +- context.Bac //@unimported(" //", contextBackground) -} -diff -urN a/gopls/internal/lsp/testdata/semantic/a.go.golden b/gopls/internal/lsp/testdata/semantic/a.go.golden ---- a/gopls/internal/lsp/testdata/semantic/a.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/a.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,83 +0,0 @@ ---- semantic -- --/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") -- --/*⇒6,keyword,[]*/import ( -- _ "encoding/utf8" -- /*⇒3,namespace,[]*/utf "encoding/utf8" -- "fmt"/*⇐3,namespace,[]*/ /*⇒19,comment,[]*///@ semantic("fmt") -- . "fmt" -- "unicode/utf8"/*⇐4,namespace,[]*/ --) - --/*⇒3,keyword,[]*/var ( -- /*⇒1,variable,[definition]*/a = /*⇒3,namespace,[]*/fmt./*⇒5,function,[]*/Print -- /*⇒1,variable,[definition]*/b []/*⇒6,type,[defaultLibrary]*/string = []/*⇒6,type,[defaultLibrary]*/string{/*⇒5,string,[]*/"foo"} -- /*⇒2,variable,[definition]*/c1 /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int -- /*⇒2,variable,[definition]*/c2 /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int -- /*⇒2,variable,[definition]*/c3 = /*⇒4,function,[defaultLibrary]*/make([]/*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒3,type,[defaultLibrary]*/int) -- /*⇒1,variable,[definition]*/b = /*⇒1,type,[]*/A{/*⇒1,variable,[]*/X: /*⇒2,number,[]*/23} -- /*⇒1,variable,[definition]*/m /*⇒3,keyword,[]*/map[/*⇒4,type,[defaultLibrary]*/bool][/*⇒1,number,[]*/3]/*⇒1,operator,[]*/*/*⇒7,type,[defaultLibrary]*/float64 --) +-// Create markers for unimported std lib packages. Only for use by this test. +-/* http */ //@item(nethttp, "http", "\"net/http\"", "package") - --/*⇒5,keyword,[]*/const ( -- /*⇒2,variable,[definition readonly]*/xx /*⇒1,type,[]*/F = /*⇒4,variable,[readonly]*/iota -- /*⇒2,variable,[definition readonly]*/yy = /*⇒2,variable,[readonly]*/xx /*⇒1,operator,[]*/+ /*⇒1,number,[]*/3 -- /*⇒2,variable,[definition readonly]*/zz = /*⇒2,string,[]*/"" -- /*⇒2,variable,[definition readonly]*/ww = /*⇒6,string,[]*/"not " /*⇒1,operator,[]*/+ /*⇒2,variable,[readonly]*/zz --) +-/* ring.Ring */ //@item(ringring, "Ring", "(from \"container/ring\")", "var") - --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/A /*⇒6,keyword,[]*/struct { -- /*⇒1,variable,[definition]*/X /*⇒3,type,[defaultLibrary]*/int /*⇒6,string,[]*/`foof` --} --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/B /*⇒9,keyword,[]*/interface { -- /*⇒1,type,[]*/A -- /*⇒3,method,[definition]*/sad(/*⇒3,type,[defaultLibrary]*/int) /*⇒4,type,[defaultLibrary]*/bool --} +-/* signature.Foo */ //@item(signaturefoo, "Foo", "func (from \"golang.org/lsptests/signature\")", "func") - --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/F /*⇒3,type,[defaultLibrary]*/int +-/* context.Background */ //@item(contextBackground, "Background", "func (from \"context\")", "func") - --/*⇒4,keyword,[]*/func (/*⇒1,variable,[]*/a /*⇒1,operator,[]*/*/*⇒1,type,[]*/A) /*⇒1,method,[definition]*/f() /*⇒4,type,[defaultLibrary]*/bool { -- /*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/z /*⇒6,type,[defaultLibrary]*/string -- /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"foo" -- /*⇒1,variable,[]*/a(/*⇒1,variable,[]*/x) -- /*⇒1,variable,[definition]*/y /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"bar" /*⇒1,operator,[]*/+ /*⇒1,variable,[]*/x -- /*⇒6,keyword,[]*/switch /*⇒1,variable,[]*/z { -- /*⇒4,keyword,[]*/case /*⇒4,string,[]*/"xx": -- /*⇒7,keyword,[]*/default: -- } -- /*⇒6,keyword,[]*/select { -- /*⇒4,keyword,[]*/case /*⇒1,variable,[definition]*/z /*⇒2,operator,[]*/:= /*⇒2,operator,[]*/<-/*⇒2,variable,[]*/c3[/*⇒1,number,[]*/0]: -- /*⇒7,keyword,[]*/default: -- } -- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/k, /*⇒1,variable,[definition]*/v := /*⇒5,keyword,[]*/range /*⇒1,variable,[]*/m { -- /*⇒6,keyword,[]*/return (/*⇒1,operator,[]*/!/*⇒1,variable,[]*/k) /*⇒2,operator,[]*/&& /*⇒1,variable,[]*/v[/*⇒1,number,[]*/0] /*⇒2,operator,[]*/== /*⇒3,variable,[readonly defaultLibrary]*/nil -- } -- /*⇒2,variable,[]*/c2 /*⇒2,operator,[]*/<- /*⇒1,type,[]*/A./*⇒1,variable,[]*/X -- /*⇒1,variable,[definition]*/w /*⇒2,operator,[]*/:= /*⇒1,variable,[]*/b[/*⇒1,number,[]*/4:] -- /*⇒1,variable,[definition]*/j /*⇒2,operator,[]*/:= /*⇒3,function,[defaultLibrary]*/len(/*⇒1,variable,[]*/x) -- /*⇒1,variable,[]*/j/*⇒2,operator,[]*/-- -- /*⇒1,variable,[definition]*/q /*⇒2,operator,[]*/:= []/*⇒9,keyword,[]*/interface{}{/*⇒1,variable,[]*/j, /*⇒3,number,[]*/23i, /*⇒1,operator,[]*/&/*⇒1,variable,[]*/y} -- /*⇒1,function,[]*/g(/*⇒1,variable,[]*/q/*⇒3,operator,[]*/...) -- /*⇒6,keyword,[]*/return /*⇒4,variable,[readonly]*/true --} +-// Now that we no longer type-check imported completions, +-// we don't expect the context.Background().Err method (see golang/go#58663). +-/* context.Background().Err */ //@item(contextBackgroundErr, "Background().Err", "func (from \"context\")", "method") +diff -urN a/gopls/internal/lsp/testdata/unimported/x_test.go b/gopls/internal/lsp/testdata/unimported/x_test.go +--- a/gopls/internal/lsp/testdata/unimported/x_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/unimported/x_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,9 +0,0 @@ +-package unimported_test - --/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/g(/*⇒2,parameter,[definition]*/vv /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { -- /*⇒2,variable,[definition]*/ff /*⇒2,operator,[]*/:= /*⇒4,keyword,[]*/func() {} -- /*⇒5,keyword,[]*/defer /*⇒2,function,[]*/ff() -- /*⇒2,keyword,[]*/go /*⇒3,namespace,[]*/utf./*⇒9,function,[]*/RuneCount(/*⇒2,string,[]*/"") -- /*⇒2,keyword,[]*/go /*⇒4,namespace,[]*/utf8./*⇒9,function,[]*/RuneCount(/*⇒2,parameter,[]*/vv.(/*⇒6,type,[]*/string)) -- /*⇒2,keyword,[]*/if /*⇒4,variable,[readonly]*/true { -- } /*⇒4,keyword,[]*/else { -- } --/*⇒5,parameter,[definition]*/Never: -- /*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/i /*⇒2,operator,[]*/:= /*⇒1,number,[]*/0; /*⇒1,variable,[]*/i /*⇒1,operator,[]*/< /*⇒2,number,[]*/10; { -- /*⇒5,keyword,[]*/break Never -- } -- _, /*⇒2,variable,[definition]*/ok /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒1,type,[]*/A) -- /*⇒2,keyword,[]*/if /*⇒1,operator,[]*/!/*⇒2,variable,[]*/ok { -- /*⇒6,keyword,[]*/switch /*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒2,parameter,[]*/vv[/*⇒1,number,[]*/0].(/*⇒4,keyword,[]*/type) { -- } -- /*⇒4,keyword,[]*/goto Never -- } +-import ( +- "testing" +-) +- +-func TestSomething(t *testing.T) { +- _ = unimported.TestExport //@unimported("TestExport", testexport) -} +diff -urN a/gopls/internal/lsp/testdata/unresolved/unresolved.go.in b/gopls/internal/lsp/testdata/unresolved/unresolved.go.in +--- a/gopls/internal/lsp/testdata/unresolved/unresolved.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/unresolved/unresolved.go.in 1970-01-01 00:00:00.000000000 +0000 +@@ -1,6 +0,0 @@ +-package unresolved - -diff -urN a/gopls/internal/lsp/testdata/semantic/b.go b/gopls/internal/lsp/testdata/semantic/b.go ---- a/gopls/internal/lsp/testdata/semantic/b.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/b.go 1970-01-01 00:00:00.000000000 +0000 +-func foo(interface{}) { +- // don't crash on fake "resolved" type +- foo(func(i, j f //@complete(" //") +-} +diff -urN a/gopls/internal/lsp/testdata/unsafe/unsafe.go b/gopls/internal/lsp/testdata/unsafe/unsafe.go +--- a/gopls/internal/lsp/testdata/unsafe/unsafe.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/unsafe/unsafe.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-package unsafe +- +-import ( +- "unsafe" +-) +- +-// Pre-set this marker, as we don't have a "source" for it in this package. +-/* unsafe.Sizeof */ //@item(Sizeof, "Sizeof", "invalid type", "text") +- +-func _() { +- x := struct{}{} +- _ = unsafe.Sizeof(x) //@complete("z", Sizeof) +-} +diff -urN a/gopls/internal/lsp/testdata/variadic/variadic.go.in b/gopls/internal/lsp/testdata/variadic/variadic.go.in +--- a/gopls/internal/lsp/testdata/variadic/variadic.go.in 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/variadic/variadic.go.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ --package semantictokens //@ semantic("") +-package variadic - --func f(x ...interface{}) { +-func foo(i int, strs ...string) {} +- +-func bar() []string { //@item(vFunc, "bar", "func() []string", "func") +- return nil -} - --func weirⰀd() { /*😀*/ // comment -- const ( -- snil = nil -- nil = true -- true = false -- false = snil -- cmd = `foof` -- double = iota -- iota = copy -- four = (len(cmd)/2 < 5) -- five = four +-func _() { +- var ( +- i int //@item(vInt, "i", "int", "var") +- s string //@item(vStr, "s", "string", "var") +- ss []string //@item(vStrSlice, "ss", "[]string", "var") +- v interface{} //@item(vIntf, "v", "interface{}", "var") - ) -- f(cmd, nil, double, iota) --} - --/* +- foo() //@rank(")", vInt, vStr),rank(")", vInt, vStrSlice) +- foo(123, ) //@rank(")", vStr, vInt),rank(")", vStrSlice, vInt) +- foo(123, "", ) //@rank(")", vStr, vInt),rank(")", vStr, vStrSlice) +- foo(123, s, "") //@rank(", \"", vStr, vStrSlice) - --multiline */ /* --multiline --*/ --type AA int --type BB struct { -- AA +- // snippet will add the "..." for you +- foo(123, ) //@snippet(")", vStrSlice, "ss...", "ss..."),snippet(")", vFunc, "bar()...", "bar()..."),snippet(")", vStr, "s", "s") +- +- // don't add "..." for interface{} +- foo(123, ) //@snippet(")", vIntf, "v", "v") -} --type CC struct { -- AA int +- +-func qux(...func()) {} +-func f() {} //@item(vVarArg, "f", "func()", "func") +- +-func _() { +- qux(f) //@snippet(")", vVarArg, "f", "f") -} --type D func(aa AA) (BB error) --type E func(AA) BB - --var a chan<- chan int --var b chan<- <-chan int --var c <-chan <-chan int -diff -urN a/gopls/internal/lsp/testdata/semantic/b.go.golden b/gopls/internal/lsp/testdata/semantic/b.go.golden ---- a/gopls/internal/lsp/testdata/semantic/b.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/b.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,40 +0,0 @@ ---- semantic -- --/*⇒7,keyword,[]*/package /*⇒14,namespace,[]*/semantictokens /*⇒16,comment,[]*///@ semantic("") +-func _() { +- foo(0, []string{}...) //@complete(")") +-} +diff -urN a/gopls/internal/lsp/testdata/variadic/variadic_intf.go b/gopls/internal/lsp/testdata/variadic/variadic_intf.go +--- a/gopls/internal/lsp/testdata/variadic/variadic_intf.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/testdata/variadic/variadic_intf.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +-package variadic - --/*⇒4,keyword,[]*/func /*⇒1,function,[definition]*/f(/*⇒1,parameter,[definition]*/x /*⇒3,operator,[]*/.../*⇒9,keyword,[]*/interface{}) { +-type baz interface { +- baz() -} - --/*⇒4,keyword,[]*/func /*⇒6,function,[definition]*/weirⰀd() { /*⇒5,comment,[]*//*😀*/ /*⇒10,comment,[]*/// comment -- /*⇒5,keyword,[]*/const ( -- /*⇒4,variable,[definition readonly]*/snil = /*⇒3,variable,[readonly defaultLibrary]*/nil -- /*⇒3,variable,[definition readonly]*/nil = /*⇒4,variable,[readonly]*/true -- /*⇒4,variable,[definition readonly]*/true = /*⇒5,variable,[readonly]*/false -- /*⇒5,variable,[definition readonly]*/false = /*⇒4,variable,[readonly]*/snil -- /*⇒3,variable,[definition readonly]*/cmd = /*⇒6,string,[]*/`foof` -- /*⇒6,variable,[definition readonly]*/double = /*⇒4,variable,[readonly]*/iota -- /*⇒4,variable,[definition readonly]*/iota = /*⇒4,function,[defaultLibrary]*/copy -- /*⇒4,variable,[definition readonly]*/four = (/*⇒3,function,[defaultLibrary]*/len(/*⇒3,variable,[readonly]*/cmd)/*⇒1,operator,[]*// /*⇒1,number,[]*/2 /*⇒1,operator,[]*/< /*⇒1,number,[]*/5) -- /*⇒4,variable,[definition readonly]*/five = /*⇒4,variable,[readonly]*/four +-func wantsBaz(...baz) {} +- +-type bazImpl int +- +-func (bazImpl) baz() {} +- +-func _() { +- var ( +- impls []bazImpl //@item(vImplSlice, "impls", "[]bazImpl", "var") +- impl bazImpl //@item(vImpl, "impl", "bazImpl", "var") +- bazes []baz //@item(vIntfSlice, "bazes", "[]baz", "var") - ) -- /*⇒1,function,[]*/f(/*⇒3,variable,[readonly]*/cmd, /*⇒3,variable,[readonly]*/nil, /*⇒6,variable,[readonly]*/double, /*⇒4,variable,[readonly]*/iota) +- +- wantsBaz() //@rank(")", vImpl, vImplSlice),rank(")", vIntfSlice, vImplSlice) -} +diff -urN a/gopls/internal/lsp/tests/compare/text.go b/gopls/internal/lsp/tests/compare/text.go +--- a/gopls/internal/lsp/tests/compare/text.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/compare/text.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,49 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --/*⇒2,comment,[]*//* --/*⇒0,comment,[]*/ --/*⇒12,comment,[]*/multiline */ /*⇒2,comment,[]*//* --/*⇒9,comment,[]*/multiline --/*⇒2,comment,[]*/*/ --/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int --/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/BB /*⇒6,keyword,[]*/struct { -- /*⇒2,type,[]*/AA +-package compare +- +-import ( +- "bytes" +- +- "golang.org/x/tools/internal/diff" +-) +- +-// Text returns a formatted unified diff of the edits to go from want to +-// got, returning "" if and only if want == got. +-// +-// This function is intended for use in testing, and panics if any error occurs +-// while computing the diff. It is not sufficiently tested for production use. +-func Text(want, got string) string { +- return NamedText("want", "got", want, got) -} --/*⇒4,keyword,[]*/type /*⇒2,type,[definition]*/CC /*⇒6,keyword,[]*/struct { -- /*⇒2,variable,[definition]*/AA /*⇒3,type,[defaultLibrary]*/int +- +-// NamedText is like text, but allows passing custom names of the 'want' and +-// 'got' content. +-func NamedText(wantName, gotName, want, got string) string { +- if want == got { +- return "" +- } +- +- // Add newlines to avoid verbose newline messages ("No newline at end of file"). +- unified := diff.Unified(wantName, gotName, want+"\n", got+"\n") +- +- // Defensively assert that we get an actual diff, so that we guarantee the +- // invariant that we return "" if and only if want == got. +- // +- // This is probably unnecessary, but convenient. +- if unified == "" { +- panic("empty diff for non-identical input") +- } +- +- return unified -} --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/D /*⇒4,keyword,[]*/func(/*⇒2,parameter,[definition]*/aa /*⇒2,type,[]*/AA) (/*⇒2,parameter,[definition]*/BB /*⇒5,type,[]*/error) --/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/E /*⇒4,keyword,[]*/func(/*⇒2,type,[]*/AA) /*⇒2,type,[]*/BB - --/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/a /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int --/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/b /*⇒4,keyword,[]*/chan/*⇒2,operator,[]*/<- /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int --/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/c /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒2,operator,[]*/<-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int +-// Bytes is like Text but using byte slices. +-func Bytes(want, got []byte) string { +- if bytes.Equal(want, got) { +- return "" // common case +- } +- return Text(string(want), string(got)) +-} +diff -urN a/gopls/internal/lsp/tests/compare/text_test.go b/gopls/internal/lsp/tests/compare/text_test.go +--- a/gopls/internal/lsp/tests/compare/text_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/compare/text_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,28 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/semantic/README.md b/gopls/internal/lsp/testdata/semantic/README.md ---- a/gopls/internal/lsp/testdata/semantic/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/README.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,2 +0,0 @@ --The golden files are the output of `gopls semtok `, with `-- semantic --` --inserted as the first line (the spaces are mandatory) and an extra newline at the end. -diff -urN a/gopls/internal/lsp/testdata/semantic/semantic_test.go b/gopls/internal/lsp/testdata/semantic/semantic_test.go ---- a/gopls/internal/lsp/testdata/semantic/semantic_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/semantic/semantic_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package semantictokens +-package compare_test - -import ( -- "os" - "testing" --) -- --func TestSemanticTokens(t *testing.T) { -- a, _ := os.Getwd() -- // climb up to find internal/lsp -- // find all the .go files - --} -diff -urN a/gopls/internal/lsp/testdata/signature/signature2.go.golden b/gopls/internal/lsp/testdata/signature/signature2.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature2.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature2.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ ---- Foo(a string, b int) (c bool)-signature -- --Foo(a string, b int) (c bool) +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +-) - -diff -urN a/gopls/internal/lsp/testdata/signature/signature2.go.in b/gopls/internal/lsp/testdata/signature/signature2.go.in ---- a/gopls/internal/lsp/testdata/signature/signature2.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature2.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package signature +-func TestText(t *testing.T) { +- tests := []struct { +- got, want, wantDiff string +- }{ +- {"", "", ""}, +- {"equal", "equal", ""}, +- {"a", "b", "--- want\n+++ got\n@@ -1 +1 @@\n-b\n+a\n"}, +- {"a\nd\nc\n", "a\nb\nc\n", "--- want\n+++ got\n@@ -1,4 +1,4 @@\n a\n-b\n+d\n c\n \n"}, +- } - --func _() { -- Foo(//@signature("//", "Foo(a string, b int) (c bool)", 0) +- for _, test := range tests { +- if gotDiff := compare.Text(test.want, test.got); gotDiff != test.wantDiff { +- t.Errorf("compare.Text(%q, %q) =\n%q, want\n%q", test.want, test.got, gotDiff, test.wantDiff) +- } +- } -} -diff -urN a/gopls/internal/lsp/testdata/signature/signature3.go.golden b/gopls/internal/lsp/testdata/signature/signature3.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature3.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature3.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ ---- Foo(a string, b int) (c bool)-signature -- --Foo(a string, b int) (c bool) +diff -urN a/gopls/internal/lsp/tests/markdown_go118.go b/gopls/internal/lsp/tests/markdown_go118.go +--- a/gopls/internal/lsp/tests/markdown_go118.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/markdown_go118.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/signature/signature3.go.in b/gopls/internal/lsp/testdata/signature/signature3.go.in ---- a/gopls/internal/lsp/testdata/signature/signature3.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature3.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package signature +-//go:build !go1.19 +-// +build !go1.19 - --func _() { -- Foo("hello",//@signature("//", "Foo(a string, b int) (c bool)", 1) --} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/signature/signature.go b/gopls/internal/lsp/testdata/signature/signature.go ---- a/gopls/internal/lsp/testdata/signature/signature.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,85 +0,0 @@ --// Package signature has tests for signature help. --package signature +-package tests - -import ( -- "bytes" -- "encoding/json" -- "math/big" +- "regexp" +- "strings" +- +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -) - --func Foo(a string, b int) (c bool) { -- return +-// DiffMarkdown compares two markdown strings produced by parsing go doc +-// comments. +-// +-// For go1.19 and later, markdown conversion is done using go/doc/comment. +-// Compared to the newer version, the older version has extra escapes, and +-// treats code blocks slightly differently. +-func DiffMarkdown(want, got string) string { +- want = normalizeMarkdown(want) +- got = normalizeMarkdown(got) +- return compare.Text(want, got) -} - --func Bar(float64, ...byte) { --} +-// normalizeMarkdown normalizes whitespace and escaping of the input string, to +-// eliminate differences between the Go 1.18 and Go 1.19 generated markdown for +-// doc comments. Note that it does not normalize to either the 1.18 or 1.19 +-// formatting: it simplifies both so that they may be compared. +-// +-// This function may need to be adjusted as we encounter more differences in +-// the generated text. +-// +-// TODO(rfindley): this function doesn't correctly handle the case of +-// multi-line docstrings. +-func normalizeMarkdown(input string) string { +- input = strings.TrimSpace(input) - --type myStruct struct{} +- // For simplicity, eliminate blank lines. +- input = regexp.MustCompile("\n+").ReplaceAllString(input, "\n") - --func (*myStruct) foo(e *json.Decoder) (*big.Int, error) { -- return nil, nil +- // Replace common escaped characters with their unescaped version. +- // +- // This list may not be exhaustive: it was just sufficient to make tests +- // pass. +- input = strings.NewReplacer( +- `\\`, ``, +- `\@`, `@`, +- `\(`, `(`, +- `\)`, `)`, +- `\{`, `{`, +- `\}`, `}`, +- `\"`, `"`, +- `\.`, `.`, +- `\-`, `-`, +- `\'`, `'`, +- `\+`, `+`, +- `\~`, `~`, +- `\=`, `=`, +- `\:`, `:`, +- `\?`, `?`, +- `\n\n\n`, `\n\n`, // Note that these are *escaped* newlines. +- ).Replace(input) +- +- return input -} +diff -urN a/gopls/internal/lsp/tests/markdown_go119.go b/gopls/internal/lsp/tests/markdown_go119.go +--- a/gopls/internal/lsp/tests/markdown_go119.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/markdown_go119.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --type MyType struct{} +-//go:build go1.19 +-// +build go1.19 - --type MyFunc func(foo int) string +-package tests - --type Alias = int --type OtherAlias = int --type StringAlias = string +-import ( +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +-) - --func AliasSlice(a []*Alias) (b Alias) { return 0 } --func AliasMap(a map[*Alias]StringAlias) (b, c map[*Alias]StringAlias) { return nil, nil } --func OtherAliasMap(a, b map[Alias]OtherAlias) map[Alias]OtherAlias { return nil } +-// DiffMarkdown compares two markdown strings produced by parsing go doc +-// comments. +-// +-// For go1.19 and later, markdown conversion is done using go/doc/comment. +-// Compared to the newer version, the older version has extra escapes, and +-// treats code blocks slightly differently. +-func DiffMarkdown(want, got string) string { +- return compare.Text(want, got) +-} +diff -urN a/gopls/internal/lsp/tests/README.md b/gopls/internal/lsp/tests/README.md +--- a/gopls/internal/lsp/tests/README.md 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/README.md 1970-01-01 00:00:00.000000000 +0000 +@@ -1,66 +0,0 @@ +-# Testing - --func Qux() { -- Foo("foo", 123) //@signature("(", "Foo(a string, b int) (c bool)", 0) -- Foo("foo", 123) //@signature("123", "Foo(a string, b int) (c bool)", 1) -- Foo("foo", 123) //@signature(",", "Foo(a string, b int) (c bool)", 0) -- Foo("foo", 123) //@signature(" 1", "Foo(a string, b int) (c bool)", 1) -- Foo("foo", 123) //@signature(")", "Foo(a string, b int) (c bool)", 1) +-LSP has "marker tests" defined in `internal/lsp/testdata`, as well as +-traditional tests. - -- Bar(13.37, 0x13) //@signature("13.37", "Bar(float64, ...byte)", 0) -- Bar(13.37, 0x37) //@signature("0x37", "Bar(float64, ...byte)", 1) -- Bar(13.37, 1, 2, 3, 4) //@signature("4", "Bar(float64, ...byte)", 1) +-## Marker tests - -- fn := func(hi, there string) func(i int) rune { -- return func(int) rune { return 0 } -- } +-Marker tests have a standard input file, like +-`internal/lsp/testdata/foo/bar.go`, and some may have a corresponding golden +-file, like `internal/lsp/testdata/foo/bar.go.golden`. The former is the "input" +-and the latter is the expected output. - -- fn("hi", "there") //@signature("hi", "", 0) -- fn("hi", "there") //@signature(",", "fn(hi string, there string) func(i int) rune", 0) -- fn("hi", "there")(1) //@signature("1", "func(i int) rune", 0) +-Each input file contains annotations like +-`//@suggestedfix("}", "refactor.rewrite", "Fill anonymous struct")`. These annotations are interpreted by +-test runners to perform certain actions. The expected output after those actions +-is encoded in the golden file. - -- fnPtr := &fn -- (*fnPtr)("hi", "there") //@signature(",", "func(hi string, there string) func(i int) rune", 0) +-When tests are run, each annotation results in a new subtest, which is encoded +-in the golden file with a heading like, - -- var fnIntf interface{} = Foo -- fnIntf.(func(string, int) bool)("hi", 123) //@signature("123", "func(string, int) bool", 1) +-```bash +--- suggestedfix_bar_11_21 -- +-// expected contents go here +--- suggestedfix_bar_13_20 -- +-// expected contents go here +-``` - -- (&bytes.Buffer{}).Next(2) //@signature("2", "Next(n int) []byte", 0) +-The format of these headings vary: they are defined by the +-[`Golden`](https://pkg.go.dev/golang.org/x/tools/gopls/internal/lsp/tests#Data.Golden) +-function for each annotation. In the case above, the format is: annotation +-name, file name, annotation line location, annotation character location. - -- myFunc := MyFunc(func(n int) string { return "" }) -- myFunc(123) //@signature("123", "myFunc(foo int) string", 0) +-So, if `internal/lsp/testdata/foo/bar.go` has three `suggestedfix` annotations, +-the golden file should have three headers with `suggestedfix_bar_xx_yy` +-headings. - -- var ms myStruct -- ms.foo(nil) //@signature("nil", "foo(e *json.Decoder) (*big.Int, error)", 0) +-To see a list of all available annotations, see the exported "expectations" in +-[tests.go](https://github.com/golang/tools/blob/299f270db45902e93469b1152fafed034bb3f033/internal/lsp/tests/tests.go#L418-L447). - -- _ = make([]int, 1, 2) //@signature("2", "make(t Type, size ...int) Type", 1) +-To run marker tests, - -- Foo(myFunc(123), 456) //@signature("myFunc", "Foo(a string, b int) (c bool)", 0) -- Foo(myFunc(123), 456) //@signature("123", "myFunc(foo int) string", 0) +-```bash +-cd /path/to/tools - -- panic("oops!") //@signature(")", "panic(v interface{})", 0) -- println("hello", "world") //@signature(",", "println(args ...Type)", 0) +-# The marker tests are located in "internal/lsp", "internal/lsp/cmd, and +-# "internal/lsp/source". +-go test ./internal/lsp/... +-``` - -- Hello(func() { -- //@signature("//", "", 0) -- }) +-There are quite a lot of marker tests, so to run one individually, pass the test +-path and heading into a -run argument: - -- AliasSlice() //@signature(")", "AliasSlice(a []*Alias) (b Alias)", 0) -- AliasMap() //@signature(")", "AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias)", 0) -- OtherAliasMap() //@signature(")", "OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias", 0) --} +-```bash +-cd /path/to/tools +-go test ./internal/lsp/... -v -run TestLSP/Modules/SuggestedFix/bar_11_21 +-``` - --func Hello(func()) {} -diff -urN a/gopls/internal/lsp/testdata/signature/signature.go.golden b/gopls/internal/lsp/testdata/signature/signature.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,53 +0,0 @@ ---- AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias)-signature -- --AliasMap(a map[*Alias]StringAlias) (b map[*Alias]StringAlias, c map[*Alias]StringAlias) +-## Resetting marker tests - ---- AliasSlice(a []*Alias) (b Alias)-signature -- --AliasSlice(a []*Alias) (b Alias) +-Sometimes, a change is made to lsp that requires a change to multiple golden +-files. When this happens, you can run, - ---- Bar(float64, ...byte)-signature -- --Bar(float64, ...byte) +-```bash +-cd /path/to/tools +-./internal/lsp/reset_golden.sh +-``` +diff -urN a/gopls/internal/lsp/tests/tests.go b/gopls/internal/lsp/tests/tests.go +--- a/gopls/internal/lsp/tests/tests.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/tests.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,1175 +0,0 @@ +-// Copyright 2019 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-// Package tests exports functionality to be used across a variety of gopls tests. +-package tests +- +-import ( +- "bytes" +- "context" +- "flag" +- "fmt" +- "go/ast" +- "go/token" +- "io" +- "io/ioutil" +- "os" +- "path/filepath" +- "regexp" +- "sort" +- "strconv" +- "strings" +- "sync" +- "testing" +- "time" +- +- "golang.org/x/tools/go/expect" +- "golang.org/x/tools/go/packages" +- "golang.org/x/tools/go/packages/packagestest" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/safetoken" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/source/completion" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/testenv" +- "golang.org/x/tools/internal/typeparams" +- "golang.org/x/tools/txtar" +-) - ---- Foo(a string, b int) (c bool)-signature -- --Foo(a string, b int) (c bool) +-const ( +- overlayFileSuffix = ".overlay" +- goldenFileSuffix = ".golden" +- inFileSuffix = ".in" - ---- Next(n int) []byte-signature -- --Next(n int) []byte +- // The module path containing the testdata packages. +- // +- // Warning: the length of this module path matters, as we have bumped up +- // against command-line limitations on windows (golang/go#54800). +- testModule = "golang.org/lsptests" +-) - --Next returns a slice containing the next n bytes from the buffer, advancing the buffer as if the bytes had been returned by Read. +-var summaryFile = "summary.txt" - ---- OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias-signature -- --OtherAliasMap(a map[Alias]OtherAlias, b map[Alias]OtherAlias) map[Alias]OtherAlias +-func init() { +- if testenv.Go1Point() >= 21 { +- summaryFile = "summary_go1.21.txt" +- } else if testenv.Go1Point() >= 18 { +- summaryFile = "summary_go1.18.txt" +- } +-} - ---- fn(hi string, there string) func(i int) rune-signature -- --fn(hi string, there string) func(i int) rune +-var UpdateGolden = flag.Bool("golden", false, "Update golden files") - ---- foo(e *json.Decoder) (*big.Int, error)-signature -- --foo(e *json.Decoder) (*big.Int, error) +-// These type names apparently avoid the need to repeat the +-// type in the field name and the make() expression. +-type CallHierarchy = map[span.Span]*CallHierarchyResult +-type CodeLens = map[span.URI][]protocol.CodeLens +-type Diagnostics = map[span.URI][]*source.Diagnostic +-type CompletionItems = map[token.Pos]*completion.CompletionItem +-type Completions = map[span.Span][]Completion +-type CompletionSnippets = map[span.Span][]CompletionSnippet +-type UnimportedCompletions = map[span.Span][]Completion +-type DeepCompletions = map[span.Span][]Completion +-type FuzzyCompletions = map[span.Span][]Completion +-type CaseSensitiveCompletions = map[span.Span][]Completion +-type RankCompletions = map[span.Span][]Completion +-type FoldingRanges = []span.Span +-type SemanticTokens = []span.Span +-type SuggestedFixes = map[span.Span][]SuggestedFix +-type MethodExtractions = map[span.Span]span.Span +-type Definitions = map[span.Span]Definition +-type Highlights = map[span.Span][]span.Span +-type Renames = map[span.Span]string +-type PrepareRenames = map[span.Span]*source.PrepareItem +-type InlayHints = []span.Span +-type Signatures = map[span.Span]*protocol.SignatureHelp +-type Links = map[span.URI][]Link +-type AddImport = map[span.URI]string +-type SelectionRanges = []span.Span - ---- func(hi string, there string) func(i int) rune-signature -- --func(hi string, there string) func(i int) rune +-type Data struct { +- Config packages.Config +- Exported *packagestest.Exported +- CallHierarchy CallHierarchy +- CodeLens CodeLens +- Diagnostics Diagnostics +- CompletionItems CompletionItems +- Completions Completions +- CompletionSnippets CompletionSnippets +- UnimportedCompletions UnimportedCompletions +- DeepCompletions DeepCompletions +- FuzzyCompletions FuzzyCompletions +- CaseSensitiveCompletions CaseSensitiveCompletions +- RankCompletions RankCompletions +- FoldingRanges FoldingRanges +- SemanticTokens SemanticTokens +- SuggestedFixes SuggestedFixes +- MethodExtractions MethodExtractions +- Definitions Definitions +- Highlights Highlights +- Renames Renames +- InlayHints InlayHints +- PrepareRenames PrepareRenames +- Signatures Signatures +- Links Links +- AddImport AddImport +- SelectionRanges SelectionRanges - ---- func(i int) rune-signature -- --func(i int) rune +- fragments map[string]string +- dir string +- golden map[string]*Golden +- mode string - ---- func(string, int) bool-signature -- --func(string, int) bool +- ModfileFlagAvailable bool - ---- make(t Type, size ...int) Type-signature -- --make(t Type, size ...int) Type +- mappersMu sync.Mutex +- mappers map[span.URI]*protocol.Mapper +-} - --The make built-in function allocates and initializes an object of type slice, map, or chan (only). +-// The Tests interface abstracts the LSP-based implementation of the marker +-// test operators (such as @codelens) appearing in files beneath ../testdata/. +-// +-// TODO(adonovan): reduce duplication; see https://github.com/golang/go/issues/54845. +-// There is only one implementation (*runner in ../lsp_test.go), so +-// we can abolish the interface now. +-type Tests interface { +- CallHierarchy(*testing.T, span.Span, *CallHierarchyResult) +- CodeLens(*testing.T, span.URI, []protocol.CodeLens) +- Diagnostics(*testing.T, span.URI, []*source.Diagnostic) +- Completion(*testing.T, span.Span, Completion, CompletionItems) +- CompletionSnippet(*testing.T, span.Span, CompletionSnippet, bool, CompletionItems) +- UnimportedCompletion(*testing.T, span.Span, Completion, CompletionItems) +- DeepCompletion(*testing.T, span.Span, Completion, CompletionItems) +- FuzzyCompletion(*testing.T, span.Span, Completion, CompletionItems) +- CaseSensitiveCompletion(*testing.T, span.Span, Completion, CompletionItems) +- RankCompletion(*testing.T, span.Span, Completion, CompletionItems) +- FoldingRanges(*testing.T, span.Span) +- SemanticTokens(*testing.T, span.Span) +- SuggestedFix(*testing.T, span.Span, []SuggestedFix, int) +- MethodExtraction(*testing.T, span.Span, span.Span) +- Definition(*testing.T, span.Span, Definition) +- Highlight(*testing.T, span.Span, []span.Span) +- InlayHints(*testing.T, span.Span) +- Rename(*testing.T, span.Span, string) +- PrepareRename(*testing.T, span.Span, *source.PrepareItem) +- SignatureHelp(*testing.T, span.Span, *protocol.SignatureHelp) +- Link(*testing.T, span.URI, []Link) +- AddImport(*testing.T, span.URI, string) +- SelectionRanges(*testing.T, span.Span) +-} - ---- myFunc(foo int) string-signature -- --myFunc(foo int) string +-type Definition struct { +- Name string +- IsType bool +- OnlyHover bool +- Src, Def span.Span +-} - ---- panic(v interface{})-signature -- --panic(v any) +-type CompletionTestType int - --The panic built-in function stops normal execution of the current goroutine. +-const ( +- // Default runs the standard completion tests. +- CompletionDefault = CompletionTestType(iota) - ---- println(args ...Type)-signature -- --println(args ...Type) +- // Unimported tests the autocompletion of unimported packages. +- CompletionUnimported - --The println built-in function formats its arguments in an implementation-specific way and writes the result to standard error. +- // Deep tests deep completion. +- CompletionDeep - -diff -urN a/gopls/internal/lsp/testdata/signature/signature_test.go b/gopls/internal/lsp/testdata/signature/signature_test.go ---- a/gopls/internal/lsp/testdata/signature/signature_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package signature_test +- // Fuzzy tests deep completion and fuzzy matching. +- CompletionFuzzy - --import ( -- "testing" +- // CaseSensitive tests case sensitive completion. +- CompletionCaseSensitive - -- sig "golang.org/lsptests/signature" +- // CompletionRank candidates in test must be valid and in the right relative order. +- CompletionRank -) - --func TestSignature(t *testing.T) { -- sig.AliasSlice() //@signature(")", "AliasSlice(a []*sig.Alias) (b sig.Alias)", 0) -- sig.AliasMap() //@signature(")", "AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias)", 0) -- sig.OtherAliasMap() //@signature(")", "OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias", 0) +-type Completion struct { +- CompletionItems []token.Pos -} -diff -urN a/gopls/internal/lsp/testdata/signature/signature_test.go.golden b/gopls/internal/lsp/testdata/signature/signature_test.go.golden ---- a/gopls/internal/lsp/testdata/signature/signature_test.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/signature/signature_test.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ ---- AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias)-signature -- --AliasMap(a map[*sig.Alias]sig.StringAlias) (b map[*sig.Alias]sig.StringAlias, c map[*sig.Alias]sig.StringAlias) -- ---- AliasSlice(a []*sig.Alias) (b sig.Alias)-signature -- --AliasSlice(a []*sig.Alias) (b sig.Alias) -- ---- OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias-signature -- --OtherAliasMap(a map[sig.Alias]sig.OtherAlias, b map[sig.Alias]sig.OtherAlias) map[sig.Alias]sig.OtherAlias -- -diff -urN a/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in b/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in ---- a/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/func_snippets118.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ --// +build go1.18 --//go:build go1.18 -- --package snippets - --type SyncMap[K comparable, V any] struct{} +-type CompletionSnippet struct { +- CompletionItem token.Pos +- PlainSnippet string +- PlaceholderSnippet string +-} - --func NewSyncMap[K comparable, V any]() (result *SyncMap[K, V]) { //@item(NewSyncMap, "NewSyncMap", "", "") -- return +-type CallHierarchyResult struct { +- IncomingCalls, OutgoingCalls []protocol.CallHierarchyItem -} - --func Identity[P ~int](p P) P { //@item(Identity, "Identity", "", "") -- return p +-type Link struct { +- Src span.Span +- Target string +- NotePosition token.Position -} - --func _() { -- _ = NewSyncM //@snippet(" //", NewSyncMap, "NewSyncMap[${1:}]()", "NewSyncMap[${1:K comparable}, ${2:V any}]()") -- _ = Identi //@snippet(" //", Identity, "Identity[${1:}](${2:})", "Identity[${1:P ~int}](${2:p P})") +-type SuggestedFix struct { +- ActionKind, Title string -} -diff -urN a/gopls/internal/lsp/testdata/snippets/literal.go b/gopls/internal/lsp/testdata/snippets/literal.go ---- a/gopls/internal/lsp/testdata/snippets/literal.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/literal.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ --package snippets - --import ( -- "golang.org/lsptests/signature" -- t "golang.org/lsptests/types" --) +-type Golden struct { +- Filename string +- Archive *txtar.Archive +- Modified bool +-} - --type structy struct { -- x signature.MyType +-func Context(t testing.TB) context.Context { +- return context.Background() -} - --func X(_ map[signature.Alias]t.CoolAlias) (map[signature.Alias]t.CoolAlias) { -- return nil +-func DefaultOptions(o *source.Options) { +- o.SupportedCodeActions = map[source.FileKind]map[protocol.CodeActionKind]bool{ +- source.Go: { +- protocol.SourceOrganizeImports: true, +- protocol.QuickFix: true, +- protocol.RefactorRewrite: true, +- protocol.RefactorInline: true, +- protocol.RefactorExtract: true, +- protocol.SourceFixAll: true, +- }, +- source.Mod: { +- protocol.SourceOrganizeImports: true, +- }, +- source.Sum: {}, +- source.Work: {}, +- source.Tmpl: {}, +- } +- o.UserOptions.Codelenses[string(command.Test)] = true +- o.HoverKind = source.SynopsisDocumentation +- o.InsertTextFormat = protocol.SnippetTextFormat +- o.CompletionBudget = time.Minute +- o.HierarchicalDocumentSymbolSupport = true +- o.SemanticTokens = true +- o.InternalOptions.NewDiff = "new" -} - --func _() { -- X() //@signature(")", "X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias", 0) -- _ = signature.MyType{} //@item(literalMyType, "signature.MyType{}", "", "var") -- s := structy{ -- x: //@snippet(" //", literalMyType, "signature.MyType{\\}", "signature.MyType{\\}") +-func RunTests(t *testing.T, dataDir string, includeMultiModule bool, f func(*testing.T, *Data)) { +- t.Helper() +- modes := []string{"Modules", "GOPATH"} +- if includeMultiModule { +- modes = append(modes, "MultiModule") +- } +- for _, mode := range modes { +- t.Run(mode, func(t *testing.T) { +- datum := load(t, mode, dataDir) +- t.Helper() +- f(t, datum) +- }) - } -} -\ No newline at end of file -diff -urN a/gopls/internal/lsp/testdata/snippets/literal.go.golden b/gopls/internal/lsp/testdata/snippets/literal.go.golden ---- a/gopls/internal/lsp/testdata/snippets/literal.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/literal.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ ---- X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias-signature -- --X(_ map[signature.Alias]t.CoolAlias) map[signature.Alias]t.CoolAlias - -diff -urN a/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in b/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in ---- a/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ --// +build go1.18 --//go:build go1.18 +-func load(t testing.TB, mode string, dir string) *Data { +- datum := &Data{ +- CallHierarchy: make(CallHierarchy), +- CodeLens: make(CodeLens), +- Diagnostics: make(Diagnostics), +- CompletionItems: make(CompletionItems), +- Completions: make(Completions), +- CompletionSnippets: make(CompletionSnippets), +- UnimportedCompletions: make(UnimportedCompletions), +- DeepCompletions: make(DeepCompletions), +- FuzzyCompletions: make(FuzzyCompletions), +- RankCompletions: make(RankCompletions), +- CaseSensitiveCompletions: make(CaseSensitiveCompletions), +- Definitions: make(Definitions), +- Highlights: make(Highlights), +- Renames: make(Renames), +- PrepareRenames: make(PrepareRenames), +- SuggestedFixes: make(SuggestedFixes), +- MethodExtractions: make(MethodExtractions), +- Signatures: make(Signatures), +- Links: make(Links), +- AddImport: make(AddImport), - --package snippets +- dir: dir, +- fragments: map[string]string{}, +- golden: map[string]*Golden{}, +- mode: mode, +- mappers: map[span.URI]*protocol.Mapper{}, +- } - --type Tree[T any] struct{} +- if !*UpdateGolden { +- summary := filepath.Join(filepath.FromSlash(dir), summaryFile+goldenFileSuffix) +- if _, err := os.Stat(summary); os.IsNotExist(err) { +- t.Fatalf("could not find golden file summary.txt in %#v", dir) +- } +- archive, err := txtar.ParseFile(summary) +- if err != nil { +- t.Fatalf("could not read golden file %v/%v: %v", dir, summary, err) +- } +- datum.golden[summaryFile] = &Golden{ +- Filename: summary, +- Archive: archive, +- } +- } - --func (tree Tree[T]) Do(f func(s T)) {} +- files := packagestest.MustCopyFileTree(dir) +- // Prune test cases that exercise generics. +- if !typeparams.Enabled { +- for name := range files { +- if strings.Contains(name, "_generics") { +- delete(files, name) +- } +- } +- } +- overlays := map[string][]byte{} +- for fragment, operation := range files { +- if trimmed := strings.TrimSuffix(fragment, goldenFileSuffix); trimmed != fragment { +- delete(files, fragment) +- goldFile := filepath.Join(dir, fragment) +- archive, err := txtar.ParseFile(goldFile) +- if err != nil { +- t.Fatalf("could not read golden file %v: %v", fragment, err) +- } +- datum.golden[trimmed] = &Golden{ +- Filename: goldFile, +- Archive: archive, +- } +- } else if trimmed := strings.TrimSuffix(fragment, inFileSuffix); trimmed != fragment { +- delete(files, fragment) +- files[trimmed] = operation +- } else if index := strings.Index(fragment, overlayFileSuffix); index >= 0 { +- delete(files, fragment) +- partial := fragment[:index] + fragment[index+len(overlayFileSuffix):] +- contents, err := ioutil.ReadFile(filepath.Join(dir, fragment)) +- if err != nil { +- t.Fatal(err) +- } +- overlays[partial] = contents +- } +- } - --func _() { -- _ = "func(...) {}" //@item(litFunc, "func(...) {}", "", "var") -- var t Tree[string] -- t.Do(fun) //@complete(")", litFunc),snippet(")", litFunc, "func(s string) {$0\\}", "func(s string) {$0\\}") --} -diff -urN a/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in b/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in ---- a/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,233 +0,0 @@ --package snippets +- modules := []packagestest.Module{ +- { +- Name: testModule, +- Files: files, +- Overlay: overlays, +- }, +- } +- switch mode { +- case "Modules": +- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) +- case "GOPATH": +- datum.Exported = packagestest.Export(t, packagestest.GOPATH, modules) +- case "MultiModule": +- files := map[string]interface{}{} +- for k, v := range modules[0].Files { +- files[filepath.Join("testmodule", k)] = v +- } +- modules[0].Files = files - --import ( -- "bytes" -- "context" -- "go/ast" -- "net/http" -- "sort" +- overlays := map[string][]byte{} +- for k, v := range modules[0].Overlay { +- overlays[filepath.Join("testmodule", k)] = v +- } +- modules[0].Overlay = overlays - -- "golang.org/lsptests/foo" --) +- golden := map[string]*Golden{} +- for k, v := range datum.golden { +- if k == summaryFile { +- golden[k] = v +- } else { +- golden[filepath.Join("testmodule", k)] = v +- } +- } +- datum.golden = golden - --func _() { -- []int{} //@item(litIntSlice, "[]int{}", "", "var") -- &[]int{} //@item(litIntSliceAddr, "&[]int{}", "", "var") -- make([]int, 0) //@item(makeIntSlice, "make([]int, 0)", "", "func") +- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) +- default: +- panic("unknown mode " + mode) +- } - -- var _ *[]int = in //@snippet(" //", litIntSliceAddr, "&[]int{$0\\}", "&[]int{$0\\}") -- var _ **[]int = in //@complete(" //") +- for _, m := range modules { +- for fragment := range m.Files { +- filename := datum.Exported.File(m.Name, fragment) +- datum.fragments[filename] = fragment +- } +- } - -- var slice []int -- slice = i //@snippet(" //", litIntSlice, "[]int{$0\\}", "[]int{$0\\}") -- slice = m //@snippet(" //", makeIntSlice, "make([]int, ${1:})", "make([]int, ${1:0})") --} +- // Turn off go/packages debug logging. +- datum.Exported.Config.Logf = nil +- datum.Config.Logf = nil - --func _() { -- type namedInt []int +- // Merge the exported.Config with the view.Config. +- datum.Config = *datum.Exported.Config +- datum.Config.Fset = token.NewFileSet() +- datum.Config.Context = Context(nil) +- datum.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { +- panic("ParseFile should not be called") +- } - -- namedInt{} //@item(litNamedSlice, "namedInt{}", "", "var") -- make(namedInt, 0) //@item(makeNamedSlice, "make(namedInt, 0)", "", "func") +- // Do a first pass to collect special markers for completion and workspace symbols. +- if err := datum.Exported.Expect(map[string]interface{}{ +- "item": func(name string, r packagestest.Range, _ []string) { +- datum.Exported.Mark(name, r) +- }, +- "symbol": func(name string, r packagestest.Range, _ []string) { +- datum.Exported.Mark(name, r) +- }, +- }); err != nil { +- t.Fatal(err) +- } - -- var namedSlice namedInt -- namedSlice = n //@snippet(" //", litNamedSlice, "namedInt{$0\\}", "namedInt{$0\\}") -- namedSlice = m //@snippet(" //", makeNamedSlice, "make(namedInt, ${1:})", "make(namedInt, ${1:0})") --} +- // Collect any data that needs to be used by subsequent tests. +- if err := datum.Exported.Expect(map[string]interface{}{ +- "codelens": datum.collectCodeLens, +- "diag": datum.collectDiagnostics, +- "item": datum.collectCompletionItems, +- "complete": datum.collectCompletions(CompletionDefault), +- "unimported": datum.collectCompletions(CompletionUnimported), +- "deep": datum.collectCompletions(CompletionDeep), +- "fuzzy": datum.collectCompletions(CompletionFuzzy), +- "casesensitive": datum.collectCompletions(CompletionCaseSensitive), +- "rank": datum.collectCompletions(CompletionRank), +- "snippet": datum.collectCompletionSnippets, +- "fold": datum.collectFoldingRanges, +- "semantic": datum.collectSemanticTokens, +- "godef": datum.collectDefinitions, +- "typdef": datum.collectTypeDefinitions, +- "hoverdef": datum.collectHoverDefinitions, +- "highlight": datum.collectHighlights, +- "inlayHint": datum.collectInlayHints, +- "rename": datum.collectRenames, +- "prepare": datum.collectPrepareRenames, +- "signature": datum.collectSignatures, +- "link": datum.collectLinks, +- "suggestedfix": datum.collectSuggestedFixes, +- "extractmethod": datum.collectMethodExtractions, +- "incomingcalls": datum.collectIncomingCalls, +- "outgoingcalls": datum.collectOutgoingCalls, +- "addimport": datum.collectAddImports, +- "selectionrange": datum.collectSelectionRanges, +- }); err != nil { +- t.Fatal(err) +- } - --func _() { -- make(chan int) //@item(makeChan, "make(chan int)", "", "func") +- // Collect names for the entries that require golden files. +- if err := datum.Exported.Expect(map[string]interface{}{ +- "godef": datum.collectDefinitionNames, +- "hoverdef": datum.collectDefinitionNames, +- }); err != nil { +- t.Fatal(err) +- } +- if mode == "MultiModule" { +- if err := moveFile(filepath.Join(datum.Config.Dir, "go.mod"), filepath.Join(datum.Config.Dir, "testmodule/go.mod")); err != nil { +- t.Fatal(err) +- } +- } - -- var ch chan int -- ch = m //@snippet(" //", makeChan, "make(chan int)", "make(chan int)") +- return datum -} - --func _() { -- map[string]struct{}{} //@item(litMap, "map[string]struct{}{}", "", "var") -- make(map[string]struct{}) //@item(makeMap, "make(map[string]struct{})", "", "func") -- -- var m map[string]struct{} -- m = m //@snippet(" //", litMap, "map[string]struct{\\}{$0\\}", "map[string]struct{\\}{$0\\}") -- m = m //@snippet(" //", makeMap, "make(map[string]struct{\\})", "make(map[string]struct{\\})") -- -- struct{}{} //@item(litEmptyStruct, "struct{}{}", "", "var") +-// moveFile moves the file at oldpath to newpath, by renaming if possible +-// or copying otherwise. +-func moveFile(oldpath, newpath string) (err error) { +- renameErr := os.Rename(oldpath, newpath) +- if renameErr == nil { +- return nil +- } - -- m["hi"] = s //@snippet(" //", litEmptyStruct, "struct{\\}{\\}", "struct{\\}{\\}") --} +- src, err := os.Open(oldpath) +- if err != nil { +- return err +- } +- defer func() { +- src.Close() +- if err == nil { +- err = os.Remove(oldpath) +- } +- }() - --func _() { -- type myStruct struct{ i int } //@item(myStructType, "myStruct", "struct{...}", "struct") +- perm := os.ModePerm +- fi, err := src.Stat() +- if err == nil { +- perm = fi.Mode().Perm() +- } - -- myStruct{} //@item(litStruct, "myStruct{}", "", "var") -- &myStruct{} //@item(litStructPtr, "&myStruct{}", "", "var") +- dst, err := os.OpenFile(newpath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) +- if err != nil { +- return err +- } - -- var ms myStruct -- ms = m //@snippet(" //", litStruct, "myStruct{$0\\}", "myStruct{$0\\}") +- _, err = io.Copy(dst, src) +- if closeErr := dst.Close(); err == nil { +- err = closeErr +- } +- return err +-} - -- var msPtr *myStruct -- msPtr = m //@snippet(" //", litStructPtr, "&myStruct{$0\\}", "&myStruct{$0\\}") +-func Run(t *testing.T, tests Tests, data *Data) { +- t.Helper() +- checkData(t, data) - -- msPtr = &m //@snippet(" //", litStruct, "myStruct{$0\\}", "myStruct{$0\\}") +- eachCompletion := func(t *testing.T, cases map[span.Span][]Completion, test func(*testing.T, span.Span, Completion, CompletionItems)) { +- t.Helper() - -- type myStructCopy struct { i int } //@item(myStructCopyType, "myStructCopy", "struct{...}", "struct") +- for src, exp := range cases { +- for i, e := range exp { +- t.Run(SpanName(src)+"_"+strconv.Itoa(i), func(t *testing.T) { +- t.Helper() +- if strings.Contains(t.Name(), "cgo") { +- testenv.NeedsTool(t, "cgo") +- } +- test(t, src, e, data.CompletionItems) +- }) +- } - -- // Don't offer literal completion for convertible structs. -- ms = myStruct //@complete(" //", litStruct, myStructType, myStructCopyType) --} +- } +- } - --type myImpl struct{} +- t.Run("CallHierarchy", func(t *testing.T) { +- t.Helper() +- for spn, callHierarchyResult := range data.CallHierarchy { +- t.Run(SpanName(spn), func(t *testing.T) { +- t.Helper() +- tests.CallHierarchy(t, spn, callHierarchyResult) +- }) +- } +- }) - --func (myImpl) foo() {} +- t.Run("Completion", func(t *testing.T) { +- t.Helper() +- eachCompletion(t, data.Completions, tests.Completion) +- }) - --func (*myImpl) bar() {} +- t.Run("CompletionSnippets", func(t *testing.T) { +- t.Helper() +- for _, placeholders := range []bool{true, false} { +- for src, expecteds := range data.CompletionSnippets { +- for i, expected := range expecteds { +- name := SpanName(src) + "_" + strconv.Itoa(i+1) +- if placeholders { +- name += "_placeholders" +- } - --type myBasicImpl string +- t.Run(name, func(t *testing.T) { +- t.Helper() +- tests.CompletionSnippet(t, src, expected, placeholders, data.CompletionItems) +- }) +- } +- } +- } +- }) - --func (myBasicImpl) foo() {} +- t.Run("UnimportedCompletion", func(t *testing.T) { +- t.Helper() +- eachCompletion(t, data.UnimportedCompletions, tests.UnimportedCompletion) +- }) - --func _() { -- type myIntf interface { -- foo() -- } +- t.Run("DeepCompletion", func(t *testing.T) { +- t.Helper() +- eachCompletion(t, data.DeepCompletions, tests.DeepCompletion) +- }) - -- myImpl{} //@item(litImpl, "myImpl{}", "", "var") +- t.Run("FuzzyCompletion", func(t *testing.T) { +- t.Helper() +- eachCompletion(t, data.FuzzyCompletions, tests.FuzzyCompletion) +- }) - -- var mi myIntf -- mi = m //@snippet(" //", litImpl, "myImpl{\\}", "myImpl{\\}") +- t.Run("CaseSensitiveCompletion", func(t *testing.T) { +- t.Helper() +- eachCompletion(t, data.CaseSensitiveCompletions, tests.CaseSensitiveCompletion) +- }) - -- myBasicImpl() //@item(litBasicImpl, "myBasicImpl()", "string", "var") +- t.Run("RankCompletions", func(t *testing.T) { +- t.Helper() +- eachCompletion(t, data.RankCompletions, tests.RankCompletion) +- }) - -- mi = m //@snippet(" //", litBasicImpl, "myBasicImpl($0)", "myBasicImpl($0)") +- t.Run("CodeLens", func(t *testing.T) { +- t.Helper() +- for uri, want := range data.CodeLens { +- // Check if we should skip this URI if the -modfile flag is not available. +- if shouldSkip(data, uri) { +- continue +- } +- t.Run(uriName(uri), func(t *testing.T) { +- t.Helper() +- tests.CodeLens(t, uri, want) +- }) +- } +- }) - -- // only satisfied by pointer to myImpl -- type myPtrIntf interface { -- bar() -- } +- t.Run("Diagnostics", func(t *testing.T) { +- t.Helper() +- for uri, want := range data.Diagnostics { +- // Check if we should skip this URI if the -modfile flag is not available. +- if shouldSkip(data, uri) { +- continue +- } +- t.Run(uriName(uri), func(t *testing.T) { +- t.Helper() +- tests.Diagnostics(t, uri, want) +- }) +- } +- }) - -- &myImpl{} //@item(litImplPtr, "&myImpl{}", "", "var") +- t.Run("FoldingRange", func(t *testing.T) { +- t.Helper() +- for _, spn := range data.FoldingRanges { +- t.Run(uriName(spn.URI()), func(t *testing.T) { +- t.Helper() +- tests.FoldingRanges(t, spn) +- }) +- } +- }) - -- var mpi myPtrIntf -- mpi = m //@snippet(" //", litImplPtr, "&myImpl{\\}", "&myImpl{\\}") --} +- t.Run("SemanticTokens", func(t *testing.T) { +- t.Helper() +- for _, spn := range data.SemanticTokens { +- t.Run(uriName(spn.URI()), func(t *testing.T) { +- t.Helper() +- tests.SemanticTokens(t, spn) +- }) +- } +- }) - --func _() { -- var s struct{ i []int } //@item(litSliceField, "i", "[]int", "field") -- var foo []int -- // no literal completions after selector -- foo = s.i //@complete(" //", litSliceField) --} +- t.Run("SuggestedFix", func(t *testing.T) { +- t.Helper() +- for spn, actionKinds := range data.SuggestedFixes { +- // Check if we should skip this spn if the -modfile flag is not available. +- if shouldSkip(data, spn.URI()) { +- continue +- } +- t.Run(SpanName(spn), func(t *testing.T) { +- t.Helper() +- tests.SuggestedFix(t, spn, actionKinds, 1) +- }) +- } +- }) - --func _() { -- type myStruct struct{ i int } //@item(litMyStructType, "myStruct", "struct{...}", "struct") -- myStruct{} //@item(litMyStruct, "myStruct{}", "", "var") +- t.Run("MethodExtraction", func(t *testing.T) { +- t.Helper() +- for start, end := range data.MethodExtractions { +- // Check if we should skip this spn if the -modfile flag is not available. +- if shouldSkip(data, start.URI()) { +- continue +- } +- t.Run(SpanName(start), func(t *testing.T) { +- t.Helper() +- tests.MethodExtraction(t, start, end) +- }) +- } +- }) - -- foo := func(s string, args ...myStruct) {} -- // Don't give literal slice candidate for variadic arg. -- // Do give literal candidates for variadic element. -- foo("", myStruct) //@complete(")", litMyStruct, litMyStructType) --} +- t.Run("Definition", func(t *testing.T) { +- t.Helper() +- for spn, d := range data.Definitions { +- t.Run(SpanName(spn), func(t *testing.T) { +- t.Helper() +- if strings.Contains(t.Name(), "cgo") { +- testenv.NeedsTool(t, "cgo") +- } +- tests.Definition(t, spn, d) +- }) +- } +- }) - --func _() { -- Buffer{} //@item(litBuffer, "Buffer{}", "", "var") +- t.Run("Highlight", func(t *testing.T) { +- t.Helper() +- for pos, locations := range data.Highlights { +- t.Run(SpanName(pos), func(t *testing.T) { +- t.Helper() +- tests.Highlight(t, pos, locations) +- }) +- } +- }) - -- var b *bytes.Buffer -- b = bytes.Bu //@snippet(" //", litBuffer, "Buffer{\\}", "Buffer{\\}") --} +- t.Run("InlayHints", func(t *testing.T) { +- t.Helper() +- for _, src := range data.InlayHints { +- t.Run(SpanName(src), func(t *testing.T) { +- t.Helper() +- tests.InlayHints(t, src) +- }) +- } +- }) - --func _() { -- _ = "func(...) {}" //@item(litFunc, "func(...) {}", "", "var") +- t.Run("Renames", func(t *testing.T) { +- t.Helper() +- for spn, newText := range data.Renames { +- t.Run(uriName(spn.URI())+"_"+newText, func(t *testing.T) { +- t.Helper() +- tests.Rename(t, spn, newText) +- }) +- } +- }) - -- sort.Slice(nil, fun) //@complete(")", litFunc),snippet(")", litFunc, "func(i, j int) bool {$0\\}", "func(i, j int) bool {$0\\}") +- t.Run("PrepareRenames", func(t *testing.T) { +- t.Helper() +- for src, want := range data.PrepareRenames { +- t.Run(SpanName(src), func(t *testing.T) { +- t.Helper() +- tests.PrepareRename(t, src, want) +- }) +- } +- }) - -- http.HandleFunc("", f) //@snippet(")", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}", "func(${1:w} http.ResponseWriter, ${2:r} *http.Request) {$0\\}") +- t.Run("SignatureHelp", func(t *testing.T) { +- t.Helper() +- for spn, expectedSignature := range data.Signatures { +- t.Run(SpanName(spn), func(t *testing.T) { +- t.Helper() +- tests.SignatureHelp(t, spn, expectedSignature) +- }) +- } +- }) - -- // no literal "func" completions -- http.Handle("", fun) //@complete(")") +- t.Run("Link", func(t *testing.T) { +- t.Helper() +- for uri, wantLinks := range data.Links { +- // If we are testing GOPATH, then we do not want links with the versions +- // attached (pkg.go.dev/repoa/moda@v1.1.0/pkg), unless the file is a +- // go.mod, then we can skip it altogether. +- if data.Exported.Exporter == packagestest.GOPATH { +- if strings.HasSuffix(uri.Filename(), ".mod") { +- continue +- } +- re := regexp.MustCompile(`@v\d+\.\d+\.[\w-]+`) +- for i, link := range wantLinks { +- wantLinks[i].Target = re.ReplaceAllString(link.Target, "") +- } +- } +- t.Run(uriName(uri), func(t *testing.T) { +- t.Helper() +- tests.Link(t, uri, wantLinks) +- }) +- } +- }) - -- http.HandlerFunc() //@item(handlerFunc, "http.HandlerFunc()", "", "var") -- http.Handle("", h) //@snippet(")", handlerFunc, "http.HandlerFunc($0)", "http.HandlerFunc($0)") -- http.Handle("", http.HandlerFunc()) //@snippet("))", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}", "func(${1:w} http.ResponseWriter, ${2:r} *http.Request) {$0\\}") +- t.Run("AddImport", func(t *testing.T) { +- t.Helper() +- for uri, exp := range data.AddImport { +- t.Run(uriName(uri), func(t *testing.T) { +- tests.AddImport(t, uri, exp) +- }) +- } +- }) - -- var namedReturn func(s string) (b bool) -- namedReturn = f //@snippet(" //", litFunc, "func(s string) (b bool) {$0\\}", "func(s string) (b bool) {$0\\}") +- t.Run("SelectionRanges", func(t *testing.T) { +- t.Helper() +- for _, span := range data.SelectionRanges { +- t.Run(SpanName(span), func(t *testing.T) { +- tests.SelectionRanges(t, span) +- }) +- } +- }) - -- var multiReturn func() (bool, int) -- multiReturn = f //@snippet(" //", litFunc, "func() (bool, int) {$0\\}", "func() (bool, int) {$0\\}") +- if *UpdateGolden { +- for _, golden := range data.golden { +- if !golden.Modified { +- continue +- } +- sort.Slice(golden.Archive.Files, func(i, j int) bool { +- return golden.Archive.Files[i].Name < golden.Archive.Files[j].Name +- }) +- if err := ioutil.WriteFile(golden.Filename, txtar.Format(golden.Archive), 0666); err != nil { +- t.Fatal(err) +- } +- } +- } +-} - -- var multiNamedReturn func() (b bool, i int) -- multiNamedReturn = f //@snippet(" //", litFunc, "func() (b bool, i int) {$0\\}", "func() (b bool, i int) {$0\\}") +-func checkData(t *testing.T, data *Data) { +- buf := &bytes.Buffer{} +- diagnosticsCount := 0 +- for _, want := range data.Diagnostics { +- diagnosticsCount += len(want) +- } +- linksCount := 0 +- for _, want := range data.Links { +- linksCount += len(want) +- } +- definitionCount := 0 +- typeDefinitionCount := 0 +- for _, d := range data.Definitions { +- if d.IsType { +- typeDefinitionCount++ +- } else { +- definitionCount++ +- } +- } - -- var duplicateParams func(myImpl, int, myImpl) -- duplicateParams = f //@snippet(" //", litFunc, "func(mi1 myImpl, i int, mi2 myImpl) {$0\\}", "func(${1:mi1} myImpl, ${2:i} int, ${3:mi2} myImpl) {$0\\}") +- snippetCount := 0 +- for _, want := range data.CompletionSnippets { +- snippetCount += len(want) +- } - -- type aliasImpl = myImpl -- var aliasParams func(aliasImpl) aliasImpl -- aliasParams = f //@snippet(" //", litFunc, "func(ai aliasImpl) aliasImpl {$0\\}", "func(${1:ai} aliasImpl) aliasImpl {$0\\}") +- countCompletions := func(c map[span.Span][]Completion) (count int) { +- for _, want := range c { +- count += len(want) +- } +- return count +- } - -- const two = 2 -- var builtinTypes func([]int, [two]bool, map[string]string, struct{ i int }, interface{ foo() }, <-chan int) -- builtinTypes = f //@snippet(" //", litFunc, "func(i1 []int, b [two]bool, m map[string]string, s struct{ i int \\}, i2 interface{ foo() \\}, c <-chan int) {$0\\}", "func(${1:i1} []int, ${2:b} [two]bool, ${3:m} map[string]string, ${4:s} struct{ i int \\}, ${5:i2} interface{ foo() \\}, ${6:c} <-chan int) {$0\\}") +- countCodeLens := func(c map[span.URI][]protocol.CodeLens) (count int) { +- for _, want := range c { +- count += len(want) +- } +- return count +- } - -- var _ func(ast.Node) = f //@snippet(" //", litFunc, "func(n ast.Node) {$0\\}", "func(${1:n} ast.Node) {$0\\}") -- var _ func(error) = f //@snippet(" //", litFunc, "func(err error) {$0\\}", "func(${1:err} error) {$0\\}") -- var _ func(context.Context) = f //@snippet(" //", litFunc, "func(ctx context.Context) {$0\\}", "func(${1:ctx} context.Context) {$0\\}") +- fmt.Fprintf(buf, "CallHierarchyCount = %v\n", len(data.CallHierarchy)) +- fmt.Fprintf(buf, "CodeLensCount = %v\n", countCodeLens(data.CodeLens)) +- fmt.Fprintf(buf, "CompletionsCount = %v\n", countCompletions(data.Completions)) +- fmt.Fprintf(buf, "CompletionSnippetCount = %v\n", snippetCount) +- fmt.Fprintf(buf, "UnimportedCompletionsCount = %v\n", countCompletions(data.UnimportedCompletions)) +- fmt.Fprintf(buf, "DeepCompletionsCount = %v\n", countCompletions(data.DeepCompletions)) +- fmt.Fprintf(buf, "FuzzyCompletionsCount = %v\n", countCompletions(data.FuzzyCompletions)) +- fmt.Fprintf(buf, "RankedCompletionsCount = %v\n", countCompletions(data.RankCompletions)) +- fmt.Fprintf(buf, "CaseSensitiveCompletionsCount = %v\n", countCompletions(data.CaseSensitiveCompletions)) +- fmt.Fprintf(buf, "DiagnosticsCount = %v\n", diagnosticsCount) +- fmt.Fprintf(buf, "FoldingRangesCount = %v\n", len(data.FoldingRanges)) +- fmt.Fprintf(buf, "SemanticTokenCount = %v\n", len(data.SemanticTokens)) +- fmt.Fprintf(buf, "SuggestedFixCount = %v\n", len(data.SuggestedFixes)) +- fmt.Fprintf(buf, "MethodExtractionCount = %v\n", len(data.MethodExtractions)) +- fmt.Fprintf(buf, "DefinitionsCount = %v\n", definitionCount) +- fmt.Fprintf(buf, "TypeDefinitionsCount = %v\n", typeDefinitionCount) +- fmt.Fprintf(buf, "HighlightsCount = %v\n", len(data.Highlights)) +- fmt.Fprintf(buf, "InlayHintsCount = %v\n", len(data.InlayHints)) +- fmt.Fprintf(buf, "RenamesCount = %v\n", len(data.Renames)) +- fmt.Fprintf(buf, "PrepareRenamesCount = %v\n", len(data.PrepareRenames)) +- fmt.Fprintf(buf, "SignaturesCount = %v\n", len(data.Signatures)) +- fmt.Fprintf(buf, "LinksCount = %v\n", linksCount) +- fmt.Fprintf(buf, "SelectionRangesCount = %v\n", len(data.SelectionRanges)) - -- type context struct {} -- var _ func(context) = f //@snippet(" //", litFunc, "func(ctx context) {$0\\}", "func(${1:ctx} context) {$0\\}") +- want := string(data.Golden(t, "summary", summaryFile, func() ([]byte, error) { +- return buf.Bytes(), nil +- })) +- got := buf.String() +- if want != got { +- // These counters change when assertions are added or removed. +- // They act as an independent safety net to ensure that the +- // tests didn't spuriously pass because they did no work. +- t.Errorf("test summary does not match:\n%s\n(Run with -golden to update golden file; also, there may be one per Go version.)", compare.Text(want, got)) +- } -} - --func _() { -- StructFoo{} //@item(litStructFoo, "StructFoo{}", "struct{...}", "struct") -- -- var sfp *foo.StructFoo -- // Don't insert the "&" before "StructFoo{}". -- sfp = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}") +-func (data *Data) Mapper(uri span.URI) (*protocol.Mapper, error) { +- data.mappersMu.Lock() +- defer data.mappersMu.Unlock() - -- var sf foo.StructFoo -- sf = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}") -- sf = foo. //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}") +- if _, ok := data.mappers[uri]; !ok { +- content, err := data.Exported.FileContents(uri.Filename()) +- if err != nil { +- return nil, err +- } +- data.mappers[uri] = protocol.NewMapper(uri, content) +- } +- return data.mappers[uri], nil -} - --func _() { -- float64() //@item(litFloat64, "float64()", "float64", "var") +-func (data *Data) Golden(t *testing.T, tag, target string, update func() ([]byte, error)) []byte { +- t.Helper() +- fragment, found := data.fragments[target] +- if !found { +- if filepath.IsAbs(target) { +- t.Fatalf("invalid golden file fragment %v", target) +- } +- fragment = target +- } +- golden := data.golden[fragment] +- if golden == nil { +- if !*UpdateGolden { +- t.Fatalf("could not find golden file %v: %v", fragment, tag) +- } +- golden = &Golden{ +- Filename: filepath.Join(data.dir, fragment+goldenFileSuffix), +- Archive: &txtar.Archive{}, +- Modified: true, +- } +- data.golden[fragment] = golden +- } +- var file *txtar.File +- for i := range golden.Archive.Files { +- f := &golden.Archive.Files[i] +- if f.Name == tag { +- file = f +- break +- } +- } +- if *UpdateGolden { +- if file == nil { +- golden.Archive.Files = append(golden.Archive.Files, txtar.File{ +- Name: tag, +- }) +- file = &golden.Archive.Files[len(golden.Archive.Files)-1] +- } +- contents, err := update() +- if err != nil { +- t.Fatalf("could not update golden file %v: %v", fragment, err) +- } +- file.Data = append(contents, '\n') // add trailing \n for txtar +- golden.Modified = true - -- // don't complete to "&float64()" -- var _ *float64 = float64 //@complete(" //") +- } +- if file == nil { +- t.Fatalf("could not find golden contents %v: %v", fragment, tag) +- } +- if len(file.Data) == 0 { +- return file.Data +- } +- return file.Data[:len(file.Data)-1] // drop the trailing \n +-} - -- var f float64 -- f = fl //@complete(" //", litFloat64),snippet(" //", litFloat64, "float64($0)", "float64($0)") +-func (data *Data) collectCodeLens(spn span.Span, title, cmd string) { +- data.CodeLens[spn.URI()] = append(data.CodeLens[spn.URI()], protocol.CodeLens{ +- Range: data.mustRange(spn), +- Command: &protocol.Command{ +- Title: title, +- Command: cmd, +- }, +- }) +-} - -- type myInt int -- myInt() //@item(litMyInt, "myInt()", "", "var") +-func (data *Data) collectDiagnostics(spn span.Span, msgSource, msgPattern, msgSeverity string) { +- severity := protocol.SeverityError +- switch msgSeverity { +- case "error": +- severity = protocol.SeverityError +- case "warning": +- severity = protocol.SeverityWarning +- case "hint": +- severity = protocol.SeverityHint +- case "information": +- severity = protocol.SeverityInformation +- } - -- var mi myInt -- mi = my //@snippet(" //", litMyInt, "myInt($0)", "myInt($0)") +- data.Diagnostics[spn.URI()] = append(data.Diagnostics[spn.URI()], &source.Diagnostic{ +- Range: data.mustRange(spn), +- Severity: severity, +- Source: source.DiagnosticSource(msgSource), +- Message: msgPattern, +- }) -} - --func _() { -- type ptrStruct struct { -- p *ptrStruct +-func (data *Data) collectCompletions(typ CompletionTestType) func(span.Span, []token.Pos) { +- result := func(m map[span.Span][]Completion, src span.Span, expected []token.Pos) { +- m[src] = append(m[src], Completion{ +- CompletionItems: expected, +- }) - } -- -- ptrStruct{} //@item(litPtrStruct, "ptrStruct{}", "", "var") -- -- ptrStruct{ -- p: &ptrSt, //@rank(",", litPtrStruct) +- switch typ { +- case CompletionDeep: +- return func(src span.Span, expected []token.Pos) { +- result(data.DeepCompletions, src, expected) +- } +- case CompletionUnimported: +- return func(src span.Span, expected []token.Pos) { +- result(data.UnimportedCompletions, src, expected) +- } +- case CompletionFuzzy: +- return func(src span.Span, expected []token.Pos) { +- result(data.FuzzyCompletions, src, expected) +- } +- case CompletionRank: +- return func(src span.Span, expected []token.Pos) { +- result(data.RankCompletions, src, expected) +- } +- case CompletionCaseSensitive: +- return func(src span.Span, expected []token.Pos) { +- result(data.CaseSensitiveCompletions, src, expected) +- } +- default: +- return func(src span.Span, expected []token.Pos) { +- result(data.Completions, src, expected) +- } - } +-} - -- &ptrStruct{} //@item(litPtrStructPtr, "&ptrStruct{}", "", "var") -- -- &ptrStruct{ -- p: ptrSt, //@rank(",", litPtrStructPtr) +-func (data *Data) collectCompletionItems(pos token.Pos, label, detail, kind string, args []string) { +- var documentation string +- if len(args) > 3 { +- documentation = args[3] +- } +- data.CompletionItems[pos] = &completion.CompletionItem{ +- Label: label, +- Detail: detail, +- Kind: protocol.ParseCompletionItemKind(kind), +- Documentation: documentation, - } -} - --func _() { -- f := func(...[]int) {} -- f() //@snippet(")", litIntSlice, "[]int{$0\\}", "[]int{$0\\}") +-func (data *Data) collectFoldingRanges(spn span.Span) { +- data.FoldingRanges = append(data.FoldingRanges, spn) -} - -- --func _() { -- // don't complete to "untyped int()" -- []int{}[untyped] //@complete("] //") +-func (data *Data) collectAddImports(spn span.Span, imp string) { +- data.AddImport[spn.URI()] = imp -} -diff -urN a/gopls/internal/lsp/testdata/snippets/postfix.go b/gopls/internal/lsp/testdata/snippets/postfix.go ---- a/gopls/internal/lsp/testdata/snippets/postfix.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/postfix.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,42 +0,0 @@ --package snippets -- --// These tests check that postfix completions do and do not show up in --// certain cases. Tests for the postfix completion contents are under --// regtest. -- --func _() { -- /* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet") -- var foo []int -- foo.append //@rank(" //", postfixAppend) -- -- []int{}.append //@complete(" //") -- -- []int{}.last //@complete(" //") -- -- /* copy! */ //@item(postfixCopy, "copy!", "duplicate slice", "snippet") -- -- foo.copy //@rank(" //", postfixCopy) -- -- var s struct{ i []int } -- s.i.copy //@rank(" //", postfixCopy) - -- var _ []int = s.i.copy //@complete(" //") -- -- var blah func() []int -- blah().append //@complete(" //") +-func (data *Data) collectSemanticTokens(spn span.Span) { +- data.SemanticTokens = append(data.SemanticTokens, spn) -} - --func _() { -- /* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet") -- /* last! */ //@item(postfixLast, "last!", "s[len(s)-1]", "snippet") -- /* print! */ //@item(postfixPrint, "print!", "print to stdout", "snippet") -- /* range! */ //@item(postfixRange, "range!", "range over slice", "snippet") -- /* reverse! */ //@item(postfixReverse, "reverse!", "reverse slice", "snippet") -- /* sort! */ //@item(postfixSort, "sort!", "sort.Slice()", "snippet") -- /* var! */ //@item(postfixVar, "var!", "assign to variable", "snippet") -- -- var foo []int -- foo. //@complete(" //", postfixAppend, postfixCopy, postfixLast, postfixPrint, postfixRange, postfixReverse, postfixSort, postfixVar) -- -- foo = nil +-func (data *Data) collectSuggestedFixes(spn span.Span, actionKind, fix string) { +- data.SuggestedFixes[spn] = append(data.SuggestedFixes[spn], SuggestedFix{actionKind, fix}) -} -diff -urN a/gopls/internal/lsp/testdata/snippets/snippets.go.golden b/gopls/internal/lsp/testdata/snippets/snippets.go.golden ---- a/gopls/internal/lsp/testdata/snippets/snippets.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/snippets.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ ---- baz(at AliasType, b bool)-signature -- --baz(at AliasType, b bool) -- -diff -urN a/gopls/internal/lsp/testdata/snippets/snippets.go.in b/gopls/internal/lsp/testdata/snippets/snippets.go.in ---- a/gopls/internal/lsp/testdata/snippets/snippets.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/snippets/snippets.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,61 +0,0 @@ --package snippets -- --type AliasType = int //@item(sigAliasType, "AliasType", "AliasType", "type") -- --func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func") --func bar(fn func()) func() {} //@item(snipBar, "bar", "func(fn func())", "func") --func baz(at AliasType, b bool) {} //@item(snipBaz, "baz", "func(at AliasType, b bool)", "func") - --type Foo struct { -- Bar int //@item(snipFieldBar, "Bar", "int", "field") -- Func func(at AliasType) error //@item(snipFieldFunc, "Func", "func(at AliasType) error", "field") +-func (data *Data) collectMethodExtractions(start span.Span, end span.Span) { +- if _, ok := data.MethodExtractions[start]; !ok { +- data.MethodExtractions[start] = end +- } -} - --func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz", "func() func()", "method") --func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar", "func() func()", "method") --func (Foo) BazBaz(at AliasType) func() {} //@item(snipMethodBazBaz, "BazBaz", "func(at AliasType) func()", "method") -- --func _() { -- f //@snippet(" //", snipFoo, "foo(${1:})", "foo(${1:i int}, ${2:b bool})") -- -- bar //@snippet(" //", snipBar, "bar(${1:})", "bar(${1:fn func()})") -- -- baz //@snippet(" //", snipBaz, "baz(${1:})", "baz(${1:at AliasType}, ${2:b bool})") -- baz() //@signature("(", "baz(at AliasType, b bool)", 0) +-func (data *Data) collectDefinitions(src, target span.Span) { +- data.Definitions[src] = Definition{ +- Src: src, +- Def: target, +- } +-} - -- bar(nil) //@snippet("(", snipBar, "bar", "bar") -- bar(ba) //@snippet(")", snipBar, "bar(${1:})", "bar(${1:fn func()})") -- var f Foo -- bar(f.Ba) //@snippet(")", snipMethodBaz, "Baz()", "Baz()") -- (bar)(nil) //@snippet(")", snipBar, "bar(${1:})", "bar(${1:fn func()})") -- (f.Ba)() //@snippet(")", snipMethodBaz, "Baz()", "Baz()") +-func (data *Data) collectSelectionRanges(spn span.Span) { +- data.SelectionRanges = append(data.SelectionRanges, spn) +-} - -- Foo{ -- B //@snippet(" //", snipFieldBar, "Bar: ${1:},", "Bar: ${1:int},") +-func (data *Data) collectIncomingCalls(src span.Span, calls []span.Span) { +- for _, call := range calls { +- rng := data.mustRange(call) +- // we're only comparing protocol.range +- if data.CallHierarchy[src] != nil { +- data.CallHierarchy[src].IncomingCalls = append(data.CallHierarchy[src].IncomingCalls, +- protocol.CallHierarchyItem{ +- URI: protocol.DocumentURI(call.URI()), +- Range: rng, +- }) +- } else { +- data.CallHierarchy[src] = &CallHierarchyResult{ +- IncomingCalls: []protocol.CallHierarchyItem{ +- {URI: protocol.DocumentURI(call.URI()), Range: rng}, +- }, +- } +- } - } +-} - -- Foo{ -- F //@snippet(" //", snipFieldFunc, "Func: ${1:},", "Func: ${1:func(at AliasType) error},") +-func (data *Data) collectOutgoingCalls(src span.Span, calls []span.Span) { +- if data.CallHierarchy[src] == nil { +- data.CallHierarchy[src] = &CallHierarchyResult{} +- } +- for _, call := range calls { +- // we're only comparing protocol.range +- data.CallHierarchy[src].OutgoingCalls = append(data.CallHierarchy[src].OutgoingCalls, +- protocol.CallHierarchyItem{ +- URI: protocol.DocumentURI(call.URI()), +- Range: data.mustRange(call), +- }) - } -- -- Foo{B} //@snippet("}", snipFieldBar, "Bar: ${1:}", "Bar: ${1:int}") -- Foo{} //@snippet("}", snipFieldBar, "Bar: ${1:}", "Bar: ${1:int}") -- -- Foo{Foo{}.B} //@snippet("} ", snipFieldBar, "Bar", "Bar") -- -- var err error -- err.Error() //@snippet("E", Error, "Error()", "Error()") -- f.Baz() //@snippet("B", snipMethodBaz, "Baz()", "Baz()") -- -- f.Baz() //@snippet("(", snipMethodBazBar, "BazBar", "BazBar") -- -- f.Baz() //@snippet("B", snipMethodBazBaz, "BazBaz(${1:})", "BazBaz(${1:at AliasType})") -} - --func _() { -- type bar struct { -- a int -- b float64 //@item(snipBarB, "b", "float64", "field") +-func (data *Data) collectHoverDefinitions(src, target span.Span) { +- data.Definitions[src] = Definition{ +- Src: src, +- Def: target, +- OnlyHover: true, - } -- bar{b} //@snippet("}", snipBarB, "b: ${1:}", "b: ${1:float64}") -} -diff -urN a/gopls/internal/lsp/testdata/statements/append.go b/gopls/internal/lsp/testdata/statements/append.go ---- a/gopls/internal/lsp/testdata/statements/append.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/append.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,42 +0,0 @@ --package statements -- --func _() { -- type mySlice []int -- -- var ( -- abc []int //@item(stmtABC, "abc", "[]int", "var") -- abcdef mySlice //@item(stmtABCDEF, "abcdef", "mySlice", "var") -- ) - -- /* abcdef = append(abcdef, ) */ //@item(stmtABCDEFAssignAppend, "abcdef = append(abcdef, )", "", "func") -- -- // don't offer "abc = append(abc, )" because "abc" isn't necessarily -- // better than "abcdef". -- abc //@complete(" //", stmtABC, stmtABCDEF) -- -- abcdef //@complete(" //", stmtABCDEF, stmtABCDEFAssignAppend) -- -- /* append(abc, ) */ //@item(stmtABCAppend, "append(abc, )", "", "func") -- -- abc = app //@snippet(" //", stmtABCAppend, "append(abc, ${1:})", "append(abc, ${1:})") +-func (data *Data) collectTypeDefinitions(src, target span.Span) { +- data.Definitions[src] = Definition{ +- Src: src, +- Def: target, +- IsType: true, +- } -} - --func _() { -- var s struct{ xyz []int } -- -- /* xyz = append(s.xyz, ) */ //@item(stmtXYZAppend, "xyz = append(s.xyz, )", "", "func") -- -- s.x //@snippet(" //", stmtXYZAppend, "xyz = append(s.xyz, ${1:})", "xyz = append(s.xyz, ${1:})") -- -- /* s.xyz = append(s.xyz, ) */ //@item(stmtDeepXYZAppend, "s.xyz = append(s.xyz, )", "", "func") -- -- sx //@snippet(" //", stmtDeepXYZAppend, "s.xyz = append(s.xyz, ${1:})", "s.xyz = append(s.xyz, ${1:})") +-func (data *Data) collectDefinitionNames(src span.Span, name string) { +- d := data.Definitions[src] +- d.Name = name +- data.Definitions[src] = d -} - --func _() { -- var foo [][]int -- -- /* append(foo[0], ) */ //@item(stmtFooAppend, "append(foo[0], )", "", "func") -- -- foo[0] = app //@complete(" //"),snippet(" //", stmtFooAppend, "append(foo[0], ${1:})", "append(foo[0], ${1:})") +-func (data *Data) collectHighlights(src span.Span, expected []span.Span) { +- // Declaring a highlight in a test file: @highlight(src, expected1, expected2) +- data.Highlights[src] = append(data.Highlights[src], expected...) -} -diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go b/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go ---- a/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/if_err_check_return_2.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package statements -- --import "os" -- --func two() error { -- var s struct{ err error } -- -- /* if s.err != nil { return s.err } */ //@item(stmtTwoIfErrReturn, "if s.err != nil { return s.err }", "", "") - -- _, s.err = os.Open("foo") -- //@snippet("", stmtTwoIfErrReturn, "", "if s.err != nil {\n\treturn ${1:s.err}\n\\}") +-func (data *Data) collectInlayHints(src span.Span) { +- data.InlayHints = append(data.InlayHints, src) -} -diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_return.go b/gopls/internal/lsp/testdata/statements/if_err_check_return.go ---- a/gopls/internal/lsp/testdata/statements/if_err_check_return.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/if_err_check_return.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package statements -- --import ( -- "bytes" -- "io" -- "os" --) -- --func one() (int, float32, io.Writer, *int, []int, bytes.Buffer, error) { -- /* if err != nil { return err } */ //@item(stmtOneIfErrReturn, "if err != nil { return err }", "", "") -- /* err != nil { return err } */ //@item(stmtOneErrReturn, "err != nil { return err }", "", "") -- -- _, err := os.Open("foo") -- //@snippet("", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") - -- _, err = os.Open("foo") -- i //@snippet(" //", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +-func (data *Data) collectRenames(src span.Span, newText string) { +- data.Renames[src] = newText +-} - -- _, err = os.Open("foo") -- if er //@snippet(" //", stmtOneErrReturn, "", "err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +-func (data *Data) collectPrepareRenames(src, spn span.Span, placeholder string) { +- data.PrepareRenames[src] = &source.PrepareItem{ +- Range: data.mustRange(spn), +- Text: placeholder, +- } +-} - -- _, err = os.Open("foo") -- if //@snippet(" //", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +-// mustRange converts spn into a protocol.Range, panicking on any error. +-func (data *Data) mustRange(spn span.Span) protocol.Range { +- m, err := data.Mapper(spn.URI()) +- rng, err := m.SpanRange(spn) +- if err != nil { +- panic(fmt.Sprintf("converting span %s to range: %v", spn, err)) +- } +- return rng +-} - -- _, err = os.Open("foo") -- if //@snippet("//", stmtOneIfErrReturn, "", "if err != nil {\n\treturn 0, 0, nil, nil, nil, bytes.Buffer{\\}, ${1:err}\n\\}") +-func (data *Data) collectSignatures(spn span.Span, signature string, activeParam int64) { +- data.Signatures[spn] = &protocol.SignatureHelp{ +- Signatures: []protocol.SignatureInformation{ +- { +- Label: signature, +- }, +- }, +- ActiveParameter: uint32(activeParam), +- } +- // Hardcode special case to test the lack of a signature. +- if signature == "" && activeParam == 0 { +- data.Signatures[spn] = nil +- } -} -diff -urN a/gopls/internal/lsp/testdata/statements/if_err_check_test.go b/gopls/internal/lsp/testdata/statements/if_err_check_test.go ---- a/gopls/internal/lsp/testdata/statements/if_err_check_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/statements/if_err_check_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ --package statements - --import ( -- "os" -- "testing" --) +-func (data *Data) collectCompletionSnippets(spn span.Span, item token.Pos, plain, placeholder string) { +- data.CompletionSnippets[spn] = append(data.CompletionSnippets[spn], CompletionSnippet{ +- CompletionItem: item, +- PlainSnippet: plain, +- PlaceholderSnippet: placeholder, +- }) +-} - --func TestErr(t *testing.T) { -- /* if err != nil { t.Fatal(err) } */ //@item(stmtOneIfErrTFatal, "if err != nil { t.Fatal(err) }", "", "") +-func (data *Data) collectLinks(spn span.Span, link string, note *expect.Note, fset *token.FileSet) { +- position := safetoken.StartPosition(fset, note.Pos) +- uri := spn.URI() +- data.Links[uri] = append(data.Links[uri], Link{ +- Src: spn, +- Target: link, +- NotePosition: position, +- }) +-} - -- _, err := os.Open("foo") -- //@snippet("", stmtOneIfErrTFatal, "", "if err != nil {\n\tt.Fatal(err)\n\\}") +-func uriName(uri span.URI) string { +- return filepath.Base(strings.TrimSuffix(uri.Filename(), ".go")) -} - --func BenchmarkErr(b *testing.B) { -- /* if err != nil { b.Fatal(err) } */ //@item(stmtOneIfErrBFatal, "if err != nil { b.Fatal(err) }", "", "") +-// TODO(golang/go#54845): improve the formatting here to match standard +-// line:column position formatting. +-func SpanName(spn span.Span) string { +- return fmt.Sprintf("%v_%v_%v", uriName(spn.URI()), spn.Start().Line(), spn.Start().Column()) +-} - -- _, err := os.Open("foo") -- //@snippet("", stmtOneIfErrBFatal, "", "if err != nil {\n\tb.Fatal(err)\n\\}") +-func shouldSkip(data *Data, uri span.URI) bool { +- if data.ModfileFlagAvailable { +- return false +- } +- // If the -modfile flag is not available, then we do not want to run +- // any tests on the go.mod file. +- if strings.HasSuffix(uri.Filename(), ".mod") { +- return true +- } +- // If the -modfile flag is not available, then we do not want to test any +- // uri that contains "go mod tidy". +- m, err := data.Mapper(uri) +- return err == nil && strings.Contains(string(m.Content), ", \"go mod tidy\",") -} -diff -urN a/gopls/internal/lsp/testdata/stub/other/other.go b/gopls/internal/lsp/testdata/stub/other/other.go ---- a/gopls/internal/lsp/testdata/stub/other/other.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/other/other.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package other +diff -urN a/gopls/internal/lsp/tests/util.go b/gopls/internal/lsp/tests/util.go +--- a/gopls/internal/lsp/tests/util.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/util.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,478 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package tests - -import ( - "bytes" -- renamed_context "context" +- "fmt" +- "go/token" +- "path" +- "regexp" +- "sort" +- "strconv" +- "strings" +- "testing" +- +- "github.com/google/go-cmp/cmp" +- "github.com/google/go-cmp/cmp/cmpopts" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/lsp/source/completion" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "golang.org/x/tools/gopls/internal/span" -) - --type Interface interface { -- Get(renamed_context.Context) *bytes.Buffer +-var builtins = map[string]bool{ +- "append": true, +- "cap": true, +- "close": true, +- "complex": true, +- "copy": true, +- "delete": true, +- "error": true, +- "false": true, +- "imag": true, +- "iota": true, +- "len": true, +- "make": true, +- "new": true, +- "nil": true, +- "panic": true, +- "print": true, +- "println": true, +- "real": true, +- "recover": true, +- "true": true, -} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go b/gopls/internal/lsp/testdata/stub/stub_add_selector.go ---- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --package stub -- --import "io" -- --// This file tests that if an interface --// method references a type from its own package --// then our implementation must add the import/package selector --// in the concrete method if the concrete type is outside of the interface --// package --var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "refactor.rewrite", "") -- --type readerFrom struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_add_selector.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,19 +0,0 @@ ---- suggestedfix_stub_add_selector_10_23 -- --package stub - --import "io" -- --// This file tests that if an interface --// method references a type from its own package --// then our implementation must add the import/package selector --// in the concrete method if the concrete type is outside of the interface --// package --var _ io.ReaderFrom = &readerFrom{} //@suggestedfix("&readerFrom", "refactor.rewrite", "") +-// DiffLinks takes the links we got and checks if they are located within the source or a Note. +-// If the link is within a Note, the link is removed. +-// Returns an diff comment if there are differences and empty string if no diffs. +-func DiffLinks(mapper *protocol.Mapper, wantLinks []Link, gotLinks []protocol.DocumentLink) string { +- var notePositions []token.Position +- links := make(map[span.Span]string, len(wantLinks)) +- for _, link := range wantLinks { +- links[link.Src] = link.Target +- notePositions = append(notePositions, link.NotePosition) +- } - --type readerFrom struct{} +- var msg strings.Builder +- for _, link := range gotLinks { +- spn, err := mapper.RangeSpan(link.Range) +- if err != nil { +- return fmt.Sprintf("%v", err) +- } +- linkInNote := false +- for _, notePosition := range notePositions { +- // Drop the links found inside expectation notes arguments as this links are not collected by expect package. +- if notePosition.Line == spn.Start().Line() && +- notePosition.Column <= spn.Start().Column() { +- delete(links, spn) +- linkInNote = true +- } +- } +- if linkInNote { +- continue +- } - --// ReadFrom implements io.ReaderFrom --func (*readerFrom) ReadFrom(r io.Reader) (n int64, err error) { -- panic("unimplemented") +- if target, ok := links[spn]; ok { +- delete(links, spn) +- if target != *link.Target { +- fmt.Fprintf(&msg, "%s: want link with target %q, got %q\n", spn, target, *link.Target) +- } +- } else { +- fmt.Fprintf(&msg, "%s: got unexpected link with target %q\n", spn, *link.Target) +- } +- } +- for spn, target := range links { +- fmt.Fprintf(&msg, "%s: expected link with target %q is missing\n", spn, target) +- } +- return msg.String() -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go b/gopls/internal/lsp/testdata/stub/stub_assign.go ---- a/gopls/internal/lsp/testdata/stub/stub_assign.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package stub -- --import "io" -- --func main() { -- var br io.ByteWriter -- br = &byteWriter{} //@suggestedfix("&", "refactor.rewrite", "") --} +-// CompareDiagnostics reports testing errors to t when the diagnostic set got +-// does not match want. +-func CompareDiagnostics(t *testing.T, uri span.URI, want, got []*source.Diagnostic) { +- t.Helper() +- fileName := path.Base(string(uri)) - --type byteWriter struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,17 +0,0 @@ ---- suggestedfix_stub_assign_7_7 -- --package stub +- // Build a helper function to match an actual diagnostic to an overlapping +- // expected diagnostic (if any). +- unmatched := make([]*source.Diagnostic, len(want)) +- copy(unmatched, want) +- source.SortDiagnostics(unmatched) +- match := func(g *source.Diagnostic) *source.Diagnostic { +- // Find the last expected diagnostic d for which start(d) < end(g), and +- // check to see if it overlaps. +- i := sort.Search(len(unmatched), func(i int) bool { +- d := unmatched[i] +- // See rangeOverlaps: if a range is a single point, we consider End to be +- // included in the range... +- if g.Range.Start == g.Range.End { +- return protocol.ComparePosition(d.Range.Start, g.Range.End) > 0 +- } +- // ...otherwise the end position of a range is not included. +- return protocol.ComparePosition(d.Range.Start, g.Range.End) >= 0 +- }) +- if i == 0 { +- return nil +- } +- w := unmatched[i-1] +- if rangeOverlaps(w.Range, g.Range) { +- unmatched = append(unmatched[:i-1], unmatched[i:]...) +- return w +- } +- return nil +- } - --import "io" +- for _, g := range got { +- w := match(g) +- if w == nil { +- t.Errorf("%s:%s: unexpected diagnostic %q", fileName, g.Range, g.Message) +- continue +- } +- if match, err := regexp.MatchString(w.Message, g.Message); err != nil { +- t.Errorf("%s:%s: invalid regular expression %q: %v", fileName, w.Range.Start, w.Message, err) +- } else if !match { +- t.Errorf("%s:%s: got Message %q, want match for pattern %q", fileName, g.Range.Start, g.Message, w.Message) +- } +- if w.Severity != g.Severity { +- t.Errorf("%s:%s: got Severity %v, want %v", fileName, g.Range.Start, g.Severity, w.Severity) +- } +- if w.Source != g.Source { +- t.Errorf("%s:%s: got Source %v, want %v", fileName, g.Range.Start, g.Source, w.Source) +- } +- } - --func main() { -- var br io.ByteWriter -- br = &byteWriter{} //@suggestedfix("&", "refactor.rewrite", "") +- for _, w := range unmatched { +- t.Errorf("%s:%s: unmatched diagnostic pattern %q", fileName, w.Range, w.Message) +- } -} - --type byteWriter struct{} -- --// WriteByte implements io.ByteWriter --func (*byteWriter) WriteByte(c byte) error { -- panic("unimplemented") +-// rangeOverlaps reports whether r1 and r2 overlap. +-func rangeOverlaps(r1, r2 protocol.Range) bool { +- if inRange(r2.Start, r1) || inRange(r1.Start, r2) { +- return true +- } +- return false -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go ---- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package stub -- --import "io" -- --func main() { -- var br io.ByteWriter -- var i int -- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "refactor.rewrite", "") +-// inRange reports whether p is contained within [r.Start, r.End), or if p == +-// r.Start == r.End (special handling for the case where the range is a single +-// point). +-func inRange(p protocol.Position, r protocol.Range) bool { +- if protocol.IsPoint(r) { +- return protocol.ComparePosition(r.Start, p) == 0 +- } +- if protocol.ComparePosition(r.Start, p) <= 0 && protocol.ComparePosition(p, r.End) < 0 { +- return true +- } +- return false -} - --type multiByteWriter struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_assign_multivars.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_assign_multivars_8_13 -- --package stub -- --import "io" +-func DiffCodeLens(uri span.URI, want, got []protocol.CodeLens) string { +- sortCodeLens(want) +- sortCodeLens(got) - --func main() { -- var br io.ByteWriter -- var i int -- i, br = 1, &multiByteWriter{} //@suggestedfix("&", "refactor.rewrite", "") +- if len(got) != len(want) { +- return summarizeCodeLens(-1, uri, want, got, "different lengths got %v want %v", len(got), len(want)) +- } +- for i, w := range want { +- g := got[i] +- if w.Command.Command != g.Command.Command { +- return summarizeCodeLens(i, uri, want, got, "incorrect Command Name got %v want %v", g.Command.Command, w.Command.Command) +- } +- if w.Command.Title != g.Command.Title { +- return summarizeCodeLens(i, uri, want, got, "incorrect Command Title got %v want %v", g.Command.Title, w.Command.Title) +- } +- if protocol.ComparePosition(w.Range.Start, g.Range.Start) != 0 { +- return summarizeCodeLens(i, uri, want, got, "incorrect Start got %v want %v", g.Range.Start, w.Range.Start) +- } +- if !protocol.IsPoint(g.Range) { // Accept any 'want' range if the codelens returns a zero-length range. +- if protocol.ComparePosition(w.Range.End, g.Range.End) != 0 { +- return summarizeCodeLens(i, uri, want, got, "incorrect End got %v want %v", g.Range.End, w.Range.End) +- } +- } +- } +- return "" -} - --type multiByteWriter struct{} +-func sortCodeLens(c []protocol.CodeLens) { +- sort.Slice(c, func(i int, j int) bool { +- if r := protocol.CompareRange(c[i].Range, c[j].Range); r != 0 { +- return r < 0 +- } +- if c[i].Command.Command < c[j].Command.Command { +- return true +- } else if c[i].Command.Command == c[j].Command.Command { +- return c[i].Command.Title < c[j].Command.Title +- } else { +- return false +- } +- }) +-} - --// WriteByte implements io.ByteWriter --func (*multiByteWriter) WriteByte(c byte) error { -- panic("unimplemented") +-func summarizeCodeLens(i int, uri span.URI, want, got []protocol.CodeLens, reason string, args ...interface{}) string { +- msg := &bytes.Buffer{} +- fmt.Fprint(msg, "codelens failed") +- if i >= 0 { +- fmt.Fprintf(msg, " at %d", i) +- } +- fmt.Fprint(msg, " because of ") +- fmt.Fprintf(msg, reason, args...) +- fmt.Fprint(msg, ":\nexpected:\n") +- for _, d := range want { +- fmt.Fprintf(msg, " %s:%v: %s | %s\n", uri, d.Range, d.Command.Command, d.Command.Title) +- } +- fmt.Fprintf(msg, "got:\n") +- for _, d := range got { +- fmt.Fprintf(msg, " %s:%v: %s | %s\n", uri, d.Range, d.Command.Command, d.Command.Title) +- } +- return msg.String() -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go b/gopls/internal/lsp/testdata/stub/stub_call_expr.go ---- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package stub +-func DiffSignatures(spn span.Span, want, got *protocol.SignatureHelp) string { +- decorate := func(f string, args ...interface{}) string { +- return fmt.Sprintf("invalid signature at %s: %s", spn, fmt.Sprintf(f, args...)) +- } +- if len(got.Signatures) != 1 { +- return decorate("wanted 1 signature, got %d", len(got.Signatures)) +- } +- if got.ActiveSignature != 0 { +- return decorate("wanted active signature of 0, got %d", int(got.ActiveSignature)) +- } +- if want.ActiveParameter != got.ActiveParameter { +- return decorate("wanted active parameter of %d, got %d", want.ActiveParameter, int(got.ActiveParameter)) +- } +- g := got.Signatures[0] +- w := want.Signatures[0] +- if diff := compare.Text(NormalizeAny(w.Label), NormalizeAny(g.Label)); diff != "" { +- return decorate("mismatched labels:\n%s", diff) +- } +- var paramParts []string +- for _, p := range g.Parameters { +- paramParts = append(paramParts, p.Label) +- } +- paramsStr := strings.Join(paramParts, ", ") +- if !strings.Contains(g.Label, paramsStr) { +- return decorate("expected signature %q to contain params %q", g.Label, paramsStr) +- } +- return "" +-} - --func main() { -- check(&callExpr{}) //@suggestedfix("&", "refactor.rewrite", "") +-// NormalizeAny replaces occurrences of interface{} in input with any. +-// +-// In Go 1.18, standard library functions were changed to use the 'any' +-// alias in place of interface{}, which affects their type string. +-func NormalizeAny(input string) string { +- return strings.ReplaceAll(input, "interface{}", "any") -} - --func check(err error) { -- if err != nil { -- panic(err) +-// DiffCallHierarchyItems returns the diff between expected and actual call locations for incoming/outgoing call hierarchies +-func DiffCallHierarchyItems(gotCalls []protocol.CallHierarchyItem, expectedCalls []protocol.CallHierarchyItem) string { +- expected := make(map[protocol.Location]bool) +- for _, call := range expectedCalls { +- expected[protocol.Location{URI: call.URI, Range: call.Range}] = true - } +- +- got := make(map[protocol.Location]bool) +- for _, call := range gotCalls { +- got[protocol.Location{URI: call.URI, Range: call.Range}] = true +- } +- if len(got) != len(expected) { +- return fmt.Sprintf("expected %d calls but got %d", len(expected), len(got)) +- } +- for spn := range got { +- if !expected[spn] { +- return fmt.Sprintf("incorrect calls, expected locations %v but got locations %v", expected, got) +- } +- } +- return "" -} - --type callExpr struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_call_expr.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,20 +0,0 @@ ---- suggestedfix_stub_call_expr_4_8 -- --package stub +-func FilterBuiltins(src span.Span, items []protocol.CompletionItem) []protocol.CompletionItem { +- var ( +- got []protocol.CompletionItem +- wantBuiltins = strings.Contains(string(src.URI()), "builtins") +- wantKeywords = strings.Contains(string(src.URI()), "keywords") +- ) +- for _, item := range items { +- if !wantBuiltins && isBuiltin(item.Label, item.Detail, item.Kind) { +- continue +- } - --func main() { -- check(&callExpr{}) //@suggestedfix("&", "refactor.rewrite", "") --} +- if !wantKeywords && token.Lookup(item.Label).IsKeyword() { +- continue +- } - --func check(err error) { -- if err != nil { -- panic(err) +- got = append(got, item) - } +- return got -} - --type callExpr struct{} -- --// Error implements error --func (*callExpr) Error() string { -- panic("unimplemented") +-func isBuiltin(label, detail string, kind protocol.CompletionItemKind) bool { +- if detail == "" && kind == protocol.ClassCompletion { +- return true +- } +- // Remaining builtin constants, variables, interfaces, and functions. +- trimmed := label +- if i := strings.Index(trimmed, "("); i >= 0 { +- trimmed = trimmed[:i] +- } +- return builtins[trimmed] -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go b/gopls/internal/lsp/testdata/stub/stub_embedded.go ---- a/gopls/internal/lsp/testdata/stub/stub_embedded.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ --package stub +-func CheckCompletionOrder(want, got []protocol.CompletionItem, strictScores bool) string { +- var ( +- matchedIdxs []int +- lastGotIdx int +- lastGotSort float64 +- inOrder = true +- errorMsg = "completions out of order" +- ) +- for _, w := range want { +- var found bool +- for i, g := range got { +- if w.Label == g.Label && NormalizeAny(w.Detail) == NormalizeAny(g.Detail) && w.Kind == g.Kind { +- matchedIdxs = append(matchedIdxs, i) +- found = true - --import ( -- "io" -- "sort" --) +- if i < lastGotIdx { +- inOrder = false +- } +- lastGotIdx = i - --var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "refactor.rewrite", "") +- sort, _ := strconv.ParseFloat(g.SortText, 64) +- if strictScores && len(matchedIdxs) > 1 && sort <= lastGotSort { +- inOrder = false +- errorMsg = "candidate scores not strictly decreasing" +- } +- lastGotSort = sort - --type embeddedConcrete struct{} +- break +- } +- } +- if !found { +- return summarizeCompletionItems(-1, []protocol.CompletionItem{w}, got, "didn't find expected completion") +- } +- } - --type embeddedInterface interface { -- sort.Interface -- io.Reader --} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_embedded.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,37 +0,0 @@ ---- suggestedfix_stub_embedded_8_27 -- --package stub +- sort.Ints(matchedIdxs) +- matched := make([]protocol.CompletionItem, 0, len(matchedIdxs)) +- for _, idx := range matchedIdxs { +- matched = append(matched, got[idx]) +- } - --import ( -- "io" -- "sort" --) +- if !inOrder { +- return summarizeCompletionItems(-1, want, matched, errorMsg) +- } - --var _ embeddedInterface = (*embeddedConcrete)(nil) //@suggestedfix("(", "refactor.rewrite", "") +- return "" +-} - --type embeddedConcrete struct{} +-func DiffSnippets(want string, got *protocol.CompletionItem) string { +- if want == "" { +- if got != nil { +- x := got.TextEdit +- return fmt.Sprintf("expected no snippet but got %s", x.NewText) +- } +- } else { +- if got == nil { +- return fmt.Sprintf("couldn't find completion matching %q", want) +- } +- x := got.TextEdit +- if want != x.NewText { +- return fmt.Sprintf("expected snippet %q, got %q", want, x.NewText) +- } +- } +- return "" +-} - --// Len implements embeddedInterface --func (*embeddedConcrete) Len() int { -- panic("unimplemented") +-func FindItem(list []protocol.CompletionItem, want completion.CompletionItem) *protocol.CompletionItem { +- for _, item := range list { +- if item.Label == want.Label { +- return &item +- } +- } +- return nil -} - --// Less implements embeddedInterface --func (*embeddedConcrete) Less(i int, j int) bool { -- panic("unimplemented") +-// DiffCompletionItems prints the diff between expected and actual completion +-// test results. +-// +-// The diff will be formatted using '-' and '+' for want and got, respectively. +-func DiffCompletionItems(want, got []protocol.CompletionItem) string { +- // Many fields are not set in the "want" slice. +- irrelevantFields := []string{ +- "AdditionalTextEdits", +- "Documentation", +- "TextEdit", +- "SortText", +- "Preselect", +- "FilterText", +- "InsertText", +- "InsertTextFormat", +- } +- ignore := cmpopts.IgnoreFields(protocol.CompletionItem{}, irrelevantFields...) +- normalizeAny := cmpopts.AcyclicTransformer("NormalizeAny", func(item protocol.CompletionItem) protocol.CompletionItem { +- item.Detail = NormalizeAny(item.Detail) +- return item +- }) +- return cmp.Diff(want, got, ignore, normalizeAny) -} - --// Read implements embeddedInterface --func (*embeddedConcrete) Read(p []byte) (n int, err error) { -- panic("unimplemented") +-func summarizeCompletionItems(i int, want, got []protocol.CompletionItem, reason string, args ...interface{}) string { +- msg := &bytes.Buffer{} +- fmt.Fprint(msg, "completion failed") +- if i >= 0 { +- fmt.Fprintf(msg, " at %d", i) +- } +- fmt.Fprint(msg, " because of ") +- fmt.Fprintf(msg, reason, args...) +- fmt.Fprint(msg, ":\nexpected:\n") +- for _, d := range want { +- fmt.Fprintf(msg, " %v\n", d) +- } +- fmt.Fprintf(msg, "got:\n") +- for _, d := range got { +- fmt.Fprintf(msg, " %v\n", d) +- } +- return msg.String() -} - --// Swap implements embeddedInterface --func (*embeddedConcrete) Swap(i int, j int) { -- panic("unimplemented") +-func EnableAllAnalyzers(opts *source.Options) { +- if opts.Analyses == nil { +- opts.Analyses = make(map[string]bool) +- } +- for _, a := range opts.DefaultAnalyzers { +- if !a.IsEnabled(opts) { +- opts.Analyses[a.Analyzer.Name] = true +- } +- } +- for _, a := range opts.TypeErrorAnalyzers { +- if !a.IsEnabled(opts) { +- opts.Analyses[a.Analyzer.Name] = true +- } +- } +- for _, a := range opts.ConvenienceAnalyzers { +- if !a.IsEnabled(opts) { +- opts.Analyses[a.Analyzer.Name] = true +- } +- } +- for _, a := range opts.StaticcheckAnalyzers { +- if !a.IsEnabled(opts) { +- opts.Analyses[a.Analyzer.Name] = true +- } +- } -} - --type embeddedInterface interface { -- sort.Interface -- io.Reader +-func EnableAllInlayHints(opts *source.Options) { +- if opts.Hints == nil { +- opts.Hints = make(map[string]bool) +- } +- for name := range source.AllInlayHints { +- opts.Hints[name] = true +- } -} +diff -urN a/gopls/internal/lsp/tests/util_go118.go b/gopls/internal/lsp/tests/util_go118.go +--- a/gopls/internal/lsp/tests/util_go118.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/util_go118.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go b/gopls/internal/lsp/testdata/stub/stub_err.go ---- a/gopls/internal/lsp/testdata/stub/stub_err.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_err.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package stub +-//go:build go1.18 +-// +build go1.18 - --func main() { -- var br error = &customErr{} //@suggestedfix("&", "refactor.rewrite", "") --} +-package tests - --type customErr struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_err.go.golden b/gopls/internal/lsp/testdata/stub/stub_err.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_err.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_err.go.golden 1970-01-01 00:00:00.000000000 +0000 +-func init() { +- builtins["any"] = true +- builtins["comparable"] = true +-} +diff -urN a/gopls/internal/lsp/tests/util_go121.go b/gopls/internal/lsp/tests/util_go121.go +--- a/gopls/internal/lsp/tests/util_go121.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/util_go121.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ ---- suggestedfix_stub_err_4_17 -- --package stub +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.21 +-// +build go1.21 +- +-package tests +- +-func init() { +- builtins["clear"] = true +- builtins["max"] = true +- builtins["min"] = true +-} +diff -urN a/gopls/internal/lsp/tests/util_go122.go b/gopls/internal/lsp/tests/util_go122.go +--- a/gopls/internal/lsp/tests/util_go122.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/tests/util_go122.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func main() { -- var br error = &customErr{} //@suggestedfix("&", "refactor.rewrite", "") --} +-//go:build go1.22 +-// +build go1.22 - --type customErr struct{} +-package tests - --// Error implements error --func (*customErr) Error() string { -- panic("unimplemented") +-func init() { +- builtins["zero"] = true -} +diff -urN a/gopls/internal/lsp/text_synchronization.go b/gopls/internal/lsp/text_synchronization.go +--- a/gopls/internal/lsp/text_synchronization.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/text_synchronization.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,366 +0,0 @@ +-// Copyright 2019 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go b/gopls/internal/lsp/testdata/stub/stub_function_return.go ---- a/gopls/internal/lsp/testdata/stub/stub_function_return.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package stub +-package lsp - -import ( -- "io" +- "bytes" +- "context" +- "errors" +- "fmt" +- "path/filepath" +- "sync" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/event/tag" +- "golang.org/x/tools/internal/jsonrpc2" -) - --func newCloser() io.Closer { -- return closer{} //@suggestedfix("c", "refactor.rewrite", "") --} +-// ModificationSource identifies the originating cause of a file modification. +-type ModificationSource int - --type closer struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_function_return.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_function_return_8_9 -- --package stub +-const ( +- // FromDidOpen is a file modification caused by opening a file. +- FromDidOpen = ModificationSource(iota) - --import ( -- "io" +- // FromDidChange is a file modification caused by changing a file. +- FromDidChange +- +- // FromDidChangeWatchedFiles is a file modification caused by a change to a +- // watched file. +- FromDidChangeWatchedFiles +- +- // FromDidSave is a file modification caused by a file save. +- FromDidSave +- +- // FromDidClose is a file modification caused by closing a file. +- FromDidClose +- +- // TODO: add FromDidChangeConfiguration, once configuration changes cause a +- // new snapshot to be created. +- +- // FromRegenerateCgo refers to file modifications caused by regenerating +- // the cgo sources for the workspace. +- FromRegenerateCgo +- +- // FromInitialWorkspaceLoad refers to the loading of all packages in the +- // workspace when the view is first created. +- FromInitialWorkspaceLoad -) - --func newCloser() io.Closer { -- return closer{} //@suggestedfix("c", "refactor.rewrite", "") +-func (m ModificationSource) String() string { +- switch m { +- case FromDidOpen: +- return "opened files" +- case FromDidChange: +- return "changed files" +- case FromDidChangeWatchedFiles: +- return "files changed on disk" +- case FromDidSave: +- return "saved files" +- case FromDidClose: +- return "close files" +- case FromRegenerateCgo: +- return "regenerate cgo" +- case FromInitialWorkspaceLoad: +- return "initial workspace load" +- default: +- return "unknown file modification" +- } -} - --type closer struct{} +-func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didOpen", tag.URI.Of(params.TextDocument.URI)) +- defer done() - --// Close implements io.Closer --func (closer) Close() error { -- panic("unimplemented") +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil +- } +- // There may not be any matching view in the current session. If that's +- // the case, try creating a new view based on the opened file path. +- // +- // TODO(rstambler): This seems like it would continuously add new +- // views, but it won't because ViewOf only returns an error when there +- // are no views in the session. I don't know if that logic should go +- // here, or if we can continue to rely on that implementation detail. +- if _, err := s.session.ViewOf(uri); err != nil { +- dir := filepath.Dir(uri.Filename()) +- if err := s.addFolders(ctx, []protocol.WorkspaceFolder{{ +- URI: string(protocol.URIFromPath(dir)), +- Name: filepath.Base(dir), +- }}); err != nil { +- return err +- } +- } +- return s.didModifyFiles(ctx, []source.FileModification{{ +- URI: uri, +- Action: source.Open, +- Version: params.TextDocument.Version, +- Text: []byte(params.TextDocument.Text), +- LanguageID: params.TextDocument.LanguageID, +- }}, FromDidOpen) -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go ---- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,15 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didChange", tag.URI.Of(params.TextDocument.URI)) +- defer done() - --package stub +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil +- } - --import "io" +- text, err := s.changedText(ctx, uri, params.ContentChanges) +- if err != nil { +- return err +- } +- c := source.FileModification{ +- URI: uri, +- Action: source.Change, +- Version: params.TextDocument.Version, +- Text: text, +- } +- if err := s.didModifyFiles(ctx, []source.FileModification{c}, FromDidChange); err != nil { +- return err +- } +- return s.warnAboutModifyingGeneratedFiles(ctx, uri) +-} - --// This file tests that that the stub method generator accounts for concrete --// types that have type parameters defined. --var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "refactor.rewrite", "Implement io.ReaderFrom") +-// warnAboutModifyingGeneratedFiles shows a warning if a user tries to edit a +-// generated file for the first time. +-func (s *Server) warnAboutModifyingGeneratedFiles(ctx context.Context, uri span.URI) error { +- s.changedFilesMu.Lock() +- _, ok := s.changedFiles[uri] +- if !ok { +- s.changedFiles[uri] = struct{}{} +- } +- s.changedFilesMu.Unlock() - --type genReader[T, Y any] struct { -- T T -- Y Y +- // This file has already been edited before. +- if ok { +- return nil +- } +- +- // Ideally, we should be able to specify that a generated file should +- // be opened as read-only. Tell the user that they should not be +- // editing a generated file. +- view, err := s.session.ViewOf(uri) +- if err != nil { +- return err +- } +- snapshot, release, err := view.Snapshot() +- if err != nil { +- return err +- } +- isGenerated := source.IsGenerated(ctx, snapshot, uri) +- release() +- +- if !isGenerated { +- return nil +- } +- return s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ +- Message: fmt.Sprintf("Do not edit this file! %s is a generated file.", uri.Filename()), +- Type: protocol.Warning, +- }) -} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_generic_receiver.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ ---- suggestedfix_stub_generic_receiver_10_23 -- --//go:build go1.18 --// +build go1.18 - --package stub +-func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.DidChangeWatchedFilesParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didChangeWatchedFiles") +- defer done() - --import "io" +- var modifications []source.FileModification +- for _, change := range params.Changes { +- uri := change.URI.SpanURI() +- if !uri.IsFile() { +- continue +- } +- action := changeTypeToFileAction(change.Type) +- modifications = append(modifications, source.FileModification{ +- URI: uri, +- Action: action, +- OnDisk: true, +- }) +- } +- return s.didModifyFiles(ctx, modifications, FromDidChangeWatchedFiles) +-} - --// This file tests that that the stub method generator accounts for concrete --// types that have type parameters defined. --var _ io.ReaderFrom = &genReader[string, int]{} //@suggestedfix("&genReader", "refactor.rewrite", "Implement io.ReaderFrom") +-func (s *Server) didSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didSave", tag.URI.Of(params.TextDocument.URI)) +- defer done() - --type genReader[T, Y any] struct { -- T T -- Y Y +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil +- } +- c := source.FileModification{ +- URI: uri, +- Action: source.Save, +- } +- if params.Text != nil { +- c.Text = []byte(*params.Text) +- } +- return s.didModifyFiles(ctx, []source.FileModification{c}, FromDidSave) -} - --// ReadFrom implements io.ReaderFrom --func (*genReader[T, Y]) ReadFrom(r io.Reader) (n int64, err error) { -- panic("unimplemented") +-func (s *Server) didClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didClose", tag.URI.Of(params.TextDocument.URI)) +- defer done() +- +- uri := params.TextDocument.URI.SpanURI() +- if !uri.IsFile() { +- return nil +- } +- return s.didModifyFiles(ctx, []source.FileModification{ +- { +- URI: uri, +- Action: source.Close, +- Version: -1, +- Text: nil, +- }, +- }, FromDidClose) -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go ---- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ --package stub +-func (s *Server) didModifyFiles(ctx context.Context, modifications []source.FileModification, cause ModificationSource) error { +- // wg guards two conditions: +- // 1. didModifyFiles is complete +- // 2. the goroutine diagnosing changes on behalf of didModifyFiles is +- // complete, if it was started +- // +- // Both conditions must be satisfied for the purpose of testing: we don't +- // want to observe the completion of change processing until we have received +- // all diagnostics as well as all server->client notifications done on behalf +- // of this function. +- var wg sync.WaitGroup +- wg.Add(1) +- defer wg.Done() - --import ( -- "compress/zlib" -- . "io" -- _ "io" --) +- if s.session.Options().VerboseWorkDoneProgress { +- work := s.progress.Start(ctx, DiagnosticWorkTitle(cause), "Calculating file diagnostics...", nil, nil) +- go func() { +- wg.Wait() +- work.End(ctx, "Done.") +- }() +- } - --// This file tests that dot-imports and underscore imports --// are properly ignored and that a new import is added to --// reference method types +- onDisk := cause == FromDidChangeWatchedFiles - --var ( -- _ Reader -- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "refactor.rewrite", "") --) +- s.stateMu.Lock() +- if s.state >= serverShutDown { +- // This state check does not prevent races below, and exists only to +- // produce a better error message. The actual race to the cache should be +- // guarded by Session.viewMu. +- s.stateMu.Unlock() +- return errors.New("server is shut down") +- } +- s.stateMu.Unlock() - --type ignoredResetter struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_ignored_imports.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,25 +0,0 @@ ---- suggestedfix_stub_ignored_imports_15_20 -- --package stub +- // If the set of changes included directories, expand those directories +- // to their files. +- modifications = s.session.ExpandModificationsToDirectories(ctx, modifications) - --import ( -- "compress/zlib" -- . "io" -- _ "io" --) +- // Build a lookup map for file modifications, so that we can later join +- // with the snapshot file associations. +- modMap := make(map[span.URI]source.FileModification) +- for _, mod := range modifications { +- modMap[mod.URI] = mod +- } - --// This file tests that dot-imports and underscore imports --// are properly ignored and that a new import is added to --// reference method types +- snapshots, release, err := s.session.DidModifyFiles(ctx, modifications) +- if err != nil { +- return err +- } - --var ( -- _ Reader -- _ zlib.Resetter = (*ignoredResetter)(nil) //@suggestedfix("(", "refactor.rewrite", "") --) +- // golang/go#50267: diagnostics should be re-sent after an open or close. For +- // some clients, it may be helpful to re-send after each change. +- for snapshot, uris := range snapshots { +- for _, uri := range uris { +- mod := modMap[uri] +- if snapshot.Options().ChattyDiagnostics || mod.Action == source.Open || mod.Action == source.Close { +- s.mustPublishDiagnostics(uri) +- } +- } +- } - --type ignoredResetter struct{} +- wg.Add(1) +- go func() { +- s.diagnoseSnapshots(snapshots, onDisk) +- release() +- wg.Done() +- }() - --// Reset implements zlib.Resetter --func (*ignoredResetter) Reset(r Reader, dict []byte) error { -- panic("unimplemented") +- // After any file modifications, we need to update our watched files, +- // in case something changed. Compute the new set of directories to watch, +- // and if it differs from the current set, send updated registrations. +- return s.updateWatchedDirectories(ctx) -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go b/gopls/internal/lsp/testdata/stub/stub_issue2606.go ---- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package stub -- --type I interface{ error } +-// DiagnosticWorkTitle returns the title of the diagnostic work resulting from a +-// file change originating from the given cause. +-func DiagnosticWorkTitle(cause ModificationSource) string { +- return fmt.Sprintf("diagnosing %v", cause) +-} - --type C int +-func (s *Server) changedText(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { +- if len(changes) == 0 { +- return nil, fmt.Errorf("%w: no content changes provided", jsonrpc2.ErrInternal) +- } - --var _ I = C(0) //@suggestedfix("C", "refactor.rewrite", "") -diff -urN a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_issue2606.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ ---- suggestedfix_stub_issue2606_7_11 -- --package stub +- // Check if the client sent the full content of the file. +- // We accept a full content change even if the server expected incremental changes. +- if len(changes) == 1 && changes[0].Range == nil && changes[0].RangeLength == 0 { +- return []byte(changes[0].Text), nil +- } +- return s.applyIncrementalChanges(ctx, uri, changes) +-} - --type I interface{ error } +-func (s *Server) applyIncrementalChanges(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { +- fh, err := s.session.ReadFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- content, err := fh.Content() +- if err != nil { +- return nil, fmt.Errorf("%w: file not found (%v)", jsonrpc2.ErrInternal, err) +- } +- for _, change := range changes { +- // TODO(adonovan): refactor to use diff.Apply, which is robust w.r.t. +- // out-of-order or overlapping changes---and much more efficient. - --type C int +- // Make sure to update mapper along with the content. +- m := protocol.NewMapper(uri, content) +- if change.Range == nil { +- return nil, fmt.Errorf("%w: unexpected nil range for change", jsonrpc2.ErrInternal) +- } +- spn, err := m.RangeSpan(*change.Range) +- if err != nil { +- return nil, err +- } +- start, end := spn.Start().Offset(), spn.End().Offset() +- if end < start { +- return nil, fmt.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) +- } +- var buf bytes.Buffer +- buf.Write(content[:start]) +- buf.WriteString(change.Text) +- buf.Write(content[end:]) +- content = buf.Bytes() +- } +- return content, nil +-} - --// Error implements I --func (C) Error() string { -- panic("unimplemented") +-func changeTypeToFileAction(ct protocol.FileChangeType) source.FileAction { +- switch ct { +- case protocol.Changed: +- return source.Change +- case protocol.Created: +- return source.Create +- case protocol.Deleted: +- return source.Delete +- } +- return source.UnknownFileAction -} +diff -urN a/gopls/internal/lsp/work/completion.go b/gopls/internal/lsp/work/completion.go +--- a/gopls/internal/lsp/work/completion.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/completion.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,154 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --var _ I = C(0) //@suggestedfix("C", "refactor.rewrite", "") +-package work - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go b/gopls/internal/lsp/testdata/stub/stub_multi_var.go ---- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package stub +-import ( +- "context" +- "errors" +- "fmt" +- "os" +- "path/filepath" +- "sort" +- "strings" - --import "io" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +-) - --// This test ensures that a variable declaration that --// has multiple values on the same line can still be --// analyzed correctly to target the interface implementation --// diagnostic. --var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "refactor.rewrite", "") +-func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.CompletionList, error) { +- ctx, done := event.Start(ctx, "work.Completion") +- defer done() - --type multiVar struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_multi_var.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_multi_var_9_38 -- --package stub +- // Get the position of the cursor. +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- return nil, fmt.Errorf("getting go.work file handle: %w", err) +- } +- cursor, err := pw.Mapper.PositionOffset(position) +- if err != nil { +- return nil, fmt.Errorf("computing cursor offset: %w", err) +- } - --import "io" +- // Find the use statement the user is in. +- use, pathStart, _ := usePath(pw, cursor) +- if use == nil { +- return &protocol.CompletionList{}, nil +- } +- completingFrom := use.Path[:cursor-pathStart] - --// This test ensures that a variable declaration that --// has multiple values on the same line can still be --// analyzed correctly to target the interface implementation --// diagnostic. --var one, two, three io.Reader = nil, &multiVar{}, nil //@suggestedfix("&", "refactor.rewrite", "") +- // We're going to find the completions of the user input +- // (completingFrom) by doing a walk on the innermost directory +- // of the given path, and comparing the found paths to make sure +- // that they match the component of the path after the +- // innermost directory. +- // +- // We'll maintain two paths when doing this: pathPrefixSlash +- // is essentially the path the user typed in, and pathPrefixAbs +- // is the path made absolute from the go.work directory. +- +- pathPrefixSlash := completingFrom +- pathPrefixAbs := filepath.FromSlash(pathPrefixSlash) +- if !filepath.IsAbs(pathPrefixAbs) { +- pathPrefixAbs = filepath.Join(filepath.Dir(pw.URI.Filename()), pathPrefixAbs) +- } +- +- // pathPrefixDir is the directory that will be walked to find matches. +- // If pathPrefixSlash is not explicitly a directory boundary (is either equivalent to "." or +- // ends in a separator) we need to examine its parent directory to find sibling files that +- // match. +- depthBound := 5 +- pathPrefixDir, pathPrefixBase := pathPrefixAbs, "" +- pathPrefixSlashDir := pathPrefixSlash +- if filepath.Clean(pathPrefixSlash) != "." && !strings.HasSuffix(pathPrefixSlash, "/") { +- depthBound++ +- pathPrefixDir, pathPrefixBase = filepath.Split(pathPrefixAbs) +- pathPrefixSlashDir = dirNonClean(pathPrefixSlash) +- } - --type multiVar struct{} +- var completions []string +- // Stop traversing deeper once we've hit 10k files to try to stay generally under 100ms. +- const numSeenBound = 10000 +- var numSeen int +- stopWalking := errors.New("hit numSeenBound") +- err = filepath.Walk(pathPrefixDir, func(wpath string, info os.FileInfo, err error) error { +- if numSeen > numSeenBound { +- // Stop traversing if we hit bound. +- return stopWalking +- } +- numSeen++ - --// Read implements io.Reader --func (*multiVar) Read(p []byte) (n int, err error) { -- panic("unimplemented") --} +- // rel is the path relative to pathPrefixDir. +- // Make sure that it has pathPrefixBase as a prefix +- // otherwise it won't match the beginning of the +- // base component of the path the user typed in. +- rel := strings.TrimPrefix(wpath[len(pathPrefixDir):], string(filepath.Separator)) +- if info.IsDir() && wpath != pathPrefixDir && !strings.HasPrefix(rel, pathPrefixBase) { +- return filepath.SkipDir +- } - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go b/gopls/internal/lsp/testdata/stub/stub_pointer.go ---- a/gopls/internal/lsp/testdata/stub/stub_pointer.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package stub +- // Check for a match (a module directory). +- if filepath.Base(rel) == "go.mod" { +- relDir := strings.TrimSuffix(dirNonClean(rel), string(os.PathSeparator)) +- completionPath := join(pathPrefixSlashDir, filepath.ToSlash(relDir)) - --import "io" +- if !strings.HasPrefix(completionPath, completingFrom) { +- return nil +- } +- if strings.HasSuffix(completionPath, "/") { +- // Don't suggest paths that end in "/". This happens +- // when the input is a path that ends in "/" and +- // the completion is empty. +- return nil +- } +- completion := completionPath[len(completingFrom):] +- if completingFrom == "" && !strings.HasPrefix(completion, "./") { +- // Bias towards "./" prefixes. +- completion = join(".", completion) +- } - --func getReaderFrom() io.ReaderFrom { -- return &pointerImpl{} //@suggestedfix("&", "refactor.rewrite", "") --} +- completions = append(completions, completion) +- } - --type pointerImpl struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_pointer.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ ---- suggestedfix_stub_pointer_6_9 -- --package stub +- if depth := strings.Count(rel, string(filepath.Separator)); depth >= depthBound { +- return filepath.SkipDir +- } +- return nil +- }) +- if err != nil && !errors.Is(err, stopWalking) { +- return nil, fmt.Errorf("walking to find completions: %w", err) +- } - --import "io" +- sort.Strings(completions) - --func getReaderFrom() io.ReaderFrom { -- return &pointerImpl{} //@suggestedfix("&", "refactor.rewrite", "") +- items := []protocol.CompletionItem{} // must be a slice +- for _, c := range completions { +- items = append(items, protocol.CompletionItem{ +- Label: c, +- InsertText: c, +- }) +- } +- return &protocol.CompletionList{Items: items}, nil -} - --type pointerImpl struct{} +-// dirNonClean is filepath.Dir, without the Clean at the end. +-func dirNonClean(path string) string { +- vol := filepath.VolumeName(path) +- i := len(path) - 1 +- for i >= len(vol) && !os.IsPathSeparator(path[i]) { +- i-- +- } +- return path[len(vol) : i+1] +-} - --// ReadFrom implements io.ReaderFrom --func (*pointerImpl) ReadFrom(r io.Reader) (n int64, err error) { -- panic("unimplemented") +-func join(a, b string) string { +- if a == "" { +- return b +- } +- if b == "" { +- return a +- } +- return strings.TrimSuffix(a, "/") + "/" + b -} +diff -urN a/gopls/internal/lsp/work/diagnostics.go b/gopls/internal/lsp/work/diagnostics.go +--- a/gopls/internal/lsp/work/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,92 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package stub +-package work - -import ( -- "compress/zlib" -- myio "io" --) -- --var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "refactor.rewrite", "") --var _ myio.Reader -- --type myIO struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ ---- suggestedfix_stub_renamed_import_8_23 -- --package stub +- "context" +- "fmt" +- "os" +- "path/filepath" - --import ( -- "compress/zlib" -- myio "io" +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" -) - --var _ zlib.Resetter = &myIO{} //@suggestedfix("&", "refactor.rewrite", "") --var _ myio.Reader +-func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[span.URI][]*source.Diagnostic, error) { +- ctx, done := event.Start(ctx, "work.Diagnostics", source.SnapshotLabels(snapshot)...) +- defer done() - --type myIO struct{} +- reports := map[span.URI][]*source.Diagnostic{} +- uri := snapshot.WorkFile() +- if uri == "" { +- return nil, nil +- } +- fh, err := snapshot.ReadFile(ctx, uri) +- if err != nil { +- return nil, err +- } +- reports[fh.URI()] = []*source.Diagnostic{} +- diagnostics, err := DiagnosticsForWork(ctx, snapshot, fh) +- if err != nil { +- return nil, err +- } +- for _, d := range diagnostics { +- fh, err := snapshot.ReadFile(ctx, d.URI) +- if err != nil { +- return nil, err +- } +- reports[fh.URI()] = append(reports[fh.URI()], d) +- } - --// Reset implements zlib.Resetter --func (*myIO) Reset(r myio.Reader, dict []byte) error { -- panic("unimplemented") +- return reports, nil -} - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package stub -- --import ( -- "golang.org/lsptests/stub/other" --) -- --// This file tests that if an interface --// method references an import from its own package --// that the concrete type does not yet import, and that import happens --// to be renamed, then we prefer the renaming of the interface. --var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "refactor.rewrite", "") +-func DiagnosticsForWork(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]*source.Diagnostic, error) { +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- if pw == nil || len(pw.ParseErrors) == 0 { +- return nil, err +- } +- return pw.ParseErrors, nil +- } - --type otherInterfaceImpl struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_renamed_import_iface.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ ---- suggestedfix_stub_renamed_import_iface_11_25 -- --package stub +- // Add diagnostic if a directory does not contain a module. +- var diagnostics []*source.Diagnostic +- for _, use := range pw.File.Use { +- rng, err := pw.Mapper.OffsetRange(use.Syntax.Start.Byte, use.Syntax.End.Byte) +- if err != nil { +- return nil, err +- } - --import ( -- "bytes" -- "context" -- "golang.org/lsptests/stub/other" --) +- modfh, err := snapshot.ReadFile(ctx, modFileURI(pw, use)) +- if err != nil { +- return nil, err +- } +- if _, err := modfh.Content(); err != nil && os.IsNotExist(err) { +- diagnostics = append(diagnostics, &source.Diagnostic{ +- URI: fh.URI(), +- Range: rng, +- Severity: protocol.SeverityError, +- Source: source.WorkFileError, +- Message: fmt.Sprintf("directory %v does not contain a module", use.Path), +- }) +- } +- } +- return diagnostics, nil +-} - --// This file tests that if an interface --// method references an import from its own package --// that the concrete type does not yet import, and that import happens --// to be renamed, then we prefer the renaming of the interface. --var _ other.Interface = &otherInterfaceImpl{} //@suggestedfix("&otherInterfaceImpl", "refactor.rewrite", "") +-func modFileURI(pw *source.ParsedWorkFile, use *modfile.Use) span.URI { +- workdir := filepath.Dir(pw.URI.Filename()) - --type otherInterfaceImpl struct{} +- modroot := filepath.FromSlash(use.Path) +- if !filepath.IsAbs(modroot) { +- modroot = filepath.Join(workdir, modroot) +- } - --// Get implements other.Interface --func (*otherInterfaceImpl) Get(context.Context) *bytes.Buffer { -- panic("unimplemented") +- return span.URIFromPath(filepath.Join(modroot, "go.mod")) -} +diff -urN a/gopls/internal/lsp/work/format.go b/gopls/internal/lsp/work/format.go +--- a/gopls/internal/lsp/work/format.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/format.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,28 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go b/gopls/internal/lsp/testdata/stub/stub_stdlib.go ---- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package stub +-package work - -import ( -- "io" --) -- --var _ io.Writer = writer{} //@suggestedfix("w", "refactor.rewrite", "") -- --type writer struct{} -diff -urN a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_stdlib.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ ---- suggestedfix_stub_stdlib_7_19 -- --package stub +- "context" - --import ( -- "io" +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" -) - --var _ io.Writer = writer{} //@suggestedfix("w", "refactor.rewrite", "") -- --type writer struct{} +-func Format(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.TextEdit, error) { +- ctx, done := event.Start(ctx, "work.Format") +- defer done() - --// Write implements io.Writer --func (writer) Write(p []byte) (n int, err error) { -- panic("unimplemented") +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- return nil, err +- } +- formatted := modfile.Format(pw.File.Syntax) +- // Calculate the edits to be made due to the change. +- diffs := snapshot.Options().ComputeEdits(string(pw.Mapper.Content), string(formatted)) +- return source.ToProtocolEdits(pw.Mapper, diffs) -} +diff -urN a/gopls/internal/lsp/work/hover.go b/gopls/internal/lsp/work/hover.go +--- a/gopls/internal/lsp/work/hover.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/work/hover.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,92 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go ---- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --package stub -- --// Regression test for Issue #56825: file corrupted by insertion of --// methods after TypeSpec in a parenthesized TypeDecl. -- --import "io" +-package work - --func newReadCloser() io.ReadCloser { -- return rdcloser{} //@suggestedfix("rd", "refactor.rewrite", "") --} +-import ( +- "bytes" +- "context" +- "fmt" - --type ( -- A int -- rdcloser struct{} -- B int +- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" -) - --func _() { -- // Local types can't be stubbed as there's nowhere to put the methods. -- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. -- type local struct{} -- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` --} -- --type ( -- C int --) -diff -urN a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden ---- a/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/stub/stub_typedecl_group.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,39 +0,0 @@ ---- suggestedfix_stub_typedecl_group_9_9 -- --package stub +-func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) { +- // We only provide hover information for the view's go.work file. +- if fh.URI() != snapshot.WorkFile() { +- return nil, nil +- } - --// Regression test for Issue #56825: file corrupted by insertion of --// methods after TypeSpec in a parenthesized TypeDecl. +- ctx, done := event.Start(ctx, "work.Hover") +- defer done() - --import "io" +- // Get the position of the cursor. +- pw, err := snapshot.ParseWork(ctx, fh) +- if err != nil { +- return nil, fmt.Errorf("getting go.work file handle: %w", err) +- } +- offset, err := pw.Mapper.PositionOffset(position) +- if err != nil { +- return nil, fmt.Errorf("computing cursor offset: %w", err) +- } - --func newReadCloser() io.ReadCloser { -- return rdcloser{} //@suggestedfix("rd", "refactor.rewrite", "") --} +- // Confirm that the cursor is inside a use statement, and then find +- // the position of the use statement's directory path. +- use, pathStart, pathEnd := usePath(pw, offset) - --type ( -- A int -- rdcloser struct{} -- B int --) +- // The cursor position is not on a use statement. +- if use == nil { +- return nil, nil +- } - --// Close implements io.ReadCloser --func (rdcloser) Close() error { -- panic("unimplemented") --} +- // Get the mod file denoted by the use. +- modfh, err := snapshot.ReadFile(ctx, modFileURI(pw, use)) +- if err != nil { +- return nil, fmt.Errorf("getting modfile handle: %w", err) +- } +- pm, err := snapshot.ParseMod(ctx, modfh) +- if err != nil { +- return nil, fmt.Errorf("getting modfile handle: %w", err) +- } +- if pm.File.Module == nil { +- return nil, fmt.Errorf("modfile has no module declaration") +- } +- mod := pm.File.Module.Mod - --// Read implements io.ReadCloser --func (rdcloser) Read(p []byte) (n int, err error) { -- panic("unimplemented") +- // Get the range to highlight for the hover. +- rng, err := pw.Mapper.OffsetRange(pathStart, pathEnd) +- if err != nil { +- return nil, err +- } +- options := snapshot.Options() +- return &protocol.Hover{ +- Contents: protocol.MarkupContent{ +- Kind: options.PreferredContentFormat, +- Value: mod.Path, +- }, +- Range: rng, +- }, nil -} - --func _() { -- // Local types can't be stubbed as there's nowhere to put the methods. -- // The suggestedfix assertion can't express this yet. TODO(adonovan): support it. -- type local struct{} -- var _ io.ReadCloser = local{} // want error: `local type "local" cannot be stubbed` +-func usePath(pw *source.ParsedWorkFile, offset int) (use *modfile.Use, pathStart, pathEnd int) { +- for _, u := range pw.File.Use { +- path := []byte(u.Path) +- s, e := u.Syntax.Start.Byte, u.Syntax.End.Byte +- i := bytes.Index(pw.Mapper.Content[s:e], path) +- if i == -1 { +- // This should not happen. +- continue +- } +- // Shift the start position to the location of the +- // module directory within the use statement. +- pathStart, pathEnd = s+i, s+i+len(path) +- if pathStart <= offset && offset <= pathEnd { +- return u, pathStart, pathEnd +- } +- } +- return nil, 0, 0 -} +diff -urN a/gopls/internal/lsp/workspace.go b/gopls/internal/lsp/workspace.go +--- a/gopls/internal/lsp/workspace.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/workspace.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,102 +0,0 @@ +-// Copyright 2019 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --type ( -- C int --) -- -diff -urN a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go ---- a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,11 +0,0 @@ --package suggestedfix +-package lsp - -import ( -- "log" --) -- --func goodbye() { -- s := "hiiiiiii" -- s = s //@suggestedfix("s = s", "quickfix", "") -- log.Print(s) --} -diff -urN a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden ---- a/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ ---- suggestedfix_has_suggested_fix_9_2 -- --package suggestedfix +- "context" +- "fmt" - --import ( -- "log" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/gopls/internal/span" +- "golang.org/x/tools/internal/event" -) - --func goodbye() { -- s := "hiiiiiii" -- //@suggestedfix("s = s", "quickfix", "") -- log.Print(s) --} -- -diff -urN a/gopls/internal/lsp/testdata/summary_go1.18.txt.golden b/gopls/internal/lsp/testdata/summary_go1.18.txt.golden ---- a/gopls/internal/lsp/testdata/summary_go1.18.txt.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/summary_go1.18.txt.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,32 +0,0 @@ ---- summary -- --CallHierarchyCount = 2 --CodeLensCount = 5 --CompletionsCount = 264 --CompletionSnippetCount = 115 --UnimportedCompletionsCount = 5 --DeepCompletionsCount = 5 --FuzzyCompletionsCount = 8 --RankedCompletionsCount = 174 --CaseSensitiveCompletionsCount = 4 --DiagnosticsCount = 42 --FoldingRangesCount = 2 --FormatCount = 6 --ImportCount = 8 --SemanticTokenCount = 3 --SuggestedFixCount = 71 --FunctionExtractionCount = 27 --MethodExtractionCount = 6 --DefinitionsCount = 47 --TypeDefinitionsCount = 18 --HighlightsCount = 69 --InlayHintsCount = 5 --ReferencesCount = 30 --RenamesCount = 48 --PrepareRenamesCount = 7 --SymbolsCount = 2 --WorkspaceSymbolsCount = 20 --SignaturesCount = 33 --LinksCount = 7 --ImplementationsCount = 26 --SelectionRangesCount = 3 -- -diff -urN a/gopls/internal/lsp/testdata/summary.txt.golden b/gopls/internal/lsp/testdata/summary.txt.golden ---- a/gopls/internal/lsp/testdata/summary.txt.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/summary.txt.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,32 +0,0 @@ ---- summary -- --CallHierarchyCount = 2 --CodeLensCount = 5 --CompletionsCount = 263 --CompletionSnippetCount = 106 --UnimportedCompletionsCount = 5 --DeepCompletionsCount = 5 --FuzzyCompletionsCount = 8 --RankedCompletionsCount = 164 --CaseSensitiveCompletionsCount = 4 --DiagnosticsCount = 42 --FoldingRangesCount = 2 --FormatCount = 6 --ImportCount = 8 --SemanticTokenCount = 3 --SuggestedFixCount = 65 --FunctionExtractionCount = 27 --MethodExtractionCount = 6 --DefinitionsCount = 47 --TypeDefinitionsCount = 18 --HighlightsCount = 69 --InlayHintsCount = 4 --ReferencesCount = 30 --RenamesCount = 41 --PrepareRenamesCount = 7 --SymbolsCount = 1 --WorkspaceSymbolsCount = 20 --SignaturesCount = 33 --LinksCount = 7 --ImplementationsCount = 16 --SelectionRangesCount = 3 +-func (s *Server) didChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error { +- event := params.Event +- for _, folder := range event.Removed { +- view := s.session.ViewByName(folder.Name) +- if view != nil { +- s.session.RemoveView(view) +- } else { +- return fmt.Errorf("view %s for %v not found", folder.Name, folder.URI) +- } +- } +- return s.addFolders(ctx, event.Added) +-} - -diff -urN a/gopls/internal/lsp/testdata/symbols/go1.18.go b/gopls/internal/lsp/testdata/symbols/go1.18.go ---- a/gopls/internal/lsp/testdata/symbols/go1.18.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/symbols/go1.18.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ --//go:build go1.18 --// +build go1.18 +-// addView returns a Snapshot and a release function that must be +-// called when it is no longer needed. +-func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.Snapshot, func(), error) { +- s.stateMu.Lock() +- state := s.state +- s.stateMu.Unlock() +- if state < serverInitialized { +- return nil, nil, fmt.Errorf("addView called before server initialized") +- } +- options := s.session.Options().Clone() +- if err := s.fetchConfig(ctx, name, uri, options); err != nil { +- return nil, nil, err +- } +- _, snapshot, release, err := s.session.NewView(ctx, name, uri, options) +- return snapshot, release, err +-} - --package main +-func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error { +- ctx, done := event.Start(ctx, "lsp.Server.didChangeConfiguration") +- defer done() - --type T[P any] struct { //@symbol("T", "T", "Struct", "struct{...}", "T", "") -- F P //@symbol("F", "F", "Field", "P", "", "T") --} +- // Apply any changes to the session-level settings. +- options := s.session.Options().Clone() +- if err := s.fetchConfig(ctx, "", "", options); err != nil { +- return err +- } +- s.session.SetOptions(options) +- +- // Go through each view, getting and updating its configuration. +- for _, view := range s.session.Views() { +- options := s.session.Options().Clone() +- if err := s.fetchConfig(ctx, view.Name(), view.Folder(), options); err != nil { +- return err +- } +- _, err := s.session.SetViewOptions(ctx, view, options) +- if err != nil { +- return err +- } +- } +- +- // Now that all views have been updated: reset vulncheck diagnostics, rerun +- // diagnostics, and hope for the best... +- // +- // TODO(golang/go#60465): this not a reliable way to ensure the correctness +- // of the resulting diagnostics below. A snapshot could still be in the +- // process of diagnosing the workspace, and not observe the configuration +- // changes above. +- // +- // The real fix is golang/go#42814: we should create a new snapshot on any +- // change that could affect the derived results in that snapshot. However, we +- // are currently (2023-05-26) on the verge of a release, and the proper fix +- // is too risky a change. Since in the common case a configuration change is +- // only likely to occur during a period of quiescence on the server, it is +- // likely that the clearing below will have the desired effect. +- s.clearDiagnosticSource(modVulncheckSource) +- +- for _, view := range s.session.Views() { +- view := view +- go func() { +- snapshot, release, err := view.Snapshot() +- if err != nil { +- return // view is shut down; no need to diagnose +- } +- defer release() +- s.diagnoseSnapshot(snapshot, nil, false, 0) +- }() +- } - --type Constraint interface { //@symbol("Constraint", "Constraint", "Interface", "interface{...}", "Constraint", "") -- ~int | struct{ int } //@symbol("~int | struct{int}", "~int | struct{ int }", "Field", "", "", "Constraint") +- // An options change may have affected the detected Go version. +- s.checkViewGoVersions() - -- // TODO(rfindley): the selection range below is the entire interface field. -- // Can we reduce it? -- interface{ M() } //@symbol("interface{...}", "interface{ M() }", "Field", "", "iFaceField", "Constraint"), symbol("M", "M", "Method", "func()", "", "iFaceField") +- return nil -} -diff -urN a/gopls/internal/lsp/testdata/symbols/go1.18.go.golden b/gopls/internal/lsp/testdata/symbols/go1.18.go.golden ---- a/gopls/internal/lsp/testdata/symbols/go1.18.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/symbols/go1.18.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ ---- symbols -- --T Struct 6:6-6:7 -- F Field 7:2-7:3 --Constraint Interface 10:6-10:16 -- interface{...} Field 15:2-15:18 -- ~int | struct{int} Field 11:2-11:22 -- -diff -urN a/gopls/internal/lsp/testdata/symbols/main.go b/gopls/internal/lsp/testdata/symbols/main.go ---- a/gopls/internal/lsp/testdata/symbols/main.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/symbols/main.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,91 +0,0 @@ --package main +diff -urN a/gopls/internal/lsp/workspace_symbol.go b/gopls/internal/lsp/workspace_symbol.go +--- a/gopls/internal/lsp/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/lsp/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,32 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --import ( -- "io" --) +-package lsp - --// Each symbol marker in this file defines the following information: --// symbol(name, selectionSpan, kind, detail, id, parentID) --// - name: DocumentSymbol.Name --// - selectionSpan: DocumentSymbol.SelectionRange --// - kind: DocumentSymbol.Kind --// - detail: DocumentSymbol.Detail --// - id: if non-empty, a unique identifier for this symbol --// - parentID: if non-empty, the id of the parent of this symbol --// --// This data in aggregate defines a set of document symbols and their --// parent-child relationships, which is compared against the DocummentSymbols --// response from gopls for the current file. --// --// TODO(rfindley): the symbol annotations here are complicated and difficult to --// maintain. It would be simpler to just write out the full expected response --// in the golden file, perhaps as raw JSON. +-import ( +- "context" - --var _ = 1 +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/event" +-) - --var x = 42 //@symbol("x", "x", "Variable", "", "", "") +-func (s *Server) symbol(ctx context.Context, params *protocol.WorkspaceSymbolParams) ([]protocol.SymbolInformation, error) { +- ctx, done := event.Start(ctx, "lsp.Server.symbol") +- defer done() - --var nested struct { //@symbol("nested", "nested", "Variable", "struct{...}", "nested", "") -- nestedField struct { //@symbol("nestedField", "nestedField", "Field", "struct{...}", "nestedField", "nested") -- f int //@symbol("f", "f", "Field", "int", "", "nestedField") +- views := s.session.Views() +- matcher := s.session.Options().SymbolMatcher +- style := s.session.Options().SymbolStyle +- // TODO(rfindley): it looks wrong that we need to pass views here. +- // +- // Evidence: +- // - this is the only place we convert views to []source.View +- // - workspace symbols is the only place where we call source.View.Snapshot +- var sourceViews []source.View +- for _, v := range views { +- sourceViews = append(sourceViews, v) - } +- return source.WorkspaceSymbols(ctx, matcher, style, sourceViews, params.Query) -} +diff -urN a/gopls/internal/regtest/bench/bench_test.go b/gopls/internal/regtest/bench/bench_test.go +--- a/gopls/internal/regtest/bench/bench_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/bench_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,352 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package bench +- +-import ( +- "bytes" +- "compress/gzip" +- "context" +- "flag" +- "fmt" +- "io" +- "io/ioutil" +- "log" +- "os" +- "os/exec" +- "path/filepath" +- "strings" +- "sync" +- "testing" +- "time" - --const y = 43 //@symbol("y", "y", "Constant", "", "", "") +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/cmd" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/event" +- "golang.org/x/tools/internal/fakenet" +- "golang.org/x/tools/internal/jsonrpc2" +- "golang.org/x/tools/internal/jsonrpc2/servertest" +- "golang.org/x/tools/internal/pprof" +- "golang.org/x/tools/internal/tool" +-) - --type Number int //@symbol("Number", "Number", "Class", "int", "", "") +-var ( +- goplsPath = flag.String("gopls_path", "", "if set, use this gopls for testing; incompatible with -gopls_commit") - --type Alias = string //@symbol("Alias", "Alias", "Class", "string", "", "") +- installGoplsOnce sync.Once // guards installing gopls at -gopls_commit +- goplsCommit = flag.String("gopls_commit", "", "if set, install and use gopls at this commit for testing; incompatible with -gopls_path") - --type NumberAlias = Number //@symbol("NumberAlias", "NumberAlias", "Class", "Number", "", "") +- cpuProfile = flag.String("gopls_cpuprofile", "", "if set, the cpu profile file suffix; see \"Profiling\" in the package doc") +- memProfile = flag.String("gopls_memprofile", "", "if set, the mem profile file suffix; see \"Profiling\" in the package doc") +- allocProfile = flag.String("gopls_allocprofile", "", "if set, the alloc profile file suffix; see \"Profiling\" in the package doc") +- trace = flag.String("gopls_trace", "", "if set, the trace file suffix; see \"Profiling\" in the package doc") - --type ( -- Boolean bool //@symbol("Boolean", "Boolean", "Class", "bool", "", "") -- BoolAlias = bool //@symbol("BoolAlias", "BoolAlias", "Class", "bool", "", "") +- // If non-empty, tempDir is a temporary working dir that was created by this +- // test suite. +- makeTempDirOnce sync.Once // guards creation of the temp dir +- tempDir string -) - --type Foo struct { //@symbol("Foo", "Foo", "Struct", "struct{...}", "Foo", "") -- Quux //@symbol("Quux", "Quux", "Field", "Quux", "", "Foo") -- W io.Writer //@symbol("W", "W", "Field", "io.Writer", "", "Foo") -- Bar int //@symbol("Bar", "Bar", "Field", "int", "", "Foo") -- baz string //@symbol("baz", "baz", "Field", "string", "", "Foo") -- funcField func(int) int //@symbol("funcField", "funcField", "Field", "func(int) int", "", "Foo") +-// if runAsGopls is "true", run the gopls command instead of the testing.M. +-const runAsGopls = "_GOPLS_BENCH_RUN_AS_GOPLS" +- +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- if os.Getenv(runAsGopls) == "true" { +- tool.Main(context.Background(), cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) +- os.Exit(0) +- } +- event.SetExporter(nil) // don't log to stderr +- code := m.Run() +- if err := cleanup(); err != nil { +- fmt.Fprintf(os.Stderr, "cleaning up after benchmarks: %v\n", err) +- if code == 0 { +- code = 1 +- } +- } +- os.Exit(code) -} - --type Quux struct { //@symbol("Quux", "Quux", "Struct", "struct{...}", "Quux", "") -- X, Y float64 //@symbol("X", "X", "Field", "float64", "", "Quux"), symbol("Y", "Y", "Field", "float64", "", "Quux") +-// getTempDir returns the temporary directory to use for benchmark files, +-// creating it if necessary. +-func getTempDir() string { +- makeTempDirOnce.Do(func() { +- var err error +- tempDir, err = ioutil.TempDir("", "gopls-bench") +- if err != nil { +- log.Fatal(err) +- } +- }) +- return tempDir -} - --type EmptyStruct struct{} //@symbol("EmptyStruct", "EmptyStruct", "Struct", "struct{}", "", "") +-// shallowClone performs a shallow clone of repo into dir at the given +-// 'commitish' ref (any commit reference understood by git). +-// +-// The directory dir must not already exist. +-func shallowClone(dir, repo, commitish string) error { +- if err := os.Mkdir(dir, 0750); err != nil { +- return fmt.Errorf("creating dir for %s: %v", repo, err) +- } +- +- // Set a timeout for git fetch. If this proves flaky, it can be removed. +- ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) +- defer cancel() - --func (f Foo) Baz() string { //@symbol("(Foo).Baz", "Baz", "Method", "func() string", "", "") -- return f.baz +- // Use a shallow fetch to download just the relevant commit. +- shInit := fmt.Sprintf("git init && git fetch --depth=1 %q %q && git checkout FETCH_HEAD", repo, commitish) +- initCmd := exec.CommandContext(ctx, "/bin/sh", "-c", shInit) +- initCmd.Dir = dir +- if output, err := initCmd.CombinedOutput(); err != nil { +- return fmt.Errorf("checking out %s: %v\n%s", repo, err, output) +- } +- return nil -} - --func _() {} +-// connectEditor connects a fake editor session in the given dir, using the +-// given editor config. +-func connectEditor(dir string, config fake.EditorConfig, ts servertest.Connector) (*fake.Sandbox, *fake.Editor, *regtest.Awaiter, error) { +- s, err := fake.NewSandbox(&fake.SandboxConfig{ +- Workdir: dir, +- GOPROXY: "https://proxy.golang.org", +- }) +- if err != nil { +- return nil, nil, nil, err +- } - --func (q *Quux) Do() {} //@symbol("(*Quux).Do", "Do", "Method", "func()", "", "") +- a := regtest.NewAwaiter(s.Workdir) +- const skipApplyEdits = false +- editor, err := fake.NewEditor(s, config).Connect(context.Background(), ts, a.Hooks(), skipApplyEdits) +- if err != nil { +- return nil, nil, nil, err +- } - --func main() { //@symbol("main", "main", "Function", "func()", "", "") +- return s, editor, a, nil -} - --type Stringer interface { //@symbol("Stringer", "Stringer", "Interface", "interface{...}", "Stringer", "") -- String() string //@symbol("String", "String", "Method", "func() string", "", "Stringer") +-// newGoplsConnector returns a connector that connects to a new gopls process, +-// executed with the provided arguments. +-func newGoplsConnector(args []string) (servertest.Connector, error) { +- if *goplsPath != "" && *goplsCommit != "" { +- panic("can't set both -gopls_path and -gopls_commit") +- } +- var ( +- goplsPath = *goplsPath +- env []string +- ) +- if *goplsCommit != "" { +- goplsPath = getInstalledGopls() +- } +- if goplsPath == "" { +- var err error +- goplsPath, err = os.Executable() +- if err != nil { +- return nil, err +- } +- env = []string{fmt.Sprintf("%s=true", runAsGopls)} +- } +- return &SidecarServer{ +- goplsPath: goplsPath, +- env: env, +- args: args, +- }, nil -} - --type ABer interface { //@symbol("ABer", "ABer", "Interface", "interface{...}", "ABer", "") -- B() //@symbol("B", "B", "Method", "func()", "", "ABer") -- A() string //@symbol("A", "A", "Method", "func() string", "", "ABer") +-// profileArgs returns additional command-line arguments to use when invoking +-// gopls, to enable the user-requested profiles. +-// +-// If wantCPU is set, CPU profiling is enabled as well. Some tests may want to +-// instrument profiling around specific critical sections of the benchmark, +-// rather than the entire process. +-// +-// TODO(rfindley): like CPU, all of these would be better served by a custom +-// command. Very rarely do we care about memory usage as the process exits: we +-// care about specific points in time during the benchmark. mem and alloc +-// should be snapshotted, and tracing should be bracketed around critical +-// sections. +-func profileArgs(name string, wantCPU bool) []string { +- var args []string +- if wantCPU && *cpuProfile != "" { +- args = append(args, fmt.Sprintf("-profile.cpu=%s", qualifiedName(name, *cpuProfile))) +- } +- if *memProfile != "" { +- args = append(args, fmt.Sprintf("-profile.mem=%s", qualifiedName(name, *memProfile))) +- } +- if *allocProfile != "" { +- args = append(args, fmt.Sprintf("-profile.alloc=%s", qualifiedName(name, *allocProfile))) +- } +- if *trace != "" { +- args = append(args, fmt.Sprintf("-profile.trace=%s", qualifiedName(name, *trace))) +- } +- return args -} - --type WithEmbeddeds interface { //@symbol("WithEmbeddeds", "WithEmbeddeds", "Interface", "interface{...}", "WithEmbeddeds", "") -- Do() //@symbol("Do", "Do", "Method", "func()", "", "WithEmbeddeds") -- ABer //@symbol("ABer", "ABer", "Field", "ABer", "", "WithEmbeddeds") -- io.Writer //@symbol("Writer", "Writer", "Field", "io.Writer", "", "WithEmbeddeds") +-func qualifiedName(args ...string) string { +- return strings.Join(args, ".") -} - --type EmptyInterface interface{} //@symbol("EmptyInterface", "EmptyInterface", "Interface", "interface{}", "", "") -- --func Dunk() int { return 0 } //@symbol("Dunk", "Dunk", "Function", "func() int", "", "") +-// getInstalledGopls builds gopls at the given -gopls_commit, returning the +-// path to the gopls binary. +-func getInstalledGopls() string { +- if *goplsCommit == "" { +- panic("must provide -gopls_commit") +- } +- toolsDir := filepath.Join(getTempDir(), "gopls_build") +- goplsPath := filepath.Join(toolsDir, "gopls", "gopls") - --func dunk() {} //@symbol("dunk", "dunk", "Function", "func()", "", "") -diff -urN a/gopls/internal/lsp/testdata/symbols/main.go.golden b/gopls/internal/lsp/testdata/symbols/main.go.golden ---- a/gopls/internal/lsp/testdata/symbols/main.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/symbols/main.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,36 +0,0 @@ ---- symbols -- --x Variable 26:5-26:6 --nested Variable 28:5-28:11 -- nestedField Field 29:2-29:13 --y Constant 34:7-34:8 --Number Class 36:6-36:12 --Alias Class 38:6-38:11 --NumberAlias Class 40:6-40:17 --Boolean Class 43:2-43:9 --BoolAlias Class 44:2-44:11 --Foo Struct 47:6-47:9 -- Bar Field 50:2-50:5 -- Quux Field 48:2-48:6 -- W Field 49:2-49:3 -- baz Field 51:2-51:5 -- funcField Field 52:2-52:11 --Quux Struct 55:6-55:10 -- X Field 56:2-56:3 -- Y Field 56:5-56:6 --EmptyStruct Struct 59:6-59:17 --(Foo).Baz Method 61:14-61:17 --(*Quux).Do Method 67:16-67:18 --main Function 69:6-69:10 --Stringer Interface 72:6-72:14 -- String Method 73:2-73:8 --ABer Interface 76:6-76:10 -- A Method 78:2-78:3 -- B Method 77:2-77:3 --WithEmbeddeds Interface 81:6-81:19 -- ABer Field 83:2-83:6 -- Do Method 82:2-82:4 -- Writer Field 84:5-84:11 --EmptyInterface Interface 87:6-87:20 --Dunk Function 89:6-89:10 --dunk Function 91:6-91:10 +- installGoplsOnce.Do(func() { +- log.Printf("installing gopls: checking out x/tools@%s into %s\n", *goplsCommit, toolsDir) +- if err := shallowClone(toolsDir, "https://go.googlesource.com/tools", *goplsCommit); err != nil { +- log.Fatal(err) +- } - -diff -urN a/gopls/internal/lsp/testdata/testy/testy.go b/gopls/internal/lsp/testdata/testy/testy.go ---- a/gopls/internal/lsp/testdata/testy/testy.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/testy/testy.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package testy +- log.Println("installing gopls: building...") +- bld := exec.Command("go", "build", ".") +- bld.Dir = filepath.Join(toolsDir, "gopls") +- if output, err := bld.CombinedOutput(); err != nil { +- log.Fatalf("building gopls: %v\n%s", err, output) +- } - --func a() { //@mark(identA, "a"),item(funcA, "a", "func()", "func"),refs("a", identA, testyA) -- //@complete("", funcA) +- // Confirm that the resulting path now exists. +- if _, err := os.Stat(goplsPath); err != nil { +- log.Fatalf("os.Stat(%s): %v", goplsPath, err) +- } +- }) +- return goplsPath -} -diff -urN a/gopls/internal/lsp/testdata/testy/testy_test.go b/gopls/internal/lsp/testdata/testy/testy_test.go ---- a/gopls/internal/lsp/testdata/testy/testy_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/testy/testy_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ --package testy -- --import ( -- "testing" -- -- sig "golang.org/lsptests/signature" -- "golang.org/lsptests/snippets" --) - --func TestSomething(t *testing.T) { //@item(TestSomething, "TestSomething(t *testing.T)", "", "func") -- var x int //@mark(testyX, "x"),diag("x", "compiler", "x declared (and|but) not used", "error"),refs("x", testyX) -- a() //@mark(testyA, "a") +-// A SidecarServer starts (and connects to) a separate gopls process at the +-// given path. +-type SidecarServer struct { +- goplsPath string +- env []string // additional environment bindings +- args []string // command-line arguments -} - --func _() { -- _ = snippets.X(nil) //@signature("nil", "X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias", 0) -- var _ sig.Alias --} -diff -urN a/gopls/internal/lsp/testdata/testy/testy_test.go.golden b/gopls/internal/lsp/testdata/testy/testy_test.go.golden ---- a/gopls/internal/lsp/testdata/testy/testy_test.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/testy/testy_test.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ ---- X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias-signature -- --X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias +-// Connect creates new io.Pipes and binds them to the underlying StreamServer. +-// +-// It implements the servertest.Connector interface. +-func (s *SidecarServer) Connect(ctx context.Context) jsonrpc2.Conn { +- // Note: don't use CommandContext here, as we want gopls to exit gracefully +- // in order to write out profile data. +- // +- // We close the connection on context cancelation below. +- cmd := exec.Command(s.goplsPath, s.args...) - -diff -urN a/gopls/internal/lsp/testdata/typdef/typdef.go b/gopls/internal/lsp/testdata/typdef/typdef.go ---- a/gopls/internal/lsp/testdata/typdef/typdef.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typdef/typdef.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,65 +0,0 @@ --package typdef +- stdin, err := cmd.StdinPipe() +- if err != nil { +- log.Fatal(err) +- } +- stdout, err := cmd.StdoutPipe() +- if err != nil { +- log.Fatal(err) +- } +- cmd.Stderr = os.Stderr +- cmd.Env = append(os.Environ(), s.env...) +- if err := cmd.Start(); err != nil { +- log.Fatalf("starting gopls: %v", err) +- } - --type Struct struct { //@item(Struct, "Struct", "struct{...}", "struct") -- Field string --} +- go func() { +- // If we don't log.Fatal here, benchmarks may hang indefinitely if gopls +- // exits abnormally. +- // +- // TODO(rfindley): ideally we would shut down the connection gracefully, +- // but that doesn't currently work. +- if err := cmd.Wait(); err != nil { +- log.Fatalf("gopls invocation failed with error: %v", err) +- } +- }() - --type Int int //@item(Int, "Int", "int", "type") +- clientStream := jsonrpc2.NewHeaderStream(fakenet.NewConn("stdio", stdout, stdin)) +- clientConn := jsonrpc2.NewConn(clientStream) - --func _() { -- var ( -- value Struct -- point *Struct -- ) -- _ = value //@typdef("value", Struct) -- _ = point //@typdef("point", Struct) +- go func() { +- select { +- case <-ctx.Done(): +- clientConn.Close() +- clientStream.Close() +- case <-clientConn.Done(): +- } +- }() - -- var ( -- array [3]Struct -- slice []Struct -- ch chan Struct -- complex [3]chan *[5][]Int -- ) -- _ = array //@typdef("array", Struct) -- _ = slice //@typdef("slice", Struct) -- _ = ch //@typdef("ch", Struct) -- _ = complex //@typdef("complex", Int) +- return clientConn +-} - -- var s struct { -- x struct { -- xx struct { -- field1 []Struct -- field2 []Int +-// startProfileIfSupported checks to see if the remote gopls instance supports +-// the start/stop profiling commands. If so, it starts profiling and returns a +-// function that stops profiling and records the total CPU seconds sampled in the +-// cpu_seconds benchmark metric. +-// +-// If the remote gopls instance does not support profiling commands, this +-// function returns nil. +-// +-// If the supplied userSuffix is non-empty, the profile is written to +-// ., and not deleted when the benchmark exits. Otherwise, +-// the profile is written to a temp file that is deleted after the cpu_seconds +-// metric has been computed. +-func startProfileIfSupported(b *testing.B, env *regtest.Env, name string) func() { +- if !env.Editor.HasCommand(command.StartProfile.ID()) { +- return nil +- } +- b.StopTimer() +- stopProfile := env.StartProfile() +- b.StartTimer() +- return func() { +- b.StopTimer() +- profFile := stopProfile() +- totalCPU, err := totalCPUForProfile(profFile) +- if err != nil { +- b.Fatalf("reading profile: %v", err) +- } +- b.ReportMetric(totalCPU.Seconds()/float64(b.N), "cpu_seconds/op") +- if *cpuProfile == "" { +- // The user didn't request profiles, so delete it to clean up. +- if err := os.Remove(profFile); err != nil { +- b.Errorf("removing profile file: %v", err) +- } +- } else { +- // NOTE: if this proves unreliable (due to e.g. EXDEV), we can fall back +- // on Read+Write+Remove. +- name := qualifiedName(name, *cpuProfile) +- if err := os.Rename(profFile, name); err != nil { +- b.Fatalf("renaming profile file: %v", err) - } - } - } -- s.x.xx.field1 //@typdef("field1", Struct) -- s.x.xx.field2 //@typdef("field2", Int) -} - --func F1() Int { return 0 } --func F2() (Int, float64) { return 0, 0 } --func F3() (Struct, int, bool, error) { return Struct{}, 0, false, nil } --func F4() (**int, Int, bool, *error) { return nil, Struct{}, false, nil } --func F5() (int, float64, error, Struct) { return 0, 0, nil, Struct{} } --func F6() (int, float64, ***Struct, error) { return 0, 0, nil, nil } -- --func _() { -- F1() //@typdef("F1", Int) -- F2() //@typdef("F2", Int) -- F3() //@typdef("F3", Struct) -- F4() //@typdef("F4", Int) -- F5() //@typdef("F5", Struct) -- F6() //@typdef("F6", Struct) +-// totalCPUForProfile reads the pprof profile with the given file name, parses, +-// and aggregates the total CPU sampled during the profile. +-func totalCPUForProfile(filename string) (time.Duration, error) { +- protoGz, err := os.ReadFile(filename) +- if err != nil { +- return 0, err +- } +- rd, err := gzip.NewReader(bytes.NewReader(protoGz)) +- if err != nil { +- return 0, fmt.Errorf("creating gzip reader for %s: %v", filename, err) +- } +- data, err := io.ReadAll(rd) +- if err != nil { +- return 0, fmt.Errorf("reading %s: %v", filename, err) +- } +- return pprof.TotalTime(data) +-} - -- f := func() Int { return 0 } -- f() //@typdef("f", Int) +-// closeBuffer stops the benchmark timer and closes the buffer with the given +-// name. +-// +-// It may be used to clean up files opened in the shared environment during +-// benchmarking. +-func closeBuffer(b *testing.B, env *regtest.Env, name string) { +- b.StopTimer() +- env.CloseBuffer(name) +- env.AfterChange() +- b.StartTimer() -} +diff -urN a/gopls/internal/regtest/bench/codeaction_test.go b/gopls/internal/regtest/bench/codeaction_test.go +--- a/gopls/internal/regtest/bench/codeaction_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/codeaction_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --// https://github.com/golang/go/issues/38589#issuecomment-620350922 --func _() { -- type myFunc func(int) Int //@item(myFunc, "myFunc", "func", "type") +-package bench - -- var foo myFunc -- bar := foo() //@typdef("foo", myFunc) --} -diff -urN a/gopls/internal/lsp/testdata/typeassert/type_assert.go b/gopls/internal/lsp/testdata/typeassert/type_assert.go ---- a/gopls/internal/lsp/testdata/typeassert/type_assert.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeassert/type_assert.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,24 +0,0 @@ --package typeassert +-import ( +- "fmt" +- "sync/atomic" +- "testing" - --type abc interface { //@item(abcIntf, "abc", "interface{...}", "interface") -- abc() --} +- "golang.org/x/tools/gopls/internal/lsp/protocol" +-) - --type abcImpl struct{} //@item(abcImpl, "abcImpl", "struct{...}", "struct") --func (abcImpl) abc() +-func BenchmarkCodeAction(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) +- env.AfterChange() - --type abcPtrImpl struct{} //@item(abcPtrImpl, "abcPtrImpl", "struct{...}", "struct") --func (*abcPtrImpl) abc() +- env.CodeAction(test.file, nil) // pre-warm - --type abcNotImpl struct{} //@item(abcNotImpl, "abcNotImpl", "struct{...}", "struct") +- b.ResetTimer() - --func _() { -- var a abc -- switch a.(type) { -- case ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) -- case *ab: //@complete(":", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- env.CodeAction(test.file, nil) +- } +- }) - } +-} - -- a.(ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) -- a.(*ab) //@complete(")", abcImpl, abcPtrImpl, abcIntf, abcNotImpl) +-func BenchmarkCodeActionFollowingEdit(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- env.AfterChange() +- +- env.CodeAction(test.file, nil) // pre-warm +- +- b.ResetTimer() +- +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- env.CodeAction(test.file, nil) +- } +- }) +- } -} -diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go ---- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,5 +0,0 @@ --package typeerrors +diff -urN a/gopls/internal/regtest/bench/completion_test.go b/gopls/internal/regtest/bench/completion_test.go +--- a/gopls/internal/regtest/bench/completion_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/completion_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,249 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func x() { return nil } //@suggestedfix("nil", "quickfix", "") +-package bench - --func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") -diff -urN a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden ---- a/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeerrors/noresultvalues.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ ---- suggestedfix_noresultvalues_3_19 -- --package typeerrors +-import ( +- "fmt" +- "sync/atomic" +- "testing" - --func x() { return } //@suggestedfix("nil", "quickfix", "") +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --func y() { return nil, "hello" } //@suggestedfix("nil", "quickfix", "") +-// TODO(rfindley): update these completion tests to run on multiple repos. - ---- suggestedfix_noresultvalues_5_19 -- --package typeerrors +-type completionBenchOptions struct { +- file, locationRegexp string - --func x() { return nil } //@suggestedfix("nil", "quickfix", "") +- // Hooks to run edits before initial completion +- setup func(*Env) // run before the benchmark starts +- beforeCompletion func(*Env) // run before each completion +-} - --func y() { return } //@suggestedfix("nil", "quickfix", "") +-func benchmarkCompletion(options completionBenchOptions, b *testing.B) { +- repo := getRepo(b, "tools") +- _ = repo.sharedEnv(b) // ensure cache is warm +- env := repo.newEnv(b, fake.EditorConfig{}, "completion", false) +- defer env.Close() - -diff -urN a/gopls/internal/lsp/testdata/typemods/type_mods.go b/gopls/internal/lsp/testdata/typemods/type_mods.go ---- a/gopls/internal/lsp/testdata/typemods/type_mods.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typemods/type_mods.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ --package typemods +- // Run edits required for this completion. +- if options.setup != nil { +- options.setup(env) +- } - --func fooFunc() func() int { //@item(modFooFunc, "fooFunc", "func() func() int", "func") -- return func() int { -- return 0 +- // Run a completion to make sure the system is warm. +- loc := env.RegexpSearch(options.file, options.locationRegexp) +- completions := env.Completion(loc) +- +- if testing.Verbose() { +- fmt.Println("Results:") +- for i := 0; i < len(completions.Items); i++ { +- fmt.Printf("\t%d. %v\n", i, completions.Items[i]) +- } - } --} - --func fooPtr() *int { //@item(modFooPtr, "fooPtr", "func() *int", "func") -- return nil --} +- b.Run("tools", func(b *testing.B) { +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName("tools", "completion")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func _() { -- var _ int = foo //@snippet(" //", modFooFunc, "fooFunc()()", "fooFunc()()"),snippet(" //", modFooPtr, "*fooPtr()", "*fooPtr()") +- for i := 0; i < b.N; i++ { +- if options.beforeCompletion != nil { +- options.beforeCompletion(env) +- } +- env.Completion(loc) +- } +- }) -} - --func _() { -- var m map[int][]chan int //@item(modMapChanPtr, "m", "map[int]chan *int", "var") -- -- var _ int = m //@snippet(" //", modMapChanPtr, "<-m[${1:}][${2:}]", "<-m[${1:}][${2:}]") +-// endRangeInBuffer returns the position for last character in the buffer for +-// the given file. +-func endRangeInBuffer(env *Env, name string) protocol.Range { +- buffer := env.BufferText(name) +- m := protocol.NewMapper("", []byte(buffer)) +- rng, err := m.OffsetRange(len(buffer), len(buffer)) +- if err != nil { +- env.T.Fatal(err) +- } +- return rng -} -diff -urN a/gopls/internal/lsp/testdata/typeparams/type_params.go b/gopls/internal/lsp/testdata/typeparams/type_params.go ---- a/gopls/internal/lsp/testdata/typeparams/type_params.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/typeparams/type_params.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,61 +0,0 @@ --//go:build go1.18 --// +build go1.18 - --package typeparams +-// Benchmark struct completion in tools codebase. +-func BenchmarkStructCompletion(b *testing.B) { +- file := "internal/lsp/cache/session.go" - --func one[a int | string]() {} --func two[a int | string, b float64 | int]() {} +- setup := func(env *Env) { +- env.OpenFile(file) +- env.EditBuffer(file, protocol.TextEdit{ +- Range: endRangeInBuffer(env, file), +- NewText: "\nvar testVariable map[string]bool = Session{}.\n", +- }) +- } - --func _() { -- one[]() //@rank("]", string, float64) -- two[]() //@rank("]", int, float64) -- two[int, f]() //@rank("]", float64, float32) +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `var testVariable map\[string\]bool = Session{}(\.)`, +- setup: setup, +- }, b) -} - --func slices[a []int | []float64]() {} //@item(tpInts, "[]int", "[]int", "type"),item(tpFloats, "[]float64", "[]float64", "type") -- --func _() { -- slices[]() //@rank("]", tpInts),rank("]", tpFloats) +-// Benchmark import completion in tools codebase. +-func BenchmarkImportCompletion(b *testing.B) { +- const file = "internal/lsp/source/completion/completion.go" +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `go\/()`, +- setup: func(env *Env) { env.OpenFile(file) }, +- }, b) -} - --type s[a int | string] struct{} +-// Benchmark slice completion in tools codebase. +-func BenchmarkSliceCompletion(b *testing.B) { +- file := "internal/lsp/cache/session.go" - --func _() { -- s[]{} //@rank("]", int, float64) --} +- setup := func(env *Env) { +- env.OpenFile(file) +- env.EditBuffer(file, protocol.TextEdit{ +- Range: endRangeInBuffer(env, file), +- NewText: "\nvar testVariable []byte = \n", +- }) +- } - --func takesGeneric[a int | string](s[a]) { -- "s[a]{}" //@item(tpInScopeLit, "s[a]{}", "", "var") -- takesGeneric() //@rank(")", tpInScopeLit),snippet(")", tpInScopeLit, "s[a]{\\}", "s[a]{\\}") +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `var testVariable \[\]byte (=)`, +- setup: setup, +- }, b) -} - --func _() { -- s[int]{} //@item(tpInstLit, "s[int]{}", "", "var") -- takesGeneric[int]() //@rank(")", tpInstLit),snippet(")", tpInstLit, "s[int]{\\}", "s[int]{\\}") -- -- "s[...]{}" //@item(tpUninstLit, "s[...]{}", "", "var") -- takesGeneric() //@rank(")", tpUninstLit),snippet(")", tpUninstLit, "s[${1:}]{\\}", "s[${1:a}]{\\}") +-// Benchmark deep completion in function call in tools codebase. +-func BenchmarkFuncDeepCompletion(b *testing.B) { +- file := "internal/lsp/source/completion/completion.go" +- fileContent := ` +-func (c *completer) _() { +- c.inference.kindMatches(c.) -} +-` +- setup := func(env *Env) { +- env.OpenFile(file) +- originalBuffer := env.BufferText(file) +- env.EditBuffer(file, protocol.TextEdit{ +- Range: endRangeInBuffer(env, file), +- // TODO(rfindley): this is a bug: it should just be fileContent. +- NewText: originalBuffer + fileContent, +- }) +- } - --func returnTP[A int | float64](a A) A { //@item(returnTP, "returnTP", "something", "func") -- return a +- benchmarkCompletion(completionBenchOptions{ +- file: file, +- locationRegexp: `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, +- setup: setup, +- }, b) -} - --func _() { -- // disabled - see issue #54822 -- var _ int = returnTP // snippet(" //", returnTP, "returnTP[${1:}](${2:})", "returnTP[${1:A int|float64}](${2:a A})") +-// Benchmark completion following an arbitrary edit. +-// +-// Edits force type-checked packages to be invalidated, so we want to measure +-// how long it takes before completion results are available. +-func BenchmarkCompletionFollowingEdit(b *testing.B) { +- tests := []struct { +- repo string +- file string // repo-relative file to create +- content string // file content +- locationRegexp string // regexp for completion +- }{ +- { +- "tools", +- "internal/lsp/source/completion/completion2.go", +- ` +-package completion - -- var aa int //@item(tpInt, "aa", "int", "var") -- var ab float64 //@item(tpFloat, "ab", "float64", "var") -- returnTP[int](a) //@rank(")", tpInt, tpFloat) +-func (c *completer) _() { +- c.inference.kindMatches(c.) -} +-`, +- `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, +- }, +- { +- "kubernetes", +- "pkg/kubelet/kubelet2.go", +- ` +-package kubelet - --func takesFunc[T any](func(T) T) { -- var _ func(t T) T = f //@snippet(" //", tpLitFunc, "func(t T) T {$0\\}", "func(t T) T {$0\\}") +-func (kl *Kubelet) _() { +- kl. -} +-`, +- `kl\.()`, +- }, +- { +- "oracle", +- "dataintegration/pivot2.go", +- ` +-package dataintegration - --func _() { -- _ = "func(...) {}" //@item(tpLitFunc, "func(...) {}", "", "var") -- takesFunc() //@snippet(")", tpLitFunc, "func(${1:}) ${2:} {$0\\}", "func(${1:t} ${2:T}) ${3:T} {$0\\}") -- takesFunc[int]() //@snippet(")", tpLitFunc, "func(i int) int {$0\\}", "func(${1:i} int) int {$0\\}") +-func (p *Pivot) _() { +- p. -} -diff -urN a/gopls/internal/lsp/testdata/types/types.go b/gopls/internal/lsp/testdata/types/types.go ---- a/gopls/internal/lsp/testdata/types/types.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/types/types.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ --package types +-`, +- `p\.()`, +- }, +- } - --type CoolAlias = int //@item(CoolAlias, "CoolAlias", "int", "type") +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- repo := getRepo(b, test.repo) +- sharedEnv := repo.sharedEnv(b) // ensure cache is warm +- env := repo.newEnv(b, fake.EditorConfig{ +- Env: map[string]string{ +- "GOPATH": sharedEnv.Sandbox.GOPATH(), // use the warm cache +- }, +- Settings: map[string]interface{}{ +- "completeUnimported": false, +- }, +- }, "completionFollowingEdit", false) +- defer env.Close() - --type X struct { //@item(X_struct, "X", "struct{...}", "struct") -- x int --} +- env.CreateBuffer(test.file, "// __REGTEST_PLACEHOLDER_0__\n"+test.content) +- editPlaceholder := func() { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- } +- env.AfterChange() - --type Y struct { //@item(Y_struct, "Y", "struct{...}", "struct") -- y int --} +- // Run a completion to make sure the system is warm. +- loc := env.RegexpSearch(test.file, test.locationRegexp) +- completions := env.Completion(loc) - --type Bob interface { //@item(Bob_interface, "Bob", "interface{...}", "interface") -- Bobby() --} +- if testing.Verbose() { +- fmt.Println("Results:") +- for i := 0; i < len(completions.Items); i++ { +- fmt.Printf("\t%d. %v\n", i, completions.Items[i]) +- } +- } - --func (*X) Bobby() {} --func (*Y) Bobby() {} -diff -urN a/gopls/internal/lsp/testdata/undeclared/var.go b/gopls/internal/lsp/testdata/undeclared/var.go ---- a/gopls/internal/lsp/testdata/undeclared/var.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/undeclared/var.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,14 +0,0 @@ --package undeclared +- b.ResetTimer() - --func m() int { -- z, _ := 1+y, 11 //@diag("y", "compiler", "(undeclared name|undefined): y", "error"),suggestedfix("y", "quickfix", "") -- if 100 < 90 { -- z = 1 -- } else if 100 > n+2 { //@diag("n", "compiler", "(undeclared name|undefined): n", "error"),suggestedfix("n", "quickfix", "") -- z = 4 -- } -- for i < 200 { //@diag("i", "compiler", "(undeclared name|undefined): i", "error"),suggestedfix("i", "quickfix", "") -- } -- r() //@diag("r", "compiler", "(undeclared name|undefined): r", "error") -- return z --} -diff -urN a/gopls/internal/lsp/testdata/undeclared/var.go.golden b/gopls/internal/lsp/testdata/undeclared/var.go.golden ---- a/gopls/internal/lsp/testdata/undeclared/var.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/undeclared/var.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,51 +0,0 @@ ---- suggestedfix_var_10_6 -- --package undeclared +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "completionFollowingEdit")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func m() int { -- z, _ := 1+y, 11 //@diag("y", "compiler", "(undeclared name|undefined): y", "error"),suggestedfix("y", "quickfix", "") -- if 100 < 90 { -- z = 1 -- } else if 100 > n+2 { //@diag("n", "compiler", "(undeclared name|undefined): n", "error"),suggestedfix("n", "quickfix", "") -- z = 4 -- } -- i := -- for i < 200 { //@diag("i", "compiler", "(undeclared name|undefined): i", "error"),suggestedfix("i", "quickfix", "") +- for i := 0; i < b.N; i++ { +- editPlaceholder() +- loc := env.RegexpSearch(test.file, test.locationRegexp) +- env.Completion(loc) +- } +- }) - } -- r() //@diag("r", "compiler", "(undeclared name|undefined): r", "error") -- return z -} +diff -urN a/gopls/internal/regtest/bench/definition_test.go b/gopls/internal/regtest/bench/definition_test.go +--- a/gopls/internal/regtest/bench/definition_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/definition_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,46 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - ---- suggestedfix_var_4_12 -- --package undeclared +-package bench - --func m() int { -- y := -- z, _ := 1+y, 11 //@diag("y", "compiler", "(undeclared name|undefined): y", "error"),suggestedfix("y", "quickfix", "") -- if 100 < 90 { -- z = 1 -- } else if 100 > n+2 { //@diag("n", "compiler", "(undeclared name|undefined): n", "error"),suggestedfix("n", "quickfix", "") -- z = 4 -- } -- for i < 200 { //@diag("i", "compiler", "(undeclared name|undefined): i", "error"),suggestedfix("i", "quickfix", "") +-import ( +- "testing" +-) +- +-func BenchmarkDefinition(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, +- {"google-cloud-go", "httpreplay/httpreplay.go", `proxy\.(ForRecording)`}, +- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`}, +- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, +- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, +- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, +- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, - } -- r() //@diag("r", "compiler", "(undeclared name|undefined): r", "error") -- return z --} - ---- suggestedfix_var_7_18 -- --package undeclared +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --func m() int { -- z, _ := 1+y, 11 //@diag("y", "compiler", "(undeclared name|undefined): y", "error"),suggestedfix("y", "quickfix", "") -- n := -- if 100 < 90 { -- z = 1 -- } else if 100 > n+2 { //@diag("n", "compiler", "(undeclared name|undefined): n", "error"),suggestedfix("n", "quickfix", "") -- z = 4 -- } -- for i < 200 { //@diag("i", "compiler", "(undeclared name|undefined): i", "error"),suggestedfix("i", "quickfix", "") +- loc := env.RegexpSearch(test.file, test.regexp) +- env.Await(env.DoneWithOpen()) +- env.GoToDefinition(loc) // pre-warm the query, and open the target file +- b.ResetTimer() +- +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "definition")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- env.GoToDefinition(loc) // pre-warm the query +- } +- }) - } -- r() //@diag("r", "compiler", "(undeclared name|undefined): r", "error") -- return z -} +diff -urN a/gopls/internal/regtest/bench/didchange_test.go b/gopls/internal/regtest/bench/didchange_test.go +--- a/gopls/internal/regtest/bench/didchange_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/didchange_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,142 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -diff -urN a/gopls/internal/lsp/testdata/unimported/export_test.go b/gopls/internal/lsp/testdata/unimported/export_test.go ---- a/gopls/internal/lsp/testdata/unimported/export_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unimported/export_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ --package unimported -- --var TestExport int //@item(testexport, "TestExport", "var (from \"golang.org/lsptests/unimported\")", "var") -diff -urN a/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go b/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go ---- a/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,16 +0,0 @@ --package unimported +-package bench - -import ( -- _ "context" +- "fmt" +- "sync/atomic" +- "testing" +- "time" - -- "golang.org/lsptests/baz" -- _ "golang.org/lsptests/signature" // provide type information for unimported completions in the other file +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" -) - --func _() { -- foo.StructFoo{} //@item(litFooStructFoo, "foo.StructFoo{}", "struct{...}", "struct") +-// Use a global edit counter as bench function may execute multiple times, and +-// we want to avoid cache hits. Use time.Now to also avoid cache hits from the +-// shared file cache. +-var editID int64 = time.Now().UnixNano() - -- // We get the literal completion for "foo.StructFoo{}" even though we haven't -- // imported "foo" yet. -- baz.FooStruct = f //@snippet(" //", litFooStructFoo, "foo.StructFoo{$0\\}", "foo.StructFoo{$0\\}") +-type changeTest struct { +- repo string +- file string +- canSave bool -} -diff -urN a/gopls/internal/lsp/testdata/unimported/unimported.go.in b/gopls/internal/lsp/testdata/unimported/unimported.go.in ---- a/gopls/internal/lsp/testdata/unimported/unimported.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unimported/unimported.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,23 +0,0 @@ --package unimported - --func _() { -- http //@unimported("p", nethttp) -- // container/ring is extremely unlikely to be imported by anything, so shouldn't have type information. -- ring.Ring //@unimported("Ring", ringring) -- signature.Foo //@unimported("Foo", signaturefoo) +-var didChangeTests = []changeTest{ +- {"google-cloud-go", "internal/annotate.go", true}, +- {"istio", "pkg/fuzz/util.go", true}, +- {"kubernetes", "pkg/controller/lookup_cache.go", true}, +- {"kuma", "api/generic/insights.go", true}, +- {"oracle", "dataintegration/data_type.go", false}, // diagnoseSave fails because this package is generated +- {"pkgsite", "internal/frontend/server.go", true}, +- {"starlark", "starlark/eval.go", true}, +- {"tools", "internal/lsp/cache/snapshot.go", true}, +-} - -- context.Bac //@unimported(" //", contextBackground) +-// BenchmarkDidChange benchmarks modifications of a single file by making +-// synthetic modifications in a comment. It controls pacing by waiting for the +-// server to actually start processing the didChange notification before +-// proceeding. Notably it does not wait for diagnostics to complete. +-func BenchmarkDidChange(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) +- +- // Insert the text we'll be modifying at the top of the file. +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- env.AfterChange() +- b.ResetTimer() +- +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "didchange")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- env.Await(env.StartedChange()) +- } +- }) +- } -} - --// Create markers for unimported std lib packages. Only for use by this test. --/* http */ //@item(nethttp, "http", "\"net/http\"", "package") +-func BenchmarkDiagnoseChange(b *testing.B) { +- for _, test := range didChangeTests { +- runChangeDiagnosticsBenchmark(b, test, false, "diagnoseChange") +- } +-} - --/* ring.Ring */ //@item(ringring, "Ring", "(from \"container/ring\")", "var") +-// TODO(rfindley): add a benchmark for with a metadata-affecting change, when +-// this matters. +-func BenchmarkDiagnoseSave(b *testing.B) { +- for _, test := range didChangeTests { +- runChangeDiagnosticsBenchmark(b, test, true, "diagnoseSave") +- } +-} - --/* signature.Foo */ //@item(signaturefoo, "Foo", "func (from \"golang.org/lsptests/signature\")", "func") +-// runChangeDiagnosticsBenchmark runs a benchmark to edit the test file and +-// await the resulting diagnostics pass. If save is set, the file is also saved. +-func runChangeDiagnosticsBenchmark(b *testing.B, test changeTest, save bool, operation string) { +- b.Run(test.repo, func(b *testing.B) { +- if !test.canSave { +- b.Skipf("skipping as %s cannot be saved", test.file) +- } +- sharedEnv := getRepo(b, test.repo).sharedEnv(b) +- config := fake.EditorConfig{ +- Env: map[string]string{ +- "GOPATH": sharedEnv.Sandbox.GOPATH(), +- }, +- Settings: map[string]interface{}{ +- "diagnosticsDelay": "0s", +- }, +- } +- // Use a new env to avoid the diagnostic delay: we want to measure how +- // long it takes to produce the diagnostics. +- env := getRepo(b, test.repo).newEnv(b, config, operation, false) +- defer env.Close() +- env.OpenFile(test.file) +- // Insert the text we'll be modifying at the top of the file. +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- if save { +- env.SaveBuffer(test.file) +- } +- env.AfterChange() +- b.ResetTimer() - --/* context.Background */ //@item(contextBackground, "Background", "func (from \"context\")", "func") +- // We must use an extra subtest layer here, so that we only set up the +- // shared env once (otherwise we pay additional overhead and the profiling +- // flags don't work). +- b.Run("diagnose", func(b *testing.B) { +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, operation)); stopAndRecord != nil { +- defer stopAndRecord() +- } +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- if save { +- env.SaveBuffer(test.file) +- } +- env.AfterChange() +- } +- }) +- }) +-} +diff -urN a/gopls/internal/regtest/bench/doc.go b/gopls/internal/regtest/bench/doc.go +--- a/gopls/internal/regtest/bench/doc.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/doc.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,40 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --// Now that we no longer type-check imported completions, --// we don't expect the context.Background().Err method (see golang/go#58663). --/* context.Background().Err */ //@item(contextBackgroundErr, "Background().Err", "func (from \"context\")", "method") -diff -urN a/gopls/internal/lsp/testdata/unimported/x_test.go b/gopls/internal/lsp/testdata/unimported/x_test.go ---- a/gopls/internal/lsp/testdata/unimported/x_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unimported/x_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package unimported_test +-// The bench package implements benchmarks for various LSP operations. +-// +-// Benchmarks check out specific commits of popular and/or exemplary +-// repositories, and script an external gopls process via a fake text editor. +-// By default, benchmarks run the test executable as gopls (using a special +-// "gopls mode" environment variable). A different gopls binary may be used by +-// setting the -gopls_path or -gopls_commit flags. +-// +-// This package is a work in progress. +-// +-// # Profiling +-// +-// Benchmark functions run gopls in a separate process, which means the normal +-// test flags for profiling aren't useful. Instead the -gopls_cpuprofile, +-// -gopls_memprofile, -gopls_allocprofile, and -gopls_trace flags may be used +-// to pass through profiling to the gopls subproces. +-// +-// Each of these flags sets a suffix for the respective gopls profile, which is +-// named according to the schema ... For example, +-// setting -gopls_cpuprofile=cpu will result in profiles named tools.iwl.cpu, +-// tools.rename.cpu, etc. In some cases, these profiles are for the entire +-// gopls subprocess (as in the initial workspace load), whereas in others they +-// span only the critical section of the benchmark. It is up to each benchmark +-// to implement profiling as appropriate. +-// +-// # Integration with perf.golang.org +-// +-// Benchmarks that run with -short are automatically tracked by +-// perf.golang.org, at +-// https://perf.golang.org/dashboard/?benchmark=all&repository=tools&branch=release-branch.go1.20 +-// +-// # TODO +-// - add more benchmarks, and more repositories +-// - fix the perf dashboard to not require the branch= parameter +-// - improve this documentation +-package bench +diff -urN a/gopls/internal/regtest/bench/hover_test.go b/gopls/internal/regtest/bench/hover_test.go +--- a/gopls/internal/regtest/bench/hover_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/hover_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package bench - -import ( - "testing" -) - --func TestSomething(t *testing.T) { -- _ = unimported.TestExport //@unimported("TestExport", testexport) --} -diff -urN a/gopls/internal/lsp/testdata/unresolved/unresolved.go.in b/gopls/internal/lsp/testdata/unresolved/unresolved.go.in ---- a/gopls/internal/lsp/testdata/unresolved/unresolved.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unresolved/unresolved.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,6 +0,0 @@ --package unresolved +-func BenchmarkHover(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `proxy\.(ForRecording)`}, +- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, +- {"kubernetes", "pkg/apis/core/types.go", "type (Pod)"}, +- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, +- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, +- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, +- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, +- } - --func foo(interface{}) { -- // don't crash on fake "resolved" type -- foo(func(i, j f //@complete(" //") --} -diff -urN a/gopls/internal/lsp/testdata/unsafe/unsafe.go b/gopls/internal/lsp/testdata/unsafe/unsafe.go ---- a/gopls/internal/lsp/testdata/unsafe/unsafe.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/unsafe/unsafe.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --package unsafe -- --import ( -- "unsafe" --) -- --// Pre-set this marker, as we don't have a "source" for it in this package. --/* unsafe.Sizeof */ //@item(Sizeof, "Sizeof", "invalid type", "text") -- --func _() { -- x := struct{}{} -- _ = unsafe.Sizeof(x) //@complete("z", Sizeof) --} -diff -urN a/gopls/internal/lsp/testdata/variadic/variadic.go.in b/gopls/internal/lsp/testdata/variadic/variadic.go.in ---- a/gopls/internal/lsp/testdata/variadic/variadic.go.in 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/variadic/variadic.go.in 1970-01-01 00:00:00.000000000 +0000 -@@ -1,38 +0,0 @@ --package variadic +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --func foo(i int, strs ...string) {} +- loc := env.RegexpSearch(test.file, test.regexp) +- env.AfterChange() - --func bar() []string { //@item(vFunc, "bar", "func() []string", "func") -- return nil +- env.Hover(loc) // pre-warm the query +- b.ResetTimer() +- +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "hover")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- env.Hover(loc) // pre-warm the query +- } +- }) +- } -} +diff -urN a/gopls/internal/regtest/bench/implementations_test.go b/gopls/internal/regtest/bench/implementations_test.go +--- a/gopls/internal/regtest/bench/implementations_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/implementations_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,44 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func _() { -- var ( -- i int //@item(vInt, "i", "int", "var") -- s string //@item(vStr, "s", "string", "var") -- ss []string //@item(vStrSlice, "ss", "[]string", "var") -- v interface{} //@item(vIntf, "v", "interface{}", "var") -- ) +-package bench - -- foo() //@rank(")", vInt, vStr),rank(")", vInt, vStrSlice) -- foo(123, ) //@rank(")", vStr, vInt),rank(")", vStrSlice, vInt) -- foo(123, "", ) //@rank(")", vStr, vInt),rank(")", vStr, vStrSlice) -- foo(123, s, "") //@rank(", \"", vStr, vStrSlice) +-import "testing" - -- // snippet will add the "..." for you -- foo(123, ) //@snippet(")", vStrSlice, "ss...", "ss..."),snippet(")", vFunc, "bar()...", "bar()..."),snippet(")", vStr, "s", "s") +-func BenchmarkImplementations(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `type (Recorder)`}, +- {"istio", "pkg/config/mesh/watcher.go", `type (Watcher)`}, +- {"kubernetes", "pkg/controller/lookup_cache.go", `objectWithMeta`}, +- {"kuma", "api/generic/insights.go", `type (Insight)`}, +- {"pkgsite", "internal/datasource.go", `type (DataSource)`}, +- {"starlark", "syntax/syntax.go", `type (Expr)`}, +- {"tools", "internal/lsp/source/view.go", `type (Snapshot)`}, +- } - -- // don't add "..." for interface{} -- foo(123, ) //@snippet(")", vIntf, "v", "v") --} +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --func qux(...func()) {} --func f() {} //@item(vVarArg, "f", "func()", "func") +- loc := env.RegexpSearch(test.file, test.regexp) +- env.AfterChange() +- env.Implementations(loc) // pre-warm the query +- b.ResetTimer() - --func _() { -- qux(f) //@snippet(")", vVarArg, "f", "f") --} +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "implementations")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func _() { -- foo(0, []string{}...) //@complete(")") +- for i := 0; i < b.N; i++ { +- env.Implementations(loc) +- } +- }) +- } -} -diff -urN a/gopls/internal/lsp/testdata/variadic/variadic_intf.go b/gopls/internal/lsp/testdata/variadic/variadic_intf.go ---- a/gopls/internal/lsp/testdata/variadic/variadic_intf.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/variadic/variadic_intf.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ --package variadic +diff -urN a/gopls/internal/regtest/bench/iwl_test.go b/gopls/internal/regtest/bench/iwl_test.go +--- a/gopls/internal/regtest/bench/iwl_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/iwl_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,76 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --type baz interface { -- baz() --} +-package bench - --func wantsBaz(...baz) {} +-import ( +- "testing" - --type bazImpl int +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --func (bazImpl) baz() {} +-// BenchmarkInitialWorkspaceLoad benchmarks the initial workspace load time for +-// a new editing session. +-func BenchmarkInitialWorkspaceLoad(b *testing.B) { +- tests := []struct { +- repo string +- file string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go"}, +- {"istio", "pkg/fuzz/util.go"}, +- {"kubernetes", "pkg/controller/lookup_cache.go"}, +- {"kuma", "api/generic/insights.go"}, +- {"oracle", "dataintegration/data_type.go"}, +- {"pkgsite", "internal/frontend/server.go"}, +- {"starlark", "starlark/eval.go"}, +- {"tools", "internal/lsp/cache/snapshot.go"}, +- {"hashiform", "internal/provider/provider.go"}, +- } - --func _() { -- var ( -- impls []bazImpl //@item(vImplSlice, "impls", "[]bazImpl", "var") -- impl bazImpl //@item(vImpl, "impl", "bazImpl", "var") -- bazes []baz //@item(vIntfSlice, "bazes", "[]baz", "var") -- ) +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- repo := getRepo(b, test.repo) +- // get the (initialized) shared env to ensure the cache is warm. +- // Reuse its GOPATH so that we get cache hits for things in the module +- // cache. +- sharedEnv := repo.sharedEnv(b) +- b.ResetTimer() - -- wantsBaz() //@rank(")", vImpl, vImplSlice),rank(")", vIntfSlice, vImplSlice) +- for i := 0; i < b.N; i++ { +- doIWL(b, sharedEnv.Sandbox.GOPATH(), repo, test.file) +- } +- }) +- } -} -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/a/a.go b/gopls/internal/lsp/testdata/workspacesymbol/a/a.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/a/a.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/a/a.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,9 +0,0 @@ --package a - --var RandomGopherVariableA = "a" +-func doIWL(b *testing.B, gopath string, repo *repo, file string) { +- // Exclude the time to set up the env from the benchmark time, as this may +- // involve installing gopls and/or checking out the repo dir. +- b.StopTimer() +- config := fake.EditorConfig{Env: map[string]string{"GOPATH": gopath}} +- env := repo.newEnv(b, config, "iwl", true) +- defer env.Close() +- b.StartTimer() - --const RandomGopherConstantA = "a" +- // Note: in the future, we may need to open a file in order to cause gopls to +- // start loading the workspace. - --const ( -- randomgopherinvariable = iota --) -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/a/a_test.go b/gopls/internal/lsp/testdata/workspacesymbol/a/a_test.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/a/a_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/a/a_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ --package a +- env.Await(InitialWorkspaceLoad) - --var RandomGopherTestVariableA = "a" -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/a/a_x_test.go b/gopls/internal/lsp/testdata/workspacesymbol/a/a_x_test.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/a/a_x_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/a/a_x_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ --package a_test +- if env.Editor.HasCommand(command.MemStats.ID()) { +- b.StopTimer() +- params := &protocol.ExecuteCommandParams{ +- Command: command.MemStats.ID(), +- } +- var memstats command.MemStatsResult +- env.ExecuteCommand(params, &memstats) +- b.ReportMetric(float64(memstats.HeapAlloc), "alloc_bytes") +- b.ReportMetric(float64(memstats.HeapInUse), "in_use_bytes") +- b.ReportMetric(float64(memstats.TotalAlloc), "total_alloc_bytes") +- b.StartTimer() +- } +-} +diff -urN a/gopls/internal/regtest/bench/references_test.go b/gopls/internal/regtest/bench/references_test.go +--- a/gopls/internal/regtest/bench/references_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/references_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,44 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --var RandomGopherXTestVariableA = "a" -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/b/b.go b/gopls/internal/lsp/testdata/workspacesymbol/b/b.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/b/b.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/b/b.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,7 +0,0 @@ --package b +-package bench - --var RandomGopherVariableB = "b" +-import "testing" - --type RandomGopherStructB struct { -- Bar int --} -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/issue44806.go b/gopls/internal/lsp/testdata/workspacesymbol/issue44806.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/issue44806.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/issue44806.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,10 +0,0 @@ --package main +-func BenchmarkReferences(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `func (NewRecorder)`}, +- {"istio", "pkg/config/model.go", "type (Meta)"}, +- {"kubernetes", "pkg/controller/lookup_cache.go", "type (objectWithMeta)"}, // TODO: choose an exported identifier +- {"kuma", "pkg/events/interfaces.go", "type (Event)"}, +- {"pkgsite", "internal/log/log.go", "func (Infof)"}, +- {"starlark", "syntax/syntax.go", "type (Ident)"}, +- {"tools", "internal/lsp/source/view.go", "type (Snapshot)"}, +- } - --type T struct{} +- for _, test := range tests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - --// We should accept all valid receiver syntax when scanning symbols. --func (*(T)) m1() {} --func (*T) m2() {} --func (T) m3() {} --func ((T)) m4() {} --func ((*T)) m5() {} -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/main.go b/gopls/internal/lsp/testdata/workspacesymbol/main.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/main.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/main.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,47 +0,0 @@ --package main +- loc := env.RegexpSearch(test.file, test.regexp) +- env.AfterChange() +- env.References(loc) // pre-warm the query +- b.ResetTimer() - --import ( -- "encoding/json" -- "fmt" --) +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "references")); stopAndRecord != nil { +- defer stopAndRecord() +- } - --func main() { // function -- fmt.Println("Hello") +- for i := 0; i < b.N; i++ { +- env.References(loc) +- } +- }) +- } -} +diff -urN a/gopls/internal/regtest/bench/reload_test.go b/gopls/internal/regtest/bench/reload_test.go +--- a/gopls/internal/regtest/bench/reload_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/reload_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,52 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +-package bench - --var myvar int // variable +-import ( +- "testing" - --type myType string // basic type +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --type myDecoder json.Decoder // to use the encoding/json import +-// BenchmarkReload benchmarks reloading a file metadata after a change to an import. +-// +-// This ensures we are able to diagnose a changed file without reloading all +-// invalidated packages. See also golang/go#61344 +-func BenchmarkReload(b *testing.B) { +- // TODO(rfindley): add more tests, make this test table-driven +- const ( +- repo = "kubernetes" +- // pkg/util/hash is transitively imported by a large number of packages. +- // We should not need to reload those packages to get a diagnostic. +- file = "pkg/util/hash/hash.go" +- ) +- b.Run(repo, func(b *testing.B) { +- env := getRepo(b, repo).sharedEnv(b) - --func (m *myType) Blahblah() {} // method +- env.OpenFile(file) +- defer closeBuffer(b, env, file) - --type myStruct struct { // struct type -- myStructField int // struct field --} +- env.AfterChange() - --type myInterface interface { // interface -- DoSomeCoolStuff() string // interface method +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(repo, "reload")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- b.ResetTimer() +- for i := 0; i < b.N; i++ { +- // Change the "hash" import. This may result in cache hits, but that's +- // OK: the goal is to ensure that we don't reload more than just the +- // current package. +- env.RegexpReplace(file, `"hash"`, `"hashx"`) +- // Note: don't use env.AfterChange() here: we only want to await the +- // first diagnostic. +- // +- // Awaiting a full diagnosis would await diagnosing everything, which +- // would require reloading everything. +- env.Await(Diagnostics(ForFile(file))) +- env.RegexpReplace(file, `"hashx"`, `"hash"`) +- env.Await(NoDiagnostics(ForFile(file))) +- } +- }) -} +diff -urN a/gopls/internal/regtest/bench/rename_test.go b/gopls/internal/regtest/bench/rename_test.go +--- a/gopls/internal/regtest/bench/rename_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/rename_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,49 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --type embed struct { -- myStruct +-package bench - -- nestedStruct struct { -- nestedField int +-import ( +- "fmt" +- "testing" +-) - -- nestedStruct2 struct { -- int -- } +-func BenchmarkRename(b *testing.B) { +- tests := []struct { +- repo string +- file string +- regexp string +- baseName string +- }{ +- {"google-cloud-go", "httpreplay/httpreplay.go", `func (NewRecorder)`, "NewRecorder"}, +- {"istio", "pkg/config/model.go", `(Namespace) string`, "Namespace"}, +- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`, "DeepHashObject"}, +- {"kuma", "pkg/events/interfaces.go", `Delete`, "Delete"}, +- {"pkgsite", "internal/log/log.go", `func (Infof)`, "Infof"}, +- {"starlark", "starlark/eval.go", `Program\) (Filename)`, "Filename"}, +- {"tools", "internal/lsp/cache/snapshot.go", `meta \*(metadataGraph)`, "metadataGraph"}, - } - -- nestedInterface interface { -- myInterface -- nestedMethod() +- for _, test := range tests { +- names := 0 // bench function may execute multiple times +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- loc := env.RegexpSearch(test.file, test.regexp) +- env.Await(env.DoneWithOpen()) +- env.Rename(loc, test.baseName+"X") // pre-warm the query +- b.ResetTimer() +- +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "rename")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- +- for i := 0; i < b.N; i++ { +- names++ +- newName := fmt.Sprintf("%s%d", test.baseName, names) +- env.Rename(loc, newName) +- } +- }) - } -} +diff -urN a/gopls/internal/regtest/bench/repo_test.go b/gopls/internal/regtest/bench/repo_test.go +--- a/gopls/internal/regtest/bench/repo_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/repo_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,290 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func Dunk() int { return 0 } +-package bench - --func dunk() {} -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/p/p.go b/gopls/internal/lsp/testdata/workspacesymbol/p/p.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/p/p.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/p/p.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,3 +0,0 @@ --package p +-import ( +- "bytes" +- "context" +- "errors" +- "flag" +- "fmt" +- "log" +- "os" +- "path/filepath" +- "sync" +- "testing" +- "time" - --const Message = "Hello World." // constant -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/query.go b/gopls/internal/lsp/testdata/workspacesymbol/query.go ---- a/gopls/internal/lsp/testdata/workspacesymbol/query.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/query.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ --package main +- "golang.org/x/tools/gopls/internal/lsp/fake" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - --// Contains all of the workspace symbol queries. -- --// -- Fuzzy matching -- --//@workspacesymbolfuzzy("rgop") --//@workspacesymbolfuzzy("randoma") --//@workspacesymbolfuzzy("randomb") -- --// -- Case sensitive -- --//@workspacesymbolcasesensitive("main.main") --//@workspacesymbolcasesensitive("p.Message") --//@workspacesymbolcasesensitive("main.myvar") --//@workspacesymbolcasesensitive("main.myType") --//@workspacesymbolcasesensitive("main.myType.Blahblah") --//@workspacesymbolcasesensitive("main.myStruct") --//@workspacesymbolcasesensitive("main.myStruct.myStructField") --//@workspacesymbolcasesensitive("main.myInterface") --//@workspacesymbolcasesensitive("main.myInterface.DoSomeCoolStuff") --//@workspacesymbolcasesensitive("main.embed.myStruct") --//@workspacesymbolcasesensitive("main.embed.nestedStruct.nestedStruct2.int") --//@workspacesymbolcasesensitive("main.embed.nestedInterface.myInterface") --//@workspacesymbolcasesensitive("main.embed.nestedInterface.nestedMethod") --//@workspacesymbolcasesensitive("dunk") --//@workspacesymbolcasesensitive("Dunk") -- --// -- Standard -- --//@workspacesymbol("") --//@workspacesymbol("randomgophervar") -diff -urN a/gopls/internal/lsp/testdata/workspacesymbol/query.go.golden b/gopls/internal/lsp/testdata/workspacesymbol/query.go.golden ---- a/gopls/internal/lsp/testdata/workspacesymbol/query.go.golden 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/testdata/workspacesymbol/query.go.golden 1970-01-01 00:00:00.000000000 +0000 -@@ -1,83 +0,0 @@ ---- workspace_symbol-caseinsensitive- -- +-// repos holds shared repositories for use in benchmarks. +-// +-// These repos were selected to represent a variety of different types of +-// codebases. +-var repos = map[string]*repo{ +- // google-cloud-go has 145 workspace modules (!), and is quite large. +- "google-cloud-go": { +- name: "google-cloud-go", +- url: "https://github.com/googleapis/google-cloud-go.git", +- commit: "07da765765218debf83148cc7ed8a36d6e8921d5", +- inDir: flag.String("cloud_go_dir", "", "if set, reuse this directory as google-cloud-go@07da7657"), +- }, +- +- // Used by x/benchmarks; large. +- "istio": { +- name: "istio", +- url: "https://github.com/istio/istio", +- commit: "1.17.0", +- inDir: flag.String("istio_dir", "", "if set, reuse this directory as istio@v1.17.0"), +- }, +- +- // Kubernetes is a large repo with many dependencies, and in the past has +- // been about as large a repo as gopls could handle. +- "kubernetes": { +- name: "kubernetes", +- url: "https://github.com/kubernetes/kubernetes", +- commit: "v1.24.0", +- short: true, +- inDir: flag.String("kubernetes_dir", "", "if set, reuse this directory as kubernetes@v1.24.0"), +- }, - +- // A large, industrial application. +- "kuma": { +- name: "kuma", +- url: "https://github.com/kumahq/kuma", +- commit: "2.1.1", +- inDir: flag.String("kuma_dir", "", "if set, reuse this directory as kuma@v2.1.1"), +- }, - ---- workspace_symbol-caseinsensitive-randomgophervar -- --workspacesymbol/a/a.go:3:5-26 RandomGopherVariableA Variable --workspacesymbol/b/b.go:3:5-26 RandomGopherVariableB Variable +- // A repo containing a very large package (./dataintegration). +- "oracle": { +- name: "oracle", +- url: "https://github.com/oracle/oci-go-sdk.git", +- commit: "v65.43.0", +- short: true, +- inDir: flag.String("oracle_dir", "", "if set, reuse this directory as oracle/oci-go-sdk@v65.43.0"), +- }, - ---- workspace_symbol-casesensitive-Dunk -- --workspacesymbol/main.go:45:6-10 Dunk Function +- // x/pkgsite is familiar and represents a common use case (a webserver). It +- // also has a number of static non-go files and template files. +- "pkgsite": { +- name: "pkgsite", +- url: "https://go.googlesource.com/pkgsite", +- commit: "81f6f8d4175ad0bf6feaa03543cc433f8b04b19b", +- short: true, +- inDir: flag.String("pkgsite_dir", "", "if set, reuse this directory as pkgsite@81f6f8d4"), +- }, - ---- workspace_symbol-casesensitive-dunk -- --workspacesymbol/main.go:47:6-10 dunk Function +- // A tiny self-contained project. +- "starlark": { +- name: "starlark", +- url: "https://github.com/google/starlark-go", +- commit: "3f75dec8e4039385901a30981e3703470d77e027", +- short: true, +- inDir: flag.String("starlark_dir", "", "if set, reuse this directory as starlark@3f75dec8"), +- }, - ---- workspace_symbol-casesensitive-main.embed.myStruct -- --workspacesymbol/main.go:29:2-10 main.embed.myStruct Field +- // The current repository, which is medium-small and has very few dependencies. +- "tools": { +- name: "tools", +- url: "https://go.googlesource.com/tools", +- commit: "gopls/v0.9.0", +- short: true, +- inDir: flag.String("tools_dir", "", "if set, reuse this directory as x/tools@v0.9.0"), +- }, - ---- workspace_symbol-casesensitive-main.embed.nestedInterface.myInterface -- --workspacesymbol/main.go:40:3-14 main.embed.nestedInterface.myInterface Interface +- // A repo of similar size to kubernetes, but with substantially more +- // complex types that led to a serious performance regression (issue #60621). +- "hashiform": { +- name: "hashiform", +- url: "https://github.com/hashicorp/terraform-provider-aws", +- commit: "ac55de2b1950972d93feaa250d7505d9ed829c7c", +- inDir: flag.String("hashiform_dir", "", "if set, reuse this directory as hashiform@ac55de2"), +- }, +-} - ---- workspace_symbol-casesensitive-main.embed.nestedInterface.nestedMethod -- --workspacesymbol/main.go:41:3-15 main.embed.nestedInterface.nestedMethod Method +-// getRepo gets the requested repo, and skips the test if -short is set and +-// repo is not configured as a short repo. +-func getRepo(tb testing.TB, name string) *repo { +- tb.Helper() +- repo := repos[name] +- if repo == nil { +- tb.Fatalf("repo %s does not exist", name) +- } +- if !repo.short && testing.Short() { +- tb.Skipf("large repo %s does not run with -short", repo.name) +- } +- return repo +-} - ---- workspace_symbol-casesensitive-main.embed.nestedStruct.nestedStruct2.int -- --workspacesymbol/main.go:35:4-7 main.embed.nestedStruct.nestedStruct2.int Field +-// A repo represents a working directory for a repository checked out at a +-// specific commit. +-// +-// Repos are used for sharing state across benchmarks that operate on the same +-// codebase. +-type repo struct { +- // static configuration +- name string // must be unique, used for subdirectory +- url string // repo url +- commit string // full commit hash or tag +- short bool // whether this repo runs with -short +- inDir *string // if set, use this dir as url@commit, and don't delete - ---- workspace_symbol-casesensitive-main.main -- --workspacesymbol/main.go:8:6-10 main.main Function +- dirOnce sync.Once +- dir string // directory contaning source code checked out to url@commit - ---- workspace_symbol-casesensitive-main.myInterface -- --workspacesymbol/main.go:24:6-17 main.myInterface Interface --workspacesymbol/main.go:25:2-17 main.myInterface.DoSomeCoolStuff Method +- // shared editor state +- editorOnce sync.Once +- editor *fake.Editor +- sandbox *fake.Sandbox +- awaiter *Awaiter +-} - ---- workspace_symbol-casesensitive-main.myInterface.DoSomeCoolStuff -- --workspacesymbol/main.go:25:2-17 main.myInterface.DoSomeCoolStuff Method +-// reusableDir return a reusable directory for benchmarking, or "". +-// +-// If the user specifies a directory, the test will create and populate it +-// on the first run an re-use it on subsequent runs. Otherwise it will +-// create, populate, and delete a temporary directory. +-func (r *repo) reusableDir() string { +- if r.inDir == nil { +- return "" +- } +- return *r.inDir +-} - ---- workspace_symbol-casesensitive-main.myStruct -- --workspacesymbol/main.go:20:6-14 main.myStruct Struct --workspacesymbol/main.go:21:2-15 main.myStruct.myStructField Field +-// getDir returns directory containing repo source code, creating it if +-// necessary. It is safe for concurrent use. +-func (r *repo) getDir() string { +- r.dirOnce.Do(func() { +- if r.dir = r.reusableDir(); r.dir == "" { +- r.dir = filepath.Join(getTempDir(), r.name) +- } - ---- workspace_symbol-casesensitive-main.myStruct.myStructField -- --workspacesymbol/main.go:21:2-15 main.myStruct.myStructField Field +- _, err := os.Stat(r.dir) +- switch { +- case os.IsNotExist(err): +- log.Printf("cloning %s@%s into %s", r.url, r.commit, r.dir) +- if err := shallowClone(r.dir, r.url, r.commit); err != nil { +- log.Fatal(err) +- } +- case err != nil: +- log.Fatal(err) +- default: +- log.Printf("reusing %s as %s@%s", r.dir, r.url, r.commit) +- } +- }) +- return r.dir +-} - ---- workspace_symbol-casesensitive-main.myType -- --workspacesymbol/main.go:14:6-12 main.myType Class --workspacesymbol/main.go:18:18-26 main.myType.Blahblah Method +-// sharedEnv returns a shared benchmark environment. It is safe for concurrent +-// use. +-// +-// Every call to sharedEnv uses the same editor and sandbox, as a means to +-// avoid reinitializing the editor for large repos. Calling repo.Close cleans +-// up the shared environment. +-// +-// Repos in the package-local Repos var are closed at the end of the test main +-// function. +-func (r *repo) sharedEnv(tb testing.TB) *Env { +- r.editorOnce.Do(func() { +- dir := r.getDir() - ---- workspace_symbol-casesensitive-main.myType.Blahblah -- --workspacesymbol/main.go:18:18-26 main.myType.Blahblah Method +- start := time.Now() +- log.Printf("starting initial workspace load for %s", r.name) +- ts, err := newGoplsConnector(profileArgs(r.name, false)) +- if err != nil { +- log.Fatal(err) +- } +- r.sandbox, r.editor, r.awaiter, err = connectEditor(dir, fake.EditorConfig{}, ts) +- if err != nil { +- log.Fatalf("connecting editor: %v", err) +- } - ---- workspace_symbol-casesensitive-main.myvar -- --workspacesymbol/main.go:12:5-10 main.myvar Variable +- if err := r.awaiter.Await(context.Background(), InitialWorkspaceLoad); err != nil { +- log.Fatal(err) +- } +- log.Printf("initial workspace load (cold) for %s took %v", r.name, time.Since(start)) +- }) - ---- workspace_symbol-casesensitive-p.Message -- --workspacesymbol/p/p.go:3:7-14 p.Message Constant +- return &Env{ +- T: tb, +- Ctx: context.Background(), +- Editor: r.editor, +- Sandbox: r.sandbox, +- Awaiter: r.awaiter, +- } +-} - ---- workspace_symbol-fuzzy-randoma -- --workspacesymbol/a/a.go:3:5-26 RandomGopherVariableA Variable --workspacesymbol/a/a.go:5:7-28 RandomGopherConstantA Constant --workspacesymbol/a/a.go:8:2-24 randomgopherinvariable Constant --workspacesymbol/a/a_test.go:3:5-30 RandomGopherTestVariableA Variable --workspacesymbol/a/a_x_test.go:3:5-31 RandomGopherXTestVariableA Variable --workspacesymbol/b/b.go:3:5-26 RandomGopherVariableB Variable --workspacesymbol/b/b.go:6:2-5 RandomGopherStructB.Bar Field +-// newEnv returns a new Env connected to a new gopls process communicating +-// over stdin/stdout. It is safe for concurrent use. +-// +-// It is the caller's responsibility to call Close on the resulting Env when it +-// is no longer needed. +-func (r *repo) newEnv(tb testing.TB, config fake.EditorConfig, forOperation string, cpuProfile bool) *Env { +- dir := r.getDir() - ---- workspace_symbol-fuzzy-randomb -- --workspacesymbol/a/a.go:3:5-26 RandomGopherVariableA Variable --workspacesymbol/a/a.go:8:2-24 randomgopherinvariable Constant --workspacesymbol/a/a_test.go:3:5-30 RandomGopherTestVariableA Variable --workspacesymbol/a/a_x_test.go:3:5-31 RandomGopherXTestVariableA Variable --workspacesymbol/b/b.go:3:5-26 RandomGopherVariableB Variable --workspacesymbol/b/b.go:5:6-25 RandomGopherStructB Struct --workspacesymbol/b/b.go:6:2-5 RandomGopherStructB.Bar Field +- args := profileArgs(qualifiedName(r.name, forOperation), cpuProfile) +- ts, err := newGoplsConnector(args) +- if err != nil { +- tb.Fatal(err) +- } +- sandbox, editor, awaiter, err := connectEditor(dir, config, ts) +- if err != nil { +- log.Fatalf("connecting editor: %v", err) +- } - ---- workspace_symbol-fuzzy-rgop -- --workspacesymbol/a/a.go:3:5-26 RandomGopherVariableA Variable --workspacesymbol/a/a.go:5:7-28 RandomGopherConstantA Constant --workspacesymbol/a/a.go:8:2-24 randomgopherinvariable Constant --workspacesymbol/a/a_test.go:3:5-30 RandomGopherTestVariableA Variable --workspacesymbol/a/a_x_test.go:3:5-31 RandomGopherXTestVariableA Variable --workspacesymbol/b/b.go:3:5-26 RandomGopherVariableB Variable --workspacesymbol/b/b.go:5:6-25 RandomGopherStructB Struct --workspacesymbol/b/b.go:6:2-5 RandomGopherStructB.Bar Field +- return &Env{ +- T: tb, +- Ctx: context.Background(), +- Editor: editor, +- Sandbox: sandbox, +- Awaiter: awaiter, +- } +-} - -diff -urN a/gopls/internal/lsp/tests/compare/text.go b/gopls/internal/lsp/tests/compare/text.go ---- a/gopls/internal/lsp/tests/compare/text.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/compare/text.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,49 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. +-// Close cleans up shared state referenced by the repo. +-func (r *repo) Close() error { +- var errBuf bytes.Buffer +- if r.editor != nil { +- if err := r.editor.Close(context.Background()); err != nil { +- fmt.Fprintf(&errBuf, "closing editor: %v", err) +- } +- } +- if r.sandbox != nil { +- if err := r.sandbox.Close(); err != nil { +- fmt.Fprintf(&errBuf, "closing sandbox: %v", err) +- } +- } +- if r.dir != "" && r.reusableDir() == "" { +- if err := os.RemoveAll(r.dir); err != nil { +- fmt.Fprintf(&errBuf, "cleaning dir: %v", err) +- } +- } +- if errBuf.Len() > 0 { +- return errors.New(errBuf.String()) +- } +- return nil +-} +- +-// cleanup cleans up state that is shared across benchmark functions. +-func cleanup() error { +- var errBuf bytes.Buffer +- for _, repo := range repos { +- if err := repo.Close(); err != nil { +- fmt.Fprintf(&errBuf, "closing %q: %v", repo.name, err) +- } +- } +- if tempDir != "" { +- if err := os.RemoveAll(tempDir); err != nil { +- fmt.Fprintf(&errBuf, "cleaning tempDir: %v", err) +- } +- } +- if errBuf.Len() > 0 { +- return errors.New(errBuf.String()) +- } +- return nil +-} +diff -urN a/gopls/internal/regtest/bench/stress_test.go b/gopls/internal/regtest/bench/stress_test.go +--- a/gopls/internal/regtest/bench/stress_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/stress_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,94 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --package compare +-package bench - -import ( -- "bytes" +- "context" +- "flag" +- "fmt" +- "testing" +- "time" - -- "golang.org/x/tools/internal/diff" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/cache" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/lsprpc" +- "golang.org/x/tools/internal/jsonrpc2" +- "golang.org/x/tools/internal/jsonrpc2/servertest" -) - --// Text returns a formatted unified diff of the edits to go from want to --// got, returning "" if and only if want == got. --// --// This function is intended for use in testing, and panics if any error occurs --// while computing the diff. It is not sufficiently tested for production use. --func Text(want, got string) string { -- return NamedText("want", "got", want, got) --} -- --// NamedText is like text, but allows passing custom names of the 'want' and --// 'got' content. --func NamedText(wantName, gotName, want, got string) string { -- if want == got { -- return "" -- } +-// github.com/pilosa/pilosa is a repository that has historically caused +-// significant memory problems for Gopls. We use it for a simple stress test +-// that types arbitrarily in a file with lots of dependents. - -- // Add newlines to avoid verbose newline messages ("No newline at end of file"). -- unified := diff.Unified(wantName, gotName, want+"\n", got+"\n") +-var pilosaPath = flag.String("pilosa_path", "", "Path to a directory containing "+ +- "github.com/pilosa/pilosa, for stress testing. Do not set this unless you "+ +- "know what you're doing!") - -- // Defensively assert that we get an actual diff, so that we guarantee the -- // invariant that we return "" if and only if want == got. +-func TestPilosaStress(t *testing.T) { +- // TODO(rfindley): revisit this test and make it is hermetic: it should check +- // out pilosa into a directory. - // -- // This is probably unnecessary, but convenient. -- if unified == "" { -- panic("empty diff for non-identical input") +- // Note: This stress test has not been run recently, and may no longer +- // function properly. +- if *pilosaPath == "" { +- t.Skip("-pilosa_path not configured") - } - -- return unified --} -- --// Bytes is like Text but using byte slices. --func Bytes(want, got []byte) string { -- if bytes.Equal(want, got) { -- return "" // common case +- sandbox, err := fake.NewSandbox(&fake.SandboxConfig{ +- Workdir: *pilosaPath, +- GOPROXY: "https://proxy.golang.org", +- }) +- if err != nil { +- t.Fatal(err) - } -- return Text(string(want), string(got)) --} -diff -urN a/gopls/internal/lsp/tests/compare/text_test.go b/gopls/internal/lsp/tests/compare/text_test.go ---- a/gopls/internal/lsp/tests/compare/text_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/compare/text_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,28 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package compare_test -- --import ( -- "testing" +- server := lsprpc.NewStreamServer(cache.New(nil), false, hooks.Options) +- ts := servertest.NewPipeServer(server, jsonrpc2.NewRawStream) +- ctx := context.Background() - -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" --) +- const skipApplyEdits = false +- editor, err := fake.NewEditor(sandbox, fake.EditorConfig{}).Connect(ctx, ts, fake.ClientHooks{}, skipApplyEdits) +- if err != nil { +- t.Fatal(err) +- } - --func TestText(t *testing.T) { -- tests := []struct { -- got, want, wantDiff string -- }{ -- {"", "", ""}, -- {"equal", "equal", ""}, -- {"a", "b", "--- want\n+++ got\n@@ -1 +1 @@\n-b\n+a\n"}, -- {"a\nd\nc\n", "a\nb\nc\n", "--- want\n+++ got\n@@ -1,4 +1,4 @@\n a\n-b\n+d\n c\n \n"}, +- files := []string{ +- "cmd.go", +- "internal/private.pb.go", +- "roaring/roaring.go", +- "roaring/roaring_internal_test.go", +- "server/handler_test.go", +- } +- for _, file := range files { +- if err := editor.OpenFile(ctx, file); err != nil { +- t.Fatal(err) +- } - } +- ctx, cancel := context.WithTimeout(ctx, 10*time.Minute) +- defer cancel() - -- for _, test := range tests { -- if gotDiff := compare.Text(test.want, test.got); gotDiff != test.wantDiff { -- t.Errorf("compare.Text(%q, %q) =\n%q, want\n%q", test.want, test.got, gotDiff, test.wantDiff) +- i := 1 +- // MagicNumber is an identifier that occurs in roaring.go. Just change it +- // arbitrarily. +- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", "MagicNumber", fmt.Sprintf("MagicNumber%d", 1)); err != nil { +- t.Fatal(err) +- } +- for { +- select { +- case <-ctx.Done(): +- return +- default: +- } +- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", fmt.Sprintf("MagicNumber%d", i), fmt.Sprintf("MagicNumber%d", i+1)); err != nil { +- t.Fatal(err) - } +- // Simulate (very fast) typing. +- // +- // Typing 80 wpm ~150ms per keystroke. +- time.Sleep(150 * time.Millisecond) +- i++ - } -} -diff -urN a/gopls/internal/lsp/tests/markdown_go118.go b/gopls/internal/lsp/tests/markdown_go118.go ---- a/gopls/internal/lsp/tests/markdown_go118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/markdown_go118.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,69 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/regtest/bench/typing_test.go b/gopls/internal/regtest/bench/typing_test.go +--- a/gopls/internal/regtest/bench/typing_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/typing_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,63 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --//go:build !go1.19 --// +build !go1.19 -- --package tests +-package bench - -import ( -- "regexp" -- "strings" +- "fmt" +- "sync/atomic" +- "testing" +- "time" - -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "golang.org/x/tools/gopls/internal/lsp/protocol" -) - --// DiffMarkdown compares two markdown strings produced by parsing go doc --// comments. --// --// For go1.19 and later, markdown conversion is done using go/doc/comment. --// Compared to the newer version, the older version has extra escapes, and --// treats code blocks slightly differently. --func DiffMarkdown(want, got string) string { -- want = normalizeMarkdown(want) -- got = normalizeMarkdown(got) -- return compare.Text(want, got) --} -- --// normalizeMarkdown normalizes whitespace and escaping of the input string, to --// eliminate differences between the Go 1.18 and Go 1.19 generated markdown for --// doc comments. Note that it does not normalize to either the 1.18 or 1.19 --// formatting: it simplifies both so that they may be compared. --// --// This function may need to be adjusted as we encounter more differences in --// the generated text. +-// BenchmarkTyping simulates typing steadily in a single file at different +-// paces. -// --// TODO(rfindley): this function doesn't correctly handle the case of --// multi-line docstrings. --func normalizeMarkdown(input string) string { -- input = strings.TrimSpace(input) +-// The key metric for this benchmark is not latency, but cpu_seconds per +-// operation. +-func BenchmarkTyping(b *testing.B) { +- for _, test := range didChangeTests { +- b.Run(test.repo, func(b *testing.B) { +- env := getRepo(b, test.repo).sharedEnv(b) +- env.OpenFile(test.file) +- defer closeBuffer(b, env, test.file) - -- // For simplicity, eliminate blank lines. -- input = regexp.MustCompile("\n+").ReplaceAllString(input, "\n") +- // Insert the text we'll be modifying at the top of the file. +- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) +- env.AfterChange() - -- // Replace common escaped characters with their unescaped version. -- // -- // This list may not be exhaustive: it was just sufficient to make tests -- // pass. -- input = strings.NewReplacer( -- `\\`, ``, -- `\@`, `@`, -- `\(`, `(`, -- `\)`, `)`, -- `\{`, `{`, -- `\}`, `}`, -- `\"`, `"`, -- `\.`, `.`, -- `\-`, `-`, -- `\'`, `'`, -- `\+`, `+`, -- `\~`, `~`, -- `\=`, `=`, -- `\:`, `:`, -- `\?`, `?`, -- `\n\n\n`, `\n\n`, // Note that these are *escaped* newlines. -- ).Replace(input) +- delays := []time.Duration{ +- 10 * time.Millisecond, // automated changes +- 50 * time.Millisecond, // very fast mashing, or fast key sequences +- 150 * time.Millisecond, // avg interval for 80wpm typing. +- } - -- return input +- for _, delay := range delays { +- b.Run(delay.String(), func(b *testing.B) { +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(test.repo, "typing")); stopAndRecord != nil { +- defer stopAndRecord() +- } +- ticker := time.NewTicker(delay) +- for i := 0; i < b.N; i++ { +- edits := atomic.AddInt64(&editID, 1) +- env.EditBuffer(test.file, protocol.TextEdit{ +- Range: protocol.Range{ +- Start: protocol.Position{Line: 0, Character: 0}, +- End: protocol.Position{Line: 1, Character: 0}, +- }, +- // Increment the placeholder text, to ensure cache misses. +- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), +- }) +- <-ticker.C +- } +- b.StopTimer() +- ticker.Stop() +- env.AfterChange() // wait for all change processing to complete +- }) +- } +- }) +- } -} -diff -urN a/gopls/internal/lsp/tests/markdown_go119.go b/gopls/internal/lsp/tests/markdown_go119.go ---- a/gopls/internal/lsp/tests/markdown_go119.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/markdown_go119.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ +diff -urN a/gopls/internal/regtest/bench/workspace_symbols_test.go b/gopls/internal/regtest/bench/workspace_symbols_test.go +--- a/gopls/internal/regtest/bench/workspace_symbols_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/bench/workspace_symbols_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,41 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --//go:build go1.19 --// +build go1.19 -- --package tests +-package bench - -import ( -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "flag" +- "fmt" +- "testing" -) - --// DiffMarkdown compares two markdown strings produced by parsing go doc --// comments. --// --// For go1.19 and later, markdown conversion is done using go/doc/comment. --// Compared to the newer version, the older version has extra escapes, and --// treats code blocks slightly differently. --func DiffMarkdown(want, got string) string { -- return compare.Text(want, got) --} -diff -urN a/gopls/internal/lsp/tests/normalizer.go b/gopls/internal/lsp/tests/normalizer.go ---- a/gopls/internal/lsp/tests/normalizer.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/normalizer.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,113 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --package tests +-var symbolQuery = flag.String("symbol_query", "test", "symbol query to use in benchmark") - --import ( -- "path/filepath" -- "strconv" -- "strings" +-// BenchmarkWorkspaceSymbols benchmarks the time to execute a workspace symbols +-// request (controlled by the -symbol_query flag). +-func BenchmarkWorkspaceSymbols(b *testing.B) { +- for name := range repos { +- b.Run(name, func(b *testing.B) { +- env := getRepo(b, name).sharedEnv(b) +- symbols := env.Symbol(*symbolQuery) // warm the cache - -- "golang.org/x/tools/go/packages/packagestest" --) +- if testing.Verbose() { +- fmt.Println("Results:") +- for i, symbol := range symbols { +- fmt.Printf("\t%d. %s (%s)\n", i, symbol.Name, symbol.ContainerName) +- } +- } - --type Normalizer struct { -- path string -- slashed string -- escaped string -- fragment string --} +- b.ResetTimer() - --func CollectNormalizers(exported *packagestest.Exported) []Normalizer { -- // build the path normalizing patterns -- var normalizers []Normalizer -- for _, m := range exported.Modules { -- for fragment := range m.Files { -- n := Normalizer{ -- path: exported.File(m.Name, fragment), -- fragment: fragment, +- if stopAndRecord := startProfileIfSupported(b, env, qualifiedName(name, "workspaceSymbols")); stopAndRecord != nil { +- defer stopAndRecord() - } -- if n.slashed = filepath.ToSlash(n.path); n.slashed == n.path { -- n.slashed = "" -- } -- quoted := strconv.Quote(n.path) -- if n.escaped = quoted[1 : len(quoted)-1]; n.escaped == n.path { -- n.escaped = "" -- } -- normalizers = append(normalizers, n) -- } -- } -- return normalizers --} - --// Normalize replaces all paths present in s with just the fragment portion --// this is used to make golden files not depend on the temporary paths of the files --func Normalize(s string, normalizers []Normalizer) string { -- type entry struct { -- path string -- index int -- fragment string -- } -- var match []entry -- // collect the initial state of all the matchers -- for _, n := range normalizers { -- index := strings.Index(s, n.path) -- if index >= 0 { -- match = append(match, entry{n.path, index, n.fragment}) -- } -- if n.slashed != "" { -- index := strings.Index(s, n.slashed) -- if index >= 0 { -- match = append(match, entry{n.slashed, index, n.fragment}) -- } -- } -- if n.escaped != "" { -- index := strings.Index(s, n.escaped) -- if index >= 0 { -- match = append(match, entry{n.escaped, index, n.fragment}) +- for i := 0; i < b.N; i++ { +- env.Symbol(*symbolQuery) - } -- } +- }) - } -- // result should be the same or shorter than the input -- var b strings.Builder -- last := 0 -- for { -- // find the nearest path match to the start of the buffer -- next := -1 -- nearest := len(s) -- for i, c := range match { -- if c.index >= 0 && nearest > c.index { -- nearest = c.index -- next = i -- } -- } -- // if there are no matches, we copy the rest of the string and are done -- if next < 0 { -- b.WriteString(s[last:]) -- return b.String() -- } -- // we have a match -- n := &match[next] -- // copy up to the start of the match -- b.WriteString(s[last:n.index]) -- // skip over the filename -- last = n.index + len(n.path) +-} +diff -urN a/gopls/internal/regtest/codelens/codelens_test.go b/gopls/internal/regtest/codelens/codelens_test.go +--- a/gopls/internal/regtest/codelens/codelens_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/codelens/codelens_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,348 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- // Hack: In multi-module mode, we add a "testmodule/" prefix, so trim -- // it from the fragment. -- fragment := n.fragment -- if strings.HasPrefix(fragment, "testmodule") { -- split := strings.Split(filepath.ToSlash(fragment), "/") -- fragment = filepath.FromSlash(strings.Join(split[1:], "/")) -- } +-package codelens - -- // add in the fragment instead -- b.WriteString(fragment) -- // see what the next match for this path is -- n.index = strings.Index(s[last:], n.path) -- if n.index >= 0 { -- n.index += last -- } -- } --} -diff -urN a/gopls/internal/lsp/tests/README.md b/gopls/internal/lsp/tests/README.md ---- a/gopls/internal/lsp/tests/README.md 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/README.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,66 +0,0 @@ --# Testing +-import ( +- "fmt" +- "testing" - --LSP has "marker tests" defined in `internal/lsp/testdata`, as well as --traditional tests. +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" - --## Marker tests +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/internal/testenv" +-) - --Marker tests have a standard input file, like --`internal/lsp/testdata/foo/bar.go`, and some may have a corresponding golden --file, like `internal/lsp/testdata/foo/bar.go.golden`. The former is the "input" --and the latter is the expected output. +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- Main(m, hooks.Options) +-} - --Each input file contains annotations like --`//@suggestedfix("}", "refactor.rewrite", "Fill anonymous struct")`. These annotations are interpreted by --test runners to perform certain actions. The expected output after those actions --is encoded in the golden file. +-func TestDisablingCodeLens(t *testing.T) { +- const workspace = ` +--- go.mod -- +-module codelens.test - --When tests are run, each annotation results in a new subtest, which is encoded --in the golden file with a heading like, +-go 1.12 +--- lib.go -- +-package lib - --```bash ---- suggestedfix_bar_11_21 -- --// expected contents go here ---- suggestedfix_bar_13_20 -- --// expected contents go here --``` +-type Number int - --The format of these headings vary: they are defined by the --[`Golden`](https://pkg.go.dev/golang.org/x/tools/gopls/internal/lsp/tests#Data.Golden) --function for each annotation. In the case above, the format is: annotation --name, file name, annotation line location, annotation character location. +-const ( +- Zero Number = iota +- One +- Two +-) - --So, if `internal/lsp/testdata/foo/bar.go` has three `suggestedfix` annotations, --the golden file should have three headers with `suggestedfix_bar_xx_yy` --headings. +-//` + `go:generate stringer -type=Number +-` +- tests := []struct { +- label string +- enabled map[string]bool +- wantCodeLens bool +- }{ +- { +- label: "default", +- wantCodeLens: true, +- }, +- { +- label: "generate disabled", +- enabled: map[string]bool{string(command.Generate): false}, +- wantCodeLens: false, +- }, +- } +- for _, test := range tests { +- t.Run(test.label, func(t *testing.T) { +- WithOptions( +- Settings{"codelenses": test.enabled}, +- ).Run(t, workspace, func(t *testing.T, env *Env) { +- env.OpenFile("lib.go") +- lens := env.CodeLens("lib.go") +- if gotCodeLens := len(lens) > 0; gotCodeLens != test.wantCodeLens { +- t.Errorf("got codeLens: %t, want %t", gotCodeLens, test.wantCodeLens) +- } +- }) +- }) +- } +-} - --To see a list of all available annotations, see the exported "expectations" in --[tests.go](https://github.com/golang/tools/blob/299f270db45902e93469b1152fafed034bb3f033/internal/lsp/tests/tests.go#L418-L447). +-// This test confirms the full functionality of the code lenses for updating +-// dependencies in a go.mod file. It checks for the code lens that suggests +-// an update and then executes the command associated with that code lens. A +-// regression test for golang/go#39446. It also checks that these code lenses +-// only affect the diagnostics and contents of the containing go.mod file. +-func TestUpgradeCodelens(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // uses go.work - --To run marker tests, +- const proxyWithLatest = ` +--- golang.org/x/hello@v1.3.3/go.mod -- +-module golang.org/x/hello - --```bash --cd /path/to/tools +-go 1.12 +--- golang.org/x/hello@v1.3.3/hi/hi.go -- +-package hi - --# The marker tests are located in "internal/lsp", "internal/lsp/cmd, and --# "internal/lsp/source". --go test ./internal/lsp/... --``` +-var Goodbye error +--- golang.org/x/hello@v1.2.3/go.mod -- +-module golang.org/x/hello - --There are quite a lot of marker tests, so to run one individually, pass the test --path and heading into a -run argument: +-go 1.12 +--- golang.org/x/hello@v1.2.3/hi/hi.go -- +-package hi - --```bash --cd /path/to/tools --go test ./internal/lsp/... -v -run TestLSP/Modules/SuggestedFix/bar_11_21 --``` +-var Goodbye error +-` - --## Resetting marker tests +- const shouldUpdateDep = ` +--- go.work -- +-go 1.18 - --Sometimes, a change is made to lsp that requires a change to multiple golden --files. When this happens, you can run, +-use ( +- ./a +- ./b +-) +--- a/go.mod -- +-module mod.com/a - --```bash --cd /path/to/tools --./internal/lsp/reset_golden.sh --``` -diff -urN a/gopls/internal/lsp/tests/tests.go b/gopls/internal/lsp/tests/tests.go ---- a/gopls/internal/lsp/tests/tests.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/tests.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1446 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-go 1.14 - --// Package tests exports functionality to be used across a variety of gopls tests. --package tests +-require golang.org/x/hello v1.2.3 +--- a/go.sum -- +-golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= +-golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= +--- a/main.go -- +-package main - --import ( -- "bytes" -- "context" -- "flag" -- "fmt" -- "go/ast" -- "go/token" -- "io" -- "io/ioutil" -- "os" -- "path/filepath" -- "regexp" -- "sort" -- "strconv" -- "strings" -- "sync" -- "testing" -- "time" +-import "golang.org/x/hello/hi" - -- "golang.org/x/tools/go/expect" -- "golang.org/x/tools/go/packages" -- "golang.org/x/tools/go/packages/packagestest" -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/safetoken" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/source/completion" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/testenv" -- "golang.org/x/tools/internal/typeparams" -- "golang.org/x/tools/txtar" --) +-func main() { +- _ = hi.Goodbye +-} +--- b/go.mod -- +-module mod.com/b - --const ( -- overlayFileSuffix = ".overlay" -- goldenFileSuffix = ".golden" -- inFileSuffix = ".in" +-go 1.14 - -- // The module path containing the testdata packages. -- // -- // Warning: the length of this module path matters, as we have bumped up -- // against command-line limitations on windows (golang/go#54800). -- testModule = "golang.org/lsptests" --) +-require golang.org/x/hello v1.2.3 +--- b/go.sum -- +-golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= +-golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= +--- b/main.go -- +-package main - --var summaryFile = "summary.txt" +-import ( +- "golang.org/x/hello/hi" +-) - --func init() { -- if typeparams.Enabled { -- summaryFile = "summary_go1.18.txt" -- } +-func main() { +- _ = hi.Goodbye -} +-` - --var UpdateGolden = flag.Bool("golden", false, "Update golden files") -- --// These type names apparently avoid the need to repeat the --// type in the field name and the make() expression. --type CallHierarchy = map[span.Span]*CallHierarchyResult --type CodeLens = map[span.URI][]protocol.CodeLens --type Diagnostics = map[span.URI][]*source.Diagnostic --type CompletionItems = map[token.Pos]*completion.CompletionItem --type Completions = map[span.Span][]Completion --type CompletionSnippets = map[span.Span][]CompletionSnippet --type UnimportedCompletions = map[span.Span][]Completion --type DeepCompletions = map[span.Span][]Completion --type FuzzyCompletions = map[span.Span][]Completion --type CaseSensitiveCompletions = map[span.Span][]Completion --type RankCompletions = map[span.Span][]Completion --type FoldingRanges = []span.Span --type Formats = []span.Span --type Imports = []span.Span --type SemanticTokens = []span.Span --type SuggestedFixes = map[span.Span][]SuggestedFix --type FunctionExtractions = map[span.Span]span.Span --type MethodExtractions = map[span.Span]span.Span --type Definitions = map[span.Span]Definition --type Implementations = map[span.Span][]span.Span --type Highlights = map[span.Span][]span.Span --type References = map[span.Span][]span.Span --type Renames = map[span.Span]string --type PrepareRenames = map[span.Span]*source.PrepareItem --type Symbols = map[span.URI][]*symbol --type InlayHints = []span.Span --type WorkspaceSymbols = map[WorkspaceSymbolsTestType]map[span.URI][]string --type Signatures = map[span.Span]*protocol.SignatureHelp --type Links = map[span.URI][]Link --type AddImport = map[span.URI]string --type SelectionRanges = []span.Span +- const wantGoModA = `module mod.com/a - --type Data struct { -- Config packages.Config -- Exported *packagestest.Exported -- CallHierarchy CallHierarchy -- CodeLens CodeLens -- Diagnostics Diagnostics -- CompletionItems CompletionItems -- Completions Completions -- CompletionSnippets CompletionSnippets -- UnimportedCompletions UnimportedCompletions -- DeepCompletions DeepCompletions -- FuzzyCompletions FuzzyCompletions -- CaseSensitiveCompletions CaseSensitiveCompletions -- RankCompletions RankCompletions -- FoldingRanges FoldingRanges -- Formats Formats -- Imports Imports -- SemanticTokens SemanticTokens -- SuggestedFixes SuggestedFixes -- FunctionExtractions FunctionExtractions -- MethodExtractions MethodExtractions -- Definitions Definitions -- Implementations Implementations -- Highlights Highlights -- References References -- Renames Renames -- InlayHints InlayHints -- PrepareRenames PrepareRenames -- Symbols Symbols -- WorkspaceSymbols WorkspaceSymbols -- Signatures Signatures -- Links Links -- AddImport AddImport -- SelectionRanges SelectionRanges +-go 1.14 - -- fragments map[string]string -- dir string -- golden map[string]*Golden -- mode string +-require golang.org/x/hello v1.3.3 +-` +- // Applying the diagnostics or running the codelenses for a/go.mod +- // should not change the contents of b/go.mod +- const wantGoModB = `module mod.com/b - -- ModfileFlagAvailable bool +-go 1.14 - -- mappersMu sync.Mutex -- mappers map[span.URI]*protocol.Mapper --} +-require golang.org/x/hello v1.2.3 +-` - --// The Tests interface abstracts the LSP-based implementation of the marker --// test operators (such as @codelens) appearing in files beneath ../testdata/. --// --// TODO(adonovan): reduce duplication; see https://github.com/golang/go/issues/54845. --// There is only one implementation (*runner in ../lsp_test.go), so --// we can abolish the interface now. --type Tests interface { -- CallHierarchy(*testing.T, span.Span, *CallHierarchyResult) -- CodeLens(*testing.T, span.URI, []protocol.CodeLens) -- Diagnostics(*testing.T, span.URI, []*source.Diagnostic) -- Completion(*testing.T, span.Span, Completion, CompletionItems) -- CompletionSnippet(*testing.T, span.Span, CompletionSnippet, bool, CompletionItems) -- UnimportedCompletion(*testing.T, span.Span, Completion, CompletionItems) -- DeepCompletion(*testing.T, span.Span, Completion, CompletionItems) -- FuzzyCompletion(*testing.T, span.Span, Completion, CompletionItems) -- CaseSensitiveCompletion(*testing.T, span.Span, Completion, CompletionItems) -- RankCompletion(*testing.T, span.Span, Completion, CompletionItems) -- FoldingRanges(*testing.T, span.Span) -- Format(*testing.T, span.Span) -- Import(*testing.T, span.Span) -- SemanticTokens(*testing.T, span.Span) -- SuggestedFix(*testing.T, span.Span, []SuggestedFix, int) -- FunctionExtraction(*testing.T, span.Span, span.Span) -- MethodExtraction(*testing.T, span.Span, span.Span) -- Definition(*testing.T, span.Span, Definition) -- Implementation(*testing.T, span.Span, []span.Span) -- Highlight(*testing.T, span.Span, []span.Span) -- InlayHints(*testing.T, span.Span) -- References(*testing.T, span.Span, []span.Span) -- Rename(*testing.T, span.Span, string) -- PrepareRename(*testing.T, span.Span, *source.PrepareItem) -- Symbols(*testing.T, span.URI, []protocol.DocumentSymbol) -- WorkspaceSymbols(*testing.T, span.URI, string, WorkspaceSymbolsTestType) -- SignatureHelp(*testing.T, span.Span, *protocol.SignatureHelp) -- Link(*testing.T, span.URI, []Link) -- AddImport(*testing.T, span.URI, string) -- SelectionRanges(*testing.T, span.Span) --} +- for _, commandTitle := range []string{ +- "Upgrade transitive dependencies", +- "Upgrade direct dependencies", +- } { +- t.Run(commandTitle, func(t *testing.T) { +- WithOptions( +- ProxyFiles(proxyWithLatest), +- ).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { +- env.OpenFile("a/go.mod") +- env.OpenFile("b/go.mod") +- var lens protocol.CodeLens +- var found bool +- for _, l := range env.CodeLens("a/go.mod") { +- if l.Command.Title == commandTitle { +- lens = l +- found = true +- } +- } +- if !found { +- t.Fatalf("found no command with the title %s", commandTitle) +- } +- if _, err := env.Editor.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{ +- Command: lens.Command.Command, +- Arguments: lens.Command.Arguments, +- }); err != nil { +- t.Fatal(err) +- } +- env.AfterChange() +- if got := env.BufferText("a/go.mod"); got != wantGoModA { +- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) +- } +- if got := env.BufferText("b/go.mod"); got != wantGoModB { +- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) +- } +- }) +- }) +- } +- for _, vendoring := range []bool{false, true} { +- t.Run(fmt.Sprintf("Upgrade individual dependency vendoring=%v", vendoring), func(t *testing.T) { +- WithOptions( +- ProxyFiles(proxyWithLatest), +- ).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { +- if vendoring { +- env.RunGoCommandInDirWithEnv("a", []string{"GOWORK=off"}, "mod", "vendor") +- } +- env.AfterChange() +- env.OpenFile("a/go.mod") +- env.OpenFile("b/go.mod") - --type Definition struct { -- Name string -- IsType bool -- OnlyHover bool -- Src, Def span.Span --} +- // Await the diagnostics resulting from opening the modfiles, because +- // otherwise they may cause races when running asynchronously to the +- // explicit re-diagnosing below. +- // +- // TODO(golang/go#58750): there is still a race here, inherent to +- // accessing state on the View; we should create a new snapshot when +- // the view diagnostics change. +- env.AfterChange() - --type CompletionTestType int +- env.ExecuteCodeLensCommand("a/go.mod", command.CheckUpgrades, nil) +- d := &protocol.PublishDiagnosticsParams{} +- env.OnceMet( +- Diagnostics(env.AtRegexp("a/go.mod", `require`), WithMessage("can be upgraded")), +- ReadDiagnostics("a/go.mod", d), +- // We do not want there to be a diagnostic for b/go.mod, +- // but there may be some subtlety in timing here, where this +- // should always succeed, but may not actually test the correct +- // behavior. +- NoDiagnostics(env.AtRegexp("b/go.mod", `require`)), +- ) +- // Check for upgrades in b/go.mod and then clear them. +- env.ExecuteCodeLensCommand("b/go.mod", command.CheckUpgrades, nil) +- env.Await(Diagnostics(env.AtRegexp("b/go.mod", `require`), WithMessage("can be upgraded"))) +- env.ExecuteCodeLensCommand("b/go.mod", command.ResetGoModDiagnostics, nil) +- env.Await(NoDiagnostics(ForFile("b/go.mod"))) - --const ( -- // Default runs the standard completion tests. -- CompletionDefault = CompletionTestType(iota) +- // Apply the diagnostics to a/go.mod. +- env.ApplyQuickFixes("a/go.mod", d.Diagnostics) +- env.AfterChange() +- if got := env.BufferText("a/go.mod"); got != wantGoModA { +- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) +- } +- if got := env.BufferText("b/go.mod"); got != wantGoModB { +- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) +- } +- }) +- }) +- } +-} - -- // Unimported tests the autocompletion of unimported packages. -- CompletionUnimported +-func TestUnusedDependenciesCodelens(t *testing.T) { +- const proxy = ` +--- golang.org/x/hello@v1.0.0/go.mod -- +-module golang.org/x/hello - -- // Deep tests deep completion. -- CompletionDeep +-go 1.14 +--- golang.org/x/hello@v1.0.0/hi/hi.go -- +-package hi - -- // Fuzzy tests deep completion and fuzzy matching. -- CompletionFuzzy +-var Goodbye error +--- golang.org/x/unused@v1.0.0/go.mod -- +-module golang.org/x/unused - -- // CaseSensitive tests case sensitive completion. -- CompletionCaseSensitive +-go 1.14 +--- golang.org/x/unused@v1.0.0/nouse/nouse.go -- +-package nouse - -- // CompletionRank candidates in test must be valid and in the right relative order. -- CompletionRank --) +-var NotUsed error +-` - --type WorkspaceSymbolsTestType int +- const shouldRemoveDep = ` +--- go.mod -- +-module mod.com - --const ( -- // Default runs the standard workspace symbols tests. -- WorkspaceSymbolsDefault = WorkspaceSymbolsTestType(iota) +-go 1.14 - -- // Fuzzy tests workspace symbols with fuzzy matching. -- WorkspaceSymbolsFuzzy +-require golang.org/x/hello v1.0.0 +-require golang.org/x/unused v1.0.0 +--- go.sum -- +-golang.org/x/hello v1.0.0 h1:qbzE1/qT0/zojAMd/JcPsO2Vb9K4Bkeyq0vB2JGMmsw= +-golang.org/x/hello v1.0.0/go.mod h1:WW7ER2MRNXWA6c8/4bDIek4Hc/+DofTrMaQQitGXcco= +-golang.org/x/unused v1.0.0 h1:LecSbCn5P3vTcxubungSt1Pn4D/WocCaiWOPDC0y0rw= +-golang.org/x/unused v1.0.0/go.mod h1:ihoW8SgWzugwwj0N2SfLfPZCxTB1QOVfhMfB5PWTQ8U= +--- main.go -- +-package main - -- // CaseSensitive tests workspace symbols with case sensitive. -- WorkspaceSymbolsCaseSensitive --) +-import "golang.org/x/hello/hi" - --type Completion struct { -- CompletionItems []token.Pos +-func main() { +- _ = hi.Goodbye -} +-` +- WithOptions(ProxyFiles(proxy)).Run(t, shouldRemoveDep, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.ExecuteCodeLensCommand("go.mod", command.Tidy, nil) +- env.Await(env.DoneWithChangeWatchedFiles()) +- got := env.BufferText("go.mod") +- const wantGoMod = `module mod.com - --type CompletionSnippet struct { -- CompletionItem token.Pos -- PlainSnippet string -- PlaceholderSnippet string --} +-go 1.14 - --type CallHierarchyResult struct { -- IncomingCalls, OutgoingCalls []protocol.CallHierarchyItem +-require golang.org/x/hello v1.0.0 +-` +- if got != wantGoMod { +- t.Fatalf("go.mod tidy failed:\n%s", compare.Text(wantGoMod, got)) +- } +- }) -} - --type Link struct { -- Src span.Span -- Target string -- NotePosition token.Position --} +-func TestRegenerateCgo(t *testing.T) { +- testenv.NeedsTool(t, "cgo") +- const workspace = ` +--- go.mod -- +-module example.com - --type SuggestedFix struct { -- ActionKind, Title string --} +-go 1.12 +--- cgo.go -- +-package x - --// A symbol holds a DocumentSymbol along with its parent-child edge. --type symbol struct { -- pSymbol protocol.DocumentSymbol -- id, parentID string --} +-/* +-int fortythree() { return 42; } +-*/ +-import "C" - --type Golden struct { -- Filename string -- Archive *txtar.Archive -- Modified bool +-func Foo() { +- print(C.fortytwo()) -} +-` +- Run(t, workspace, func(t *testing.T, env *Env) { +- // Open the file. We have a nonexistant symbol that will break cgo processing. +- env.OpenFile("cgo.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), +- ) - --func Context(t testing.TB) context.Context { -- return context.Background() --} +- // Fix the C function name. We haven't regenerated cgo, so nothing should be fixed. +- env.RegexpReplace("cgo.go", `int fortythree`, "int fortytwo") +- env.SaveBuffer("cgo.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), +- ) - --func DefaultOptions(o *source.Options) { -- o.SupportedCodeActions = map[source.FileKind]map[protocol.CodeActionKind]bool{ -- source.Go: { -- protocol.SourceOrganizeImports: true, -- protocol.QuickFix: true, -- protocol.RefactorRewrite: true, -- protocol.RefactorExtract: true, -- protocol.SourceFixAll: true, -- }, -- source.Mod: { -- protocol.SourceOrganizeImports: true, -- }, -- source.Sum: {}, -- source.Work: {}, -- source.Tmpl: {}, -- } -- o.UserOptions.Codelenses[string(command.Test)] = true -- o.HoverKind = source.SynopsisDocumentation -- o.InsertTextFormat = protocol.SnippetTextFormat -- o.CompletionBudget = time.Minute -- o.HierarchicalDocumentSymbolSupport = true -- o.SemanticTokens = true -- o.InternalOptions.NewDiff = "both" +- // Regenerate cgo, fixing the diagnostic. +- env.ExecuteCodeLensCommand("cgo.go", command.RegenerateCgo, nil) +- env.Await(NoDiagnostics(ForFile("cgo.go"))) +- }) -} +diff -urN a/gopls/internal/regtest/codelens/gcdetails_test.go b/gopls/internal/regtest/codelens/gcdetails_test.go +--- a/gopls/internal/regtest/codelens/gcdetails_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/codelens/gcdetails_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,127 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func RunTests(t *testing.T, dataDir string, includeMultiModule bool, f func(*testing.T, *Data)) { -- t.Helper() -- modes := []string{"Modules", "GOPATH"} -- if includeMultiModule { -- modes = append(modes, "MultiModule") -- } -- for _, mode := range modes { -- t.Run(mode, func(t *testing.T) { -- datum := load(t, mode, dataDir) -- t.Helper() -- f(t, datum) -- }) -- } --} +-package codelens - --func load(t testing.TB, mode string, dir string) *Data { -- datum := &Data{ -- CallHierarchy: make(CallHierarchy), -- CodeLens: make(CodeLens), -- Diagnostics: make(Diagnostics), -- CompletionItems: make(CompletionItems), -- Completions: make(Completions), -- CompletionSnippets: make(CompletionSnippets), -- UnimportedCompletions: make(UnimportedCompletions), -- DeepCompletions: make(DeepCompletions), -- FuzzyCompletions: make(FuzzyCompletions), -- RankCompletions: make(RankCompletions), -- CaseSensitiveCompletions: make(CaseSensitiveCompletions), -- Definitions: make(Definitions), -- Implementations: make(Implementations), -- Highlights: make(Highlights), -- References: make(References), -- Renames: make(Renames), -- PrepareRenames: make(PrepareRenames), -- SuggestedFixes: make(SuggestedFixes), -- FunctionExtractions: make(FunctionExtractions), -- MethodExtractions: make(MethodExtractions), -- Symbols: make(Symbols), -- WorkspaceSymbols: make(WorkspaceSymbols), -- Signatures: make(Signatures), -- Links: make(Links), -- AddImport: make(AddImport), +-import ( +- "runtime" +- "strings" +- "testing" - -- dir: dir, -- fragments: map[string]string{}, -- golden: map[string]*Golden{}, -- mode: mode, -- mappers: map[span.URI]*protocol.Mapper{}, -- } +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - -- if !*UpdateGolden { -- summary := filepath.Join(filepath.FromSlash(dir), summaryFile+goldenFileSuffix) -- if _, err := os.Stat(summary); os.IsNotExist(err) { -- t.Fatalf("could not find golden file summary.txt in %#v", dir) -- } -- archive, err := txtar.ParseFile(summary) -- if err != nil { -- t.Fatalf("could not read golden file %v/%v: %v", dir, summary, err) -- } -- datum.golden[summaryFile] = &Golden{ -- Filename: summary, -- Archive: archive, -- } +-func TestGCDetails_Toggle(t *testing.T) { +- if runtime.GOOS == "android" { +- t.Skipf("the gc details code lens doesn't work on Android") - } - -- files := packagestest.MustCopyFileTree(dir) -- // Prune test cases that exercise generics. -- if !typeparams.Enabled { -- for name := range files { -- if strings.Contains(name, "_generics") { -- delete(files, name) -- } -- } -- } -- overlays := map[string][]byte{} -- for fragment, operation := range files { -- if trimmed := strings.TrimSuffix(fragment, goldenFileSuffix); trimmed != fragment { -- delete(files, fragment) -- goldFile := filepath.Join(dir, fragment) -- archive, err := txtar.ParseFile(goldFile) -- if err != nil { -- t.Fatalf("could not read golden file %v: %v", fragment, err) -- } -- datum.golden[trimmed] = &Golden{ -- Filename: goldFile, -- Archive: archive, -- } -- } else if trimmed := strings.TrimSuffix(fragment, inFileSuffix); trimmed != fragment { -- delete(files, fragment) -- files[trimmed] = operation -- } else if index := strings.Index(fragment, overlayFileSuffix); index >= 0 { -- delete(files, fragment) -- partial := fragment[:index] + fragment[index+len(overlayFileSuffix):] -- contents, err := ioutil.ReadFile(filepath.Join(dir, fragment)) -- if err != nil { -- t.Fatal(err) -- } -- overlays[partial] = contents -- } -- } +- const mod = ` +--- go.mod -- +-module mod.com - -- modules := []packagestest.Module{ -- { -- Name: testModule, -- Files: files, -- Overlay: overlays, +-go 1.15 +--- main.go -- +-package main +- +-import "fmt" +- +-func main() { +- fmt.Println(42) +-} +-` +- WithOptions( +- Settings{ +- "codelenses": map[string]bool{ +- "gc_details": true, +- }, - }, -- } -- switch mode { -- case "Modules": -- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) -- case "GOPATH": -- datum.Exported = packagestest.Export(t, packagestest.GOPATH, modules) -- case "MultiModule": -- files := map[string]interface{}{} -- for k, v := range modules[0].Files { -- files[filepath.Join("testmodule", k)] = v +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) +- d := &protocol.PublishDiagnosticsParams{} +- env.OnceMet( +- Diagnostics(AtPosition("main.go", 5, 13)), +- ReadDiagnostics("main.go", d), +- ) +- // Confirm that the diagnostics come from the gc details code lens. +- var found bool +- for _, d := range d.Diagnostics { +- if d.Severity != protocol.SeverityInformation { +- t.Fatalf("unexpected diagnostic severity %v, wanted Information", d.Severity) +- } +- if strings.Contains(d.Message, "42 escapes") { +- found = true +- } - } -- modules[0].Files = files -- -- overlays := map[string][]byte{} -- for k, v := range modules[0].Overlay { -- overlays[filepath.Join("testmodule", k)] = v +- if !found { +- t.Fatalf(`expected to find diagnostic with message "escape(42 escapes to heap)", found none`) - } -- modules[0].Overlay = overlays - -- golden := map[string]*Golden{} -- for k, v := range datum.golden { -- if k == summaryFile { -- golden[k] = v -- } else { -- golden[filepath.Join("testmodule", k)] = v -- } -- } -- datum.golden = golden +- // Editing a buffer should cause gc_details diagnostics to disappear, since +- // they only apply to saved buffers. +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, "\n\n")) +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) - -- datum.Exported = packagestest.Export(t, packagestest.Modules, modules) -- default: -- panic("unknown mode " + mode) -- } +- // Saving a buffer should re-format back to the original state, and +- // re-enable the gc_details diagnostics. +- env.SaveBuffer("main.go") +- env.AfterChange(Diagnostics(AtPosition("main.go", 5, 13))) - -- for _, m := range modules { -- for fragment := range m.Files { -- filename := datum.Exported.File(m.Name, fragment) -- datum.fragments[filename] = fragment -- } -- } +- // Toggle the GC details code lens again so now it should be off. +- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) +- env.Await(NoDiagnostics(ForFile("main.go"))) +- }) +-} - -- // Turn off go/packages debug logging. -- datum.Exported.Config.Logf = nil -- datum.Config.Logf = nil +-// Test for the crasher in golang/go#54199 +-func TestGCDetails_NewFile(t *testing.T) { +- bug.PanicOnBugs = false +- const src = ` +--- go.mod -- +-module mod.test - -- // Merge the exported.Config with the view.Config. -- datum.Config = *datum.Exported.Config -- datum.Config.Fset = token.NewFileSet() -- datum.Config.Context = Context(nil) -- datum.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { -- panic("ParseFile should not be called") -- } +-go 1.12 +-` - -- // Do a first pass to collect special markers for completion and workspace symbols. -- if err := datum.Exported.Expect(map[string]interface{}{ -- "item": func(name string, r packagestest.Range, _ []string) { -- datum.Exported.Mark(name, r) -- }, -- "symbol": func(name string, r packagestest.Range, _ []string) { -- datum.Exported.Mark(name, r) +- WithOptions( +- Settings{ +- "codelenses": map[string]bool{ +- "gc_details": true, +- }, - }, -- }); err != nil { -- t.Fatal(err) -- } +- ).Run(t, src, func(t *testing.T, env *Env) { +- env.CreateBuffer("p_test.go", "") - -- // Collect any data that needs to be used by subsequent tests. -- if err := datum.Exported.Expect(map[string]interface{}{ -- "codelens": datum.collectCodeLens, -- "diag": datum.collectDiagnostics, -- "item": datum.collectCompletionItems, -- "complete": datum.collectCompletions(CompletionDefault), -- "unimported": datum.collectCompletions(CompletionUnimported), -- "deep": datum.collectCompletions(CompletionDeep), -- "fuzzy": datum.collectCompletions(CompletionFuzzy), -- "casesensitive": datum.collectCompletions(CompletionCaseSensitive), -- "rank": datum.collectCompletions(CompletionRank), -- "snippet": datum.collectCompletionSnippets, -- "fold": datum.collectFoldingRanges, -- "format": datum.collectFormats, -- "import": datum.collectImports, -- "semantic": datum.collectSemanticTokens, -- "godef": datum.collectDefinitions, -- "implementations": datum.collectImplementations, -- "typdef": datum.collectTypeDefinitions, -- "hoverdef": datum.collectHoverDefinitions, -- "highlight": datum.collectHighlights, -- "inlayHint": datum.collectInlayHints, -- "refs": datum.collectReferences, -- "rename": datum.collectRenames, -- "prepare": datum.collectPrepareRenames, -- "symbol": datum.collectSymbols, -- "signature": datum.collectSignatures, -- "link": datum.collectLinks, -- "suggestedfix": datum.collectSuggestedFixes, -- "extractfunc": datum.collectFunctionExtractions, -- "extractmethod": datum.collectMethodExtractions, -- "incomingcalls": datum.collectIncomingCalls, -- "outgoingcalls": datum.collectOutgoingCalls, -- "addimport": datum.collectAddImports, -- "selectionrange": datum.collectSelectionRanges, -- }); err != nil { -- t.Fatal(err) -- } +- const gcDetailsCommand = "gopls." + string(command.GCDetails) - -- // Collect names for the entries that require golden files. -- if err := datum.Exported.Expect(map[string]interface{}{ -- "godef": datum.collectDefinitionNames, -- "hoverdef": datum.collectDefinitionNames, -- "workspacesymbol": datum.collectWorkspaceSymbols(WorkspaceSymbolsDefault), -- "workspacesymbolfuzzy": datum.collectWorkspaceSymbols(WorkspaceSymbolsFuzzy), -- "workspacesymbolcasesensitive": datum.collectWorkspaceSymbols(WorkspaceSymbolsCaseSensitive), -- }); err != nil { -- t.Fatal(err) -- } -- if mode == "MultiModule" { -- if err := moveFile(filepath.Join(datum.Config.Dir, "go.mod"), filepath.Join(datum.Config.Dir, "testmodule/go.mod")); err != nil { -- t.Fatal(err) +- hasGCDetails := func() bool { +- lenses := env.CodeLens("p_test.go") // should not crash +- for _, lens := range lenses { +- if lens.Command.Command == gcDetailsCommand { +- return true +- } +- } +- return false - } -- } - -- return datum --} +- // With an empty file, we shouldn't get the gc_details codelens because +- // there is nowhere to position it (it needs a package name). +- if hasGCDetails() { +- t.Errorf("got the gc_details codelens for an empty file") +- } - --// moveFile moves the file at oldpath to newpath, by renaming if possible --// or copying otherwise. --func moveFile(oldpath, newpath string) (err error) { -- renameErr := os.Rename(oldpath, newpath) -- if renameErr == nil { -- return nil -- } +- // Edit to provide a package name. +- env.EditBuffer("p_test.go", fake.NewEdit(0, 0, 0, 0, "package p")) - -- src, err := os.Open(oldpath) -- if err != nil { -- return err -- } -- defer func() { -- src.Close() -- if err == nil { -- err = os.Remove(oldpath) +- // Now we should get the gc_details codelens. +- if !hasGCDetails() { +- t.Errorf("didn't get the gc_details codelens for a valid non-empty Go file") - } -- }() +- }) +-} +diff -urN a/gopls/internal/regtest/completion/completion18_test.go b/gopls/internal/regtest/completion/completion18_test.go +--- a/gopls/internal/regtest/completion/completion18_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/completion/completion18_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,124 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- perm := os.ModePerm -- fi, err := src.Stat() -- if err == nil { -- perm = fi.Mode().Perm() -- } +-//go:build go1.18 +-// +build go1.18 - -- dst, err := os.OpenFile(newpath, os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) -- if err != nil { -- return err -- } +-package completion - -- _, err = io.Copy(dst, src) -- if closeErr := dst.Close(); err == nil { -- err = closeErr -- } -- return err --} +-import ( +- "testing" - --func Run(t *testing.T, tests Tests, data *Data) { -- t.Helper() -- checkData(t, data) +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - -- eachCompletion := func(t *testing.T, cases map[span.Span][]Completion, test func(*testing.T, span.Span, Completion, CompletionItems)) { -- t.Helper() +-// test generic receivers +-func TestGenericReceiver(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- for src, exp := range cases { -- for i, e := range exp { -- t.Run(SpanName(src)+"_"+strconv.Itoa(i), func(t *testing.T) { -- t.Helper() -- if strings.Contains(t.Name(), "cgo") { -- testenv.NeedsTool(t, "cgo") -- } -- test(t, src, e, data.CompletionItems) -- }) -- } +-go 1.18 +--- main.go -- +-package main +-type SyncMap[K any, V comparable] struct {} +-func (s *SyncMap[K,V]) f() {} +-type XX[T any] struct {} +-type UU[T any] struct {} +-func (s SyncMap[XX,string]) g(v UU) {} +-` - -- } +- tests := []struct { +- pat string +- want []string +- }{ +- {"s .Syn", []string{"SyncMap[K, V]"}}, +- {"Map.X", []string{}}, // This is probably wrong, Maybe "XX"? +- {"v U", []string{"UU", "uint", "uint16", "uint32", "uint64", "uint8", "uintptr"}}, // not U[T] - } -- -- t.Run("CallHierarchy", func(t *testing.T) { -- t.Helper() -- for spn, callHierarchyResult := range data.CallHierarchy { -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- tests.CallHierarchy(t, spn, callHierarchyResult) -- }) +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- for _, tst := range tests { +- loc := env.RegexpSearch("main.go", tst.pat) +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(tst.pat))) +- completions := env.Completion(loc) +- result := compareCompletionLabels(tst.want, completions.Items) +- if result != "" { +- t.Errorf("%s: wanted %v", result, tst.want) +- for i, g := range completions.Items { +- t.Errorf("got %d %s %s", i, g.Label, g.Detail) +- } +- } - } - }) +-} +-func TestFuzzFunc(t *testing.T) { +- // use the example from the package documentation +- modfile := ` +--- go.mod -- +-module mod.com - -- t.Run("Completion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.Completions, tests.Completion) +-go 1.18 +-` +- part0 := `package foo +-import "testing" +-func FuzzNone(f *testing.F) { +- f.Add(12) // better not find this f.Add +-} +-func FuzzHex(f *testing.F) { +- for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} { +- f.Ad` +- part1 := `d(seed) +- } +- f.F` +- part2 := `uzz(func(t *testing.T, in []byte) { +- enc := hex.EncodeToString(in) +- out, err := hex.DecodeString(enc) +- if err != nil { +- f.Failed() +- } +- if !bytes.Equal(in, out) { +- t.Fatalf("%v: round trip: %v, %s", in, out, f.Name()) +- } - }) +-} +-` +- data := modfile + `-- a_test.go -- +-` + part0 + ` +--- b_test.go -- +-` + part0 + part1 + ` +--- c_test.go -- +-` + part0 + part1 + part2 - -- t.Run("CompletionSnippets", func(t *testing.T) { -- t.Helper() -- for _, placeholders := range []bool{true, false} { -- for src, expecteds := range data.CompletionSnippets { -- for i, expected := range expecteds { -- name := SpanName(src) + "_" + strconv.Itoa(i+1) -- if placeholders { -- name += "_placeholders" -- } -- -- t.Run(name, func(t *testing.T) { -- t.Helper() -- tests.CompletionSnippet(t, src, expected, placeholders, data.CompletionItems) -- }) +- tests := []struct { +- file string +- pat string +- offset uint32 // UTF16 length from the beginning of pat to what the user just typed +- want []string +- }{ +- {"a_test.go", "f.Ad", 3, []string{"Add"}}, +- {"c_test.go", " f.F", 4, []string{"Failed"}}, +- {"c_test.go", "f.N", 3, []string{"Name"}}, +- {"b_test.go", "f.F", 3, []string{"Fuzz(func(t *testing.T, a []byte)", "Fail", "FailNow", +- "Failed", "Fatal", "Fatalf"}}, +- } +- Run(t, data, func(t *testing.T, env *Env) { +- for _, test := range tests { +- env.OpenFile(test.file) +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch(test.file, test.pat) +- loc.Range.Start.Character += test.offset // character user just typed? will type? +- completions := env.Completion(loc) +- result := compareCompletionLabels(test.want, completions.Items) +- if result != "" { +- t.Errorf("pat %q %q", test.pat, result) +- for i, it := range completions.Items { +- t.Errorf("%d got %q %q", i, it.Label, it.Detail) - } - } - } - }) +-} +diff -urN a/gopls/internal/regtest/completion/completion_test.go b/gopls/internal/regtest/completion/completion_test.go +--- a/gopls/internal/regtest/completion/completion_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/completion/completion_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,870 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- t.Run("UnimportedCompletion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.UnimportedCompletions, tests.UnimportedCompletion) -- }) +-package completion - -- t.Run("DeepCompletion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.DeepCompletions, tests.DeepCompletion) -- }) +-import ( +- "fmt" +- "strings" +- "testing" +- "time" - -- t.Run("FuzzyCompletion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.FuzzyCompletions, tests.FuzzyCompletion) -- }) +- "github.com/google/go-cmp/cmp" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/fake" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/testenv" +-) - -- t.Run("CaseSensitiveCompletion", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.CaseSensitiveCompletions, tests.CaseSensitiveCompletion) -- }) +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- Main(m, hooks.Options) +-} - -- t.Run("RankCompletions", func(t *testing.T) { -- t.Helper() -- eachCompletion(t, data.RankCompletions, tests.RankCompletion) -- }) +-const proxy = ` +--- example.com@v1.2.3/go.mod -- +-module example.com - -- t.Run("CodeLens", func(t *testing.T) { -- t.Helper() -- for uri, want := range data.CodeLens { -- // Check if we should skip this URI if the -modfile flag is not available. -- if shouldSkip(data, uri) { -- continue -- } -- t.Run(uriName(uri), func(t *testing.T) { -- t.Helper() -- tests.CodeLens(t, uri, want) -- }) -- } -- }) +-go 1.12 +--- example.com@v1.2.3/blah/blah.go -- +-package blah - -- t.Run("Diagnostics", func(t *testing.T) { -- t.Helper() -- for uri, want := range data.Diagnostics { -- // Check if we should skip this URI if the -modfile flag is not available. -- if shouldSkip(data, uri) { -- continue -- } -- t.Run(uriName(uri), func(t *testing.T) { -- t.Helper() -- tests.Diagnostics(t, uri, want) -- }) -- } -- }) +-const Name = "Blah" +--- random.org@v1.2.3/go.mod -- +-module random.org - -- t.Run("FoldingRange", func(t *testing.T) { -- t.Helper() -- for _, spn := range data.FoldingRanges { -- t.Run(uriName(spn.URI()), func(t *testing.T) { -- t.Helper() -- tests.FoldingRanges(t, spn) -- }) -- } -- }) +-go 1.12 +--- random.org@v1.2.3/blah/blah.go -- +-package hello - -- t.Run("Format", func(t *testing.T) { -- t.Helper() -- for _, spn := range data.Formats { -- t.Run(uriName(spn.URI()), func(t *testing.T) { -- t.Helper() -- tests.Format(t, spn) -- }) -- } -- }) +-const Name = "Hello" +-` - -- t.Run("Import", func(t *testing.T) { -- t.Helper() -- for _, spn := range data.Imports { -- t.Run(uriName(spn.URI()), func(t *testing.T) { -- t.Helper() -- tests.Import(t, spn) -- }) -- } -- }) +-func TestPackageCompletion(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- t.Run("SemanticTokens", func(t *testing.T) { -- t.Helper() -- for _, spn := range data.SemanticTokens { -- t.Run(uriName(spn.URI()), func(t *testing.T) { -- t.Helper() -- tests.SemanticTokens(t, spn) -- }) -- } -- }) +-go 1.12 +--- fruits/apple.go -- +-package apple - -- t.Run("SuggestedFix", func(t *testing.T) { -- t.Helper() -- for spn, actionKinds := range data.SuggestedFixes { -- // Check if we should skip this spn if the -modfile flag is not available. -- if shouldSkip(data, spn.URI()) { -- continue -- } -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- tests.SuggestedFix(t, spn, actionKinds, 1) -- }) -- } -- }) +-fun apple() int { +- return 0 +-} +- +--- fruits/testfile.go -- +-// this is a comment +- +-/* +- this is a multiline comment +-*/ +- +-import "fmt" +- +-func test() {} +- +--- fruits/testfile2.go -- +-package +- +--- fruits/testfile3.go -- +-pac +--- 123f_r.u~its-123/testfile.go -- +-package +- +--- .invalid-dir@-name/testfile.go -- +-package +-` +- var ( +- testfile4 = "" +- testfile5 = "/*a comment*/ " +- testfile6 = "/*a comment*/\n" +- ) +- for _, tc := range []struct { +- name string +- filename string +- content *string +- triggerRegexp string +- want []string +- editRegexp string +- }{ +- { +- name: "package completion at valid position", +- filename: "fruits/testfile.go", +- triggerRegexp: "\n()", +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "\n()", +- }, +- { +- name: "package completion in a comment", +- filename: "fruits/testfile.go", +- triggerRegexp: "th(i)s", +- want: nil, +- }, +- { +- name: "package completion in a multiline comment", +- filename: "fruits/testfile.go", +- triggerRegexp: `\/\*\n()`, +- want: nil, +- }, +- { +- name: "package completion at invalid position", +- filename: "fruits/testfile.go", +- triggerRegexp: "import \"fmt\"\n()", +- want: nil, +- }, +- { +- name: "package completion after keyword 'package'", +- filename: "fruits/testfile2.go", +- triggerRegexp: "package()", +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "package\n", +- }, +- { +- name: "package completion with 'pac' prefix", +- filename: "fruits/testfile3.go", +- triggerRegexp: "pac()", +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "pac", +- }, +- { +- name: "package completion for empty file", +- filename: "fruits/testfile4.go", +- triggerRegexp: "^$", +- content: &testfile4, +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: "^$", +- }, +- { +- name: "package completion without terminal newline", +- filename: "fruits/testfile5.go", +- triggerRegexp: `\*\/ ()`, +- content: &testfile5, +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: `\*\/ ()`, +- }, +- { +- name: "package completion on terminal newline", +- filename: "fruits/testfile6.go", +- triggerRegexp: `\*\/\n()`, +- content: &testfile6, +- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, +- editRegexp: `\*\/\n()`, +- }, +- // Issue golang/go#44680 +- { +- name: "package completion for dir name with punctuation", +- filename: "123f_r.u~its-123/testfile.go", +- triggerRegexp: "package()", +- want: []string{"package fruits123", "package fruits123_test", "package main"}, +- editRegexp: "package\n", +- }, +- { +- name: "package completion for invalid dir name", +- filename: ".invalid-dir@-name/testfile.go", +- triggerRegexp: "package()", +- want: []string{"package main"}, +- editRegexp: "package\n", +- }, +- } { +- t.Run(tc.name, func(t *testing.T) { +- Run(t, files, func(t *testing.T, env *Env) { +- if tc.content != nil { +- env.WriteWorkspaceFile(tc.filename, *tc.content) +- env.Await(env.DoneWithChangeWatchedFiles()) +- } +- env.OpenFile(tc.filename) +- completions := env.Completion(env.RegexpSearch(tc.filename, tc.triggerRegexp)) - -- t.Run("FunctionExtraction", func(t *testing.T) { -- t.Helper() -- for start, end := range data.FunctionExtractions { -- // Check if we should skip this spn if the -modfile flag is not available. -- if shouldSkip(data, start.URI()) { -- continue -- } -- t.Run(SpanName(start), func(t *testing.T) { -- t.Helper() -- tests.FunctionExtraction(t, start, end) -- }) -- } -- }) +- // Check that the completion item suggestions are in the range +- // of the file. {Start,End}.Line are zero-based. +- lineCount := len(strings.Split(env.BufferText(tc.filename), "\n")) +- for _, item := range completions.Items { +- if start := int(item.TextEdit.Range.Start.Line); start > lineCount { +- t.Fatalf("unexpected text edit range start line number: got %d, want <= %d", start, lineCount) +- } +- if end := int(item.TextEdit.Range.End.Line); end > lineCount { +- t.Fatalf("unexpected text edit range end line number: got %d, want <= %d", end, lineCount) +- } +- } - -- t.Run("MethodExtraction", func(t *testing.T) { -- t.Helper() -- for start, end := range data.MethodExtractions { -- // Check if we should skip this spn if the -modfile flag is not available. -- if shouldSkip(data, start.URI()) { -- continue -- } -- t.Run(SpanName(start), func(t *testing.T) { -- t.Helper() -- tests.MethodExtraction(t, start, end) -- }) -- } -- }) +- if tc.want != nil { +- expectedLoc := env.RegexpSearch(tc.filename, tc.editRegexp) +- for _, item := range completions.Items { +- gotRng := item.TextEdit.Range +- if expectedLoc.Range != gotRng { +- t.Errorf("unexpected completion range for completion item %s: got %v, want %v", +- item.Label, gotRng, expectedLoc.Range) +- } +- } +- } - -- t.Run("Definition", func(t *testing.T) { -- t.Helper() -- for spn, d := range data.Definitions { -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- if strings.Contains(t.Name(), "cgo") { -- testenv.NeedsTool(t, "cgo") +- diff := compareCompletionLabels(tc.want, completions.Items) +- if diff != "" { +- t.Error(diff) - } -- tests.Definition(t, spn, d) - }) -- } -- }) +- }) +- } +-} - -- t.Run("Implementation", func(t *testing.T) { -- t.Helper() -- for spn, m := range data.Implementations { -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- tests.Implementation(t, spn, m) -- }) -- } -- }) +-func TestPackageNameCompletion(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- t.Run("Highlight", func(t *testing.T) { -- t.Helper() -- for pos, locations := range data.Highlights { -- t.Run(SpanName(pos), func(t *testing.T) { -- t.Helper() -- tests.Highlight(t, pos, locations) -- }) -- } -- }) +-go 1.12 +--- math/add.go -- +-package ma +-` - -- t.Run("InlayHints", func(t *testing.T) { -- t.Helper() -- for _, src := range data.InlayHints { -- t.Run(SpanName(src), func(t *testing.T) { -- t.Helper() -- tests.InlayHints(t, src) -- }) -- } -- }) +- want := []string{"ma", "ma_test", "main", "math", "math_test"} +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("math/add.go") +- completions := env.Completion(env.RegexpSearch("math/add.go", "package ma()")) - -- t.Run("References", func(t *testing.T) { -- t.Helper() -- for src, itemList := range data.References { -- t.Run(SpanName(src), func(t *testing.T) { -- t.Helper() -- tests.References(t, src, itemList) -- }) +- diff := compareCompletionLabels(want, completions.Items) +- if diff != "" { +- t.Fatal(diff) - } - }) +-} - -- t.Run("Renames", func(t *testing.T) { -- t.Helper() -- for spn, newText := range data.Renames { -- t.Run(uriName(spn.URI())+"_"+newText, func(t *testing.T) { -- t.Helper() -- tests.Rename(t, spn, newText) -- }) +-// TODO(rfindley): audit/clean up call sites for this helper, to ensure +-// consistent test errors. +-func compareCompletionLabels(want []string, gotItems []protocol.CompletionItem) string { +- var got []string +- for _, item := range gotItems { +- got = append(got, item.Label) +- if item.Label != item.InsertText && item.TextEdit == nil { +- // Label should be the same as InsertText, if InsertText is to be used +- return fmt.Sprintf("label not the same as InsertText %#v", item) - } -- }) +- } - -- t.Run("PrepareRenames", func(t *testing.T) { -- t.Helper() -- for src, want := range data.PrepareRenames { -- t.Run(SpanName(src), func(t *testing.T) { -- t.Helper() -- tests.PrepareRename(t, src, want) -- }) -- } -- }) +- if len(got) == 0 && len(want) == 0 { +- return "" // treat nil and the empty slice as equivalent +- } - -- t.Run("Symbols", func(t *testing.T) { -- t.Helper() -- for uri, allSymbols := range data.Symbols { -- byParent := make(map[string][]*symbol) -- for _, sym := range allSymbols { -- if sym.parentID != "" { -- byParent[sym.parentID] = append(byParent[sym.parentID], sym) -- } -- } +- if diff := cmp.Diff(want, got); diff != "" { +- return fmt.Sprintf("completion item mismatch (-want +got):\n%s", diff) +- } +- return "" +-} - -- // collectChildren does a depth-first traversal of the symbol tree, -- // computing children of child nodes before returning to their parent. -- // This is necessary as the Children field is slice of non-pointer types, -- // and therefore we need to be careful to mutate children first before -- // assigning them to their parent. -- var collectChildren func(id string) []protocol.DocumentSymbol -- collectChildren = func(id string) []protocol.DocumentSymbol { -- children := byParent[id] -- // delete from byParent before recursing, to ensure that -- // collectChildren terminates even in the presence of cycles. -- delete(byParent, id) -- var result []protocol.DocumentSymbol -- for _, child := range children { -- child.pSymbol.Children = collectChildren(child.id) -- result = append(result, child.pSymbol) -- } -- return result -- } +-func TestUnimportedCompletion(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - -- var topLevel []protocol.DocumentSymbol -- for _, sym := range allSymbols { -- if sym.parentID == "" { -- sym.pSymbol.Children = collectChildren(sym.id) -- topLevel = append(topLevel, sym.pSymbol) -- } -- } +-go 1.14 - -- t.Run(uriName(uri), func(t *testing.T) { -- t.Helper() -- tests.Symbols(t, uri, topLevel) -- }) -- } -- }) +-require example.com v1.2.3 +--- go.sum -- +-example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= +-example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= +--- main.go -- +-package main - -- t.Run("WorkspaceSymbols", func(t *testing.T) { -- t.Helper() +-func main() { +- _ = blah +-} +--- main2.go -- +-package main - -- for _, typ := range []WorkspaceSymbolsTestType{ -- WorkspaceSymbolsDefault, -- WorkspaceSymbolsCaseSensitive, -- WorkspaceSymbolsFuzzy, -- } { -- for uri, cases := range data.WorkspaceSymbols[typ] { -- for _, query := range cases { -- name := query -- if name == "" { -- name = "EmptyQuery" -- } -- t.Run(name, func(t *testing.T) { -- t.Helper() -- tests.WorkspaceSymbols(t, uri, query, typ) -- }) -- } -- } -- } +-import "example.com/blah" - -- }) +-func _() { +- _ = blah.Hello +-} +-` +- WithOptions( +- ProxyFiles(proxy), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- // Make sure the dependency is in the module cache and accessible for +- // unimported completions, and then remove it before proceeding. +- env.RemoveWorkspaceFile("main2.go") +- env.RunGoCommand("mod", "tidy") +- env.Await(env.DoneWithChangeWatchedFiles()) - -- t.Run("SignatureHelp", func(t *testing.T) { -- t.Helper() -- for spn, expectedSignature := range data.Signatures { -- t.Run(SpanName(spn), func(t *testing.T) { -- t.Helper() -- tests.SignatureHelp(t, spn, expectedSignature) -- }) +- // Trigger unimported completions for the example.com/blah package. +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch("main.go", "ah") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") - } -- }) +- env.AcceptCompletion(loc, completions.Items[0]) // adds blah import to main.go +- env.Await(env.DoneWithChange()) - -- t.Run("Link", func(t *testing.T) { -- t.Helper() -- for uri, wantLinks := range data.Links { -- // If we are testing GOPATH, then we do not want links with the versions -- // attached (pkg.go.dev/repoa/moda@v1.1.0/pkg), unless the file is a -- // go.mod, then we can skip it altogether. -- if data.Exported.Exporter == packagestest.GOPATH { -- if strings.HasSuffix(uri.Filename(), ".mod") { -- continue -- } -- re := regexp.MustCompile(`@v\d+\.\d+\.[\w-]+`) -- for i, link := range wantLinks { -- wantLinks[i].Target = re.ReplaceAllString(link.Target, "") -- } -- } -- t.Run(uriName(uri), func(t *testing.T) { -- t.Helper() -- tests.Link(t, uri, wantLinks) -- }) +- // Trigger completions once again for the blah.<> selector. +- env.RegexpReplace("main.go", "_ = blah", "_ = blah.") +- env.Await(env.DoneWithChange()) +- loc = env.RegexpSearch("main.go", "\n}") +- completions = env.Completion(loc) +- if len(completions.Items) != 1 { +- t.Fatalf("expected 1 completion item, got %v", len(completions.Items)) - } -- }) -- -- t.Run("AddImport", func(t *testing.T) { -- t.Helper() -- for uri, exp := range data.AddImport { -- t.Run(uriName(uri), func(t *testing.T) { -- tests.AddImport(t, uri, exp) -- }) +- item := completions.Items[0] +- if item.Label != "Name" { +- t.Fatalf("expected completion item blah.Name, got %v", item.Label) - } -- }) +- env.AcceptCompletion(loc, item) - -- t.Run("SelectionRanges", func(t *testing.T) { -- t.Helper() -- for _, span := range data.SelectionRanges { -- t.Run(SpanName(span), func(t *testing.T) { -- tests.SelectionRanges(t, span) -- }) -- } +- // Await the diagnostics to add example.com/blah to the go.mod file. +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"example.com/blah"`)), +- ) - }) -- -- if *UpdateGolden { -- for _, golden := range data.golden { -- if !golden.Modified { -- continue -- } -- sort.Slice(golden.Archive.Files, func(i, j int) bool { -- return golden.Archive.Files[i].Name < golden.Archive.Files[j].Name -- }) -- if err := ioutil.WriteFile(golden.Filename, txtar.Format(golden.Archive), 0666); err != nil { -- t.Fatal(err) -- } -- } -- } -} - --func checkData(t *testing.T, data *Data) { -- buf := &bytes.Buffer{} -- diagnosticsCount := 0 -- for _, want := range data.Diagnostics { -- diagnosticsCount += len(want) -- } -- linksCount := 0 -- for _, want := range data.Links { -- linksCount += len(want) -- } -- definitionCount := 0 -- typeDefinitionCount := 0 -- for _, d := range data.Definitions { -- if d.IsType { -- typeDefinitionCount++ -- } else { -- definitionCount++ -- } -- } +-// Test that completions still work with an undownloaded module, golang/go#43333. +-func TestUndownloadedModule(t *testing.T) { +- // mod.com depends on example.com, but only in a file that's hidden by a +- // build tag, so the IWL won't download example.com. That will cause errors +- // in the go list -m call performed by the imports package. +- const files = ` +--- go.mod -- +-module mod.com - -- snippetCount := 0 -- for _, want := range data.CompletionSnippets { -- snippetCount += len(want) -- } +-go 1.14 - -- countCompletions := func(c map[span.Span][]Completion) (count int) { -- for _, want := range c { -- count += len(want) -- } -- return count -- } +-require example.com v1.2.3 +--- go.sum -- +-example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= +-example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= +--- useblah.go -- +-// +build hidden - -- countCodeLens := func(c map[span.URI][]protocol.CodeLens) (count int) { -- for _, want := range c { -- count += len(want) -- } -- return count -- } +-package pkg +-import "example.com/blah" +-var _ = blah.Name +--- mainmod/mainmod.go -- +-package mainmod - -- countWorkspaceSymbols := func(c map[WorkspaceSymbolsTestType]map[span.URI][]string) (count int) { -- for _, typs := range c { -- for _, queries := range typs { -- count += len(queries) -- } +-const Name = "mainmod" +-` +- WithOptions(ProxyFiles(proxy)).Run(t, files, func(t *testing.T, env *Env) { +- env.CreateBuffer("import.go", "package pkg\nvar _ = mainmod.Name\n") +- env.SaveBuffer("import.go") +- content := env.ReadWorkspaceFile("import.go") +- if !strings.Contains(content, `import "mod.com/mainmod`) { +- t.Errorf("expected import of mod.com/mainmod in %q", content) - } -- return count -- } +- }) +-} - -- fmt.Fprintf(buf, "CallHierarchyCount = %v\n", len(data.CallHierarchy)) -- fmt.Fprintf(buf, "CodeLensCount = %v\n", countCodeLens(data.CodeLens)) -- fmt.Fprintf(buf, "CompletionsCount = %v\n", countCompletions(data.Completions)) -- fmt.Fprintf(buf, "CompletionSnippetCount = %v\n", snippetCount) -- fmt.Fprintf(buf, "UnimportedCompletionsCount = %v\n", countCompletions(data.UnimportedCompletions)) -- fmt.Fprintf(buf, "DeepCompletionsCount = %v\n", countCompletions(data.DeepCompletions)) -- fmt.Fprintf(buf, "FuzzyCompletionsCount = %v\n", countCompletions(data.FuzzyCompletions)) -- fmt.Fprintf(buf, "RankedCompletionsCount = %v\n", countCompletions(data.RankCompletions)) -- fmt.Fprintf(buf, "CaseSensitiveCompletionsCount = %v\n", countCompletions(data.CaseSensitiveCompletions)) -- fmt.Fprintf(buf, "DiagnosticsCount = %v\n", diagnosticsCount) -- fmt.Fprintf(buf, "FoldingRangesCount = %v\n", len(data.FoldingRanges)) -- fmt.Fprintf(buf, "FormatCount = %v\n", len(data.Formats)) -- fmt.Fprintf(buf, "ImportCount = %v\n", len(data.Imports)) -- fmt.Fprintf(buf, "SemanticTokenCount = %v\n", len(data.SemanticTokens)) -- fmt.Fprintf(buf, "SuggestedFixCount = %v\n", len(data.SuggestedFixes)) -- fmt.Fprintf(buf, "FunctionExtractionCount = %v\n", len(data.FunctionExtractions)) -- fmt.Fprintf(buf, "MethodExtractionCount = %v\n", len(data.MethodExtractions)) -- fmt.Fprintf(buf, "DefinitionsCount = %v\n", definitionCount) -- fmt.Fprintf(buf, "TypeDefinitionsCount = %v\n", typeDefinitionCount) -- fmt.Fprintf(buf, "HighlightsCount = %v\n", len(data.Highlights)) -- fmt.Fprintf(buf, "InlayHintsCount = %v\n", len(data.InlayHints)) -- fmt.Fprintf(buf, "ReferencesCount = %v\n", len(data.References)) -- fmt.Fprintf(buf, "RenamesCount = %v\n", len(data.Renames)) -- fmt.Fprintf(buf, "PrepareRenamesCount = %v\n", len(data.PrepareRenames)) -- fmt.Fprintf(buf, "SymbolsCount = %v\n", len(data.Symbols)) -- fmt.Fprintf(buf, "WorkspaceSymbolsCount = %v\n", countWorkspaceSymbols(data.WorkspaceSymbols)) -- fmt.Fprintf(buf, "SignaturesCount = %v\n", len(data.Signatures)) -- fmt.Fprintf(buf, "LinksCount = %v\n", linksCount) -- fmt.Fprintf(buf, "ImplementationsCount = %v\n", len(data.Implementations)) -- fmt.Fprintf(buf, "SelectionRangesCount = %v\n", len(data.SelectionRanges)) +-// Test that we can doctor the source code enough so the file is +-// parseable and completion works as expected. +-func TestSourceFixup(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- want := string(data.Golden(t, "summary", summaryFile, func() ([]byte, error) { -- return buf.Bytes(), nil -- })) -- got := buf.String() -- if want != got { -- // These counters change when assertions are added or removed. -- // They act as an independent safety net to ensure that the -- // tests didn't spuriously pass because they did no work. -- t.Errorf("test summary does not match:\n%s\n(Run with -golden to update golden file; also, there may be one per Go version.)", compare.Text(want, got)) -- } +-go 1.12 +--- foo.go -- +-package foo +- +-func _() { +- var s S +- if s. -} - --func (data *Data) Mapper(uri span.URI) (*protocol.Mapper, error) { -- data.mappersMu.Lock() -- defer data.mappersMu.Unlock() +-type S struct { +- i int +-} +-` - -- if _, ok := data.mappers[uri]; !ok { -- content, err := data.Exported.FileContents(uri.Filename()) -- if err != nil { -- return nil, err +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("foo.go") +- completions := env.Completion(env.RegexpSearch("foo.go", `if s\.()`)) +- diff := compareCompletionLabels([]string{"i"}, completions.Items) +- if diff != "" { +- t.Fatal(diff) - } -- data.mappers[uri] = protocol.NewMapper(uri, content) -- } -- return data.mappers[uri], nil +- }) -} - --func (data *Data) Golden(t *testing.T, tag, target string, update func() ([]byte, error)) []byte { -- t.Helper() -- fragment, found := data.fragments[target] -- if !found { -- if filepath.IsAbs(target) { -- t.Fatalf("invalid golden file fragment %v", target) -- } -- fragment = target -- } -- golden := data.golden[fragment] -- if golden == nil { -- if !*UpdateGolden { -- t.Fatalf("could not find golden file %v: %v", fragment, tag) -- } -- golden = &Golden{ -- Filename: filepath.Join(data.dir, fragment+goldenFileSuffix), -- Archive: &txtar.Archive{}, -- Modified: true, -- } -- data.golden[fragment] = golden -- } -- var file *txtar.File -- for i := range golden.Archive.Files { -- f := &golden.Archive.Files[i] -- if f.Name == tag { -- file = f -- break -- } -- } -- if *UpdateGolden { -- if file == nil { -- golden.Archive.Files = append(golden.Archive.Files, txtar.File{ -- Name: tag, -- }) -- file = &golden.Archive.Files[len(golden.Archive.Files)-1] -- } -- contents, err := update() -- if err != nil { -- t.Fatalf("could not update golden file %v: %v", fragment, err) -- } -- file.Data = append(contents, '\n') // add trailing \n for txtar -- golden.Modified = true +-func TestCompletion_Issue45510(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- main.go -- +-package main +- +-func _() { +- type a *a +- var aaaa1, aaaa2 a +- var _ a = aaaa - -- } -- if file == nil { -- t.Fatalf("could not find golden contents %v: %v", fragment, tag) -- } -- if len(file.Data) == 0 { -- return file.Data -- } -- return file.Data[:len(file.Data)-1] // drop the trailing \n +- type b a +- var bbbb1, bbbb2 b +- var _ b = bbbb -} - --func (data *Data) collectCodeLens(spn span.Span, title, cmd string) { -- data.CodeLens[spn.URI()] = append(data.CodeLens[spn.URI()], protocol.CodeLens{ -- Range: data.mustRange(spn), -- Command: &protocol.Command{ -- Title: title, -- Command: cmd, -- }, -- }) --} +-type ( +- c *d +- d *e +- e **c +-) - --func (data *Data) collectDiagnostics(spn span.Span, msgSource, msgPattern, msgSeverity string) { -- severity := protocol.SeverityError -- switch msgSeverity { -- case "error": -- severity = protocol.SeverityError -- case "warning": -- severity = protocol.SeverityWarning -- case "hint": -- severity = protocol.SeverityHint -- case "information": -- severity = protocol.SeverityInformation -- } +-func _() { +- var ( +- xxxxc c +- xxxxd d +- xxxxe e +- ) - -- data.Diagnostics[spn.URI()] = append(data.Diagnostics[spn.URI()], &source.Diagnostic{ -- Range: data.mustRange(spn), -- Severity: severity, -- Source: source.DiagnosticSource(msgSource), -- Message: msgPattern, -- }) +- var _ c = xxxx +- var _ d = xxxx +- var _ e = xxxx -} +-` - --func (data *Data) collectCompletions(typ CompletionTestType) func(span.Span, []token.Pos) { -- result := func(m map[span.Span][]Completion, src span.Span, expected []token.Pos) { -- m[src] = append(m[src], Completion{ -- CompletionItems: expected, -- }) -- } -- switch typ { -- case CompletionDeep: -- return func(src span.Span, expected []token.Pos) { -- result(data.DeepCompletions, src, expected) +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- +- tests := []struct { +- re string +- want []string +- }{ +- {`var _ a = aaaa()`, []string{"aaaa1", "aaaa2"}}, +- {`var _ b = bbbb()`, []string{"bbbb1", "bbbb2"}}, +- {`var _ c = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, +- {`var _ d = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, +- {`var _ e = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, - } -- case CompletionUnimported: -- return func(src span.Span, expected []token.Pos) { -- result(data.UnimportedCompletions, src, expected) +- for _, tt := range tests { +- completions := env.Completion(env.RegexpSearch("main.go", tt.re)) +- diff := compareCompletionLabels(tt.want, completions.Items) +- if diff != "" { +- t.Errorf("%s: %s", tt.re, diff) +- } - } -- case CompletionFuzzy: -- return func(src span.Span, expected []token.Pos) { -- result(data.FuzzyCompletions, src, expected) +- }) +-} +- +-func TestCompletionDeprecation(t *testing.T) { +- const files = ` +--- go.mod -- +-module test.com +- +-go 1.16 +--- prog.go -- +-package waste +-// Deprecated, use newFoof +-func fooFunc() bool { +- return false +-} +- +-// Deprecated +-const badPi = 3.14 +- +-func doit() { +- if fooF +- panic() +- x := badP +-} +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("prog.go") +- loc := env.RegexpSearch("prog.go", "if fooF") +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("if fooF"))) +- completions := env.Completion(loc) +- diff := compareCompletionLabels([]string{"fooFunc"}, completions.Items) +- if diff != "" { +- t.Error(diff) - } -- case CompletionRank: -- return func(src span.Span, expected []token.Pos) { -- result(data.RankCompletions, src, expected) +- if completions.Items[0].Tags == nil { +- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) - } -- case CompletionCaseSensitive: -- return func(src span.Span, expected []token.Pos) { -- result(data.CaseSensitiveCompletions, src, expected) +- loc = env.RegexpSearch("prog.go", "= badP") +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("= badP"))) +- completions = env.Completion(loc) +- diff = compareCompletionLabels([]string{"badPi"}, completions.Items) +- if diff != "" { +- t.Error(diff) - } -- default: -- return func(src span.Span, expected []token.Pos) { -- result(data.Completions, src, expected) +- if completions.Items[0].Tags == nil { +- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) - } -- } +- }) -} - --func (data *Data) collectCompletionItems(pos token.Pos, label, detail, kind string, args []string) { -- var documentation string -- if len(args) > 3 { -- documentation = args[3] -- } -- data.CompletionItems[pos] = &completion.CompletionItem{ -- Label: label, -- Detail: detail, -- Kind: protocol.ParseCompletionItemKind(kind), -- Documentation: documentation, -- } --} +-func TestUnimportedCompletion_VSCodeIssue1489(t *testing.T) { +- const src = ` +--- go.mod -- +-module mod.com - --func (data *Data) collectFoldingRanges(spn span.Span) { -- data.FoldingRanges = append(data.FoldingRanges, spn) --} +-go 1.14 - --func (data *Data) collectFormats(spn span.Span) { -- data.Formats = append(data.Formats, spn) --} +--- main.go -- +-package main - --func (data *Data) collectImports(spn span.Span) { -- data.Imports = append(data.Imports, spn) --} +-import "fmt" - --func (data *Data) collectAddImports(spn span.Span, imp string) { -- data.AddImport[spn.URI()] = imp +-func main() { +- fmt.Println("a") +- math.Sqr -} -- --func (data *Data) collectSemanticTokens(spn span.Span) { -- data.SemanticTokens = append(data.SemanticTokens, spn) +-` +- WithOptions( +- WindowsLineEndings(), +- Settings{"ui.completion.usePlaceholders": true}, +- ).Run(t, src, func(t *testing.T, env *Env) { +- // Trigger unimported completions for the mod.com package. +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch("main.go", "Sqr()") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } +- env.AcceptCompletion(loc, completions.Items[0]) +- env.Await(env.DoneWithChange()) +- got := env.BufferText("main.go") +- want := "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"math\"\r\n)\r\n\r\nfunc main() {\r\n\tfmt.Println(\"a\")\r\n\tmath.Sqrt(${1:x float64})\r\n}\r\n" +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("unimported completion (-want +got):\n%s", diff) +- } +- }) -} - --func (data *Data) collectSuggestedFixes(spn span.Span, actionKind, fix string) { -- data.SuggestedFixes[spn] = append(data.SuggestedFixes[spn], SuggestedFix{actionKind, fix}) --} +-func TestUnimportedCompletionHasPlaceholders60269(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // uses type params - --func (data *Data) collectFunctionExtractions(start span.Span, end span.Span) { -- if _, ok := data.FunctionExtractions[start]; !ok { -- data.FunctionExtractions[start] = end -- } --} +- // We can't express this as a marker test because it doesn't support AcceptCompletion. +- const src = ` +--- go.mod -- +-module example.com +-go 1.12 - --func (data *Data) collectMethodExtractions(start span.Span, end span.Span) { -- if _, ok := data.MethodExtractions[start]; !ok { -- data.MethodExtractions[start] = end -- } --} +--- a/a.go -- +-package a - --func (data *Data) collectDefinitions(src, target span.Span) { -- data.Definitions[src] = Definition{ -- Src: src, -- Def: target, -- } --} +-var _ = b.F - --func (data *Data) collectSelectionRanges(spn span.Span) { -- data.SelectionRanges = append(data.SelectionRanges, spn) --} +--- b/b.go -- +-package b - --func (data *Data) collectImplementations(src span.Span, targets []span.Span) { -- data.Implementations[src] = targets --} +-func F0(a, b int, c float64) {} +-func F1(int, chan *string) {} +-func F2[K, V any](map[K]V, chan V) {} // missing type parameters was issue #60959 +-func F3[K comparable, V any](map[K]V, chan V) {} +-` +- WithOptions( +- WindowsLineEndings(), +- Settings{"ui.completion.usePlaceholders": true}, +- ).Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.Await(env.DoneWithOpen()) - --func (data *Data) collectIncomingCalls(src span.Span, calls []span.Span) { -- for _, call := range calls { -- rng := data.mustRange(call) -- // we're only comparing protocol.range -- if data.CallHierarchy[src] != nil { -- data.CallHierarchy[src].IncomingCalls = append(data.CallHierarchy[src].IncomingCalls, -- protocol.CallHierarchyItem{ -- URI: protocol.DocumentURI(call.URI()), -- Range: rng, -- }) -- } else { -- data.CallHierarchy[src] = &CallHierarchyResult{ -- IncomingCalls: []protocol.CallHierarchyItem{ -- {URI: protocol.DocumentURI(call.URI()), Range: rng}, -- }, +- // The table lists the expected completions of b.F as they appear in Items. +- const common = "package a\r\n\r\nimport \"example.com/b\"\r\n\r\nvar _ = " +- for i, want := range []string{ +- common + "b.F0(${1:a int}, ${2:b int}, ${3:c float64})\r\n", +- common + "b.F1(${1:_ int}, ${2:_ chan *string})\r\n", +- common + "b.F2[${1:K any}, ${2:V any}](${3:_ map[K]V}, ${4:_ chan V})\r\n", +- common + "b.F3[${1:K comparable}, ${2:V any}](${3:_ map[K]V}, ${4:_ chan V})\r\n", +- } { +- loc := env.RegexpSearch("a/a.go", "b.F()") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") - } +- saved := env.BufferText("a/a.go") +- env.AcceptCompletion(loc, completions.Items[i]) +- env.Await(env.DoneWithChange()) +- got := env.BufferText("a/a.go") +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("%d: unimported completion (-want +got):\n%s", i, diff) +- } +- env.SetBufferContent("a/a.go", saved) // restore - } -- } +- }) -} - --func (data *Data) collectOutgoingCalls(src span.Span, calls []span.Span) { -- if data.CallHierarchy[src] == nil { -- data.CallHierarchy[src] = &CallHierarchyResult{} -- } -- for _, call := range calls { -- // we're only comparing protocol.range -- data.CallHierarchy[src].OutgoingCalls = append(data.CallHierarchy[src].OutgoingCalls, -- protocol.CallHierarchyItem{ -- URI: protocol.DocumentURI(call.URI()), -- Range: data.mustRange(call), -- }) -- } --} +-func TestPackageMemberCompletionAfterSyntaxError(t *testing.T) { +- // This test documents the current broken behavior due to golang/go#58833. +- const src = ` +--- go.mod -- +-module mod.com - --func (data *Data) collectHoverDefinitions(src, target span.Span) { -- data.Definitions[src] = Definition{ -- Src: src, -- Def: target, -- OnlyHover: true, -- } --} +-go 1.14 - --func (data *Data) collectTypeDefinitions(src, target span.Span) { -- data.Definitions[src] = Definition{ -- Src: src, -- Def: target, -- IsType: true, -- } --} +--- main.go -- +-package main - --func (data *Data) collectDefinitionNames(src span.Span, name string) { -- d := data.Definitions[src] -- d.Name = name -- data.Definitions[src] = d --} +-import "math" - --func (data *Data) collectHighlights(src span.Span, expected []span.Span) { -- // Declaring a highlight in a test file: @highlight(src, expected1, expected2) -- data.Highlights[src] = append(data.Highlights[src], expected...) +-func main() { +- math.Sqrt(,0) +- math.Ldex -} -- --func (data *Data) collectInlayHints(src span.Span) { -- data.InlayHints = append(data.InlayHints, src) +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.Await(env.DoneWithOpen()) +- loc := env.RegexpSearch("main.go", "Ldex()") +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } +- env.AcceptCompletion(loc, completions.Items[0]) +- env.Await(env.DoneWithChange()) +- got := env.BufferText("main.go") +- // The completion of math.Ldex after the syntax error on the +- // previous line is not "math.Ldexp" but "math.Ldexmath.Abs". +- // (In VSCode, "Abs" wrongly appears in the completion menu.) +- // This is a consequence of poor error recovery in the parser +- // causing "math.Ldex" to become a BadExpr. +- want := "package main\n\nimport \"math\"\n\nfunc main() {\n\tmath.Sqrt(,0)\n\tmath.Ldexmath.Abs(${1:})\n}\n" +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("unimported completion (-want +got):\n%s", diff) +- } +- }) -} - --func (data *Data) collectReferences(src span.Span, expected []span.Span) { -- data.References[src] = expected --} +-func TestCompleteAllFields(t *testing.T) { +- // This test verifies that completion results always include all struct fields. +- // See golang/go#53992. - --func (data *Data) collectRenames(src span.Span, newText string) { -- data.Renames[src] = newText +- const src = ` +--- go.mod -- +-module mod.com +- +-go 1.18 +- +--- p/p.go -- +-package p +- +-import ( +- "fmt" +- +- . "net/http" +- . "runtime" +- . "go/types" +- . "go/parser" +- . "go/ast" +-) +- +-type S struct { +- a, b, c, d, e, f, g, h, i, j, k, l, m int +- n, o, p, q, r, s, t, u, v, w, x, y, z int -} - --func (data *Data) collectPrepareRenames(src, spn span.Span, placeholder string) { -- data.PrepareRenames[src] = &source.PrepareItem{ -- Range: data.mustRange(spn), -- Text: placeholder, -- } +-func _() { +- var s S +- fmt.Println(s.) -} +-` - --// collectSymbols is responsible for collecting @symbol annotations. --func (data *Data) collectSymbols(name string, selectionRng span.Span, kind, detail, id, parentID string) { -- // We don't set 'Range' here as it is difficult (impossible?) to express -- // multi-line ranges in the packagestest framework. -- uri := selectionRng.URI() -- data.Symbols[uri] = append(data.Symbols[uri], &symbol{ -- pSymbol: protocol.DocumentSymbol{ -- Name: name, -- Kind: protocol.ParseSymbolKind(kind), -- SelectionRange: data.mustRange(selectionRng), -- Detail: detail, -- }, -- id: id, -- parentID: parentID, +- WithOptions(Settings{ +- "completionBudget": "1ns", // must be non-zero as 0 => infinity +- }).Run(t, src, func(t *testing.T, env *Env) { +- wantFields := make(map[string]bool) +- for c := 'a'; c <= 'z'; c++ { +- wantFields[string(c)] = true +- } +- +- env.OpenFile("p/p.go") +- // Make an arbitrary edit to ensure we're not hitting the cache. +- env.EditBuffer("p/p.go", fake.NewEdit(0, 0, 0, 0, fmt.Sprintf("// current time: %v\n", time.Now()))) +- loc := env.RegexpSearch("p/p.go", `s\.()`) +- completions := env.Completion(loc) +- gotFields := make(map[string]bool) +- for _, item := range completions.Items { +- if item.Kind == protocol.FieldCompletion { +- gotFields[item.Label] = true +- } +- } +- +- if diff := cmp.Diff(wantFields, gotFields); diff != "" { +- t.Errorf("Completion(...) returned mismatching fields (-want +got):\n%s", diff) +- } - }) -} - --// mustRange converts spn into a protocol.Range, panicking on any error. --func (data *Data) mustRange(spn span.Span) protocol.Range { -- m, err := data.Mapper(spn.URI()) -- rng, err := m.SpanRange(spn) -- if err != nil { -- panic(fmt.Sprintf("converting span %s to range: %v", spn, err)) -- } -- return rng --} +-func TestDefinition(t *testing.T) { +- testenv.NeedsGo1Point(t, 17) // in go1.16, The FieldList in func x is not empty +- files := ` +--- go.mod -- +-module mod.com - --func (data *Data) collectWorkspaceSymbols(typ WorkspaceSymbolsTestType) func(*expect.Note, string) { -- return func(note *expect.Note, query string) { -- if data.WorkspaceSymbols[typ] == nil { -- data.WorkspaceSymbols[typ] = make(map[span.URI][]string) -- } -- pos := safetoken.StartPosition(data.Exported.ExpectFileSet, note.Pos) -- uri := span.URIFromPath(pos.Filename) -- data.WorkspaceSymbols[typ][uri] = append(data.WorkspaceSymbols[typ][uri], query) +-go 1.18 +--- a_test.go -- +-package foo +-` +- tests := []struct { +- line string // the sole line in the buffer after the package statement +- pat string // the pattern to search for +- want []string // expected completions +- }{ +- {"func T", "T", []string{"TestXxx(t *testing.T)", "TestMain(m *testing.M)"}}, +- {"func T()", "T", []string{"TestMain", "Test"}}, +- {"func TestM", "TestM", []string{"TestMain(m *testing.M)", "TestM(t *testing.T)"}}, +- {"func TestM()", "TestM", []string{"TestMain"}}, +- {"func TestMi", "TestMi", []string{"TestMi(t *testing.T)"}}, +- {"func TestMi()", "TestMi", nil}, +- {"func TestG", "TestG", []string{"TestG(t *testing.T)"}}, +- {"func TestG(", "TestG", nil}, +- {"func Ben", "B", []string{"BenchmarkXxx(b *testing.B)"}}, +- {"func Ben(", "Ben", []string{"Benchmark"}}, +- {"func BenchmarkFoo", "BenchmarkFoo", []string{"BenchmarkFoo(b *testing.B)"}}, +- {"func BenchmarkFoo(", "BenchmarkFoo", nil}, +- {"func Fuz", "F", []string{"FuzzXxx(f *testing.F)"}}, +- {"func Fuz(", "Fuz", []string{"Fuzz"}}, +- {"func Testx", "Testx", nil}, +- {"func TestMe(t *testing.T)", "TestMe", nil}, +- {"func Te(t *testing.T)", "Te", []string{"TestMain", "Test"}}, - } +- fname := "a_test.go" +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile(fname) +- env.Await(env.DoneWithOpen()) +- for _, test := range tests { +- env.SetBufferContent(fname, "package foo\n"+test.line) +- loc := env.RegexpSearch(fname, test.pat) +- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(test.pat))) +- completions := env.Completion(loc) +- if diff := compareCompletionLabels(test.want, completions.Items); diff != "" { +- t.Error(diff) +- } +- } +- }) -} - --func (data *Data) collectSignatures(spn span.Span, signature string, activeParam int64) { -- data.Signatures[spn] = &protocol.SignatureHelp{ -- Signatures: []protocol.SignatureInformation{ -- { -- Label: signature, -- }, +-// Test that completing a definition replaces source text when applied, golang/go#56852. +-// Note: With go <= 1.16 the completions does not add parameters and fails these tests. +-func TestDefinitionReplaceRange(t *testing.T) { +- testenv.NeedsGo1Point(t, 17) +- +- const mod = ` +--- go.mod -- +-module mod.com +- +-go 1.17 +-` +- +- tests := []struct { +- name string +- before, after string +- }{ +- { +- name: "func TestMa", +- before: ` +-package foo_test +- +-func TestMa +-`, +- after: ` +-package foo_test +- +-func TestMain(m *testing.M) +-`, +- }, +- { +- name: "func TestSome", +- before: ` +-package foo_test +- +-func TestSome +-`, +- after: ` +-package foo_test +- +-func TestSome(t *testing.T) +-`, +- }, +- { +- name: "func Bench", +- before: ` +-package foo_test +- +-func Bench +-`, +- // Note: Snippet with escaped }. +- after: ` +-package foo_test +- +-func Benchmark${1:Xxx}(b *testing.B) { +- $0 +-\} +-`, - }, -- ActiveParameter: uint32(activeParam), -- } -- // Hardcode special case to test the lack of a signature. -- if signature == "" && activeParam == 0 { -- data.Signatures[spn] = nil - } --} - --func (data *Data) collectCompletionSnippets(spn span.Span, item token.Pos, plain, placeholder string) { -- data.CompletionSnippets[spn] = append(data.CompletionSnippets[spn], CompletionSnippet{ -- CompletionItem: item, -- PlainSnippet: plain, -- PlaceholderSnippet: placeholder, -- }) --} +- Run(t, mod, func(t *testing.T, env *Env) { +- env.CreateBuffer("foo_test.go", "") - --func (data *Data) collectLinks(spn span.Span, link string, note *expect.Note, fset *token.FileSet) { -- position := safetoken.StartPosition(fset, note.Pos) -- uri := spn.URI() -- data.Links[uri] = append(data.Links[uri], Link{ -- Src: spn, -- Target: link, -- NotePosition: position, +- for _, tst := range tests { +- tst.before = strings.Trim(tst.before, "\n") +- tst.after = strings.Trim(tst.after, "\n") +- env.SetBufferContent("foo_test.go", tst.before) +- +- loc := env.RegexpSearch("foo_test.go", tst.name) +- loc.Range.Start.Character = uint32(protocol.UTF16Len([]byte(tst.name))) +- completions := env.Completion(loc) +- if len(completions.Items) == 0 { +- t.Fatalf("no completion items") +- } +- +- env.AcceptCompletion(loc, completions.Items[0]) +- env.Await(env.DoneWithChange()) +- if buf := env.BufferText("foo_test.go"); buf != tst.after { +- t.Errorf("%s:incorrect completion: got %q, want %q", tst.name, buf, tst.after) +- } +- } - }) -} - --func uriName(uri span.URI) string { -- return filepath.Base(strings.TrimSuffix(uri.Filename(), ".go")) --} +-func TestGoWorkCompletion(t *testing.T) { +- const files = ` +--- go.work -- +-go 1.18 - --// TODO(golang/go#54845): improve the formatting here to match standard --// line:column position formatting. --func SpanName(spn span.Span) string { -- return fmt.Sprintf("%v_%v_%v", uriName(spn.URI()), spn.Start().Line(), spn.Start().Column()) --} +-use ./a +-use ./a/ba +-use ./a/b/ +-use ./dir/foo +-use ./dir/foobar/ +--- a/go.mod -- +--- go.mod -- +--- a/bar/go.mod -- +--- a/b/c/d/e/f/go.mod -- +--- dir/bar -- +--- dir/foobar/go.mod -- +-` - --func CopyFolderToTempDir(folder string) (string, error) { -- if _, err := os.Stat(folder); err != nil { -- return "", err -- } -- dst, err := ioutil.TempDir("", "modfile_test") -- if err != nil { -- return "", err -- } -- fds, err := ioutil.ReadDir(folder) -- if err != nil { -- return "", err -- } -- for _, fd := range fds { -- srcfp := filepath.Join(folder, fd.Name()) -- stat, err := os.Stat(srcfp) -- if err != nil { -- return "", err -- } -- if !stat.Mode().IsRegular() { -- return "", fmt.Errorf("cannot copy non regular file %s", srcfp) -- } -- contents, err := ioutil.ReadFile(srcfp) -- if err != nil { -- return "", err +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.work") +- +- tests := []struct { +- re string +- want []string +- }{ +- {`use ()\.`, []string{".", "./a", "./a/bar", "./dir/foobar"}}, +- {`use \.()`, []string{"", "/a", "/a/bar", "/dir/foobar"}}, +- {`use \./()`, []string{"a", "a/bar", "dir/foobar"}}, +- {`use ./a()`, []string{"", "/b/c/d/e/f", "/bar"}}, +- {`use ./a/b()`, []string{"/c/d/e/f", "ar"}}, +- {`use ./a/b/()`, []string{`c/d/e/f`}}, +- {`use ./a/ba()`, []string{"r"}}, +- {`use ./dir/foo()`, []string{"bar"}}, +- {`use ./dir/foobar/()`, []string{}}, - } -- if err := ioutil.WriteFile(filepath.Join(dst, fd.Name()), contents, stat.Mode()); err != nil { -- return "", err +- for _, tt := range tests { +- completions := env.Completion(env.RegexpSearch("go.work", tt.re)) +- diff := compareCompletionLabels(tt.want, completions.Items) +- if diff != "" { +- t.Errorf("%s: %s", tt.re, diff) +- } - } -- } -- return dst, nil --} -- --func shouldSkip(data *Data, uri span.URI) bool { -- if data.ModfileFlagAvailable { -- return false -- } -- // If the -modfile flag is not available, then we do not want to run -- // any tests on the go.mod file. -- if strings.HasSuffix(uri.Filename(), ".mod") { -- return true -- } -- // If the -modfile flag is not available, then we do not want to test any -- // uri that contains "go mod tidy". -- m, err := data.Mapper(uri) -- return err == nil && strings.Contains(string(m.Content), ", \"go mod tidy\",") +- }) -} -diff -urN a/gopls/internal/lsp/tests/util.go b/gopls/internal/lsp/tests/util.go ---- a/gopls/internal/lsp/tests/util.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/util.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,547 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/regtest/completion/postfix_snippet_test.go b/gopls/internal/regtest/completion/postfix_snippet_test.go +--- a/gopls/internal/regtest/completion/postfix_snippet_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/completion/postfix_snippet_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,590 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --package tests +-package completion - -import ( -- "bytes" -- "context" -- "fmt" -- "go/token" -- "path" -- "path/filepath" -- "regexp" -- "sort" -- "strconv" - "strings" - "testing" - -- "github.com/google/go-cmp/cmp" -- "github.com/google/go-cmp/cmp/cmpopts" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/lsp/source/completion" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- "golang.org/x/tools/gopls/internal/span" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --var builtins = map[string]bool{ -- "append": true, -- "cap": true, -- "close": true, -- "complex": true, -- "copy": true, -- "delete": true, -- "error": true, -- "false": true, -- "imag": true, -- "iota": true, -- "len": true, -- "make": true, -- "new": true, -- "nil": true, -- "panic": true, -- "print": true, -- "println": true, -- "real": true, -- "recover": true, -- "true": true, --} +-func TestPostfixSnippetCompletion(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - --// DiffLinks takes the links we got and checks if they are located within the source or a Note. --// If the link is within a Note, the link is removed. --// Returns an diff comment if there are differences and empty string if no diffs. --func DiffLinks(mapper *protocol.Mapper, wantLinks []Link, gotLinks []protocol.DocumentLink) string { -- var notePositions []token.Position -- links := make(map[span.Span]string, len(wantLinks)) -- for _, link := range wantLinks { -- links[link.Src] = link.Target -- notePositions = append(notePositions, link.NotePosition) -- } +-go 1.12 +-` - -- var msg strings.Builder -- for _, link := range gotLinks { -- spn, err := mapper.RangeSpan(link.Range) -- if err != nil { -- return fmt.Sprintf("%v", err) -- } -- linkInNote := false -- for _, notePosition := range notePositions { -- // Drop the links found inside expectation notes arguments as this links are not collected by expect package. -- if notePosition.Line == spn.Start().Line() && -- notePosition.Column <= spn.Start().Column() { -- delete(links, spn) -- linkInNote = true -- } -- } -- if linkInNote { -- continue -- } +- cases := []struct { +- name string +- before, after string +- }{ +- { +- name: "sort", +- before: ` +-package foo - -- if target, ok := links[spn]; ok { -- delete(links, spn) -- if target != link.Target { -- fmt.Fprintf(&msg, "%s: want link with target %q, got %q\n", spn, target, link.Target) -- } -- } else { -- fmt.Fprintf(&msg, "%s: got unexpected link with target %q\n", spn, link.Target) -- } -- } -- for spn, target := range links { -- fmt.Fprintf(&msg, "%s: expected link with target %q is missing\n", spn, target) -- } -- return msg.String() +-func _() { +- var foo []int +- foo.sort -} +-`, +- after: ` +-package foo - --// CompareDiagnostics reports testing errors to t when the diagnostic set got --// does not match want. If the sole expectation has source "no_diagnostics", --// the test expects that no diagnostics were received for the given document. --func CompareDiagnostics(t *testing.T, uri span.URI, want, got []*source.Diagnostic) { -- t.Helper() -- fileName := path.Base(string(uri)) -- -- // A special case to test that there are no diagnostics for a file. -- if len(want) == 1 && want[0].Source == "no_diagnostics" { -- want = nil -- } +-import "sort" - -- // Build a helper function to match an actual diagnostic to an overlapping -- // expected diagnostic (if any). -- unmatched := make([]*source.Diagnostic, len(want)) -- copy(unmatched, want) -- source.SortDiagnostics(unmatched) -- match := func(g *source.Diagnostic) *source.Diagnostic { -- // Find the last expected diagnostic d for which start(d) < end(g), and -- // check to see if it overlaps. -- i := sort.Search(len(unmatched), func(i int) bool { -- d := unmatched[i] -- // See rangeOverlaps: if a range is a single point, we consider End to be -- // included in the range... -- if g.Range.Start == g.Range.End { -- return protocol.ComparePosition(d.Range.Start, g.Range.End) > 0 -- } -- // ...otherwise the end position of a range is not included. -- return protocol.ComparePosition(d.Range.Start, g.Range.End) >= 0 -- }) -- if i == 0 { -- return nil -- } -- w := unmatched[i-1] -- if rangeOverlaps(w.Range, g.Range) { -- unmatched = append(unmatched[:i-1], unmatched[i:]...) -- return w -- } -- return nil -- } +-func _() { +- var foo []int +- sort.Slice(foo, func(i, j int) bool { +- $0 +-}) +-} +-`, +- }, +- { +- name: "sort_renamed_sort_package", +- before: ` +-package foo - -- for _, g := range got { -- w := match(g) -- if w == nil { -- t.Errorf("%s:%s: unexpected diagnostic %q", fileName, g.Range, g.Message) -- continue -- } -- if match, err := regexp.MatchString(w.Message, g.Message); err != nil { -- t.Errorf("%s:%s: invalid regular expression %q: %v", fileName, w.Range.Start, w.Message, err) -- } else if !match { -- t.Errorf("%s:%s: got Message %q, want match for pattern %q", fileName, g.Range.Start, g.Message, w.Message) -- } -- if w.Severity != g.Severity { -- t.Errorf("%s:%s: got Severity %v, want %v", fileName, g.Range.Start, g.Severity, w.Severity) -- } -- if w.Source != g.Source { -- t.Errorf("%s:%s: got Source %v, want %v", fileName, g.Range.Start, g.Source, w.Source) -- } -- } +-import blahsort "sort" - -- for _, w := range unmatched { -- t.Errorf("%s:%s: unmatched diagnostic pattern %q", fileName, w.Range, w.Message) -- } --} +-var j int - --// rangeOverlaps reports whether r1 and r2 overlap. --func rangeOverlaps(r1, r2 protocol.Range) bool { -- if inRange(r2.Start, r1) || inRange(r1.Start, r2) { -- return true -- } -- return false +-func _() { +- var foo []int +- foo.sort -} +-`, +- after: ` +-package foo - --// inRange reports whether p is contained within [r.Start, r.End), or if p == --// r.Start == r.End (special handling for the case where the range is a single --// point). --func inRange(p protocol.Position, r protocol.Range) bool { -- if protocol.IsPoint(r) { -- return protocol.ComparePosition(r.Start, p) == 0 -- } -- if protocol.ComparePosition(r.Start, p) <= 0 && protocol.ComparePosition(p, r.End) < 0 { -- return true -- } -- return false --} +-import blahsort "sort" - --func DiffCodeLens(uri span.URI, want, got []protocol.CodeLens) string { -- sortCodeLens(want) -- sortCodeLens(got) +-var j int - -- if len(got) != len(want) { -- return summarizeCodeLens(-1, uri, want, got, "different lengths got %v want %v", len(got), len(want)) -- } -- for i, w := range want { -- g := got[i] -- if w.Command.Command != g.Command.Command { -- return summarizeCodeLens(i, uri, want, got, "incorrect Command Name got %v want %v", g.Command.Command, w.Command.Command) -- } -- if w.Command.Title != g.Command.Title { -- return summarizeCodeLens(i, uri, want, got, "incorrect Command Title got %v want %v", g.Command.Title, w.Command.Title) -- } -- if protocol.ComparePosition(w.Range.Start, g.Range.Start) != 0 { -- return summarizeCodeLens(i, uri, want, got, "incorrect Start got %v want %v", g.Range.Start, w.Range.Start) -- } -- if !protocol.IsPoint(g.Range) { // Accept any 'want' range if the codelens returns a zero-length range. -- if protocol.ComparePosition(w.Range.End, g.Range.End) != 0 { -- return summarizeCodeLens(i, uri, want, got, "incorrect End got %v want %v", g.Range.End, w.Range.End) -- } -- } -- } -- return "" +-func _() { +- var foo []int +- blahsort.Slice(foo, func(i, j2 int) bool { +- $0 +-}) -} +-`, +- }, +- { +- name: "last", +- before: ` +-package foo - --func sortCodeLens(c []protocol.CodeLens) { -- sort.Slice(c, func(i int, j int) bool { -- if r := protocol.CompareRange(c[i].Range, c[j].Range); r != 0 { -- return r < 0 -- } -- if c[i].Command.Command < c[j].Command.Command { -- return true -- } else if c[i].Command.Command == c[j].Command.Command { -- return c[i].Command.Title < c[j].Command.Title -- } else { -- return false -- } -- }) +-func _() { +- var s struct { i []int } +- s.i.last -} +-`, +- after: ` +-package foo - --func summarizeCodeLens(i int, uri span.URI, want, got []protocol.CodeLens, reason string, args ...interface{}) string { -- msg := &bytes.Buffer{} -- fmt.Fprint(msg, "codelens failed") -- if i >= 0 { -- fmt.Fprintf(msg, " at %d", i) -- } -- fmt.Fprint(msg, " because of ") -- fmt.Fprintf(msg, reason, args...) -- fmt.Fprint(msg, ":\nexpected:\n") -- for _, d := range want { -- fmt.Fprintf(msg, " %s:%v: %s | %s\n", uri, d.Range, d.Command.Command, d.Command.Title) -- } -- fmt.Fprintf(msg, "got:\n") -- for _, d := range got { -- fmt.Fprintf(msg, " %s:%v: %s | %s\n", uri, d.Range, d.Command.Command, d.Command.Title) -- } -- return msg.String() +-func _() { +- var s struct { i []int } +- s.i[len(s.i)-1] -} +-`, +- }, +- { +- name: "reverse", +- before: ` +-package foo - --func DiffSignatures(spn span.Span, want, got *protocol.SignatureHelp) string { -- decorate := func(f string, args ...interface{}) string { -- return fmt.Sprintf("invalid signature at %s: %s", spn, fmt.Sprintf(f, args...)) -- } -- if len(got.Signatures) != 1 { -- return decorate("wanted 1 signature, got %d", len(got.Signatures)) -- } -- if got.ActiveSignature != 0 { -- return decorate("wanted active signature of 0, got %d", int(got.ActiveSignature)) -- } -- if want.ActiveParameter != got.ActiveParameter { -- return decorate("wanted active parameter of %d, got %d", want.ActiveParameter, int(got.ActiveParameter)) -- } -- g := got.Signatures[0] -- w := want.Signatures[0] -- if diff := compare.Text(NormalizeAny(w.Label), NormalizeAny(g.Label)); diff != "" { -- return decorate("mismatched labels:\n%s", diff) -- } -- var paramParts []string -- for _, p := range g.Parameters { -- paramParts = append(paramParts, p.Label) -- } -- paramsStr := strings.Join(paramParts, ", ") -- if !strings.Contains(g.Label, paramsStr) { -- return decorate("expected signature %q to contain params %q", g.Label, paramsStr) -- } -- return "" +-func _() { +- var foo []int +- foo.reverse -} +-`, +- after: ` +-package foo - --// NormalizeAny replaces occurrences of interface{} in input with any. --// --// In Go 1.18, standard library functions were changed to use the 'any' --// alias in place of interface{}, which affects their type string. --func NormalizeAny(input string) string { -- return strings.ReplaceAll(input, "interface{}", "any") +-func _() { +- var foo []int +- for i, j := 0, len(foo)-1; i < j; i, j = i+1, j-1 { +- foo[i], foo[j] = foo[j], foo[i] -} - --// DiffCallHierarchyItems returns the diff between expected and actual call locations for incoming/outgoing call hierarchies --func DiffCallHierarchyItems(gotCalls []protocol.CallHierarchyItem, expectedCalls []protocol.CallHierarchyItem) string { -- expected := make(map[protocol.Location]bool) -- for _, call := range expectedCalls { -- expected[protocol.Location{URI: call.URI, Range: call.Range}] = true -- } -- -- got := make(map[protocol.Location]bool) -- for _, call := range gotCalls { -- got[protocol.Location{URI: call.URI, Range: call.Range}] = true -- } -- if len(got) != len(expected) { -- return fmt.Sprintf("expected %d calls but got %d", len(expected), len(got)) -- } -- for spn := range got { -- if !expected[spn] { -- return fmt.Sprintf("incorrect calls, expected locations %v but got locations %v", expected, got) -- } -- } -- return "" -} +-`, +- }, +- { +- name: "slice_range", +- before: ` +-package foo - --func FilterBuiltins(src span.Span, items []protocol.CompletionItem) []protocol.CompletionItem { -- var ( -- got []protocol.CompletionItem -- wantBuiltins = strings.Contains(string(src.URI()), "builtins") -- wantKeywords = strings.Contains(string(src.URI()), "keywords") -- ) -- for _, item := range items { -- if !wantBuiltins && isBuiltin(item.Label, item.Detail, item.Kind) { -- continue -- } +-func _() { +- type myThing struct{} +- var foo []myThing +- foo.range +-} +-`, +- after: ` +-package foo - -- if !wantKeywords && token.Lookup(item.Label).IsKeyword() { -- continue -- } +-func _() { +- type myThing struct{} +- var foo []myThing +- for i, mt := range foo { +- $0 +-} +-} +-`, +- }, +- { +- name: "append_stmt", +- before: ` +-package foo - -- got = append(got, item) -- } -- return got +-func _() { +- var foo []int +- foo.append -} +-`, +- after: ` +-package foo - --func isBuiltin(label, detail string, kind protocol.CompletionItemKind) bool { -- if detail == "" && kind == protocol.ClassCompletion { -- return true -- } -- // Remaining builtin constants, variables, interfaces, and functions. -- trimmed := label -- if i := strings.Index(trimmed, "("); i >= 0 { -- trimmed = trimmed[:i] -- } -- return builtins[trimmed] +-func _() { +- var foo []int +- foo = append(foo, $0) -} +-`, +- }, +- { +- name: "append_expr", +- before: ` +-package foo - --func CheckCompletionOrder(want, got []protocol.CompletionItem, strictScores bool) string { -- var ( -- matchedIdxs []int -- lastGotIdx int -- lastGotSort float64 -- inOrder = true -- errorMsg = "completions out of order" -- ) -- for _, w := range want { -- var found bool -- for i, g := range got { -- if w.Label == g.Label && NormalizeAny(w.Detail) == NormalizeAny(g.Detail) && w.Kind == g.Kind { -- matchedIdxs = append(matchedIdxs, i) -- found = true +-func _() { +- var foo []int +- var _ []int = foo.append +-} +-`, +- after: ` +-package foo - -- if i < lastGotIdx { -- inOrder = false -- } -- lastGotIdx = i +-func _() { +- var foo []int +- var _ []int = append(foo, $0) +-} +-`, +- }, +- { +- name: "slice_copy", +- before: ` +-package foo - -- sort, _ := strconv.ParseFloat(g.SortText, 64) -- if strictScores && len(matchedIdxs) > 1 && sort <= lastGotSort { -- inOrder = false -- errorMsg = "candidate scores not strictly decreasing" -- } -- lastGotSort = sort +-func _() { +- var foo []int +- foo.copy +-} +-`, +- after: ` +-package foo - -- break -- } -- } -- if !found { -- return summarizeCompletionItems(-1, []protocol.CompletionItem{w}, got, "didn't find expected completion") -- } -- } +-func _() { +- var foo []int +- fooCopy := make([]int, len(foo)) +-copy(fooCopy, foo) - -- sort.Ints(matchedIdxs) -- matched := make([]protocol.CompletionItem, 0, len(matchedIdxs)) -- for _, idx := range matchedIdxs { -- matched = append(matched, got[idx]) -- } +-} +-`, +- }, +- { +- name: "map_range", +- before: ` +-package foo - -- if !inOrder { -- return summarizeCompletionItems(-1, want, matched, errorMsg) -- } +-func _() { +- var foo map[string]int +- foo.range +-} +-`, +- after: ` +-package foo - -- return "" +-func _() { +- var foo map[string]int +- for k, v := range foo { +- $0 -} +-} +-`, +- }, +- { +- name: "map_clear", +- before: ` +-package foo - --func DiffSnippets(want string, got *protocol.CompletionItem) string { -- if want == "" { -- if got != nil { -- x := got.TextEdit -- return fmt.Sprintf("expected no snippet but got %s", x.NewText) -- } -- } else { -- if got == nil { -- return fmt.Sprintf("couldn't find completion matching %q", want) -- } -- x := got.TextEdit -- if want != x.NewText { -- return fmt.Sprintf("expected snippet %q, got %q", want, x.NewText) -- } -- } -- return "" +-func _() { +- var foo map[string]int +- foo.clear -} +-`, +- after: ` +-package foo - --func FindItem(list []protocol.CompletionItem, want completion.CompletionItem) *protocol.CompletionItem { -- for _, item := range list { -- if item.Label == want.Label { -- return &item -- } -- } -- return nil +-func _() { +- var foo map[string]int +- for k := range foo { +- delete(foo, k) -} - --// DiffCompletionItems prints the diff between expected and actual completion --// test results. --// --// The diff will be formatted using '-' and '+' for want and got, respectively. --func DiffCompletionItems(want, got []protocol.CompletionItem) string { -- // Many fields are not set in the "want" slice. -- irrelevantFields := []string{ -- "AdditionalTextEdits", -- "Documentation", -- "TextEdit", -- "SortText", -- "Preselect", -- "FilterText", -- "InsertText", -- "InsertTextFormat", -- } -- ignore := cmpopts.IgnoreFields(protocol.CompletionItem{}, irrelevantFields...) -- normalizeAny := cmpopts.AcyclicTransformer("NormalizeAny", func(item protocol.CompletionItem) protocol.CompletionItem { -- item.Detail = NormalizeAny(item.Detail) -- return item -- }) -- return cmp.Diff(want, got, ignore, normalizeAny) -} +-`, +- }, +- { +- name: "map_keys", +- before: ` +-package foo - --func summarizeCompletionItems(i int, want, got []protocol.CompletionItem, reason string, args ...interface{}) string { -- msg := &bytes.Buffer{} -- fmt.Fprint(msg, "completion failed") -- if i >= 0 { -- fmt.Fprintf(msg, " at %d", i) -- } -- fmt.Fprint(msg, " because of ") -- fmt.Fprintf(msg, reason, args...) -- fmt.Fprint(msg, ":\nexpected:\n") -- for _, d := range want { -- fmt.Fprintf(msg, " %v\n", d) -- } -- fmt.Fprintf(msg, "got:\n") -- for _, d := range got { -- fmt.Fprintf(msg, " %v\n", d) -- } -- return msg.String() +-func _() { +- var foo map[string]int +- foo.keys -} +-`, +- after: ` +-package foo - --func EnableAllAnalyzers(opts *source.Options) { -- if opts.Analyses == nil { -- opts.Analyses = make(map[string]bool) -- } -- for _, a := range opts.DefaultAnalyzers { -- if !a.IsEnabled(opts) { -- opts.Analyses[a.Analyzer.Name] = true -- } -- } -- for _, a := range opts.TypeErrorAnalyzers { -- if !a.IsEnabled(opts) { -- opts.Analyses[a.Analyzer.Name] = true -- } -- } -- for _, a := range opts.ConvenienceAnalyzers { -- if !a.IsEnabled(opts) { -- opts.Analyses[a.Analyzer.Name] = true -- } -- } -- for _, a := range opts.StaticcheckAnalyzers { -- if !a.IsEnabled(opts) { -- opts.Analyses[a.Analyzer.Name] = true -- } -- } +-func _() { +- var foo map[string]int +- keys := make([]string, 0, len(foo)) +-for k := range foo { +- keys = append(keys, k) -} - --func EnableAllInlayHints(opts *source.Options) { -- if opts.Hints == nil { -- opts.Hints = make(map[string]bool) -- } -- for name := range source.AllInlayHints { -- opts.Hints[name] = true -- } -} +-`, +- }, +- { +- name: "channel_range", +- before: ` +-package foo - --func WorkspaceSymbolsString(ctx context.Context, data *Data, queryURI span.URI, symbols []protocol.SymbolInformation) (string, error) { -- queryDir := filepath.Dir(queryURI.Filename()) -- var filtered []string -- for _, s := range symbols { -- uri := s.Location.URI.SpanURI() -- dir := filepath.Dir(uri.Filename()) -- if !source.InDir(queryDir, dir) { // assume queries always issue from higher directories -- continue -- } -- m, err := data.Mapper(uri) -- if err != nil { -- return "", err -- } -- spn, err := m.LocationSpan(s.Location) -- if err != nil { -- return "", err -- } -- filtered = append(filtered, fmt.Sprintf("%s %s %s", spn, s.Name, s.Kind)) -- } -- sort.Strings(filtered) -- return strings.Join(filtered, "\n") + "\n", nil +-func _() { +- foo := make(chan int) +- foo.range -} +-`, +- after: ` +-package foo - --func WorkspaceSymbolsTestTypeToMatcher(typ WorkspaceSymbolsTestType) source.SymbolMatcher { -- switch typ { -- case WorkspaceSymbolsFuzzy: -- return source.SymbolFuzzy -- case WorkspaceSymbolsCaseSensitive: -- return source.SymbolCaseSensitive -- default: -- return source.SymbolCaseInsensitive -- } +-func _() { +- foo := make(chan int) +- for e := range foo { +- $0 +-} -} +-`, +- }, +- { +- name: "var", +- before: ` +-package foo - --// LocationsToSpans converts protocol location into span form for testing. --func LocationsToSpans(data *Data, locs []protocol.Location) ([]span.Span, error) { -- spans := make([]span.Span, len(locs)) -- for i, loc := range locs { -- m, err := data.Mapper(loc.URI.SpanURI()) -- if err != nil { -- return nil, err -- } -- spn, err := m.LocationSpan(loc) -- if err != nil { -- return nil, fmt.Errorf("failed for %v: %w", loc, err) -- } -- spans[i] = spn -- } -- return spans, nil +-func foo() (int, error) { return 0, nil } +- +-func _() { +- foo().var -} +-`, +- after: ` +-package foo - --// SortAndFormatSpans sorts and formats a list of spans for use in an assertion. --func SortAndFormatSpans(spans []span.Span) string { -- span.SortSpans(spans) -- var buf strings.Builder -- for _, spn := range spans { -- fmt.Fprintf(&buf, "%v\n", spn) -- } -- return buf.String() +-func foo() (int, error) { return 0, nil } +- +-func _() { +- i, err := foo() -} -diff -urN a/gopls/internal/lsp/tests/util_go118.go b/gopls/internal/lsp/tests/util_go118.go ---- a/gopls/internal/lsp/tests/util_go118.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/util_go118.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,13 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-`, +- }, +- { +- name: "var_single_value", +- before: ` +-package foo - --//go:build go1.18 --// +build go1.18 +-func foo() error { return nil } - --package tests +-func _() { +- foo().var +-} +-`, +- after: ` +-package foo - --func init() { -- builtins["any"] = true -- builtins["comparable"] = true +-func foo() error { return nil } +- +-func _() { +- err := foo() -} -diff -urN a/gopls/internal/lsp/tests/util_go121.go b/gopls/internal/lsp/tests/util_go121.go ---- a/gopls/internal/lsp/tests/util_go121.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/tests/util_go121.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,12 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-`, +- }, +- { +- name: "var_same_type", +- before: ` +-package foo - --//go:build go1.21 --// +build go1.21 +-func foo() (int, int) { return 0, 0 } - --package tests +-func _() { +- foo().var +-} +-`, +- after: ` +-package foo - --func init() { -- builtins["clear"] = true +-func foo() (int, int) { return 0, 0 } +- +-func _() { +- i, i2 := foo() -} -diff -urN a/gopls/internal/lsp/text_synchronization.go b/gopls/internal/lsp/text_synchronization.go ---- a/gopls/internal/lsp/text_synchronization.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/text_synchronization.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,349 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-`, +- }, +- { +- name: "print_scalar", +- before: ` +-package foo - --package lsp +-func _() { +- var foo int +- foo.print +-} +-`, +- after: ` +-package foo - --import ( -- "bytes" -- "context" -- "errors" -- "fmt" -- "path/filepath" -- "sync" +-import "fmt" - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/jsonrpc2" --) +-func _() { +- var foo int +- fmt.Printf("foo: %v\n", foo) +-} +-`, +- }, +- { +- name: "print_multi", +- before: ` +-package foo - --// ModificationSource identifies the originating cause of a file modification. --type ModificationSource int +-func foo() (int, error) { return 0, nil } - --const ( -- // FromDidOpen is a file modification caused by opening a file. -- FromDidOpen = ModificationSource(iota) +-func _() { +- foo().print +-} +-`, +- after: ` +-package foo - -- // FromDidChange is a file modification caused by changing a file. -- FromDidChange +-import "fmt" - -- // FromDidChangeWatchedFiles is a file modification caused by a change to a -- // watched file. -- FromDidChangeWatchedFiles +-func foo() (int, error) { return 0, nil } - -- // FromDidSave is a file modification caused by a file save. -- FromDidSave +-func _() { +- fmt.Println(foo()) +-} +-`, +- }, +- { +- name: "string split", +- before: ` +-package foo - -- // FromDidClose is a file modification caused by closing a file. -- FromDidClose +-func foo() []string { +- x := "test" +- return x.split +-}`, +- after: ` +-package foo - -- // TODO: add FromDidChangeConfiguration, once configuration changes cause a -- // new snapshot to be created. +-import "strings" - -- // FromRegenerateCgo refers to file modifications caused by regenerating -- // the cgo sources for the workspace. -- FromRegenerateCgo +-func foo() []string { +- x := "test" +- return strings.Split(x, "$0") +-}`, +- }, +- { +- name: "string slice join", +- before: ` +-package foo - -- // FromInitialWorkspaceLoad refers to the loading of all packages in the -- // workspace when the view is first created. -- FromInitialWorkspaceLoad --) +-func foo() string { +- x := []string{"a", "test"} +- return x.join +-}`, +- after: ` +-package foo - --func (m ModificationSource) String() string { -- switch m { -- case FromDidOpen: -- return "opened files" -- case FromDidChange: -- return "changed files" -- case FromDidChangeWatchedFiles: -- return "files changed on disk" -- case FromDidSave: -- return "saved files" -- case FromDidClose: -- return "close files" -- case FromRegenerateCgo: -- return "regenerate cgo" -- case FromInitialWorkspaceLoad: -- return "initial workspace load" -- default: -- return "unknown file modification" -- } --} +-import "strings" - --func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error { -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } -- // There may not be any matching view in the current session. If that's -- // the case, try creating a new view based on the opened file path. -- // -- // TODO(rstambler): This seems like it would continuously add new -- // views, but it won't because ViewOf only returns an error when there -- // are no views in the session. I don't know if that logic should go -- // here, or if we can continue to rely on that implementation detail. -- if _, err := s.session.ViewOf(uri); err != nil { -- dir := filepath.Dir(uri.Filename()) -- if err := s.addFolders(ctx, []protocol.WorkspaceFolder{{ -- URI: string(protocol.URIFromPath(dir)), -- Name: filepath.Base(dir), -- }}); err != nil { -- return err -- } -- } -- return s.didModifyFiles(ctx, []source.FileModification{{ -- URI: uri, -- Action: source.Open, -- Version: params.TextDocument.Version, -- Text: []byte(params.TextDocument.Text), -- LanguageID: params.TextDocument.LanguageID, -- }}, FromDidOpen) --} +-func foo() string { +- x := []string{"a", "test"} +- return strings.Join(x, "$0") +-}`, +- }, +- { +- name: "if not nil interface", +- before: ` +-package foo - --func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error { -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } +-func _() { +- var foo error +- foo.ifnotnil +-} +-`, +- after: ` +-package foo - -- text, err := s.changedText(ctx, uri, params.ContentChanges) -- if err != nil { -- return err -- } -- c := source.FileModification{ -- URI: uri, -- Action: source.Change, -- Version: params.TextDocument.Version, -- Text: text, -- } -- if err := s.didModifyFiles(ctx, []source.FileModification{c}, FromDidChange); err != nil { -- return err -- } -- return s.warnAboutModifyingGeneratedFiles(ctx, uri) +-func _() { +- var foo error +- if foo != nil { +- $0 +-} +-} +-`, +- }, +- { +- name: "if not nil pointer", +- before: ` +-package foo +- +-func _() { +- var foo *int +- foo.ifnotnil -} +-`, +- after: ` +-package foo - --// warnAboutModifyingGeneratedFiles shows a warning if a user tries to edit a --// generated file for the first time. --func (s *Server) warnAboutModifyingGeneratedFiles(ctx context.Context, uri span.URI) error { -- s.changedFilesMu.Lock() -- _, ok := s.changedFiles[uri] -- if !ok { -- s.changedFiles[uri] = struct{}{} -- } -- s.changedFilesMu.Unlock() +-func _() { +- var foo *int +- if foo != nil { +- $0 +-} +-} +-`, +- }, +- { +- name: "if not nil slice", +- before: ` +-package foo - -- // This file has already been edited before. -- if ok { -- return nil -- } +-func _() { +- var foo []int +- foo.ifnotnil +-} +-`, +- after: ` +-package foo - -- // Ideally, we should be able to specify that a generated file should -- // be opened as read-only. Tell the user that they should not be -- // editing a generated file. -- view, err := s.session.ViewOf(uri) -- if err != nil { -- return err -- } -- snapshot, release, err := view.Snapshot() -- if err != nil { -- return err -- } -- isGenerated := source.IsGenerated(ctx, snapshot, uri) -- release() +-func _() { +- var foo []int +- if foo != nil { +- $0 +-} +-} +-`, +- }, +- { +- name: "if not nil map", +- before: ` +-package foo - -- if !isGenerated { -- return nil -- } -- return s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ -- Message: fmt.Sprintf("Do not edit this file! %s is a generated file.", uri.Filename()), -- Type: protocol.Warning, -- }) +-func _() { +- var foo map[string]any +- foo.ifnotnil -} +-`, +- after: ` +-package foo - --func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.DidChangeWatchedFilesParams) error { -- var modifications []source.FileModification -- for _, change := range params.Changes { -- uri := change.URI.SpanURI() -- if !uri.IsFile() { -- continue -- } -- action := changeTypeToFileAction(change.Type) -- modifications = append(modifications, source.FileModification{ -- URI: uri, -- Action: action, -- OnDisk: true, -- }) -- } -- return s.didModifyFiles(ctx, modifications, FromDidChangeWatchedFiles) +-func _() { +- var foo map[string]any +- if foo != nil { +- $0 +-} -} +-`, +- }, +- { +- name: "if not nil channel", +- before: ` +-package foo - --func (s *Server) didSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) error { -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } -- c := source.FileModification{ -- URI: uri, -- Action: source.Save, -- } -- if params.Text != nil { -- c.Text = []byte(*params.Text) -- } -- return s.didModifyFiles(ctx, []source.FileModification{c}, FromDidSave) +-func _() { +- var foo chan int +- foo.ifnotnil -} +-`, +- after: ` +-package foo - --func (s *Server) didClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error { -- uri := params.TextDocument.URI.SpanURI() -- if !uri.IsFile() { -- return nil -- } -- return s.didModifyFiles(ctx, []source.FileModification{ -- { -- URI: uri, -- Action: source.Close, -- Version: -1, -- Text: nil, -- }, -- }, FromDidClose) +-func _() { +- var foo chan int +- if foo != nil { +- $0 +-} -} +-`, +- }, +- { +- name: "if not nil function", +- before: ` +-package foo - --func (s *Server) didModifyFiles(ctx context.Context, modifications []source.FileModification, cause ModificationSource) error { -- // wg guards two conditions: -- // 1. didModifyFiles is complete -- // 2. the goroutine diagnosing changes on behalf of didModifyFiles is -- // complete, if it was started -- // -- // Both conditions must be satisfied for the purpose of testing: we don't -- // want to observe the completion of change processing until we have received -- // all diagnostics as well as all server->client notifications done on behalf -- // of this function. -- var wg sync.WaitGroup -- wg.Add(1) -- defer wg.Done() +-func _() { +- var foo func() +- foo.ifnotnil +-} +-`, +- after: ` +-package foo - -- if s.session.Options().VerboseWorkDoneProgress { -- work := s.progress.Start(ctx, DiagnosticWorkTitle(cause), "Calculating file diagnostics...", nil, nil) -- go func() { -- wg.Wait() -- work.End(ctx, "Done.") -- }() +-func _() { +- var foo func() +- if foo != nil { +- $0 +-} +-} +-`, +- }, - } - -- onDisk := cause == FromDidChangeWatchedFiles +- r := WithOptions( +- Settings{ +- "experimentalPostfixCompletions": true, +- }, +- ) +- r.Run(t, mod, func(t *testing.T, env *Env) { +- env.CreateBuffer("foo.go", "") - -- s.stateMu.Lock() -- if s.state >= serverShutDown { -- // This state check does not prevent races below, and exists only to -- // produce a better error message. The actual race to the cache should be -- // guarded by Session.viewMu. -- s.stateMu.Unlock() -- return errors.New("server is shut down") -- } -- s.stateMu.Unlock() +- for _, c := range cases { +- t.Run(c.name, func(t *testing.T) { +- c.before = strings.Trim(c.before, "\n") +- c.after = strings.Trim(c.after, "\n") - -- // If the set of changes included directories, expand those directories -- // to their files. -- modifications = s.session.ExpandModificationsToDirectories(ctx, modifications) +- env.SetBufferContent("foo.go", c.before) - -- // Build a lookup map for file modifications, so that we can later join -- // with the snapshot file associations. -- modMap := make(map[span.URI]source.FileModification) -- for _, mod := range modifications { -- modMap[mod.URI] = mod -- } +- loc := env.RegexpSearch("foo.go", "\n}") +- completions := env.Completion(loc) +- if len(completions.Items) != 1 { +- t.Fatalf("expected one completion, got %v", completions.Items) +- } - -- snapshots, release, err := s.session.DidModifyFiles(ctx, modifications) -- if err != nil { -- return err -- } +- env.AcceptCompletion(loc, completions.Items[0]) - -- // golang/go#50267: diagnostics should be re-sent after an open or close. For -- // some clients, it may be helpful to re-send after each change. -- for snapshot, uris := range snapshots { -- for _, uri := range uris { -- mod := modMap[uri] -- if snapshot.View().Options().ChattyDiagnostics || mod.Action == source.Open || mod.Action == source.Close { -- s.mustPublishDiagnostics(uri) -- } +- if buf := env.BufferText("foo.go"); buf != c.after { +- t.Errorf("\nGOT:\n%s\nEXPECTED:\n%s", buf, c.after) +- } +- }) - } -- } +- }) +-} +diff -urN a/gopls/internal/regtest/debug/debug_test.go b/gopls/internal/regtest/debug/debug_test.go +--- a/gopls/internal/regtest/debug/debug_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/debug/debug_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,101 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- wg.Add(1) -- go func() { -- s.diagnoseSnapshots(snapshots, onDisk) -- release() -- wg.Done() -- }() +-package debug - -- // After any file modifications, we need to update our watched files, -- // in case something changed. Compute the new set of directories to watch, -- // and if it differs from the current set, send updated registrations. -- return s.updateWatchedDirectories(ctx) +-import ( +- "context" +- "encoding/json" +- "io" +- "net/http" +- "strings" +- "testing" +- +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp/command" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) +- +-func TestMain(m *testing.M) { +- Main(m, hooks.Options) -} - --// DiagnosticWorkTitle returns the title of the diagnostic work resulting from a --// file change originating from the given cause. --func DiagnosticWorkTitle(cause ModificationSource) string { -- return fmt.Sprintf("diagnosing %v", cause) +-func TestBugNotification(t *testing.T) { +- // Verify that a properly configured session gets notified of a bug on the +- // server. +- WithOptions( +- Modes(Default), // must be in-process to receive the bug report below +- Settings{"showBugReports": true}, +- ).Run(t, "", func(t *testing.T, env *Env) { +- const desc = "got a bug" +- bug.Report(desc) +- env.Await(ShownMessage(desc)) +- }) -} - --func (s *Server) changedText(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { -- if len(changes) == 0 { -- return nil, fmt.Errorf("%w: no content changes provided", jsonrpc2.ErrInternal) -- } +-// TestStartDebugging executes a gopls.start_debugging command to +-// start the internal web server. +-func TestStartDebugging(t *testing.T) { +- WithOptions( +- Modes(Default|Experimental), // doesn't work in Forwarded mode +- ).Run(t, "", func(t *testing.T, env *Env) { +- // Start a debugging server. +- res, err := startDebugging(env.Ctx, env.Editor.Server, &command.DebuggingArgs{ +- Addr: "", // any free port +- }) +- if err != nil { +- t.Fatalf("startDebugging: %v", err) +- } - -- // Check if the client sent the full content of the file. -- // We accept a full content change even if the server expected incremental changes. -- if len(changes) == 1 && changes[0].Range == nil && changes[0].RangeLength == 0 { -- return []byte(changes[0].Text), nil -- } -- return s.applyIncrementalChanges(ctx, uri, changes) +- // Assert that the server requested that the +- // client show the debug page in a browser. +- debugURL := res.URLs[0] +- env.Await(ShownDocument(debugURL)) +- +- // Send a request to the debug server and ensure it responds. +- resp, err := http.Get(debugURL) +- if err != nil { +- t.Fatal(err) +- } +- defer resp.Body.Close() +- data, err := io.ReadAll(resp.Body) +- if err != nil { +- t.Fatalf("reading HTTP response body: %v", err) +- } +- const want = "GoPls" +- if !strings.Contains(string(data), want) { +- t.Errorf("GET %s response does not contain %q: <<%s>>", debugURL, want, data) +- } +- }) -} - --func (s *Server) applyIncrementalChanges(ctx context.Context, uri span.URI, changes []protocol.TextDocumentContentChangeEvent) ([]byte, error) { -- fh, err := s.session.GetFile(ctx, uri) +-// startDebugging starts a debugging server. +-// TODO(adonovan): move into command package? +-func startDebugging(ctx context.Context, server protocol.Server, args *command.DebuggingArgs) (*command.DebuggingResult, error) { +- rawArgs, err := command.MarshalArgs(args) - if err != nil { - return nil, err - } -- content, err := fh.Read() +- res0, err := server.ExecuteCommand(ctx, &protocol.ExecuteCommandParams{ +- Command: command.StartDebugging.ID(), +- Arguments: rawArgs, +- }) - if err != nil { -- return nil, fmt.Errorf("%w: file not found (%v)", jsonrpc2.ErrInternal, err) +- return nil, err - } -- for _, change := range changes { -- // TODO(adonovan): refactor to use diff.Apply, which is robust w.r.t. -- // out-of-order or overlapping changes---and much more efficient. -- -- // Make sure to update mapper along with the content. -- m := protocol.NewMapper(uri, content) -- if change.Range == nil { -- return nil, fmt.Errorf("%w: unexpected nil range for change", jsonrpc2.ErrInternal) -- } -- spn, err := m.RangeSpan(*change.Range) -- if err != nil { -- return nil, err -- } -- start, end := spn.Start().Offset(), spn.End().Offset() -- if end < start { -- return nil, fmt.Errorf("%w: invalid range for content change", jsonrpc2.ErrInternal) -- } -- var buf bytes.Buffer -- buf.Write(content[:start]) -- buf.WriteString(change.Text) -- buf.Write(content[end:]) -- content = buf.Bytes() +- // res0 is the result of a schemaless (map[string]any) JSON decoding. +- // Re-encode and decode into the correct Go struct type. +- // TODO(adonovan): fix (*serverDispatcher).ExecuteCommand. +- data, err := json.Marshal(res0) +- if err != nil { +- return nil, err - } -- return content, nil --} -- --func changeTypeToFileAction(ct protocol.FileChangeType) source.FileAction { -- switch ct { -- case protocol.Changed: -- return source.Change -- case protocol.Created: -- return source.Create -- case protocol.Deleted: -- return source.Delete +- var res *command.DebuggingResult +- if err := json.Unmarshal(data, &res); err != nil { +- return nil, err - } -- return source.UnknownFileAction +- return res, nil -} -diff -urN a/gopls/internal/lsp/work/completion.go b/gopls/internal/lsp/work/completion.go ---- a/gopls/internal/lsp/work/completion.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/completion.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,154 +0,0 @@ +diff -urN a/gopls/internal/regtest/diagnostics/analysis_test.go b/gopls/internal/regtest/diagnostics/analysis_test.go +--- a/gopls/internal/regtest/diagnostics/analysis_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/analysis_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,127 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --package work +-package diagnostics - -import ( -- "context" -- "errors" - "fmt" -- "os" -- "path/filepath" -- "sort" -- "strings" +- "testing" - +- "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/event" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" -) - --func Completion(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.CompletionList, error) { -- ctx, done := event.Start(ctx, "work.Completion") -- defer done() +-// Test for the timeformat analyzer, following golang/vscode-go#2406. +-// +-// This test checks that applying the suggested fix from the analyzer resolves +-// the diagnostic warning. +-func TestTimeFormatAnalyzer(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- // Get the position of the cursor. -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- return nil, fmt.Errorf("getting go.work file handle: %w", err) -- } -- cursor, err := pw.Mapper.PositionOffset(position) -- if err != nil { -- return nil, fmt.Errorf("computing cursor offset: %w", err) -- } +-go 1.18 +--- main.go -- +-package main - -- // Find the use statement the user is in. -- use, pathStart, _ := usePath(pw, cursor) -- if use == nil { -- return &protocol.CompletionList{}, nil -- } -- completingFrom := use.Path[:cursor-pathStart] +-import ( +- "fmt" +- "time" +-) - -- // We're going to find the completions of the user input -- // (completingFrom) by doing a walk on the innermost directory -- // of the given path, and comparing the found paths to make sure -- // that they match the component of the path after the -- // innermost directory. -- // -- // We'll maintain two paths when doing this: pathPrefixSlash -- // is essentially the path the user typed in, and pathPrefixAbs -- // is the path made absolute from the go.work directory. +-func main() { +- now := time.Now() +- fmt.Println(now.Format("2006-02-01")) +-}` - -- pathPrefixSlash := completingFrom -- pathPrefixAbs := filepath.FromSlash(pathPrefixSlash) -- if !filepath.IsAbs(pathPrefixAbs) { -- pathPrefixAbs = filepath.Join(filepath.Dir(pw.URI.Filename()), pathPrefixAbs) +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "2006-02-01")), +- ReadDiagnostics("main.go", &d), +- ) +- +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +- }) +-} +- +-func TestAnalysisProgressReporting(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com +- +-go 1.18 +- +--- main.go -- +-package main +- +-func main() { +-}` +- +- tests := []struct { +- setting bool +- want Expectation +- }{ +- {true, CompletedWork(cache.AnalysisProgressTitle, 1, true)}, +- {false, Not(CompletedWork(cache.AnalysisProgressTitle, 1, true))}, - } - -- // pathPrefixDir is the directory that will be walked to find matches. -- // If pathPrefixSlash is not explicitly a directory boundary (is either equivalent to "." or -- // ends in a separator) we need to examine its parent directory to find sibling files that -- // match. -- depthBound := 5 -- pathPrefixDir, pathPrefixBase := pathPrefixAbs, "" -- pathPrefixSlashDir := pathPrefixSlash -- if filepath.Clean(pathPrefixSlash) != "." && !strings.HasSuffix(pathPrefixSlash, "/") { -- depthBound++ -- pathPrefixDir, pathPrefixBase = filepath.Split(pathPrefixAbs) -- pathPrefixSlashDir = dirNonClean(pathPrefixSlash) +- for _, test := range tests { +- t.Run(fmt.Sprint(test.setting), func(t *testing.T) { +- WithOptions( +- Settings{ +- "reportAnalysisProgressAfter": "0s", +- "analysisProgressReporting": test.setting, +- }, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.AfterChange(test.want) +- }) +- }) - } +-} - -- var completions []string -- // Stop traversing deeper once we've hit 10k files to try to stay generally under 100ms. -- const numSeenBound = 10000 -- var numSeen int -- stopWalking := errors.New("hit numSeenBound") -- err = filepath.Walk(pathPrefixDir, func(wpath string, info os.FileInfo, err error) error { -- if numSeen > numSeenBound { -- // Stop traversing if we hit bound. -- return stopWalking -- } -- numSeen++ +-// Test the embed directive analyzer. +-// +-// There is a fix for missing imports, but it should not trigger for other +-// kinds of issues reported by the analayzer, here the variable +-// declaration following the embed directive is wrong. +-func TestNoSuggestedFixesForEmbedDirectiveDeclaration(t *testing.T) { +- const generated = ` +--- go.mod -- +-module mod.com - -- // rel is the path relative to pathPrefixDir. -- // Make sure that it has pathPrefixBase as a prefix -- // otherwise it won't match the beginning of the -- // base component of the path the user typed in. -- rel := strings.TrimPrefix(wpath[len(pathPrefixDir):], string(filepath.Separator)) -- if info.IsDir() && wpath != pathPrefixDir && !strings.HasPrefix(rel, pathPrefixBase) { -- return filepath.SkipDir -- } +-go 1.20 - -- // Check for a match (a module directory). -- if filepath.Base(rel) == "go.mod" { -- relDir := strings.TrimSuffix(dirNonClean(rel), string(os.PathSeparator)) -- completionPath := join(pathPrefixSlashDir, filepath.ToSlash(relDir)) +--- foo.txt -- +-FOO - -- if !strings.HasPrefix(completionPath, completingFrom) { -- return nil -- } -- if strings.HasSuffix(completionPath, "/") { -- // Don't suggest paths that end in "/". This happens -- // when the input is a path that ends in "/" and -- // the completion is empty. -- return nil -- } -- completion := completionPath[len(completingFrom):] -- if completingFrom == "" && !strings.HasPrefix(completion, "./") { -- // Bias towards "./" prefixes. -- completion = join(".", completion) -- } +--- main.go -- +-package main +- +-import _ "embed" +- +-//go:embed foo.txt +-var foo, bar string +- +-func main() { +- _ = foo +-} +-` +- Run(t, generated, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "//go:embed")), +- ReadDiagnostics("main.go", &d), +- ) +- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { +- t.Errorf("got quick fixes %v, wanted none", fixes) +- } +- }) +-} +diff -urN a/gopls/internal/regtest/diagnostics/builtin_test.go b/gopls/internal/regtest/diagnostics/builtin_test.go +--- a/gopls/internal/regtest/diagnostics/builtin_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/builtin_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,35 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- completions = append(completions, completion) -- } +-package diagnostics - -- if depth := strings.Count(rel, string(filepath.Separator)); depth >= depthBound { -- return filepath.SkipDir -- } -- return nil -- }) -- if err != nil && !errors.Is(err, stopWalking) { -- return nil, fmt.Errorf("walking to find completions: %w", err) -- } +-import ( +- "strings" +- "testing" - -- sort.Strings(completions) +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) - -- var items []protocol.CompletionItem -- for _, c := range completions { -- items = append(items, protocol.CompletionItem{ -- Label: c, -- InsertText: c, -- }) -- } -- return &protocol.CompletionList{Items: items}, nil --} +-func TestIssue44866(t *testing.T) { +- src := ` +--- go.mod -- +-module mod.com - --// dirNonClean is filepath.Dir, without the Clean at the end. --func dirNonClean(path string) string { -- vol := filepath.VolumeName(path) -- i := len(path) - 1 -- for i >= len(vol) && !os.IsPathSeparator(path[i]) { -- i-- -- } -- return path[len(vol) : i+1] --} +-go 1.12 +--- a.go -- +-package a - --func join(a, b string) string { -- if a == "" { -- return b -- } -- if b == "" { -- return a -- } -- return strings.TrimSuffix(a, "/") + "/" + b +-const ( +- c = iota +-) +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- loc := env.GoToDefinition(env.RegexpSearch("a.go", "iota")) +- if !strings.HasSuffix(string(loc.URI), "builtin.go") { +- t.Fatalf("jumped to %q, want builtin.go", loc.URI) +- } +- env.AfterChange(NoDiagnostics(ForFile("builtin.go"))) +- }) -} -diff -urN a/gopls/internal/lsp/work/diagnostics.go b/gopls/internal/lsp/work/diagnostics.go ---- a/gopls/internal/lsp/work/diagnostics.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/diagnostics.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,92 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. +diff -urN a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/internal/regtest/diagnostics/diagnostics_test.go +--- a/gopls/internal/regtest/diagnostics/diagnostics_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/diagnostics_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,2114 +0,0 @@ +-// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - --package work +-package diagnostics - -import ( - "context" - "fmt" -- "os" -- "path/filepath" +- "os/exec" +- "testing" - -- "golang.org/x/mod/modfile" +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- "golang.org/x/tools/gopls/internal/lsp" +- "golang.org/x/tools/gopls/internal/lsp/fake" - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" -- "golang.org/x/tools/internal/event" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/testenv" -) - --func Diagnostics(ctx context.Context, snapshot source.Snapshot) (map[span.URI][]*source.Diagnostic, error) { -- ctx, done := event.Start(ctx, "work.Diagnostics", source.SnapshotLabels(snapshot)...) -- defer done() +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- Main(m, hooks.Options) +-} - -- reports := map[span.URI][]*source.Diagnostic{} -- uri := snapshot.WorkFile() -- if uri == "" { -- return nil, nil -- } -- fh, err := snapshot.GetFile(ctx, uri) -- if err != nil { -- return nil, err -- } -- reports[fh.URI()] = []*source.Diagnostic{} -- diagnostics, err := DiagnosticsForWork(ctx, snapshot, fh) -- if err != nil { -- return nil, err -- } -- for _, d := range diagnostics { -- fh, err := snapshot.GetFile(ctx, d.URI) -- if err != nil { -- return nil, err -- } -- reports[fh.URI()] = append(reports[fh.URI()], d) -- } +-// Use mod.com for all go.mod files due to golang/go#35230. +-const exampleProgram = ` +--- go.mod -- +-module mod.com - -- return reports, nil +-go 1.12 +--- main.go -- +-package main +- +-import "fmt" +- +-func main() { +- fmt.Println("Hello World.") +-}` +- +-func TestDiagnosticErrorInEditedFile(t *testing.T) { +- // This test is very basic: start with a clean Go program, make an error, and +- // get a diagnostic for that error. However, it also demonstrates how to +- // combine Expectations to await more complex state in the editor. +- Run(t, exampleProgram, func(t *testing.T, env *Env) { +- // Deleting the 'n' at the end of Println should generate a single error +- // diagnostic. +- env.OpenFile("main.go") +- env.RegexpReplace("main.go", "Printl(n)", "") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "Printl")), +- // Assert that this test has sent no error logs to the client. This is not +- // strictly necessary for testing this regression, but is included here +- // as an example of using the NoErrorLogs() expectation. Feel free to +- // delete. +- NoErrorLogs(), +- ) +- }) -} - --func DiagnosticsForWork(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]*source.Diagnostic, error) { -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- if pw == nil || len(pw.ParseErrors) == 0 { -- return nil, err -- } -- return pw.ParseErrors, nil -- } +-func TestMissingImportDiagsClearOnFirstFile(t *testing.T) { +- const onlyMod = ` +--- go.mod -- +-module mod.com - -- // Add diagnostic if a directory does not contain a module. -- var diagnostics []*source.Diagnostic -- for _, use := range pw.File.Use { -- rng, err := pw.Mapper.OffsetRange(use.Syntax.Start.Byte, use.Syntax.End.Byte) -- if err != nil { -- return nil, err -- } +-go 1.12 +-` +- Run(t, onlyMod, func(t *testing.T, env *Env) { +- env.CreateBuffer("main.go", `package main - -- modfh, err := snapshot.GetFile(ctx, modFileURI(pw, use)) -- if err != nil { -- return nil, err -- } -- if _, err := modfh.Read(); err != nil && os.IsNotExist(err) { -- diagnostics = append(diagnostics, &source.Diagnostic{ -- URI: fh.URI(), -- Range: rng, -- Severity: protocol.SeverityError, -- Source: source.WorkFileError, -- Message: fmt.Sprintf("directory %v does not contain a module", use.Path), -- }) -- } -- } -- return diagnostics, nil +-func m() { +- log.Println() +-} +-`) +- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "log"))) +- env.SaveBuffer("main.go") +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +- }) -} - --func modFileURI(pw *source.ParsedWorkFile, use *modfile.Use) span.URI { -- workdir := filepath.Dir(pw.URI.Filename()) +-func TestDiagnosticErrorInNewFile(t *testing.T) { +- const brokenFile = `package main - -- modroot := filepath.FromSlash(use.Path) -- if !filepath.IsAbs(modroot) { -- modroot = filepath.Join(workdir, modroot) -- } +-const Foo = "abc +-` +- Run(t, brokenFile, func(t *testing.T, env *Env) { +- env.CreateBuffer("broken.go", brokenFile) +- env.AfterChange(Diagnostics(env.AtRegexp("broken.go", "\"abc"))) +- }) +-} - -- return span.URIFromPath(filepath.Join(modroot, "go.mod")) +-// badPackage contains a duplicate definition of the 'a' const. +-const badPackage = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- a.go -- +-package consts +- +-const a = 1 +--- b.go -- +-package consts +- +-const a = 2 +-` +- +-func TestDiagnosticClearingOnEdit(t *testing.T) { +- Run(t, badPackage, func(t *testing.T, env *Env) { +- env.OpenFile("b.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- ) +- +- // Fix the error by editing the const name in b.go to `b`. +- env.RegexpReplace("b.go", "(a) = 2", "b") +- env.AfterChange( +- NoDiagnostics(ForFile("a.go")), +- NoDiagnostics(ForFile("b.go")), +- ) +- }) -} -diff -urN a/gopls/internal/lsp/work/format.go b/gopls/internal/lsp/work/format.go ---- a/gopls/internal/lsp/work/format.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/format.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,28 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package work +-func TestDiagnosticClearingOnDelete_Issue37049(t *testing.T) { +- Run(t, badPackage, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- ) +- env.RemoveWorkspaceFile("b.go") - --import ( -- "context" +- env.AfterChange( +- NoDiagnostics(ForFile("a.go")), +- NoDiagnostics(ForFile("b.go")), +- ) +- }) +-} - -- "golang.org/x/mod/modfile" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/event" --) +-func TestDiagnosticClearingOnClose(t *testing.T) { +- Run(t, badPackage, func(t *testing.T, env *Env) { +- env.CreateBuffer("c.go", `package consts - --func Format(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle) ([]protocol.TextEdit, error) { -- ctx, done := event.Start(ctx, "work.Format") -- defer done() +-const a = 3`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- Diagnostics(env.AtRegexp("c.go", "a = 3")), +- ) +- env.CloseBuffer("c.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a.go", "a = 1")), +- Diagnostics(env.AtRegexp("b.go", "a = 2")), +- NoDiagnostics(ForFile("c.go")), +- ) +- }) +-} - -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- return nil, err -- } -- formatted := modfile.Format(pw.File.Syntax) -- // Calculate the edits to be made due to the change. -- diffs := snapshot.View().Options().ComputeEdits(string(pw.Mapper.Content), string(formatted)) -- return source.ToProtocolEdits(pw.Mapper, diffs) +-// Tests golang/go#37978. +-func TestIssue37978(t *testing.T) { +- Run(t, exampleProgram, func(t *testing.T, env *Env) { +- // Create a new workspace-level directory and empty file. +- env.CreateBuffer("c/c.go", "") +- +- // Write the file contents with a missing import. +- env.EditBuffer("c/c.go", protocol.TextEdit{ +- NewText: `package c +- +-const a = http.MethodGet +-`, +- }) +- env.AfterChange( +- Diagnostics(env.AtRegexp("c/c.go", "http.MethodGet")), +- ) +- // Save file, which will organize imports, adding the expected import. +- // Expect the diagnostics to clear. +- env.SaveBuffer("c/c.go") +- env.AfterChange( +- NoDiagnostics(ForFile("c/c.go")), +- ) +- }) -} -diff -urN a/gopls/internal/lsp/work/hover.go b/gopls/internal/lsp/work/hover.go ---- a/gopls/internal/lsp/work/hover.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/work/hover.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,89 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package work +-// Tests golang/go#38878: good a.go, bad a_test.go, remove a_test.go but its errors remain +-// If the file is open in the editor, this is working as intended +-// If the file is not open in the editor, the errors go away +-const test38878 = ` +--- go.mod -- +-module foo - --import ( -- "bytes" -- "context" -- "fmt" +-go 1.12 +--- a.go -- +-package x - -- "golang.org/x/mod/modfile" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/event" --) +-// import "fmt" - --func Hover(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, position protocol.Position) (*protocol.Hover, error) { -- // We only provide hover information for the view's go.work file. -- if fh.URI() != snapshot.WorkFile() { -- return nil, nil -- } +-func f() {} - -- ctx, done := event.Start(ctx, "work.Hover") -- defer done() +--- a_test.go -- +-package x - -- // Get the position of the cursor. -- pw, err := snapshot.ParseWork(ctx, fh) -- if err != nil { -- return nil, fmt.Errorf("getting go.work file handle: %w", err) -- } -- offset, err := pw.Mapper.PositionOffset(position) -- if err != nil { -- return nil, fmt.Errorf("computing cursor offset: %w", err) -- } +-import "testing" - -- // Confirm that the cursor is inside a use statement, and then find -- // the position of the use statement's directory path. -- use, pathStart, pathEnd := usePath(pw, offset) +-func TestA(t *testing.T) { +- f(3) +-} +-` - -- // The cursor position is not on a use statement. -- if use == nil { -- return nil, nil -- } +-// Tests golang/go#38878: deleting a test file should clear its errors, and +-// not break the workspace. +-func TestDeleteTestVariant(t *testing.T) { +- Run(t, test38878, func(t *testing.T, env *Env) { +- env.AfterChange(Diagnostics(env.AtRegexp("a_test.go", `f\((3)\)`))) +- env.RemoveWorkspaceFile("a_test.go") +- env.AfterChange(NoDiagnostics(ForFile("a_test.go"))) - -- // Get the mod file denoted by the use. -- modfh, err := snapshot.GetFile(ctx, modFileURI(pw, use)) -- if err != nil { -- return nil, fmt.Errorf("getting modfile handle: %w", err) -- } -- pm, err := snapshot.ParseMod(ctx, modfh) -- if err != nil { -- return nil, fmt.Errorf("getting modfile handle: %w", err) -- } -- mod := pm.File.Module.Mod +- // Make sure the test variant has been removed from the workspace by +- // triggering a metadata load. +- env.OpenFile("a.go") +- env.RegexpReplace("a.go", `// import`, "import") +- env.AfterChange(Diagnostics(env.AtRegexp("a.go", `"fmt"`))) +- }) +-} - -- // Get the range to highlight for the hover. -- rng, err := pw.Mapper.OffsetRange(pathStart, pathEnd) -- if err != nil { -- return nil, err -- } -- options := snapshot.View().Options() -- return &protocol.Hover{ -- Contents: protocol.MarkupContent{ -- Kind: options.PreferredContentFormat, -- Value: mod.Path, -- }, -- Range: rng, -- }, nil +-// Tests golang/go#38878: deleting a test file on disk while it's still open +-// should not clear its errors. +-func TestDeleteTestVariant_DiskOnly(t *testing.T) { +- Run(t, test38878, func(t *testing.T, env *Env) { +- env.OpenFile("a_test.go") +- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) +- env.Sandbox.Workdir.RemoveFile(context.Background(), "a_test.go") +- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) +- }) -} - --func usePath(pw *source.ParsedWorkFile, offset int) (use *modfile.Use, pathStart, pathEnd int) { -- for _, u := range pw.File.Use { -- path := []byte(u.Path) -- s, e := u.Syntax.Start.Byte, u.Syntax.End.Byte -- i := bytes.Index(pw.Mapper.Content[s:e], path) -- if i == -1 { -- // This should not happen. -- continue -- } -- // Shift the start position to the location of the -- // module directory within the use statement. -- pathStart, pathEnd = s+i, s+i+len(path) -- if pathStart <= offset && offset <= pathEnd { -- return u, pathStart, pathEnd -- } -- } -- return nil, 0, 0 +-// TestNoMod confirms that gopls continues to work when a user adds a go.mod +-// file to their workspace. +-func TestNoMod(t *testing.T) { +- const noMod = ` +--- main.go -- +-package main +- +-import "mod.com/bob" +- +-func main() { +- bob.Hello() -} -diff -urN a/gopls/internal/lsp/workspace.go b/gopls/internal/lsp/workspace.go ---- a/gopls/internal/lsp/workspace.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/workspace.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,95 +0,0 @@ --// Copyright 2019 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +--- bob/bob.go -- +-package bob - --package lsp +-func Hello() { +- var x int +-} +-` +- +- t.Run("manual", func(t *testing.T) { +- Run(t, noMod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), +- ) +- env.CreateBuffer("go.mod", `module mod.com +- +- go 1.12 +-`) +- env.SaveBuffer("go.mod") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("bob/bob.go", "x")), +- ReadDiagnostics("bob/bob.go", &d), +- ) +- if len(d.Diagnostics) != 1 { +- t.Fatalf("expected 1 diagnostic, got %v", len(d.Diagnostics)) +- } +- }) +- }) +- t.Run("initialized", func(t *testing.T) { +- Run(t, noMod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), +- ) +- env.RunGoCommand("mod", "init", "mod.com") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("bob/bob.go", "x")), +- ) +- }) +- }) +- +- t.Run("without workspace module", func(t *testing.T) { +- WithOptions( +- Modes(Default), +- ).Run(t, noMod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), +- ) +- if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}, nil, true); err != nil { +- t.Fatal(err) +- } +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("bob/bob.go", "x")), +- ) +- }) +- }) +-} - --import ( -- "context" -- "fmt" +-// Tests golang/go#38267. +-func TestIssue38267(t *testing.T) { +- const testPackage = ` +--- go.mod -- +-module mod.com - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/gopls/internal/span" --) +-go 1.12 +--- lib.go -- +-package lib - --func (s *Server) didChangeWorkspaceFolders(ctx context.Context, params *protocol.DidChangeWorkspaceFoldersParams) error { -- event := params.Event -- for _, folder := range event.Removed { -- view := s.session.View(folder.Name) -- if view != nil { -- s.session.RemoveView(view) -- } else { -- return fmt.Errorf("view %s for %v not found", folder.Name, folder.URI) -- } -- } -- return s.addFolders(ctx, event.Added) +-func Hello(x string) { +- _ = x -} +--- lib_test.go -- +-package lib - --// addView returns a Snapshot and a release function that must be --// called when it is no longer needed. --func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.Snapshot, func(), error) { -- s.stateMu.Lock() -- state := s.state -- s.stateMu.Unlock() -- if state < serverInitialized { -- return nil, nil, fmt.Errorf("addView called before server initialized") -- } -- options := s.session.Options().Clone() -- if err := s.fetchConfig(ctx, name, uri, options); err != nil { -- return nil, nil, err -- } -- _, snapshot, release, err := s.session.NewView(ctx, name, uri, options) -- return snapshot, release, err +-import "testing" +- +-type testStruct struct{ +- name string -} - --func (s *Server) didChangeConfiguration(ctx context.Context, _ *protocol.DidChangeConfigurationParams) error { -- // Apply any changes to the session-level settings. -- options := s.session.Options().Clone() -- if err := s.fetchConfig(ctx, "", "", options); err != nil { -- return err +-func TestHello(t *testing.T) { +- testStructs := []*testStruct{ +- &testStruct{"hello"}, +- &testStruct{"goodbye"}, - } -- s.session.SetOptions(options) -- -- // Go through each view, getting and updating its configuration. -- for _, view := range s.session.Views() { -- options := s.session.Options().Clone() -- if err := s.fetchConfig(ctx, view.Name(), view.Folder(), options); err != nil { -- return err -- } -- view, err := s.session.SetViewOptions(ctx, view, options) -- if err != nil { -- return err -- } -- go func() { -- snapshot, release, err := view.Snapshot() -- if err != nil { -- return // view is shut down; no need to diagnose -- } -- defer release() -- s.diagnoseDetached(snapshot) -- }() +- for y := range testStructs { +- _ = y - } -- -- // An options change may have affected the detected Go version. -- s.checkViewGoVersions() -- -- return nil -} +-` - --func semanticTokenRegistration(tokenTypes, tokenModifiers []string) protocol.Registration { -- return protocol.Registration{ -- ID: "textDocument/semanticTokens", -- Method: "textDocument/semanticTokens", -- RegisterOptions: &protocol.SemanticTokensOptions{ -- Legend: protocol.SemanticTokensLegend{ -- // TODO(pjw): trim these to what we use (and an unused one -- // at position 0 of TokTypes, to catch typos) -- TokenTypes: tokenTypes, -- TokenModifiers: tokenModifiers, -- }, -- Full: &protocol.Or_SemanticTokensOptions_full{Value: true}, -- Range: &protocol.Or_SemanticTokensOptions_range{Value: true}, -- }, -- } +- Run(t, testPackage, func(t *testing.T, env *Env) { +- env.OpenFile("lib_test.go") +- env.AfterChange( +- Diagnostics(AtPosition("lib_test.go", 10, 2)), +- Diagnostics(AtPosition("lib_test.go", 11, 2)), +- ) +- env.OpenFile("lib.go") +- env.RegexpReplace("lib.go", "_ = x", "var y int") +- env.AfterChange( +- Diagnostics(env.AtRegexp("lib.go", "y int")), +- NoDiagnostics(ForFile("lib_test.go")), +- ) +- }) -} -diff -urN a/gopls/internal/lsp/workspace_symbol.go b/gopls/internal/lsp/workspace_symbol.go ---- a/gopls/internal/lsp/workspace_symbol.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/lsp/workspace_symbol.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,32 +0,0 @@ --// Copyright 2020 The Go Authors. 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 -- --import ( -- "context" +-// Tests golang/go#38328. +-func TestPackageChange_Issue38328(t *testing.T) { +- const packageChange = ` +--- go.mod -- +-module fake - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/event" --) +-go 1.12 +--- a.go -- +-package foo +-func main() {} +-` +- Run(t, packageChange, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- env.RegexpReplace("a.go", "foo", "foox") +- env.AfterChange( +- NoDiagnostics(ForFile("a.go")), +- ) +- }) +-} - --func (s *Server) symbol(ctx context.Context, params *protocol.WorkspaceSymbolParams) ([]protocol.SymbolInformation, error) { -- ctx, done := event.Start(ctx, "lsp.Server.symbol") -- defer done() +-const testPackageWithRequire = ` +--- go.mod -- +-module mod.com - -- views := s.session.Views() -- matcher := s.session.Options().SymbolMatcher -- style := s.session.Options().SymbolStyle -- // TODO(rfindley): it looks wrong that we need to pass views here. -- // -- // Evidence: -- // - this is the only place we convert views to []source.View -- // - workspace symbols is the only place where we call source.View.Snapshot -- var sourceViews []source.View -- for _, v := range views { -- sourceViews = append(sourceViews, v) -- } -- return source.WorkspaceSymbols(ctx, matcher, style, sourceViews, params.Query) --} -diff -urN a/gopls/internal/regtest/bench/bench_test.go b/gopls/internal/regtest/bench/bench_test.go ---- a/gopls/internal/regtest/bench/bench_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/bench_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,249 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-go 1.12 - --package bench +-require foo.test v1.2.3 +--- go.sum -- +-foo.test v1.2.3 h1:TMA+lyd1ck0TqjSFpNe4T6cf/K6TYkoHwOOcMBMjaEw= +-foo.test v1.2.3/go.mod h1:Ij3kyLIe5lzjycjh13NL8I2gX0quZuTdW0MnmlwGBL4= +--- print.go -- +-package lib - -import ( -- "context" -- "flag" - "fmt" -- "io/ioutil" -- "log" -- "os" -- "os/exec" -- "path/filepath" -- "sync" -- "testing" -- "time" -- -- "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp/cmd" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/internal/bug" -- "golang.org/x/tools/internal/event" -- "golang.org/x/tools/internal/fakenet" -- "golang.org/x/tools/internal/jsonrpc2" -- "golang.org/x/tools/internal/jsonrpc2/servertest" -- "golang.org/x/tools/internal/tool" - -- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "foo.test/bar" -) - --var ( -- goplsPath = flag.String("gopls_path", "", "if set, use this gopls for testing; incompatible with -gopls_commit") -- -- installGoplsOnce sync.Once // guards installing gopls at -gopls_commit -- goplsCommit = flag.String("gopls_commit", "", "if set, install and use gopls at this commit for testing; incompatible with -gopls_path") +-func PrintAnswer() { +- fmt.Printf("answer: %s", bar.Answer) +-} +-` - -- cpuProfile = flag.String("gopls_cpuprofile", "", "if set, the cpu profile file suffix; see \"Profiling\" in the package doc") -- memProfile = flag.String("gopls_memprofile", "", "if set, the mem profile file suffix; see \"Profiling\" in the package doc") -- trace = flag.String("gopls_trace", "", "if set, the trace file suffix; see \"Profiling\" in the package doc") +-const testPackageWithRequireProxy = ` +--- foo.test@v1.2.3/go.mod -- +-module foo.test - -- // If non-empty, tempDir is a temporary working dir that was created by this -- // test suite. -- makeTempDirOnce sync.Once // guards creation of the temp dir -- tempDir string --) +-go 1.12 +--- foo.test@v1.2.3/bar/const.go -- +-package bar - --// if runAsGopls is "true", run the gopls command instead of the testing.M. --const runAsGopls = "_GOPLS_BENCH_RUN_AS_GOPLS" +-const Answer = 42 +-` - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- if os.Getenv(runAsGopls) == "true" { -- tool.Main(context.Background(), cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) -- os.Exit(0) -- } -- event.SetExporter(nil) // don't log to stderr -- code := m.Run() -- if err := cleanup(); err != nil { -- fmt.Fprintf(os.Stderr, "cleaning up after benchmarks: %v\n", err) -- if code == 0 { -- code = 1 -- } -- } -- os.Exit(code) +-func TestResolveDiagnosticWithDownload(t *testing.T) { +- WithOptions( +- ProxyFiles(testPackageWithRequireProxy), +- ).Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { +- env.OpenFile("print.go") +- // Check that gopackages correctly loaded this dependency. We should get a +- // diagnostic for the wrong formatting type. +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("print.go", "fmt.Printf"), +- WithMessage("wrong type int"), +- ), +- ) +- }) -} - --// getTempDir returns the temporary directory to use for benchmark files, --// creating it if necessary. --func getTempDir() string { -- makeTempDirOnce.Do(func() { -- var err error -- tempDir, err = ioutil.TempDir("", "gopls-bench") -- if err != nil { -- log.Fatal(err) -- } +-func TestMissingDependency(t *testing.T) { +- Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { +- env.OpenFile("print.go") +- env.Await( +- // Log messages are asynchronous to other events on the LSP stream, so we +- // can't use OnceMet or AfterChange here. +- LogMatching(protocol.Error, "initial workspace load failed", 1, false), +- ) - }) -- return tempDir -} - --// shallowClone performs a shallow clone of repo into dir at the given --// 'commitish' ref (any commit reference understood by git). --// --// The directory dir must not already exist. --func shallowClone(dir, repo, commitish string) error { -- if err := os.Mkdir(dir, 0750); err != nil { -- return fmt.Errorf("creating dir for %s: %v", repo, err) -- } -- -- // Set a timeout for git fetch. If this proves flaky, it can be removed. -- ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) -- defer cancel() +-// Tests golang/go#36951. +-func TestAdHocPackages_Issue36951(t *testing.T) { +- const adHoc = ` +--- b/b.go -- +-package b - -- // Use a shallow fetch to download just the relevant commit. -- shInit := fmt.Sprintf("git init && git fetch --depth=1 %q %q && git checkout FETCH_HEAD", repo, commitish) -- initCmd := exec.CommandContext(ctx, "/bin/sh", "-c", shInit) -- initCmd.Dir = dir -- if output, err := initCmd.CombinedOutput(); err != nil { -- return fmt.Errorf("checking out %s: %v\n%s", repo, err, output) -- } -- return nil +-func Hello() { +- var x int -} -- --// connectEditor connects a fake editor session in the given dir, using the --// given editor config. --func connectEditor(dir string, config fake.EditorConfig, ts servertest.Connector) (*fake.Sandbox, *fake.Editor, *Awaiter, error) { -- s, err := fake.NewSandbox(&fake.SandboxConfig{ -- Workdir: dir, -- GOPROXY: "https://proxy.golang.org", +-` +- Run(t, adHoc, func(t *testing.T, env *Env) { +- env.OpenFile("b/b.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("b/b.go", "x")), +- ) - }) -- if err != nil { -- return nil, nil, nil, err -- } +-} - -- a := NewAwaiter(s.Workdir) -- const skipApplyEdits = false -- editor, err := fake.NewEditor(s, config).Connect(context.Background(), ts, a.Hooks(), skipApplyEdits) -- if err != nil { -- return nil, nil, nil, err -- } +-// Tests golang/go#37984: GOPATH should be read from the go command. +-func TestNoGOPATH_Issue37984(t *testing.T) { +- const files = ` +--- main.go -- +-package main - -- return s, editor, a, nil +-func _() { +- fmt.Println("Hello World") -} -- --// newGoplsServer returns a connector that connects to a new gopls process. --func newGoplsServer(name string) (servertest.Connector, error) { -- if *goplsPath != "" && *goplsCommit != "" { -- panic("can't set both -gopls_path and -gopls_commit") -- } -- var ( -- goplsPath = *goplsPath -- env []string -- ) -- if *goplsCommit != "" { -- goplsPath = getInstalledGopls() -- } -- if goplsPath == "" { -- var err error -- goplsPath, err = os.Executable() -- if err != nil { -- return nil, err -- } -- env = []string{fmt.Sprintf("%s=true", runAsGopls)} -- } -- var args []string -- if *cpuProfile != "" { -- args = append(args, fmt.Sprintf("-profile.cpu=%s", name+"."+*cpuProfile)) -- } -- if *memProfile != "" { -- args = append(args, fmt.Sprintf("-profile.mem=%s", name+"."+*memProfile)) -- } -- if *trace != "" { -- args = append(args, fmt.Sprintf("-profile.trace=%s", name+"."+*trace)) -- } -- return &SidecarServer{ -- goplsPath: goplsPath, -- env: env, -- args: args, -- }, nil +-` +- WithOptions( +- EnvVars{ +- "GOPATH": "", +- "GO111MODULE": "off", +- }, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "fmt"))) +- env.SaveBuffer("main.go") +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) +- }) -} - --// getInstalledGopls builds gopls at the given -gopls_commit, returning the --// path to the gopls binary. --func getInstalledGopls() string { -- if *goplsCommit == "" { -- panic("must provide -gopls_commit") -- } -- toolsDir := filepath.Join(getTempDir(), "gopls_build") -- goplsPath := filepath.Join(toolsDir, "gopls", "gopls") +-// Tests golang/go#38669. +-func TestEqualInEnv_Issue38669(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- installGoplsOnce.Do(func() { -- log.Printf("installing gopls: checking out x/tools@%s into %s\n", *goplsCommit, toolsDir) -- if err := shallowClone(toolsDir, "https://go.googlesource.com/tools", *goplsCommit); err != nil { -- log.Fatal(err) -- } +-go 1.12 +--- main.go -- +-package main - -- log.Println("installing gopls: building...") -- bld := exec.Command("go", "build", ".") -- bld.Dir = filepath.Join(toolsDir, "gopls") -- if output, err := bld.CombinedOutput(); err != nil { -- log.Fatalf("building gopls: %v\n%s", err, output) -- } +-var _ = x.X +--- x/x.go -- +-package x - -- // Confirm that the resulting path now exists. -- if _, err := os.Stat(goplsPath); err != nil { -- log.Fatalf("os.Stat(%s): %v", goplsPath, err) -- } +-var X = 0 +-` +- WithOptions( +- EnvVars{"GOFLAGS": "-tags=foo"}, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.OrganizeImports("main.go") +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) - }) -- return goplsPath -} - --// A SidecarServer starts (and connects to) a separate gopls process at the --// given path. --type SidecarServer struct { -- goplsPath string -- env []string // additional environment bindings -- args []string // command-line arguments --} +-// Tests golang/go#38467. +-func TestNoSuggestedFixesForGeneratedFiles_Issue38467(t *testing.T) { +- const generated = ` +--- go.mod -- +-module mod.com - --// Connect creates new io.Pipes and binds them to the underlying StreamServer. --// --// It implements the servertest.Connector interface. --func (s *SidecarServer) Connect(ctx context.Context) jsonrpc2.Conn { -- // Note: don't use CommandContext here, as we want gopls to exit gracefully -- // in order to write out profile data. -- // -- // We close the connection on context cancelation below. -- cmd := exec.Command(s.goplsPath, s.args...) +-go 1.12 +--- main.go -- +-package main - -- stdin, err := cmd.StdinPipe() -- if err != nil { -- log.Fatal(err) -- } -- stdout, err := cmd.StdoutPipe() -- if err != nil { -- log.Fatal(err) -- } -- cmd.Stderr = os.Stderr -- cmd.Env = append(os.Environ(), s.env...) -- if err := cmd.Start(); err != nil { -- log.Fatalf("starting gopls: %v", err) -- } +-// Code generated by generator.go. DO NOT EDIT. - -- go func() { -- // If we don't log.Fatal here, benchmarks may hang indefinitely if gopls -- // exits abnormally. -- // -- // TODO(rfindley): ideally we would shut down the connection gracefully, -- // but that doesn't currently work. -- if err := cmd.Wait(); err != nil { -- log.Fatalf("gopls invocation failed with error: %v", err) +-func _() { +- for i, _ := range []string{} { +- _ = i +- } +-} +-` +- Run(t, generated, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(AtPosition("main.go", 5, 8)), +- ReadDiagnostics("main.go", &d), +- ) +- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { +- t.Errorf("got quick fixes %v, wanted none", fixes) - } -- }() +- }) +-} - -- clientStream := jsonrpc2.NewHeaderStream(fakenet.NewConn("stdio", stdout, stdin)) -- clientConn := jsonrpc2.NewConn(clientStream) +-// Expect a module/GOPATH error if there is an error in the file at startup. +-// Tests golang/go#37279. +-func TestBrokenWorkspace_OutsideModule(t *testing.T) { +- const noModule = ` +--- a.go -- +-package foo - -- go func() { -- select { -- case <-ctx.Done(): -- clientConn.Close() -- clientStream.Close() -- case <-clientConn.Done(): -- } -- }() +-import "mod.com/hello" - -- return clientConn +-func f() { +- hello.Goodbye() +-} +-` +- Run(t, noModule, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- env.AfterChange( +- // Expect the adHocPackagesWarning. +- OutstandingWork(lsp.WorkspaceLoadFailure, "outside of a module"), +- ) +- // Deleting the import dismisses the warning. +- env.RegexpReplace("a.go", `import "mod.com/hello"`, "") +- env.AfterChange( +- NoOutstandingWork(), +- ) +- }) +-} +- +-func TestNonGoFolder(t *testing.T) { +- const files = ` +--- hello.txt -- +-hi mom +-` +- for _, go111module := range []string{"on", "off", ""} { +- t.Run(fmt.Sprintf("GO111MODULE_%v", go111module), func(t *testing.T) { +- WithOptions( +- EnvVars{"GO111MODULE": go111module}, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- NoOutstandingWork(), +- ) +- }) +- }) +- } -} -diff -urN a/gopls/internal/regtest/bench/completion_test.go b/gopls/internal/regtest/bench/completion_test.go ---- a/gopls/internal/regtest/bench/completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/completion_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,173 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --package bench - --import ( -- "fmt" -- "testing" +-// Tests the repro case from golang/go#38602. Diagnostics are now handled properly, +-// which blocks type checking. +-func TestConflictingMainPackageErrors(t *testing.T) { +- const collision = ` +--- x/x.go -- +-package x - -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-import "x/hello" - --// TODO(rfindley): update these completion tests to run on multiple repos. +-func Hello() { +- hello.HiThere() +-} +--- x/main.go -- +-package main - --type completionBenchOptions struct { -- file, locationRegexp string +-func main() { +- fmt.Println("") +-} +-` +- WithOptions( +- InGOPATH(), +- EnvVars{"GO111MODULE": "off"}, +- ).Run(t, collision, func(t *testing.T, env *Env) { +- env.OpenFile("x/x.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("x/x.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), +- Diagnostics(env.AtRegexp("x/main.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), +- ) - -- // Hooks to run edits before initial completion -- setup func(*Env) // run before the benchmark starts -- beforeCompletion func(*Env) // run before each completion +- // We don't recover cleanly from the errors without good overlay support. +- if testenv.Go1Point() >= 16 { +- env.RegexpReplace("x/x.go", `package x`, `package main`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("x/main.go", `fmt`)), +- ) +- } +- }) -} - --func benchmarkCompletion(options completionBenchOptions, b *testing.B) { -- repo := getRepo(b, "tools") -- env := repo.newEnv(b, "completion.tools", fake.EditorConfig{}) -- defer env.Close() +-const ardanLabsProxy = ` +--- github.com/ardanlabs/conf@v1.2.3/go.mod -- +-module github.com/ardanlabs/conf - -- // Run edits required for this completion. -- if options.setup != nil { -- options.setup(env) -- } +-go 1.12 +--- github.com/ardanlabs/conf@v1.2.3/conf.go -- +-package conf - -- // Run a completion to make sure the system is warm. -- loc := env.RegexpSearch(options.file, options.locationRegexp) -- completions := env.Completion(loc) +-var ErrHelpWanted error +-` - -- if testing.Verbose() { -- fmt.Println("Results:") -- for i := 0; i < len(completions.Items); i++ { -- fmt.Printf("\t%d. %v\n", i, completions.Items[i]) -- } -- } +-// Test for golang/go#38211. +-func Test_Issue38211(t *testing.T) { +- const ardanLabs = ` +--- go.mod -- +-module mod.com - -- b.Run("tools", func(b *testing.B) { -- for i := 0; i < b.N; i++ { -- if options.beforeCompletion != nil { -- options.beforeCompletion(env) -- } -- env.Completion(loc) -- } +-go 1.14 +--- main.go -- +-package main +- +-import "github.com/ardanlabs/conf" +- +-func main() { +- _ = conf.ErrHelpWanted +-} +-` +- WithOptions( +- ProxyFiles(ardanLabsProxy), +- ).Run(t, ardanLabs, func(t *testing.T, env *Env) { +- // Expect a diagnostic with a suggested fix to add +- // "github.com/ardanlabs/conf" to the go.mod file. +- env.OpenFile("go.mod") +- env.OpenFile("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), +- ReadDiagnostics("main.go", &d), +- ) +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.SaveBuffer("go.mod") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- // Comment out the line that depends on conf and expect a +- // diagnostic and a fix to remove the import. +- env.RegexpReplace("main.go", "_ = conf.ErrHelpWanted", "//_ = conf.ErrHelpWanted") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), +- ) +- env.SaveBuffer("main.go") +- // Expect a diagnostic and fix to remove the dependency in the go.mod. +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- Diagnostics(env.AtRegexp("go.mod", "require github.com/ardanlabs/conf"), WithMessage("not used in this module")), +- ReadDiagnostics("go.mod", &d), +- ) +- env.ApplyQuickFixes("go.mod", d.Diagnostics) +- env.SaveBuffer("go.mod") +- env.AfterChange( +- NoDiagnostics(ForFile("go.mod")), +- ) +- // Uncomment the lines and expect a new diagnostic for the import. +- env.RegexpReplace("main.go", "//_ = conf.ErrHelpWanted", "_ = conf.ErrHelpWanted") +- env.SaveBuffer("main.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), +- ) - }) -} - --// endRangeInBuffer returns the position for last character in the buffer for --// the given file. --func endRangeInBuffer(env *Env, name string) protocol.Range { -- buffer := env.BufferText(name) -- m := protocol.NewMapper("", []byte(buffer)) -- rng, err := m.OffsetRange(len(buffer), len(buffer)) -- if err != nil { -- env.T.Fatal(err) -- } -- return rng --} +-// Test for golang/go#38207. +-func TestNewModule_Issue38207(t *testing.T) { +- const emptyFile = ` +--- go.mod -- +-module mod.com - --// Benchmark struct completion in tools codebase. --func BenchmarkStructCompletion(b *testing.B) { -- file := "internal/lsp/cache/session.go" +-go 1.12 +--- main.go -- +-` +- WithOptions( +- ProxyFiles(ardanLabsProxy), +- ).Run(t, emptyFile, func(t *testing.T, env *Env) { +- env.CreateBuffer("main.go", `package main - -- setup := func(env *Env) { -- env.OpenFile(file) -- env.EditBuffer(file, protocol.TextEdit{ -- Range: endRangeInBuffer(env, file), -- NewText: "\nvar testVariable map[string]bool = Session{}.\n", -- }) -- } +-import "github.com/ardanlabs/conf" - -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `var testVariable map\[string\]bool = Session{}(\.)`, -- setup: setup, -- }, b) +-func main() { +- _ = conf.ErrHelpWanted -} -- --// Benchmark import completion in tools codebase. --func BenchmarkImportCompletion(b *testing.B) { -- const file = "internal/lsp/source/completion/completion.go" -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `go\/()`, -- setup: func(env *Env) { env.OpenFile(file) }, -- }, b) +-`) +- env.SaveBuffer("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`), WithMessage("no required module")), +- ReadDiagnostics("main.go", &d), +- ) +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- }) -} - --// Benchmark slice completion in tools codebase. --func BenchmarkSliceCompletion(b *testing.B) { -- file := "internal/lsp/cache/session.go" +-// Test for golang/go#36960. +-func TestNewFileBadImports_Issue36960(t *testing.T) { +- const simplePackage = ` +--- go.mod -- +-module mod.com - -- setup := func(env *Env) { -- env.OpenFile(file) -- env.EditBuffer(file, protocol.TextEdit{ -- Range: endRangeInBuffer(env, file), -- NewText: "\nvar testVariable []byte = \n", -- }) -- } +-go 1.14 +--- a/a1.go -- +-package a - -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `var testVariable \[\]byte (=)`, -- setup: setup, -- }, b) --} +-import "fmt" - --// Benchmark deep completion in function call in tools codebase. --func BenchmarkFuncDeepCompletion(b *testing.B) { -- file := "internal/lsp/source/completion/completion.go" -- fileContent := ` --func (c *completer) _() { -- c.inference.kindMatches(c.) +-func _() { +- fmt.Println("hi") -} -` -- setup := func(env *Env) { -- env.OpenFile(file) -- originalBuffer := env.BufferText(file) -- env.EditBuffer(file, protocol.TextEdit{ -- Range: endRangeInBuffer(env, file), -- NewText: originalBuffer + fileContent, -- }) -- } +- Run(t, simplePackage, func(t *testing.T, env *Env) { +- env.OpenFile("a/a1.go") +- env.CreateBuffer("a/a2.go", ``) +- env.SaveBufferWithoutActions("a/a2.go") +- env.AfterChange( +- NoDiagnostics(ForFile("a/a1.go")), +- ) +- env.EditBuffer("a/a2.go", fake.NewEdit(0, 0, 0, 0, `package a`)) +- env.AfterChange( +- NoDiagnostics(ForFile("a/a1.go")), +- ) +- }) +-} - -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, -- setup: setup, -- }, b) +-// This test tries to replicate the workflow of a user creating a new x test. +-// It also tests golang/go#39315. +-func TestManuallyCreatingXTest(t *testing.T) { +- // Create a package that already has a test variant (in-package test). +- const testVariant = ` +--- go.mod -- +-module mod.com +- +-go 1.15 +--- hello/hello.go -- +-package hello +- +-func Hello() { +- var x int -} +--- hello/hello_test.go -- +-package hello - --// Benchmark completion following an arbitrary edit. --// --// Edits force type-checked packages to be invalidated, so we want to measure --// how long it takes before completion results are available. --func BenchmarkCompletionFollowingEdit(b *testing.B) { -- file := "internal/lsp/source/completion/completion2.go" -- fileContent := ` --package completion +-import "testing" - --func (c *completer) _() { -- c.inference.kindMatches(c.) -- // __MAGIC_STRING_1 +-func TestHello(t *testing.T) { +- var x int +- Hello() -} -` -- setup := func(env *Env) { -- env.CreateBuffer(file, fileContent) -- } +- Run(t, testVariant, func(t *testing.T, env *Env) { +- // Open the file, triggering the workspace load. +- // There are errors in the code to ensure all is working as expected. +- env.OpenFile("hello/hello.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("hello/hello.go", "x")), +- Diagnostics(env.AtRegexp("hello/hello_test.go", "x")), +- ) - -- n := 1 -- beforeCompletion := func(env *Env) { -- old := fmt.Sprintf("__MAGIC_STRING_%d", n) -- new := fmt.Sprintf("__MAGIC_STRING_%d", n+1) -- n++ -- env.RegexpReplace(file, old, new) -- } +- // Create an empty file with the intention of making it an x test. +- // This resembles a typical flow in an editor like VS Code, in which +- // a user would create an empty file and add content, saving +- // intermittently. +- // TODO(rstambler): There might be more edge cases here, as file +- // content can be added incrementally. +- env.CreateBuffer("hello/hello_x_test.go", ``) - -- benchmarkCompletion(completionBenchOptions{ -- file: file, -- locationRegexp: `func \(c \*completer\) _\(\) {\n\tc\.inference\.kindMatches\((c)`, -- setup: setup, -- beforeCompletion: beforeCompletion, -- }, b) --} -diff -urN a/gopls/internal/regtest/bench/definition_test.go b/gopls/internal/regtest/bench/definition_test.go ---- a/gopls/internal/regtest/bench/definition_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/definition_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,39 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +- // Save the empty file (no actions since formatting will fail). +- env.SaveBufferWithoutActions("hello/hello_x_test.go") - --package bench +- // Add the content. The missing import is for the package under test. +- env.EditBuffer("hello/hello_x_test.go", fake.NewEdit(0, 0, 0, 0, `package hello_test - -import ( - "testing" -) - --func BenchmarkDefinition(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, -- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`}, -- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, -- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, -- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, -- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, -- } -- -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- loc := env.RegexpSearch(test.file, test.regexp) -- env.Await(env.DoneWithOpen()) -- env.GoToDefinition(loc) // pre-warm the query, and open the target file -- b.ResetTimer() -- -- for i := 0; i < b.N; i++ { -- env.GoToDefinition(loc) // pre-warm the query -- } -- }) -- } +-func TestHello(t *testing.T) { +- hello.Hello() +-} +-`)) +- // Expect a diagnostic for the missing import. Save, which should +- // trigger import organization. The diagnostic should clear. +- env.AfterChange( +- Diagnostics(env.AtRegexp("hello/hello_x_test.go", "hello.Hello")), +- ) +- env.SaveBuffer("hello/hello_x_test.go") +- env.AfterChange( +- NoDiagnostics(ForFile("hello/hello_x_test.go")), +- ) +- }) -} -diff -urN a/gopls/internal/regtest/bench/didchange_test.go b/gopls/internal/regtest/bench/didchange_test.go ---- a/gopls/internal/regtest/bench/didchange_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/didchange_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,99 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --package bench - --import ( -- "fmt" -- "sync/atomic" -- "testing" -- "time" +-// Reproduce golang/go#40690. +-func TestCreateOnlyXTest(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" --) +-go 1.12 +--- foo/foo.go -- +-package foo +--- foo/bar_test.go -- +-` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("foo/bar_test.go") +- env.EditBuffer("foo/bar_test.go", fake.NewEdit(0, 0, 0, 0, "package foo")) +- env.Await(env.DoneWithChange()) +- env.RegexpReplace("foo/bar_test.go", "package foo", `package foo_test - --// Use a global edit counter as bench function may execute multiple times, and --// we want to avoid cache hits. Use time.Now to also avoid cache hits from the --// shared file cache. --var editID int64 = time.Now().UnixNano() +-import "testing" - --var didChangeTests = []struct { -- repo string -- file string --}{ -- {"istio", "pkg/fuzz/util.go"}, -- {"kubernetes", "pkg/controller/lookup_cache.go"}, -- {"kuma", "api/generic/insights.go"}, -- {"pkgsite", "internal/frontend/server.go"}, -- {"starlark", "starlark/eval.go"}, -- {"tools", "internal/lsp/cache/snapshot.go"}, +-func TestX(t *testing.T) { +- var x int +-} +-`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("foo/bar_test.go", "x")), +- ) +- }) -} - --// BenchmarkDidChange benchmarks modifications of a single file by making --// synthetic modifications in a comment. It controls pacing by waiting for the --// server to actually start processing the didChange notification before --// proceeding. Notably it does not wait for diagnostics to complete. --func BenchmarkDidChange(b *testing.B) { -- for _, test := range didChangeTests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- // Insert the text we'll be modifying at the top of the file. -- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) -- env.AfterChange() -- b.ResetTimer() +-func TestChangePackageName(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - -- for i := 0; i < b.N; i++ { -- edits := atomic.AddInt64(&editID, 1) -- env.EditBuffer(test.file, protocol.TextEdit{ -- Range: protocol.Range{ -- Start: protocol.Position{Line: 0, Character: 0}, -- End: protocol.Position{Line: 1, Character: 0}, -- }, -- // Increment the placeholder text, to ensure cache misses. -- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), -- }) -- env.Await(env.StartedChange()) -- } -- }) -- } +-go 1.12 +--- foo/foo.go -- +-package foo +--- foo/bar_test.go -- +-package foo_ +-` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("foo/bar_test.go") +- env.AfterChange() +- env.RegexpReplace("foo/bar_test.go", "package foo_", "package foo_test") +- env.AfterChange( +- NoDiagnostics(ForFile("foo/bar_test.go")), +- NoDiagnostics(ForFile("foo/foo.go")), +- ) +- }) -} - --func BenchmarkDiagnoseChange(b *testing.B) { -- for _, test := range didChangeTests { -- b.Run(test.repo, func(b *testing.B) { -- // Use a new env to avoid the diagnostic delay: we want to measure how -- // long it takes to produce the diagnostics. -- env := repos[test.repo].newEnv(b, "diagnoseChange", fake.EditorConfig{ -- Settings: map[string]interface{}{ -- "diagnosticsDelay": "0s", -- }, -- }) -- env.OpenFile(test.file) -- // Insert the text we'll be modifying at the top of the file. -- env.EditBuffer(test.file, protocol.TextEdit{NewText: "// __REGTEST_PLACEHOLDER_0__\n"}) -- env.AfterChange() -- b.ResetTimer() +-func TestIgnoredFiles(t *testing.T) { +- const ws = ` +--- go.mod -- +-module mod.com - -- // We must use an extra subtest layer here, so that we only set up the -- // shared env once (otherwise we pay additional overhead and the profiling -- // flags don't work). -- b.Run("diagnose", func(b *testing.B) { -- for i := 0; i < b.N; i++ { -- edits := atomic.AddInt64(&editID, 1) -- env.EditBuffer(test.file, protocol.TextEdit{ -- Range: protocol.Range{ -- Start: protocol.Position{Line: 0, Character: 0}, -- End: protocol.Position{Line: 1, Character: 0}, -- }, -- // Increment the placeholder text, to ensure cache misses. -- NewText: fmt.Sprintf("// __REGTEST_PLACEHOLDER_%d__\n", edits), -- }) -- env.AfterChange() -- } -- }) -- }) -- } +-go 1.12 +--- _foo/x.go -- +-package x +- +-var _ = foo.Bar +-` +- Run(t, ws, func(t *testing.T, env *Env) { +- env.OpenFile("_foo/x.go") +- env.AfterChange( +- NoDiagnostics(ForFile("_foo/x.go")), +- ) +- }) -} -diff -urN a/gopls/internal/regtest/bench/doc.go b/gopls/internal/regtest/bench/doc.go ---- a/gopls/internal/regtest/bench/doc.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/doc.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,33 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --// The bench package implements benchmarks for various LSP operations. --// --// Benchmarks check out specific commits of popular and/or exemplary --// repositories, and script an external gopls process via a fake text editor. --// By default, benchmarks run the test executable as gopls (using a special --// "gopls mode" environment variable). A different gopls binary may be used by --// setting the -gopls_path or -gopls_commit flags. --// --// This package is a work in progress. --// --// # Profiling --// --// As benchmark functions run gopls in a separate process, the normal test --// flags for profiling are not useful. Instead the -gopls_cpuprofile, --// -gopls_memprofile, and -gopls_trace flags may be used to pass through --// profiling flags to the gopls process. Each of these flags sets a suffix --// for the respective gopls profiling flag, which is prefixed with a name --// corresponding to the shared repository or (in some cases) benchmark name. --// For example, settings -gopls_cpuprofile=cpu.out will result in profiles --// named tools.cpu.out, BenchmarkInitialWorkspaceLoad.cpu.out, etc. Here, --// tools.cpu.out is the cpu profile for the shared x/tools session, which may --// be used by multiple benchmark functions, and BenchmarkInitialWorkspaceLoad --// is the cpu profile for the last iteration of the initial workspace load --// test, which starts a new editor session for each iteration. --// --// # TODO --// - add more benchmarks, and more repositories --// - improve this documentation --package bench -diff -urN a/gopls/internal/regtest/bench/hover_test.go b/gopls/internal/regtest/bench/hover_test.go ---- a/gopls/internal/regtest/bench/hover_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/hover_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,39 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-// Partially reproduces golang/go#38977, moving a file between packages. +-// It also gets hit by some go command bug fixed in 1.15, but we don't +-// care about that so much here. +-func TestDeletePackage(t *testing.T) { +- const ws = ` +--- go.mod -- +-module mod.com +- +-go 1.15 +--- a/a.go -- +-package a +- +-const A = 1 - --package bench +--- b/b.go -- +-package b - --import ( -- "testing" --) +-import "mod.com/a" - --func BenchmarkHover(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"istio", "pkg/config/model.go", `gogotypes\.(MarshalAny)`}, -- {"kubernetes", "pkg/apis/core/types.go", "type (Pod)"}, -- {"kuma", "api/generic/insights.go", `proto\.(Message)`}, -- {"pkgsite", "internal/log/log.go", `derrors\.(Wrap)`}, -- {"starlark", "starlark/eval.go", "prog.compiled.(Encode)"}, -- {"tools", "internal/lsp/cache/check.go", `(snapshot)\) buildKey`}, -- } +-const B = a.A - -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- loc := env.RegexpSearch(test.file, test.regexp) -- env.Await(env.DoneWithOpen()) -- env.Hover(loc) // pre-warm the query -- b.ResetTimer() +--- c/c.go -- +-package c - -- for i := 0; i < b.N; i++ { -- env.Hover(loc) // pre-warm the query -- } -- }) -- } +-import "mod.com/a" +- +-const C = a.A +-` +- Run(t, ws, func(t *testing.T, env *Env) { +- env.OpenFile("b/b.go") +- env.Await(env.DoneWithOpen()) +- // Delete c/c.go, the only file in package c. +- env.RemoveWorkspaceFile("c/c.go") +- +- // We should still get diagnostics for files that exist. +- env.RegexpReplace("b/b.go", `a.A`, "a.Nonexistant") +- env.AfterChange( +- Diagnostics(env.AtRegexp("b/b.go", `Nonexistant`)), +- ) +- }) -} -diff -urN a/gopls/internal/regtest/bench/implementations_test.go b/gopls/internal/regtest/bench/implementations_test.go ---- a/gopls/internal/regtest/bench/implementations_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/implementations_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,37 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package bench +-// This is a copy of the scenario_default/quickfix_empty_files.txt test from +-// govim. Reproduces golang/go#39646. +-func TestQuickFixEmptyFiles(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - --import "testing" +-go 1.12 +-` +- // To fully recreate the govim tests, we create files by inserting +- // a newline, adding to the file, and then deleting the newline. +- // Wait for each event to process to avoid cancellations and force +- // package loads. +- writeGoVim := func(env *Env, name, content string) { +- env.WriteWorkspaceFile(name, "") +- env.Await(env.DoneWithChangeWatchedFiles()) - --func BenchmarkImplementations(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"istio", "pkg/config/mesh/watcher.go", `type (Watcher)`}, -- {"kubernetes", "pkg/controller/lookup_cache.go", `objectWithMeta`}, -- {"kuma", "api/generic/insights.go", `type (Insight)`}, -- {"pkgsite", "internal/datasource.go", `type (DataSource)`}, -- {"starlark", "syntax/syntax.go", `type (Expr)`}, -- {"tools", "internal/lsp/source/view.go", `type (Snapshot)`}, -- } +- env.CreateBuffer(name, "\n") +- env.Await(env.DoneWithOpen()) - -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- loc := env.RegexpSearch(test.file, test.regexp) -- env.Await(env.DoneWithOpen()) -- env.Implementations(loc) // pre-warm the query -- b.ResetTimer() +- env.EditBuffer(name, fake.NewEdit(1, 0, 1, 0, content)) +- env.Await(env.DoneWithChange()) - -- for i := 0; i < b.N; i++ { -- env.Implementations(loc) -- } -- }) +- env.EditBuffer(name, fake.NewEdit(0, 0, 1, 0, "")) +- env.Await(env.DoneWithChange()) - } +- +- const p = `package p; func DoIt(s string) {};` +- const main = `package main +- +-import "mod.com/p" +- +-func main() { +- p.DoIt(5) -} -diff -urN a/gopls/internal/regtest/bench/iwl_test.go b/gopls/internal/regtest/bench/iwl_test.go ---- a/gopls/internal/regtest/bench/iwl_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/iwl_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,77 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-` +- // A simple version of the test that reproduces most of the problems it +- // exposes. +- t.Run("short", func(t *testing.T) { +- Run(t, mod, func(t *testing.T, env *Env) { +- writeGoVim(env, "p/p.go", p) +- writeGoVim(env, "main.go", main) +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "5")), +- ) +- }) +- }) - --package bench +- // A full version that replicates the whole flow of the test. +- t.Run("full", func(t *testing.T) { +- Run(t, mod, func(t *testing.T, env *Env) { +- writeGoVim(env, "p/p.go", p) +- writeGoVim(env, "main.go", main) +- writeGoVim(env, "p/p_test.go", `package p +- +-import "testing" +- +-func TestDoIt(t *testing.T) { +- DoIt(5) +-} +-`) +- writeGoVim(env, "p/x_test.go", `package p_test - -import ( - "testing" - -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "mod.com/p" -) - --// BenchmarkInitialWorkspaceLoad benchmarks the initial workspace load time for --// a new editing session. --func BenchmarkInitialWorkspaceLoad(b *testing.B) { -- if testing.Short() { -- // TODO(rfindley): remove this skip once the released gopls version -- // supports the memstats command. -- b.Skip("temporarily skipping as baseline gopls versions do not support the memstats command") -- } -- tests := []struct { -- repo string -- file string -- }{ -- {"tools", "internal/lsp/cache/snapshot.go"}, -- {"kubernetes", "pkg/controller/lookup_cache.go"}, -- {"pkgsite", "internal/frontend/server.go"}, -- {"starlark", "starlark/eval.go"}, -- {"istio", "pkg/fuzz/util.go"}, -- {"kuma", "api/generic/insights.go"}, -- } +-func TestDoIt(t *testing.T) { +- p.DoIt(5) +-} +-`) +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "5")), +- Diagnostics(env.AtRegexp("p/p_test.go", "5")), +- Diagnostics(env.AtRegexp("p/x_test.go", "5")), +- ) +- env.RegexpReplace("p/p.go", "s string", "i int") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- NoDiagnostics(ForFile("p/p_test.go")), +- NoDiagnostics(ForFile("p/x_test.go")), +- ) +- }) +- }) +-} - -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- repo := getRepo(b, test.repo) -- // get the (initialized) shared env to ensure the cache is warm. -- // Reuse its GOPATH so that we get cache hits for things in the module -- // cache. -- sharedEnv := repo.sharedEnv(b) -- b.ResetTimer() +-func TestSingleFile(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - -- for i := 0; i < b.N; i++ { -- doIWL(b, sharedEnv.Sandbox.GOPATH(), repo, test.file) -- } -- }) -- } +-go 1.13 +--- a/a.go -- +-package a +- +-func _() { +- var x int +-} +-` +- WithOptions( +- // Empty workspace folders. +- WorkspaceFolders(), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "x")), +- ) +- }) -} - --func doIWL(b *testing.B, gopath string, repo *repo, file string) { -- // Exclude the time to set up the env from the benchmark time, as this may -- // involve installing gopls and/or checking out the repo dir. -- b.StopTimer() -- config := fake.EditorConfig{Env: map[string]string{"GOPATH": gopath}} -- env := repo.newEnv(b, "iwl."+repo.name, config) -- defer env.Close() -- b.StartTimer() +-// Reproduces the case described in +-// https://github.com/golang/go/issues/39296#issuecomment-652058883. +-func TestPkgm(t *testing.T) { +- const basic = ` +--- go.mod -- +-module mod.com - -- // Open an arbitrary file to ensure that gopls starts working. -- // -- // In the future, this may matter if gopls doesn't eagerly construct -- // the workspace. -- env.OpenFile(file) +-go 1.15 +--- foo/foo.go -- +-package foo - -- env.Await(InitialWorkspaceLoad) -- b.StopTimer() -- params := &protocol.ExecuteCommandParams{ -- Command: command.MemStats.ID(), -- } -- var memstats command.MemStatsResult -- env.ExecuteCommand(params, &memstats) -- b.ReportMetric(float64(memstats.HeapAlloc), "alloc_bytes") -- b.ReportMetric(float64(memstats.HeapInUse), "in_use_bytes") -- b.StartTimer() +-import "fmt" +- +-func Foo() { +- fmt.Println("") -} -diff -urN a/gopls/internal/regtest/bench/references_test.go b/gopls/internal/regtest/bench/references_test.go ---- a/gopls/internal/regtest/bench/references_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/references_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,37 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-` +- Run(t, basic, func(t *testing.T, env *Env) { +- env.WriteWorkspaceFile("foo/foo_test.go", `package main - --package bench +-func main() { - --import "testing" +-}`) +- env.OpenFile("foo/foo_test.go") +- env.RegexpReplace("foo/foo_test.go", `package main`, `package foo`) +- env.AfterChange(NoDiagnostics(ForFile("foo/foo.go"))) +- }) +-} - --func BenchmarkReferences(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- }{ -- {"istio", "pkg/config/model.go", "type (Meta)"}, -- {"kubernetes", "pkg/controller/lookup_cache.go", "type (objectWithMeta)"}, -- {"kuma", "pkg/events/interfaces.go", "type (Event)"}, -- {"pkgsite", "internal/log/log.go", "func (Infof)"}, -- {"starlark", "syntax/syntax.go", "type (Ident)"}, -- {"tools", "internal/lsp/source/view.go", "type (Snapshot)"}, -- } +-func TestClosingBuffer(t *testing.T) { +- const basic = ` +--- go.mod -- +-module mod.com - -- for _, test := range tests { -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- loc := env.RegexpSearch(test.file, test.regexp) -- env.Await(env.DoneWithOpen()) -- env.References(loc) // pre-warm the query -- b.ResetTimer() +-go 1.14 +--- main.go -- +-package main - -- for i := 0; i < b.N; i++ { -- env.References(loc) -- } -- }) -- } +-func main() {} +-` +- Run(t, basic, func(t *testing.T, env *Env) { +- env.Editor.CreateBuffer(env.Ctx, "foo.go", `package main`) +- env.AfterChange() +- env.CloseBuffer("foo.go") +- env.AfterChange(NoLogMatching(protocol.Info, "packages=0")) +- }) -} -diff -urN a/gopls/internal/regtest/bench/rename_test.go b/gopls/internal/regtest/bench/rename_test.go ---- a/gopls/internal/regtest/bench/rename_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/rename_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,44 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package bench +-// Reproduces golang/go#38424. +-func TestCutAndPaste(t *testing.T) { +- const basic = ` +--- go.mod -- +-module mod.com - --import ( -- "fmt" -- "testing" --) +-go 1.14 +--- main2.go -- +-package main +-` +- Run(t, basic, func(t *testing.T, env *Env) { +- env.CreateBuffer("main.go", "") +- env.Await(env.DoneWithOpen()) - --func BenchmarkRename(b *testing.B) { -- tests := []struct { -- repo string -- file string -- regexp string -- baseName string -- }{ -- {"kubernetes", "pkg/controller/lookup_cache.go", `hashutil\.(DeepHashObject)`, "DeepHashObject"}, -- {"kuma", "pkg/events/interfaces.go", `Delete`, "Delete"}, -- {"istio", "pkg/config/model.go", `(Namespace) string`, "Namespace"}, -- {"pkgsite", "internal/log/log.go", `func (Infof)`, "Infof"}, -- {"starlark", "starlark/eval.go", `Program\) (Filename)`, "Filename"}, -- {"tools", "internal/lsp/cache/snapshot.go", `meta \*(metadataGraph)`, "metadataGraph"}, -- } +- env.SaveBufferWithoutActions("main.go") +- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) - -- for _, test := range tests { -- names := 0 // bench function may execute multiple times -- b.Run(test.repo, func(b *testing.B) { -- env := getRepo(b, test.repo).sharedEnv(b) -- env.OpenFile(test.file) -- loc := env.RegexpSearch(test.file, test.regexp) -- env.Await(env.DoneWithOpen()) -- env.Rename(loc, test.baseName+"X") // pre-warm the query -- b.ResetTimer() +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main - -- for i := 0; i < b.N; i++ { -- names++ -- newName := fmt.Sprintf("%s%d", test.baseName, names) -- env.Rename(loc, newName) -- } -- }) -- } +-func main() { -} -diff -urN a/gopls/internal/regtest/bench/repo_test.go b/gopls/internal/regtest/bench/repo_test.go ---- a/gopls/internal/regtest/bench/repo_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/repo_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,231 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-`)) +- env.Await(env.DoneWithChange()) - --package bench +- env.SaveBuffer("main.go") +- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) - --import ( -- "bytes" -- "context" -- "errors" -- "fmt" -- "log" -- "os" -- "path/filepath" -- "sync" -- "testing" -- "time" +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 4, 0, "")) +- env.Await(env.DoneWithChange()) - -- "golang.org/x/tools/gopls/internal/lsp/fake" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main - --// repos holds shared repositories for use in benchmarks. --// --// These repos were selected to represent a variety of different types of --// codebases. --var repos = map[string]*repo{ -- // Used by x/benchmarks; large. -- "istio": { -- name: "istio", -- url: "https://github.com/istio/istio", -- commit: "1.17.0", -- }, +-func main() { +- var x int +-} +-`)) +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "x")), +- ) +- }) +-} - -- // Kubernetes is a large repo with many dependencies, and in the past has -- // been about as large a repo as gopls could handle. -- "kubernetes": { -- name: "kubernetes", -- url: "https://github.com/kubernetes/kubernetes", -- commit: "v1.24.0", -- }, +-// Reproduces golang/go#39763. +-func TestInvalidPackageName(t *testing.T) { +- const pkgDefault = ` +--- go.mod -- +-module mod.com - -- // A large, industrial application. -- "kuma": { -- name: "kuma", -- url: "https://github.com/kumahq/kuma", -- commit: "2.1.1", -- }, +-go 1.12 +--- main.go -- +-package default +- +-func main() {} +-` +- Run(t, pkgDefault, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("main.go", "default"), +- WithMessage("expected 'IDENT'"), +- ), +- ) +- }) +-} +- +-// This tests the functionality of the "limitWorkspaceScope" +-func TestLimitWorkspaceScope(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- a/main.go -- +-package main +- +-func main() {} +--- main.go -- +-package main +- +-func main() { +- var x int +-} +-` +- WithOptions( +- WorkspaceFolders("a"), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/main.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "x")), +- ) +- }) +- WithOptions( +- WorkspaceFolders("a"), +- Settings{"expandWorkspaceToModule": false}, +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/main.go") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- }) +-} - -- // x/pkgsite is familiar and represents a common use case (a webserver). It -- // also has a number of static non-go files and template files. -- "pkgsite": { -- name: "pkgsite", -- url: "https://go.googlesource.com/pkgsite", -- commit: "81f6f8d4175ad0bf6feaa03543cc433f8b04b19b", -- short: true, -- }, +-func TestSimplifyCompositeLitDiagnostic(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- // A tiny self-contained project. -- "starlark": { -- name: "starlark", -- url: "https://github.com/google/starlark-go", -- commit: "3f75dec8e4039385901a30981e3703470d77e027", -- short: true, -- }, +-go 1.12 +--- main.go -- +-package main - -- // The current repository, which is medium-small and has very few dependencies. -- "tools": { -- name: "tools", -- url: "https://go.googlesource.com/tools", -- commit: "gopls/v0.9.0", -- short: true, -- }, --} +-import "fmt" - --// getRepo gets the requested repo, and skips the test if -short is set and --// repo is not configured as a short repo. --func getRepo(tb testing.TB, name string) *repo { -- tb.Helper() -- repo := repos[name] -- if repo == nil { -- tb.Fatalf("repo %s does not exist", name) -- } -- if !repo.short && testing.Short() { -- tb.Skipf("large repo %s does not run whith -short", repo.name) -- } -- return repo +-type t struct { +- msg string -} - --// A repo represents a working directory for a repository checked out at a --// specific commit. --// --// Repos are used for sharing state across benchmarks that operate on the same --// codebase. --type repo struct { -- // static configuration -- name string // must be unique, used for subdirectory -- url string // repo url -- commit string // full commit hash or tag -- short bool // whether this repo runs with -short -- -- dirOnce sync.Once -- dir string // directory contaning source code checked out to url@commit -- -- // shared editor state -- editorOnce sync.Once -- editor *fake.Editor -- sandbox *fake.Sandbox -- awaiter *Awaiter +-func main() { +- x := []t{t{"msg"}} +- fmt.Println(x) -} +-` - --// getDir returns directory containing repo source code, creating it if --// necessary. It is safe for concurrent use. --func (r *repo) getDir() string { -- r.dirOnce.Do(func() { -- r.dir = filepath.Join(getTempDir(), r.name) -- log.Printf("cloning %s@%s into %s", r.url, r.commit, r.dir) -- if err := shallowClone(r.dir, r.url, r.commit); err != nil { -- log.Fatal(err) +- WithOptions( +- Settings{"staticcheck": true}, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", `t{"msg"}`), WithMessage("redundant type")), +- ReadDiagnostics("main.go", &d), +- ) +- if tags := d.Diagnostics[0].Tags; len(tags) == 0 || tags[0] != protocol.Unnecessary { +- t.Errorf("wanted Unnecessary tag on diagnostic, got %v", tags) - } +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange(NoDiagnostics(ForFile("main.go"))) - }) -- return r.dir -} - --// sharedEnv returns a shared benchmark environment. It is safe for concurrent --// use. --// --// Every call to sharedEnv uses the same editor and sandbox, as a means to --// avoid reinitializing the editor for large repos. Calling repo.Close cleans --// up the shared environment. --// --// Repos in the package-local Repos var are closed at the end of the test main --// function. --func (r *repo) sharedEnv(tb testing.TB) *Env { -- r.editorOnce.Do(func() { -- dir := r.getDir() +-// Test some secondary diagnostics +-func TestSecondaryDiagnostics(t *testing.T) { +- const dir = ` +--- go.mod -- +-module mod.com - -- start := time.Now() -- log.Printf("starting initial workspace load for %s", r.name) -- ts, err := newGoplsServer(r.name) -- if err != nil { -- log.Fatal(err) +-go 1.12 +--- main.go -- +-package main +-func main() { +- panic("not here") +-} +--- other.go -- +-package main +-func main() {} +-` +- Run(t, dir, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.OpenFile("other.go") +- var mainDiags, otherDiags protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &mainDiags), +- ReadDiagnostics("other.go", &otherDiags), +- ) +- if len(mainDiags.Diagnostics) != 1 { +- t.Fatalf("main.go, got %d diagnostics, expected 1", len(mainDiags.Diagnostics)) - } -- r.sandbox, r.editor, r.awaiter, err = connectEditor(dir, fake.EditorConfig{}, ts) -- if err != nil { -- log.Fatalf("connecting editor: %v", err) +- keep := mainDiags.Diagnostics[0] +- if len(otherDiags.Diagnostics) != 1 { +- t.Fatalf("other.go: got %d diagnostics, expected 1", len(otherDiags.Diagnostics)) - } -- -- if err := r.awaiter.Await(context.Background(), InitialWorkspaceLoad); err != nil { -- log.Fatal(err) +- if len(otherDiags.Diagnostics[0].RelatedInformation) != 1 { +- t.Fatalf("got %d RelatedInformations, expected 1", len(otherDiags.Diagnostics[0].RelatedInformation)) +- } +- // check that the RelatedInformation matches the error from main.go +- c := otherDiags.Diagnostics[0].RelatedInformation[0] +- if c.Location.Range != keep.Range { +- t.Errorf("locations don't match. Got %v expected %v", c.Location.Range, keep.Range) - } -- log.Printf("initial workspace load (cold) for %s took %v", r.name, time.Since(start)) - }) -- -- return &Env{ -- T: tb, -- Ctx: context.Background(), -- Editor: r.editor, -- Sandbox: r.sandbox, -- Awaiter: r.awaiter, -- } -} - --// newEnv returns a new Env connected to a new gopls process communicating --// over stdin/stdout. It is safe for concurrent use. --// --// It is the caller's responsibility to call Close on the resulting Env when it --// is no longer needed. --func (r *repo) newEnv(tb testing.TB, name string, config fake.EditorConfig) *Env { -- dir := r.getDir() +-func TestOrphanedFiles(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - -- ts, err := newGoplsServer(name) -- if err != nil { -- tb.Fatal(err) -- } -- sandbox, editor, awaiter, err := connectEditor(dir, config, ts) -- if err != nil { -- log.Fatalf("connecting editor: %v", err) -- } +-go 1.12 +--- a/a.go -- +-package a - -- return &Env{ -- T: tb, -- Ctx: context.Background(), -- Editor: editor, -- Sandbox: sandbox, -- Awaiter: awaiter, -- } +-func main() { +- var x int -} +--- a/a_exclude.go -- +-// +build exclude - --// Close cleans up shared state referenced by the repo. --func (r *repo) Close() error { -- var errBuf bytes.Buffer -- if r.editor != nil { -- if err := r.editor.Close(context.Background()); err != nil { -- fmt.Fprintf(&errBuf, "closing editor: %v", err) -- } -- } -- if r.sandbox != nil { -- if err := r.sandbox.Close(); err != nil { -- fmt.Fprintf(&errBuf, "closing sandbox: %v", err) -- } -- } -- if r.dir != "" { -- if err := os.RemoveAll(r.dir); err != nil { -- fmt.Fprintf(&errBuf, "cleaning dir: %v", err) -- } -- } -- if errBuf.Len() > 0 { -- return errors.New(errBuf.String()) -- } -- return nil --} +-package a - --// cleanup cleans up state that is shared across benchmark functions. --func cleanup() error { -- var errBuf bytes.Buffer -- for _, repo := range repos { -- if err := repo.Close(); err != nil { -- fmt.Fprintf(&errBuf, "closing %q: %v", repo.name, err) -- } -- } -- if tempDir != "" { -- if err := os.RemoveAll(tempDir); err != nil { -- fmt.Fprintf(&errBuf, "cleaning tempDir: %v", err) -- } -- } -- if errBuf.Len() > 0 { -- return errors.New(errBuf.String()) -- } -- return nil +-func _() { +- var x int -} -diff -urN a/gopls/internal/regtest/bench/stress_test.go b/gopls/internal/regtest/bench/stress_test.go ---- a/gopls/internal/regtest/bench/stress_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/stress_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,94 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "x")), +- ) +- env.OpenFile("a/a_exclude.go") - --package bench +- loadOnce := LogMatching(protocol.Info, "query=.*file=.*a_exclude.go", 1, false) - --import ( -- "context" -- "flag" -- "fmt" -- "testing" -- "time" +- // can't use OnceMet or AfterChange as logs are async +- env.Await(loadOnce) +- // ...but ensure that the change has been fully processed before editing. +- // Otherwise, there may be a race where the snapshot is cloned before all +- // state changes resulting from the load have been processed +- // (golang/go#61521). +- env.AfterChange() - -- "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp/cache" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/lsprpc" -- "golang.org/x/tools/internal/jsonrpc2" -- "golang.org/x/tools/internal/jsonrpc2/servertest" --) +- // Check that orphaned files are not reloaded, by making a change in +- // a.go file and confirming that the workspace diagnosis did not reload +- // a_exclude.go. +- // +- // This is racy (but fails open) because logs are asynchronous to other LSP +- // operations. There's a chance gopls _did_ log, and we just haven't seen +- // it yet. +- env.RegexpReplace("a/a.go", "package a", "package a // arbitrary comment") +- env.AfterChange(loadOnce) +- }) +-} - --// github.com/pilosa/pilosa is a repository that has historically caused --// significant memory problems for Gopls. We use it for a simple stress test --// that types arbitrarily in a file with lots of dependents. +-func TestEnableAllExperiments(t *testing.T) { +- // Before the oldest supported Go version, gopls sends a warning to upgrade +- // Go, which fails the expectation below. +- testenv.NeedsGo1Point(t, lsp.OldestSupportedGoVersion()) - --var pilosaPath = flag.String("pilosa_path", "", "Path to a directory containing "+ -- "github.com/pilosa/pilosa, for stress testing. Do not set this unless you "+ -- "know what you're doing!") +- const mod = ` +--- go.mod -- +-module mod.com - --func TestPilosaStress(t *testing.T) { -- // TODO(rfindley): revisit this test and make it is hermetic: it should check -- // out pilosa into a directory. -- // -- // Note: This stress test has not been run recently, and may no longer -- // function properly. -- if *pilosaPath == "" { -- t.Skip("-pilosa_path not configured") -- } +-go 1.12 +--- main.go -- +-package main - -- sandbox, err := fake.NewSandbox(&fake.SandboxConfig{ -- Workdir: *pilosaPath, -- GOPROXY: "https://proxy.golang.org", -- }) -- if err != nil { -- t.Fatal(err) -- } +-import "bytes" - -- server := lsprpc.NewStreamServer(cache.New(nil), false, hooks.Options) -- ts := servertest.NewPipeServer(server, jsonrpc2.NewRawStream) -- ctx := context.Background() +-func b(c bytes.Buffer) { +- _ = 1 +-} +-` +- WithOptions( +- Settings{"allExperiments": true}, +- ).Run(t, mod, func(t *testing.T, env *Env) { +- // Confirm that the setting doesn't cause any warnings. +- env.OnceMet( +- InitialWorkspaceLoad, +- NoShownMessage(""), // empty substring to match any message +- ) +- }) +-} - -- const skipApplyEdits = false -- editor, err := fake.NewEditor(sandbox, fake.EditorConfig{}).Connect(ctx, ts, fake.ClientHooks{}, skipApplyEdits) -- if err != nil { -- t.Fatal(err) -- } +-func TestSwig(t *testing.T) { +- // This is fixed in Go 1.17, but not earlier. +- testenv.NeedsGo1Point(t, 17) - -- files := []string{ -- "cmd.go", -- "internal/private.pb.go", -- "roaring/roaring.go", -- "roaring/roaring_internal_test.go", -- "server/handler_test.go", +- if _, err := exec.LookPath("swig"); err != nil { +- t.Skip("skipping test: swig not available") - } -- for _, file := range files { -- if err := editor.OpenFile(ctx, file); err != nil { -- t.Fatal(err) -- } +- if _, err := exec.LookPath("g++"); err != nil { +- t.Skip("skipping test: g++ not available") - } -- ctx, cancel := context.WithTimeout(ctx, 10*time.Minute) -- defer cancel() - -- i := 1 -- // MagicNumber is an identifier that occurs in roaring.go. Just change it -- // arbitrarily. -- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", "MagicNumber", fmt.Sprintf("MagicNumber%d", 1)); err != nil { -- t.Fatal(err) -- } -- for { -- select { -- case <-ctx.Done(): -- return -- default: -- } -- if err := editor.RegexpReplace(ctx, "roaring/roaring.go", fmt.Sprintf("MagicNumber%d", i), fmt.Sprintf("MagicNumber%d", i+1)); err != nil { -- t.Fatal(err) -- } -- // Simulate (very fast) typing. -- // -- // Typing 80 wpm ~150ms per keystroke. -- time.Sleep(150 * time.Millisecond) -- i++ -- } +- const mod = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- pkg/simple/export_swig.go -- +-package simple +- +-func ExportSimple(x, y int) int { +- return Gcd(x, y) -} -diff -urN a/gopls/internal/regtest/bench/workspace_symbols_test.go b/gopls/internal/regtest/bench/workspace_symbols_test.go ---- a/gopls/internal/regtest/bench/workspace_symbols_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/bench/workspace_symbols_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,37 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +--- pkg/simple/simple.swigcxx -- +-%module simple - --package bench +-%inline %{ +-extern int gcd(int x, int y) +-{ +- int g; +- g = y; +- while (x > 0) { +- g = x; +- x = y % x; +- y = g; +- } +- return g; +-} +-%} +--- main.go -- +-package a - --import ( -- "flag" -- "fmt" -- "testing" --) +-func main() { +- var x int +-} +-` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- NoDiagnostics(WithMessage("illegal character U+0023 '#'")), +- ) +- }) +-} - --var symbolQuery = flag.String("symbol_query", "test", "symbol query to use in benchmark") +-// When foo_test.go is opened, gopls will object to the borked package name. +-// This test asserts that when the package name is fixed, gopls will soon after +-// have no more complaints about it. +-// https://github.com/golang/go/issues/41061 +-func TestRenamePackage(t *testing.T) { +- const proxy = ` +--- example.com@v1.2.3/go.mod -- +-module example.com - --// BenchmarkWorkspaceSymbols benchmarks the time to execute a workspace symbols --// request (controlled by the -symbol_query flag). --func BenchmarkWorkspaceSymbols(b *testing.B) { -- for name := range repos { -- b.Run(name, func(b *testing.B) { -- env := getRepo(b, name).sharedEnv(b) -- symbols := env.Symbol(*symbolQuery) // warm the cache +-go 1.12 +--- example.com@v1.2.3/blah/blah.go -- +-package blah - -- if testing.Verbose() { -- fmt.Println("Results:") -- for i, symbol := range symbols { -- fmt.Printf("\t%d. %s (%s)\n", i, symbol.Name, symbol.ContainerName) -- } -- } +-const Name = "Blah" +--- random.org@v1.2.3/go.mod -- +-module random.org - -- b.ResetTimer() +-go 1.12 +--- random.org@v1.2.3/blah/blah.go -- +-package hello - -- for i := 0; i < b.N; i++ { -- env.Symbol(*symbolQuery) -- } -- }) -- } +-const Name = "Hello" +-` +- +- const contents = ` +--- go.mod -- +-module mod.com +- +-go 1.12 +--- main.go -- +-package main +- +-import "example.com/blah" +- +-func main() { +- blah.Hello() -} -diff -urN a/gopls/internal/regtest/codelens/codelens_test.go b/gopls/internal/regtest/codelens/codelens_test.go ---- a/gopls/internal/regtest/codelens/codelens_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/codelens/codelens_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,336 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +--- bob.go -- +-package main +--- foo/foo.go -- +-package foo +--- foo/foo_test.go -- +-package foo_ +-` - --package codelens +- WithOptions( +- ProxyFiles(proxy), +- InGOPATH(), +- EnvVars{"GO111MODULE": "off"}, +- ).Run(t, contents, func(t *testing.T, env *Env) { +- // Simulate typing character by character. +- env.OpenFile("foo/foo_test.go") +- env.Await(env.DoneWithOpen()) +- env.RegexpReplace("foo/foo_test.go", "_", "_t") +- env.Await(env.DoneWithChange()) +- env.RegexpReplace("foo/foo_test.go", "_t", "_test") +- env.AfterChange( +- NoDiagnostics(ForFile("foo/foo_test.go")), +- NoOutstandingWork(), +- ) +- }) +-} - --import ( -- "fmt" -- "testing" +-// TestProgressBarErrors confirms that critical workspace load errors are shown +-// and updated via progress reports. +-func TestProgressBarErrors(t *testing.T) { +- const pkg = ` +--- go.mod -- +-modul mod.com - -- "golang.org/x/tools/gopls/internal/hooks" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- "golang.org/x/tools/internal/bug" +-go 1.12 +--- main.go -- +-package main +-` +- Run(t, pkg, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.AfterChange( +- OutstandingWork(lsp.WorkspaceLoadFailure, "unknown directive"), +- ) +- env.EditBuffer("go.mod", fake.NewEdit(0, 0, 3, 0, `module mod.com +- +-go 1.hello +-`)) +- // As of golang/go#42529, go.mod changes do not reload the workspace until +- // they are saved. +- env.SaveBufferWithoutActions("go.mod") +- env.AfterChange( +- OutstandingWork(lsp.WorkspaceLoadFailure, "invalid go version"), +- ) +- env.RegexpReplace("go.mod", "go 1.hello", "go 1.12") +- env.SaveBufferWithoutActions("go.mod") +- env.AfterChange( +- NoOutstandingWork(), +- ) +- }) +-} - -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/internal/testenv" --) +-func TestDeleteDirectory(t *testing.T) { +- const mod = ` +--- bob/bob.go -- +-package bob - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- Main(m, hooks.Options) +-func Hello() { +- var x int -} -- --func TestDisablingCodeLens(t *testing.T) { -- const workspace = ` --- go.mod -- --module codelens.test -- --go 1.12 ---- lib.go -- --package lib -- --type Number int +-module mod.com +--- cmd/main.go -- +-package main - --const ( -- Zero Number = iota -- One -- Two --) +-import "mod.com/bob" - --//` + `go:generate stringer -type=Number +-func main() { +- bob.Hello() +-} -` -- tests := []struct { -- label string -- enabled map[string]bool -- wantCodeLens bool -- }{ -- { -- label: "default", -- wantCodeLens: true, -- }, -- { -- label: "generate disabled", -- enabled: map[string]bool{string(command.Generate): false}, -- wantCodeLens: false, +- WithOptions( +- Settings{ +- // Now that we don't watch subdirs by default (except for VS Code), +- // we must explicitly ask gopls to requests subdir watch patterns. +- "subdirWatchPatterns": "on", - }, -- } -- for _, test := range tests { -- t.Run(test.label, func(t *testing.T) { -- WithOptions( -- Settings{"codelenses": test.enabled}, -- ).Run(t, workspace, func(t *testing.T, env *Env) { -- env.OpenFile("lib.go") -- lens := env.CodeLens("lib.go") -- if gotCodeLens := len(lens) > 0; gotCodeLens != test.wantCodeLens { -- t.Errorf("got codeLens: %t, want %t", gotCodeLens, test.wantCodeLens) -- } -- }) -- }) -- } +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- FileWatchMatching("bob"), +- ) +- env.RemoveWorkspaceFile("bob") +- env.AfterChange( +- Diagnostics(env.AtRegexp("cmd/main.go", `"mod.com/bob"`)), +- NoDiagnostics(ForFile("bob/bob.go")), +- NoFileWatchMatching("bob"), +- ) +- }) -} - --// This test confirms the full functionality of the code lenses for updating --// dependencies in a go.mod file. It checks for the code lens that suggests --// an update and then executes the command associated with that code lens. A --// regression test for golang/go#39446. It also checks that these code lenses --// only affect the diagnostics and contents of the containing go.mod file. --func TestUpgradeCodelens(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) // uses go.work -- -- const proxyWithLatest = ` ---- golang.org/x/hello@v1.3.3/go.mod -- --module golang.org/x/hello +-// Confirms that circular imports are tested and reported. +-func TestCircularImports(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - -go 1.12 ---- golang.org/x/hello@v1.3.3/hi/hi.go -- --package hi +--- self/self.go -- +-package self - --var Goodbye error ---- golang.org/x/hello@v1.2.3/go.mod -- --module golang.org/x/hello +-import _ "mod.com/self" +-func Hello() {} +--- double/a/a.go -- +-package a - --go 1.12 ---- golang.org/x/hello@v1.2.3/hi/hi.go -- --package hi +-import _ "mod.com/double/b" +--- double/b/b.go -- +-package b - --var Goodbye error +-import _ "mod.com/double/a" +--- triple/a/a.go -- +-package a +- +-import _ "mod.com/triple/b" +--- triple/b/b.go -- +-package b +- +-import _ "mod.com/triple/c" +--- triple/c/c.go -- +-package c +- +-import _ "mod.com/triple/a" -` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("self/self.go", `_ "mod.com/self"`), WithMessage("import cycle not allowed")), +- Diagnostics(env.AtRegexp("double/a/a.go", `_ "mod.com/double/b"`), WithMessage("import cycle not allowed")), +- Diagnostics(env.AtRegexp("triple/a/a.go", `_ "mod.com/triple/b"`), WithMessage("import cycle not allowed")), +- ) +- }) +-} - -- const shouldUpdateDep = ` ---- go.work -- --go 1.18 +-// Tests golang/go#46667: deleting a problematic import path should resolve +-// import cycle errors. +-func TestResolveImportCycle(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.test - --use ( -- ./a -- ./b --) ---- a/go.mod -- --module mod.com/a +-go 1.16 +--- a/a.go -- +-package a - --go 1.14 +-import "mod.test/b" - --require golang.org/x/hello v1.2.3 ---- a/go.sum -- --golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= --golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= ---- a/main.go -- --package main +-const A = b.A +-const B = 2 +--- b/b.go -- +-package b - --import "golang.org/x/hello/hi" +-import "mod.test/a" - --func main() { -- _ = hi.Goodbye +-const A = 1 +-const B = a.B +- ` +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.OpenFile("b/b.go") +- env.AfterChange( +- // The Go command sometimes tells us about only one of the import cycle +- // errors below. For robustness of this test, succeed if we get either. +- // +- // TODO(golang/go#52904): we should get *both* of these errors. +- AnyOf( +- Diagnostics(env.AtRegexp("a/a.go", `"mod.test/b"`), WithMessage("import cycle")), +- Diagnostics(env.AtRegexp("b/b.go", `"mod.test/a"`), WithMessage("import cycle")), +- ), +- ) +- env.RegexpReplace("b/b.go", `const B = a\.B`, "") +- env.SaveBuffer("b/b.go") +- env.AfterChange( +- NoDiagnostics(ForFile("a/a.go")), +- NoDiagnostics(ForFile("b/b.go")), +- ) +- }) -} ---- b/go.mod -- --module mod.com/b - --go 1.14 +-func TestBadImport(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com - --require golang.org/x/hello v1.2.3 ---- b/go.sum -- --golang.org/x/hello v1.2.3 h1:7Wesfkx/uBd+eFgPrq0irYj/1XfmbvLV8jZ/W7C2Dwg= --golang.org/x/hello v1.2.3/go.mod h1:OgtlzsxVMUUdsdQCIDYgaauCTH47B8T8vofouNJfzgY= ---- b/main.go -- +-go 1.12 +--- main.go -- -package main - -import ( -- "golang.org/x/hello/hi" +- _ "nosuchpkg" -) -- --func main() { -- _ = hi.Goodbye --} --` -- -- const wantGoModA = `module mod.com/a -- --go 1.14 -- --require golang.org/x/hello v1.3.3 --` -- // Applying the diagnostics or running the codelenses for a/go.mod -- // should not change the contents of b/go.mod -- const wantGoModB = `module mod.com/b -- --go 1.14 -- --require golang.org/x/hello v1.2.3 -` -- -- for _, commandTitle := range []string{ -- "Upgrade transitive dependencies", -- "Upgrade direct dependencies", -- } { -- t.Run(commandTitle, func(t *testing.T) { -- WithOptions( -- ProxyFiles(proxyWithLatest), -- ).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { -- env.OpenFile("a/go.mod") -- env.OpenFile("b/go.mod") -- var lens protocol.CodeLens -- var found bool -- for _, l := range env.CodeLens("a/go.mod") { -- if l.Command.Title == commandTitle { -- lens = l -- found = true -- } -- } -- if !found { -- t.Fatalf("found no command with the title %s", commandTitle) -- } -- if _, err := env.Editor.ExecuteCommand(env.Ctx, &protocol.ExecuteCommandParams{ -- Command: lens.Command.Command, -- Arguments: lens.Command.Arguments, -- }); err != nil { -- t.Fatal(err) -- } -- env.AfterChange() -- if got := env.BufferText("a/go.mod"); got != wantGoModA { -- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) -- } -- if got := env.BufferText("b/go.mod"); got != wantGoModB { -- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) -- } -- }) +- t.Run("module", func(t *testing.T) { +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`could not import nosuchpkg (no required module provides package "nosuchpkg"`)), +- ) - }) -- } -- for _, vendoring := range []bool{false, true} { -- t.Run(fmt.Sprintf("Upgrade individual dependency vendoring=%v", vendoring), func(t *testing.T) { -- WithOptions(ProxyFiles(proxyWithLatest)).Run(t, shouldUpdateDep, func(t *testing.T, env *Env) { -- if vendoring { -- env.RunGoCommandInDir("a", "mod", "vendor") -- } -- env.AfterChange() -- env.OpenFile("a/go.mod") -- env.OpenFile("b/go.mod") -- env.ExecuteCodeLensCommand("a/go.mod", command.CheckUpgrades, nil) -- d := &protocol.PublishDiagnosticsParams{} -- env.OnceMet( -- Diagnostics(env.AtRegexp("a/go.mod", `require`), WithMessage("can be upgraded")), -- ReadDiagnostics("a/go.mod", d), -- // We do not want there to be a diagnostic for b/go.mod, -- // but there may be some subtlety in timing here, where this -- // should always succeed, but may not actually test the correct -- // behavior. -- NoDiagnostics(env.AtRegexp("b/go.mod", `require`)), -- ) -- // Check for upgrades in b/go.mod and then clear them. -- env.ExecuteCodeLensCommand("b/go.mod", command.CheckUpgrades, nil) -- env.Await(Diagnostics(env.AtRegexp("b/go.mod", `require`), WithMessage("can be upgraded"))) -- env.ExecuteCodeLensCommand("b/go.mod", command.ResetGoModDiagnostics, nil) -- env.Await(NoDiagnostics(ForFile("b/go.mod"))) -- -- // Apply the diagnostics to a/go.mod. -- env.ApplyQuickFixes("a/go.mod", d.Diagnostics) -- env.AfterChange() -- if got := env.BufferText("a/go.mod"); got != wantGoModA { -- t.Fatalf("a/go.mod upgrade failed:\n%s", compare.Text(wantGoModA, got)) -- } -- if got := env.BufferText("b/go.mod"); got != wantGoModB { -- t.Fatalf("b/go.mod changed unexpectedly:\n%s", compare.Text(wantGoModB, got)) -- } -- }) +- }) +- t.Run("GOPATH", func(t *testing.T) { +- WithOptions( +- InGOPATH(), +- EnvVars{"GO111MODULE": "off"}, +- Modes(Default), +- ).Run(t, mod, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`cannot find package "nosuchpkg"`)), +- ) - }) -- } +- }) -} - --func TestUnusedDependenciesCodelens(t *testing.T) { +-func TestNestedModules(t *testing.T) { - const proxy = ` ---- golang.org/x/hello@v1.0.0/go.mod -- --module golang.org/x/hello -- --go 1.14 ---- golang.org/x/hello@v1.0.0/hi/hi.go -- --package hi -- --var Goodbye error ---- golang.org/x/unused@v1.0.0/go.mod -- --module golang.org/x/unused +--- nested.com@v1.0.0/go.mod -- +-module nested.com - --go 1.14 ---- golang.org/x/unused@v1.0.0/nouse/nouse.go -- --package nouse +-go 1.12 +--- nested.com@v1.0.0/hello/hello.go -- +-package hello - --var NotUsed error +-func Hello() {} -` - -- const shouldRemoveDep = ` +- const nested = ` --- go.mod -- -module mod.com - --go 1.14 +-go 1.12 - --require golang.org/x/hello v1.0.0 --require golang.org/x/unused v1.0.0 +-require nested.com v1.0.0 --- go.sum -- --golang.org/x/hello v1.0.0 h1:qbzE1/qT0/zojAMd/JcPsO2Vb9K4Bkeyq0vB2JGMmsw= --golang.org/x/hello v1.0.0/go.mod h1:WW7ER2MRNXWA6c8/4bDIek4Hc/+DofTrMaQQitGXcco= --golang.org/x/unused v1.0.0 h1:LecSbCn5P3vTcxubungSt1Pn4D/WocCaiWOPDC0y0rw= --golang.org/x/unused v1.0.0/go.mod h1:ihoW8SgWzugwwj0N2SfLfPZCxTB1QOVfhMfB5PWTQ8U= +-nested.com v1.0.0 h1:I6spLE4CgFqMdBPc+wTV2asDO2QJ3tU0YAT+jkLeN1I= +-nested.com v1.0.0/go.mod h1:ly53UzXQgVjSlV7wicdBB4p8BxfytuGT1Xcyv0ReJfI= --- main.go -- -package main - --import "golang.org/x/hello/hi" +-import "nested.com/hello" - -func main() { -- _ = hi.Goodbye +- hello.Hello() +-} +--- nested/go.mod -- +-module nested.com +- +--- nested/hello/hello.go -- +-package hello +- +-func Hello() { +- helloHelper() -} +--- nested/hello/hello_helper.go -- +-package hello +- +-func helloHelper() {} -` -- WithOptions(ProxyFiles(proxy)).Run(t, shouldRemoveDep, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.ExecuteCodeLensCommand("go.mod", command.Tidy, nil) -- env.Await(env.DoneWithChangeWatchedFiles()) -- got := env.BufferText("go.mod") -- const wantGoMod = `module mod.com +- WithOptions( +- ProxyFiles(proxy), +- Modes(Default), +- ).Run(t, nested, func(t *testing.T, env *Env) { +- // Expect a diagnostic in a nested module. +- env.OpenFile("nested/hello/hello.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("nested/hello/hello.go", "helloHelper")), +- Diagnostics(env.AtRegexp("nested/hello/hello.go", "package (hello)"), WithMessage("not included in your workspace")), +- ) +- }) +-} - --go 1.14 +-func TestAdHocPackagesReloading(t *testing.T) { +- const nomod = ` +--- main.go -- +-package main - --require golang.org/x/hello v1.0.0 +-func main() {} -` -- if got != wantGoMod { -- t.Fatalf("go.mod tidy failed:\n%s", compare.Text(wantGoMod, got)) -- } +- Run(t, nomod, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.RegexpReplace("main.go", "{}", "{ var x int; }") // simulate typing +- env.AfterChange(NoLogMatching(protocol.Info, "packages=1")) - }) -} - --func TestRegenerateCgo(t *testing.T) { -- testenv.NeedsTool(t, "cgo") -- const workspace = ` +-func TestBuildTagChange(t *testing.T) { +- const files = ` --- go.mod -- --module example.com +-module mod.com - -go 1.12 ---- cgo.go -- --package x +--- foo.go -- +-// decoy comment +-// +build hidden +-// decoy comment - --/* --int fortythree() { return 42; } --*/ --import "C" +-package foo +-var Foo = 1 +--- bar.go -- +-package foo +-var Bar = Foo +-` - --func Foo() { -- print(C.fortytwo()) +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("foo.go") +- env.AfterChange(Diagnostics(env.AtRegexp("bar.go", `Foo`))) +- env.RegexpReplace("foo.go", `\+build`, "") +- env.AfterChange(NoDiagnostics(ForFile("bar.go"))) +- }) +- +-} +- +-func TestIssue44736(t *testing.T) { +- const files = ` +- -- go.mod -- +-module blah.com +- +-go 1.16 +--- main.go -- +-package main +- +-import "fmt" +- +-func main() { +- asdf +- fmt.Printf("This is a test %v") +- fdas -} +--- other.go -- +-package main +- -` -- Run(t, workspace, func(t *testing.T, env *Env) { -- // Open the file. We have a nonexistant symbol that will break cgo processing. -- env.OpenFile("cgo.go") +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.OpenFile("other.go") - env.AfterChange( -- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), +- Diagnostics(env.AtRegexp("main.go", "asdf")), +- Diagnostics(env.AtRegexp("main.go", "fdas")), - ) -- -- // Fix the C function name. We haven't regenerated cgo, so nothing should be fixed. -- env.RegexpReplace("cgo.go", `int fortythree`, "int fortytwo") -- env.SaveBuffer("cgo.go") +- env.SetBufferContent("other.go", "package main\n\nasdf") +- // The new diagnostic in other.go should not suppress diagnostics in main.go. - env.AfterChange( -- Diagnostics(env.AtRegexp("cgo.go", ``), WithMessage("go list failed to return CompiledGoFiles")), +- Diagnostics(env.AtRegexp("other.go", "asdf"), WithMessage("expected declaration")), +- Diagnostics(env.AtRegexp("main.go", "asdf")), - ) -- -- // Regenerate cgo, fixing the diagnostic. -- env.ExecuteCodeLensCommand("cgo.go", command.RegenerateCgo, nil) -- env.Await(NoDiagnostics(ForFile("cgo.go"))) - }) -} -diff -urN a/gopls/internal/regtest/codelens/gcdetails_test.go b/gopls/internal/regtest/codelens/gcdetails_test.go ---- a/gopls/internal/regtest/codelens/gcdetails_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/codelens/gcdetails_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,127 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package codelens -- --import ( -- "runtime" -- "strings" -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/command" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/bug" --) +-func TestInitialization(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.com - --func TestGCDetails_Toggle(t *testing.T) { -- if runtime.GOOS == "android" { -- t.Skipf("the gc details code lens doesn't work on Android") -- } +-go 1.16 +--- main.go -- +-package main +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.Await(env.DoneWithOpen()) +- env.RegexpReplace("go.mod", "module", "modul") +- env.SaveBufferWithoutActions("go.mod") +- env.AfterChange( +- NoLogMatching(protocol.Error, "initial workspace load failed"), +- ) +- }) +-} - -- const mod = ` +-// This test confirms that the view does not reinitialize when a go.mod file is +-// opened. +-func TestNoReinitialize(t *testing.T) { +- const files = ` --- go.mod -- -module mod.com - --go 1.15 +-go 1.12 --- main.go -- -package main - --import "fmt" -- --func main() { -- fmt.Println(42) --} +-func main() {} -` -- WithOptions( -- Settings{ -- "codelenses": map[string]bool{ -- "gc_details": true, -- }, -- }, -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) -- d := &protocol.PublishDiagnosticsParams{} -- env.OnceMet( -- Diagnostics(AtPosition("main.go", 5, 13)), -- ReadDiagnostics("main.go", d), +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.mod") +- env.Await( +- // Check that we have only loaded "<dir>/..." once. +- // Log messages are asynchronous to other events on the LSP stream, so we +- // can't use OnceMet or AfterChange here. +- LogMatching(protocol.Info, `.*query=.*\.\.\..*`, 1, false), - ) -- // Confirm that the diagnostics come from the gc details code lens. -- var found bool -- for _, d := range d.Diagnostics { -- if d.Severity != protocol.SeverityInformation { -- t.Fatalf("unexpected diagnostic severity %v, wanted Information", d.Severity) -- } -- if strings.Contains(d.Message, "42 escapes") { -- found = true -- } -- } -- if !found { -- t.Fatalf(`expected to find diagnostic with message "escape(42 escapes to heap)", found none`) -- } -- -- // Editing a buffer should cause gc_details diagnostics to disappear, since -- // they only apply to saved buffers. -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, "\n\n")) -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- -- // Saving a buffer should re-format back to the original state, and -- // re-enable the gc_details diagnostics. -- env.SaveBuffer("main.go") -- env.AfterChange(Diagnostics(AtPosition("main.go", 5, 13))) -- -- // Toggle the GC details code lens again so now it should be off. -- env.ExecuteCodeLensCommand("main.go", command.GCDetails, nil) -- env.Await(NoDiagnostics(ForFile("main.go"))) - }) -} - --// Test for the crasher in golang/go#54199 --func TestGCDetails_NewFile(t *testing.T) { -- bug.PanicOnBugs = false -- const src = ` +-func TestLangVersion(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // Requires types.Config.GoVersion, new in 1.18. +- const files = ` --- go.mod -- --module mod.test +-module mod.com - -go 1.12 --` -- -- WithOptions( -- Settings{ -- "codelenses": map[string]bool{ -- "gc_details": true, -- }, -- }, -- ).Run(t, src, func(t *testing.T, env *Env) { -- env.CreateBuffer("p_test.go", "") -- -- const gcDetailsCommand = "gopls." + string(command.GCDetails) -- -- hasGCDetails := func() bool { -- lenses := env.CodeLens("p_test.go") // should not crash -- for _, lens := range lenses { -- if lens.Command.Command == gcDetailsCommand { -- return true -- } -- } -- return false -- } -- -- // With an empty file, we shouldn't get the gc_details codelens because -- // there is nowhere to position it (it needs a package name). -- if hasGCDetails() { -- t.Errorf("got the gc_details codelens for an empty file") -- } -- -- // Edit to provide a package name. -- env.EditBuffer("p_test.go", fake.NewEdit(0, 0, 0, 0, "package p")) +--- main.go -- +-package main - -- // Now we should get the gc_details codelens. -- if !hasGCDetails() { -- t.Errorf("didn't get the gc_details codelens for a valid non-empty Go file") -- } +-const C = 0b10 +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `0b10`), WithMessage("go1.13 or later")), +- ) +- env.WriteWorkspaceFile("go.mod", "module mod.com \n\ngo 1.13\n") +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) - }) -} -diff -urN a/gopls/internal/regtest/completion/completion18_test.go b/gopls/internal/regtest/completion/completion18_test.go ---- a/gopls/internal/regtest/completion/completion18_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/completion/completion18_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,124 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --//go:build go1.18 --// +build go1.18 -- --package completion -- --import ( -- "testing" -- -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) - --// test generic receivers --func TestGenericReceiver(t *testing.T) { +-func TestNoQuickFixForUndeclaredConstraint(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) - const files = ` --- go.mod -- -module mod.com @@ -108980,5025 +122063,4355 @@ diff -urN a/gopls/internal/regtest/completion/completion18_test.go b/gopls/inter -go 1.18 --- main.go -- -package main --type SyncMap[K any, V comparable] struct {} --func (s *SyncMap[K,V]) f() {} --type XX[T any] struct {} --type UU[T any] struct {} --func (s SyncMap[XX,string]) g(v UU) {} +- +-func F[T C](_ T) { +-} -` - -- tests := []struct { -- pat string -- want []string -- }{ -- {"s .Syn", []string{"SyncMap[K, V]"}}, -- {"Map.X", []string{}}, // This is probably wrong, Maybe "XX"? -- {"v U", []string{"UU", "uint", "uint16", "uint32", "uint64", "uint8", "uintptr"}}, // not U[T] -- } - Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.Await(env.DoneWithOpen()) -- for _, tst := range tests { -- loc := env.RegexpSearch("main.go", tst.pat) -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(tst.pat))) -- completions := env.Completion(loc) -- result := compareCompletionLabels(tst.want, completions.Items) -- if result != "" { -- t.Errorf("%s: wanted %v", result, tst.want) -- for i, g := range completions.Items { -- t.Errorf("got %d %s %s", i, g.Label, g.Detail) -- } -- } +- var d protocol.PublishDiagnosticsParams +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `C`)), +- ReadDiagnostics("main.go", &d), +- ) +- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { +- t.Errorf("got quick fixes %v, wanted none", fixes) - } - }) -} --func TestFuzzFunc(t *testing.T) { -- // use the example from the package documentation -- modfile := ` +- +-func TestEditGoDirective(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) +- const files = ` --- go.mod -- -module mod.com - --go 1.18 --` -- part0 := `package foo --import "testing" --func FuzzNone(f *testing.F) { -- f.Add(12) // better not find this f.Add --} --func FuzzHex(f *testing.F) { -- for _, seed := range [][]byte{{}, {0}, {9}, {0xa}, {0xf}, {1, 2, 3, 4}} { -- f.Ad` -- part1 := `d(seed) -- } -- f.F` -- part2 := `uzz(func(t *testing.T, in []byte) { -- enc := hex.EncodeToString(in) -- out, err := hex.DecodeString(enc) -- if err != nil { -- f.Failed() -- } -- if !bytes.Equal(in, out) { -- t.Fatalf("%v: round trip: %v, %s", in, out, f.Name()) -- } -- }) +-go 1.16 +--- main.go -- +-package main +- +-func F[T any](_ T) { -} -` -- data := modfile + `-- a_test.go -- --` + part0 + ` ---- b_test.go -- --` + part0 + part1 + ` ---- c_test.go -- --` + part0 + part1 + part2 +- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +- var d protocol.PublishDiagnosticsParams +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), +- ReadDiagnostics("main.go", &d), +- ) - -- tests := []struct { -- file string -- pat string -- offset uint32 // UTF16 length from the beginning of pat to what the user just typed -- want []string -- }{ -- {"a_test.go", "f.Ad", 3, []string{"Add"}}, -- {"c_test.go", " f.F", 4, []string{"Failed"}}, -- {"c_test.go", "f.N", 3, []string{"Name"}}, -- {"b_test.go", "f.F", 3, []string{"Fuzz(func(t *testing.T, a []byte)", "Fail", "FailNow", -- "Failed", "Fatal", "Fatalf"}}, -- } -- Run(t, data, func(t *testing.T, env *Env) { -- for _, test := range tests { -- env.OpenFile(test.file) -- env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch(test.file, test.pat) -- loc.Range.Start.Character += test.offset // character user just typed? will type? -- completions := env.Completion(loc) -- result := compareCompletionLabels(test.want, completions.Items) -- if result != "" { -- t.Errorf("pat %q %q", test.pat, result) -- for i, it := range completions.Items { -- t.Errorf("%d got %q %q", i, it.Label, it.Detail) -- } -- } -- } +- env.ApplyQuickFixes("main.go", d.Diagnostics) +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) - }) -} -diff -urN a/gopls/internal/regtest/completion/completion_test.go b/gopls/internal/regtest/completion/completion_test.go ---- a/gopls/internal/regtest/completion/completion_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/completion/completion_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,754 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package completion -- --import ( -- "fmt" -- "strings" -- "testing" +-func TestEditGoDirectiveWorkspace(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) +- const files = ` +--- go.mod -- +-module mod.com - -- "github.com/google/go-cmp/cmp" -- "golang.org/x/tools/gopls/internal/hooks" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/bug" -- "golang.org/x/tools/internal/testenv" +-go 1.16 +--- go.work -- +-go 1.18 - -- "golang.org/x/tools/gopls/internal/lsp/protocol" --) +-use . +--- main.go -- +-package main - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- Main(m, hooks.Options) +-func F[T any](_ T) { -} +-` +- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +- var d protocol.PublishDiagnosticsParams - --const proxy = ` ---- example.com@v1.2.3/go.mod -- --module example.com -- --go 1.12 ---- example.com@v1.2.3/blah/blah.go -- --package blah -- --const Name = "Blah" ---- random.org@v1.2.3/go.mod -- --module random.org +- // We should have a diagnostic because generics are not supported at 1.16. +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), +- ReadDiagnostics("main.go", &d), +- ) - --go 1.12 ---- random.org@v1.2.3/blah/blah.go -- --package hello +- // This diagnostic should have a quick fix to edit the go version. +- env.ApplyQuickFixes("main.go", d.Diagnostics) - --const Name = "Hello" --` +- // Once the edit is applied, the problematic diagnostics should be +- // resolved. +- env.AfterChange( +- NoDiagnostics(ForFile("main.go")), +- ) +- }) +-} - --func TestPackageCompletion(t *testing.T) { -- const files = ` +-// This test demonstrates that analysis facts are correctly propagated +-// across packages. +-func TestInterpackageAnalysis(t *testing.T) { +- const src = ` --- go.mod -- --module mod.com +-module example.com +--- a/a.go -- +-package a - --go 1.12 ---- fruits/apple.go -- --package apple +-import "example.com/b" - --fun apple() int { -- return 0 +-func _() { +- new(b.B).Printf("%d", "s") // printf error -} - ---- fruits/testfile.go -- --// this is a comment +--- b/b.go -- +-package b - --/* -- this is a multiline comment --*/ +-import "example.com/c" - --import "fmt" +-type B struct{} - --func test() {} +-func (B) Printf(format string, args ...interface{}) { +- c.MyPrintf(format, args...) +-} - ---- fruits/testfile2.go -- --package +--- c/c.go -- +-package c - ---- fruits/testfile3.go -- --pac ---- 123f_r.u~its-123/testfile.go -- --package +-import "fmt" - ---- .invalid-dir@-name/testfile.go -- --package +-func MyPrintf(format string, args ...interface{}) { +- fmt.Printf(format, args...) +-} -` -- var ( -- testfile4 = "" -- testfile5 = "/*a comment*/ " -- testfile6 = "/*a comment*/\n" -- ) -- for _, tc := range []struct { -- name string -- filename string -- content *string -- triggerRegexp string -- want []string -- editRegexp string -- }{ -- { -- name: "package completion at valid position", -- filename: "fruits/testfile.go", -- triggerRegexp: "\n()", -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "\n()", -- }, -- { -- name: "package completion in a comment", -- filename: "fruits/testfile.go", -- triggerRegexp: "th(i)s", -- want: nil, -- }, -- { -- name: "package completion in a multiline comment", -- filename: "fruits/testfile.go", -- triggerRegexp: `\/\*\n()`, -- want: nil, -- }, -- { -- name: "package completion at invalid position", -- filename: "fruits/testfile.go", -- triggerRegexp: "import \"fmt\"\n()", -- want: nil, -- }, -- { -- name: "package completion after keyword 'package'", -- filename: "fruits/testfile2.go", -- triggerRegexp: "package()", -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "package\n", -- }, -- { -- name: "package completion with 'pac' prefix", -- filename: "fruits/testfile3.go", -- triggerRegexp: "pac()", -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "pac", -- }, -- { -- name: "package completion for empty file", -- filename: "fruits/testfile4.go", -- triggerRegexp: "^$", -- content: &testfile4, -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: "^$", -- }, -- { -- name: "package completion without terminal newline", -- filename: "fruits/testfile5.go", -- triggerRegexp: `\*\/ ()`, -- content: &testfile5, -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: `\*\/ ()`, -- }, -- { -- name: "package completion on terminal newline", -- filename: "fruits/testfile6.go", -- triggerRegexp: `\*\/\n()`, -- content: &testfile6, -- want: []string{"package apple", "package apple_test", "package fruits", "package fruits_test", "package main"}, -- editRegexp: `\*\/\n()`, -- }, -- // Issue golang/go#44680 -- { -- name: "package completion for dir name with punctuation", -- filename: "123f_r.u~its-123/testfile.go", -- triggerRegexp: "package()", -- want: []string{"package fruits123", "package fruits123_test", "package main"}, -- editRegexp: "package\n", -- }, -- { -- name: "package completion for invalid dir name", -- filename: ".invalid-dir@-name/testfile.go", -- triggerRegexp: "package()", -- want: []string{"package main"}, -- editRegexp: "package\n", -- }, -- } { -- t.Run(tc.name, func(t *testing.T) { -- Run(t, files, func(t *testing.T, env *Env) { -- if tc.content != nil { -- env.WriteWorkspaceFile(tc.filename, *tc.content) -- env.Await(env.DoneWithChangeWatchedFiles()) -- } -- env.OpenFile(tc.filename) -- completions := env.Completion(env.RegexpSearch(tc.filename, tc.triggerRegexp)) +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("a/a.go", "new.*Printf"), +- WithMessage("format %d has arg \"s\" of wrong type string"), +- ), +- ) +- }) +-} - -- // Check that the completion item suggestions are in the range -- // of the file. {Start,End}.Line are zero-based. -- lineCount := len(strings.Split(env.BufferText(tc.filename), "\n")) -- for _, item := range completions.Items { -- if start := int(item.TextEdit.Range.Start.Line); start > lineCount { -- t.Fatalf("unexpected text edit range start line number: got %d, want <= %d", start, lineCount) -- } -- if end := int(item.TextEdit.Range.End.Line); end > lineCount { -- t.Fatalf("unexpected text edit range end line number: got %d, want <= %d", end, lineCount) -- } -- } +-// This test ensures that only Analyzers with RunDespiteErrors=true +-// are invoked on a package that would not compile, even if the errors +-// are distant and localized. +-func TestErrorsThatPreventAnalysis(t *testing.T) { +- const src = ` +--- go.mod -- +-module example.com +--- a/a.go -- +-package a +- +-import "fmt" +-import "sync" +-import _ "example.com/b" +- +-func _() { +- // The copylocks analyzer (RunDespiteErrors, FactTypes={}) does run. +- var mu sync.Mutex +- mu2 := mu // copylocks error, reported +- _ = &mu2 - -- if tc.want != nil { -- expectedLoc := env.RegexpSearch(tc.filename, tc.editRegexp) -- for _, item := range completions.Items { -- gotRng := item.TextEdit.Range -- if expectedLoc.Range != gotRng { -- t.Errorf("unexpected completion range for completion item %s: got %v, want %v", -- item.Label, gotRng, expectedLoc.Range) -- } -- } -- } +- // The printf analyzer (!RunDespiteErrors, FactTypes!={}) does not run: +- // (c, printf) failed because of type error in c +- // (b, printf) and (a, printf) do not run because of failed prerequisites. +- fmt.Printf("%d", "s") // printf error, unreported - -- diff := compareCompletionLabels(tc.want, completions.Items) -- if diff != "" { -- t.Error(diff) -- } -- }) -- }) -- } +- // The bools analyzer (!RunDespiteErrors, FactTypes={}) does not run: +- var cond bool +- _ = cond != true && cond != true // bools error, unreported -} - --func TestPackageNameCompletion(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +--- b/b.go -- +-package b - --go 1.12 ---- math/add.go -- --package ma --` +-import _ "example.com/c" - -- want := []string{"ma", "ma_test", "main", "math", "math_test"} -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("math/add.go") -- completions := env.Completion(env.RegexpSearch("math/add.go", "package ma()")) +--- c/c.go -- +-package c - -- diff := compareCompletionLabels(want, completions.Items) -- if diff != "" { -- t.Fatal(diff) +-var _ = 1 / "" // type error +- +-` +- Run(t, src, func(t *testing.T, env *Env) { +- var diags protocol.PublishDiagnosticsParams +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "mu2 := (mu)"), WithMessage("assignment copies lock value")), +- ReadDiagnostics("a/a.go", &diags)) +- +- // Assert that there were no other diagnostics. +- // In particular: +- // - "fmt.Printf" does not trigger a [printf] finding; +- // - "cond != true" does not trigger a [bools] finding. +- // +- // We use this check in preference to NoDiagnosticAtRegexp +- // as it is robust in case of minor mistakes in the position +- // regexp, and because it reports unexpected diagnostics. +- if got, want := len(diags.Diagnostics), 1; got != want { +- t.Errorf("got %d diagnostics in a/a.go, want %d:", got, want) +- for i, diag := range diags.Diagnostics { +- t.Logf("Diagnostics[%d] = %+v", i, diag) +- } - } - }) -} - --// TODO(rfindley): audit/clean up call sites for this helper, to ensure --// consistent test errors. --func compareCompletionLabels(want []string, gotItems []protocol.CompletionItem) string { -- var got []string -- for _, item := range gotItems { -- got = append(got, item.Label) -- if item.Label != item.InsertText && item.TextEdit == nil { -- // Label should be the same as InsertText, if InsertText is to be used -- return fmt.Sprintf("label not the same as InsertText %#v", item) -- } -- } +-// This test demonstrates the deprecated symbol analyzer +-// produces deprecation notices with expected severity and tags. +-func TestDeprecatedAnalysis(t *testing.T) { +- const src = ` +--- go.mod -- +-module example.com +--- a/a.go -- +-package a - -- if len(got) == 0 && len(want) == 0 { -- return "" // treat nil and the empty slice as equivalent -- } +-import "example.com/b" - -- if diff := cmp.Diff(want, got); diff != "" { -- return fmt.Sprintf("completion item mismatch (-want +got):\n%s", diff) -- } -- return "" +-func _() { +- new(b.B).Obsolete() // deprecated -} - --func TestUnimportedCompletion(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +--- b/b.go -- +-package b - --go 1.14 +-type B struct{} - --require example.com v1.2.3 ---- go.sum -- --example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= --example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= ---- main.go -- --package main +-// Deprecated: use New instead. +-func (B) Obsolete() {} - --func main() { -- _ = blah +-func (B) New() {} +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- env.AfterChange( +- Diagnostics( +- env.AtRegexp("a/a.go", "new.*Obsolete"), +- WithMessage("use New instead."), +- WithSeverityTags("deprecated", protocol.SeverityHint, []protocol.DiagnosticTag{protocol.Deprecated}), +- ), +- ) +- }) -} ---- main2.go -- --package main +diff -urN a/gopls/internal/regtest/diagnostics/golist_test.go b/gopls/internal/regtest/diagnostics/golist_test.go +--- a/gopls/internal/regtest/diagnostics/golist_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/golist_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,71 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --import "example.com/blah" +-package diagnostics - --func _() { -- _ = blah.Hello +-import ( +- "testing" +- +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/gopls/internal/lsp/source" +- "golang.org/x/tools/internal/testenv" +-) +- +-func TestGoListErrors(t *testing.T) { +- testenv.NeedsTool(t, "cgo") +- +- const src = ` +--- go.mod -- +-module a.com +- +-go 1.18 +--- a/a.go -- +-package a +- +-import +--- c/c.go -- +-package c +- +-/* +-int fortythree() { return 42; } +-*/ +-import "C" +- +-func Foo() { +- print(C.fortytwo()) -} --` -- WithOptions( -- ProxyFiles(proxy), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- // Make sure the dependency is in the module cache and accessible for -- // unimported completions, and then remove it before proceeding. -- env.RemoveWorkspaceFile("main2.go") -- env.RunGoCommand("mod", "tidy") -- env.Await(env.DoneWithChangeWatchedFiles()) +--- p/p.go -- +-package p - -- // Trigger unimported completions for the example.com/blah package. -- env.OpenFile("main.go") -- env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch("main.go", "ah") -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } -- env.AcceptCompletion(loc, completions.Items[0]) // adds blah import to main.go -- env.Await(env.DoneWithChange()) +-import "a.com/q" - -- // Trigger completions once again for the blah.<> selector. -- env.RegexpReplace("main.go", "_ = blah", "_ = blah.") -- env.Await(env.DoneWithChange()) -- loc = env.RegexpSearch("main.go", "\n}") -- completions = env.Completion(loc) -- if len(completions.Items) != 1 { -- t.Fatalf("expected 1 completion item, got %v", len(completions.Items)) -- } -- item := completions.Items[0] -- if item.Label != "Name" { -- t.Fatalf("expected completion item blah.Name, got %v", item.Label) -- } -- env.AcceptCompletion(loc, item) +-const P = q.Q + 1 +--- q/q.go -- +-package q - -- // Await the diagnostics to add example.com/blah to the go.mod file. -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"example.com/blah"`)), +-import "a.com/p" +- +-const Q = p.P + 1 +-` +- +- Run(t, src, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- Diagnostics( +- env.AtRegexp("a/a.go", "import\n()"), +- FromSource(string(source.ParseError)), +- ), +- Diagnostics( +- AtPosition("c/c.go", 0, 0), +- FromSource(string(source.ListError)), +- WithMessage("may indicate failure to perform cgo processing"), +- ), +- Diagnostics( +- env.AtRegexp("p/p.go", `"a.com/q"`), +- FromSource(string(source.ListError)), +- WithMessage("import cycle not allowed"), +- ), - ) - }) -} +diff -urN a/gopls/internal/regtest/diagnostics/invalidation_test.go b/gopls/internal/regtest/diagnostics/invalidation_test.go +--- a/gopls/internal/regtest/diagnostics/invalidation_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/invalidation_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,111 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --// Test that completions still work with an undownloaded module, golang/go#43333. --func TestUndownloadedModule(t *testing.T) { -- // mod.com depends on example.com, but only in a file that's hidden by a -- // build tag, so the IWL won't download example.com. That will cause errors -- // in the go list -m call performed by the imports package. +-package diagnostics +- +-import ( +- "fmt" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) +- +-// Test for golang/go#50267: diagnostics should be re-sent after a file is +-// opened. +-func TestDiagnosticsAreResentAfterCloseOrOpen(t *testing.T) { - const files = ` --- go.mod -- -module mod.com - --go 1.14 -- --require example.com v1.2.3 ---- go.sum -- --example.com v1.2.3 h1:ihBTGWGjTU3V4ZJ9OmHITkU9WQ4lGdQkMjgyLFk0FaY= --example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo= ---- useblah.go -- --// +build hidden -- --package pkg --import "example.com/blah" --var _ = blah.Name ---- mainmod/mainmod.go -- --package mainmod +-go 1.16 +--- main.go -- +-package main - --const Name = "mainmod" +-func _() { +- x := 2 +-} -` -- WithOptions(ProxyFiles(proxy)).Run(t, files, func(t *testing.T, env *Env) { -- env.CreateBuffer("import.go", "package pkg\nvar _ = mainmod.Name\n") -- env.SaveBuffer("import.go") -- content := env.ReadWorkspaceFile("import.go") -- if !strings.Contains(content, `import "mod.com/mainmod`) { -- t.Errorf("expected import of mod.com/mainmod in %q", content) +- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +- env.OpenFile("main.go") +- var afterOpen protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &afterOpen), +- ) +- env.CloseBuffer("main.go") +- var afterClose protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &afterClose), +- ) +- if afterOpen.Version == afterClose.Version { +- t.Errorf("publishDiagnostics: got the same version after closing (%d) as after opening", afterOpen.Version) +- } +- env.OpenFile("main.go") +- var afterReopen protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &afterReopen), +- ) +- if afterReopen.Version == afterClose.Version { +- t.Errorf("pubslishDiagnostics: got the same version after reopening (%d) as after closing", afterClose.Version) - } - }) -} - --// Test that we can doctor the source code enough so the file is --// parseable and completion works as expected. --func TestSourceFixup(t *testing.T) { +-// Test for the "chattyDiagnostics" setting: we should get re-published +-// diagnostics after every file change, even if diagnostics did not change. +-func TestChattyDiagnostics(t *testing.T) { - const files = ` --- go.mod -- -module mod.com - --go 1.12 ---- foo.go -- --package foo +-go 1.16 +--- main.go -- +-package main - -func _() { -- var s S -- if s. +- x := 2 -} - --type S struct { -- i int --} +-// Irrelevant comment #0 -` - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("foo.go") -- completions := env.Completion(env.RegexpSearch("foo.go", `if s\.()`)) -- diff := compareCompletionLabels([]string{"i"}, completions.Items) -- if diff != "" { -- t.Fatal(diff) +- WithOptions( +- Settings{ +- "chattyDiagnostics": true, +- }, +- ).Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +- +- env.OpenFile("main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange( +- ReadDiagnostics("main.go", &d), +- ) +- +- if len(d.Diagnostics) != 1 { +- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) +- } +- msg := d.Diagnostics[0].Message +- +- for i := 0; i < 5; i++ { +- before := d.Version +- env.RegexpReplace("main.go", "Irrelevant comment #.", fmt.Sprintf("Irrelevant comment #%d", i)) +- env.AfterChange( +- ReadDiagnostics("main.go", &d), +- ) +- +- if d.Version == before { +- t.Errorf("after change, got version %d, want new version", d.Version) +- } +- +- // As a sanity check, make sure we have the same diagnostic. +- if len(d.Diagnostics) != 1 { +- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) +- } +- newMsg := d.Diagnostics[0].Message +- if newMsg != msg { +- t.Errorf("after change, got message %q, want %q", newMsg, msg) +- } - } - }) -} +diff -urN a/gopls/internal/regtest/diagnostics/undeclared_test.go b/gopls/internal/regtest/diagnostics/undeclared_test.go +--- a/gopls/internal/regtest/diagnostics/undeclared_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/diagnostics/undeclared_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,73 +0,0 @@ +-// Copyright 2021 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - --func TestCompletion_Issue45510(t *testing.T) { -- const files = ` +-package diagnostics +- +-import ( +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) +- +-func TestUndeclaredDiagnostics(t *testing.T) { +- src := ` --- go.mod -- -module mod.com - -go 1.12 ---- main.go -- --package main +--- a/a.go -- +-package a - --func _() { -- type a *a -- var aaaa1, aaaa2 a -- var _ a = aaaa +-func _() int { +- return x +-} +--- b/b.go -- +-package b - -- type b a -- var bbbb1, bbbb2 b -- var _ b = bbbb +-func _() int { +- var y int +- y = y +- return y -} +-` +- Run(t, src, func(t *testing.T, env *Env) { +- isUnnecessary := func(diag protocol.Diagnostic) bool { +- for _, tag := range diag.Tags { +- if tag == protocol.Unnecessary { +- return true +- } +- } +- return false +- } - --type ( -- c *d -- d *e -- e **c +- // 'x' is undeclared, but still necessary. +- env.OpenFile("a/a.go") +- var adiags protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("a/a.go", "x")), +- ReadDiagnostics("a/a.go", &adiags), +- ) +- if got := len(adiags.Diagnostics); got != 1 { +- t.Errorf("len(Diagnostics) = %d, want 1", got) +- } +- if diag := adiags.Diagnostics[0]; isUnnecessary(diag) { +- t.Errorf("%v tagged unnecessary, want necessary", diag) +- } +- +- // 'y = y' is pointless, and should be detected as unnecessary. +- env.OpenFile("b/b.go") +- var bdiags protocol.PublishDiagnosticsParams +- env.AfterChange( +- Diagnostics(env.AtRegexp("b/b.go", "y = y")), +- ReadDiagnostics("b/b.go", &bdiags), +- ) +- if got := len(bdiags.Diagnostics); got != 1 { +- t.Errorf("len(Diagnostics) = %d, want 1", got) +- } +- if diag := bdiags.Diagnostics[0]; !isUnnecessary(diag) { +- t.Errorf("%v tagged necessary, want unnecessary", diag) +- } +- }) +-} +diff -urN a/gopls/internal/regtest/inlayhints/inlayhints_test.go b/gopls/internal/regtest/inlayhints/inlayhints_test.go +--- a/gopls/internal/regtest/inlayhints/inlayhints_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/inlayhints/inlayhints_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +-package inlayhint +- +-import ( +- "testing" +- +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/gopls/internal/lsp/source" -) - --func _() { -- var ( -- xxxxc c -- xxxxd d -- xxxxe e -- ) +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- Main(m, hooks.Options) +-} - -- var _ c = xxxx -- var _ d = xxxx -- var _ e = xxxx +-func TestEnablingInlayHints(t *testing.T) { +- const workspace = ` +--- go.mod -- +-module inlayHint.test +-go 1.12 +--- lib.go -- +-package lib +-type Number int +-const ( +- Zero Number = iota +- One +- Two +-) +-` +- tests := []struct { +- label string +- enabled map[string]bool +- wantInlayHint bool +- }{ +- { +- label: "default", +- wantInlayHint: false, +- }, +- { +- label: "enable const", +- enabled: map[string]bool{source.ConstantValues: true}, +- wantInlayHint: true, +- }, +- { +- label: "enable parameter names", +- enabled: map[string]bool{source.ParameterNames: true}, +- wantInlayHint: false, +- }, +- } +- for _, test := range tests { +- t.Run(test.label, func(t *testing.T) { +- WithOptions( +- Settings{ +- "hints": test.enabled, +- }, +- ).Run(t, workspace, func(t *testing.T, env *Env) { +- env.OpenFile("lib.go") +- lens := env.InlayHints("lib.go") +- if gotInlayHint := len(lens) > 0; gotInlayHint != test.wantInlayHint { +- t.Errorf("got inlayHint: %t, want %t", gotInlayHint, test.wantInlayHint) +- } +- }) +- }) +- } -} --` +diff -urN a/gopls/internal/regtest/marker/marker_test.go b/gopls/internal/regtest/marker/marker_test.go +--- a/gopls/internal/regtest/marker/marker_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/marker_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") +-package marker - -- tests := []struct { -- re string -- want []string -- }{ -- {`var _ a = aaaa()`, []string{"aaaa1", "aaaa2"}}, -- {`var _ b = bbbb()`, []string{"bbbb1", "bbbb2"}}, -- {`var _ c = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, -- {`var _ d = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, -- {`var _ e = xxxx()`, []string{"xxxxc", "xxxxd", "xxxxe"}}, -- } -- for _, tt := range tests { -- completions := env.Completion(env.RegexpSearch("main.go", tt.re)) -- diff := compareCompletionLabels(tt.want, completions.Items) -- if diff != "" { -- t.Errorf("%s: %s", tt.re, diff) -- } -- } -- }) --} +-import ( +- "os" +- "testing" - --func TestCompletionDeprecation(t *testing.T) { -- const files = ` ---- go.mod -- --module test.com +- "golang.org/x/tools/gopls/internal/bug" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/testenv" +-) - --go 1.16 ---- prog.go -- --package waste --// Deprecated, use newFoof --func fooFunc() bool { -- return false +-func TestMain(m *testing.M) { +- bug.PanicOnBugs = true +- testenv.ExitIfSmallMachine() +- os.Exit(m.Run()) -} - --// Deprecated --const badPi = 3.14 +-// Note: we use a separate package for the marker tests so that we can easily +-// compare their performance to the existing marker tests in ./internal/lsp. - --func doit() { -- if fooF -- panic() -- x := badP --} --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("prog.go") -- loc := env.RegexpSearch("prog.go", "if fooF") -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("if fooF"))) -- completions := env.Completion(loc) -- diff := compareCompletionLabels([]string{"fooFunc"}, completions.Items) -- if diff != "" { -- t.Error(diff) -- } -- if completions.Items[0].Tags == nil { -- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) -- } -- loc = env.RegexpSearch("prog.go", "= badP") -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte("= badP"))) -- completions = env.Completion(loc) -- diff = compareCompletionLabels([]string{"badPi"}, completions.Items) -- if diff != "" { -- t.Error(diff) -- } -- if completions.Items[0].Tags == nil { -- t.Errorf("expected Tags to show deprecation %#v", completions.Items[0].Tags) -- } -- }) +-// TestMarkers runs the marker tests from the testdata directory. +-// +-// See RunMarkerTests for details on how marker tests work. +-func TestMarkers(t *testing.T) { +- RunMarkerTests(t, "testdata") -} +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction_issue44813.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-This test verifies the fix for golang/go#44813: extraction failure when there +-are blank identifiers. - --func TestUnimportedCompletion_VSCodeIssue1489(t *testing.T) { -- const src = ` --- go.mod -- --module mod.com +-module mod.test/extract - --go 1.14 +-go 1.18 - ---- main.go -- --package main +--- p.go -- +-package extract - -import "fmt" - -func main() { -- fmt.Println("a") -- math.Sqr --} --` -- WithOptions( -- WindowsLineEndings(), -- ).Run(t, src, func(t *testing.T, env *Env) { -- // Trigger unimported completions for the mod.com package. -- env.OpenFile("main.go") -- env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch("main.go", "Sqr()") -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } -- env.AcceptCompletion(loc, completions.Items[0]) -- env.Await(env.DoneWithChange()) -- got := env.BufferText("main.go") -- want := "package main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"math\"\r\n)\r\n\r\nfunc main() {\r\n\tfmt.Println(\"a\")\r\n\tmath.Sqrt(${1:})\r\n}\r\n" -- if diff := cmp.Diff(want, got); diff != "" { -- t.Errorf("unimported completion (-want +got):\n%s", diff) -- } -- }) +- x := []rune{} //@codeaction("refactor.extract", "x", end, ext) +- s := "HELLO" +- for _, c := range s { +- x = append(x, c) +- } //@loc(end, "}") +- fmt.Printf("%x\n", x) -} - --func TestPackageMemberCompletionAfterSyntaxError(t *testing.T) { -- // This test documents the current broken behavior due to golang/go#58833. -- const src = ` ---- go.mod -- --module mod.com -- --go 1.14 -- ---- main.go -- --package main +--- @ext/p.go -- +-package extract - --import "math" +-import "fmt" - -func main() { -- math.Sqrt(,0) -- math.Ldex --} --` -- Run(t, src, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.Await(env.DoneWithOpen()) -- loc := env.RegexpSearch("main.go", "Ldex()") -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } -- env.AcceptCompletion(loc, completions.Items[0]) -- env.Await(env.DoneWithChange()) -- got := env.BufferText("main.go") -- // The completion of math.Ldex after the syntax error on the -- // previous line is not "math.Ldexp" but "math.Ldexmath.Abs". -- // (In VSCode, "Abs" wrongly appears in the completion menu.) -- // This is a consequence of poor error recovery in the parser -- // causing "math.Ldex" to become a BadExpr. -- want := "package main\n\nimport \"math\"\n\nfunc main() {\n\tmath.Sqrt(,0)\n\tmath.Ldexmath.Abs(${1:})\n}\n" -- if diff := cmp.Diff(want, got); diff != "" { -- t.Errorf("unimported completion (-want +got):\n%s", diff) -- } -- }) +- //@codeaction("refactor.extract", "x", end, ext) +- x := newFunction() //@loc(end, "}") +- fmt.Printf("%x\n", x) -} - --func TestDefinition(t *testing.T) { -- testenv.NeedsGo1Point(t, 17) // in go1.16, The FieldList in func x is not empty -- files := ` ---- go.mod -- --module mod.com -- --go 1.18 ---- a_test.go -- --package foo --` -- tests := []struct { -- line string // the sole line in the buffer after the package statement -- pat string // the pattern to search for -- want []string // expected completions -- }{ -- {"func T", "T", []string{"TestXxx(t *testing.T)", "TestMain(m *testing.M)"}}, -- {"func T()", "T", []string{"TestMain", "Test"}}, -- {"func TestM", "TestM", []string{"TestMain(m *testing.M)", "TestM(t *testing.T)"}}, -- {"func TestM()", "TestM", []string{"TestMain"}}, -- {"func TestMi", "TestMi", []string{"TestMi(t *testing.T)"}}, -- {"func TestMi()", "TestMi", nil}, -- {"func TestG", "TestG", []string{"TestG(t *testing.T)"}}, -- {"func TestG(", "TestG", nil}, -- {"func Ben", "B", []string{"BenchmarkXxx(b *testing.B)"}}, -- {"func Ben(", "Ben", []string{"Benchmark"}}, -- {"func BenchmarkFoo", "BenchmarkFoo", []string{"BenchmarkFoo(b *testing.B)"}}, -- {"func BenchmarkFoo(", "BenchmarkFoo", nil}, -- {"func Fuz", "F", []string{"FuzzXxx(f *testing.F)"}}, -- {"func Fuz(", "Fuz", []string{"Fuzz"}}, -- {"func Testx", "Testx", nil}, -- {"func TestMe(t *testing.T)", "TestMe", nil}, -- {"func Te(t *testing.T)", "Te", []string{"TestMain", "Test"}}, +-func newFunction() []rune { +- x := []rune{} +- s := "HELLO" +- for _, c := range s { +- x = append(x, c) - } -- fname := "a_test.go" -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile(fname) -- env.Await(env.DoneWithOpen()) -- for _, test := range tests { -- env.SetBufferContent(fname, "package foo\n"+test.line) -- loc := env.RegexpSearch(fname, test.pat) -- loc.Range.Start.Character += uint32(protocol.UTF16Len([]byte(test.pat))) -- completions := env.Completion(loc) -- if diff := compareCompletionLabels(test.want, completions.Items); diff != "" { -- t.Error(diff) -- } -- } -- }) +- return x -} - --// Test that completing a definition replaces source text when applied, golang/go#56852. --// Note: With go <= 1.16 the completions does not add parameters and fails these tests. --func TestDefinitionReplaceRange(t *testing.T) { -- testenv.NeedsGo1Point(t, 17) +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/functionextraction.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,583 +0,0 @@ +-This test verifies various behaviors of function extraction. - -- const mod = ` --- go.mod -- --module mod.com +-module mod.test/extract - --go 1.17 --` +-go 1.18 - -- tests := []struct { -- name string -- before, after string -- }{ -- { -- name: "func TestMa", -- before: ` --package foo_test +--- basic.go -- +-package extract - --func TestMa --`, -- after: ` --package foo_test +-func _() { //@codeaction("refactor.extract", "{", closeBracket, outer) +- a := 1 //@codeaction("refactor.extract", "a", end, inner) +- _ = a + 4 //@loc(end, "4") +-} //@loc(closeBracket, "}") - --func TestMain(m *testing.M) --`, -- }, -- { -- name: "func TestSome", -- before: ` --package foo_test +--- @inner/basic.go -- +-package extract - --func TestSome --`, -- after: ` --package foo_test +-func _() { //@codeaction("refactor.extract", "{", closeBracket, outer) +- //@codeaction("refactor.extract", "a", end, inner) +- newFunction() //@loc(end, "4") +-} - --func TestSome(t *testing.T) --`, -- }, -- { -- name: "func Bench", -- before: ` --package foo_test +-func newFunction() { +- a := 1 +- _ = a + 4 +-} //@loc(closeBracket, "}") - --func Bench --`, -- // Note: Snippet with escaped }. -- after: ` --package foo_test +--- @outer/basic.go -- +-package extract - --func Benchmark${1:Xxx}(b *testing.B) { -- $0 --\} --`, -- }, -- } +-func _() { //@codeaction("refactor.extract", "{", closeBracket, outer) +- //@codeaction("refactor.extract", "a", end, inner) +- newFunction() //@loc(end, "4") +-} - -- Run(t, mod, func(t *testing.T, env *Env) { -- env.CreateBuffer("foo_test.go", "") +-func newFunction() { +- a := 1 +- _ = a + 4 +-} //@loc(closeBracket, "}") - -- for _, tst := range tests { -- tst.before = strings.Trim(tst.before, "\n") -- tst.after = strings.Trim(tst.after, "\n") -- env.SetBufferContent("foo_test.go", tst.before) +--- return.go -- +-package extract - -- loc := env.RegexpSearch("foo_test.go", tst.name) -- loc.Range.Start.Character = uint32(protocol.UTF16Len([]byte(tst.name))) -- completions := env.Completion(loc) -- if len(completions.Items) == 0 { -- t.Fatalf("no completion items") -- } +-func _() bool { +- x := 1 +- if x == 0 { //@codeaction("refactor.extract", "if", ifend, return) +- return true +- } //@loc(ifend, "}") +- return false +-} - -- env.AcceptCompletion(loc, completions.Items[0]) -- env.Await(env.DoneWithChange()) -- if buf := env.BufferText("foo_test.go"); buf != tst.after { -- t.Errorf("%s:incorrect completion: got %q, want %q", tst.name, buf, tst.after) -- } -- } -- }) +--- @return/return.go -- +-package extract +- +-func _() bool { +- x := 1 +- //@codeaction("refactor.extract", "if", ifend, return) +- shouldReturn, returnValue := newFunction(x) +- if shouldReturn { +- return returnValue +- } //@loc(ifend, "}") +- return false -} - --func TestGoWorkCompletion(t *testing.T) { -- const files = ` ---- go.work -- --go 1.18 +-func newFunction(x int) (bool, bool) { +- if x == 0 { +- return true, true +- } +- return false, false +-} - --use ./a --use ./a/ba --use ./a/b/ --use ./dir/foo --use ./dir/foobar/ ---- a/go.mod -- ---- go.mod -- ---- a/bar/go.mod -- ---- a/b/c/d/e/f/go.mod -- ---- dir/bar -- ---- dir/foobar/go.mod -- --` +--- return_nonnested.go -- +-package extract - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("go.work") +-func _() bool { +- x := 1 //@codeaction("refactor.extract", "x", rnnEnd, rnn) +- if x == 0 { +- return true +- } +- return false //@loc(rnnEnd, "false") +-} - -- tests := []struct { -- re string -- want []string -- }{ -- {`use ()\.`, []string{".", "./a", "./a/bar", "./dir/foobar"}}, -- {`use \.()`, []string{"", "/a", "/a/bar", "/dir/foobar"}}, -- {`use \./()`, []string{"a", "a/bar", "dir/foobar"}}, -- {`use ./a()`, []string{"", "/b/c/d/e/f", "/bar"}}, -- {`use ./a/b()`, []string{"/c/d/e/f", "ar"}}, -- {`use ./a/b/()`, []string{`c/d/e/f`}}, -- {`use ./a/ba()`, []string{"r"}}, -- {`use ./dir/foo()`, []string{"bar"}}, -- {`use ./dir/foobar/()`, []string{}}, -- } -- for _, tt := range tests { -- completions := env.Completion(env.RegexpSearch("go.work", tt.re)) -- diff := compareCompletionLabels(tt.want, completions.Items) -- if diff != "" { -- t.Errorf("%s: %s", tt.re, diff) -- } -- } -- }) +--- @rnn/return_nonnested.go -- +-package extract +- +-func _() bool { +- //@codeaction("refactor.extract", "x", rnnEnd, rnn) +- return newFunction() //@loc(rnnEnd, "false") -} -diff -urN a/gopls/internal/regtest/completion/postfix_snippet_test.go b/gopls/internal/regtest/completion/postfix_snippet_test.go ---- a/gopls/internal/regtest/completion/postfix_snippet_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/completion/postfix_snippet_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,464 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package completion +-func newFunction() bool { +- x := 1 +- if x == 0 { +- return true +- } +- return false +-} - --import ( -- "strings" -- "testing" +--- return_complex.go -- +-package extract - -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-import "fmt" - --func TestPostfixSnippetCompletion(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- z := "bye" //@codeaction("refactor.extract", "z", rcEnd, rc) +- if y == z { +- return x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return x, z, nil +- } //@loc(rcEnd, "}") +- return x, z, nil +-} - --go 1.12 --` +--- @rc/return_complex.go -- +-package extract - -- cases := []struct { -- name string -- before, after string -- }{ -- { -- name: "sort", -- before: ` --package foo +-import "fmt" - --func _() { -- var foo []int -- foo.sort +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- //@codeaction("refactor.extract", "z", rcEnd, rc) +- z, shouldReturn, returnValue, returnValue1, returnValue2 := newFunction(y, x) +- if shouldReturn { +- return returnValue, returnValue1, returnValue2 +- } //@loc(rcEnd, "}") +- return x, z, nil -} --`, -- after: ` --package foo -- --import "sort" - --func _() { -- var foo []int -- sort.Slice(foo, func(i, j int) bool { -- $0 --}) +-func newFunction(y string, x int) (string, bool, int, string, error) { +- z := "bye" +- if y == z { +- return "", true, x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return "", true, x, z, nil +- } +- return z, false, 0, "", nil -} --`, -- }, -- { -- name: "sort_renamed_sort_package", -- before: ` --package foo - --import blahsort "sort" +--- return_complex_nonnested.go -- +-package extract - --var j int +-import "fmt" - --func _() { -- var foo []int -- foo.sort +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- z := "bye" //@codeaction("refactor.extract", "z", rcnnEnd, rcnn) +- if y == z { +- return x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return x, z, nil +- } +- return x, z, nil //@loc(rcnnEnd, "nil") -} --`, -- after: ` --package foo - --import blahsort "sort" +--- @rcnn/return_complex_nonnested.go -- +-package extract - --var j int +-import "fmt" - --func _() { -- var foo []int -- blahsort.Slice(foo, func(i, j2 int) bool { -- $0 --}) +-func _() (int, string, error) { +- x := 1 +- y := "hello" +- //@codeaction("refactor.extract", "z", rcnnEnd, rcnn) +- return newFunction(y, x) //@loc(rcnnEnd, "nil") -} --`, -- }, -- { -- name: "last", -- before: ` --package foo - --func _() { -- var s struct { i []int } -- s.i.last +-func newFunction(y string, x int) (int, string, error) { +- z := "bye" +- if y == z { +- return x, y, fmt.Errorf("same") +- } else if false { +- z = "hi" +- return x, z, nil +- } +- return x, z, nil -} --`, -- after: ` --package foo - --func _() { -- var s struct { i []int } -- s.i[len(s.i)-1] --} --`, -- }, -- { -- name: "reverse", -- before: ` --package foo +--- return_func_lit.go -- +-package extract +- +-import "go/ast" - -func _() { -- var foo []int -- foo.reverse +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- if n == nil { //@codeaction("refactor.extract", "if", rflEnd, rfl) +- return true +- } //@loc(rflEnd, "}") +- return false +- }) -} --`, -- after: ` --package foo +- +--- @rfl/return_func_lit.go -- +-package extract +- +-import "go/ast" - -func _() { -- var foo []int -- for i, j := 0, len(foo)-1; i < j; i, j = i+1, j-1 { -- foo[i], foo[j] = foo[j], foo[i] +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- //@codeaction("refactor.extract", "if", rflEnd, rfl) +- shouldReturn, returnValue := newFunction(n) +- if shouldReturn { +- return returnValue +- } //@loc(rflEnd, "}") +- return false +- }) -} - +-func newFunction(n ast.Node) (bool, bool) { +- if n == nil { +- return true, true +- } +- return false, false -} --`, -- }, -- { -- name: "slice_range", -- before: ` --package foo - --func _() { -- type myThing struct{} -- var foo []myThing -- foo.range --} --`, -- after: ` --package foo +--- return_func_lit_nonnested.go -- +-package extract +- +-import "go/ast" - -func _() { -- type myThing struct{} -- var foo []myThing -- for i, mt := range foo { -- $0 --} +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- if n == nil { //@codeaction("refactor.extract", "if", rflnnEnd, rflnn) +- return true +- } +- return false //@loc(rflnnEnd, "false") +- }) -} --`, -- }, -- { -- name: "append_stmt", -- before: ` --package foo +- +--- @rflnn/return_func_lit_nonnested.go -- +-package extract +- +-import "go/ast" - -func _() { -- var foo []int -- foo.append +- ast.Inspect(ast.NewIdent("a"), func(n ast.Node) bool { +- //@codeaction("refactor.extract", "if", rflnnEnd, rflnn) +- return newFunction(n) //@loc(rflnnEnd, "false") +- }) -} --`, -- after: ` --package foo - --func _() { -- var foo []int -- foo = append(foo, $0) +-func newFunction(n ast.Node) bool { +- if n == nil { +- return true +- } +- return false -} --`, -- }, -- { -- name: "append_expr", -- before: ` --package foo - --func _() { -- var foo []int -- var _ []int = foo.append +--- return_init.go -- +-package extract +- +-func _() string { +- x := 1 +- if x == 0 { //@codeaction("refactor.extract", "if", riEnd, ri) +- x = 3 +- return "a" +- } //@loc(riEnd, "}") +- x = 2 +- return "b" -} --`, -- after: ` --package foo - --func _() { -- var foo []int -- var _ []int = append(foo, $0) +--- @ri/return_init.go -- +-package extract +- +-func _() string { +- x := 1 +- //@codeaction("refactor.extract", "if", riEnd, ri) +- shouldReturn, returnValue := newFunction(x) +- if shouldReturn { +- return returnValue +- } //@loc(riEnd, "}") +- x = 2 +- return "b" -} --`, -- }, -- { -- name: "slice_copy", -- before: ` --package foo - --func _() { -- var foo []int -- foo.copy +-func newFunction(x int) (bool, string) { +- if x == 0 { +- x = 3 +- return true, "a" +- } +- return false, "" -} --`, -- after: ` --package foo - --func _() { -- var foo []int -- fooCopy := make([]int, len(foo)) --copy(fooCopy, foo) +--- return_init_nonnested.go -- +-package extract - +-func _() string { +- x := 1 +- if x == 0 { //@codeaction("refactor.extract", "if", rinnEnd, rinn) +- x = 3 +- return "a" +- } +- x = 2 +- return "b" //@loc(rinnEnd, "\"b\"") -} --`, -- }, -- { -- name: "map_range", -- before: ` --package foo - --func _() { -- var foo map[string]int -- foo.range --} --`, -- after: ` --package foo +--- @rinn/return_init_nonnested.go -- +-package extract - --func _() { -- var foo map[string]int -- for k, v := range foo { -- $0 +-func _() string { +- x := 1 +- //@codeaction("refactor.extract", "if", rinnEnd, rinn) +- return newFunction(x) //@loc(rinnEnd, "\"b\"") -} +- +-func newFunction(x int) string { +- if x == 0 { +- x = 3 +- return "a" +- } +- x = 2 +- return "b" -} --`, -- }, -- { -- name: "map_clear", -- before: ` --package foo +- +--- args_returns.go -- +-package extract - -func _() { -- var foo map[string]int -- foo.clear +- a := 1 +- a = 5 //@codeaction("refactor.extract", "a", araend, ara) +- a = a + 2 //@loc(araend, "2") +- +- b := a * 2 //@codeaction("refactor.extract", "b", arbend, arb) +- _ = b + 4 //@loc(arbend, "4") -} --`, -- after: ` --package foo +- +--- @ara/args_returns.go -- +-package extract - -func _() { -- var foo map[string]int -- for k := range foo { -- delete(foo, k) --} +- a := 1 +- //@codeaction("refactor.extract", "a", araend, ara) +- a = newFunction(a) //@loc(araend, "2") - +- b := a * 2 //@codeaction("refactor.extract", "b", arbend, arb) +- _ = b + 4 //@loc(arbend, "4") -} --`, -- }, -- { -- name: "map_keys", -- before: ` --package foo - --func _() { -- var foo map[string]int -- foo.keys +-func newFunction(a int) int { +- a = 5 +- a = a + 2 +- return a -} --`, -- after: ` --package foo +- +--- @arb/args_returns.go -- +-package extract - -func _() { -- var foo map[string]int -- keys := make([]string, 0, len(foo)) --for k := range foo { -- keys = append(keys, k) --} +- a := 1 +- a = 5 //@codeaction("refactor.extract", "a", araend, ara) +- a = a + 2 //@loc(araend, "2") - +- //@codeaction("refactor.extract", "b", arbend, arb) +- newFunction(a) //@loc(arbend, "4") -} --`, -- }, -- { -- name: "channel_range", -- before: ` --package foo - --func _() { -- foo := make(chan int) -- foo.range +-func newFunction(a int) { +- b := a * 2 +- _ = b + 4 -} --`, -- after: ` --package foo +- +--- scope.go -- +-package extract - -func _() { -- foo := make(chan int) -- for e := range foo { -- $0 +- newFunction := 1 +- a := newFunction //@codeaction("refactor.extract", "a", "newFunction", scope) +- _ = a // avoid diagnostic -} +- +-func newFunction1() int { +- return 1 -} --`, -- }, -- { -- name: "var", -- before: ` --package foo - --func foo() (int, error) { return 0, nil } +--- @scope/scope.go -- +-package extract - -func _() { -- foo().var +- newFunction := 1 +- a := newFunction2(newFunction) //@codeaction("refactor.extract", "a", "newFunction", scope) +- _ = a // avoid diagnostic -} --`, -- after: ` --package foo - --func foo() (int, error) { return 0, nil } +-func newFunction2(newFunction int) int { +- a := newFunction +- return a +-} - --func _() { -- i, err := foo() +-func newFunction1() int { +- return 1 -} --`, -- }, -- { -- name: "var_single_value", -- before: ` --package foo - --func foo() error { return nil } +--- smart_initialization.go -- +-package extract - -func _() { -- foo().var +- var a []int +- a = append(a, 2) //@codeaction("refactor.extract", "a", siEnd, si) +- b := 4 //@loc(siEnd, "4") +- a = append(a, b) -} --`, -- after: ` --package foo - --func foo() error { return nil } +--- @si/smart_initialization.go -- +-package extract - -func _() { -- err := foo() +- var a []int +- //@codeaction("refactor.extract", "a", siEnd, si) +- a, b := newFunction(a) //@loc(siEnd, "4") +- a = append(a, b) -} --`, -- }, -- { -- name: "var_same_type", -- before: ` --package foo - --func foo() (int, int) { return 0, 0 } +-func newFunction(a []int) ([]int, int) { +- a = append(a, 2) +- b := 4 +- return a, b +-} +- +--- smart_return.go -- +-package extract - -func _() { -- foo().var +- var b []int +- var a int +- a = 2 //@codeaction("refactor.extract", "a", srEnd, sr) +- b = []int{} +- b = append(b, a) //@loc(srEnd, ")") +- b[0] = 1 -} --`, -- after: ` --package foo - --func foo() (int, int) { return 0, 0 } +--- @sr/smart_return.go -- +-package extract - -func _() { -- i, i2 := foo() +- var b []int +- var a int +- //@codeaction("refactor.extract", "a", srEnd, sr) +- b = newFunction(a, b) //@loc(srEnd, ")") +- b[0] = 1 -} --`, -- }, -- { -- name: "print_scalar", -- before: ` --package foo - --func _() { -- var foo int -- foo.print +-func newFunction(a int, b []int) []int { +- a = 2 +- b = []int{} +- b = append(b, a) +- return b -} --`, -- after: ` --package foo - --import "fmt" +--- unnecessary_param.go -- +-package extract - -func _() { -- var foo int -- fmt.Printf("foo: %v\n", foo) +- var b []int +- a := 2 //@codeaction("refactor.extract", "a", upEnd, up) +- b = []int{} +- b = append(b, a) //@loc(upEnd, ")") +- b[0] = 1 +- if a == 2 { +- return +- } -} --`, -- }, -- { -- name: "print_multi", -- before: ` --package foo - --func foo() (int, error) { return 0, nil } +--- @up/unnecessary_param.go -- +-package extract - -func _() { -- foo().print +- var b []int +- //@codeaction("refactor.extract", "a", upEnd, up) +- a, b := newFunction(b) //@loc(upEnd, ")") +- b[0] = 1 +- if a == 2 { +- return +- } -} --`, -- after: ` --package foo - --import "fmt" +-func newFunction(b []int) (int, []int) { +- a := 2 +- b = []int{} +- b = append(b, a) +- return a, b +-} - --func foo() (int, error) { return 0, nil } +--- comment.go -- +-package extract - -func _() { -- fmt.Println(foo()) +- a := /* comment in the middle of a line */ 1 //@codeaction("refactor.extract", "a", commentEnd, comment1) +- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) +- _ = a + 4 //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) +- // Comment right after 3 + 4 +- +- // Comment after with space //@loc(lastComment, "Comment") -} --`, -- }, -- { -- name: "string split", -- before: ` --package foo - --func foo() []string { -- x := "test" -- return x.split --}`, -- after: ` --package foo +--- @comment1/comment.go -- +-package extract - --import "strings" +-func _() { +- /* comment in the middle of a line */ +- //@codeaction("refactor.extract", "a", commentEnd, comment1) +- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) +- newFunction() //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) +- // Comment right after 3 + 4 - --func foo() []string { -- x := "test" -- return strings.Split(x, "$0") --}`, -- }, -- { -- name: "string slice join", -- before: ` --package foo +- // Comment after with space //@loc(lastComment, "Comment") +-} - --func foo() string { -- x := []string{"a", "test"} -- return x.join --}`, -- after: ` --package foo +-func newFunction() { +- a := 1 - --import "strings" +- _ = a + 4 +-} - --func foo() string { -- x := []string{"a", "test"} -- return strings.Join(x, "$0") --}`, -- }, -- } +--- @comment2/comment.go -- +-package extract - -- r := WithOptions( -- Settings{ -- "experimentalPostfixCompletions": true, -- }, -- ) -- r.Run(t, mod, func(t *testing.T, env *Env) { -- env.CreateBuffer("foo.go", "") +-func _() { +- a := /* comment in the middle of a line */ 1 //@codeaction("refactor.extract", "a", commentEnd, comment1) +- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) +- newFunction(a) //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) +- // Comment right after 3 + 4 - -- for _, c := range cases { -- t.Run(c.name, func(t *testing.T) { -- c.before = strings.Trim(c.before, "\n") -- c.after = strings.Trim(c.after, "\n") +- // Comment after with space //@loc(lastComment, "Comment") +-} - -- env.SetBufferContent("foo.go", c.before) +-func newFunction(a int) { +- _ = a + 4 +-} - -- loc := env.RegexpSearch("foo.go", "\n}") -- completions := env.Completion(loc) -- if len(completions.Items) != 1 { -- t.Fatalf("expected one completion, got %v", completions.Items) -- } +--- @comment3/comment.go -- +-package extract - -- env.AcceptCompletion(loc, completions.Items[0]) +-func _() { +- a := /* comment in the middle of a line */ 1 //@codeaction("refactor.extract", "a", commentEnd, comment1) +- // Comment on its own line //@codeaction("refactor.extract", "Comment", commentEnd, comment2) +- newFunction(a) //@loc(commentEnd, "4"),codeaction("refactor.extract", "_", lastComment, comment3) +- // Comment right after 3 + 4 - -- if buf := env.BufferText("foo.go"); buf != c.after { -- t.Errorf("\nGOT:\n%s\nEXPECTED:\n%s", buf, c.after) -- } -- }) -- } -- }) +- // Comment after with space //@loc(lastComment, "Comment") -} -diff -urN a/gopls/internal/regtest/debug/debug_test.go b/gopls/internal/regtest/debug/debug_test.go ---- a/gopls/internal/regtest/debug/debug_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/debug/debug_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,30 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package debug +-func newFunction(a int) { +- _ = a + 4 +-} - --import ( -- "testing" +--- redefine.go -- +-package extract - -- "golang.org/x/tools/gopls/internal/hooks" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/bug" --) +-import "strconv" - --func TestMain(m *testing.M) { -- Main(m, hooks.Options) +-func _() { +- i, err := strconv.Atoi("1") +- u, err := strconv.Atoi("2") //@codeaction("refactor.extract", "u", ")", redefine) +- if i == u || err == nil { +- return +- } -} - --func TestBugNotification(t *testing.T) { -- // Verify that a properly configured session gets notified of a bug on the -- // server. -- WithOptions( -- Modes(Default), // must be in-process to receive the bug report below -- Settings{"showBugReports": true}, -- ).Run(t, "", func(t *testing.T, env *Env) { -- const desc = "got a bug" -- bug.Report(desc, nil) -- env.Await(ShownMessage(desc)) -- }) +--- @redefine/redefine.go -- +-package extract +- +-import "strconv" +- +-func _() { +- i, err := strconv.Atoi("1") +- u, err := newFunction() //@codeaction("refactor.extract", "u", ")", redefine) +- if i == u || err == nil { +- return +- } -} -diff -urN a/gopls/internal/regtest/diagnostics/analysis_test.go b/gopls/internal/regtest/diagnostics/analysis_test.go ---- a/gopls/internal/regtest/diagnostics/analysis_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/analysis_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,49 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package diagnostics +-func newFunction() (int, error) { +- u, err := strconv.Atoi("2") +- return u, err +-} - --import ( -- "testing" +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/imports.txt b/gopls/internal/regtest/marker/testdata/codeaction/imports.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/imports.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/imports.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,175 +0,0 @@ +-This test verifies the behavior of the 'source.organizeImports' code action. - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" +--- go.mod -- +-module mod.test/imports +- +-go 1.18 +- +--- add.go -- +-package imports //@codeaction("source.organizeImports", "imports", "", add) +- +-import ( +- "fmt" -) - --// Test for the timeformat analyzer, following golang/vscode-go#2406. --// --// This test checks that applying the suggested fix from the analyzer resolves --// the diagnostic warning. --func TestTimeFormatAnalyzer(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +-func _() { +- fmt.Println("") +- bytes.NewBuffer(nil) //@diag("bytes", re"(undeclared|undefined)") +-} - --go 1.18 ---- main.go -- --package main +--- @add/add.go -- +-package imports //@codeaction("source.organizeImports", "imports", "", add) - -import ( +- "bytes" - "fmt" -- "time" -) - --func main() { -- now := time.Now() -- fmt.Println(now.Format("2006-02-01")) --}` +-func _() { +- fmt.Println("") +- bytes.NewBuffer(nil) //@diag("bytes", re"(undeclared|undefined)") +-} - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") +--- good.go -- +-package imports //@codeactionerr("source.organizeImports", "imports", "", re"found 0 CodeActions") - -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "2006-02-01")), -- ReadDiagnostics("main.go", &d), -- ) +-import "fmt" - -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- }) +-func _() { +-fmt.Println("") -} -diff -urN a/gopls/internal/regtest/diagnostics/builtin_test.go b/gopls/internal/regtest/diagnostics/builtin_test.go ---- a/gopls/internal/regtest/diagnostics/builtin_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/builtin_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,35 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package diagnostics +--- issue35458.go -- - --import ( -- "strings" -- "testing" - -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) - --func TestIssue44866(t *testing.T) { -- src := ` ---- go.mod -- --module mod.com - --go 1.12 ---- a.go -- --package a - --const ( -- c = iota --) --` -- Run(t, src, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- loc := env.GoToDefinition(env.RegexpSearch("a.go", "iota")) -- if !strings.HasSuffix(string(loc.URI), "builtin.go") { -- t.Fatalf("jumped to %q, want builtin.go", loc.URI) -- } -- env.AfterChange(NoDiagnostics(ForFile("builtin.go"))) -- }) --} -diff -urN a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/internal/regtest/diagnostics/diagnostics_test.go ---- a/gopls/internal/regtest/diagnostics/diagnostics_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/diagnostics_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,2048 +0,0 @@ --// Copyright 2020 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-// package doc +-package imports //@codeaction("source.organizeImports", "imports", "", issue35458) - --package diagnostics - --import ( -- "context" -- "fmt" -- "os/exec" -- "testing" - -- "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/bug" -- "golang.org/x/tools/internal/testenv" --) - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- Main(m, hooks.Options) +- +- +-func _() { +- println("Hello, world!") -} - --// Use mod.com for all go.mod files due to golang/go#35230. --const exampleProgram = ` ---- go.mod -- --module mod.com - --go 1.12 ---- main.go -- --package main - --import "fmt" - --func main() { -- fmt.Println("Hello World.") --}` - --func TestDiagnosticErrorInEditedFile(t *testing.T) { -- // This test is very basic: start with a clean Go program, make an error, and -- // get a diagnostic for that error. However, it also demonstrates how to -- // combine Expectations to await more complex state in the editor. -- Run(t, exampleProgram, func(t *testing.T, env *Env) { -- // Deleting the 'n' at the end of Println should generate a single error -- // diagnostic. -- env.OpenFile("main.go") -- env.RegexpReplace("main.go", "Printl(n)", "") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "Printl")), -- // Assert that this test has sent no error logs to the client. This is not -- // strictly necessary for testing this regression, but is included here -- // as an example of using the NoErrorLogs() expectation. Feel free to -- // delete. -- NoErrorLogs(), -- ) -- }) --} - --func TestMissingImportDiagsClearOnFirstFile(t *testing.T) { -- const onlyMod = ` ---- go.mod -- --module mod.com - --go 1.12 --` -- Run(t, onlyMod, func(t *testing.T, env *Env) { -- env.CreateBuffer("main.go", `package main - --func m() { -- log.Println() --} --`) -- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "log"))) -- env.SaveBuffer("main.go") -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- }) --} +--- @issue35458/issue35458.go -- +-// package doc +-package imports //@codeaction("source.organizeImports", "imports", "", issue35458) - --func TestDiagnosticErrorInNewFile(t *testing.T) { -- const brokenFile = `package main - --const Foo = "abc --` -- Run(t, brokenFile, func(t *testing.T, env *Env) { -- env.CreateBuffer("broken.go", brokenFile) -- env.AfterChange(Diagnostics(env.AtRegexp("broken.go", "\"abc"))) -- }) +- +- +- +- +-func _() { +- println("Hello, world!") -} - --// badPackage contains a duplicate definition of the 'a' const. --const badPackage = ` ---- go.mod -- --module mod.com - --go 1.12 ---- a.go -- --package consts - --const a = 1 ---- b.go -- --package consts - --const a = 2 --` - --func TestDiagnosticClearingOnEdit(t *testing.T) { -- Run(t, badPackage, func(t *testing.T, env *Env) { -- env.OpenFile("b.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- ) - -- // Fix the error by editing the const name in b.go to `b`. -- env.RegexpReplace("b.go", "(a) = 2", "b") -- env.AfterChange( -- NoDiagnostics(ForFile("a.go")), -- NoDiagnostics(ForFile("b.go")), -- ) -- }) +- +- +--- multi.go -- +-package imports //@codeaction("source.organizeImports", "imports", "", multi) +- +-import "fmt" +- +-import "bytes" //@diag("\"bytes\"", re"not used") +- +-func _() { +- fmt.Println("") -} - --func TestDiagnosticClearingOnDelete_Issue37049(t *testing.T) { -- Run(t, badPackage, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- ) -- env.RemoveWorkspaceFile("b.go") +--- @multi/multi.go -- +-package imports //@codeaction("source.organizeImports", "imports", "", multi) - -- env.AfterChange( -- NoDiagnostics(ForFile("a.go")), -- NoDiagnostics(ForFile("b.go")), -- ) -- }) +-import "fmt" +- +-//@diag("\"bytes\"", re"not used") +- +-func _() { +- fmt.Println("") -} - --func TestDiagnosticClearingOnClose(t *testing.T) { -- Run(t, badPackage, func(t *testing.T, env *Env) { -- env.CreateBuffer("c.go", `package consts +--- needs.go -- +-package imports //@codeaction("source.organizeImports", "package", "", needs) - --const a = 3`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- Diagnostics(env.AtRegexp("c.go", "a = 3")), -- ) -- env.CloseBuffer("c.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a.go", "a = 1")), -- Diagnostics(env.AtRegexp("b.go", "a = 2")), -- NoDiagnostics(ForFile("c.go")), -- ) -- }) +-func goodbye() { +- fmt.Printf("HI") //@diag("fmt", re"(undeclared|undefined)") +- log.Printf("byeeeee") //@diag("log", re"(undeclared|undefined)") -} - --// Tests golang/go#37978. --func TestIssue37978(t *testing.T) { -- Run(t, exampleProgram, func(t *testing.T, env *Env) { -- // Create a new workspace-level directory and empty file. -- env.CreateBuffer("c/c.go", "") +--- @needs/needs.go -- +-package imports //@codeaction("source.organizeImports", "package", "", needs) - -- // Write the file contents with a missing import. -- env.EditBuffer("c/c.go", protocol.TextEdit{ -- NewText: `package c +-import ( +- "fmt" +- "log" +-) - --const a = http.MethodGet --`, -- }) -- env.AfterChange( -- Diagnostics(env.AtRegexp("c/c.go", "http.MethodGet")), -- ) -- // Save file, which will organize imports, adding the expected import. -- // Expect the diagnostics to clear. -- env.SaveBuffer("c/c.go") -- env.AfterChange( -- NoDiagnostics(ForFile("c/c.go")), -- ) -- }) +-func goodbye() { +- fmt.Printf("HI") //@diag("fmt", re"(undeclared|undefined)") +- log.Printf("byeeeee") //@diag("log", re"(undeclared|undefined)") -} - --// Tests golang/go#38878: good a.go, bad a_test.go, remove a_test.go but its errors remain --// If the file is open in the editor, this is working as intended --// If the file is not open in the editor, the errors go away --const test38878 = ` ---- go.mod -- --module foo -- --go 1.12 ---- a.go -- --package x +--- remove.go -- +-package imports //@codeaction("source.organizeImports", "package", "", remove) - --// import "fmt" +-import ( +- "bytes" //@diag("\"bytes\"", re"not used") +- "fmt" +-) - --func f() {} +-func _() { +- fmt.Println("") +-} - ---- a_test.go -- --package x +--- @remove/remove.go -- +-package imports //@codeaction("source.organizeImports", "package", "", remove) - --import "testing" +-import ( +- "fmt" +-) - --func TestA(t *testing.T) { -- f(3) +-func _() { +- fmt.Println("") -} --` - --// Tests golang/go#38878: deleting a test file should clear its errors, and --// not break the workspace. --func TestDeleteTestVariant(t *testing.T) { -- Run(t, test38878, func(t *testing.T, env *Env) { -- env.AfterChange(Diagnostics(env.AtRegexp("a_test.go", `f\((3)\)`))) -- env.RemoveWorkspaceFile("a_test.go") -- env.AfterChange(NoDiagnostics(ForFile("a_test.go"))) +--- removeall.go -- +-package imports //@codeaction("source.organizeImports", "package", "", removeall) - -- // Make sure the test variant has been removed from the workspace by -- // triggering a metadata load. -- env.OpenFile("a.go") -- env.RegexpReplace("a.go", `// import`, "import") -- env.AfterChange(Diagnostics(env.AtRegexp("a.go", `"fmt"`))) -- }) +-import ( +- "bytes" //@diag("\"bytes\"", re"not used") +- "fmt" //@diag("\"fmt\"", re"not used") +- +-) +- +-func _() { -} - --// Tests golang/go#38878: deleting a test file on disk while it's still open --// should not clear its errors. --func TestDeleteTestVariant_DiskOnly(t *testing.T) { -- Run(t, test38878, func(t *testing.T, env *Env) { -- env.OpenFile("a_test.go") -- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) -- env.Sandbox.Workdir.RemoveFile(context.Background(), "a_test.go") -- env.AfterChange(Diagnostics(AtPosition("a_test.go", 5, 3))) -- }) +--- @removeall/removeall.go -- +-package imports //@codeaction("source.organizeImports", "package", "", removeall) +- +-//@diag("\"fmt\"", re"not used") +- +-func _() { -} - --// TestNoMod confirms that gopls continues to work when a user adds a go.mod --// file to their workspace. --func TestNoMod(t *testing.T) { -- const noMod = ` ---- main.go -- --package main +--- twolines.go -- +-package imports +-func main() {} //@codeactionerr("source.organizeImports", "main", "", re"found 0") +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt b/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/infertypeargs.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-This test verifies the infertypeargs refactoring. - --import "mod.com/bob" +--- flags -- +--min_go=go1.18 - --func main() { -- bob.Hello() +--- go.mod -- +-module mod.test/infertypeargs +- +-go 1.18 +- +--- p.go -- +-package infertypeargs +- +-func app[S interface{ ~[]E }, E interface{}](s S, e E) S { +- return append(s, e) -} ---- bob/bob.go -- --package bob - --func Hello() { -- var x int +-func _() { +- _ = app[[]int] +- _ = app[[]int, int] +- _ = app[[]int]([]int{}, 0) //@codeaction("refactor.rewrite", "app", ")", infer) +- _ = app([]int{}, 0) -} --` - -- t.Run("manual", func(t *testing.T) { -- Run(t, noMod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), -- ) -- env.CreateBuffer("go.mod", `module mod.com +--- @infer/p.go -- +-package infertypeargs - -- go 1.12 --`) -- env.SaveBuffer("go.mod") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("bob/bob.go", "x")), -- ReadDiagnostics("bob/bob.go", &d), -- ) -- if len(d.Diagnostics) != 1 { -- t.Fatalf("expected 1 diagnostic, got %v", len(d.Diagnostics)) -- } -- }) -- }) -- t.Run("initialized", func(t *testing.T) { -- Run(t, noMod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), -- ) -- env.RunGoCommand("mod", "init", "mod.com") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("bob/bob.go", "x")), -- ) -- }) -- }) +-func app[S interface{ ~[]E }, E interface{}](s S, e E) S { +- return append(s, e) +-} - -- t.Run("without workspace module", func(t *testing.T) { -- WithOptions( -- Modes(Default), -- ).Run(t, noMod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"mod.com/bob"`)), -- ) -- if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}, true); err != nil { -- t.Fatal(err) -- } -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("bob/bob.go", "x")), -- ) -- }) -- }) +-func _() { +- _ = app[[]int] +- _ = app[[]int, int] +- _ = app([]int{}, 0) //@codeaction("refactor.rewrite", "app", ")", infer) +- _ = app([]int{}, 0) -} - --// Tests golang/go#38267. --func TestIssue38267(t *testing.T) { -- const testPackage = ` +diff -urN a/gopls/internal/regtest/marker/testdata/codeaction/inline.txt b/gopls/internal/regtest/marker/testdata/codeaction/inline.txt +--- a/gopls/internal/regtest/marker/testdata/codeaction/inline.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/codeaction/inline.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,23 +0,0 @@ +-This is a minimal test of the refactor.inline code action. +- --- go.mod -- --module mod.com +-module testdata/codeaction +-go 1.18 - --go 1.12 ---- lib.go -- --package lib +--- a/a.go -- +-package a - --func Hello(x string) { -- _ = x +-func _() { +- println(add(1, 2)) //@codeaction("refactor.inline", "add", ")", inline) -} ---- lib_test.go -- --package lib - --import "testing" +-func add(x, y int) int { return x + y } - --type testStruct struct{ -- name string --} +--- @inline/a/a.go -- +-package a - --func TestHello(t *testing.T) { -- testStructs := []*testStruct{ -- &testStruct{"hello"}, -- &testStruct{"goodbye"}, -- } -- for y := range testStructs { -- _ = y -- } +-func _() { +- println(func(x, y int) int { return x + y }(1, 2)) //@codeaction("refactor.inline", "add", ")", inline) -} --` - -- Run(t, testPackage, func(t *testing.T, env *Env) { -- env.OpenFile("lib_test.go") -- env.AfterChange( -- Diagnostics(AtPosition("lib_test.go", 10, 2)), -- Diagnostics(AtPosition("lib_test.go", 11, 2)), -- ) -- env.OpenFile("lib.go") -- env.RegexpReplace("lib.go", "_ = x", "var y int") -- env.AfterChange( -- Diagnostics(env.AtRegexp("lib.go", "y int")), -- NoDiagnostics(ForFile("lib_test.go")), -- ) -- }) --} +-func add(x, y int) int { return x + y } +diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue59096.txt b/gopls/internal/regtest/marker/testdata/completion/issue59096.txt +--- a/gopls/internal/regtest/marker/testdata/completion/issue59096.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue59096.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-This test exercises the panic in golang/go#59096: completing at a syntactic +-type-assert expression was panicking because gopls was translating it into +-a (malformed) selector expr. - --// Tests golang/go#38328. --func TestPackageChange_Issue38328(t *testing.T) { -- const packageChange = ` --- go.mod -- --module fake +-module example.com - --go 1.12 ---- a.go -- --package foo --func main() {} --` -- Run(t, packageChange, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- env.RegexpReplace("a.go", "foo", "foox") -- env.AfterChange( -- NoDiagnostics(ForFile("a.go")), -- ) -- }) +--- a/a.go -- +-package a +- +-func _() { +- b.(foo) //@complete(re"b.()", "B"), diag("b", re"(undefined|undeclared name): b") -} - --const testPackageWithRequire = ` ---- go.mod -- --module mod.com +--- b/b.go -- +-package b - --go 1.12 +-const B = 0 +diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue60545.txt b/gopls/internal/regtest/marker/testdata/completion/issue60545.txt +--- a/gopls/internal/regtest/marker/testdata/completion/issue60545.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue60545.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-This test checks that unimported completion is case-insensitive. - --require foo.test v1.2.3 ---- go.sum -- --foo.test v1.2.3 h1:TMA+lyd1ck0TqjSFpNe4T6cf/K6TYkoHwOOcMBMjaEw= --foo.test v1.2.3/go.mod h1:Ij3kyLIe5lzjycjh13NL8I2gX0quZuTdW0MnmlwGBL4= ---- print.go -- --package lib +--- go.mod -- +-module mod.test - --import ( -- "fmt" +-go 1.18 - -- "foo.test/bar" --) +--- main.go -- +-package main - --func PrintAnswer() { -- fmt.Printf("answer: %s", bar.Answer) +-func main() { +- fmt.p //@complete(re"p()","Print", "Printf", "Println"), diag("fmt", re"(undefined|undeclared)") -} --` -- --const testPackageWithRequireProxy = ` ---- foo.test@v1.2.3/go.mod -- --module foo.test - --go 1.12 ---- foo.test@v1.2.3/bar/const.go -- --package bar +--- other.go -- +-package main - --const Answer = 42 --` +-// Including another package that imports "fmt" causes completion to use the +-// existing metadata, which is the codepath leading to golang/go#60545. +-import "fmt" - --func TestResolveDiagnosticWithDownload(t *testing.T) { -- WithOptions( -- ProxyFiles(testPackageWithRequireProxy), -- ).Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { -- env.OpenFile("print.go") -- // Check that gopackages correctly loaded this dependency. We should get a -- // diagnostic for the wrong formatting type. -- env.AfterChange( -- Diagnostics( -- env.AtRegexp("print.go", "fmt.Printf"), -- WithMessage("wrong type int"), -- ), -- ) -- }) +-func _() { +- fmt.Println() -} +diff -urN a/gopls/internal/regtest/marker/testdata/completion/issue62141.txt b/gopls/internal/regtest/marker/testdata/completion/issue62141.txt +--- a/gopls/internal/regtest/marker/testdata/completion/issue62141.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/completion/issue62141.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,39 +0,0 @@ +-This test checks that we don't suggest completion to an untyped conversion such +-as "untyped float(abcdef)". +- +--- main.go -- +-package main +- +-func main() { +- abcdef := 32 //@diag("abcdef", re"not used") +- x := 1.0 / abcd //@acceptcompletion(re"abcd()", "abcdef", int), diag("x", re"not used"), diag("abcd", re"(undefined|undeclared)") - --func TestMissingDependency(t *testing.T) { -- Run(t, testPackageWithRequire, func(t *testing.T, env *Env) { -- env.OpenFile("print.go") -- env.Await(LogMatching(protocol.Error, "initial workspace load failed", 1, false)) -- }) +- // Verify that we don't suggest converting compatible untyped constants. +- const untypedConst = 42 +- y := 1.1 / untypedC //@acceptcompletion(re"untypedC()", "untypedConst", untyped), diag("y", re"not used"), diag("untypedC", re"(undefined|undeclared)") -} - --// Tests golang/go#36951. --func TestAdHocPackages_Issue36951(t *testing.T) { -- const adHoc = ` ---- b/b.go -- --package b +--- @int/main.go -- +-package main - --func Hello() { -- var x int --} --` -- Run(t, adHoc, func(t *testing.T, env *Env) { -- env.OpenFile("b/b.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("b/b.go", "x")), -- ) -- }) +-func main() { +- abcdef := 32 //@diag("abcdef", re"not used") +- x := 1.0 / float64(abcdef) //@acceptcompletion(re"abcd()", "abcdef", int), diag("x", re"not used"), diag("abcd", re"(undefined|undeclared)") +- +- // Verify that we don't suggest converting compatible untyped constants. +- const untypedConst = 42 +- y := 1.1 / untypedC //@acceptcompletion(re"untypedC()", "untypedConst", untyped), diag("y", re"not used"), diag("untypedC", re"(undefined|undeclared)") -} - --// Tests golang/go#37984: GOPATH should be read from the go command. --func TestNoGOPATH_Issue37984(t *testing.T) { -- const files = ` ---- main.go -- +--- @untyped/main.go -- -package main - --func _() { -- fmt.Println("Hello World") --} --` -- WithOptions( -- EnvVars{ -- "GOPATH": "", -- "GO111MODULE": "off", -- }, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.AfterChange(Diagnostics(env.AtRegexp("main.go", "fmt"))) -- env.SaveBuffer("main.go") -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- }) +-func main() { +- abcdef := 32 //@diag("abcdef", re"not used") +- x := 1.0 / abcd //@acceptcompletion(re"abcd()", "abcdef", int), diag("x", re"not used"), diag("abcd", re"(undefined|undeclared)") +- +- // Verify that we don't suggest converting compatible untyped constants. +- const untypedConst = 42 +- y := 1.1 / untypedConst //@acceptcompletion(re"untypedC()", "untypedConst", untyped), diag("y", re"not used"), diag("untypedC", re"(undefined|undeclared)") -} - --// Tests golang/go#38669. --func TestEqualInEnv_Issue38669(t *testing.T) { -- const files = ` +diff -urN a/gopls/internal/regtest/marker/testdata/definition/embed.txt b/gopls/internal/regtest/marker/testdata/definition/embed.txt +--- a/gopls/internal/regtest/marker/testdata/definition/embed.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/definition/embed.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,254 +0,0 @@ +-This test checks definition and hover operations over embedded fields and methods. +- --- go.mod -- -module mod.com - --go 1.12 ---- main.go -- --package main +-go 1.18 - --var _ = x.X ---- x/x.go -- --package x +--- a/a.go -- +-package a - --var X = 0 --` -- WithOptions( -- EnvVars{"GOFLAGS": "-tags=foo"}, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.OrganizeImports("main.go") -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- }) +-type A string //@loc(AString, "A") +- +-func (_ A) Hi() {} //@loc(AHi, "Hi") +- +-type S struct { +- Field int //@loc(SField, "Field") +- R // embed a struct +- H // embed an interface -} - --// Tests golang/go#38467. --func TestNoSuggestedFixesForGeneratedFiles_Issue38467(t *testing.T) { -- const generated = ` ---- go.mod -- --module mod.com +-type R struct { +- Field2 int //@loc(RField2, "Field2") +-} - --go 1.12 ---- main.go -- --package main +-func (_ R) Hey() {} //@loc(RHey, "Hey") - --// Code generated by generator.go. DO NOT EDIT. +-type H interface { //@loc(H, "H") +- Goodbye() //@loc(HGoodbye, "Goodbye") +-} - --func _() { -- for i, _ := range []string{} { -- _ = i -- } +-type I interface { //@loc(I, "I") +- B() //@loc(IB, "B") +- J -} --` -- Run(t, generated, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(AtPosition("main.go", 5, 8)), -- ReadDiagnostics("main.go", &d), -- ) -- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { -- t.Errorf("got quick fixes %v, wanted none", fixes) -- } -- }) +- +-type J interface { //@loc(J, "J") +- Hello() //@loc(JHello, "Hello") -} - --// Expect a module/GOPATH error if there is an error in the file at startup. --// Tests golang/go#37279. --func TestBrokenWorkspace_OutsideModule(t *testing.T) { -- const noModule = ` ---- a.go -- --package foo +--- b/b.go -- +-package b - --import "mod.com/hello" +-import "mod.com/a" //@loc(AImport, re"\".*\"") - --func f() { -- hello.Goodbye() +-type embed struct { +- F int //@loc(F, "F") -} --` -- Run(t, noModule, func(t *testing.T, env *Env) { -- env.OpenFile("a.go") -- env.AfterChange( -- // Expect the adHocPackagesWarning. -- OutstandingWork(lsp.WorkspaceLoadFailure, "outside of a module"), -- ) -- // Deleting the import dismisses the warning. -- env.RegexpReplace("a.go", `import "mod.com/hello"`, "") -- env.AfterChange( -- NoOutstandingWork(), -- ) -- }) +- +-func (embed) M() //@loc(M, "M") +- +-type Embed struct { +- embed +- *a.A +- a.I +- a.S -} - --func TestNonGoFolder(t *testing.T) { -- const files = ` ---- hello.txt -- --hi mom --` -- for _, go111module := range []string{"on", "off", ""} { -- t.Run(fmt.Sprintf("GO111MODULE_%v", go111module), func(t *testing.T) { -- WithOptions( -- EnvVars{"GO111MODULE": go111module}, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- NoOutstandingWork(), -- ) -- }) -- }) -- } +-func _() { +- e := Embed{} +- e.Hi() //@def("Hi", AHi),hover("Hi", "Hi", AHi) +- e.B() //@def("B", IB),hover("B", "B", IB) +- _ = e.Field //@def("Field", SField),hover("Field", "Field", SField) +- _ = e.Field2 //@def("Field2", RField2),hover("Field2", "Field2", RField2) +- e.Hello() //@def("Hello", JHello),hover("Hello", "Hello",JHello) +- e.Hey() //@def("Hey", RHey),hover("Hey", "Hey", RHey) +- e.Goodbye() //@def("Goodbye", HGoodbye),hover("Goodbye", "Goodbye", HGoodbye) +- e.M() //@def("M", M),hover("M", "M", M) +- _ = e.F //@def("F", F),hover("F", "F", F) -} - --// Tests the repro case from golang/go#38602. Diagnostics are now handled properly, --// which blocks type checking. --func TestConflictingMainPackageErrors(t *testing.T) { -- const collision = ` ---- x/x.go -- --package x +-type aAlias = a.A //@loc(aAlias, "aAlias") - --import "x/hello" +-type S1 struct { //@loc(S1, "S1") +- F1 int //@loc(S1F1, "F1") +- S2 //@loc(S1S2, "S2"),def("S2", S2),hover("S2", "S2", S2) +- a.A //@def("A", AString),hover("A", "A", aA) +- aAlias //@def("a", aAlias),hover("a", "aAlias", aAlias) +-} - --func Hello() { -- hello.HiThere() +-type S2 struct { //@loc(S2, "S2") +- F1 string //@loc(S2F1, "F1") +- F2 int //@loc(S2F2, "F2") +- *a.A //@def("A", AString),def("a",AImport) -} ---- x/main.go -- --package main - --func main() { -- fmt.Println("") +-type S3 struct { +- F1 struct { +- a.A //@def("A", AString) +- } -} --` -- WithOptions( -- InGOPATH(), -- EnvVars{"GO111MODULE": "off"}, -- ).Run(t, collision, func(t *testing.T, env *Env) { -- env.OpenFile("x/x.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("x/x.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), -- Diagnostics(env.AtRegexp("x/main.go", `^`), WithMessage("found packages main (main.go) and x (x.go)")), -- ) - -- // We don't recover cleanly from the errors without good overlay support. -- if testenv.Go1Point() >= 16 { -- env.RegexpReplace("x/x.go", `package x`, `package main`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("x/main.go", `fmt`)), -- ) -- } -- }) +-func Bar() { +- var x S1 //@def("S1", S1),hover("S1", "S1", S1) +- _ = x.S2 //@def("S2", S1S2),hover("S2", "S2", S1S2) +- _ = x.F1 //@def("F1", S1F1),hover("F1", "F1", S1F1) +- _ = x.F2 //@def("F2", S2F2),hover("F2", "F2", S2F2) +- _ = x.S2.F1 //@def("F1", S2F1),hover("F1", "F1", S2F1) -} - --const ardanLabsProxy = ` ---- github.com/ardanlabs/conf@v1.2.3/go.mod -- --module github.com/ardanlabs/conf +--- b/c.go -- +-package b - --go 1.12 ---- github.com/ardanlabs/conf@v1.2.3/conf.go -- --package conf +-var _ = S1{ //@def("S1", S1),hover("S1", "S1", S1) +- F1: 99, //@def("F1", S1F1),hover("F1", "F1", S1F1) +-} - --var ErrHelpWanted error --` +--- @AHi/hover.md -- +-```go +-func (a.A).Hi() +-``` - --// Test for golang/go#38211. --func Test_Issue38211(t *testing.T) { -- const ardanLabs = ` ---- go.mod -- --module mod.com +-[`(a.A).Hi` on pkg.go.dev](https://pkg.go.dev/mod.com/a#A.Hi) +--- @F/hover.md -- +-```go +-field F int +-``` - --go 1.14 ---- main.go -- --package main +-@loc(F, "F") - --import "github.com/ardanlabs/conf" - --func main() { -- _ = conf.ErrHelpWanted --} --` -- WithOptions( -- ProxyFiles(ardanLabsProxy), -- ).Run(t, ardanLabs, func(t *testing.T, env *Env) { -- // Expect a diagnostic with a suggested fix to add -- // "github.com/ardanlabs/conf" to the go.mod file. -- env.OpenFile("go.mod") -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), -- ReadDiagnostics("main.go", &d), -- ) -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.SaveBuffer("go.mod") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- // Comment out the line that depends on conf and expect a -- // diagnostic and a fix to remove the import. -- env.RegexpReplace("main.go", "_ = conf.ErrHelpWanted", "//_ = conf.ErrHelpWanted") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), -- ) -- env.SaveBuffer("main.go") -- // Expect a diagnostic and fix to remove the dependency in the go.mod. -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- Diagnostics(env.AtRegexp("go.mod", "require github.com/ardanlabs/conf"), WithMessage("not used in this module")), -- ReadDiagnostics("go.mod", &d), -- ) -- env.ApplyQuickFixes("go.mod", d.Diagnostics) -- env.SaveBuffer("go.mod") -- env.AfterChange( -- NoDiagnostics(ForFile("go.mod")), -- ) -- // Uncomment the lines and expect a new diagnostic for the import. -- env.RegexpReplace("main.go", "//_ = conf.ErrHelpWanted", "_ = conf.ErrHelpWanted") -- env.SaveBuffer("main.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`)), -- ) -- }) --} +-[`(b.Embed).F` on pkg.go.dev](https://pkg.go.dev/mod.com/b#Embed.F) +--- @HGoodbye/hover.md -- +-```go +-func (a.H).Goodbye() +-``` - --// Test for golang/go#38207. --func TestNewModule_Issue38207(t *testing.T) { -- const emptyFile = ` ---- go.mod -- --module mod.com +-@loc(HGoodbye, "Goodbye") - --go 1.12 ---- main.go -- --` -- WithOptions( -- ProxyFiles(ardanLabsProxy), -- ).Run(t, emptyFile, func(t *testing.T, env *Env) { -- env.CreateBuffer("main.go", `package main - --import "github.com/ardanlabs/conf" +-[`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/mod.com/a#H.Goodbye) +--- @IB/hover.md -- +-```go +-func (a.I).B() +-``` - --func main() { -- _ = conf.ErrHelpWanted --} --`) -- env.SaveBuffer("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `"github.com/ardanlabs/conf"`), WithMessage("no required module")), -- ReadDiagnostics("main.go", &d), -- ) -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) --} +-@loc(IB, "B") - --// Test for golang/go#36960. --func TestNewFileBadImports_Issue36960(t *testing.T) { -- const simplePackage = ` ---- go.mod -- --module mod.com - --go 1.14 ---- a/a1.go -- --package a +-[`(a.I).B` on pkg.go.dev](https://pkg.go.dev/mod.com/a#I.B) +--- @JHello/hover.md -- +-```go +-func (a.J).Hello() +-``` - --import "fmt" +-@loc(JHello, "Hello") - --func _() { -- fmt.Println("hi") --} --` -- Run(t, simplePackage, func(t *testing.T, env *Env) { -- env.OpenFile("a/a1.go") -- env.CreateBuffer("a/a2.go", ``) -- env.SaveBufferWithoutActions("a/a2.go") -- env.AfterChange( -- NoDiagnostics(ForFile("a/a1.go")), -- ) -- env.EditBuffer("a/a2.go", fake.NewEdit(0, 0, 0, 0, `package a`)) -- env.AfterChange( -- NoDiagnostics(ForFile("a/a1.go")), -- ) -- }) --} - --// This test tries to replicate the workflow of a user creating a new x test. --// It also tests golang/go#39315. --func TestManuallyCreatingXTest(t *testing.T) { -- // Create a package that already has a test variant (in-package test). -- const testVariant = ` ---- go.mod -- --module mod.com +-[`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/mod.com/a#J.Hello) +--- @M/hover.md -- +-```go +-func (embed).M() +-``` - --go 1.15 ---- hello/hello.go -- --package hello +-[`(b.Embed).M` on pkg.go.dev](https://pkg.go.dev/mod.com/b#Embed.M) +--- @RField2/hover.md -- +-```go +-field Field2 int +-``` - --func Hello() { -- var x int --} ---- hello/hello_test.go -- --package hello +-@loc(RField2, "Field2") - --import "testing" - --func TestHello(t *testing.T) { -- var x int -- Hello() +-[`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/mod.com/a#R.Field2) +--- @RHey/hover.md -- +-```go +-func (a.R).Hey() +-``` +- +-[`(a.R).Hey` on pkg.go.dev](https://pkg.go.dev/mod.com/a#R.Hey) +--- @S1/hover.md -- +-```go +-type S1 struct { +- F1 int //@loc(S1F1, "F1") +- S2 //@loc(S1S2, "S2"),def("S2", S2),hover("S2", "S2", S2) +- a.A //@def("A", AString),hover("A", "A", aA) +- aAlias //@def("a", aAlias),hover("a", "aAlias", aAlias) -} --` -- Run(t, testVariant, func(t *testing.T, env *Env) { -- // Open the file, triggering the workspace load. -- // There are errors in the code to ensure all is working as expected. -- env.OpenFile("hello/hello.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("hello/hello.go", "x")), -- Diagnostics(env.AtRegexp("hello/hello_test.go", "x")), -- ) +-``` - -- // Create an empty file with the intention of making it an x test. -- // This resembles a typical flow in an editor like VS Code, in which -- // a user would create an empty file and add content, saving -- // intermittently. -- // TODO(rstambler): There might be more edge cases here, as file -- // content can be added incrementally. -- env.CreateBuffer("hello/hello_x_test.go", ``) +-[`b.S1` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S1) +--- @S1F1/hover.md -- +-```go +-field F1 int +-``` - -- // Save the empty file (no actions since formatting will fail). -- env.SaveBufferWithoutActions("hello/hello_x_test.go") +-@loc(S1F1, "F1") - -- // Add the content. The missing import is for the package under test. -- env.EditBuffer("hello/hello_x_test.go", fake.NewEdit(0, 0, 0, 0, `package hello_test - --import ( -- "testing" --) +-[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S1.F1) +--- @S1S2/hover.md -- +-```go +-field S2 S2 +-``` - --func TestHello(t *testing.T) { -- hello.Hello() --} --`)) -- // Expect a diagnostic for the missing import. Save, which should -- // trigger import organization. The diagnostic should clear. -- env.AfterChange( -- Diagnostics(env.AtRegexp("hello/hello_x_test.go", "hello.Hello")), -- ) -- env.SaveBuffer("hello/hello_x_test.go") -- env.AfterChange( -- NoDiagnostics(ForFile("hello/hello_x_test.go")), -- ) -- }) +-@loc(S1S2, "S2"),def("S2", S2),hover("S2", "S2", S2) +- +- +-[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S1.S2) +--- @S2/hover.md -- +-```go +-type S2 struct { +- F1 string //@loc(S2F1, "F1") +- F2 int //@loc(S2F2, "F2") +- *a.A //@def("A", AString),def("a",AImport) -} +-``` +- +-[`b.S2` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S2) +--- @S2F1/hover.md -- +-```go +-field F1 string +-``` +- +-@loc(S2F1, "F1") +- +- +-[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S2.F1) +--- @S2F2/hover.md -- +-```go +-field F2 int +-``` +- +-@loc(S2F2, "F2") +- +- +-[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S2.F2) +--- @SField/hover.md -- +-```go +-field Field int +-``` - --// Reproduce golang/go#40690. --func TestCreateOnlyXTest(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +-@loc(SField, "Field") - --go 1.12 ---- foo/foo.go -- --package foo ---- foo/bar_test.go -- --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("foo/bar_test.go") -- env.EditBuffer("foo/bar_test.go", fake.NewEdit(0, 0, 0, 0, "package foo")) -- env.Await(env.DoneWithChange()) -- env.RegexpReplace("foo/bar_test.go", "package foo", `package foo_test - --import "testing" +-[`(a.S).Field` on pkg.go.dev](https://pkg.go.dev/mod.com/a#S.Field) +--- @aA/hover.md -- +-```go +-type A string - --func TestX(t *testing.T) { -- var x int --} --`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("foo/bar_test.go", "x")), -- ) -- }) --} +-func (a.A).Hi() +-``` - --func TestChangePackageName(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +-@loc(AString, "A") - --go 1.12 ---- foo/foo.go -- --package foo ---- foo/bar_test.go -- --package foo_ --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("foo/bar_test.go") -- env.AfterChange() -- env.RegexpReplace("foo/bar_test.go", "package foo_", "package foo_test") -- env.AfterChange( -- NoDiagnostics(ForFile("foo/bar_test.go")), -- NoDiagnostics(ForFile("foo/foo.go")), -- ) -- }) --} - --func TestIgnoredFiles(t *testing.T) { -- const ws = ` +-[`a.A` on pkg.go.dev](https://pkg.go.dev/mod.com/a#A) +--- @aAlias/hover.md -- +-```go +-type aAlias = a.A +- +-func (a.A).Hi() +-``` +- +-@loc(aAlias, "aAlias") +diff -urN a/gopls/internal/regtest/marker/testdata/definition/import.txt b/gopls/internal/regtest/marker/testdata/definition/import.txt +--- a/gopls/internal/regtest/marker/testdata/definition/import.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/definition/import.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,52 +0,0 @@ +-This test checks definition and hover over imports. --- go.mod -- -module mod.com - --go 1.12 ---- _foo/x.go -- --package x +-go 1.18 +--- foo/foo.go -- +-package foo - --var _ = foo.Bar --` -- Run(t, ws, func(t *testing.T, env *Env) { -- env.OpenFile("_foo/x.go") -- env.AfterChange( -- NoDiagnostics(ForFile("_foo/x.go")), -- ) -- }) --} +-type Foo struct{} - --// Partially reproduces golang/go#38977, moving a file between packages. --// It also gets hit by some go command bug fixed in 1.15, but we don't --// care about that so much here. --func TestDeletePackage(t *testing.T) { -- const ws = ` ---- go.mod -- --module mod.com +-// DoFoo does foo. +-func DoFoo() {} //@loc(DoFoo, "DoFoo") +--- bar/bar.go -- +-package bar - --go 1.15 ---- a/a.go -- --package a +-import ( +- myFoo "mod.com/foo" //@loc(myFoo, "myFoo") +-) - --const A = 1 +-var _ *myFoo.Foo //@def("myFoo", myFoo),hover("myFoo", "myFoo", myFoo) +--- bar/dotimport.go -- +-package bar - ---- b/b.go -- --package b +-import . "mod.com/foo" - --import "mod.com/a" +-func _() { +- // variable of type foo.Foo +- var _ Foo //@hover("_", "_", FooVar) - --const B = a.A +- DoFoo() //@hover("DoFoo", "DoFoo", DoFoo) +-} +--- @DoFoo/hover.md -- +-```go +-func DoFoo() +-``` - ---- c/c.go -- --package c +-DoFoo does foo. - --import "mod.com/a" - --const C = a.A --` -- Run(t, ws, func(t *testing.T, env *Env) { -- env.OpenFile("b/b.go") -- env.Await(env.DoneWithOpen()) -- // Delete c/c.go, the only file in package c. -- env.RemoveWorkspaceFile("c/c.go") +-[`foo.DoFoo` on pkg.go.dev](https://pkg.go.dev/mod.com/foo#DoFoo) +--- @FooVar/hover.md -- +-```go +-var _ Foo +-``` - -- // We should still get diagnostics for files that exist. -- env.RegexpReplace("b/b.go", `a.A`, "a.Nonexistant") -- env.AfterChange( -- Diagnostics(env.AtRegexp("b/b.go", `Nonexistant`)), -- ) -- }) --} +-variable of type foo.Foo +--- @myFoo/hover.md -- +-```go +-package myFoo ("mod.com/foo") +-``` - --// This is a copy of the scenario_default/quickfix_empty_files.txt test from --// govim. Reproduces golang/go#39646. --func TestQuickFixEmptyFiles(t *testing.T) { -- const mod = ` +-[`myFoo` on pkg.go.dev](https://pkg.go.dev/mod.com/foo) +diff -urN a/gopls/internal/regtest/marker/testdata/definition/misc.txt b/gopls/internal/regtest/marker/testdata/definition/misc.txt +--- a/gopls/internal/regtest/marker/testdata/definition/misc.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/definition/misc.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,230 +0,0 @@ +-This test exercises miscellaneous definition and hover requests. --- go.mod -- -module mod.com - --go 1.12 --` -- // To fully recreate the govim tests, we create files by inserting -- // a newline, adding to the file, and then deleting the newline. -- // Wait for each event to process to avoid cancellations and force -- // package loads. -- writeGoVim := func(env *Env, name, content string) { -- env.WriteWorkspaceFile(name, "") -- env.Await(env.DoneWithChangeWatchedFiles()) +-go 1.16 +--- a.go -- +-package a //@loc(aPackage, re"package (a)"),hover(aPackage, aPackage, aPackage) - -- env.CreateBuffer(name, "\n") -- env.Await(env.DoneWithOpen()) +-var ( +- // x is a variable. +- x string //@loc(x, "x"),hover(x, x, hoverx) +-) - -- env.EditBuffer(name, fake.NewEdit(1, 0, 1, 0, content)) -- env.Await(env.DoneWithChange()) +-// Constant block. When I hover on h, I should see this comment. +-const ( +- // When I hover on g, I should see this comment. +- g = 1 //@hover("g", "g", hoverg) - -- env.EditBuffer(name, fake.NewEdit(0, 0, 1, 0, "")) -- env.Await(env.DoneWithChange()) -- } +- h = 2 //@hover("h", "h", hoverh) +-) - -- const p = `package p; func DoIt(s string) {};` -- const main = `package main +-// z is a variable too. +-var z string //@loc(z, "z"),hover(z, z, hoverz) - --import "mod.com/p" +-func AStuff() { //@loc(AStuff, "AStuff") +- x := 5 +- Random2(x) //@def("dom2", Random2) +- Random() //@def("()", Random) +-} - --func main() { -- p.DoIt(5) +-type H interface { //@loc(H, "H") +- Goodbye() -} --` -- // A simple version of the test that reproduces most of the problems it -- // exposes. -- t.Run("short", func(t *testing.T) { -- Run(t, mod, func(t *testing.T, env *Env) { -- writeGoVim(env, "p/p.go", p) -- writeGoVim(env, "main.go", main) -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "5")), -- ) -- }) -- }) - -- // A full version that replicates the whole flow of the test. -- t.Run("full", func(t *testing.T) { -- Run(t, mod, func(t *testing.T, env *Env) { -- writeGoVim(env, "p/p.go", p) -- writeGoVim(env, "main.go", main) -- writeGoVim(env, "p/p_test.go", `package p +-type I interface { //@loc(I, "I") +- B() +- J +-} - --import "testing" +-type J interface { //@loc(J, "J") +- Hello() +-} - --func TestDoIt(t *testing.T) { -- DoIt(5) +-func _() { +- // 1st type declaration block +- type ( +- a struct { //@hover("a", "a", hoverDeclBlocka) +- x string +- } +- ) +- +- // 2nd type declaration block +- type ( +- // b has a comment +- b struct{} //@hover("b", "b", hoverDeclBlockb) +- ) +- +- // 3rd type declaration block +- type ( +- // c is a struct +- c struct { //@hover("c", "c", hoverDeclBlockc) +- f string +- } +- +- d string //@hover("d", "d", hoverDeclBlockd) +- ) +- +- type ( +- e struct { //@hover("e", "e", hoverDeclBlocke) +- f float64 +- } // e has a comment +- ) -} --`) -- writeGoVim(env, "p/x_test.go", `package p_test +- +-var ( +- hh H //@hover("H", "H", hoverH) +- ii I //@hover("I", "I", hoverI) +- jj J //@hover("J", "J", hoverJ) +-) +--- a_test.go -- +-package a - -import ( - "testing" -- -- "mod.com/p" -) - --func TestDoIt(t *testing.T) { -- p.DoIt(5) --} --`) -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "5")), -- Diagnostics(env.AtRegexp("p/p_test.go", "5")), -- Diagnostics(env.AtRegexp("p/x_test.go", "5")), -- ) -- env.RegexpReplace("p/p.go", "s string", "i int") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- NoDiagnostics(ForFile("p/p_test.go")), -- NoDiagnostics(ForFile("p/x_test.go")), -- ) -- }) -- }) +-func TestA(t *testing.T) { //@hover("TestA", "TestA", hoverTestA) -} -- --func TestSingleFile(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com -- --go 1.13 ---- a/a.go -- +--- random.go -- -package a - --func _() { -- var x int --} --` -- WithOptions( -- // Empty workspace folders. -- WorkspaceFolders(), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "x")), -- ) -- }) +-func Random() int { //@loc(Random, "Random") +- y := 6 + 7 +- return y -} - --// Reproduces the case described in --// https://github.com/golang/go/issues/39296#issuecomment-652058883. --func TestPkgm(t *testing.T) { -- const basic = ` ---- go.mod -- --module mod.com +-func Random2(y int) int { //@loc(Random2, "Random2"),loc(RandomParamY, "y") +- return y //@def("y", RandomParamY),hover("y", "y", hovery) +-} - --go 1.15 ---- foo/foo.go -- --package foo +-type Pos struct { +- x, y int //@loc(PosX, "x"),loc(PosY, "y") +-} - --import "fmt" +-// Typ has a comment. Its fields do not. +-type Typ struct{ field string } //@loc(TypField, "field") - --func Foo() { -- fmt.Println("") +-func _() { +- x := &Typ{} +- _ = x.field //@def("field", TypField),hover("field", "field", hoverfield) -} --` -- Run(t, basic, func(t *testing.T, env *Env) { -- env.WriteWorkspaceFile("foo/foo_test.go", `package main -- --func main() { - --}`) -- env.OpenFile("foo/foo_test.go") -- env.RegexpReplace("foo/foo_test.go", `package main`, `package foo`) -- env.AfterChange(NoDiagnostics(ForFile("foo/foo.go"))) -- }) +-func (p *Pos) Sum() int { //@loc(PosSum, "Sum") +- return p.x + p.y //@hover("x", "x", hoverpx) -} - --func TestClosingBuffer(t *testing.T) { -- const basic = ` ---- go.mod -- --module mod.com +-func _() { +- var p Pos +- _ = p.Sum() //@def("()", PosSum),hover("()", `Sum`, hoverSum) +-} +--- @aPackage/hover.md -- +--- @hoverDeclBlocka/hover.md -- +-```go +-type a struct { +- x string +-} +-``` - --go 1.14 ---- main.go -- --package main +-1st type declaration block +--- @hoverDeclBlockb/hover.md -- +-```go +-type b struct{} +-``` - --func main() {} --` -- Run(t, basic, func(t *testing.T, env *Env) { -- env.Editor.CreateBuffer(env.Ctx, "foo.go", `package main`) -- env.AfterChange() -- env.CloseBuffer("foo.go") -- env.AfterChange(NoLogMatching(protocol.Info, "packages=0")) -- }) +-b has a comment +--- @hoverDeclBlockc/hover.md -- +-```go +-type c struct { +- f string -} +-``` - --// Reproduces golang/go#38424. --func TestCutAndPaste(t *testing.T) { -- const basic = ` ---- go.mod -- --module mod.com -- --go 1.14 ---- main2.go -- --package main --` -- Run(t, basic, func(t *testing.T, env *Env) { -- env.CreateBuffer("main.go", "") -- env.Await(env.DoneWithOpen()) +-c is a struct +--- @hoverDeclBlockd/hover.md -- +-```go +-type d string +-``` - -- env.SaveBufferWithoutActions("main.go") -- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) +-3rd type declaration block +--- @hoverDeclBlocke/hover.md -- +-```go +-type e struct { +- f float64 +-} +-``` - -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main +-e has a comment +--- @hoverH/hover.md -- +-```go +-type H interface { +- Goodbye() +-} +-``` - --func main() { +-[`a.H` on pkg.go.dev](https://pkg.go.dev/mod.com#H) +--- @hoverI/hover.md -- +-```go +-type I interface { +- B() +- J -} --`)) -- env.Await(env.DoneWithChange()) +-``` - -- env.SaveBuffer("main.go") -- env.Await(env.DoneWithSave(), env.DoneWithChangeWatchedFiles()) +-[`a.I` on pkg.go.dev](https://pkg.go.dev/mod.com#I) +--- @hoverJ/hover.md -- +-```go +-type J interface { +- Hello() +-} +-``` - -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 4, 0, "")) -- env.Await(env.DoneWithChange()) +-[`a.J` on pkg.go.dev](https://pkg.go.dev/mod.com#J) +--- @hoverSum/hover.md -- +-```go +-func (*Pos).Sum() int +-``` - -- env.EditBuffer("main.go", fake.NewEdit(0, 0, 0, 0, `package main +-[`(a.Pos).Sum` on pkg.go.dev](https://pkg.go.dev/mod.com#Pos.Sum) +--- @hoverTestA/hover.md -- +-```go +-func TestA(t *testing.T) +-``` +--- @hoverfield/hover.md -- +-```go +-field field string +-``` +--- @hoverg/hover.md -- +-```go +-const g untyped int = 1 +-``` - --func main() { -- var x int --} --`)) -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "x")), -- ) -- }) --} +-When I hover on g, I should see this comment. +--- @hoverh/hover.md -- +-```go +-const h untyped int = 2 +-``` - --// Reproduces golang/go#39763. --func TestInvalidPackageName(t *testing.T) { -- const pkgDefault = ` ---- go.mod -- --module mod.com +-Constant block. When I hover on h, I should see this comment. +--- @hoverpx/hover.md -- +-```go +-field x int +-``` - --go 1.12 ---- main.go -- --package default +-@loc(PosX, "x"),loc(PosY, "y") +--- @hoverx/hover.md -- +-```go +-var x string +-``` - --func main() {} --` -- Run(t, pkgDefault, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.AfterChange( -- Diagnostics( -- env.AtRegexp("main.go", "default"), -- WithMessage("expected 'IDENT'"), -- ), -- ) -- }) --} +-x is a variable. +--- @hovery/hover.md -- +-```go +-var y int +-``` +--- @hoverz/hover.md -- +-```go +-var z string +-``` - --// This tests the functionality of the "limitWorkspaceScope" --func TestLimitWorkspaceScope(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +-z is a variable too. +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt b/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/addgowork.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,50 +0,0 @@ +-This test demonstrates diagnostics for adding a go.work file. +- +-Quick-fixes change files on disk, so are tested by regtests. +- +-TODO(rfindley): improve the "cannot find package" import errors. +- +--- skip -- +-Skipping due to go.dev/issue/60584#issuecomment-1622238115. +-There appears to be a real race in the critical error logic causing this test +-to flake with high frequency. +- +--- flags -- +--min_go=go1.18 +- +--- a/go.mod -- +-module mod.com/a +- +-go 1.18 - --go 1.12 --- a/main.go -- --package main +-package main //@diag("main", re"add a go.work file") - --func main() {} ---- main.go -- --package main +-import "mod.com/a/lib" //@diag("\"mod.com", re"cannot find package") - -func main() { -- var x int --} --` -- WithOptions( -- WorkspaceFolders("a"), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/main.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "x")), -- ) -- }) -- WithOptions( -- WorkspaceFolders("a"), -- Settings{"expandWorkspaceToModule": false}, -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/main.go") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +- _ = lib.C -} - --func TestSimplifyCompositeLitDiagnostic(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +--- a/lib/lib.go -- +-package lib //@diag("lib", re"add a go.work file") - --go 1.12 ---- main.go -- --package main +-const C = "b" +--- b/go.mod -- +-module mod.com/b - --import "fmt" +-go 1.18 - --type t struct { -- msg string --} +--- b/main.go -- +-package main //@diag("main", re"add a go.work file") +- +-import "mod.com/b/lib" //@diag("\"mod.com", re"cannot find package") - -func main() { -- x := []t{t{"msg"}} -- fmt.Println(x) +- _ = lib.C -} --` - -- WithOptions( -- Settings{"staticcheck": true}, -- ).Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", `t{"msg"}`), WithMessage("redundant type")), -- ReadDiagnostics("main.go", &d), -- ) -- if tags := d.Diagnostics[0].Tags; len(tags) == 0 || tags[0] != protocol.Unnecessary { -- t.Errorf("wanted Unnecessary tag on diagnostic, got %v", tags) -- } -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange(NoDiagnostics(ForFile("main.go"))) -- }) --} +--- b/lib/lib.go -- +-package lib //@diag("lib", re"add a go.work file") - --// Test some secondary diagnostics --func TestSecondaryDiagnostics(t *testing.T) { -- const dir = ` ---- go.mod -- --module mod.com +-const C = "b" +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt b/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/analyzers.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,51 +0,0 @@ +-Test of warning diagnostics from various analyzers: +-copylocks, printf, slog, tests, and timeformat. - +--- go.mod -- +-module example.com -go 1.12 ---- main.go -- --package main --func main() { -- panic("not here") --} ---- other.go -- --package main --func main() {} --` -- Run(t, dir, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.OpenFile("other.go") -- var mainDiags, otherDiags protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &mainDiags), -- ReadDiagnostics("other.go", &otherDiags), -- ) -- if len(mainDiags.Diagnostics) != 1 { -- t.Fatalf("main.go, got %d diagnostics, expected 1", len(mainDiags.Diagnostics)) -- } -- keep := mainDiags.Diagnostics[0] -- if len(otherDiags.Diagnostics) != 1 { -- t.Fatalf("other.go: got %d diagnostics, expected 1", len(otherDiags.Diagnostics)) -- } -- if len(otherDiags.Diagnostics[0].RelatedInformation) != 1 { -- t.Fatalf("got %d RelatedInformations, expected 1", len(otherDiags.Diagnostics[0].RelatedInformation)) -- } -- // check that the RelatedInformation matches the error from main.go -- c := otherDiags.Diagnostics[0].RelatedInformation[0] -- if c.Location.Range != keep.Range { -- t.Errorf("locations don't match. Got %v expected %v", c.Location.Range, keep.Range) -- } -- }) --} - --func TestNotifyOrphanedFiles(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +--- flags -- +--min_go=go1.21 - --go 1.12 ---- a/a.go -- --package a +--- bad_test.go -- +-package analyzer - --func main() { -- var x int +-import ( +- "fmt" +- "log/slog" +- "sync" +- "testing" +- "time" +-) +- +-// copylocks +-func _() { +- var x sync.Mutex +- _ = x //@diag("x", re"assignment copies lock value to _: sync.Mutex") -} ---- a/a_exclude.go -- --// +build exclude - --package a +-// printf +-func _() { +- printfWrapper("%s") //@diag(re`printfWrapper\(.*\)`, re"example.com.printfWrapper format %s reads arg #1, but call has 0 args") +-} +- +-func printfWrapper(format string, args ...interface{}) { +- fmt.Printf(format, args...) +-} - +-// slog -func _() { -- var x int +- slog.Info("msg", 1) //@diag("1", re`slog.Info arg "1" should be a string or a slog.Attr`) -} --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "x")), -- ) -- env.OpenFile("a/a_exclude.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a_exclude.go", "package (a)")), -- ) -- }) +- +-// tests +-func Testbad(t *testing.T) { //@diag("", re"Testbad has malformed name: first letter after 'Test' must not be lowercase") -} - --func TestEnableAllExperiments(t *testing.T) { -- // Before the oldest supported Go version, gopls sends a warning to upgrade -- // Go, which fails the expectation below. -- testenv.NeedsGo1Point(t, lsp.OldestSupportedGoVersion()) +-// timeformat +-func _() { +- now := time.Now() +- fmt.Println(now.Format("2006-02-01")) //@diag("2006-02-01", re"2006-02-01 should be 2006-01-02") +-} - -- const mod = ` ---- go.mod -- --module mod.com +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt b/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/excludedfile.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,38 +0,0 @@ +-This test demonstrates diagnostics for various forms of file exclusion. - --go 1.12 ---- main.go -- --package main +-Skip on plan9, an arbitrary GOOS, so that we can exercise GOOS exclusions +-resulting from file suffixes. - --import "bytes" +--- flags -- +--min_go=go1.18 +--skip_goos=plan9 - --func b(c bytes.Buffer) { -- _ = 1 --} --` -- WithOptions( -- Settings{"allExperiments": true}, -- ).Run(t, mod, func(t *testing.T, env *Env) { -- // Confirm that the setting doesn't cause any warnings. -- env.OnceMet( -- InitialWorkspaceLoad, -- NoShownMessage(""), // empty substring to match any message -- ) -- }) --} +--- go.work -- +-go 1.21 - --func TestSwig(t *testing.T) { -- // This is fixed in Go 1.17, but not earlier. -- testenv.NeedsGo1Point(t, 17) +-use ( +- ./a +-) +--- a/go.mod -- +-module mod.com/a - -- if _, err := exec.LookPath("swig"); err != nil { -- t.Skip("skipping test: swig not available") -- } -- if _, err := exec.LookPath("g++"); err != nil { -- t.Skip("skipping test: g++ not available") -- } +-go 1.18 - -- const mod = ` ---- go.mod -- --module mod.com +--- a/a.go -- +-package a - --go 1.12 ---- pkg/simple/export_swig.go -- --package simple +--- a/a_plan9.go -- +-package a //@diag(re"package (a)", re"excluded due to its GOOS/GOARCH") - --func ExportSimple(x, y int) int { -- return Gcd(x, y) --} ---- pkg/simple/simple.swigcxx -- --%module simple +--- a/a_ignored.go -- +-//go:build skip +-package a //@diag(re"package (a)", re"excluded due to its build tags") - --%inline %{ --extern int gcd(int x, int y) --{ -- int g; -- g = y; -- while (x > 0) { -- g = x; -- x = y % x; -- y = g; -- } -- return g; --} --%} ---- main.go -- --package a +--- b/go.mod -- +-module mod.com/b - --func main() { -- var x int --} --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- NoDiagnostics(WithMessage("illegal character U+0023 '#'")), -- ) -- }) --} +-go 1.18 - --// When foo_test.go is opened, gopls will object to the borked package name. --// This test asserts that when the package name is fixed, gopls will soon after --// have no more complaints about it. --// https://github.com/golang/go/issues/41061 --func TestRenamePackage(t *testing.T) { -- const proxy = ` ---- example.com@v1.2.3/go.mod -- --module example.com +--- b/b.go -- +-package b //@diag(re"package (b)", re"add this module to your go.work") +- +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt b/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/generated.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,21 +0,0 @@ +-Test of "undeclared" diagnostic in generated code. - +--- go.mod -- +-module example.com -go 1.12 ---- example.com@v1.2.3/blah/blah.go -- --package blah - --const Name = "Blah" ---- random.org@v1.2.3/go.mod -- --module random.org +--- generated.go -- +-package generated - --go 1.12 ---- random.org@v1.2.3/blah/blah.go -- --package hello +-// Code generated by generator.go. DO NOT EDIT. - --const Name = "Hello" --` +-func _() { +- var y int //@diag("y", re"y declared (and|but) not used") +-} - -- const contents = ` ---- go.mod -- --module mod.com +--- generator.go -- +-package generated - --go 1.12 +-func _() { +- var x int //@diag("x", re"x declared (and|but) not used") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue56943.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-This test verifies that we produce diagnostics related to mismatching +-unexported interface methods in non-workspace packages. +- +-Previously, we would fail to produce a diagnostic because we trimmed the AST. +-See golang/go#56943. --- main.go -- -package main - --import "example.com/blah" +-import ( +- "go/ast" +- "go/token" +-) - -func main() { -- blah.Hello() +- var a int //@diag(re"(a) int", re"a declared.*not used") +- var _ ast.Expr = node{} //@diag("node{}", re"missing.*exprNode") -} ---- bob.go -- --package main ---- foo/foo.go -- --package foo ---- foo/foo_test.go -- --package foo_ --` - -- WithOptions( -- ProxyFiles(proxy), -- InGOPATH(), -- EnvVars{"GO111MODULE": "off"}, -- ).Run(t, contents, func(t *testing.T, env *Env) { -- // Simulate typing character by character. -- env.OpenFile("foo/foo_test.go") -- env.Await(env.DoneWithOpen()) -- env.RegexpReplace("foo/foo_test.go", "_", "_t") -- env.Await(env.DoneWithChange()) -- env.RegexpReplace("foo/foo_test.go", "_t", "_test") -- env.AfterChange( -- NoDiagnostics(ForFile("foo/foo_test.go")), -- NoOutstandingWork(), -- ) -- }) --} +-type node struct{} +- +-func (node) Pos() token.Pos { return 0 } +-func (node) End() token.Pos { return 0 } +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue59005.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,20 +0,0 @@ +-This test verifies that we don't drop type checking errors on the floor when we +-fail to compute positions for their related errors. - --// TestProgressBarErrors confirms that critical workspace load errors are shown --// and updated via progress reports. --func TestProgressBarErrors(t *testing.T) { -- const pkg = ` --- go.mod -- --modul mod.com +-module play.ground - --go 1.12 ---- main.go -- --package main --` -- Run(t, pkg, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.AfterChange( -- OutstandingWork(lsp.WorkspaceLoadFailure, "unknown directive"), -- ) -- env.EditBuffer("go.mod", fake.NewEdit(0, 0, 3, 0, `module mod.com +--- p.go -- +-package p - --go 1.hello --`)) -- // As of golang/go#42529, go.mod changes do not reload the workspace until -- // they are saved. -- env.SaveBufferWithoutActions("go.mod") -- env.AfterChange( -- OutstandingWork(lsp.WorkspaceLoadFailure, "invalid go version"), -- ) -- env.RegexpReplace("go.mod", "go 1.hello", "go 1.12") -- env.SaveBufferWithoutActions("go.mod") -- env.AfterChange( -- NoOutstandingWork(), -- ) -- }) --} +-import ( +- . "play.ground/foo" +-) - --func TestDeleteDirectory(t *testing.T) { -- const mod = ` ---- bob/bob.go -- --package bob +-const C = 1 //@diag("C", re"C already declared through dot-import") +-var _ = C - --func Hello() { -- var x int --} ---- go.mod -- --module mod.com ---- cmd/main.go -- --package main +--- foo/foo.go -- +-package foo - --import "mod.com/bob" +-const C = 2 +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue60544.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,13 +0,0 @@ +-This test exercises a crash due to treatment of "comparable" in methodset +-calculation (golang/go#60544). - --func main() { -- bob.Hello() --} --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- FileWatchMatching("bob"), -- ) -- env.RemoveWorkspaceFile("bob") -- env.AfterChange( -- Diagnostics(env.AtRegexp("cmd/main.go", `"mod.com/bob"`)), -- NoDiagnostics(ForFile("bob/bob.go")), -- NoFileWatchMatching("bob"), -- ) -- }) --} +--min_go is 1.19 as the error message changed at this Go version. +--- flags -- +--min_go=go1.19 - --// Confirms that circular imports are tested and reported. --func TestCircularImports(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +--- main.go -- +-package main - --go 1.12 ---- self/self.go -- --package self +-type X struct{} - --import _ "mod.com/self" --func Hello() {} ---- double/a/a.go -- --package a +-func (X) test(x comparable) {} //@diag("comparable", re"outside a type constraint") +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt b/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/issue60605.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,12 +0,0 @@ +-This test verifies that we can export constants with unknown kind. +-Previously, the exporter would panic while attempting to convert such constants +-to their target type (float64, in this case). - --import _ "mod.com/double/b" ---- double/b/b.go -- --package b +--- go.mod -- +-module mod.txt/p - --import _ "mod.com/double/a" ---- triple/a/a.go -- --package a +-go 1.20 +--- p.go -- +-package p - --import _ "mod.com/triple/b" ---- triple/b/b.go -- --package b +-const EPSILON float64 = 1e- //@diag(re"1e-()", re"exponent has no digits") +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt b/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/parseerr.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ - --import _ "mod.com/triple/c" ---- triple/c/c.go -- --package c +-This test exercises diagnostics produced for syntax errors. - --import _ "mod.com/triple/a" --` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("self/self.go", `_ "mod.com/self"`), WithMessage("import cycle not allowed")), -- Diagnostics(env.AtRegexp("double/a/a.go", `_ "mod.com/double/b"`), WithMessage("import cycle not allowed")), -- Diagnostics(env.AtRegexp("triple/a/a.go", `_ "mod.com/triple/b"`), WithMessage("import cycle not allowed")), -- ) -- }) --} +-Because parser error recovery can be quite lossy, diagnostics +-for type errors are suppressed in files with syntax errors; +-see issue #59888. But diagnostics are reported for type errors +-in well-formed files of the same package. - --// Tests golang/go#46667: deleting a problematic import path should resolve --// import cycle errors. --func TestResolveImportCycle(t *testing.T) { -- const mod = ` --- go.mod -- --module mod.test +-module example.com +-go 1.12 - --go 1.16 ---- a/a.go -- --package a +--- bad.go -- +-package p - --import "mod.test/b" +-func f() { +- append("") // no diagnostic for type error in file containing syntax error +-} - --const A = b.A --const B = 2 ---- b/b.go -- --package b +-func .() {} //@diag(re"func ().", re"expected 'IDENT', found '.'") - --import "mod.test/a" +--- good.go -- +-package p - --const A = 1 --const B = a.B -- ` -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.OpenFile("b/b.go") -- env.AfterChange( -- // The Go command sometimes tells us about only one of the import cycle -- // errors below. For robustness of this test, succeed if we get either. -- // -- // TODO(golang/go#52904): we should get *both* of these errors. -- AnyOf( -- Diagnostics(env.AtRegexp("a/a.go", `"mod.test/b"`), WithMessage("import cycle")), -- Diagnostics(env.AtRegexp("b/b.go", `"mod.test/a"`), WithMessage("import cycle")), -- ), -- ) -- env.RegexpReplace("b/b.go", `const B = a\.B`, "") -- env.SaveBuffer("b/b.go") -- env.AfterChange( -- NoDiagnostics(ForFile("a/a.go")), -- NoDiagnostics(ForFile("b/b.go")), -- ) -- }) +-func g() { +- append("") //@diag(re`""`, re"a slice") -} +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt b/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/rundespiteerrors.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-This test verifies that analyzers without RunDespiteErrors are not +-executed on a package containing type errors (see issue #54762). - --func TestBadImport(t *testing.T) { -- const mod = ` ---- go.mod -- --module mod.com +-We require go1.18 because the range of the `1 + ""` go/types error +-changed then, and the new @diag marker is quite particular. - +--- go.mod -- +-module example.com -go 1.12 ---- main.go -- --package main - --import ( -- _ "nosuchpkg" --) --` -- t.Run("module", func(t *testing.T) { -- Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`could not import nosuchpkg (no required module provides package "nosuchpkg"`)), -- ) -- }) -- }) -- t.Run("GOPATH", func(t *testing.T) { -- WithOptions( -- InGOPATH(), -- EnvVars{"GO111MODULE": "off"}, -- Modes(Default), -- ).Run(t, mod, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `"nosuchpkg"`), WithMessage(`cannot find package "nosuchpkg"`)), -- ) -- }) -- }) +--- flags -- +--min_go=go1.18 +- +--- a.go -- +-package a +- +-func _() { +- // A type error. +- _ = 1 + "" //@diag(`1 + ""`, re"mismatched types|cannot convert") +- +- // A violation of an analyzer for which RunDespiteErrors=false: +- // no (simplifyrange, warning) diagnostic is produced; the diag +- // comment is merely illustrative. +- for _ = range "" { //diag("for _", "simplify range expression", ) +- +- } -} +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt b/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/typeerr.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ - --func TestNestedModules(t *testing.T) { -- const proxy = ` ---- nested.com@v1.0.0/go.mod -- --module nested.com +-This test exercises diagnostics produced for type errors +-in the absence of syntax errors. - --go 1.12 ---- nested.com@v1.0.0/hello/hello.go -- --package hello +-The type error was chosen to exercise the 'nonewvars' type-error analyzer. +-(The 'undeclaredname' analyzer depends on the text of the go/types +-"undeclared name" error, which changed in go1.20.) - --func Hello() {} --` +-The append() type error was also carefully chosen to have text and +-position that are invariant across all versions of Go run by the builders. - -- const nested = ` --- go.mod -- --module mod.com -- +-module example.com -go 1.12 - --require nested.com v1.0.0 ---- go.sum -- --nested.com v1.0.0 h1:I6spLE4CgFqMdBPc+wTV2asDO2QJ3tU0YAT+jkLeN1I= --nested.com v1.0.0/go.mod h1:ly53UzXQgVjSlV7wicdBB4p8BxfytuGT1Xcyv0ReJfI= ---- main.go -- --package main +--- typeerr.go -- +-package a - --import "nested.com/hello" +-func f(x int) { +- append("") //@diag(re`""`, re"a slice") - --func main() { -- hello.Hello() +- x := 123 //@diag(re"x := 123", re"no new variables"), suggestedfix(re"():", re"no new variables", "quickfix", fix) -} ---- nested/go.mod -- --module nested.com - ---- nested/hello/hello.go -- --package hello +--- @fix/typeerr.go -- +-package a - --func Hello() { -- helloHelper() --} ---- nested/hello/hello_helper.go -- --package hello +-func f(x int) { +- append("") //@diag(re`""`, re"a slice") - --func helloHelper() {} --` -- WithOptions( -- ProxyFiles(proxy), -- Modes(Default), -- ).Run(t, nested, func(t *testing.T, env *Env) { -- // Expect a diagnostic in a nested module. -- env.OpenFile("nested/hello/hello.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("nested/hello/hello.go", "helloHelper")), -- Diagnostics(env.AtRegexp("nested/hello/hello.go", "package hello"), WithMessage("nested module")), -- OutstandingWork(lsp.WorkspaceLoadFailure, "nested module"), -- ) -- }) +- x = 123 //@diag(re"x := 123", re"no new variables"), suggestedfix(re"():", re"no new variables", "quickfix", fix) -} - --func TestAdHocPackagesReloading(t *testing.T) { -- const nomod = ` ---- main.go -- +diff -urN a/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt b/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt +--- a/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/diagnostics/usemodule.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,51 +0,0 @@ +-This test demonstrates diagnostics for a module that is missing from the +-go.work file. +- +-Quick-fixes change files on disk, so are tested by regtests. +- +--- flags -- +--min_go=go1.18 +- +--- go.work -- +-go 1.21 +- +-use ( +- ./a +-) +- +--- a/go.mod -- +-module mod.com/a +- +-go 1.18 +- +--- a/main.go -- -package main - --func main() {} --` -- Run(t, nomod, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.RegexpReplace("main.go", "{}", "{ var x int; }") // simulate typing -- env.AfterChange(NoLogMatching(protocol.Info, "packages=1")) -- }) +-import "mod.com/a/lib" +- +-func main() { +- _ = lib.C -} - --func TestBuildTagChange(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +--- a/lib/lib.go -- +-package lib - --go 1.12 ---- foo.go -- --// decoy comment --// +build hidden --// decoy comment +-const C = "b" +--- b/go.mod -- +-module mod.com/b - --package foo --var Foo = 1 ---- bar.go -- --package foo --var Bar = Foo --` +-go 1.18 - -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("foo.go") -- env.AfterChange(Diagnostics(env.AtRegexp("bar.go", `Foo`))) -- env.RegexpReplace("foo.go", `\+build`, "") -- env.AfterChange(NoDiagnostics(ForFile("bar.go"))) -- }) +--- b/main.go -- +-package main //@diag("main", re"add this module to your go.work") - +-import "mod.com/b/lib" //@diag("\"mod.com", re"not included in a workspace module") +- +-func main() { +- _ = lib.C -} - --func TestIssue44736(t *testing.T) { -- const files = ` -- -- go.mod -- --module blah.com +--- b/lib/lib.go -- +-package lib //@diag("lib", re"add this module to your go.work") - --go 1.16 ---- main.go -- --package main +-const C = "b" +diff -urN a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt +--- a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59318.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-This test verifies that we can load multiple orphaned files as +-command-line-arguments packages. - --import "fmt" +-Previously, we would load only one because go/packages returns at most one +-command-line-arguments package per query. +- +--- a/main.go -- +-package main - -func main() { -- asdf -- fmt.Printf("This is a test %v") -- fdas +- var a int //@diag(re"var (a)", re"not used") -} ---- other.go -- +--- b/main.go -- -package main - --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("main.go") -- env.OpenFile("other.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("main.go", "asdf")), -- Diagnostics(env.AtRegexp("main.go", "fdas")), -- ) -- env.SetBufferContent("other.go", "package main\n\nasdf") -- // The new diagnostic in other.go should not suppress diagnostics in main.go. -- env.AfterChange( -- Diagnostics(env.AtRegexp("other.go", "asdf"), WithMessage("expected declaration")), -- Diagnostics(env.AtRegexp("main.go", "asdf")), -- ) -- }) +-func main() { +- var b int //@diag(re"var (b)", re"not used") -} +--- c/go.mod -- +-module c.com // The existence of this module avoids a workspace error. - --func TestInitialization(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +-go 1.18 +diff -urN a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt +--- a/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/fixedbugs/issue59944.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-This test verifies that gopls does not panic when encountering the go/types +-bug described in golang/go#59944: the Bindingf function is not included in +-the methodset of its receiver type. - --go 1.16 ---- main.go -- --package main --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.Await(env.DoneWithOpen()) -- env.RegexpReplace("go.mod", "module", "modul") -- env.SaveBufferWithoutActions("go.mod") -- env.AfterChange( -- NoLogMatching(protocol.Error, "initial workspace load failed"), -- ) -- }) --} +-Adapted from the code in question from the issue. +- +--- flags -- +--cgo - --// This test confirms that the view does not reinitialize when a go.mod file is --// opened. --func TestNoReinitialize(t *testing.T) { -- const files = ` --- go.mod -- --module mod.com +-module example.com - -go 1.12 ---- main.go -- --package main - --func main() {} --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("go.mod") -- env.AfterChange( -- LogMatching(protocol.Info, `.*query=\[builtin mod.com/...\].*`, 1, false), -- ) -- }) --} +--- cgo.go -- +-package x - --func TestLangVersion(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) // Requires types.Config.GoVersion, new in 1.18. -- const files = ` ---- go.mod -- --module mod.com +-import "fmt" - --go 1.12 ---- main.go -- --package main +-/* +-struct layout { +- int field; +-}; +-*/ +-import "C" - --const C = 0b10 --` -- Run(t, files, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `0b10`), WithMessage("go1.13 or later")), -- ) -- env.WriteWorkspaceFile("go.mod", "module mod.com \n\ngo 1.13\n") -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +-type Layout = C.struct_layout +- +-// Bindingf is a printf wrapper. This was necessary to trigger the panic in +-// objectpath while encoding facts. +-func (l *Layout) Bindingf(format string, args ...interface{}) { +- fmt.Printf(format, args...) -} +diff -urN a/gopls/internal/regtest/marker/testdata/format/format.txt b/gopls/internal/regtest/marker/testdata/format/format.txt +--- a/gopls/internal/regtest/marker/testdata/format/format.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/format/format.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,80 +0,0 @@ +-This test checks basic behavior of textDocument/formatting requests. - --func TestNoQuickFixForUndeclaredConstraint(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) -- const files = ` --- go.mod -- -module mod.com - -go 1.18 ---- main.go -- --package main +--- good.go -- +-package format //@format(good) - --func F[T C](_ T) { --} --` +-import ( +- "log" +-) - -- Run(t, files, func(t *testing.T, env *Env) { -- var d protocol.PublishDiagnosticsParams -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `C`)), -- ReadDiagnostics("main.go", &d), -- ) -- if fixes := env.GetQuickFixes("main.go", d.Diagnostics); len(fixes) != 0 { -- t.Errorf("got quick fixes %v, wanted none", fixes) -- } -- }) +-func goodbye() { +- log.Printf("byeeeee") -} - --func TestEditGoDirective(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) -- const files = ` ---- go.mod -- --module mod.com +--- @good -- +-package format //@format(good) - --go 1.16 ---- main.go -- --package main +-import ( +- "log" +-) - --func F[T any](_ T) { +-func goodbye() { +- log.Printf("byeeeee") -} --` -- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. -- var d protocol.PublishDiagnosticsParams -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), -- ReadDiagnostics("main.go", &d), -- ) +--- bad.go -- +-package format //@format(bad) - -- env.ApplyQuickFixes("main.go", d.Diagnostics) -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) --} +-import ( +- "runtime" +- "fmt" +- "log" +-) - --func TestEditGoDirectiveWorkspace(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) -- const files = ` ---- go.mod -- --module mod.com +-func hello() { - --go 1.16 ---- go.work -- --go 1.18 - --use . ---- main.go -- --package main - --func F[T any](_ T) { --} --` -- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. -- var d protocol.PublishDiagnosticsParams - -- // We should have a diagnostic because generics are not supported at 1.16. -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics(env.AtRegexp("main.go", `T any`), WithMessage("type parameter")), -- ReadDiagnostics("main.go", &d), -- ) +- var x int //@diag("x", re"x declared (and|but) not used") +-} - -- // This diagnostic should have a quick fix to edit the go version. -- env.ApplyQuickFixes("main.go", d.Diagnostics) +-func hi() { +- runtime.GOROOT() +- fmt.Printf("") - -- // Once the edit is applied, the problematic diagnostics should be -- // resolved. -- env.AfterChange( -- NoDiagnostics(ForFile("main.go")), -- ) -- }) +- log.Printf("") -} +--- @bad -- +-package format //@format(bad) - --// This test demonstrates that analysis facts are correctly propagated --// across packages. --func TestInterpackageAnalysis(t *testing.T) { -- const src = ` ---- go.mod -- --module example.com ---- a/a.go -- --package a +-import ( +- "fmt" +- "log" +- "runtime" +-) - --import "example.com/b" +-func hello() { - --func _() { -- new(b.B).Printf("%d", "s") // printf error +- var x int //@diag("x", re"x declared (and|but) not used") -} - ---- b/b.go -- --package b +-func hi() { +- runtime.GOROOT() +- fmt.Printf("") - --import "example.com/c" +- log.Printf("") +-} +--- newline.go -- +-package format //@format(newline) +-func _() {} +--- @newline -- +-package format //@format(newline) +-func _() {} +--- oneline.go -- +-package format //@format(oneline) +--- @oneline -- +-package format //@format(oneline) +diff -urN a/gopls/internal/regtest/marker/testdata/format/issue59554.txt b/gopls/internal/regtest/marker/testdata/format/issue59554.txt +--- a/gopls/internal/regtest/marker/testdata/format/issue59554.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/format/issue59554.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,33 +0,0 @@ +-Test case for golang/go#59554: data corruption on formatting due to line +-directives. - --type B struct{} +-Note that gofumpt is needed for this test case, as it reformats var decls into +-short var decls. - --func (B) Printf(format string, args ...interface{}) { -- c.MyPrintf(format, args...) --} +-Note that gofumpt requires Go 1.18. - ---- c/c.go -- --package c +--- flags -- +--min_go=go1.18 - --import "fmt" +--- settings.json -- +-{ +- "formatting.gofumpt": true +-} +--- main.go -- +-package main //@format(main) - --func MyPrintf(format string, args ...interface{}) { -- fmt.Printf(format, args...) +-func Match(data []byte) int { +-//line :1 +- var idx = ^uint(0) +- _ = idx +- return -1 -} --` -- Run(t, src, func(t *testing.T, env *Env) { -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics( -- env.AtRegexp("a/a.go", "new.*Printf"), -- WithMessage("format %d has arg \"s\" of wrong type string"), -- ), -- ) -- }) +--- @main -- +-package main //@format(main) +- +-func Match(data []byte) int { +-//line :1 +- idx := ^uint(0) +- _ = idx +- return -1 -} +diff -urN a/gopls/internal/regtest/marker/testdata/format/noparse.txt b/gopls/internal/regtest/marker/testdata/format/noparse.txt +--- a/gopls/internal/regtest/marker/testdata/format/noparse.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/format/noparse.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-This test checks that formatting does not run on code that has parse errors. - --// This test ensures that only Analyzers with RunDespiteErrors=true --// are invoked on a package that would not compile, even if the errors --// are distant and localized. --func TestErrorsThatPreventAnalysis(t *testing.T) { -- const src = ` ---- go.mod -- --module example.com ---- a/a.go -- --package a +--- parse.go -- +-package noparse_format //@format(parse) - --import "fmt" --import "sync" --import _ "example.com/b" +-func _() { +-f() //@diag("f", re"(undefined|undeclared name): f") +-} +--- @parse -- +-package noparse_format //@format(parse) - -func _() { -- // The copylocks analyzer (RunDespiteErrors, FactTypes={}) does run. -- var mu sync.Mutex -- mu2 := mu // copylocks error, reported -- _ = &mu2 +- f() //@diag("f", re"(undefined|undeclared name): f") +-} +--- noparse.go -- +-package noparse_format //@format(noparse) - -- // The printf analyzer (!RunDespiteErrors, FactTypes!={}) does not run: -- // (c, printf) failed because of type error in c -- // (b, printf) and (a, printf) do not run because of failed prerequisites. -- fmt.Printf("%d", "s") // printf error, unreported +-// The nonewvars expectation asserts that the go/analysis framework ran. - -- // The bools analyzer (!RunDespiteErrors, FactTypes={}) does not run: -- var cond bool -- _ = cond != true && cond != true // bools error, unreported +-func what() { +- var hi func() +- if { hi() //@diag(re"(){", re".*missing.*") +- } +- hi := nil -} +--- @noparse -- +-7:5: missing condition in if statement +diff -urN a/gopls/internal/regtest/marker/testdata/hover/basiclit.txt b/gopls/internal/regtest/marker/testdata/hover/basiclit.txt +--- a/gopls/internal/regtest/marker/testdata/hover/basiclit.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/basiclit.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,81 +0,0 @@ +-This test checks gopls behavior when hovering over basic literals. +--- basiclit.go -- +-package basiclit - ---- b/b.go -- --package b +-func _() { +- _ = 'a' //@hover("'a'", "'a'", latinA) +- _ = 0x61 //@hover("0x61", "0x61", latinAHex) - --import _ "example.com/c" +- _ = '\u2211' //@hover("'\\u2211'", "'\\u2211'", summation) +- _ = 0x2211 //@hover("0x2211", "0x2211", summationHex) +- _ = "foo \u2211 bar" //@hover("\\u2211", "\\u2211", summation) - ---- c/c.go -- --package c +- _ = '\a' //@hover("'\\a'", "'\\a'", control) +- _ = "foo \a bar" //@hover("\\a", "\\a", control) - --var _ = 1 / "" // type error +- _ = '\U0001F30A' //@hover("'\\U0001F30A'", "'\\U0001F30A'", waterWave) +- _ = 0x0001F30A //@hover("0x0001F30A", "0x0001F30A", waterWaveHex) +- _ = 0X0001F30A //@hover("0X0001F30A", "0X0001F30A", waterWaveHex) +- _ = "foo \U0001F30A bar" //@hover("\\U0001F30A", "\\U0001F30A", waterWave) - --` -- Run(t, src, func(t *testing.T, env *Env) { -- var diags protocol.PublishDiagnosticsParams -- env.OpenFile("a/a.go") -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "mu2 := (mu)"), WithMessage("assignment copies lock value")), -- ReadDiagnostics("a/a.go", &diags)) +- _ = '\x7E' //@hover("'\\x7E'", "'\\x7E'", tilde) +- _ = "foo \x7E bar" //@hover("\\x7E", "\\x7E", tilde) +- _ = "foo \a bar" //@hover("\\a", "\\a", control) - -- // Assert that there were no other diagnostics. -- // In particular: -- // - "fmt.Printf" does not trigger a [printf] finding; -- // - "cond != true" does not trigger a [bools] finding. -- // -- // We use this check in preference to NoDiagnosticAtRegexp -- // as it is robust in case of minor mistakes in the position -- // regexp, and because it reports unexpected diagnostics. -- if got, want := len(diags.Diagnostics), 1; got != want { -- t.Errorf("got %d diagnostics in a/a.go, want %d:", got, want) -- for i, diag := range diags.Diagnostics { -- t.Logf("Diagnostics[%d] = %+v", i, diag) -- } -- } -- }) --} -diff -urN a/gopls/internal/regtest/diagnostics/golist_test.go b/gopls/internal/regtest/diagnostics/golist_test.go ---- a/gopls/internal/regtest/diagnostics/golist_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/golist_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,71 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +- _ = '\173' //@hover("'\\173'", "'\\173'", leftCurly) +- _ = "foo \173 bar" //@hover("\\173","\\173", leftCurly) +- _ = "foo \173 bar \u2211 baz" //@hover("\\173","\\173", leftCurly) +- _ = "foo \173 bar \u2211 baz" //@hover("\\u2211","\\u2211", summation) +- _ = "foo\173bar\u2211baz" //@hover("\\173","\\173", leftCurly) +- _ = "foo\173bar\u2211baz" //@hover("\\u2211","\\u2211", summation) - --package diagnostics +- // search for runes in string only if there is an escaped sequence +- _ = "hello" //@hover(`"hello"`, _, _) - --import ( -- "testing" +- // incorrect escaped rune sequences +- _ = '\0' //@hover("'\\0'", _, _),diag(re`\\0()'`, re"illegal character") +- _ = '\u22111' //@hover("'\\u22111'", _, _) +- _ = '\U00110000' //@hover("'\\U00110000'", _, _) +- _ = '\u12e45'//@hover("'\\u12e45'", _, _) +- _ = '\xa' //@hover("'\\xa'", _, _) +- _ = 'aa' //@hover("'aa'", _, _) - -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/testenv" +- // other basic lits +- _ = 1 //@hover("1", _, _) +- _ = 1.2 //@hover("1.2", _, _) +- _ = 1.2i //@hover("1.2i", _, _) +- _ = 0123 //@hover("0123", _, _) +- _ = 0b1001 //@hover("0b", "0b1001", binaryNumber) +- _ = 0B1001 //@hover("0B", "0B1001", binaryNumber) +- _ = 0o77 //@hover("0o", "0o77", octalNumber) +- _ = 0O77 //@hover("0O", "0O77", octalNumber) +- _ = 0x1234567890 //@hover("0x1234567890", "0x1234567890", hexNumber) +- _ = 0X1234567890 //@hover("0X1234567890", "0X1234567890", hexNumber) +- _ = 0x1000000000000000000 //@hover("0x1", "0x1000000000000000000", bigHex) +-) +--- @bigHex/hover.md -- +-4722366482869645213696 +--- @binaryNumber/hover.md -- +-9 +--- @control/hover.md -- +-U+0007, control +--- @hexNumber/hover.md -- +-78187493520 +--- @latinA/hover.md -- +-'a', U+0061, LATIN SMALL LETTER A +--- @latinAHex/hover.md -- +-97, 'a', U+0061, LATIN SMALL LETTER A +--- @leftCurly/hover.md -- +-'{', U+007B, LEFT CURLY BRACKET +--- @octalNumber/hover.md -- +-63 +--- @summation/hover.md -- +-'∑', U+2211, N-ARY SUMMATION +--- @summationHex/hover.md -- +-8721, '∑', U+2211, N-ARY SUMMATION +--- @tilde/hover.md -- +-'~', U+007E, TILDE +--- @waterWave/hover.md -- +-'🌊', U+1F30A, WATER WAVE +--- @waterWaveHex/hover.md -- +-127754, '🌊', U+1F30A, WATER WAVE +diff -urN a/gopls/internal/regtest/marker/testdata/hover/const.txt b/gopls/internal/regtest/marker/testdata/hover/const.txt +--- a/gopls/internal/regtest/marker/testdata/hover/const.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/const.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,157 +0,0 @@ +-This test checks hovering over constants. +- +--- flags -- +--min_go=go1.17 +- +--- go.mod -- +-module mod.com +- +-go 1.17 +- +--- c.go -- +-package c +- +-import ( +- "math" +- "time" -) - --func TestGoListErrors(t *testing.T) { -- testenv.NeedsTool(t, "cgo") +-const X = 0 //@hover("X", "X", bX) +- +-// dur is a constant of type time.Duration. +-const dur = 15*time.Minute + 10*time.Second + 350*time.Millisecond //@hover("dur", "dur", dur) +- +-// MaxFloat32 is used in another package. +-const MaxFloat32 = 0x1p127 * (1 + (1 - 0x1p-23)) +- +-// Numbers. +-func _() { +- const hex, bin = 0xe34e, 0b1001001 +- +- const ( +- // no inline comment +- decimal = 153 +- +- numberWithUnderscore int64 = 10_000_000_000 +- octal = 0o777 +- expr = 2 << (0b111&0b101 - 2) +- boolean = (55 - 3) == (26 * 2) +- ) +- +- _ = decimal //@hover("decimal", "decimal", decimalConst) +- _ = hex //@hover("hex", "hex", hexConst) +- _ = bin //@hover("bin", "bin", binConst) +- _ = numberWithUnderscore //@hover("numberWithUnderscore", "numberWithUnderscore", numberWithUnderscoreConst) +- _ = octal //@hover("octal", "octal", octalConst) +- _ = expr //@hover("expr", "expr", exprConst) +- _ = boolean //@hover("boolean", "boolean", boolConst) - -- const src = ` ---- go.mod -- --module a.com +- const ln10 = 2.30258509299404568401799145468436420760110148862877297603332790 - --go 1.18 ---- a/a.go -- --package a +- _ = ln10 //@hover("ln10", "ln10", ln10Const) +-} - --import ---- c/c.go -- --package c +-// Iota. +-func _() { +- const ( +- a = 1 << iota +- b +- ) - --/* --int fortythree() { return 42; } --*/ --import "C" +- _ = a //@hover("a", "a", aIota) +- _ = b //@hover("b", "b", bIota) +-} - --func Foo() { -- print(C.fortytwo()) +-// Strings. +-func _() { +- const ( +- str = "hello" + " " + "world" +- longStr = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur eget ipsum non nunc +-molestie mattis id quis augue. Mauris dictum tincidunt ipsum, in auctor arcu congue eu. +-Morbi hendrerit fringilla libero commodo varius. Vestibulum in enim rutrum, rutrum tellus +-aliquet, luctus enim. Nunc sem ex, consectetur id porta nec, placerat vel urna.` +- ) +- +- _ = str //@hover("str", "str", strConst) +- _ = longStr //@hover("longStr", "longStr", longStrConst) -} ---- p/p.go -- --package p - --import "a.com/q" +-// Constants from other packages. +-func _() { +- _ = math.Log2E //@hover("Log2E", "Log2E", log2eConst) +-} - --const P = q.Q + 1 ---- q/q.go -- --package q +--- @bX/hover.md -- +-```go +-const X untyped int = 0 +-``` - --import "a.com/p" +-@hover("X", "X", bX) - --const Q = p.P + 1 --` - -- Run(t, src, func(t *testing.T, env *Env) { -- env.OnceMet( -- InitialWorkspaceLoad, -- Diagnostics( -- env.AtRegexp("a/a.go", "import\n()"), -- FromSource(string(source.ParseError)), -- ), -- Diagnostics( -- AtPosition("c/c.go", 0, 0), -- FromSource(string(source.ListError)), -- WithMessage("may indicate failure to perform cgo processing"), -- ), -- Diagnostics( -- env.AtRegexp("p/p.go", `"a.com/q"`), -- FromSource(string(source.ListError)), -- WithMessage("import cycle not allowed"), -- ), -- ) -- }) --} -diff -urN a/gopls/internal/regtest/diagnostics/invalidation_test.go b/gopls/internal/regtest/diagnostics/invalidation_test.go ---- a/gopls/internal/regtest/diagnostics/invalidation_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/invalidation_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,111 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-[`c.X` on pkg.go.dev](https://pkg.go.dev/mod.com#X) +--- @dur/hover.md -- +-```go +-const dur time.Duration = 15*time.Minute + 10*time.Second + 350*time.Millisecond // 15m10.35s +-``` - --package diagnostics +-dur is a constant of type time.Duration. +--- @decimalConst/hover.md -- +-```go +-const decimal untyped int = 153 +-``` - --import ( -- "fmt" -- "testing" +-no inline comment +--- @hexConst/hover.md -- +-```go +-const hex untyped int = 0xe34e // 58190 +-``` +--- @binConst/hover.md -- +-```go +-const bin untyped int = 0b1001001 // 73 +-``` +--- @numberWithUnderscoreConst/hover.md -- +-```go +-const numberWithUnderscore int64 = 10_000_000_000 // 10000000000 +-``` +--- @octalConst/hover.md -- +-```go +-const octal untyped int = 0o777 // 511 +-``` +--- @exprConst/hover.md -- +-```go +-const expr untyped int = 2 << (0b111&0b101 - 2) // 16 +-``` +--- @boolConst/hover.md -- +-```go +-const boolean untyped bool = (55 - 3) == (26 * 2) // true +-``` +--- @ln10Const/hover.md -- +-```go +-const ln10 untyped float = 2.30258509299404568401799145468436420760110148862877297603332790 // 2.30259 +-``` +--- @aIota/hover.md -- +-```go +-const a untyped int = 1 << iota // 1 +-``` +--- @bIota/hover.md -- +-```go +-const b untyped int = 2 +-``` +--- @strConst/hover.md -- +-```go +-const str untyped string = "hello world" +-``` +--- @longStrConst/hover.md -- +-```go +-const longStr untyped string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur e... +-``` +--- @log2eConst/hover.md -- +-```go +-const math.Log2E untyped float = 1 / Ln2 // 1.4427 +-``` - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-Mathematical constants. +- +- +-[`math.Log2E` on pkg.go.dev](https://pkg.go.dev/math#Log2E) +diff -urN a/gopls/internal/regtest/marker/testdata/hover/generics.txt b/gopls/internal/regtest/marker/testdata/hover/generics.txt +--- a/gopls/internal/regtest/marker/testdata/hover/generics.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/generics.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,76 +0,0 @@ +-This file contains tests for hovering over generic Go code. +- +--- flags -- +--min_go=go1.18 - --// Test for golang/go#50267: diagnostics should be re-sent after a file is --// opened. --func TestDiagnosticsAreResentAfterCloseOrOpen(t *testing.T) { -- const files = ` --- go.mod -- +-// A go.mod is require for correct pkgsite links. +-// TODO(rfindley): don't link to ad-hoc or command-line-arguments packages! -module mod.com - --go 1.16 ---- main.go -- --package main +-go 1.18 - --func _() { -- x := 2 +--- generics.go -- +-package generics +- +-type value[T any] struct { //hover("lue", "value", value),hover("T", "T", valueT) +- val T //@hover("T", "T", valuevalT) +- Q int //@hover("Q", "Q", valueQ) -} --` -- Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. -- env.OpenFile("main.go") -- var afterOpen protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &afterOpen), -- ) -- env.CloseBuffer("main.go") -- var afterClose protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &afterClose), -- ) -- if afterOpen.Version == afterClose.Version { -- t.Errorf("publishDiagnostics: got the same version after closing (%d) as after opening", afterOpen.Version) -- } -- env.OpenFile("main.go") -- var afterReopen protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &afterReopen), -- ) -- if afterReopen.Version == afterClose.Version { -- t.Errorf("pubslishDiagnostics: got the same version after reopening (%d) as after closing", afterClose.Version) -- } -- }) +- +-type Value[T any] struct { //@hover("T", "T", ValueT) +- val T //@hover("T", "T", ValuevalT) +- Q int //@hover("Q", "Q", ValueQ) -} - --// Test for the "chattyDiagnostics" setting: we should get re-published --// diagnostics after every file change, even if diagnostics did not change. --func TestChattyDiagnostics(t *testing.T) { -- const files = ` ---- go.mod -- --module mod.com +-// disabled - see issue #54822 +-func F[P interface{ ~int | string }]() { // hover("P","P",Ptparam) +- // disabled - see issue #54822 +- var _ P // hover("P","P",Pvar) +-} - --go 1.16 ---- main.go -- --package main +--- inferred.go -- +-package generics +- +-func app[S interface{ ~[]E }, E interface{}](s S, e E) S { +- return append(s, e) +-} - -func _() { -- x := 2 +- _ = app[[]int] //@hover("app", "app", appint) +- _ = app[[]int, int] //@hover("app", "app", appint) +- _ = app[[]int]([]int{}, 0) //@hover("app", "app", appint) +- _ = app([]int{}, 0) //@hover("app", "app", appint) -} - --// Irrelevant comment #0 --` +--- @ValueQ/hover.md -- +-```go +-field Q int +-``` - -- WithOptions( -- Settings{ -- "chattyDiagnostics": true, -- }, -- ).Run(t, files, func(_ *testing.T, env *Env) { // Create a new workspace-level directory and empty file. +-@hover("Q", "Q", ValueQ) - -- env.OpenFile("main.go") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- ReadDiagnostics("main.go", &d), -- ) - -- if len(d.Diagnostics) != 1 { -- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) -- } -- msg := d.Diagnostics[0].Message +-[`(generics.Value).Q` on pkg.go.dev](https://pkg.go.dev/mod.com#Value.Q) +--- @ValueT/hover.md -- +-```go +-type parameter T any +-``` +--- @ValuevalT/hover.md -- +-```go +-type parameter T any +-``` +--- @appint/hover.md -- +-```go +-func app(s []int, e int) []int // func[S interface{~[]E}, E interface{}](s S, e E) S +-``` +--- @valueQ/hover.md -- +-```go +-field Q int +-``` - -- for i := 0; i < 5; i++ { -- before := d.Version -- env.RegexpReplace("main.go", "Irrelevant comment #.", fmt.Sprintf("Irrelevant comment #%d", i)) -- env.AfterChange( -- ReadDiagnostics("main.go", &d), -- ) +-@hover("Q", "Q", valueQ) +--- @valuevalT/hover.md -- +-```go +-type parameter T any +-``` +diff -urN a/gopls/internal/regtest/marker/testdata/hover/goprivate.txt b/gopls/internal/regtest/marker/testdata/hover/goprivate.txt +--- a/gopls/internal/regtest/marker/testdata/hover/goprivate.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/goprivate.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-This test checks that links in hover obey GOPRIVATE. +--- env -- +-GOPRIVATE=mod.com +--- go.mod -- +-module mod.com +--- p.go -- +-package p - -- if d.Version == before { -- t.Errorf("after change, got version %d, want new version", d.Version) -- } +-// T should not be linked, as it is private. +-type T struct{} //@hover("T", "T", T) +--- lib/lib.go -- +-package lib - -- // As a sanity check, make sure we have the same diagnostic. -- if len(d.Diagnostics) != 1 { -- t.Fatalf("len(Diagnostics) = %d, want 1", len(d.Diagnostics)) -- } -- newMsg := d.Diagnostics[0].Message -- if newMsg != msg { -- t.Errorf("after change, got message %q, want %q", newMsg, msg) -- } -- } -- }) --} -diff -urN a/gopls/internal/regtest/diagnostics/undeclared_test.go b/gopls/internal/regtest/diagnostics/undeclared_test.go ---- a/gopls/internal/regtest/diagnostics/undeclared_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/diagnostics/undeclared_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,73 +0,0 @@ --// Copyright 2021 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. +-// GOPRIVATE should also match nested packages. +-type L struct{} //@hover("L", "L", L) +--- @L/hover.md -- +-```go +-type L struct{} +-``` - --package diagnostics +-GOPRIVATE should also match nested packages. +--- @T/hover.md -- +-```go +-type T struct{} +-``` - --import ( -- "testing" +-T should not be linked, as it is private. +diff -urN a/gopls/internal/regtest/marker/testdata/hover/hover.txt b/gopls/internal/regtest/marker/testdata/hover/hover.txt +--- a/gopls/internal/regtest/marker/testdata/hover/hover.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/hover.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-This test demonstrates some features of the new marker test runner. +--- a.go -- +-package a - -- "golang.org/x/tools/gopls/internal/lsp/protocol" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-const abc = 0x2a //@hover("b", "abc", abc),hover(" =", "abc", abc) +--- typeswitch.go -- +-package a +- +-func _() { +- var y interface{} +- switch x := y.(type) { //@hover("x", "x", x) +- case int: +- println(x) //@hover("x", "x", xint),hover(")", "x", xint) +- } +-} +--- @abc/hover.md -- +-```go +-const abc untyped int = 0x2a // 42 +-``` +- +-@hover("b", "abc", abc),hover(" =", "abc", abc) +--- @x/hover.md -- +-```go +-var x interface{} +-``` +--- @xint/hover.md -- +-```go +-var x int +-``` +diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt b/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt +--- a/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,145 +0,0 @@ +-This file contains tests for documentation links to generic code in hover. +- +--- flags -- +--min_go=go1.18 - --func TestUndeclaredDiagnostics(t *testing.T) { -- src := ` --- go.mod -- -module mod.com - --go 1.12 ---- a/a.go -- +-go 1.19 +- +--- a.go -- -package a - --func _() int { -- return x +-import "mod.com/generic" +- +-func _() { +- // Hovering over instantiated object should produce accurate type +- // information, but link to the generic declarations. +- +- var x generic.GT[int] //@hover("GT", "GT", xGT) +- _ = x.F //@hover("x", "x", x),hover("F", "F", xF) +- +- f := generic.GF[int] //@hover("GF", "GF", fGF) +- _ = f //@hover("f", "f", f) -} ---- b/b.go -- --package b - --func _() int { -- var y int -- y = y -- return y +--- generic/generic.go -- +-package generic +- +-// Hovering over type parameters should link to documentation. +-// +-// TODO(rfindley): should it? We should probably link to the type. +-type GT[P any] struct{ //@hover("GT", "GT", GT),hover("P", "P", GTP) +- F P //@hover("F", "F", F),hover("P", "P", FP) -} --` -- Run(t, src, func(t *testing.T, env *Env) { -- isUnnecessary := func(diag protocol.Diagnostic) bool { -- for _, tag := range diag.Tags { -- if tag == protocol.Unnecessary { -- return true -- } -- } -- return false -- } - -- // 'x' is undeclared, but still necessary. -- env.OpenFile("a/a.go") -- var adiags protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/a.go", "x")), -- ReadDiagnostics("a/a.go", &adiags), -- ) -- if got := len(adiags.Diagnostics); got != 1 { -- t.Errorf("len(Diagnostics) = %d, want 1", got) -- } -- if diag := adiags.Diagnostics[0]; isUnnecessary(diag) { -- t.Errorf("%v tagged unnecessary, want necessary", diag) -- } +-func (GT[P]) M(p P) { //@hover("GT", "GT", GTrecv),hover("M","M", M),hover(re"p (P)", re"p (P)", pP) +-} - -- // 'y = y' is pointless, and should be detected as unnecessary. -- env.OpenFile("b/b.go") -- var bdiags protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("b/b.go", "y = y")), -- ReadDiagnostics("b/b.go", &bdiags), -- ) -- if got := len(bdiags.Diagnostics); got != 1 { -- t.Errorf("len(Diagnostics) = %d, want 1", got) -- } -- if diag := bdiags.Diagnostics[0]; !isUnnecessary(diag) { -- t.Errorf("%v tagged necessary, want unnecessary", diag) -- } -- }) +-func GF[P any] (p P) { //@hover("GF", "GF", GF) -} -diff -urN a/gopls/internal/regtest/inlayhints/inlayhints_test.go b/gopls/internal/regtest/inlayhints/inlayhints_test.go ---- a/gopls/internal/regtest/inlayhints/inlayhints_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/inlayhints/inlayhints_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,69 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. --package inlayhint - --import ( -- "testing" +--- @F/hover.md -- +-```go +-field F P +-``` - -- "golang.org/x/tools/gopls/internal/hooks" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/gopls/internal/lsp/source" -- "golang.org/x/tools/internal/bug" --) +-@hover("F", "F", F),hover("P", "P", FP) - --func TestMain(m *testing.M) { -- bug.PanicOnBugs = true -- Main(m, hooks.Options) --} - --func TestEnablingInlayHints(t *testing.T) { -- const workspace = ` ---- go.mod -- --module inlayHint.test --go 1.12 ---- lib.go -- --package lib --type Number int --const ( -- Zero Number = iota -- One -- Two --) --` -- tests := []struct { -- label string -- enabled map[string]bool -- wantInlayHint bool -- }{ -- { -- label: "default", -- wantInlayHint: false, -- }, -- { -- label: "enable const", -- enabled: map[string]bool{source.ConstantValues: true}, -- wantInlayHint: true, -- }, -- { -- label: "enable parameter names", -- enabled: map[string]bool{source.ParameterNames: true}, -- wantInlayHint: false, -- }, -- } -- for _, test := range tests { -- t.Run(test.label, func(t *testing.T) { -- WithOptions( -- Settings{ -- "hints": test.enabled, -- }, -- ).Run(t, workspace, func(t *testing.T, env *Env) { -- env.OpenFile("lib.go") -- lens := env.InlayHints("lib.go") -- if gotInlayHint := len(lens) > 0; gotInlayHint != test.wantInlayHint { -- t.Errorf("got inlayHint: %t, want %t", gotInlayHint, test.wantInlayHint) -- } -- }) -- }) -- } +-[`(generic.GT).F` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT.F) +--- @FP/hover.md -- +-```go +-type parameter P any +-``` +--- @GF/hover.md -- +-```go +-func GF[P any](p P) +-``` +- +-[`generic.GF` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GF) +--- @GT/hover.md -- +-```go +-type GT[P any] struct { +- F P //@hover("F", "F", F),hover("P", "P", FP) -} -diff -urN a/gopls/internal/regtest/marker/marker_test.go b/gopls/internal/regtest/marker/marker_test.go ---- a/gopls/internal/regtest/marker/marker_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/marker_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,21 +0,0 @@ --// Copyright 2023 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. - --package marker +-func (GT[P]).M(p P) +-``` - --import ( -- "testing" +-Hovering over type parameters should link to documentation. - -- . "golang.org/x/tools/gopls/internal/lsp/regtest" --) +-TODO(rfindley): should it? We should probably link to the type. +- +- +-[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT) +--- @GTP/hover.md -- +-```go +-type parameter P any +-``` +--- @GTrecv/hover.md -- +-```go +-type GT[P any] struct { +- F P //@hover("F", "F", F),hover("P", "P", FP) +-} - --// Note: we use a separate package for the marker tests so that we can easily --// compare their performance to the existing marker tests in ./internal/lsp. +-func (GT[P]).M(p P) +-``` - --// TestMarkers runs the marker tests from the testdata directory. --// --// See RunMarkerTests for details on how marker tests work. --func TestMarkers(t *testing.T) { -- RunMarkerTests(t, "testdata") --} -diff -urN a/gopls/internal/regtest/marker/testdata/definition/embed.txt b/gopls/internal/regtest/marker/testdata/definition/embed.txt ---- a/gopls/internal/regtest/marker/testdata/definition/embed.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/definition/embed.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,254 +0,0 @@ --This test checks definition and hover operations over embedded fields and methods. +-Hovering over type parameters should link to documentation. - ---- go.mod -- --module mod.com +-TODO(rfindley): should it? We should probably link to the type. - --go 1.18 - ---- a/a.go -- --package a +-[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT) +--- @M/hover.md -- +-```go +-func (GT[P]).M(p P) +-``` - --type A string //@loc(AString, "A") +-[`(generic.GT).M` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT.M) +--- @f/hover.md -- +-```go +-var f func(p int) +-``` +--- @fGF/hover.md -- +-```go +-func generic.GF(p int) // func[P any](p P) +-``` - --func (_ A) Hi() {} //@loc(AHi, "Hi") +-[`generic.GF` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GF) +--- @pP/hover.md -- +-```go +-type parameter P any +-``` +--- @x/hover.md -- +-```go +-var x generic.GT[int] +-``` - --type S struct { -- Field int //@loc(SField, "Field") -- R // embed a struct -- H // embed an interface --} +-@hover("GT", "GT", xGT) +--- @xF/hover.md -- +-```go +-field F int +-``` - --type R struct { -- Field2 int //@loc(RField2, "Field2") --} +-@hover("F", "F", F),hover("P", "P", FP) - --func (_ R) Hey() {} //@loc(RHey, "Hey") - --type H interface { //@loc(H, "H") -- Goodbye() //@loc(HGoodbye, "Goodbye") +-[`(generic.GT).F` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT.F) +--- @xGT/hover.md -- +-```go +-type GT[P any] struct { +- F P //@hover("F", "F", F),hover("P", "P", FP) -} - --type I interface { //@loc(I, "I") -- B() //@loc(IB, "B") -- J --} +-func (generic.GT[P]).M(p P) +-``` - --type J interface { //@loc(J, "J") -- Hello() //@loc(JHello, "Hello") --} +-Hovering over type parameters should link to documentation. - ---- b/b.go -- --package b +-TODO(rfindley): should it? We should probably link to the type. - --import "mod.com/a" //@loc(AImport, re"\".*\"") - --type embed struct { -- F int //@loc(F, "F") --} +-[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT) +diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable.txt b/gopls/internal/regtest/marker/testdata/hover/linkable.txt +--- a/gopls/internal/regtest/marker/testdata/hover/linkable.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/linkable.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,120 +0,0 @@ +-This test checks that we correctly determine pkgsite links for various +-identifiers. - --func (embed) M() //@loc(M, "M") +-We should only produce links that work, meaning the object is reachable via the +-package's public API. +--- go.mod -- +-module mod.com - --type Embed struct { -- embed -- *a.A -- a.I -- a.S --} +-go 1.18 +--- p.go -- +-package p - --func _() { -- e := Embed{} -- e.Hi() //@def("Hi", AHi),hover("Hi", "Hi", AHi) -- e.B() //@def("B", IB),hover("B", "B", IB) -- _ = e.Field //@def("Field", SField),hover("Field", "Field", SField) -- _ = e.Field2 //@def("Field2", RField2),hover("Field2", "Field2", RField2) -- e.Hello() //@def("Hello", JHello),hover("Hello", "Hello",JHello) -- e.Hey() //@def("Hey", RHey),hover("Hey", "Hey", RHey) -- e.Goodbye() //@def("Goodbye", HGoodbye),hover("Goodbye", "Goodbye", HGoodbye) -- e.M() //@def("M", M),hover("M", "M", M) -- _ = e.F //@def("F", F),hover("F", "F", F) +-type E struct { +- Embed int -} - --type aAlias = a.A //@loc(aAlias, "aAlias") +-// T is in the package scope, and so should be linkable. +-type T struct{ //@hover("T", "T", T) +- // Only exported fields should be linkable - --type S1 struct { //@loc(S1, "S1") -- F1 int //@loc(S1F1, "F1") -- S2 //@loc(S1S2, "S2"),def("S2", S2),hover("S2", "S2", S2) -- a.A //@def("A", AString),hover("A", "A", aA) -- aAlias //@def("a", aAlias),hover("a", "aAlias", aAlias) --} +- f int //@hover("f", "f", f) +- F int //@hover("F", "F", F) - --type S2 struct { //@loc(S2, "S2") -- F1 string //@loc(S2F1, "F1") -- F2 int //@loc(S2F2, "F2") -- *a.A //@def("A", AString),def("a",AImport) --} +- E - --type S3 struct { -- F1 struct { -- a.A //@def("A", AString) +- // TODO(rfindley): is the link here correct? It ignores N. +- N struct { +- // Nested fields should also be linkable. +- Nested int //@hover("Nested", "Nested", Nested) - } -} +-// M is an exported method, and so should be linkable. +-func (T) M() {} - --func Bar() { -- var x S1 //@def("S1", S1),hover("S1", "S1", S1) -- _ = x.S2 //@def("S2", S1S2),hover("S2", "S2", S1S2) -- _ = x.F1 //@def("F1", S1F1),hover("F1", "F1", S1F1) -- _ = x.F2 //@def("F2", S2F2),hover("F2", "F2", S2F2) -- _ = x.S2.F1 //@def("F1", S2F1),hover("F1", "F1", S2F1) --} +-// m is not exported, and so should not be linkable. +-func (T) m() {} - ---- b/c.go -- --package b +-func _() { +- var t T - --var _ = S1{ //@def("S1", S1),hover("S1", "S1", S1) -- F1: 99, //@def("F1", S1F1),hover("F1", "F1", S1F1) --} +- // Embedded fields should be linkable. +- _ = t.Embed //@hover("Embed", "Embed", Embed) - ---- @AHi/hover.md -- +- // Local variables should not be linkable, even if they are capitalized. +- var X int //@hover("X", "X", X) +- _ = X +- +- // Local types should not be linkable, even if they are capitalized. +- type Local struct { //@hover("Local", "Local", Local) +- E +- } +- +- // But the embedded field should still be linkable. +- var l Local +- _ = l.Embed //@hover("Embed", "Embed", Embed) +-} +--- @Embed/hover.md -- -```go --func (a.A).Hi() +-field Embed int -``` - --[`(a.A).Hi` on pkg.go.dev](https://pkg.go.dev/mod.com/a#A.Hi) +-[`(p.E).Embed` on pkg.go.dev](https://pkg.go.dev/mod.com#E.Embed) --- @F/hover.md -- -```go -field F int -``` - --@loc(F, "F") +-@hover("F", "F", F) - - --[`(b.Embed).F` on pkg.go.dev](https://pkg.go.dev/mod.com/b#Embed.F) ---- @HGoodbye/hover.md -- +-[`(p.T).F` on pkg.go.dev](https://pkg.go.dev/mod.com#T.F) +--- @Local/hover.md -- -```go --func (a.H).Goodbye() +-type Local struct { +- E +-} -``` - --@loc(HGoodbye, "Goodbye") -- -- --[`(a.H).Goodbye` on pkg.go.dev](https://pkg.go.dev/mod.com/a#H.Goodbye) ---- @IB/hover.md -- +-Local types should not be linkable, even if they are capitalized. +--- @Nested/hover.md -- -```go --func (a.I).B() +-field Nested int -``` - --@loc(IB, "B") +-Nested fields should also be linkable. +--- @T/hover.md -- +-```go +-type T struct { +- f int //@hover("f", "f", f) +- F int //@hover("F", "F", F) - +- E - --[`(a.I).B` on pkg.go.dev](https://pkg.go.dev/mod.com/a#I.B) ---- @JHello/hover.md -- --```go --func (a.J).Hello() +- // TODO(rfindley): is the link here correct? It ignores N. +- N struct { +- // Nested fields should also be linkable. +- Nested int //@hover("Nested", "Nested", Nested) +- } +-} +- +-func (T).M() +-func (T).m() -``` - --@loc(JHello, "Hello") +-T is in the package scope, and so should be linkable. - - --[`(a.J).Hello` on pkg.go.dev](https://pkg.go.dev/mod.com/a#J.Hello) ---- @M/hover.md -- +-[`p.T` on pkg.go.dev](https://pkg.go.dev/mod.com#T) +--- @X/hover.md -- -```go --func (embed).M() +-var X int -``` - --[`(b.Embed).M` on pkg.go.dev](https://pkg.go.dev/mod.com/b#Embed.M) ---- @RField2/hover.md -- +-Local variables should not be linkable, even if they are capitalized. +--- @f/hover.md -- -```go --field Field2 int +-field f int -``` - --@loc(RField2, "Field2") -- +-@hover("f", "f", f) +diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkname.txt b/gopls/internal/regtest/marker/testdata/hover/linkname.txt +--- a/gopls/internal/regtest/marker/testdata/hover/linkname.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/linkname.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-This test check hover on the 2nd argument in go:linkname directives. +--- go.mod -- +-module mod.com - --[`(a.R).Field2` on pkg.go.dev](https://pkg.go.dev/mod.com/a#R.Field2) ---- @RHey/hover.md -- --```go --func (a.R).Hey() --``` +--- upper/upper.go -- +-package upper - --[`(a.R).Hey` on pkg.go.dev](https://pkg.go.dev/mod.com/a#R.Hey) ---- @S1/hover.md -- --```go --type S1 struct { -- F1 int //@loc(S1F1, "F1") -- S2 //@loc(S1S2, "S2"),def("S2", S2),hover("S2", "S2", S2) -- a.A //@def("A", AString),hover("A", "A", aA) -- aAlias //@def("a", aAlias),hover("a", "aAlias", aAlias) --} --``` +-import ( +- _ "unsafe" +- _ "mod.com/lower" +-) - --[`b.S1` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S1) ---- @S1F1/hover.md -- --```go --field F1 int --``` +-//go:linkname foo mod.com/lower.bar //@hover("mod.com/lower.bar", "mod.com/lower.bar", bar) +-func foo() string - --@loc(S1F1, "F1") +--- lower/lower.go -- +-package lower - +-// bar does foo. +-func bar() string { +- return "foo by bar" +-} - --[`(b.S1).F1` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S1.F1) ---- @S1S2/hover.md -- +--- @bar/hover.md -- -```go --field S2 S2 +-func bar() string -``` - --@loc(S1S2, "S2"),def("S2", S2),hover("S2", "S2", S2) +-bar does foo. +diff -urN a/gopls/internal/regtest/marker/testdata/hover/std.txt b/gopls/internal/regtest/marker/testdata/hover/std.txt +--- a/gopls/internal/regtest/marker/testdata/hover/std.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/hover/std.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,80 +0,0 @@ +-This test checks hover results for built-in or standard library symbols. - +-It uses synopsis documentation as full documentation for some of these +-built-ins varies across Go versions, where as it just so happens that the +-synopsis does not. - --[`(b.S1).S2` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S1.S2) ---- @S2/hover.md -- --```go --type S2 struct { -- F1 string //@loc(S2F1, "F1") -- F2 int //@loc(S2F2, "F2") -- *a.A //@def("A", AString),def("a",AImport) +-In the future we may need to limit this test to the latest Go version to avoid +-documentation churn. +--- settings.json -- +-{ +- "hoverKind": "SynopsisDocumentation" -} --``` +--- go.mod -- +-module mod.com - --[`b.S2` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S2) ---- @S2F1/hover.md -- --```go --field F1 string --``` +-go 1.18 +--- std.go -- +-package std - --@loc(S2F1, "F1") +-import ( +- "fmt" +- "go/types" +- "sync" +-) - +-func _() { +- var err error //@loc(err, "err") +- fmt.Printf("%v", err) //@def("err", err) - --[`(b.S2).F1` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S2.F1) ---- @S2F2/hover.md -- +- var _ string //@hover("string", "string", hoverstring) +- _ = make([]int, 0) //@hover("make", "make", hovermake) +- +- var mu sync.Mutex +- mu.Lock() //@hover("Lock", "Lock", hoverLock) +- +- var typ *types.Named //@hover("types", "types", hoverTypes) +- typ.Obj().Name() //@hover("Name", "Name", hoverName) +-} +--- @hoverLock/hover.md -- -```go --field F2 int +-func (*sync.Mutex).Lock() -``` - --@loc(S2F2, "F2") +-Lock locks m. - - --[`(b.S2).F2` on pkg.go.dev](https://pkg.go.dev/mod.com/b#S2.F2) ---- @SField/hover.md -- +-[`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync#Mutex.Lock) +--- @hoverName/hover.md -- -```go --field Field int +-func (*types.object).Name() string -``` - --@loc(SField, "Field") +-Name returns the object's (package-local, unqualified) name. - - --[`(a.S).Field` on pkg.go.dev](https://pkg.go.dev/mod.com/a#S.Field) ---- @aA/hover.md -- +-[`(types.TypeName).Name` on pkg.go.dev](https://pkg.go.dev/go/types#TypeName.Name) +--- @hoverTypes/hover.md -- -```go --type A string +-package types ("go/types") +-``` - --func (a.A).Hi() +-[`types` on pkg.go.dev](https://pkg.go.dev/go/types) +--- @hovermake/hover.md -- +-```go +-func make(t Type, size ...int) Type -``` - --@loc(AString, "A") +-The make built-in function allocates and initializes an object of type slice, map, or chan (only). - - --[`a.A` on pkg.go.dev](https://pkg.go.dev/mod.com/a#A) ---- @aAlias/hover.md -- +-[`make` on pkg.go.dev](https://pkg.go.dev/builtin#make) +--- @hoverstring/hover.md -- -```go --type aAlias = a.A -- --func (a.A).Hi() +-type string string -``` - --@loc(aAlias, "aAlias") -diff -urN a/gopls/internal/regtest/marker/testdata/definition/import.txt b/gopls/internal/regtest/marker/testdata/definition/import.txt ---- a/gopls/internal/regtest/marker/testdata/definition/import.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/definition/import.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,52 +0,0 @@ --This test checks definition and hover over imports. +-string is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8-encoded text. +- +- +-[`string` on pkg.go.dev](https://pkg.go.dev/builtin#string) +diff -urN a/gopls/internal/regtest/marker/testdata/implementation/basic.txt b/gopls/internal/regtest/marker/testdata/implementation/basic.txt +--- a/gopls/internal/regtest/marker/testdata/implementation/basic.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/implementation/basic.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,73 +0,0 @@ +-Basic test of implementation query. +- --- go.mod -- --module mod.com +-module example.com +-go 1.12 - --go 1.18 ---- foo/foo.go -- --package foo +--- implementation/implementation.go -- +-package implementation - --type Foo struct{} +-import "example.com/other" - --// DoFoo does foo. --func DoFoo() {} //@loc(DoFoo, "DoFoo") ---- bar/bar.go -- --package bar +-type ImpP struct{} //@loc(ImpP, "ImpP"),implementation("ImpP", Laugher, OtherLaugher) - --import ( -- myFoo "mod.com/foo" //@loc(myFoo, "myFoo") --) +-func (*ImpP) Laugh() { //@loc(LaughP, "Laugh"),implementation("Laugh", Laugh, OtherLaugh) +-} - --var _ *myFoo.Foo //@def("myFoo", myFoo),hover("myFoo", "myFoo", myFoo) ---- bar/dotimport.go -- --package bar +-type ImpS struct{} //@loc(ImpS, "ImpS"),implementation("ImpS", Laugher, OtherLaugher) - --import . "mod.com/foo" +-func (ImpS) Laugh() { //@loc(LaughS, "Laugh"),implementation("Laugh", Laugh, OtherLaugh) +-} - --func _() { -- // variable of type foo.Foo -- var _ Foo //@hover("_", "_", FooVar) +-type Laugher interface { //@loc(Laugher, "Laugher"),implementation("Laugher", ImpP, OtherImpP, ImpS, OtherImpS, embedsImpP) +- Laugh() //@loc(Laugh, "Laugh"),implementation("Laugh", LaughP, OtherLaughP, LaughS, OtherLaughS) +-} - -- DoFoo() //@hover("DoFoo", "DoFoo", DoFoo) +-type Foo struct { //@implementation("Foo", Joker) +- other.Foo -} ---- @DoFoo/hover.md -- --```go --func DoFoo() --``` - --DoFoo does foo. +-type Joker interface { //@loc(Joker, "Joker") +- Joke() //@loc(Joke, "Joke"),implementation("Joke", ImpJoker) +-} - +-type cryer int //@implementation("cryer", Cryer) - --[`foo.DoFoo` on pkg.go.dev](https://pkg.go.dev/mod.com/foo#DoFoo) ---- @FooVar/hover.md -- --```go --var _ Foo --``` +-func (cryer) Cry(other.CryType) {} //@loc(CryImpl, "Cry"),implementation("Cry", Cry) - --variable of type foo.Foo ---- @myFoo/hover.md -- --```go --package myFoo ("mod.com/foo") --``` +-type Empty interface{} //@implementation("Empty") - --[`myFoo` on pkg.go.dev](https://pkg.go.dev/mod.com/foo) -diff -urN a/gopls/internal/regtest/marker/testdata/definition/misc.txt b/gopls/internal/regtest/marker/testdata/definition/misc.txt ---- a/gopls/internal/regtest/marker/testdata/definition/misc.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/definition/misc.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,230 +0,0 @@ --This test exercises miscellaneous definition and hover requests. ---- go.mod -- --module mod.com +-var _ interface{ Joke() } //@implementation("Joke", ImpJoker) - --go 1.16 ---- a.go -- --package a //@loc(aPackage, re"package (a)"),hover(aPackage, aPackage, aPackage) +-type embedsImpP struct { //@loc(embedsImpP, "embedsImpP") +- ImpP //@implementation("ImpP", Laugher, OtherLaugher) +-} - --var ( -- // x is a variable. -- x string //@loc(x, "x"),hover(x, x, hoverx) --) +--- other/other.go -- +-package other - --// Constant block. When I hover on h, I should see this comment. --const ( -- // When I hover on g, I should see this comment. -- g = 1 //@hover("g", "g", hoverg) +-type ImpP struct{} //@loc(OtherImpP, "ImpP") - -- h = 2 //@hover("h", "h", hoverh) --) +-func (*ImpP) Laugh() { //@loc(OtherLaughP, "Laugh") +-} - --// z is a variable too. --var z string //@loc(z, "z"),hover(z, z, hoverz) +-type ImpS struct{} //@loc(OtherImpS, "ImpS") - --func AStuff() { //@loc(AStuff, "AStuff") -- x := 5 -- Random2(x) //@def("dom2", Random2) -- Random() //@def("()", Random) +-func (ImpS) Laugh() { //@loc(OtherLaughS, "Laugh") -} - --type H interface { //@loc(H, "H") -- Goodbye() +-type ImpI interface { //@loc(OtherLaugher, "ImpI") +- Laugh() //@loc(OtherLaugh, "Laugh") -} - --type I interface { //@loc(I, "I") -- B() -- J +-type Foo struct { //@implementation("Foo", Joker) -} - --type J interface { //@loc(J, "J") -- Hello() +-func (Foo) Joke() { //@loc(ImpJoker, "Joke"),implementation("Joke", Joke) -} - --func _() { -- // 1st type declaration block -- type ( -- a struct { //@hover("a", "a", hoverDeclBlocka) -- x string -- } -- ) +-type CryType int - -- // 2nd type declaration block -- type ( -- // b has a comment -- b struct{} //@hover("b", "b", hoverDeclBlockb) -- ) +-type Cryer interface { //@loc(Cryer, "Cryer") +- Cry(CryType) //@loc(Cry, "Cry"),implementation("Cry", CryImpl) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/implementation/generics.txt b/gopls/internal/regtest/marker/testdata/implementation/generics.txt +--- a/gopls/internal/regtest/marker/testdata/implementation/generics.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/implementation/generics.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,34 +0,0 @@ +-Test of 'implementation' query on generic types. - -- // 3rd type declaration block -- type ( -- // c is a struct -- c struct { //@hover("c", "c", hoverDeclBlockc) -- f string -- } +--- flags -- +--min_go=go1.18 - -- d string //@hover("d", "d", hoverDeclBlockd) -- ) +--- go.mod -- +-module example.com +-go 1.18 - -- type ( -- e struct { //@hover("e", "e", hoverDeclBlocke) -- f float64 -- } // e has a comment -- ) +--- implementation/implementation.go -- +-package implementation +- +-type GenIface[T any] interface { //@loc(GenIface, "GenIface"),implementation("GenIface", GC) +- F(int, string, T) //@loc(GenIfaceF, "F"),implementation("F", GCF) -} - --var ( -- hh H //@hover("H", "H", hoverH) -- ii I //@hover("I", "I", hoverI) -- jj J //@hover("J", "J", hoverJ) --) ---- a_test.go -- --package a +-type GenConc[U any] int //@loc(GenConc, "GenConc"),implementation("GenConc", GI) - --import ( -- "testing" --) +-func (GenConc[V]) F(int, string, V) {} //@loc(GenConcF, "F"),implementation("F", GIF) +- +-type GenConcString struct{ GenConc[string] } //@loc(GenConcString, "GenConcString"),implementation(GenConcString, GIString) +- +--- other/other.go -- +-package other - --func TestA(t *testing.T) { //@hover("TestA", "TestA", hoverTestA) +-type GI[T any] interface { //@loc(GI, "GI"),implementation("GI", GenConc) +- F(int, string, T) //@loc(GIF, "F"),implementation("F", GenConcF) -} ---- random.go -- --package a - --func Random() int { //@loc(Random, "Random") -- y := 6 + 7 -- return y --} +-type GIString GI[string] //@loc(GIString, "GIString"),implementation("GIString", GenConcString) - --func Random2(y int) int { //@loc(Random2, "Random2"),loc(RandomParamY, "y") -- return y //@def("y", RandomParamY),hover("y", "y", hovery) --} +-type GC[U any] int //@loc(GC, "GC"),implementation("GC", GenIface) - --type Pos struct { -- x, y int //@loc(PosX, "x"),loc(PosY, "y") --} +-func (GC[V]) F(int, string, V) {} //@loc(GCF, "F"),implementation("F", GenIfaceF) +diff -urN a/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt b/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt +--- a/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/implementation/issue43655.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,22 +0,0 @@ +-This test verifies that we fine implementations of the built-in error interface. - --// Typ has a comment. Its fields do not. --type Typ struct{ field string } //@loc(TypField, "field") +--- go.mod -- +-module example.com +-go 1.12 - --func _() { -- x := &Typ{} -- _ = x.field //@def("field", TypField),hover("field", "field", hoverfield) --} +--- p.go -- +-package p - --func (p *Pos) Sum() int { //@loc(PosSum, "Sum") -- return p.x + p.y //@hover("x", "x", hoverpx) --} +-type errA struct{ error } //@loc(errA, "errA") +- +-type errB struct{} //@loc(errB, "errB") +-func (errB) Error() string{ return "" } //@loc(errBError, "Error") +- +-type notAnError struct{} +-func (notAnError) Error() int { return 0 } - -func _() { -- var p Pos -- _ = p.Sum() //@def("()", PosSum),hover("()", `Sum`, hoverSum) +- var _ error //@implementation("error", errA, errB) +- var a errA +- _ = a.Error //@implementation("Error", errBError) -} ---- @aPackage/hover.md -- ---- @hoverDeclBlocka/hover.md -- --```go --type a struct { -- x string --} --``` +diff -urN a/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt b/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt +--- a/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/quickfix/undeclared.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,62 +0,0 @@ +-Tests of suggested fixes for "undeclared name" diagnostics, +-which are of ("compiler", "error") type. - --1st type declaration block ---- @hoverDeclBlockb/hover.md -- --```go --type b struct{} --``` +--- go.mod -- +-module example.com +-go 1.12 - --b has a comment ---- @hoverDeclBlockc/hover.md -- --```go --type c struct { -- f string +--- a.go -- +-package p +- +-func a() { +- z, _ := 1+y, 11 //@suggestedfix("y", re"(undeclared name|undefined): y", "quickfix", a) +- _ = z -} --``` - --c is a struct ---- @hoverDeclBlockd/hover.md -- --```go --type d string --``` +--- @a/a.go -- +-package p - --3rd type declaration block ---- @hoverDeclBlocke/hover.md -- --```go --type e struct { -- f float64 +-func a() { +- y := +- z, _ := 1+y, 11 //@suggestedfix("y", re"(undeclared name|undefined): y", "quickfix", a) +- _ = z -} --``` - --e has a comment ---- @hoverH/hover.md -- --```go --type H interface { -- Goodbye() +--- b.go -- +-package p +- +-func b() { +- if 100 < 90 { +- } else if 100 > n+2 { //@suggestedfix("n", re"(undeclared name|undefined): n", "quickfix", b) +- } -} --``` - --[`a.H` on pkg.go.dev](https://pkg.go.dev/mod.com#H) ---- @hoverI/hover.md -- --```go --type I interface { -- B() -- J +--- @b/b.go -- +-package p +- +-func b() { +- n := +- if 100 < 90 { +- } else if 100 > n+2 { //@suggestedfix("n", re"(undeclared name|undefined): n", "quickfix", b) +- } -} --``` - --[`a.I` on pkg.go.dev](https://pkg.go.dev/mod.com#I) ---- @hoverJ/hover.md -- --```go --type J interface { -- Hello() +--- c.go -- +-package p +- +-func c() { +- for i < 200 { //@suggestedfix("i", re"(undeclared name|undefined): i", "quickfix", c) +- } +- r() //@diag("r", re"(undeclared name|undefined): r") -} --``` - --[`a.J` on pkg.go.dev](https://pkg.go.dev/mod.com#J) ---- @hoverSum/hover.md -- --```go --func (*Pos).Sum() int --``` +--- @c/c.go -- +-package p - --[`(a.Pos).Sum` on pkg.go.dev](https://pkg.go.dev/mod.com#Pos.Sum) ---- @hoverTestA/hover.md -- --```go --func TestA(t *testing.T) --``` ---- @hoverfield/hover.md -- --```go --field field string --``` ---- @hoverg/hover.md -- --```go --const g untyped int = 1 --``` +-func c() { +- i := +- for i < 200 { //@suggestedfix("i", re"(undeclared name|undefined): i", "quickfix", c) +- } +- r() //@diag("r", re"(undeclared name|undefined): r") +-} - --When I hover on g, I should see this comment. ---- @hoverh/hover.md -- --```go --const h untyped int = 2 --``` +diff -urN a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt +--- a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire_gowork.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,49 +0,0 @@ +-This test checks the suggested fix to remove unused require statements from +-go.mod files, when a go.work file is used. - --Constant block. When I hover on h, I should see this comment. ---- @hoverpx/hover.md -- --```go --field x int --``` +-Note that unlike unusedrequire.txt, we need not write go.sum files when +-a go.work file is used. - --@loc(PosX, "x"),loc(PosY, "y") ---- @hoverx/hover.md -- --```go --var x string --``` +--- flags -- +--min_go=go1.18 - --x is a variable. ---- @hovery/hover.md -- --```go --var y int --``` ---- @hoverz/hover.md -- --```go --var z string --``` +--- proxy/example.com@v1.0.0/x.go -- +-package pkg +-const X = 1 - --z is a variable too. -diff -urN a/gopls/internal/regtest/marker/testdata/hover/basiclit.txt b/gopls/internal/regtest/marker/testdata/hover/basiclit.txt ---- a/gopls/internal/regtest/marker/testdata/hover/basiclit.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/basiclit.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,60 +0,0 @@ --This test checks gopls behavior when hovering over basic literals. ---- basiclit.go -- --package basiclit +--- go.work -- +-go 1.21 - --func _() { -- _ = 'a' //@hover("'a'", "'a'", latinA) -- _ = 0x61 //@hover("0x61", "0x61", latinA) +-use ( +- ./a +- ./b +-) +--- a/go.mod -- +-module mod.com/a - -- _ = '\u2211' //@hover("'\\u2211'", "'\\u2211'", summation) -- _ = 0x2211 //@hover("0x2211", "0x2211", summation) -- _ = "foo \u2211 bar" //@hover("\\u2211", "\\u2211", summation) +-go 1.14 - -- _ = '\a' //@hover("'\\a'", "'\\a'", control) -- _ = "foo \a bar" //@hover("\\a", "\\a", control) +-require example.com v1.0.0 //@suggestedfix("require", re"not used", "quickfix", a) - -- _ = '\U0001F30A' //@hover("'\\U0001F30A'", "'\\U0001F30A'", waterWave) -- _ = 0x0001F30A //@hover("0x0001F30A", "0x0001F30A", waterWave) -- _ = "foo \U0001F30A bar" //@hover("\\U0001F30A", "\\U0001F30A", waterWave) +--- @a/a/go.mod -- +-module mod.com/a - -- _ = '\x7E' //@hover("'\\x7E'", "'\\x7E'", tilde) -- _ = "foo \x7E bar" //@hover("\\x7E", "\\x7E", tilde) -- _ = "foo \a bar" //@hover("\\a", "\\a", control) +-go 1.14 +--- a/main.go -- +-package main +-func main() {} - -- _ = '\173' //@hover("'\\173'", "'\\173'", leftCurly) -- _ = "foo \173 bar" //@hover("\\173","\\173", leftCurly) -- _ = "foo \173 bar \u2211 baz" //@hover("\\173","\\173", leftCurly) -- _ = "foo \173 bar \u2211 baz" //@hover("\\u2211","\\u2211", summation) -- _ = "foo\173bar\u2211baz" //@hover("\\173","\\173", leftCurly) -- _ = "foo\173bar\u2211baz" //@hover("\\u2211","\\u2211", summation) +--- b/go.mod -- +-module mod.com/b - -- // search for runes in string only if there is an escaped sequence -- _ = "hello" //@hover(`"hello"`, _, _) +-go 1.14 - -- // incorrect escaped rune sequences -- _ = '\0' //@hover("'\\0'", _, _),diag(re`\\0()'`, re"illegal character") -- _ = '\u22111' //@hover("'\\u22111'", _, _) -- _ = '\U00110000' //@hover("'\\U00110000'", _, _) -- _ = '\u12e45'//@hover("'\\u12e45'", _, _) -- _ = '\xa' //@hover("'\\xa'", _, _) -- _ = 'aa' //@hover("'aa'", _, _) +-require example.com v1.0.0 //@suggestedfix("require", re"not used", "quickfix", b) - -- // other basic lits -- _ = 1 //@hover("1", _, _) -- _ = 1.2 //@hover("1.2", _, _) -- _ = 1.2i //@hover("1.2i", _, _) -- _ = 0123 //@hover("0123", _, _) -- _ = 0x1234567890 //@hover("0x1234567890", _, _) --) ---- @control/hover.md -- --U+0007, control ---- @latinA/hover.md -- --'a', U+0061, LATIN SMALL LETTER A ---- @leftCurly/hover.md -- --'{', U+007B, LEFT CURLY BRACKET ---- @summation/hover.md -- --'∑', U+2211, N-ARY SUMMATION ---- @tilde/hover.md -- --'~', U+007E, TILDE ---- @waterWave/hover.md -- --'🌊', U+1F30A, WATER WAVE -diff -urN a/gopls/internal/regtest/marker/testdata/hover/const.txt b/gopls/internal/regtest/marker/testdata/hover/const.txt ---- a/gopls/internal/regtest/marker/testdata/hover/const.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/const.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,18 +0,0 @@ --This test checks hovering over constants. ---- go.mod -- --module mod.com +--- @b/b/go.mod -- +-module mod.com/b - --go 1.18 ---- c.go -- --package c +-go 1.14 +--- b/main.go -- +-package main +-func main() {} +diff -urN a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt +--- a/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/quickfix/unusedrequire.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,24 +0,0 @@ +-This test checks the suggested fix to remove unused require statements from +-go.mod files. - --const X = 0 //@hover("X", "X", bX) ---- @bX/hover.md -- --```go --const X untyped int = 0 --``` +--- flags -- +--write_sumfile=a - --@hover("X", "X", bX) +--- proxy/example.com@v1.0.0/x.go -- +-package pkg +-const X = 1 - +--- a/go.mod -- +-module mod.com - --[`c.X` on pkg.go.dev](https://pkg.go.dev/mod.com#X) -diff -urN a/gopls/internal/regtest/marker/testdata/hover/generics.txt b/gopls/internal/regtest/marker/testdata/hover/generics.txt ---- a/gopls/internal/regtest/marker/testdata/hover/generics.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/generics.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,77 +0,0 @@ --This file contains tests for hovering over generic Go code. +-go 1.14 - ---- flags -- ---min_go=go1.18 +-require example.com v1.0.0 //@suggestedfix("require", re"not used", "quickfix", a) - ---- go.mod -- --// A go.mod is require for correct pkgsite links. --// TODO(rfindley): don't link to ad-hoc or command-line-arguments packages! +--- @a/a/go.mod -- -module mod.com - --go 1.18 +-go 1.14 +--- a/main.go -- +-package main +-func main() {} +diff -urN a/gopls/internal/regtest/marker/testdata/references/crosspackage.txt b/gopls/internal/regtest/marker/testdata/references/crosspackage.txt +--- a/gopls/internal/regtest/marker/testdata/references/crosspackage.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/crosspackage.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,37 +0,0 @@ +-Test of basic cross-package references. - ---- generics.go -- --package generics +--- go.mod -- +-module example.com +-go 1.12 - --type value[T any] struct { //hover("lue", "value", value),hover("T", "T", valueT) -- val T //@hover("T", "T", valuevalT) -- Q int //@hover("Q", "Q", valueQ) --} +--- a/a.go -- +-package a - --type Value[T any] struct { //@hover("T", "T", ValueT) -- val T //@hover("T", "T", ValuevalT) -- Q int //@hover("Q", "Q", ValueQ) +-type X struct { +- Y int //@loc(typeXY, "Y") -} - --// disabled - see issue #54822 --func F[P interface{ ~int | string }]() { // hover("P","P",Ptparam) -- // disabled - see issue #54822 -- var _ P // hover("P","P",Pvar) --} +--- b/b.go -- +-package b - ---- inferred.go -- --package generics +-import "example.com/a" - --func app[S interface{ ~[]E }, E interface{}](s S, e E) S { -- return append(s, e) +-func GetXes() []a.X { +- return []a.X{ +- { +- Y: 1, //@loc(GetXesY, "Y"), refs("Y", typeXY, GetXesY, anotherXY) +- }, +- } -} - +--- c/c.go -- +-package c +- +-import "example.com/b" +- -func _() { -- _ = app[[]int] //@hover("app", "app", appint) -- _ = app[[]int, int] //@hover("app", "app", appint) -- // TODO(rfindley): eliminate this diagnostic. -- _ = app[[]int]([]int{}, 0) //@hover("app", "app", appint),diag("[[]int]", re"unnecessary type arguments") -- _ = app([]int{}, 0) //@hover("app", "app", appint) +- xes := b.GetXes() +- for _, x := range xes { //@loc(defX, "x") +- _ = x.Y //@loc(useX, "x"), loc(anotherXY, "Y"), refs("Y", typeXY, anotherXY, GetXesY), refs(".", defX, useX), refs("x", defX, useX) +- } -} +diff -urN a/gopls/internal/regtest/marker/testdata/references/imports.txt b/gopls/internal/regtest/marker/testdata/references/imports.txt +--- a/gopls/internal/regtest/marker/testdata/references/imports.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/imports.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +-Test of references to local package names (imports). - ---- @ValueQ/hover.md -- --```go --field Q int --``` +--- go.mod -- +-module example.com +-go 1.12 - --@hover("Q", "Q", ValueQ) +--- a/a.go -- +-package a - +-import "os" //@loc(osDef, `"os"`), refs("os", osDef, osUse) - --[`(generics.Value).Q` on pkg.go.dev](https://pkg.go.dev/mod.com#Value.Q) ---- @ValueT/hover.md -- --```go --type parameter T any --``` ---- @ValuevalT/hover.md -- --```go --type parameter T any --``` ---- @appint/hover.md -- --```go --func app(s []int, e int) []int // func[S interface{~[]E}, E interface{}](s S, e E) S --``` ---- @valueQ/hover.md -- --```go --field Q int --``` +-import fmt2 "fmt" //@loc(fmt2Def, `fmt2`), refs("fmt2", fmt2Def, fmt2Use) +- +-func _() { +- os.Getwd() //@loc(osUse, "os") +- fmt2.Println() //@loc(fmt2Use, "fmt2") +-} +diff -urN a/gopls/internal/regtest/marker/testdata/references/interfaces.txt b/gopls/internal/regtest/marker/testdata/references/interfaces.txt +--- a/gopls/internal/regtest/marker/testdata/references/interfaces.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/interfaces.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-Test of references applied to concrete and interface types that are +-related by assignability. The result includes references to both. - --@hover("Q", "Q", valueQ) ---- @valuevalT/hover.md -- --```go --type parameter T any --``` -diff -urN a/gopls/internal/regtest/marker/testdata/hover/goprivate.txt b/gopls/internal/regtest/marker/testdata/hover/goprivate.txt ---- a/gopls/internal/regtest/marker/testdata/hover/goprivate.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/goprivate.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,27 +0,0 @@ --This test checks that links in hover obey GOPRIVATE. ---- env -- --GOPRIVATE=mod.com --- go.mod -- --module mod.com ---- p.go -- --package p +-module example.com +-go 1.12 - --// T should not be linked, as it is private. --type T struct{} //@hover("T", "T", T) ---- lib/lib.go -- --package lib +--- a/a.go -- +-package a - --// GOPRIVATE should also match nested packages. --type L struct{} //@hover("L", "L", L) ---- @L/hover.md -- --```go --type L struct{} --``` +-type first interface { +- common() //@loc(firCommon, "common"), refs("common", firCommon, xCommon, zCommon) +- firstMethod() //@loc(firMethod, "firstMethod"), refs("firstMethod", firMethod, xfMethod, zfMethod) +-} - --GOPRIVATE should also match nested packages. ---- @T/hover.md -- --```go --type T struct{} --``` +-type second interface { +- common() //@loc(secCommon, "common"), refs("common", secCommon, yCommon, zCommon) +- secondMethod() //@loc(secMethod, "secondMethod"), refs("secondMethod", secMethod, ysMethod, zsMethod) +-} - --T should not be linked, as it is private. -diff -urN a/gopls/internal/regtest/marker/testdata/hover/hover.txt b/gopls/internal/regtest/marker/testdata/hover/hover.txt ---- a/gopls/internal/regtest/marker/testdata/hover/hover.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/hover.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,29 +0,0 @@ --This test demonstrates some features of the new marker test runner. ---- a.go -- --package a +-type s struct {} - --const abc = 0x2a //@hover("b", "abc", abc),hover(" =", "abc", abc) ---- typeswitch.go -- --package a +-func (*s) common() {} //@loc(sCommon, "common"), refs("common", sCommon, xCommon, yCommon, zCommon) - --func _() { -- var y interface{} -- switch x := y.(type) { //@hover("x", "x", x) -- case int: -- println(x) //@hover("x", "x", xint),hover(")", "x", xint) -- } --} ---- @abc/hover.md -- --```go --const abc untyped int = 42 --``` +-func (*s) firstMethod() {} //@loc(sfMethod, "firstMethod"), refs("firstMethod", sfMethod, xfMethod, zfMethod) - --@hover("b", "abc", abc),hover(" =", "abc", abc) ---- @x/hover.md -- --```go --var x interface{} --``` ---- @xint/hover.md -- --```go --var x int --``` -diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt b/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt ---- a/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/linkable_generics.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,145 +0,0 @@ --This file contains tests for documentation links to generic code in hover. +-func (*s) secondMethod() {} //@loc(ssMethod, "secondMethod"), refs("secondMethod", ssMethod, ysMethod, zsMethod) - ---- flags -- ---min_go=go1.18 +-func main() { +- var x first = &s{} +- var y second = &s{} - ---- go.mod -- --module mod.com +- x.common() //@loc(xCommon, "common"), refs("common", firCommon, xCommon, zCommon) +- x.firstMethod() //@loc(xfMethod, "firstMethod"), refs("firstMethod", firMethod, xfMethod, zfMethod) +- y.common() //@loc(yCommon, "common"), refs("common", secCommon, yCommon, zCommon) +- y.secondMethod() //@loc(ysMethod, "secondMethod"), refs("secondMethod", secMethod, ysMethod, zsMethod) - --go 1.19 +- var z *s = &s{} +- z.firstMethod() //@loc(zfMethod, "firstMethod"), refs("firstMethod", sfMethod, xfMethod, zfMethod) +- z.secondMethod() //@loc(zsMethod, "secondMethod"), refs("secondMethod", ssMethod, ysMethod, zsMethod) +- z.common() //@loc(zCommon, "common"), refs("common", sCommon, xCommon, yCommon, zCommon) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/references/intrapackage.txt b/gopls/internal/regtest/marker/testdata/references/intrapackage.txt +--- a/gopls/internal/regtest/marker/testdata/references/intrapackage.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/intrapackage.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,36 +0,0 @@ +-Basic test of references within a single package. - ---- a.go -- --package a +--- go.mod -- +-module example.com +-go 1.12 - --import "mod.com/generic" +--- a/a.go -- +-package a - --func _() { -- // Hovering over instantiated object should produce accurate type -- // information, but link to the generic declarations. +-type i int //@loc(decli, "i"), refs("i", decli, argi, returni, embeddedi) - -- var x generic.GT[int] //@hover("GT", "GT", xGT) -- _ = x.F //@hover("x", "x", x),hover("F", "F", xF) +-func _(_ i) []bool { //@loc(argi, "i") +- return nil +-} - -- f := generic.GF[int] //@hover("GF", "GF", fGF) -- _ = f //@hover("f", "f", f) +-func _(_ []byte) i { //@loc(returni, "i") +- return 0 -} - ---- generic/generic.go -- --package generic +-var q string //@loc(declq, "q"), refs("q", declq, assignq, bobq) - --// Hovering over type parameters should link to documentation. --// --// TODO(rfindley): should it? We should probably link to the type. --type GT[P any] struct{ //@hover("GT", "GT", GT),hover("P", "P", GTP) -- F P //@hover("F", "F", F),hover("P", "P", FP) +-var Q string //@loc(declQ, "Q"), refs("Q", declQ) +- +-func _() { +- q = "hello" //@loc(assignq, "q") +- bob := func(_ string) {} +- bob(q) //@loc(bobq, "q") -} - --func (GT[P]) M(p P) { //@hover("GT", "GT", GTrecv),hover("M","M", M),hover(re"p (P)", re"p (P)", pP) +-type e struct { +- i //@loc(embeddedi, "i"), refs("i", embeddedi, embeddediref) -} - --func GF[P any] (p P) { //@hover("GF", "GF", GF) +-func _() { +- _ = e{}.i //@loc(embeddediref, "i") -} +diff -urN a/gopls/internal/regtest/marker/testdata/references/issue58506.txt b/gopls/internal/regtest/marker/testdata/references/issue58506.txt +--- a/gopls/internal/regtest/marker/testdata/references/issue58506.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/issue58506.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,56 +0,0 @@ +-Regression test for 'references' bug golang/go#58506. - ---- @F/hover.md -- --```go --field F P --``` +-The 'references' query below, applied to method A.F, implicitly uses +-the 'implementation' operation. The correct response includes two +-references to B.F, one from package b and one from package d. +-However, the incremental 'implementation' algorithm had a bug that +-cause it to fail to report the reference from package b. - --@hover("F", "F", F),hover("P", "P", FP) +-The reason was that the incremental implementation uses different +-algorithms for the local and global cases (with disjoint results), and +-that when it discovered that type A satisfies interface B and thus +-that B.F must be included among the global search targets, the +-implementation forgot to also search package b for local references +-to B.F. - +--- go.mod -- +-module example.com +-go 1.12 - --[`(generic.GT).F` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT.F) ---- @FP/hover.md -- --```go --type parameter P any --``` ---- @GF/hover.md -- --```go --func GF[P any](p P) --``` +--- a/a.go -- +-package a - --[`generic.GF` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GF) ---- @GT/hover.md -- --```go --type GT[P any] struct { -- F P //@hover("F", "F", F),hover("P", "P", FP) --} +-type A int - --func (GT[P]).M(p P) --``` +-func (A) F() {} //@loc(refa, "F"), refs("F", refa, refb, refd) +- +--- b/b.go -- +-package b +- +-import ( +- "example.com/a" +- "example.com/c" +-) +- +-type B interface{ F() } +- +-var _ B = a.A(0) +-var _ B = c.C(0) +- +-var _ = B.F //@loc(refb, "F") +- +--- c/c.go -- +-package c +- +-type C int +- +-// Even though C.F is "rename coupled" to A.F by B.F, +-// it should not be among the results. +-func (C) F() {} +- +--- d/d.go -- +-package d +- +-import "example.com/b" - --Hovering over type parameters should link to documentation. +-var _ interface{} = b.B.F //@loc(refd, "F") +diff -urN a/gopls/internal/regtest/marker/testdata/references/issue59851.txt b/gopls/internal/regtest/marker/testdata/references/issue59851.txt +--- a/gopls/internal/regtest/marker/testdata/references/issue59851.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/issue59851.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-Regression test for 'references' bug golang/go#59851. - --TODO(rfindley): should it? We should probably link to the type. +--- go.mod -- +-module example.com +-go 1.12 - +--- a/a.go -- +-package a - --[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT) ---- @GTP/hover.md -- --```go --type parameter P any --``` ---- @GTrecv/hover.md -- --```go --type GT[P any] struct { -- F P //@hover("F", "F", F),hover("P", "P", FP) +-type Iface interface { +- Method() -} - --func (GT[P]).M(p P) --``` -- --Hovering over type parameters should link to documentation. +-type implOne struct{} - --TODO(rfindley): should it? We should probably link to the type. +-func (implOne) Method() {} //@loc(def1, "Method"), refs(def1, def1, ref1, iref, ireftest) - +-var _ = implOne.Method //@loc(ref1, "Method") +-var _ = Iface(nil).Method //@loc(iref, "Method") - --[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT) ---- @M/hover.md -- --```go --func (GT[P]).M(p P) --``` +--- a/a_test.go -- +-package a - --[`(generic.GT).M` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT.M) ---- @f/hover.md -- --```go --var f func(p int) --``` ---- @fGF/hover.md -- --```go --func generic.GF(p int) // func[P any](p P) --``` +-type implTwo struct{} - --[`generic.GF` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GF) ---- @pP/hover.md -- --```go --type parameter P any --``` ---- @x/hover.md -- --```go --var x generic.GT[int] --``` +-func (implTwo) Method() {} //@loc(def2, "Method"), refs(def2, def2, iref, ref2, ireftest) - --@hover("GT", "GT", xGT) ---- @xF/hover.md -- --```go --field F int --``` +-var _ = implTwo.Method //@loc(ref2, "Method") +-var _ = Iface(nil).Method //@loc(ireftest, "Method") +diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60369.txt b/gopls/internal/regtest/marker/testdata/references/issue60369.txt +--- a/gopls/internal/regtest/marker/testdata/references/issue60369.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/issue60369.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-Regression test for 'references' bug golang/go#60369: a references +-query on the embedded type name T in struct{p.T} instead reports all +-references to the package name p. - --@hover("F", "F", F),hover("P", "P", FP) +-The bug was fixed in release go1.21 of go/types. - +--- flags -- +--min_go=go1.21 - --[`(generic.GT).F` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT.F) ---- @xGT/hover.md -- --```go --type GT[P any] struct { -- F P //@hover("F", "F", F),hover("P", "P", FP) --} +--- go.mod -- +-module example.com +-go 1.12 - --func (generic.GT[P]).M(p P) --``` +--- a/a.go -- +-package a - --Hovering over type parameters should link to documentation. +-type A struct{} +-const C = 0 - --TODO(rfindley): should it? We should probably link to the type. +--- b/b.go -- +-package b - +-import a "example.com/a" //@loc(adef, "a") +-type s struct { +- a.A //@loc(Aref1, "A"), loc(aref1, "a"), refs(Aref1, Aref1, Aref3), refs(aref1, adef, aref1, aref2, aref3) +-} +-var _ a.A //@loc(aref2, re" (a)"), loc(Aref2, "A") +-var _ = s{}.A //@loc(Aref3, "A") +-const c = a.C //@loc(aref3, "a") +diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60622.txt b/gopls/internal/regtest/marker/testdata/references/issue60622.txt +--- a/gopls/internal/regtest/marker/testdata/references/issue60622.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/issue60622.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +-Regression test for 'references' bug golang/go#60622: +-references to methods of generics were missing. - --[`generic.GT` on pkg.go.dev](https://pkg.go.dev/mod.com/generic#GT) -diff -urN a/gopls/internal/regtest/marker/testdata/hover/linkable.txt b/gopls/internal/regtest/marker/testdata/hover/linkable.txt ---- a/gopls/internal/regtest/marker/testdata/hover/linkable.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/linkable.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,120 +0,0 @@ --This test checks that we correctly determine pkgsite links for various --identifiers. +--- flags -- +--min_go=go1.18 - --We should only produce links that work, meaning the object is reachable via the --package's public API. --- go.mod -- --module mod.com -- +-module example.com -go 1.18 ---- p.go -- --package p - --type E struct { -- Embed int --} +--- a/a.go -- +-package a - --// T is in the package scope, and so should be linkable. --type T struct{ //@hover("T", "T", T) -- // Only exported fields should be linkable +-type G[T any] struct{} - -- f int //@hover("f", "f", f) -- F int //@hover("F", "F", F) +-func (G[T]) M() {} //@loc(Mdef, "M"), refs(Mdef, Mdef, Mref) - -- E +--- b/b.go -- +-package b - -- // TODO(rfindley): is the link here correct? It ignores N. -- N struct { -- // Nested fields should also be linkable. -- Nested int //@hover("Nested", "Nested", Nested) -- } +-import "example.com/a" +- +-func _() { +- new(a.G[int]).M() //@loc(Mref, "M") -} --// M is an exported method, and so should be linkable. --func (T) M() {} +diff -urN a/gopls/internal/regtest/marker/testdata/references/issue60676.txt b/gopls/internal/regtest/marker/testdata/references/issue60676.txt +--- a/gopls/internal/regtest/marker/testdata/references/issue60676.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/issue60676.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,69 +0,0 @@ +-This test verifies that even after importing from export data, the references +-algorithm is able to find all references to struct fields or methods that are +-shared by types from multiple packages. See golang/go#60676. - --// m is not exported, and so should not be linkable. --func (T) m() {} +-Note that the marker test runner awaits the initial workspace load, so export +-data should be populated at the time references are requested. - --func _() { -- var t T +--- flags -- +--min_go=go1.18 - -- // Embedded fields should be linkable. -- _ = t.Embed //@hover("Embed", "Embed", Embed) +--- go.mod -- +-module mod.test - -- // Local variables should not be linkable, even if they are capitalized. -- var X int //@hover("X", "X", X) -- _ = X +-go 1.18 - -- // Local types should not be linkable, even if they are capitalized. -- type Local struct { //@hover("Local", "Local", Local) -- E -- } +--- a/a.go -- +-package a - -- // But the embedded field should still be linkable. -- var l Local -- _ = l.Embed //@hover("Embed", "Embed", Embed) +-type A struct { +- F int //@loc(FDef, "F") +- E //@loc(EDef, "E") -} ---- @Embed/hover.md -- --```go --field Embed int --``` -- --[`(p.E).Embed` on pkg.go.dev](https://pkg.go.dev/mod.com#E.Embed) ---- @F/hover.md -- --```go --field F int --``` - --@hover("F", "F", F) +-type E struct { +- G string //@loc(GDef, "G") +-} - +-type AI interface { +- M() //@loc(MDef, "M") +- EI +- error +-} - --[`(p.T).F` on pkg.go.dev](https://pkg.go.dev/mod.com#T.F) ---- @Local/hover.md -- --```go --type Local struct { -- E +-type EI interface { +- N() //@loc(NDef, "N") -} --``` - --Local types should not be linkable, even if they are capitalized. ---- @Nested/hover.md -- --```go --field Nested int --``` +-type T[P any] struct{ f P } - --Nested fields should also be linkable. ---- @T/hover.md -- --```go --type T struct { -- f int //@hover("f", "f", f) -- F int //@hover("F", "F", F) +-type Error error - -- E - -- // TODO(rfindley): is the link here correct? It ignores N. -- N struct { -- // Nested fields should also be linkable. -- Nested int //@hover("Nested", "Nested", Nested) -- } --} +--- b/b.go -- +-package b - --func (T).M() --func (T).m() --``` +-import "mod.test/a" - --T is in the package scope, and so should be linkable. +-type B a.A - +-type BI a.AI - --[`p.T` on pkg.go.dev](https://pkg.go.dev/mod.com#T) ---- @X/hover.md -- --```go --var X int --``` +-type T a.T[int] // must not panic - --Local variables should not be linkable, even if they are capitalized. ---- @f/hover.md -- --```go --field f int --``` +--- c/c.go -- +-package c - --@hover("f", "f", f) -diff -urN a/gopls/internal/regtest/marker/testdata/hover/std.txt b/gopls/internal/regtest/marker/testdata/hover/std.txt ---- a/gopls/internal/regtest/marker/testdata/hover/std.txt 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/marker/testdata/hover/std.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,80 +0,0 @@ --This test checks hover results for built-in or standard library symbols. +-import "mod.test/b" - --It uses synopsis documentation as full documentation for some of these --built-ins varies across Go versions, where as it just so happens that the --synopsis does not. +-func _() { +- x := b.B{ +- F: 42, //@refs("F", FDef, "F") +- } +- x.G = "hi" //@refs("G", GDef, "G") +- _ = x.E //@refs("E", EDef, "E") - --In the future we may need to limit this test to the latest Go version to avoid --documentation churn. ---- settings.json -- --{ -- "hoverKind": "SynopsisDocumentation" +- var y b.BI +- _ = y.M //@refs("M", MDef, "M") +- _ = y.N //@refs("N", NDef, "N") -} ---- go.mod -- --module mod.com +diff -urN a/gopls/internal/regtest/marker/testdata/references/issue61618.txt b/gopls/internal/regtest/marker/testdata/references/issue61618.txt +--- a/gopls/internal/regtest/marker/testdata/references/issue61618.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/issue61618.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,39 +0,0 @@ +-Regression test for 'references' bug golang/go#61618: +-references to instantiated fields were missing. +- +--- flags -- +--min_go=go1.18 - +--- go.mod -- +-module example.com -go 1.18 ---- std.go -- --package std - --import ( -- "fmt" -- "go/types" -- "sync" --) +--- a.go -- +-package a - --func _() { -- var err error //@loc(err, "err") -- fmt.Printf("%v", err) //@def("err", err) +-// This file is adapted from the example in the issue. - -- var _ string //@hover("string", "string", hoverstring) -- _ = make([]int, 0) //@hover("make", "make", hovermake) +-type builder[S ~[]F, F ~string] struct { +- name string +- elements S //@loc(def, "elements"), refs(def, def, assign, use) +- elemData map[F][]ElemData[F] +-} - -- var mu sync.Mutex -- mu.Lock() //@hover("Lock", "Lock", hoverLock) +-type ElemData[F ~string] struct { +- Name F +-} - -- var typ *types.Named //@hover("types", "types", hoverTypes) -- typ.Obj().Name() //@hover("Name", "Name", hoverName) +-type BuilderImpl[S ~[]F, F ~string] struct{ builder[S, F] } +- +-func NewBuilderImpl[S ~[]F, F ~string](name string) *BuilderImpl[S, F] { +- impl := &BuilderImpl[S,F]{ +- builder[S, F]{ +- name: name, +- elements: S{}, //@loc(assign, "elements"), refs(assign, def, assign, use) +- elemData: map[F][]ElemData[F]{}, +- }, +- } +- +- _ = impl.elements //@loc(use, "elements"), refs(use, def, assign, use) +- return impl -} ---- @hoverLock/hover.md -- --```go --func (*sync.Mutex).Lock() --``` +diff -urN a/gopls/internal/regtest/marker/testdata/references/shadow.txt b/gopls/internal/regtest/marker/testdata/references/shadow.txt +--- a/gopls/internal/regtest/marker/testdata/references/shadow.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/shadow.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,17 +0,0 @@ +-Test of references in the presence of shadowing. - --Lock locks m. +--- go.mod -- +-module example.com +-go 1.12 - +--- a/a.go -- +-package a - --[`(sync.Mutex).Lock` on pkg.go.dev](https://pkg.go.dev/sync#Mutex.Lock) ---- @hoverName/hover.md -- --```go --func (*types.object).Name() string --``` +-func _() { +- x := 123 //@loc(x1, "x"), refs("x", x1, x1ref) +- _ = x //@loc(x1ref, "x") +- { +- x := "hi" //@loc(x2, "x"), refs("x", x2, x2ref) +- _ = x //@loc(x2ref, "x") +- } +-} +diff -urN a/gopls/internal/regtest/marker/testdata/references/test.txt b/gopls/internal/regtest/marker/testdata/references/test.txt +--- a/gopls/internal/regtest/marker/testdata/references/test.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/test.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-Test of references between the extra files of a test variant +-and the regular package. - --Name returns the object's (package-local, unqualified) name. +--- go.mod -- +-module example.com +-go 1.12 - +--- a/a.go -- +-package a - --[`(types.TypeName).Name` on pkg.go.dev](https://pkg.go.dev/go/types#TypeName.Name) ---- @hoverTypes/hover.md -- --```go --package types ("go/types") --``` +-func fn() {} //@loc(def, "fn"), refs("fn", def, use) - --[`types` on pkg.go.dev](https://pkg.go.dev/go/types) ---- @hovermake/hover.md -- --```go --func make(t Type, size ...int) Type --``` +-type t struct { g int } //@loc(gdef, "g") +-type u struct { t } - --The make built-in function allocates and initializes an object of type slice, map, or chan (only). +-var _ = new(u).g //@loc(gref, "g"), refs("g", gdef, gref) +-// TODO(adonovan): fix: gref2 and gdef2 are missing. - +--- a/a_test.go -- +-package a - --[`make` on pkg.go.dev](https://pkg.go.dev/builtin#make) ---- @hoverstring/hover.md -- --```go --type string string --``` +-func _() { +- fn() //@loc(use, "fn") - --string is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8-encoded text. +- _ = new(u).g //@loc(gref2, "g"), refs("g", gdef2, gref, gref2) +-} +- +-// This declaration changes the meaning of u.t in the test. +-func (u) g() {} //@loc(gdef2, "g") +diff -urN a/gopls/internal/regtest/marker/testdata/references/typeswitch.txt b/gopls/internal/regtest/marker/testdata/references/typeswitch.txt +--- a/gopls/internal/regtest/marker/testdata/references/typeswitch.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/references/typeswitch.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-Tests of reference to implicit type switch vars, which are +-a special case in go/types.Info{Def,Use,Implicits}. +- +--- go.mod -- +-module example.com +-go 1.12 - +--- a/a.go -- +-package a - --[`string` on pkg.go.dev](https://pkg.go.dev/builtin#string) +-func _(x interface{}) { +- switch y := x.(type) { //@loc(yDecl, "y"), refs("y", yDecl, yInt, yDefault) +- case int: +- println(y) //@loc(yInt, "y"), refs("y", yDecl, yInt, yDefault) +- default: +- println(y) //@loc(yDefault, "y") +- } +-} diff -urN a/gopls/internal/regtest/marker/testdata/rename/basic.txt b/gopls/internal/regtest/marker/testdata/rename/basic.txt --- a/gopls/internal/regtest/marker/testdata/rename/basic.txt 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/marker/testdata/rename/basic.txt 1970-01-01 00:00:00.000000000 +0000 -@@ -1,22 +0,0 @@ +@@ -1,38 +0,0 @@ -This test performs basic coverage of 'rename' within a single package. - --- basic.go -- -package p - --func f(x int) { println(x) } //@rename("x", y, param_x) +-func f(x int) { println(x) } //@rename("x", y, xToy) +- +--- @xToy/basic.go -- +-package p +- +-func f(y int) { println(y) } //@rename("x", y, xToy) +- +--- alias.go -- +-package p +- +-// from golang/go#61625 +-type LongNameHere struct{} +-type A = LongNameHere //@rename("A", B, AToB) +-func Foo() A - ---- @param_x/basic.go -- +--- @AToB/alias.go -- -package p - --func f(y int) { println(y) } //@rename("x", y, param_x) +-// from golang/go#61625 +-type LongNameHere struct{} +-type B = LongNameHere //@rename("A", B, AToB) +-func Foo() B - --- errors.go -- -package p @@ -114113,6 +126526,396 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/embed.txt b/gopls/inte - -var _ = new(B).A2 //@renameerr("A", A4, errAnonField) - +diff -urN a/gopls/internal/regtest/marker/testdata/rename/generics.txt b/gopls/internal/regtest/marker/testdata/rename/generics.txt +--- a/gopls/internal/regtest/marker/testdata/rename/generics.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/generics.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,240 +0,0 @@ +-This test exercises various renaming features on generic code. +- +-Fixed bugs: +- +-- golang/go#61614: renaming a method of a type in a package that uses type +- parameter composite lits used to panic, because previous iterations of the +- satisfy analysis did not account for this language feature. +- +-- golang/go#61635: renaming type parameters did not work when they were +- capitalized and the package was imported by another package. +- +--- flags -- +--min_go=go1.18 +- +--- go.mod -- +-module example.com +-go 1.20 +- +--- a.go -- +-package a +- +-type I int +- +-func (I) m() {} //@rename("m", M, mToM) +- +-func _[P ~[]int]() { +- _ = P{} +-} +- +--- @mToM/a.go -- +-package a +- +-type I int +- +-func (I) M() {} //@rename("m", M, mToM) +- +-func _[P ~[]int]() { +- _ = P{} +-} +- +--- g.go -- +-package a +- +-type S[P any] struct { //@rename("P", Q, PToQ) +- P P +- F func(P) P +-} +- +-func F[R any](r R) { +- var _ R //@rename("R", S, RToS) +-} +- +--- @PToQ/g.go -- +-package a +- +-type S[Q any] struct { //@rename("P", Q, PToQ) +- P Q +- F func(Q) Q +-} +- +-func F[R any](r R) { +- var _ R //@rename("R", S, RToS) +-} +- +--- @RToS/g.go -- +-package a +- +-type S[P any] struct { //@rename("P", Q, PToQ) +- P P +- F func(P) P +-} +- +-func F[S any](r S) { +- var _ S //@rename("R", S, RToS) +-} +- +--- issue61635/p.go -- +-package issue61635 +- +-type builder[S ~[]F, F ~string] struct { //@rename("S", T, SToT) +- name string +- elements S +- elemData map[F][]ElemData[F] +- // other fields... +-} +- +-type ElemData[F ~string] struct { +- Name F +- // other fields... +-} +- +-type BuilderImpl[S ~[]F, F ~string] struct{ builder[S, F] } +- +--- importer/i.go -- +-package importer +- +-import "example.com/issue61635" // importing is necessary to repro golang/go#61635 +- +-var _ issue61635.ElemData[string] +- +--- @SToT/issue61635/p.go -- +-package issue61635 +- +-type builder[T ~[]F, F ~string] struct { //@rename("S", T, SToT) +- name string +- elements T +- elemData map[F][]ElemData[F] +- // other fields... +-} +- +-type ElemData[F ~string] struct { +- Name F +- // other fields... +-} +- +-type BuilderImpl[S ~[]F, F ~string] struct{ builder[S, F] } +- +--- instances/type.go -- +-package instances +- +-type R[P any] struct { //@rename("R", u, Rtou) +- Next *R[P] //@rename("R", s, RTos) +-} +- +-func (rv R[P]) Do(R[P]) R[P] { //@rename("Do", Do1, DoToDo1) +- var x R[P] +- return rv.Do(x) //@rename("Do", Do2, DoToDo2) +-} +- +-func _() { +- var x R[int] //@rename("R", r, RTor) +- x = x.Do(x) +-} +- +--- @RTos/instances/type.go -- +-package instances +- +-type s[P any] struct { //@rename("R", u, Rtou) +- Next *s[P] //@rename("R", s, RTos) +-} +- +-func (rv s[P]) Do(s[P]) s[P] { //@rename("Do", Do1, DoToDo1) +- var x s[P] +- return rv.Do(x) //@rename("Do", Do2, DoToDo2) +-} +- +-func _() { +- var x s[int] //@rename("R", r, RTor) +- x = x.Do(x) +-} +- +--- @Rtou/instances/type.go -- +-package instances +- +-type u[P any] struct { //@rename("R", u, Rtou) +- Next *u[P] //@rename("R", s, RTos) +-} +- +-func (rv u[P]) Do(u[P]) u[P] { //@rename("Do", Do1, DoToDo1) +- var x u[P] +- return rv.Do(x) //@rename("Do", Do2, DoToDo2) +-} +- +-func _() { +- var x u[int] //@rename("R", r, RTor) +- x = x.Do(x) +-} +- +--- @DoToDo1/instances/type.go -- +-package instances +- +-type R[P any] struct { //@rename("R", u, Rtou) +- Next *R[P] //@rename("R", s, RTos) +-} +- +-func (rv R[P]) Do1(R[P]) R[P] { //@rename("Do", Do1, DoToDo1) +- var x R[P] +- return rv.Do1(x) //@rename("Do", Do2, DoToDo2) +-} +- +-func _() { +- var x R[int] //@rename("R", r, RTor) +- x = x.Do1(x) +-} +- +--- @DoToDo2/instances/type.go -- +-package instances +- +-type R[P any] struct { //@rename("R", u, Rtou) +- Next *R[P] //@rename("R", s, RTos) +-} +- +-func (rv R[P]) Do2(R[P]) R[P] { //@rename("Do", Do1, DoToDo1) +- var x R[P] +- return rv.Do2(x) //@rename("Do", Do2, DoToDo2) +-} +- +-func _() { +- var x R[int] //@rename("R", r, RTor) +- x = x.Do2(x) +-} +- +--- instances/func.go -- +-package instances +- +-func Foo[P any](p P) { //@rename("Foo", Bar, FooToBar) +- Foo(p) //@rename("Foo", Baz, FooToBaz) +-} +- +--- @FooToBar/instances/func.go -- +-package instances +- +-func Bar[P any](p P) { //@rename("Foo", Bar, FooToBar) +- Bar(p) //@rename("Foo", Baz, FooToBaz) +-} +- +--- @FooToBaz/instances/func.go -- +-package instances +- +-func Baz[P any](p P) { //@rename("Foo", Bar, FooToBar) +- Baz(p) //@rename("Foo", Baz, FooToBaz) +-} +- +--- @RTor/instances/type.go -- +-package instances +- +-type r[P any] struct { //@rename("R", u, Rtou) +- Next *r[P] //@rename("R", s, RTos) +-} +- +-func (rv r[P]) Do(r[P]) r[P] { //@rename("Do", Do1, DoToDo1) +- var x r[P] +- return rv.Do(x) //@rename("Do", Do2, DoToDo2) +-} +- +-func _() { +- var x r[int] //@rename("R", r, RTor) +- x = x.Do(x) +-} +- +diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue60789.txt b/gopls/internal/regtest/marker/testdata/rename/issue60789.txt +--- a/gopls/internal/regtest/marker/testdata/rename/issue60789.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue60789.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,36 +0,0 @@ +- +-This test renames an exported method of an unexported type, +-which is an edge case for objectpath, since it computes a path +-from a syntax package that is no good when applied to an +-export data package. +- +-See issue #60789. +- +--- go.mod -- +-module example.com +-go 1.12 +- +--- a/a.go -- +-package a +- +-type unexported int +-func (unexported) F() {} //@rename("F", G, fToG) +- +-var _ = unexported(0).F +- +--- b/b.go -- +-package b +- +-// The existence of this package is sufficient to exercise +-// the bug even though it cannot reference a.unexported. +- +-import _ "example.com/a" +- +--- @fToG/a/a.go -- +-package a +- +-type unexported int +-func (unexported) G() {} //@rename("F", G, fToG) +- +-var _ = unexported(0).G +- +diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61294.txt b/gopls/internal/regtest/marker/testdata/rename/issue61294.txt +--- a/gopls/internal/regtest/marker/testdata/rename/issue61294.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue61294.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +- +-This test renames a parameter var whose name is the same as a +-package-level var, which revealed a bug in isLocal. +- +-This is a regression test for issue #61294. +- +--- go.mod -- +-module example.com +-go 1.18 +- +--- a/a.go -- +-package a +- +-func One() +- +-func Two(One int) //@rename("One", Three, OneToThree) +- +--- b/b.go -- +-package b +- +-import _ "example.com/a" +- +--- @OneToThree/a/a.go -- +-package a +- +-func One() +- +-func Two(Three int) //@rename("One", Three, OneToThree) +- +diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61640.txt b/gopls/internal/regtest/marker/testdata/rename/issue61640.txt +--- a/gopls/internal/regtest/marker/testdata/rename/issue61640.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue61640.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,47 +0,0 @@ +-This test verifies that gopls can rename instantiated fields. +- +--- flags -- +--min_go=go1.18 +- +--- a.go -- +-package a +- +-// This file is adapted from the example in the issue. +- +-type builder[S ~[]int] struct { +- elements S //@rename("elements", elements2, OneToTwo) +-} +- +-type BuilderImpl[S ~[]int] struct{ builder[S] } +- +-func NewBuilderImpl[S ~[]int](name string) *BuilderImpl[S] { +- impl := &BuilderImpl[S]{ +- builder[S]{ +- elements: S{}, +- }, +- } +- +- _ = impl.elements +- return impl +-} +--- @OneToTwo/a.go -- +-package a +- +-// This file is adapted from the example in the issue. +- +-type builder[S ~[]int] struct { +- elements2 S //@rename("elements", elements2, OneToTwo) +-} +- +-type BuilderImpl[S ~[]int] struct{ builder[S] } +- +-func NewBuilderImpl[S ~[]int](name string) *BuilderImpl[S] { +- impl := &BuilderImpl[S]{ +- builder[S]{ +- elements2: S{}, +- }, +- } +- +- _ = impl.elements2 +- return impl +-} +diff -urN a/gopls/internal/regtest/marker/testdata/rename/issue61813.txt b/gopls/internal/regtest/marker/testdata/rename/issue61813.txt +--- a/gopls/internal/regtest/marker/testdata/rename/issue61813.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/issue61813.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,18 +0,0 @@ +-This test exercises the panic reported in golang/go#61813. +- +--- p.go -- +-package p +- +-type P struct{} +- +-func (P) M() {} //@rename("M", N, MToN) +- +-var x = []*P{{}} +--- @MToN/p.go -- +-package p +- +-type P struct{} +- +-func (P) N() {} //@rename("M", N, MToN) +- +-var x = []*P{{}} diff -urN a/gopls/internal/regtest/marker/testdata/rename/methods.txt b/gopls/internal/regtest/marker/testdata/rename/methods.txt --- a/gopls/internal/regtest/marker/testdata/rename/methods.txt 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/marker/testdata/rename/methods.txt 1970-01-01 00:00:00.000000000 +0000 @@ -114214,6 +127017,35 @@ diff -urN a/gopls/internal/regtest/marker/testdata/rename/typeswitch.txt b/gopls - } -} - +diff -urN a/gopls/internal/regtest/marker/testdata/rename/unexported.txt b/gopls/internal/regtest/marker/testdata/rename/unexported.txt +--- a/gopls/internal/regtest/marker/testdata/rename/unexported.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/rename/unexported.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,25 +0,0 @@ +- +-This test attempts to rename a.S.X to x, which would make it +-inaccessible from its external test package. The rename tool +-should report an error rather than wrecking the program. +-See issue #59403. +- +--- go.mod -- +-module example.com +-go 1.12 +- +--- a/a.go -- +-package a +- +-var S struct{ X int } //@renameerr("X", x, oops) +- +--- a/a_test.go -- +-package a_test +- +-import "example.com/a" +- +-var Y = a.S.X +- +--- @oops -- +-a/a.go:3:15: renaming "X" to "x" would make it unexported +-a/a_test.go:5:13: breaking references from packages such as "example.com/a_test" diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt b/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt --- a/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt 1970-01-01 00:00:00.000000000 +0000 @@ -114229,19 +127061,573 @@ diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/basic.txt b/gopls - -type C int - --var _ error = C(0) //@suggestedfix(re"C.0.", re"missing method Error", "refactor.rewrite", stub) +-var _ error = C(0) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) - --- @stub/a/a.go -- -package a - -type C int - --// Error implements error +-// Error implements error. +-func (C) Error() string { +- panic("unimplemented") +-} +- +-var _ error = C(0) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) +diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt b/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt +--- a/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/stubmethods/issue61693.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,35 +0,0 @@ +-This test exercises stub methods functionality with variadic parameters. +- +-In golang/go#61693 stubmethods was panicking in this case. +- +--- go.mod -- +-module mod.com +- +-go 1.18 +--- main.go -- +-package main +- +-type C int +- +-func F(err ...error) {} +- +-func _() { +- var x error +- F(x, C(0)) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) +-} +--- @stub/main.go -- +-package main +- +-type C int +- +-// Error implements error. -func (C) Error() string { - panic("unimplemented") -} - --var _ error = C(0) //@suggestedfix(re"C.0.", re"missing method Error", "refactor.rewrite", stub) +-func F(err ...error) {} +- +-func _() { +- var x error +- F(x, C(0)) //@suggestedfix(re"C.0.", re"missing method Error", "quickfix", stub) +-} +diff -urN a/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt b/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt +--- a/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/stubmethods/issue61830.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,36 +0,0 @@ +-This test verifies that method stubbing qualifies types relative to the current +-package. +- +--- p.go -- +-package p +- +-import "io" +- +-type B struct{} +- +-type I interface { +- M(io.Reader, B) +-} +- +-type A struct{} +- +-var _ I = &A{} //@suggestedfix(re"&A..", re"missing method M", "quickfix", stub) +--- @stub/p.go -- +-package p +- +-import "io" +- +-type B struct{} +- +-type I interface { +- M(io.Reader, B) +-} +- +-type A struct{} +- +-// M implements I. +-func (*A) M(io.Reader, B) { +- panic("unimplemented") +-} +- +-var _ I = &A{} //@suggestedfix(re"&A..", re"missing method M", "quickfix", stub) +diff -urN a/gopls/internal/regtest/marker/testdata/symbol/basic.txt b/gopls/internal/regtest/marker/testdata/symbol/basic.txt +--- a/gopls/internal/regtest/marker/testdata/symbol/basic.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/symbol/basic.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,114 +0,0 @@ +-Basic tests of textDocument/documentSymbols. +- +--- symbol.go -- +-package main +- +-//@symbol(want) +- +-import "io" +- +-var _ = 1 +- +-var x = 42 +- +-var nested struct { +- nestedField struct { +- f int +- } +-} +- +-const y = 43 +- +-type Number int +- +-type Alias = string +- +-type NumberAlias = Number +- +-type ( +- Boolean bool +- BoolAlias = bool +-) +- +-type Foo struct { +- Quux +- W io.Writer +- Bar int +- baz string +- funcField func(int) int +-} +- +-type Quux struct { +- X, Y float64 +-} +- +-type EmptyStruct struct{} +- +-func (f Foo) Baz() string { +- return f.baz +-} +- +-func _() {} +- +-func (q *Quux) Do() {} +- +-func main() { +-} +- +-type Stringer interface { +- String() string +-} +- +-type ABer interface { +- B() +- A() string +-} +- +-type WithEmbeddeds interface { +- Do() +- ABer +- io.Writer +-} +- +-type EmptyInterface interface{} +- +-func Dunk() int { return 0 } +- +-func dunk() {} +- +--- @want -- +-(*Quux).Do "func()" +-(Foo).Baz "func() string" +2 lines +-ABer "interface{...}" +3 lines +-ABer.A "func() string" +-ABer.B "func()" +-Alias "string" +-BoolAlias "bool" +-Boolean "bool" +-Dunk "func() int" +-EmptyInterface "interface{}" +-EmptyStruct "struct{}" +-Foo "struct{...}" +6 lines +-Foo.Bar "int" +-Foo.Quux "Quux" +-Foo.W "io.Writer" +-Foo.baz "string" +-Foo.funcField "func(int) int" +-Number "int" +-NumberAlias "Number" +-Quux "struct{...}" +2 lines +-Quux.X "float64" +-Quux.Y "float64" +-Stringer "interface{...}" +2 lines +-Stringer.String "func() string" +-WithEmbeddeds "interface{...}" +4 lines +-WithEmbeddeds.ABer "ABer" +-WithEmbeddeds.Do "func()" +-WithEmbeddeds.Writer "io.Writer" +-dunk "func()" +-main "func()" +1 lines +-nested "struct{...}" +4 lines +-nested.nestedField "struct{...}" +2 lines +-nested.nestedField.f "int" +-x "" +-y "" +diff -urN a/gopls/internal/regtest/marker/testdata/symbol/generic.txt b/gopls/internal/regtest/marker/testdata/symbol/generic.txt +--- a/gopls/internal/regtest/marker/testdata/symbol/generic.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/symbol/generic.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-Basic tests of textDocument/documentSymbols with generics. +- +--- flags -- +--min_go=go1.18 +- +--- symbol.go -- +-//@symbol(want) +- +-//go:build go1.18 +-// +build go1.18 +- +-package main +- +-type T[P any] struct { +- F P +-} +- +-type Constraint interface { +- ~int | struct{ int } +- interface{ M() } +-} +- +--- @want -- +-Constraint "interface{...}" +3 lines +-Constraint.interface{...} "" +-Constraint.interface{...}.M "func()" +-Constraint.~int | struct{int} "" +-T "struct{...}" +2 lines +-T.F "P" +diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt +--- a/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/allscope.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,30 +0,0 @@ +-This test verifies behavior when "symbolScope" is set to "all". +- +--- settings.json -- +-{ +- "symbolStyle": "full", +- "symbolMatcher": "casesensitive", +- "symbolScope": "all" +-} +- +--- go.mod -- +-module mod.test/symbols +- +-go 1.18 +- +--- query.go -- +-package symbols +- +-//@workspacesymbol("fmt.Println", println) +- +--- fmt/fmt.go -- +-package fmt +- +-import "fmt" +- +-func Println(s string) { +- fmt.Println(s) +-} +--- @println -- +-fmt/fmt.go:5:6-13 mod.test/symbols/fmt.Println Function +-<unknown> fmt.Println Function +diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt +--- a/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/caseinsensitive.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,26 +0,0 @@ +-This file contains test for symbol matches using the caseinsensitive matcher. +- +--- settings.json -- +-{ +- "symbolMatcher": "caseinsensitive" +-} +- +--- go.mod -- +-module mod.test/caseinsensitive +- +-go 1.18 +- +--- p.go -- +-package caseinsensitive +- +-//@workspacesymbol("", blank) +-//@workspacesymbol("randomgophervar", randomgophervar) +- +-var RandomGopherVariableA int +-var randomgopherVariableB int +-var RandomGopherOtherVariable int +- +--- @blank -- +--- @randomgophervar -- +-p.go:6:5-26 RandomGopherVariableA Variable +-p.go:7:5-26 randomgopherVariableB Variable +diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt +--- a/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/casesensitive.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,116 +0,0 @@ +-This file contains tests for symbol matches using the casesensitive matcher. +- +-For historical reasons, it also verifies general behavior of the symbol search. +- +--- settings.json -- +-{ +- "symbolMatcher": "casesensitive" +-} +- +--- go.mod -- +-module mod.test/casesensitive +- +-go 1.18 +- +--- main.go -- +-package main +- +-//@workspacesymbol("main.main", main) +-//@workspacesymbol("p.Message", Message) +-//@workspacesymbol("main.myvar", myvar) +-//@workspacesymbol("main.myType", myType) +-//@workspacesymbol("main.myType.Blahblah", blahblah) +-//@workspacesymbol("main.myStruct", myStruct) +-//@workspacesymbol("main.myStruct.myStructField", myStructField) +-//@workspacesymbol("main.myInterface", myInterface) +-//@workspacesymbol("main.myInterface.DoSomeCoolStuff", DoSomeCoolStuff) +-//@workspacesymbol("main.embed.myStruct", embeddedStruct) +-//@workspacesymbol("main.embed.nestedStruct.nestedStruct2.int", int) +-//@workspacesymbol("main.embed.nestedInterface.myInterface", nestedInterface) +-//@workspacesymbol("main.embed.nestedInterface.nestedMethod", nestedMethod) +-//@workspacesymbol("dunk", dunk) +-//@workspacesymbol("Dunk", Dunk) +- +-import ( +- "encoding/json" +- "fmt" +-) +- +-func main() { // function +- fmt.Println("Hello") +-} +- +-var myvar int // variable +- +-type myType string // basic type +- +-type myDecoder json.Decoder // to use the encoding/json import +- +-func (m *myType) Blahblah() {} // method +- +-type myStruct struct { // struct type +- myStructField int // struct field +-} +- +-type myInterface interface { // interface +- DoSomeCoolStuff() string // interface method +-} +- +-type embed struct { +- myStruct +- +- nestedStruct struct { +- nestedField int +- +- nestedStruct2 struct { +- int +- } +- } +- +- nestedInterface interface { +- myInterface +- nestedMethod() +- } +-} +- +-func Dunk() int { return 0 } +- +-func dunk() {} +- +--- p/p.go -- +-package p +- +-const Message = "Hello World." // constant +--- @DoSomeCoolStuff -- +-main.go:41:2-17 main.myInterface.DoSomeCoolStuff Method +--- @Dunk -- +-main.go:61:6-10 Dunk Function +--- @Message -- +-p/p.go:3:7-14 p.Message Constant +--- @blahblah -- +-main.go:34:18-26 main.myType.Blahblah Method +--- @dunk -- +-main.go:63:6-10 dunk Function +--- @int -- +-main.go:51:4-7 main.embed.nestedStruct.nestedStruct2.int Field +--- @main -- +-main.go:24:6-10 main.main Function +--- @myInterface -- +-main.go:40:6-17 main.myInterface Interface +-main.go:41:2-17 main.myInterface.DoSomeCoolStuff Method +--- @myStruct -- +-main.go:36:6-14 main.myStruct Struct +-main.go:37:2-15 main.myStruct.myStructField Field +--- @myStructField -- +-main.go:37:2-15 main.myStruct.myStructField Field +--- @myType -- +-main.go:30:6-12 main.myType Class +-main.go:34:18-26 main.myType.Blahblah Method +--- @myvar -- +-main.go:28:5-10 main.myvar Variable +--- @nestedInterface -- +-main.go:56:3-14 main.embed.nestedInterface.myInterface Interface +--- @nestedMethod -- +-main.go:57:3-15 main.embed.nestedInterface.nestedMethod Method +--- @embeddedStruct -- +-main.go:45:2-10 main.embed.myStruct Field +diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt +--- a/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/issue44806.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,27 +0,0 @@ +-This test verifies the fix for the crash encountered in golang/go#44806. +- +--- go.mod -- +-module mod.test/symbol +- +-go 1.18 +--- symbol.go -- +-package symbol +- +-//@workspacesymbol("m", m) +- +-type T struct{} +- +-// We should accept all valid receiver syntax when scanning symbols. +-func (*(T)) m1() {} +-func (*T) m2() {} +-func (T) m3() {} +-func ((T)) m4() {} +-func ((*T)) m5() {} +- +--- @m -- +-symbol.go:8:13-15 T.m1 Method +-symbol.go:9:11-13 T.m2 Method +-symbol.go:10:10-12 T.m3 Method +-symbol.go:11:12-14 T.m4 Method +-symbol.go:12:13-15 T.m5 Method +-symbol.go:5:6-7 symbol.T Struct +diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt +--- a/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/workspacesymbol.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,72 +0,0 @@ +-This test contains tests for basic functionality of the workspace/symbol +-request. +- +-TODO(rfindley): add a test for the legacy 'fuzzy' symbol matcher using setting ("symbolMatcher": "fuzzy"). This test uses the default matcher ("fastFuzzy"). +- +--- go.mod -- +-module mod.test/symbols +- +-go 1.18 +- +--- query.go -- +-package symbols +- +-//@workspacesymbol("rgop", rgop) +-//@workspacesymbol("randoma", randoma) +-//@workspacesymbol("randomb", randomb) +- +--- a/a.go -- +-package a +- +-var RandomGopherVariableA = "a" +- +-const RandomGopherConstantA = "a" +- +-const ( +- randomgopherinvariable = iota +-) +- +--- a/a_test.go -- +-package a +- +-var RandomGopherTestVariableA = "a" +- +--- a/a_x_test.go -- +-package a_test +- +-var RandomGopherXTestVariableA = "a" +- +--- b/b.go -- +-package b +- +-var RandomGopherVariableB = "b" +- +-type RandomGopherStructB struct { +- Bar int +-} +- +--- @rgop -- +-b/b.go:5:6-25 RandomGopherStructB Struct +-a/a.go:5:7-28 RandomGopherConstantA Constant +-a/a.go:3:5-26 RandomGopherVariableA Variable +-b/b.go:3:5-26 RandomGopherVariableB Variable +-a/a_test.go:3:5-30 RandomGopherTestVariableA Variable +-a/a_x_test.go:3:5-31 RandomGopherXTestVariableA Variable +-a/a.go:8:2-24 randomgopherinvariable Constant +-b/b.go:6:2-5 RandomGopherStructB.Bar Field +--- @randoma -- +-a/a.go:5:7-28 RandomGopherConstantA Constant +-a/a.go:3:5-26 RandomGopherVariableA Variable +-b/b.go:3:5-26 RandomGopherVariableB Variable +-a/a.go:8:2-24 randomgopherinvariable Constant +-a/a_test.go:3:5-30 RandomGopherTestVariableA Variable +-a/a_x_test.go:3:5-31 RandomGopherXTestVariableA Variable +-b/b.go:6:2-5 RandomGopherStructB.Bar Field +--- @randomb -- +-b/b.go:5:6-25 RandomGopherStructB Struct +-a/a.go:3:5-26 RandomGopherVariableA Variable +-b/b.go:3:5-26 RandomGopherVariableB Variable +-a/a.go:8:2-24 randomgopherinvariable Constant +-a/a_test.go:3:5-30 RandomGopherTestVariableA Variable +-a/a_x_test.go:3:5-31 RandomGopherXTestVariableA Variable +-b/b.go:6:2-5 RandomGopherStructB.Bar Field +diff -urN a/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt b/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt +--- a/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/marker/testdata/workspacesymbol/wsscope.txt 1970-01-01 00:00:00.000000000 +0000 +@@ -1,29 +0,0 @@ +-This test verifies behavior when "symbolScope" is set to "workspace". +- +--- settings.json -- +-{ +- "symbolStyle": "full", +- "symbolMatcher": "casesensitive", +- "symbolScope": "workspace" +-} +- +--- go.mod -- +-module mod.test/symbols +- +-go 1.18 +- +--- query.go -- +-package symbols +- +-//@workspacesymbol("fmt.Println", println) +- +--- fmt/fmt.go -- +-package fmt +- +-import "fmt" +- +-func Println(s string) { +- fmt.Println(s) +-} +--- @println -- +-fmt/fmt.go:5:6-13 mod.test/symbols/fmt.Println Function diff -urN a/gopls/internal/regtest/misc/call_hierarchy_test.go b/gopls/internal/regtest/misc/call_hierarchy_test.go --- a/gopls/internal/regtest/misc/call_hierarchy_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/call_hierarchy_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -114284,7 +127670,7 @@ diff -urN a/gopls/internal/regtest/misc/call_hierarchy_test.go b/gopls/internal/ diff -urN a/gopls/internal/regtest/misc/configuration_test.go b/gopls/internal/regtest/misc/configuration_test.go --- a/gopls/internal/regtest/misc/configuration_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/configuration_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,159 +0,0 @@ +@@ -1,157 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -114344,9 +127730,7 @@ diff -urN a/gopls/internal/regtest/misc/configuration_test.go b/gopls/internal/r -// -// Gopls should not get confused about buffer content when recreating the view. -func TestMajorOptionsChange(t *testing.T) { -- t.Skip("broken due to golang/go#57934") -- -- testenv.NeedsGo1Point(t, 17) +- testenv.NeedsGo1Point(t, 19) // needs staticcheck - - const files = ` --- go.mod -- @@ -114497,7 +127881,7 @@ diff -urN a/gopls/internal/regtest/misc/debugserver_test.go b/gopls/internal/reg diff -urN a/gopls/internal/regtest/misc/definition_test.go b/gopls/internal/regtest/misc/definition_test.go --- a/gopls/internal/regtest/misc/definition_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/definition_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,512 +0,0 @@ +@@ -1,534 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -114871,6 +128255,28 @@ diff -urN a/gopls/internal/regtest/misc/definition_test.go b/gopls/internal/regt - } -} - +-func TestGoToTypeDefinition_Issue60544(t *testing.T) { +- const mod = ` +--- go.mod -- +-module mod.com +- +-go 1.19 +--- main.go -- +-package main +- +-func F[T comparable]() {} +-` +- +- Run(t, mod, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- +- _, err := env.Editor.GoToTypeDefinition(env.Ctx, env.RegexpSearch("main.go", "comparable")) // must not panic +- if err != nil { +- t.Fatal(err) +- } +- }) +-} +- -// Test for golang/go#47825. -func TestImportTestVariant(t *testing.T) { - const mod = ` @@ -114976,7 +128382,7 @@ diff -urN a/gopls/internal/regtest/misc/definition_test.go b/gopls/internal/regt - } - - // Run 'go mod vendor' outside the editor. -- if err := env.Sandbox.RunGoCommand(env.Ctx, ".", "mod", []string{"vendor"}, true); err != nil { +- if err := env.Sandbox.RunGoCommand(env.Ctx, ".", "mod", []string{"vendor"}, nil, true); err != nil { - t.Fatalf("go mod vendor: %v", err) - } - @@ -115126,7 +128532,7 @@ diff -urN a/gopls/internal/regtest/misc/extract_test.go b/gopls/internal/regtest diff -urN a/gopls/internal/regtest/misc/failures_test.go b/gopls/internal/regtest/misc/failures_test.go --- a/gopls/internal/regtest/misc/failures_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/failures_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,84 +0,0 @@ +@@ -1,82 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -115144,7 +128550,6 @@ diff -urN a/gopls/internal/regtest/misc/failures_test.go b/gopls/internal/regtes -// that includes a line directive, which makes no difference since -// gopls ignores line directives. -func TestHoverFailure(t *testing.T) { -- t.Skip("line directives //line ") - const mod = ` --- go.mod -- -module mod.com @@ -115177,7 +128582,6 @@ diff -urN a/gopls/internal/regtest/misc/failures_test.go b/gopls/internal/regtes -// This test demonstrates a case where gopls is not at all confused by -// line directives, because it completely ignores them. -func TestFailingDiagnosticClearingOnEdit(t *testing.T) { -- t.Skip("line directives //line ") - // badPackageDup contains a duplicate definition of the 'a' const. - // This is a minor variant of TestDiagnosticClearingOnEdit from - // diagnostics_test.go, with a line directive, which makes no difference. @@ -115321,7 +128725,7 @@ diff -urN a/gopls/internal/regtest/misc/fix_test.go b/gopls/internal/regtest/mis diff -urN a/gopls/internal/regtest/misc/formatting_test.go b/gopls/internal/regtest/misc/formatting_test.go --- a/gopls/internal/regtest/misc/formatting_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/formatting_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,368 +0,0 @@ +@@ -1,395 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -115690,6 +129094,33 @@ diff -urN a/gopls/internal/regtest/misc/formatting_test.go b/gopls/internal/regt - } - }) -} +- +-func TestGofumpt_Issue61692(t *testing.T) { +- testenv.NeedsGo1Point(t, 21) +- +- const input = ` +--- go.mod -- +-module foo +- +-go 1.21rc3 +--- foo.go -- +-package foo +- +-func _() { +- foo := +- "bar" +-} +-` +- +- WithOptions( +- Settings{ +- "gofumpt": true, +- }, +- ).Run(t, input, func(t *testing.T, env *Env) { +- env.OpenFile("foo.go") +- env.FormatBuffer("foo.go") // golang/go#61692: must not panic +- }) +-} diff -urN a/gopls/internal/regtest/misc/generate_test.go b/gopls/internal/regtest/misc/generate_test.go --- a/gopls/internal/regtest/misc/generate_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/generate_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -115926,7 +129357,7 @@ diff -urN a/gopls/internal/regtest/misc/highlight_test.go b/gopls/internal/regte diff -urN a/gopls/internal/regtest/misc/hover_test.go b/gopls/internal/regtest/misc/hover_test.go --- a/gopls/internal/regtest/misc/hover_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/hover_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,384 +0,0 @@ +@@ -1,437 +0,0 @@ -// Copyright 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -116013,12 +129444,6 @@ diff -urN a/gopls/internal/regtest/misc/hover_test.go b/gopls/internal/regtest/m -} - -func TestHoverIntLiteral(t *testing.T) { -- // TODO(rfindley): this behavior doesn't actually make sense for vars. It is -- // misleading to format their value when it is (of course) variable. -- // -- // Instead, we should allow hovering on numeric literals. -- t.Skip("golang/go#58220: broken due to new hover logic") -- - const source = ` --- main.go -- -package main @@ -116035,13 +129460,13 @@ diff -urN a/gopls/internal/regtest/misc/hover_test.go b/gopls/internal/regtest/m - Run(t, source, func(t *testing.T, env *Env) { - env.OpenFile("main.go") - hexExpected := "58190" -- got, _ := env.Hover(env.RegexpSearch("main.go", "hex")) +- got, _ := env.Hover(env.RegexpSearch("main.go", "0xe")) - if got != nil && !strings.Contains(got.Value, hexExpected) { - t.Errorf("Hover: missing expected field '%s'. Got:\n%q", hexExpected, got.Value) - } - - binExpected := "73" -- got, _ = env.Hover(env.RegexpSearch("main.go", "bigBin")) +- got, _ = env.Hover(env.RegexpSearch("main.go", "0b1")) - if got != nil && !strings.Contains(got.Value, binExpected) { - t.Errorf("Hover: missing expected field '%s'. Got:\n%q", binExpected, got.Value) - } @@ -116311,10 +129736,69 @@ diff -urN a/gopls/internal/regtest/misc/hover_test.go b/gopls/internal/regtest/m - }) - } -} +- +-const linknameHover = ` +--- go.mod -- +-module mod.com +- +--- upper/upper.go -- +-package upper +- +-import ( +- _ "unsafe" +- _ "mod.com/lower" +-) +- +-//go:linkname foo mod.com/lower.bar +-func foo() string +- +--- lower/lower.go -- +-package lower +- +-// bar does foo. +-func bar() string { +- return "foo by bar" +-}` +- +-func TestHoverLinknameDirective(t *testing.T) { +- Run(t, linknameHover, func(t *testing.T, env *Env) { +- // Jump from directives 2nd arg. +- env.OpenFile("upper/upper.go") +- from := env.RegexpSearch("upper/upper.go", `lower.bar`) +- +- hover, _ := env.Hover(from) +- content := hover.Value +- +- expect := "bar does foo" +- if !strings.Contains(content, expect) { +- t.Errorf("hover: %q does not contain: %q", content, expect) +- } +- }) +-} +- +-func TestHoverGoWork_Issue60821(t *testing.T) { +- const files = ` +--- go.work -- +-go 1.19 +- +-use ( +- moda +- modb +-) +--- moda/go.mod -- +- +-` +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.work") +- // Neither of the requests below should crash gopls. +- _, _, _ = env.Editor.Hover(env.Ctx, env.RegexpSearch("go.work", "moda")) +- _, _, _ = env.Editor.Hover(env.Ctx, env.RegexpSearch("go.work", "modb")) +- }) +-} diff -urN a/gopls/internal/regtest/misc/imports_test.go b/gopls/internal/regtest/misc/imports_test.go --- a/gopls/internal/regtest/misc/imports_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/imports_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,258 +0,0 @@ +@@ -1,287 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -116329,6 +129813,7 @@ diff -urN a/gopls/internal/regtest/misc/imports_test.go b/gopls/internal/regtest - "testing" - - . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" - - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/internal/testenv" @@ -116371,6 +129856,34 @@ diff -urN a/gopls/internal/regtest/misc/imports_test.go b/gopls/internal/regtest - }) -} - +-func TestIssue59124(t *testing.T) { +- const stuff = ` +--- go.mod -- +-module foo +-go 1.19 +--- a.go -- +-//line foo.y:102 +-package main +- +-import "fmt" +- +-//this comment is necessary for failure +-func a() { +- fmt.Println("hello") +-} +-` +- Run(t, stuff, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- was := env.BufferText("a.go") +- env.Await(NoDiagnostics()) +- env.OrganizeImports("a.go") +- is := env.BufferText("a.go") +- if diff := compare.Text(was, is); diff != "" { +- t.Errorf("unexpected diff after organizeImports:\n%s", diff) +- } +- }) +-} +- -func TestVim1(t *testing.T) { - const vim1 = `package main - @@ -116710,99 +130223,6 @@ diff -urN a/gopls/internal/regtest/misc/import_test.go b/gopls/internal/regtest/ - - }) -} -diff -urN a/gopls/internal/regtest/misc/leak_test.go b/gopls/internal/regtest/misc/leak_test.go ---- a/gopls/internal/regtest/misc/leak_test.go 2000-01-01 00:00:00.000000000 -0000 -+++ b/gopls/internal/regtest/misc/leak_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,89 +0,0 @@ --// Copyright 2022 The Go Authors. All rights reserved. --// Use of this source code is governed by a BSD-style --// license that can be found in the LICENSE file. -- --package misc -- --import ( -- "context" -- "testing" -- -- "github.com/google/go-cmp/cmp" -- "golang.org/x/tools/gopls/internal/hooks" -- "golang.org/x/tools/gopls/internal/lsp/cache" -- "golang.org/x/tools/gopls/internal/lsp/debug" -- "golang.org/x/tools/gopls/internal/lsp/fake" -- "golang.org/x/tools/gopls/internal/lsp/lsprpc" -- . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/jsonrpc2" -- "golang.org/x/tools/internal/jsonrpc2/servertest" --) -- --// Test for golang/go#57222. --func TestCacheLeak(t *testing.T) { -- // TODO(rfindley): either fix this test with additional instrumentation, or -- // delete it. -- t.Skip("This test races with cache eviction.") -- const files = `-- a.go -- --package a -- --func _() { -- println("1") --} --` -- c := cache.New(nil) -- env := setupEnv(t, files, c) -- env.Await(InitialWorkspaceLoad) -- env.OpenFile("a.go") -- -- // Make a couple edits to stabilize cache state. -- // -- // For some reason, after only one edit we're left with two parsed files -- // (perhaps because something had to ParseHeader). If this test proves flaky, -- // we'll need to investigate exactly what is causing various parse modes to -- // be present (or rewrite the test to be more tolerant, for example make ~100 -- // modifications and assert that we're within a few of where we're started). -- env.RegexpReplace("a.go", "1", "2") -- env.RegexpReplace("a.go", "2", "3") -- env.AfterChange() -- -- // Capture cache state, make an arbitrary change, and wait for gopls to do -- // its work. Afterward, we should have the exact same number of parsed -- before := c.MemStats() -- env.RegexpReplace("a.go", "3", "4") -- env.AfterChange() -- after := c.MemStats() -- -- if diff := cmp.Diff(before, after); diff != "" { -- t.Errorf("store objects differ after change (-before +after)\n%s", diff) -- } --} -- --// setupEnv creates a new sandbox environment for editing the txtar encoded --// content of files. It uses a new gopls instance backed by the Cache c. --func setupEnv(t *testing.T, files string, c *cache.Cache) *Env { -- ctx := debug.WithInstance(context.Background(), "", "off") -- server := lsprpc.NewStreamServer(c, false, hooks.Options) -- ts := servertest.NewPipeServer(server, jsonrpc2.NewRawStream) -- s, err := fake.NewSandbox(&fake.SandboxConfig{ -- Files: fake.UnpackTxt(files), -- }) -- if err != nil { -- t.Fatal(err) -- } -- -- a := NewAwaiter(s.Workdir) -- const skipApplyEdits = false -- editor, err := fake.NewEditor(s, fake.EditorConfig{}).Connect(ctx, ts, a.Hooks(), skipApplyEdits) -- if err != nil { -- t.Fatal(err) -- } -- -- return &Env{ -- T: t, -- Ctx: ctx, -- Editor: editor, -- Sandbox: s, -- Awaiter: a, -- } --} diff -urN a/gopls/internal/regtest/misc/link_test.go b/gopls/internal/regtest/misc/link_test.go --- a/gopls/internal/regtest/misc/link_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/link_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -116871,11 +130291,11 @@ diff -urN a/gopls/internal/regtest/misc/link_test.go b/gopls/internal/regtest/mi - t.Errorf("hover: got %v in go.mod, want contains %q", content, pkgLink) - } - links := env.DocumentLink("main.go") -- if len(links) != 1 || links[0].Target != pkgLink { +- if len(links) != 1 || *links[0].Target != pkgLink { - t.Errorf("documentLink: got links %+v for main.go, want one link with target %q", links, pkgLink) - } - links = env.DocumentLink("go.mod") -- if len(links) != 1 || links[0].Target != modLink { +- if len(links) != 1 || *links[0].Target != modLink { - t.Errorf("documentLink: got links %+v for go.mod, want one link with target %q", links, modLink) - } - @@ -116916,9 +130336,9 @@ diff -urN a/gopls/internal/regtest/misc/misc_test.go b/gopls/internal/regtest/mi -import ( - "testing" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/bug" -) - -func TestMain(m *testing.M) { @@ -116976,7 +130396,7 @@ diff -urN a/gopls/internal/regtest/misc/multiple_adhoc_test.go b/gopls/internal/ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regtest/misc/references_test.go --- a/gopls/internal/regtest/misc/references_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/references_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,399 +0,0 @@ +@@ -1,583 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -116986,13 +130406,17 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt -import ( - "fmt" - "os" +- "path/filepath" +- "reflect" - "sort" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/regtest" - . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/testenv" -) - -func TestStdlibReferences(t *testing.T) { @@ -117077,6 +130501,60 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt - }) -} - +-func TestDefsRefsBuiltins(t *testing.T) { +- testenv.NeedsGo1Point(t, 17) // for unsafe.{Add,Slice} +- // TODO(adonovan): add unsafe.{SliceData,String,StringData} in later go versions. +- const files = ` +--- go.mod -- +-module example.com +-go 1.16 +- +--- a.go -- +-package a +- +-import "unsafe" +- +-const _ = iota +-var _ error +-var _ int +-var _ = append() +-var _ = unsafe.Pointer(nil) +-var _ = unsafe.Add(nil, nil) +-var _ = unsafe.Sizeof(0) +-var _ = unsafe.Alignof(0) +-var _ = unsafe.Slice(nil, 0) +-` +- +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- for _, name := range strings.Fields( +- "iota error int nil append iota Pointer Sizeof Alignof Add Slice") { +- loc := env.RegexpSearch("a.go", `\b`+name+`\b`) +- +- // definition -> {builtin,unsafe}.go +- def, err := env.Editor.GoToDefinition(env.Ctx, loc) +- if err != nil { +- t.Errorf("definition(%q) failed: %v", name, err) +- } else if (!strings.HasSuffix(string(def.URI), "builtin.go") && +- !strings.HasSuffix(string(def.URI), "unsafe.go")) || +- def.Range.Start.Line == 0 { +- t.Errorf("definition(%q) = %v, want {builtin,unsafe}.go", +- name, def) +- } +- +- // "references to (builtin "Foo"|unsafe.Foo) are not supported" +- _, err = env.Editor.References(env.Ctx, loc) +- gotErr := fmt.Sprint(err) +- if !strings.Contains(gotErr, "references to") || +- !strings.Contains(gotErr, "not supported") || +- !strings.Contains(gotErr, name) { +- t.Errorf("references(%q) error: got %q, want %q", +- name, gotErr, "references to ... are not supported") +- } +- } +- }) +-} +- -func TestPackageReferences(t *testing.T) { - tests := []struct { - packageName string @@ -117229,16 +130707,6 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt - Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("foo/foo.go") - -- // Helper to map locations relative file paths. -- fileLocations := func(locs []protocol.Location) []string { -- var got []string -- for _, loc := range locs { -- got = append(got, env.Sandbox.Workdir.URIToPath(loc.URI)) -- } -- sort.Strings(got) -- return got -- } -- - refTests := []struct { - re string - wantRefs []string @@ -117248,18 +130716,18 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt - // - inside the foo.mod/bar [foo.mod/bar.test] test variant package - // - from the foo.mod/bar_test [foo.mod/bar.test] x_test package - // - from the foo.mod/foo package -- {"Blah", []string{"bar/bar.go", "bar/bar_test.go", "bar/bar_x_test.go", "foo/foo.go"}}, +- {"Blah", []string{"bar/bar.go:3", "bar/bar_test.go:7", "bar/bar_x_test.go:12", "foo/foo.go:12"}}, - - // Foo is referenced in bar_x_test.go via the intermediate test variant - // foo.mod/foo [foo.mod/bar.test]. -- {"Foo", []string{"bar/bar_x_test.go", "foo/foo.go"}}, +- {"Foo", []string{"bar/bar_x_test.go:13", "foo/foo.go:5"}}, - } - - for _, test := range refTests { - loc := env.RegexpSearch("foo/foo.go", test.re) - refs := env.References(loc) - -- got := fileLocations(refs) +- got := fileLocations(env, refs) - if diff := cmp.Diff(test.wantRefs, got); diff != "" { - t.Errorf("References(%q) returned unexpected diff (-want +got):\n%s", test.re, diff) - } @@ -117272,18 +130740,18 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt - // InterfaceM is implemented both in foo.mod/bar [foo.mod/bar.test] (which - // doesn't import foo), and in foo.mod/bar_test [foo.mod/bar.test], which - // imports the test variant of foo. -- {"InterfaceM", []string{"bar/bar_test.go", "bar/bar_x_test.go"}}, +- {"InterfaceM", []string{"bar/bar_test.go:3", "bar/bar_x_test.go:8"}}, - - // A search within the ordinary package to should find implementations - // (Fer) within the augmented test package. -- {"InterfaceF", []string{"foo/foo_test.go"}}, +- {"InterfaceF", []string{"foo/foo_test.go:3"}}, - } - - for _, test := range implTests { - loc := env.RegexpSearch("foo/foo.go", test.re) - impls := env.Implementations(loc) - -- got := fileLocations(impls) +- got := fileLocations(env, impls) - if diff := cmp.Diff(test.wantImpls, got); diff != "" { - t.Errorf("Implementations(%q) returned unexpected diff (-want +got):\n%s", test.re, diff) - } @@ -117350,7 +130818,7 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt - checkVendor(env.Implementations(refLoc), false) - - // Run 'go mod vendor' outside the editor. -- if err := env.Sandbox.RunGoCommand(env.Ctx, ".", "mod", []string{"vendor"}, true); err != nil { +- if err := env.Sandbox.RunGoCommand(env.Ctx, ".", "mod", []string{"vendor"}, nil, true); err != nil { - t.Fatalf("go mod vendor: %v", err) - } - @@ -117376,6 +130844,142 @@ diff -urN a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regt - checkVendor(env.Implementations(refLoc), false) - }) -} +- +-// This test can't be expressed as a marker test because the marker +-// test framework opens all files (which is a bit of a hack), creating +-// a <command-line-arguments> package for packages that otherwise +-// wouldn't be found from the go.work file. +-func TestReferencesFromWorkspacePackages59674(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // for go.work support +- const src = ` +--- a/go.mod -- +-module example.com/a +-go 1.12 +- +--- b/go.mod -- +-module example.com/b +-go 1.12 +- +--- c/go.mod -- +-module example.com/c +-go 1.12 +- +--- lib/go.mod -- +-module example.com/lib +-go 1.12 +- +--- go.work -- +-use ./a +-use ./b +-// don't use ./c +-use ./lib +- +--- a/a.go -- +-package a +- +-import "example.com/lib" +- +-var _ = lib.F // query here +- +--- b/b.go -- +-package b +- +-import "example.com/lib" +- +-var _ = lib.F // also found by references +- +--- c/c.go -- +-package c +- +-import "example.com/lib" +- +-var _ = lib.F // this reference should not be reported +- +--- lib/lib.go -- +-package lib +- +-func F() {} // declaration +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a/a.go") +- refLoc := env.RegexpSearch("a/a.go", "F") +- got := fileLocations(env, env.References(refLoc)) +- want := []string{"a/a.go:5", "b/b.go:5", "lib/lib.go:3"} +- if diff := cmp.Diff(want, got); diff != "" { +- t.Errorf("incorrect References (-want +got):\n%s", diff) +- } +- }) +-} +- +-// Test an 'implementation' query on a type that implements 'error'. +-// (Unfortunately builtin locations cannot be expressed using @loc +-// in the marker test framework.) +-func TestImplementationsOfError(t *testing.T) { +- const src = ` +--- go.mod -- +-module example.com +-go 1.12 +- +--- a.go -- +-package a +- +-type Error2 interface { +- Error() string +-} +- +-type MyError int +-func (MyError) Error() string { return "" } +- +-type MyErrorPtr int +-func (*MyErrorPtr) Error() string { return "" } +-` +- Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("a.go") +- +- for _, test := range []struct { +- re string +- want []string +- }{ +- // error type +- {"Error2", []string{"a.go:10", "a.go:7", "std:builtin/builtin.go"}}, +- {"MyError", []string{"a.go:3", "std:builtin/builtin.go"}}, +- {"MyErrorPtr", []string{"a.go:3", "std:builtin/builtin.go"}}, +- // error.Error method +- {"(Error).. string", []string{"a.go:11", "a.go:8", "std:builtin/builtin.go"}}, +- {"MyError. (Error)", []string{"a.go:4", "std:builtin/builtin.go"}}, +- {"MyErrorPtr. (Error)", []string{"a.go:4", "std:builtin/builtin.go"}}, +- } { +- matchLoc := env.RegexpSearch("a.go", test.re) +- impls := env.Implementations(matchLoc) +- got := fileLocations(env, impls) +- if !reflect.DeepEqual(got, test.want) { +- t.Errorf("Implementations(%q) = %q, want %q", +- test.re, got, test.want) +- } +- } +- }) +-} +- +-// fileLocations returns a new sorted array of the +-// relative file name and line number of each location. +-// Duplicates are not removed. +-// Standard library filenames are abstracted for robustness. +-func fileLocations(env *regtest.Env, locs []protocol.Location) []string { +- got := make([]string, 0, len(locs)) +- for _, loc := range locs { +- path := env.Sandbox.Workdir.URIToPath(loc.URI) // (slashified) +- if i := strings.LastIndex(path, "/src/"); i >= 0 && filepath.IsAbs(path) { +- // Absolute path with "src" segment: assume it's in GOROOT. +- // Strip directory and don't add line/column since they are fragile. +- path = "std:" + path[i+len("/src/"):] +- } else { +- path = fmt.Sprintf("%s:%d", path, loc.Range.Start.Line+1) +- } +- got = append(got, path) +- } +- sort.Strings(got) +- return got +-} diff -urN a/gopls/internal/regtest/misc/rename_test.go b/gopls/internal/regtest/misc/rename_test.go --- a/gopls/internal/regtest/misc/rename_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/rename_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -118825,7 +132429,7 @@ diff -urN a/gopls/internal/regtest/misc/staticcheck_test.go b/gopls/internal/reg diff -urN a/gopls/internal/regtest/misc/vendor_test.go b/gopls/internal/regtest/misc/vendor_test.go --- a/gopls/internal/regtest/misc/vendor_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/vendor_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,65 +0,0 @@ +@@ -1,103 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -118891,10 +132495,48 @@ diff -urN a/gopls/internal/regtest/misc/vendor_test.go b/gopls/internal/regtest/ - ) - }) -} +- +-func TestWindowsVendoring_Issue56291(t *testing.T) { +- const src = ` +--- go.mod -- +-module mod.com +- +-go 1.14 +- +-require golang.org/x/hello v1.2.3 +--- go.sum -- +-golang.org/x/hello v1.2.3 h1:EcMp5gSkIhaTkPXp8/3+VH+IFqTpk3ZbpOhqk0Ncmho= +-golang.org/x/hello v1.2.3/go.mod h1:WW7ER2MRNXWA6c8/4bDIek4Hc/+DofTrMaQQitGXcco= +--- main.go -- +-package main +- +-import "golang.org/x/hello/hi" +- +-func main() { +- _ = hi.Goodbye +-} +-` +- WithOptions( +- Modes(Default), +- ProxyFiles(basicProxy), +- ).Run(t, src, func(t *testing.T, env *Env) { +- env.OpenFile("main.go") +- env.AfterChange(NoDiagnostics()) +- env.RunGoCommand("mod", "tidy") +- env.RunGoCommand("mod", "vendor") +- env.AfterChange(NoDiagnostics()) +- env.RegexpReplace("main.go", `import "golang.org/x/hello/hi"`, "") +- env.AfterChange( +- Diagnostics(env.AtRegexp("main.go", "hi.Goodbye")), +- ) +- env.SaveBuffer("main.go") +- env.AfterChange(NoDiagnostics()) +- }) +-} diff -urN a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/misc/vuln_test.go --- a/gopls/internal/regtest/misc/vuln_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/vuln_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,977 +0,0 @@ +@@ -1,974 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -118913,6 +132555,7 @@ diff -urN a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/mi - "testing" - - "github.com/google/go-cmp/cmp" +- - "golang.org/x/tools/gopls/internal/govulncheck" - "golang.org/x/tools/gopls/internal/lsp/command" - "golang.org/x/tools/gopls/internal/lsp/protocol" @@ -119574,10 +133217,6 @@ diff -urN a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/mi - "Upgrade to latest", - "Reset govulncheck result", - }, -- relatedInfo: []vulnRelatedInfo{ -- {"x.go", uint32(lineX.Line), "[GO-2022-01]"}, // avuln.VulnData.Vuln1 -- {"x.go", uint32(lineX.Line), "[GO-2022-01]"}, // avuln.VulnData.Vuln2 -- }, - }, - }, - codeActions: []string{ @@ -119875,7 +133514,7 @@ diff -urN a/gopls/internal/regtest/misc/vuln_test.go b/gopls/internal/regtest/mi diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/internal/regtest/misc/workspace_symbol_test.go --- a/gopls/internal/regtest/misc/workspace_symbol_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/misc/workspace_symbol_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,124 +0,0 @@ +@@ -1,114 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -119885,7 +133524,7 @@ diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/interna -import ( - "testing" - -- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "github.com/google/go-cmp/cmp" - . "golang.org/x/tools/gopls/internal/lsp/regtest" - "golang.org/x/tools/gopls/internal/lsp/source" -) @@ -119899,7 +133538,7 @@ diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/interna --- a.go -- -package p - --const C1 = "a.go" +-const K1 = "a.go" --- exclude.go -- - -//go:build exclude @@ -119907,23 +133546,17 @@ diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/interna - -package exclude - --const C2 = "exclude.go" +-const K2 = "exclude.go" -` - - Run(t, files, func(t *testing.T, env *Env) { - env.OpenFile("a.go") -- syms := env.Symbol("C") -- if got, want := len(syms), 1; got != want { -- t.Errorf("got %d symbols, want %d", got, want) -- } +- checkSymbols(env, "K", "K1") - - // Opening up an ignored file will result in an overlay with missing - // metadata, but this shouldn't break workspace symbols requests. - env.OpenFile("exclude.go") -- syms = env.Symbol("C") -- if got, want := len(syms), 1; got != want { -- t.Errorf("got %d symbols, want %d", got, want) -- } +- checkSymbols(env, "K", "K1") - }) -} - @@ -119949,15 +133582,13 @@ diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/interna - WithOptions( - Settings{"symbolMatcher": symbolMatcher}, - ).Run(t, files, func(t *testing.T, env *Env) { -- want := []string{ +- checkSymbols(env, "Foo", - "Foo", // prefer exact segment matches first - "FooBar", // ...followed by exact word matches - "Fooex", // shorter than Fooest, FooBar, lexically before Fooey - "Fooey", // shorter than Fooest, Foobar - "Fooest", -- } -- got := env.Symbol("Foo") -- compareSymbols(t, got, want...) +- ) - }) -} - @@ -119980,30 +133611,28 @@ diff -urN a/gopls/internal/regtest/misc/workspace_symbol_test.go b/gopls/interna - WithOptions( - Settings{"symbolMatcher": symbolMatcher}, - ).Run(t, files, func(t *testing.T, env *Env) { -- compareSymbols(t, env.Symbol("ABC"), "ABC", "AxxBxxCxx") -- compareSymbols(t, env.Symbol("'ABC"), "ABC") -- compareSymbols(t, env.Symbol("^mod.com"), "mod.com/a.ABC", "mod.com/a.AxxBxxCxx") -- compareSymbols(t, env.Symbol("^mod.com Axx"), "mod.com/a.AxxBxxCxx") -- compareSymbols(t, env.Symbol("C$"), "ABC") +- checkSymbols(env, "ABC", "ABC", "AxxBxxCxx") +- checkSymbols(env, "'ABC", "ABC") +- checkSymbols(env, "^mod.com", "mod.com/a.ABC", "mod.com/a.AxxBxxCxx") +- checkSymbols(env, "^mod.com Axx", "mod.com/a.AxxBxxCxx") +- checkSymbols(env, "C$", "ABC") - }) -} - --func compareSymbols(t *testing.T, got []protocol.SymbolInformation, want ...string) { -- t.Helper() -- if len(got) != len(want) { -- t.Errorf("got %d symbols, want %d", len(got), len(want)) +-func checkSymbols(env *Env, query string, want ...string) { +- env.T.Helper() +- var got []string +- for _, info := range env.Symbol(query) { +- got = append(got, info.Name) - } -- -- for i := range got { -- if got[i].Name != want[i] { -- t.Errorf("got[%d] = %q, want %q", i, got[i].Name, want[i]) -- } +- if diff := cmp.Diff(got, want); diff != "" { +- env.T.Errorf("unexpected Symbol(%q) result (+want -got):\n%s", query, diff) - } -} diff -urN a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regtest/modfile/modfile_test.go --- a/gopls/internal/regtest/modfile/modfile_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/modfile/modfile_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1188 +0,0 @@ +@@ -1,1222 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -120016,10 +133645,10 @@ diff -urN a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regt - "strings" - "testing" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" - . "golang.org/x/tools/gopls/internal/lsp/regtest" - "golang.org/x/tools/gopls/internal/lsp/tests/compare" -- "golang.org/x/tools/internal/bug" - - "golang.org/x/tools/gopls/internal/lsp/protocol" - "golang.org/x/tools/internal/testenv" @@ -120342,48 +133971,6 @@ diff -urN a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regt - }) -} - --func TestUnusedDiag(t *testing.T) { -- -- const proxy = ` ---- example.com@v1.0.0/x.go -- --package pkg --const X = 1 --` -- const files = ` ---- a/go.mod -- --module mod.com --go 1.14 --require example.com v1.0.0 ---- a/go.sum -- --example.com v1.0.0 h1:38O7j5rEBajXk+Q5wzLbRN7KqMkSgEiN9NqcM1O2bBM= --example.com v1.0.0/go.mod h1:vUsPMGpx9ZXXzECCOsOmYCW7npJTwuA16yl89n3Mgls= ---- a/main.go -- --package main --func main() {} --` -- -- const want = `module mod.com -- --go 1.14 --` -- -- RunMultiple{ -- {"default", WithOptions(ProxyFiles(proxy), WorkspaceFolders("a"))}, -- {"nested", WithOptions(ProxyFiles(proxy))}, -- }.Run(t, files, func(t *testing.T, env *Env) { -- env.OpenFile("a/go.mod") -- var d protocol.PublishDiagnosticsParams -- env.AfterChange( -- Diagnostics(env.AtRegexp("a/go.mod", `require example.com`)), -- ReadDiagnostics("a/go.mod", &d), -- ) -- env.ApplyQuickFixes("a/go.mod", d.Diagnostics) -- if got := env.BufferText("a/go.mod"); got != want { -- t.Fatalf("unexpected go.mod content:\n%s", compare.Text(want, got)) -- } -- }) --} -- -// Test to reproduce golang/go#39041. It adds a new require to a go.mod file -// that already has an unused require. -func TestNewDepWithUnusedDep(t *testing.T) { @@ -120545,6 +134132,7 @@ diff -urN a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regt - Diagnostics(env.AtRegexp("a/go.mod", `require example.com/blah/v2`), WithMessage("cannot find module providing")), - ReadDiagnostics("a/go.mod", &modDiags), - ) +- - env.ApplyQuickFixes("a/go.mod", modDiags.Diagnostics) - const want = `module mod.com - @@ -121192,6 +134780,126 @@ diff -urN a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regt - env.SaveBuffer("go.work") // doesn't fail - }) -} +- +-func TestInconsistentMod(t *testing.T) { +- const proxy = ` +--- golang.org/x/mod@v0.7.0/go.mod -- +-go 1.20 +-module golang.org/x/mod +--- golang.org/x/mod@v0.7.0/a.go -- +-package mod +-func AutoQuote(string) string { return ""} +--- golang.org/x/mod@v0.9.0/go.mod -- +-go 1.20 +-module golang.org/x/mod +--- golang.org/x/mod@v0.9.0/a.go -- +-package mod +-func AutoQuote(string) string { return ""} +-` +- const files = ` +--- go.work -- +-go 1.20 +-use ( +- ./a +- ./b +-) +- +--- a/go.mod -- +-module a.mod.com +-go 1.20 +-require golang.org/x/mod v0.6.0 // yyy +-replace golang.org/x/mod v0.6.0 => golang.org/x/mod v0.7.0 +--- a/main.go -- +-package main +-import "golang.org/x/mod" +-import "fmt" +-func main() {fmt.Println(mod.AutoQuote(""))} +- +--- b/go.mod -- +-module b.mod.com +-go 1.20 +-require golang.org/x/mod v0.9.0 // xxx +--- b/main.go -- +-package aaa +-import "golang.org/x/mod" +-import "fmt" +-func main() {fmt.Println(mod.AutoQuote(""))} +-var A int +- +--- b/c/go.mod -- +-module c.b.mod.com +-go 1.20 +-require b.mod.com v0.4.2 +-replace b.mod.com => ../ +--- b/c/main.go -- +-package main +-import "b.mod.com/aaa" +-import "fmt" +-func main() {fmt.Println(aaa.A)} +-` +- testenv.NeedsGo1Point(t, 18) +- WithOptions( +- ProxyFiles(proxy), +- Modes(Default), +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("a/go.mod") +- ahints := env.InlayHints("a/go.mod") +- if len(ahints) != 1 { +- t.Errorf("expected exactly one hint, got %d: %#v", len(ahints), ahints) +- } +- env.OpenFile("b/c/go.mod") +- bhints := env.InlayHints("b/c/go.mod") +- if len(bhints) != 0 { +- t.Errorf("expected no hints, got %d: %#v", len(bhints), bhints) +- } +- }) +- +-} +diff -urN a/gopls/internal/regtest/modfile/tempmodfile_test.go b/gopls/internal/regtest/modfile/tempmodfile_test.go +--- a/gopls/internal/regtest/modfile/tempmodfile_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/modfile/tempmodfile_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,41 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package modfile +- +-import ( +- "testing" +- +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) +- +-// This test replaces an older, problematic test (golang/go#57784). But it has +-// been a long time since the go command would mutate go.mod files. +-// +-// TODO(golang/go#61970): the tempModfile setting should be removed entirely. +-func TestTempModfileUnchanged(t *testing.T) { +- // badMod has a go.mod file that is missing a go directive. +- const badMod = ` +--- go.mod -- +-module badmod.test/p +--- p.go -- +-package p +-` +- +- WithOptions( +- Modes(Default), // no reason to test this with a remote gopls +- ProxyFiles(workspaceProxy), +- Settings{ +- "tempModfile": true, +- }, +- ).Run(t, badMod, func(t *testing.T, env *Env) { +- env.OpenFile("p.go") +- env.AfterChange() +- want := "module badmod.test/p\n" +- got := env.ReadWorkspaceFile("go.mod") +- if got != want { +- t.Errorf("go.mod content:\n%s\nwant:\n%s", got, want) +- } +- }) +-} diff -urN a/gopls/internal/regtest/template/template_test.go b/gopls/internal/regtest/template/template_test.go --- a/gopls/internal/regtest/template/template_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/template/template_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -121206,10 +134914,10 @@ diff -urN a/gopls/internal/regtest/template/template_test.go b/gopls/internal/re - "strings" - "testing" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/lsp/protocol" - . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/bug" -) - -func TestMain(m *testing.M) { @@ -121427,10 +135135,99 @@ diff -urN a/gopls/internal/regtest/template/template_test.go b/gopls/internal/re -} - -// Hover needs tests +diff -urN a/gopls/internal/regtest/watch/setting_test.go b/gopls/internal/regtest/watch/setting_test.go +--- a/gopls/internal/regtest/watch/setting_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/watch/setting_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,85 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package regtest +- +-import ( +- "fmt" +- "testing" +- +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) +- +-func TestSubdirWatchPatterns(t *testing.T) { +- const files = ` +--- go.mod -- +-module mod.test +- +-go 1.18 +--- subdir/subdir.go -- +-package subdir +-` +- +- tests := []struct { +- clientName string +- subdirWatchPatterns string +- wantWatched bool +- }{ +- {"other client", "on", true}, +- {"other client", "off", false}, +- {"other client", "auto", false}, +- {"Visual Studio Code", "auto", true}, +- } +- +- for _, test := range tests { +- t.Run(fmt.Sprintf("%s_%s", test.clientName, test.subdirWatchPatterns), func(t *testing.T) { +- WithOptions( +- ClientName(test.clientName), +- Settings{ +- "subdirWatchPatterns": test.subdirWatchPatterns, +- }, +- ).Run(t, files, func(t *testing.T, env *Env) { +- var expectation Expectation +- if test.wantWatched { +- expectation = FileWatchMatching("subdir") +- } else { +- expectation = NoFileWatchMatching("subdir") +- } +- env.OnceMet( +- InitialWorkspaceLoad, +- expectation, +- ) +- }) +- }) +- } +-} +- +-// This test checks that we surface errors for invalid subdir watch patterns, +-// as the triple of ("off"|"on"|"auto") may be confusing to users inclined to +-// use (true|false) or some other truthy value. +-func TestSubdirWatchPatterns_BadValues(t *testing.T) { +- tests := []struct { +- badValue interface{} +- wantMessage string +- }{ +- {true, "invalid type bool, expect string"}, +- {false, "invalid type bool, expect string"}, +- {"yes", `invalid option "yes"`}, +- } +- +- for _, test := range tests { +- t.Run(fmt.Sprint(test.badValue), func(t *testing.T) { +- WithOptions( +- Settings{ +- "subdirWatchPatterns": test.badValue, +- }, +- ).Run(t, "", func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- ShownMessage(test.wantMessage), +- ) +- }) +- }) +- } +-} diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/watch/watch_test.go --- a/gopls/internal/regtest/watch/watch_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/watch/watch_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,702 +0,0 @@ +@@ -1,704 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -121440,9 +135237,9 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ -import ( - "testing" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" - . "golang.org/x/tools/gopls/internal/lsp/regtest" -- "golang.org/x/tools/internal/bug" - - "golang.org/x/tools/gopls/internal/lsp/fake" - "golang.org/x/tools/gopls/internal/lsp/protocol" @@ -121816,7 +135613,9 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ - ).Run(t, pkg, func(t *testing.T, env *Env) { - env.OpenFile("a/a.go") - env.OpenFile("a/a_unneeded.go") -- env.AfterChange( +- env.Await( +- // Log messages are asynchronous to other events on the LSP stream, so we +- // can't use OnceMet or AfterChange here. - LogMatching(protocol.Info, "a_unneeded.go", 1, false), - ) - @@ -121828,7 +135627,7 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ - Diagnostics(env.AtRegexp("a/a.go", "fmt")), - ) - env.SaveBuffer("a/a.go") -- env.AfterChange( +- env.Await( - // There should only be one log message containing - // a_unneeded.go, from the initial workspace load, which we - // check for earlier. If there are more, there's a bug. @@ -121844,7 +135643,7 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ - ).Run(t, pkg, func(t *testing.T, env *Env) { - env.OpenFile("a/a.go") - env.OpenFile("a/a_unneeded.go") -- env.AfterChange( +- env.Await( - LogMatching(protocol.Info, "a_unneeded.go", 1, false), - ) - @@ -121856,7 +135655,7 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ - Diagnostics(env.AtRegexp("a/a.go", "fmt")), - ) - env.SaveBuffer("a/a.go") -- env.AfterChange( +- env.Await( - // There should only be one log message containing - // a_unneeded.go, from the initial workspace load, which we - // check for earlier. If there are more, there's a bug. @@ -122010,7 +135809,7 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ - env.AfterChange( - NoDiagnostics(ForFile("main.go")), - ) -- if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}, true); err != nil { +- if err := env.Sandbox.RunGoCommand(env.Ctx, "", "mod", []string{"init", "mod.com"}, nil, true); err != nil { - t.Fatal(err) - } - @@ -122133,10 +135932,56 @@ diff -urN a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/ - ) - }) -} +diff -urN a/gopls/internal/regtest/workspace/adhoc_test.go b/gopls/internal/regtest/workspace/adhoc_test.go +--- a/gopls/internal/regtest/workspace/adhoc_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/workspace/adhoc_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,42 +0,0 @@ +-// Copyright 2022 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package workspace +- +-import ( +- "testing" +- +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +- "golang.org/x/tools/internal/testenv" +-) +- +-// Test for golang/go#57209: editing a file in an ad-hoc package should not +-// trigger conflicting diagnostics. +-func TestAdhoc_Edits(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) +- +- const files = ` +--- a.go -- +-package foo +- +-const X = 1 +- +--- b.go -- +-package foo +- +-// import "errors" +- +-const Y = X +-` +- +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("b.go") +- +- for i := 0; i < 10; i++ { +- env.RegexpReplace("b.go", `// import "errors"`, `import "errors"`) +- env.RegexpReplace("b.go", `import "errors"`, `// import "errors"`) +- env.AfterChange(NoDiagnostics()) +- } +- }) +-} diff -urN a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/regtest/workspace/broken_test.go --- a/gopls/internal/regtest/workspace/broken_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/workspace/broken_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,264 +0,0 @@ +@@ -1,263 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -122162,10 +136007,9 @@ diff -urN a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/reg - -// Test for golang/go#53933 -func TestBrokenWorkspace_DuplicateModules(t *testing.T) { -- testenv.NeedsGo1Point(t, 18) -- -- // TODO(golang/go#57650): fix this feature. -- t.Skip("we no longer detect duplicate modules") +- // The go command error message was improved in Go 1.20 to mention multiple +- // modules. +- testenv.NeedsGo1Point(t, 20) - - // This proxy module content is replaced by the workspace, but is still - // required for module resolution to function in the Go command. @@ -122237,8 +136081,8 @@ diff -urN a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/reg - ProxyFiles(proxy), - ).Run(t, src, func(t *testing.T, env *Env) { - env.OpenFile("package1/main.go") -- env.Await( -- OutstandingWork(lsp.WorkspaceLoadFailure, `found module "example.com/foo" multiple times in the workspace`), +- env.AfterChange( +- OutstandingWork(lsp.WorkspaceLoadFailure, `module example.com/foo appears multiple times in workspace`), - ) - - // Remove the redundant vendored copy of example.com. @@ -122249,10 +136093,10 @@ diff -urN a/gopls/internal/regtest/workspace/broken_test.go b/gopls/internal/reg - ./package2/vendor/example.com/foo - ) - `) -- env.Await(NoOutstandingWork()) +- env.AfterChange(NoOutstandingWork()) - - // Check that definitions in package1 go to the copy vendored in package2. -- location := env.GoToDefinition(env.RegexpSearch("package1/main.go", "CompleteMe")).URI.SpanURI().Filename() +- location := string(env.GoToDefinition(env.RegexpSearch("package1/main.go", "CompleteMe")).URI) - const wantLocation = "package2/vendor/example.com/foo/foo.go" - if !strings.HasSuffix(location, wantLocation) { - t.Errorf("got definition of CompleteMe at %q, want %q", location, wantLocation) @@ -122667,7 +136511,7 @@ diff -urN a/gopls/internal/regtest/workspace/directoryfilters_test.go b/gopls/in diff -urN a/gopls/internal/regtest/workspace/fromenv_test.go b/gopls/internal/regtest/workspace/fromenv_test.go --- a/gopls/internal/regtest/workspace/fromenv_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/workspace/fromenv_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,68 +0,0 @@ +@@ -1,79 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -122675,6 +136519,8 @@ diff -urN a/gopls/internal/regtest/workspace/fromenv_test.go b/gopls/internal/re -package workspace - -import ( +- "fmt" +- "path/filepath" - "testing" - - . "golang.org/x/tools/gopls/internal/lsp/regtest" @@ -122684,7 +136530,12 @@ diff -urN a/gopls/internal/regtest/workspace/fromenv_test.go b/gopls/internal/re -// Test that setting go.work via environment variables or settings works. -func TestUseGoWorkOutsideTheWorkspace(t *testing.T) { - testenv.NeedsGo1Point(t, 18) -- const files = ` +- +- // As discussed in +- // https://github.com/golang/go/issues/59458#issuecomment-1513794691, we must +- // use \-separated paths in go.work use directives for this test to work +- // correctly on windows. +- var files = fmt.Sprintf(` --- work/a/go.mod -- -module a.com - @@ -122711,15 +136562,19 @@ diff -urN a/gopls/internal/regtest/workspace/fromenv_test.go b/gopls/internal/re -go 1.18 - -use ( -- $SANDBOX_WORKDIR/work/a -- $SANDBOX_WORKDIR/work/b -- $SANDBOX_WORKDIR/other/c +- %s +- %s +- %s -) --` +-`, +- filepath.Join("$SANDBOX_WORKDIR", "work", "a"), +- filepath.Join("$SANDBOX_WORKDIR", "work", "b"), +- filepath.Join("$SANDBOX_WORKDIR", "other", "c"), +- ) - - WithOptions( - WorkspaceFolders("work"), // use a nested workspace dir, so that GOWORK is outside the workspace -- EnvVars{"GOWORK": "$SANDBOX_WORKDIR/config/go.work"}, +- EnvVars{"GOWORK": filepath.Join("$SANDBOX_WORKDIR", "config", "go.work")}, - ).Run(t, files, func(t *testing.T, env *Env) { - // When we have an explicit GOWORK set, we should get a file watch request. - env.OnceMet( @@ -122739,7 +136594,7 @@ diff -urN a/gopls/internal/regtest/workspace/fromenv_test.go b/gopls/internal/re diff -urN a/gopls/internal/regtest/workspace/metadata_test.go b/gopls/internal/regtest/workspace/metadata_test.go --- a/gopls/internal/regtest/workspace/metadata_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/workspace/metadata_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,181 +0,0 @@ +@@ -1,245 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -122801,16 +136656,7 @@ diff -urN a/gopls/internal/regtest/workspace/metadata_test.go b/gopls/internal/r -func main() {} - ` - -- WithOptions( -- // TODO(golang/go#54180): we don't run in 'experimental' mode here, because -- // with "experimentalUseInvalidMetadata", this test fails because the -- // orphaned bar.go is diagnosed using stale metadata, and then not -- // re-diagnosed when new metadata arrives. -- // -- // We could fix this by re-running diagnostics after a load, but should -- // consider whether that is worthwhile. -- Modes(Default), -- ).Run(t, src, func(t *testing.T, env *Env) { +- Run(t, src, func(t *testing.T, env *Env) { - env.OpenFile("foo.go") - env.OpenFile("bar.go") - env.OnceMet( @@ -122839,7 +136685,7 @@ diff -urN a/gopls/internal/regtest/workspace/metadata_test.go b/gopls/internal/r - // packages for bar.go - env.RegexpReplace("bar.go", "ignore", "excluded") - env.AfterChange( -- Diagnostics(env.AtRegexp("bar.go", "package (main)"), WithMessage("No packages")), +- Diagnostics(env.AtRegexp("bar.go", "package (main)"), WithMessage("not included in your workspace")), - ) - }) -} @@ -122921,6 +136767,79 @@ diff -urN a/gopls/internal/regtest/workspace/metadata_test.go b/gopls/internal/r - } - }) -} +- +-// Test for golang/go#59458. With lazy module loading, we may not need +-// transitively required modules. +-func TestNestedModuleLoading_Issue59458(t *testing.T) { +- testenv.NeedsGo1Point(t, 17) // needs lazy module loading +- +- // In this test, module b.com/nested requires b.com/other, which in turn +- // requires b.com, but b.com/nested does not reach b.com through the package +- // graph. Therefore, b.com/nested does not need b.com on 1.17 and later, +- // thanks to graph pruning. +- // +- // We verify that we can load b.com/nested successfully. Previously, we +- // couldn't, because loading the pattern b.com/nested/... matched the module +- // b.com, which exists in the module graph but does not have a go.sum entry. +- +- const proxy = ` +--- b.com@v1.2.3/go.mod -- +-module b.com +- +-go 1.18 +--- b.com@v1.2.3/b/b.go -- +-package b +- +-func Hello() {} +- +--- b.com/other@v1.4.6/go.mod -- +-module b.com/other +- +-go 1.18 +- +-require b.com v1.2.3 +--- b.com/other@v1.4.6/go.sun -- +-b.com v1.2.3 h1:AGjCxWRJLUuJiZ21IUTByr9buoa6+B6Qh5LFhVLKpn4= +--- b.com/other@v1.4.6/bar/bar.go -- +-package bar +- +-import "b.com/b" +- +-func _() { +- b.Hello() +-} +--- b.com/other@v1.4.6/foo/foo.go -- +-package foo +- +-const Foo = 0 +-` +- +- const files = ` +--- go.mod -- +-module b.com/nested +- +-go 1.18 +- +-require b.com/other v1.4.6 +--- go.sum -- +-b.com/other v1.4.6 h1:pHXSzGsk6DamYXp9uRdDB9A/ZQqAN9it+JudU0sBf94= +-b.com/other v1.4.6/go.mod h1:T0TYuGdAHw4p/l0+1P/yhhYHfZRia7PaadNVDu58OWM= +--- nested.go -- +-package nested +- +-import "b.com/other/foo" +- +-const C = foo.Foo +-` +- WithOptions( +- ProxyFiles(proxy), +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OnceMet( +- InitialWorkspaceLoad, +- NoDiagnostics(), +- ) +- }) +-} diff -urN a/gopls/internal/regtest/workspace/misspelling_test.go b/gopls/internal/regtest/workspace/misspelling_test.go --- a/gopls/internal/regtest/workspace/misspelling_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/workspace/misspelling_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -123005,10 +136924,356 @@ diff -urN a/gopls/internal/regtest/workspace/misspelling_test.go b/gopls/interna - env.AfterChange(NoDiagnostics()) - }) -} +diff -urN a/gopls/internal/regtest/workspace/quickfix_test.go b/gopls/internal/regtest/workspace/quickfix_test.go +--- a/gopls/internal/regtest/workspace/quickfix_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/regtest/workspace/quickfix_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,342 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-package workspace +- +-import ( +- "strings" +- "testing" +- +- "golang.org/x/tools/gopls/internal/lsp/protocol" +- "golang.org/x/tools/gopls/internal/lsp/tests/compare" +- "golang.org/x/tools/internal/testenv" +- +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) +- +-func TestQuickFix_UseModule(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // needs go.work +- +- const files = ` +--- go.work -- +-go 1.20 +- +-use ( +- ./a +-) +--- a/go.mod -- +-module mod.com/a +- +-go 1.18 +- +--- a/main.go -- +-package main +- +-import "mod.com/a/lib" +- +-func main() { +- _ = lib.C +-} +- +--- a/lib/lib.go -- +-package lib +- +-const C = "b" +--- b/go.mod -- +-module mod.com/b +- +-go 1.18 +- +--- b/main.go -- +-package main +- +-import "mod.com/b/lib" +- +-func main() { +- _ = lib.C +-} +- +--- b/lib/lib.go -- +-package lib +- +-const C = "b" +-` +- +- for _, title := range []string{ +- "Use this module", +- "Use all modules", +- } { +- t.Run(title, func(t *testing.T) { +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("b/main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange(ReadDiagnostics("b/main.go", &d)) +- fixes := env.GetQuickFixes("b/main.go", d.Diagnostics) +- var toApply []protocol.CodeAction +- for _, fix := range fixes { +- if strings.Contains(fix.Title, title) { +- toApply = append(toApply, fix) +- } +- } +- if len(toApply) != 1 { +- t.Fatalf("codeAction: got %d quick fixes matching %q, want 1; got: %v", len(toApply), title, toApply) +- } +- env.ApplyCodeAction(toApply[0]) +- env.AfterChange(NoDiagnostics()) +- want := `go 1.20 +- +-use ( +- ./a +- ./b +-) +-` +- got := env.ReadWorkspaceFile("go.work") +- if diff := compare.Text(want, got); diff != "" { +- t.Errorf("unexpeced go.work content:\n%s", diff) +- } +- }) +- }) +- } +-} +- +-func TestQuickFix_AddGoWork(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // needs go.work +- +- const files = ` +--- a/go.mod -- +-module mod.com/a +- +-go 1.18 +- +--- a/main.go -- +-package main +- +-import "mod.com/a/lib" +- +-func main() { +- _ = lib.C +-} +- +--- a/lib/lib.go -- +-package lib +- +-const C = "b" +--- b/go.mod -- +-module mod.com/b +- +-go 1.18 +- +--- b/main.go -- +-package main +- +-import "mod.com/b/lib" +- +-func main() { +- _ = lib.C +-} +- +--- b/lib/lib.go -- +-package lib +- +-const C = "b" +-` +- +- tests := []struct { +- name string +- file string +- title string +- want string // expected go.work content, excluding go directive line +- }{ +- { +- "use b", +- "b/main.go", +- "Add a go.work file using this module", +- ` +-use ./b +-`, +- }, +- { +- "use a", +- "a/main.go", +- "Add a go.work file using this module", +- ` +-use ./a +-`, +- }, +- { +- "use all", +- "a/main.go", +- "Add a go.work file using all modules", +- ` +-use ( +- ./a +- ./b +-) +-`, +- }, +- } +- +- for _, test := range tests { +- t.Run(test.name, func(t *testing.T) { +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile(test.file) +- var d protocol.PublishDiagnosticsParams +- env.AfterChange(ReadDiagnostics(test.file, &d)) +- fixes := env.GetQuickFixes(test.file, d.Diagnostics) +- var toApply []protocol.CodeAction +- for _, fix := range fixes { +- if strings.Contains(fix.Title, test.title) { +- toApply = append(toApply, fix) +- } +- } +- if len(toApply) != 1 { +- t.Fatalf("codeAction: got %d quick fixes matching %q, want 1; got: %v", len(toApply), test.title, toApply) +- } +- env.ApplyCodeAction(toApply[0]) +- env.AfterChange( +- NoDiagnostics(ForFile(test.file)), +- ) +- +- got := env.ReadWorkspaceFile("go.work") +- // Ignore the `go` directive, which we assume is on the first line of +- // the go.work file. This allows the test to be independent of go version. +- got = strings.Join(strings.Split(got, "\n")[1:], "\n") +- if diff := compare.Text(test.want, got); diff != "" { +- t.Errorf("unexpected go.work content:\n%s", diff) +- } +- }) +- }) +- } +-} +- +-func TestQuickFix_UnsavedGoWork(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // needs go.work +- +- const files = ` +--- go.work -- +-go 1.21 +- +-use ( +- ./a +-) +--- a/go.mod -- +-module mod.com/a +- +-go 1.18 +- +--- a/main.go -- +-package main +- +-func main() {} +--- b/go.mod -- +-module mod.com/b +- +-go 1.18 +- +--- b/main.go -- +-package main +- +-func main() {} +-` +- +- for _, title := range []string{ +- "Use this module", +- "Use all modules", +- } { +- t.Run(title, func(t *testing.T) { +- Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.work") +- env.OpenFile("b/main.go") +- env.RegexpReplace("go.work", "go 1.21", "go 1.21 // arbitrary comment") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange(ReadDiagnostics("b/main.go", &d)) +- fixes := env.GetQuickFixes("b/main.go", d.Diagnostics) +- var toApply []protocol.CodeAction +- for _, fix := range fixes { +- if strings.Contains(fix.Title, title) { +- toApply = append(toApply, fix) +- } +- } +- if len(toApply) != 1 { +- t.Fatalf("codeAction: got %d quick fixes matching %q, want 1; got: %v", len(toApply), title, toApply) +- } +- fix := toApply[0] +- err := env.Editor.ApplyCodeAction(env.Ctx, fix) +- if err == nil { +- t.Fatalf("codeAction(%q) succeeded unexpectedly", fix.Title) +- } +- +- if got := err.Error(); !strings.Contains(got, "must save") { +- t.Errorf("codeAction(%q) returned error %q, want containing \"must save\"", fix.Title, err) +- } +- }) +- }) +- } +-} +- +-func TestQuickFix_GOWORKOff(t *testing.T) { +- testenv.NeedsGo1Point(t, 18) // needs go.work +- +- const files = ` +--- go.work -- +-go 1.21 +- +-use ( +- ./a +-) +--- a/go.mod -- +-module mod.com/a +- +-go 1.18 +- +--- a/main.go -- +-package main +- +-func main() {} +--- b/go.mod -- +-module mod.com/b +- +-go 1.18 +- +--- b/main.go -- +-package main +- +-func main() {} +-` +- +- for _, title := range []string{ +- "Use this module", +- "Use all modules", +- } { +- t.Run(title, func(t *testing.T) { +- WithOptions( +- EnvVars{"GOWORK": "off"}, +- ).Run(t, files, func(t *testing.T, env *Env) { +- env.OpenFile("go.work") +- env.OpenFile("b/main.go") +- var d protocol.PublishDiagnosticsParams +- env.AfterChange(ReadDiagnostics("b/main.go", &d)) +- fixes := env.GetQuickFixes("b/main.go", d.Diagnostics) +- var toApply []protocol.CodeAction +- for _, fix := range fixes { +- if strings.Contains(fix.Title, title) { +- toApply = append(toApply, fix) +- } +- } +- if len(toApply) != 1 { +- t.Fatalf("codeAction: got %d quick fixes matching %q, want 1; got: %v", len(toApply), title, toApply) +- } +- fix := toApply[0] +- err := env.Editor.ApplyCodeAction(env.Ctx, fix) +- if err == nil { +- t.Fatalf("codeAction(%q) succeeded unexpectedly", fix.Title) +- } +- +- if got := err.Error(); !strings.Contains(got, "GOWORK=off") { +- t.Errorf("codeAction(%q) returned error %q, want containing \"GOWORK=off\"", fix.Title, err) +- } +- }) +- }) +- } +-} diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal/regtest/workspace/standalone_test.go --- a/gopls/internal/regtest/workspace/standalone_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/workspace/standalone_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,206 +0,0 @@ +@@ -1,211 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -123033,7 +137298,7 @@ diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal --- lib/lib.go -- -package lib - --const C = 0 +-const K = 0 - -type I interface { - M() @@ -123048,13 +137313,13 @@ diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal - "mod.test/lib" -) - --const C = 1 +-const K = 1 - -type Mer struct{} -func (Mer) M() - -func main() { -- println(lib.C + C) +- println(lib.K + K) -} -` - WithOptions( @@ -123064,13 +137329,18 @@ diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal - Modes(Default), - ).Run(t, files, func(t *testing.T, env *Env) { - // Initially, gopls should not know about the standalone file as it hasn't -- // been opened. Therefore, we should only find one symbol 'C'. -- syms := env.Symbol("C") +- // been opened. Therefore, we should only find one symbol 'K'. +- // +- // (The choice of "K" is a little sleazy: it was originally "C" until +- // we started adding "unsafe" to the workspace unconditionally, which +- // caused a spurious match of "unsafe.Slice". But in practice every +- // workspace depends on unsafe.) +- syms := env.Symbol("K") - if got, want := len(syms), 1; got != want { -- t.Errorf("got %d symbols, want %d", got, want) +- t.Errorf("got %d symbols, want %d (%+v)", got, want, syms) - } - -- // Similarly, we should only find one reference to "C", and no +- // Similarly, we should only find one reference to "K", and no - // implementations of I. - checkLocations := func(method string, gotLocations []protocol.Location, wantFiles ...string) { - var gotFiles []string @@ -123087,14 +137357,14 @@ diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal - env.OpenFile("lib/lib.go") - env.AfterChange(NoDiagnostics()) - -- // Replacing C with D should not cause any workspace diagnostics, since we +- // Replacing K with D should not cause any workspace diagnostics, since we - // haven't yet opened the standalone file. -- env.RegexpReplace("lib/lib.go", "C", "D") +- env.RegexpReplace("lib/lib.go", "K", "D") - env.AfterChange(NoDiagnostics()) -- env.RegexpReplace("lib/lib.go", "D", "C") +- env.RegexpReplace("lib/lib.go", "D", "K") - env.AfterChange(NoDiagnostics()) - -- refs := env.References(env.RegexpSearch("lib/lib.go", "C")) +- refs := env.References(env.RegexpSearch("lib/lib.go", "K")) - checkLocations("References", refs, "lib/lib.go") - - impls := env.Implementations(env.RegexpSearch("lib/lib.go", "I")) @@ -123106,56 +137376,56 @@ diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal - - // Having opened the standalone file, we should find its symbols in the - // workspace. -- syms = env.Symbol("C") +- syms = env.Symbol("K") - if got, want := len(syms), 2; got != want { - t.Fatalf("got %d symbols, want %d", got, want) - } - -- foundMainC := false +- foundMainK := false - var symNames []string - for _, sym := range syms { - symNames = append(symNames, sym.Name) -- if sym.Name == "main.C" { -- foundMainC = true +- if sym.Name == "main.K" { +- foundMainK = true - } - } -- if !foundMainC { -- t.Errorf("WorkspaceSymbol(\"C\") = %v, want containing main.C", symNames) +- if !foundMainK { +- t.Errorf("WorkspaceSymbol(\"K\") = %v, want containing main.K", symNames) - } - - // We should resolve workspace definitions in the standalone file. -- fileLoc := env.GoToDefinition(env.RegexpSearch("lib/ignore.go", "lib.(C)")) +- fileLoc := env.GoToDefinition(env.RegexpSearch("lib/ignore.go", "lib.(K)")) - file := env.Sandbox.Workdir.URIToPath(fileLoc.URI) - if got, want := file, "lib/lib.go"; got != want { -- t.Errorf("GoToDefinition(lib.C) = %v, want %v", got, want) +- t.Errorf("GoToDefinition(lib.K) = %v, want %v", got, want) - } - - // ...as well as intra-file definitions -- loc := env.GoToDefinition(env.RegexpSearch("lib/ignore.go", "\\+ (C)")) -- wantLoc := env.RegexpSearch("lib/ignore.go", "const (C)") +- loc := env.GoToDefinition(env.RegexpSearch("lib/ignore.go", "\\+ (K)")) +- wantLoc := env.RegexpSearch("lib/ignore.go", "const (K)") - if loc != wantLoc { -- t.Errorf("GoToDefinition(C) = %v, want %v", loc, wantLoc) +- t.Errorf("GoToDefinition(K) = %v, want %v", loc, wantLoc) - } - -- // Renaming "lib.C" to "lib.D" should cause a diagnostic in the standalone +- // Renaming "lib.K" to "lib.D" should cause a diagnostic in the standalone - // file. -- env.RegexpReplace("lib/lib.go", "C", "D") -- env.AfterChange(Diagnostics(env.AtRegexp("lib/ignore.go", "lib.(C)"))) +- env.RegexpReplace("lib/lib.go", "K", "D") +- env.AfterChange(Diagnostics(env.AtRegexp("lib/ignore.go", "lib.(K)"))) - - // Undoing the replacement should fix diagnostics -- env.RegexpReplace("lib/lib.go", "D", "C") +- env.RegexpReplace("lib/lib.go", "D", "K") - env.AfterChange(NoDiagnostics()) - - // Now that our workspace has no errors, we should be able to find - // references and rename. -- refs = env.References(env.RegexpSearch("lib/lib.go", "C")) +- refs = env.References(env.RegexpSearch("lib/lib.go", "K")) - checkLocations("References", refs, "lib/lib.go", "lib/ignore.go") - - impls = env.Implementations(env.RegexpSearch("lib/lib.go", "I")) - checkLocations("Implementations", impls, "lib/ignore.go") - - // Renaming should rename in the standalone package. -- env.Rename(env.RegexpSearch("lib/lib.go", "C"), "D") +- env.Rename(env.RegexpSearch("lib/lib.go", "K"), "D") - env.RegexpSearch("lib/ignore.go", "lib.D") - }) -} @@ -123218,7 +137488,7 @@ diff -urN a/gopls/internal/regtest/workspace/standalone_test.go b/gopls/internal diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/regtest/workspace/workspace_test.go --- a/gopls/internal/regtest/workspace/workspace_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/regtest/workspace/workspace_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,1263 +0,0 @@ +@@ -1,1258 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -123232,11 +137502,11 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ - "strings" - "testing" - +- "golang.org/x/tools/gopls/internal/bug" - "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/lsp" - "golang.org/x/tools/gopls/internal/lsp/fake" - "golang.org/x/tools/gopls/internal/lsp/protocol" -- "golang.org/x/tools/internal/bug" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/testenv" - @@ -123398,35 +137668,12 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ -replace random.org => %s -`, env.ReadWorkspaceFile("pkg/go.mod"), dir) - env.WriteWorkspaceFile("pkg/go.mod", goModWithReplace) -- env.AfterChange( +- env.Await( - LogMatching(protocol.Info, `packages\.Load #\d+\n`, 2, false), - ) - }) -} - --// This test checks that gopls updates the set of files it watches when a --// replace target is added to the go.mod. --func TestWatchReplaceTargets(t *testing.T) { -- t.Skipf("skipping known-flaky test: see https://go.dev/issue/50748") -- -- WithOptions( -- ProxyFiles(workspaceProxy), -- WorkspaceFolders("pkg"), -- ).Run(t, workspaceModule, func(t *testing.T, env *Env) { -- // Add a replace directive and expect the files that gopls is watching -- // to change. -- dir := env.Sandbox.Workdir.URI("goodbye").SpanURI().Filename() -- goModWithReplace := fmt.Sprintf(`%s --replace random.org => %s --`, env.ReadWorkspaceFile("pkg/go.mod"), dir) -- env.WriteWorkspaceFile("pkg/go.mod", goModWithReplace) -- env.AfterChange( -- UnregistrationMatching("didChangeWatchedFiles"), -- RegistrationMatching("didChangeWatchedFiles"), -- ) -- }) --} -- -const workspaceModuleProxy = ` --- example.com@v1.2.3/go.mod -- -module example.com @@ -123796,10 +138043,18 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ -` - WithOptions( - ProxyFiles(workspaceModuleProxy), +- Settings{ +- "subdirWatchPatterns": "on", +- }, - ).Run(t, multiModule, func(t *testing.T, env *Env) { -- // Initially, the go.work should cause only the a.com module to be -- // loaded. Validate this by jumping to a definition in b.com and ensuring -- // that we go to the module cache. +- // Initially, the go.work should cause only the a.com module to be loaded, +- // so we shouldn't get any file watches for modb. Further validate this by +- // jumping to a definition in b.com and ensuring that we go to the module +- // cache. +- env.OnceMet( +- InitialWorkspaceLoad, +- NoFileWatchMatching("modb"), +- ) - env.OpenFile("moda/a/a.go") - env.Await(env.DoneWithOpen()) - @@ -123831,9 +138086,13 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ -`) - - // As of golang/go#54069, writing go.work to the workspace triggers a -- // workspace reload. +- // workspace reload, and new file watches. - env.AfterChange( - Diagnostics(env.AtRegexp("modb/b/b.go", "x")), +- // TODO(golang/go#60340): we don't get a file watch yet, because +- // updateWatchedDirectories runs before snapshot.load. Instead, we get it +- // after the next change (the didOpen below). +- // FileWatchMatching("modb"), - ) - - // Jumping to definition should now go to b.com in the workspace. @@ -123844,7 +138103,13 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ - // Now, let's modify the go.work *overlay* (not on disk), and verify that - // this change is only picked up once it is saved. - env.OpenFile("go.work") -- env.AfterChange() +- env.AfterChange( +- // TODO(golang/go#60340): delete this expectation in favor of +- // the commented-out expectation above, once we fix the evaluation order +- // of file watches. We should not have to wait for a second change to get +- // the correct watches. +- FileWatchMatching("modb"), +- ) - env.SetBufferContent("go.work", `go 1.17 - -use ( @@ -123868,7 +138133,7 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ - } - - // This fails if guarded with a OnceMet(DoneWithSave(), ...), because it is -- // debounced (and therefore not synchronous with the change). +- // delayed (and therefore not synchronous with the change). - env.Await(NoDiagnostics(ForFile("modb/go.mod"))) - - // Test Formatting. @@ -124280,7 +138545,7 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ - // package declaration. - env.AfterChange( - NoDiagnostics(ForFile("main.go")), -- Diagnostics(AtPosition("b/main.go", 0, 0)), +- Diagnostics(env.AtRegexp("b/main.go", "package (main)")), - ) - env.WriteWorkspaceFile("go.work", `go 1.16 - @@ -124306,7 +138571,7 @@ diff -urN a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/ - - env.AfterChange( - NoDiagnostics(ForFile("main.go")), -- Diagnostics(AtPosition("b/main.go", 0, 0)), +- Diagnostics(env.AtRegexp("b/main.go", "package (main)")), - ) - }) -} @@ -124603,7 +138868,7 @@ diff -urN a/gopls/internal/span/parse.go b/gopls/internal/span/parse.go diff -urN a/gopls/internal/span/span.go b/gopls/internal/span/span.go --- a/gopls/internal/span/span.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/span/span.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,253 +0,0 @@ +@@ -1,249 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -124703,10 +138968,6 @@ diff -urN a/gopls/internal/span/span.go b/gopls/internal/span/span.go - return comparePoint(a.v.End, b.v.End) -} - --func ComparePoint(a, b Point) int { -- return comparePoint(a.v, b.v) --} -- -func comparePoint(a, b point) int { - if !a.hasPosition() { - if a.Offset < b.Offset { @@ -124921,7 +139182,7 @@ diff -urN a/gopls/internal/span/span_test.go b/gopls/internal/span/span_test.go diff -urN a/gopls/internal/span/uri.go b/gopls/internal/span/uri.go --- a/gopls/internal/span/uri.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/span/uri.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,185 +0,0 @@ +@@ -1,177 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -125099,14 +139360,6 @@ diff -urN a/gopls/internal/span/uri.go b/gopls/internal/span/uri.go - } - return uri[0] == '/' && unicode.IsLetter(rune(uri[1])) && uri[2] == ':' -} -- --// Dir returns the URI for the directory containing uri. Dir panics if uri is --// not a file uri. --// --// TODO(rfindley): add a unit test for various edge cases. --func Dir(uri URI) URI { -- return URIFromPath(filepath.Dir(uri.Filename())) --} diff -urN a/gopls/internal/span/uri_test.go b/gopls/internal/span/uri_test.go --- a/gopls/internal/span/uri_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/span/uri_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -125344,10 +139597,196 @@ diff -urN a/gopls/internal/span/uri_windows_test.go b/gopls/internal/span/uri_wi - } - } -} +diff -urN a/gopls/internal/telemetry/telemetry.go b/gopls/internal/telemetry/telemetry.go +--- a/gopls/internal/telemetry/telemetry.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/telemetry/telemetry.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,70 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.19 +-// +build go1.19 +- +-package telemetry +- +-import ( +- "fmt" +- +- "golang.org/x/telemetry/counter" +- "golang.org/x/telemetry/upload" +- "golang.org/x/tools/gopls/internal/lsp/protocol" +-) +- +-// Start starts telemetry instrumentation. +-func Start() { +- counter.Open() +- // upload only once at startup, hoping that users restart gopls often. +- go upload.Run(nil) +-} +- +-// RecordClientInfo records gopls client info. +-func RecordClientInfo(params *protocol.ParamInitialize) { +- client := "gopls/client:other" +- if params != nil && params.ClientInfo != nil { +- switch params.ClientInfo.Name { +- case "Visual Studio Code": +- client = "gopls/client:vscode" +- case "Visual Studio Code - Insiders": +- client = "gopls/client:vscode-insiders" +- case "VSCodium": +- client = "gopls/client:vscodium" +- case "code-server": +- // https://github.com/coder/code-server/blob/3cb92edc76ecc2cfa5809205897d93d4379b16a6/ci/build/build-vscode.sh#L19 +- client = "gopls/client:code-server" +- case "Eglot": +- // https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-03/msg00954.html +- client = "gopls/client:eglot" +- case "govim": +- // https://github.com/govim/govim/pull/1189 +- client = "gopls/client:govim" +- case "Neovim": +- // https://github.com/neovim/neovim/blob/42333ea98dfcd2994ee128a3467dfe68205154cd/runtime/lua/vim/lsp.lua#L1361 +- client = "gopls/client:neovim" +- case "coc.nvim": +- // https://github.com/neoclide/coc.nvim/blob/3dc6153a85ed0f185abec1deb972a66af3fbbfb4/src/language-client/client.ts#L994 +- client = "gopls/client:coc.nvim" +- case "Sublime Text LSP": +- // https://github.com/sublimelsp/LSP/blob/e608f878e7e9dd34aabe4ff0462540fadcd88fcc/plugin/core/sessions.py#L493 +- client = "gopls/client:sublimetext" +- default: +- // at least accumulate the client name locally +- counter.New(fmt.Sprintf("gopls/client-other:%s", params.ClientInfo.Name)).Inc() +- // but also record client:other +- } +- } +- counter.Inc(client) +-} +- +-// RecordViewGoVersion records the Go minor version number (1.x) used for a view. +-func RecordViewGoVersion(x int) { +- if x < 0 { +- return +- } +- name := fmt.Sprintf("gopls/goversion:1.%d", x) +- counter.Inc(name) +-} +diff -urN a/gopls/internal/telemetry/telemetry_go118.go b/gopls/internal/telemetry/telemetry_go118.go +--- a/gopls/internal/telemetry/telemetry_go118.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/telemetry/telemetry_go118.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,19 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build !go1.19 +-// +build !go1.19 +- +-package telemetry +- +-import "golang.org/x/tools/gopls/internal/lsp/protocol" +- +-func Start() { +-} +- +-func RecordClientInfo(params *protocol.ParamInitialize) { +-} +- +-func RecordViewGoVersion(x int) { +-} +diff -urN a/gopls/internal/telemetry/telemetry_test.go b/gopls/internal/telemetry/telemetry_test.go +--- a/gopls/internal/telemetry/telemetry_test.go 2000-01-01 00:00:00.000000000 -0000 ++++ b/gopls/internal/telemetry/telemetry_test.go 1970-01-01 00:00:00.000000000 +0000 +@@ -1,85 +0,0 @@ +-// Copyright 2023 The Go Authors. All rights reserved. +-// Use of this source code is governed by a BSD-style +-// license that can be found in the LICENSE file. +- +-//go:build go1.21 && !openbsd && !js && !wasip1 && !solaris && !android && !386 +-// +build go1.21,!openbsd,!js,!wasip1,!solaris,!android,!386 +- +-package telemetry_test +- +-import ( +- "os" +- "strconv" +- "strings" +- "testing" +- "time" +- +- "golang.org/x/telemetry/counter" +- "golang.org/x/telemetry/counter/countertest" // requires go1.21+ +- "golang.org/x/tools/gopls/internal/bug" +- "golang.org/x/tools/gopls/internal/hooks" +- . "golang.org/x/tools/gopls/internal/lsp/regtest" +-) +- +-func TestMain(m *testing.M) { +- tmp, err := os.MkdirTemp("", "gopls-telemetry-test") +- if err != nil { +- panic(err) +- } +- countertest.Open(tmp) +- defer os.RemoveAll(tmp) +- Main(m, hooks.Options) +-} +- +-func TestTelemetry(t *testing.T) { +- var ( +- goversion = "" +- editor = "vscode" // We set ClientName("Visual Studio Code") below. +- ) +- +- // Verify that a properly configured session gets notified of a bug on the +- // server. +- WithOptions( +- Modes(Default), // must be in-process to receive the bug report below +- Settings{"showBugReports": true}, +- ClientName("Visual Studio Code"), +- ).Run(t, "", func(t *testing.T, env *Env) { +- goversion = strconv.Itoa(env.GoVersion()) +- const desc = "got a bug" +- bug.Report(desc) // want a stack counter with the trace starting from here. +- env.Await(ShownMessage(desc)) +- }) +- +- // gopls/editor:client +- // gopls/goversion:1.x +- for _, c := range []*counter.Counter{ +- counter.New("gopls/client:" + editor), +- counter.New("gopls/goversion:1." + goversion), +- } { +- count, err := countertest.ReadCounter(c) +- if err != nil || count != 1 { +- t.Errorf("ReadCounter(%q) = (%v, %v), want (1, nil)", c.Name(), count, err) +- t.Logf("Current timestamp = %v", time.Now().UTC()) +- } +- } +- +- // gopls/bug +- bugcount := bug.BugReportCount +- counts, err := countertest.ReadStackCounter(bugcount) +- if err != nil { +- t.Fatalf("ReadStackCounter(bugreportcount) failed - %v", err) +- } +- if len(counts) != 1 || !hasEntry(counts, t.Name(), 1) { +- t.Errorf("read stackcounter(%q) = (%#v, %v), want one entry", "gopls/bug", counts, err) +- t.Logf("Current timestamp = %v", time.Now().UTC()) +- } +-} +- +-func hasEntry(counts map[string]uint64, pattern string, want uint64) bool { +- for k, v := range counts { +- if strings.Contains(k, pattern) && v == want { +- return true +- } +- } +- return false +-} diff -urN a/gopls/internal/vulncheck/command.go b/gopls/internal/vulncheck/command.go --- a/gopls/internal/vulncheck/command.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/internal/vulncheck/command.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,381 +0,0 @@ +@@ -1,337 +0,0 @@ -// Copyright 2022 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -125364,7 +139803,6 @@ diff -urN a/gopls/internal/vulncheck/command.go b/gopls/internal/vulncheck/comma - "fmt" - "log" - "os" -- "regexp" - "sort" - "strings" - "sync" @@ -125451,49 +139889,6 @@ diff -urN a/gopls/internal/vulncheck/command.go b/gopls/internal/vulncheck/comma - } -} - --var ( -- // Regexp for matching go tags. The groups are: -- // 1 the major.minor version -- // 2 the patch version, or empty if none -- // 3 the entire prerelease, if present -- // 4 the prerelease type ("beta" or "rc") -- // 5 the prerelease number -- tagRegexp = regexp.MustCompile(`^go(\d+\.\d+)(\.\d+|)((beta|rc|-pre)(\d+))?$`) --) -- --// This is a modified copy of pkgsite/internal/stdlib:VersionForTag. --func GoTagToSemver(tag string) string { -- if tag == "" { -- return "" -- } -- -- tag = strings.Fields(tag)[0] -- // Special cases for go1. -- if tag == "go1" { -- return "v1.0.0" -- } -- if tag == "go1.0" { -- return "" -- } -- m := tagRegexp.FindStringSubmatch(tag) -- if m == nil { -- return "" -- } -- version := "v" + m[1] -- if m[2] != "" { -- version += m[2] -- } else { -- version += ".0" -- } -- if m[3] != "" { -- if !strings.HasPrefix(m[4], "-") { -- version += "-" -- } -- version += m[4] + "." + m[5] -- } -- return version --} -- -// semverToGoTag returns the Go standard library repository tag corresponding -// to semver, a version string without the initial "v". -// Go tags differ from standard semantic versions in a few ways, @@ -125591,7 +139986,7 @@ diff -urN a/gopls/internal/vulncheck/command.go b/gopls/internal/vulncheck/comma - return nil, err - } - cli, err := client.NewClient( -- findGOVULNDB(snapshot.View().Options().EnvSlice()), +- findGOVULNDB(snapshot.Options().EnvSlice()), - client.Options{HTTPCache: govulncheck.NewInMemoryCache(fsCache)}) - if err != nil { - return nil, err @@ -125603,7 +139998,7 @@ diff -urN a/gopls/internal/vulncheck/command.go b/gopls/internal/vulncheck/comma - mu sync.Mutex - ) - -- goVersion := snapshot.View().Options().Env[GoVersionForVulnTest] +- goVersion := snapshot.Options().Env[GoVersionForVulnTest] - if goVersion == "" { - goVersion = snapshot.View().GoVersionString() - } @@ -126449,7 +140844,7 @@ diff -urN a/gopls/internal/vulncheck/vulntest/testdata/report.yaml b/gopls/inter diff -urN a/gopls/main.go b/gopls/main.go --- a/gopls/main.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/main.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,33 +0,0 @@ +@@ -1,30 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. @@ -126467,26 +140862,23 @@ diff -urN a/gopls/main.go b/gopls/main.go - -import ( - "context" -- "golang.org/x/tools/internal/analysisinternal" - "os" - - "golang.org/x/tools/gopls/internal/hooks" - "golang.org/x/tools/gopls/internal/lsp/cmd" +- "golang.org/x/tools/gopls/internal/telemetry" - "golang.org/x/tools/internal/tool" -) - -func main() { -- // In 1.18, diagnostics for Fuzz tests must not be used by cmd/vet. -- // So the code for Fuzz tests diagnostics is guarded behind flag analysisinternal.DiagnoseFuzzTests -- // Turn on analysisinternal.DiagnoseFuzzTests for gopls -- analysisinternal.DiagnoseFuzzTests = true +- telemetry.Start() - ctx := context.Background() - tool.Main(ctx, cmd.New("gopls", "", nil, hooks.Options), os.Args[1:]) -} diff -urN a/gopls/README.md b/gopls/README.md --- a/gopls/README.md 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/README.md 1970-01-01 00:00:00.000000000 +0000 -@@ -1,131 +0,0 @@ +@@ -1,132 +0,0 @@ -# `gopls`, the Go language server - -[![PkgGoDev](https://pkg.go.dev/badge/golang.org/x/tools/gopls)](https://pkg.go.dev/golang.org/x/tools/gopls) @@ -126582,6 +140974,7 @@ diff -urN a/gopls/README.md b/gopls/README.md -| ----------- | --------------------------------------------------- | -| Go 1.12 | [gopls@v0.7.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.7.5) | -| Go 1.15 | [gopls@v0.9.5](https://github.com/golang/tools/releases/tag/gopls%2Fv0.9.5) | +-| Go 1.17 | [gopls@v0.11.0](https://github.com/golang/tools/releases/tag/gopls%2Fv0.11.0) | - -Our extended support is enforced via [continuous integration with older Go -versions](doc/contributing.md#ci). This legacy Go CI may not block releases: @@ -126781,14 +141174,14 @@ diff -urN a/gopls/release/release.go b/gopls/release/release.go diff -urN a/gopls/test/debug/debug_test.go b/gopls/test/debug/debug_test.go --- a/gopls/test/debug/debug_test.go 2000-01-01 00:00:00.000000000 -0000 +++ b/gopls/test/debug/debug_test.go 1970-01-01 00:00:00.000000000 +0000 -@@ -1,141 +0,0 @@ +@@ -1,153 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package debug_test - --// Provide 'static type checking' of the templates. This guards against changes is various +-// Provide 'static type checking' of the templates. This guards against changes in various -// gopls datastructures causing template execution to fail. The checking is done by -// the github.com/jba/templatecheck package. Before that is run, the test checks that -// its list of templates and their arguments corresponds to the arguments in @@ -126797,6 +141190,7 @@ diff -urN a/gopls/test/debug/debug_test.go b/gopls/test/debug/debug_test.go -import ( - "go/ast" - "html/template" +- "os" - "runtime" - "sort" - "strings" @@ -126806,33 +141200,42 @@ diff -urN a/gopls/test/debug/debug_test.go b/gopls/test/debug/debug_test.go - "golang.org/x/tools/go/packages" - "golang.org/x/tools/gopls/internal/lsp/cache" - "golang.org/x/tools/gopls/internal/lsp/debug" +- "golang.org/x/tools/internal/testenv" -) - -var templates = map[string]struct { - tmpl *template.Template - data interface{} // a value of the needed type -}{ -- "MainTmpl": {debug.MainTmpl, &debug.Instance{}}, -- "DebugTmpl": {debug.DebugTmpl, nil}, -- "RPCTmpl": {debug.RPCTmpl, &debug.Rpcs{}}, -- "TraceTmpl": {debug.TraceTmpl, debug.TraceResults{}}, -- "CacheTmpl": {debug.CacheTmpl, &cache.Cache{}}, -- "SessionTmpl": {debug.SessionTmpl, &cache.Session{}}, -- "ViewTmpl": {debug.ViewTmpl, &cache.View{}}, -- "ClientTmpl": {debug.ClientTmpl, &debug.Client{}}, -- "ServerTmpl": {debug.ServerTmpl, &debug.Server{}}, -- "FileTmpl": {debug.FileTmpl, &cache.Overlay{}}, -- "InfoTmpl": {debug.InfoTmpl, "something"}, -- "MemoryTmpl": {debug.MemoryTmpl, runtime.MemStats{}}, +- "MainTmpl": {debug.MainTmpl, &debug.Instance{}}, +- "DebugTmpl": {debug.DebugTmpl, nil}, +- "RPCTmpl": {debug.RPCTmpl, &debug.Rpcs{}}, +- "TraceTmpl": {debug.TraceTmpl, debug.TraceResults{}}, +- "CacheTmpl": {debug.CacheTmpl, &cache.Cache{}}, +- "SessionTmpl": {debug.SessionTmpl, &cache.Session{}}, +- "ViewTmpl": {debug.ViewTmpl, &cache.View{}}, +- "ClientTmpl": {debug.ClientTmpl, &debug.Client{}}, +- "ServerTmpl": {debug.ServerTmpl, &debug.Server{}}, +- "FileTmpl": {debug.FileTmpl, &cache.Overlay{}}, +- "InfoTmpl": {debug.InfoTmpl, "something"}, +- "MemoryTmpl": {debug.MemoryTmpl, runtime.MemStats{}}, +- "AnalysisTmpl": {debug.AnalysisTmpl, new(debug.State).Analysis()}, -} - -func TestTemplates(t *testing.T) { -- if runtime.GOOS == "android" { -- t.Skip("this test is not supported for Android") -- } +- testenv.NeedsGoPackages(t) +- testenv.NeedsLocalXTools(t) +- - cfg := &packages.Config{ -- Mode: packages.NeedTypesInfo | packages.LoadAllSyntax, // figure out what's necessary PJW +- Mode: packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo, - } +- cfg.Env = os.Environ() +- cfg.Env = append(cfg.Env, +- "GOPACKAGESDRIVER=off", +- "GOWORK=off", // necessary for -mod=mod below +- "GOFLAGS=-mod=mod", +- ) +- - pkgs, err := packages.Load(cfg, "golang.org/x/tools/gopls/internal/lsp/debug") - if err != nil { - t.Fatal(err) @@ -126891,7 +141294,9 @@ diff -urN a/gopls/test/debug/debug_test.go b/gopls/test/debug/debug_test.go - // the FuncMap is an annoyance; should not be necessary - if err := templatecheck.CheckHTML(v.tmpl, v.data); err != nil { - t.Errorf("%s: %v", k, err) +- continue - } +- t.Logf("%s ok", k) - } -} - diff --git a/third_party/org_golang_x_tools-gazelle.patch b/third_party/org_golang_x_tools-gazelle.patch index 3cb5eb24db..56cd8d9ffd 100644 --- a/third_party/org_golang_x_tools-gazelle.patch +++ b/third_party/org_golang_x_tools-gazelle.patch @@ -175,6 +175,42 @@ diff -urN b/cmd/benchcmp/BUILD.bazel c/cmd/benchcmp/BUILD.bazel + embed = [":benchcmp_lib"], + deps = ["//benchmark/parse"], +) +diff -urN b/cmd/bisect/BUILD.bazel c/cmd/bisect/BUILD.bazel +--- b/cmd/bisect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/cmd/bisect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,32 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") ++ ++go_library( ++ name = "bisect_lib", ++ srcs = [ ++ "go119.go", ++ "go120.go", ++ "main.go", ++ "rand.go", ++ ], ++ importpath = "golang.org/x/tools/cmd/bisect", ++ visibility = ["//visibility:private"], ++ deps = ["//internal/bisect"], ++) ++ ++go_binary( ++ name = "bisect", ++ embed = [":bisect_lib"], ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "bisect_test", ++ srcs = ["main_test.go"], ++ data = glob(["testdata/**"]), ++ embed = [":bisect_lib"], ++ deps = [ ++ "//internal/bisect", ++ "//internal/diffp", ++ "//txtar", ++ ], ++) diff -urN b/cmd/bundle/BUILD.bazel c/cmd/bundle/BUILD.bazel --- b/cmd/bundle/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/bundle/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -244,7 +280,7 @@ diff -urN b/cmd/bundle/testdata/src/initial/BUILD.bazel c/cmd/bundle/testdata/sr diff -urN b/cmd/callgraph/BUILD.bazel c/cmd/callgraph/BUILD.bazel --- b/cmd/callgraph/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/callgraph/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,74 @@ +@@ -0,0 +1,73 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -260,7 +296,6 @@ diff -urN b/cmd/callgraph/BUILD.bazel c/cmd/callgraph/BUILD.bazel + "//go/callgraph/static", + "//go/callgraph/vta", + "//go/packages", -+ "//go/pointer", + "//go/ssa", + "//go/ssa/ssautil", + ], @@ -365,12 +400,16 @@ diff -urN b/cmd/compilebench/BUILD.bazel c/cmd/compilebench/BUILD.bazel diff -urN b/cmd/digraph/BUILD.bazel c/cmd/digraph/BUILD.bazel --- b/cmd/digraph/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/digraph/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,20 @@ +@@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( + name = "digraph_lib", -+ srcs = ["digraph.go"], ++ srcs = [ ++ "digraph.go", ++ "doc.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/cmd/digraph", + visibility = ["//visibility:private"], +) @@ -412,7 +451,7 @@ diff -urN b/cmd/eg/BUILD.bazel c/cmd/eg/BUILD.bazel diff -urN b/cmd/file2fuzz/BUILD.bazel c/cmd/file2fuzz/BUILD.bazel --- b/cmd/file2fuzz/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/file2fuzz/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,20 @@ +@@ -0,0 +1,21 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( @@ -432,6 +471,7 @@ diff -urN b/cmd/file2fuzz/BUILD.bazel c/cmd/file2fuzz/BUILD.bazel + name = "file2fuzz_test", + srcs = ["main_test.go"], + embed = [":file2fuzz_lib"], ++ deps = ["//internal/testenv"], +) diff -urN b/cmd/fiximports/BUILD.bazel c/cmd/fiximports/BUILD.bazel --- b/cmd/fiximports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 @@ -887,6 +927,40 @@ diff -urN b/cmd/gomvpkg/BUILD.bazel c/cmd/gomvpkg/BUILD.bazel + embed = [":gomvpkg_lib"], + visibility = ["//visibility:public"], +) +diff -urN b/cmd/gonew/BUILD.bazel c/cmd/gonew/BUILD.bazel +--- b/cmd/gonew/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/cmd/gonew/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,30 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") ++ ++go_library( ++ name = "gonew_lib", ++ srcs = ["main.go"], ++ importpath = "golang.org/x/tools/cmd/gonew", ++ visibility = ["//visibility:private"], ++ deps = [ ++ "//internal/edit", ++ "@org_golang_x_mod//modfile:go_default_library", ++ "@org_golang_x_mod//module:go_default_library", ++ ], ++) ++ ++go_binary( ++ name = "gonew", ++ embed = [":gonew_lib"], ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "gonew_test", ++ srcs = ["main_test.go"], ++ data = glob(["testdata/**"]), ++ embed = [":gonew_lib"], ++ deps = [ ++ "//internal/diffp", ++ "//txtar", ++ ], ++) diff -urN b/cmd/gorename/BUILD.bazel c/cmd/gorename/BUILD.bazel --- b/cmd/gorename/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/gorename/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -962,32 +1036,29 @@ diff -urN b/cmd/goyacc/testdata/expr/BUILD.bazel c/cmd/goyacc/testdata/expr/BUIL --- b/cmd/goyacc/testdata/expr/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/goyacc/testdata/expr/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") ++load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "expr_lib", + srcs = ["main.go"], + importpath = "golang.org/x/tools/cmd/goyacc/testdata/expr", -+ visibility = ["//visibility:private"], ++ visibility = ["//visibility:public"], +) + -+go_binary( -+ name = "expr", -+ embed = [":expr_lib"], ++alias( ++ name = "go_default_library", ++ actual = ":expr_lib", + visibility = ["//visibility:public"], +) diff -urN b/cmd/guru/BUILD.bazel c/cmd/guru/BUILD.bazel --- b/cmd/guru/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,56 @@ +@@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") + +go_library( + name = "guru_lib", + srcs = [ -+ "callees.go", -+ "callers.go", -+ "callstack.go", + "definition.go", + "describe.go", + "freevars.go", @@ -996,12 +1067,9 @@ diff -urN b/cmd/guru/BUILD.bazel c/cmd/guru/BUILD.bazel + "isAlias18.go", + "isAlias19.go", + "main.go", -+ "peers.go", -+ "pointsto.go", + "pos.go", + "referrers.go", + "what.go", -+ "whicherrs.go", + ], + importpath = "golang.org/x/tools/cmd/guru", + visibility = ["//visibility:private"], @@ -1009,12 +1077,7 @@ diff -urN b/cmd/guru/BUILD.bazel c/cmd/guru/BUILD.bazel + "//cmd/guru/serial", + "//go/ast/astutil", + "//go/buildutil", -+ "//go/callgraph", -+ "//go/callgraph/static", + "//go/loader", -+ "//go/pointer", -+ "//go/ssa", -+ "//go/ssa/ssautil", + "//go/types/typeutil", + "//imports", + "//refactor/importgraph", @@ -1072,42 +1135,6 @@ diff -urN b/cmd/guru/testdata/src/alias/BUILD.bazel c/cmd/guru/testdata/src/alia + actual = ":alias", + visibility = ["//visibility:public"], +) -diff -urN b/cmd/guru/testdata/src/calls/BUILD.bazel c/cmd/guru/testdata/src/calls/BUILD.bazel ---- b/cmd/guru/testdata/src/calls/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/calls/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "calls_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/calls", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "calls", -+ embed = [":calls_lib"], -+ visibility = ["//visibility:public"], -+) -diff -urN b/cmd/guru/testdata/src/calls-json/BUILD.bazel c/cmd/guru/testdata/src/calls-json/BUILD.bazel ---- b/cmd/guru/testdata/src/calls-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/calls-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "calls-json_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/calls-json", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "calls-json", -+ embed = [":calls-json_lib"], -+ visibility = ["//visibility:public"], -+) diff -urN b/cmd/guru/testdata/src/definition-json/BUILD.bazel c/cmd/guru/testdata/src/definition-json/BUILD.bazel --- b/cmd/guru/testdata/src/definition-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/definition-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -1327,78 +1354,6 @@ diff -urN b/cmd/guru/testdata/src/main/BUILD.bazel c/cmd/guru/testdata/src/main/ + embed = [":main_lib"], + visibility = ["//visibility:public"], +) -diff -urN b/cmd/guru/testdata/src/peers/BUILD.bazel c/cmd/guru/testdata/src/peers/BUILD.bazel ---- b/cmd/guru/testdata/src/peers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/peers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "peers_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/peers", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "peers", -+ embed = [":peers_lib"], -+ visibility = ["//visibility:public"], -+) -diff -urN b/cmd/guru/testdata/src/peers-json/BUILD.bazel c/cmd/guru/testdata/src/peers-json/BUILD.bazel ---- b/cmd/guru/testdata/src/peers-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/peers-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "peers-json_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/peers-json", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "peers-json", -+ embed = [":peers-json_lib"], -+ visibility = ["//visibility:public"], -+) -diff -urN b/cmd/guru/testdata/src/pointsto/BUILD.bazel c/cmd/guru/testdata/src/pointsto/BUILD.bazel ---- b/cmd/guru/testdata/src/pointsto/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/pointsto/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "pointsto_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/pointsto", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "pointsto", -+ embed = [":pointsto_lib"], -+ visibility = ["//visibility:public"], -+) -diff -urN b/cmd/guru/testdata/src/pointsto-json/BUILD.bazel c/cmd/guru/testdata/src/pointsto-json/BUILD.bazel ---- b/cmd/guru/testdata/src/pointsto-json/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/pointsto-json/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "pointsto-json_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/pointsto-json", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "pointsto-json", -+ embed = [":pointsto-json_lib"], -+ visibility = ["//visibility:public"], -+) diff -urN b/cmd/guru/testdata/src/referrers/BUILD.bazel c/cmd/guru/testdata/src/referrers/BUILD.bazel --- b/cmd/guru/testdata/src/referrers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/referrers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -1444,42 +1399,6 @@ diff -urN b/cmd/guru/testdata/src/referrers-json/BUILD.bazel c/cmd/guru/testdata + embed = [":referrers-json_lib"], + visibility = ["//visibility:public"], +) -diff -urN b/cmd/guru/testdata/src/reflection/BUILD.bazel c/cmd/guru/testdata/src/reflection/BUILD.bazel ---- b/cmd/guru/testdata/src/reflection/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/reflection/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "reflection_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/reflection", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "reflection", -+ embed = [":reflection_lib"], -+ visibility = ["//visibility:public"], -+) -diff -urN b/cmd/guru/testdata/src/softerrs/BUILD.bazel c/cmd/guru/testdata/src/softerrs/BUILD.bazel ---- b/cmd/guru/testdata/src/softerrs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/softerrs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "softerrs_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/softerrs", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "softerrs", -+ embed = [":softerrs_lib"], -+ visibility = ["//visibility:public"], -+) diff -urN b/cmd/guru/testdata/src/what/BUILD.bazel c/cmd/guru/testdata/src/what/BUILD.bazel --- b/cmd/guru/testdata/src/what/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/guru/testdata/src/what/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -1516,24 +1435,6 @@ diff -urN b/cmd/guru/testdata/src/what-json/BUILD.bazel c/cmd/guru/testdata/src/ + embed = [":what-json_lib"], + visibility = ["//visibility:public"], +) -diff -urN b/cmd/guru/testdata/src/whicherrs/BUILD.bazel c/cmd/guru/testdata/src/whicherrs/BUILD.bazel ---- b/cmd/guru/testdata/src/whicherrs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/cmd/guru/testdata/src/whicherrs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "whicherrs_lib", -+ srcs = ["main.go"], -+ importpath = "golang.org/x/tools/cmd/guru/testdata/src/whicherrs", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "whicherrs", -+ embed = [":whicherrs_lib"], -+ visibility = ["//visibility:public"], -+) diff -urN b/cmd/html2article/BUILD.bazel c/cmd/html2article/BUILD.bazel --- b/cmd/html2article/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/html2article/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -1559,7 +1460,7 @@ diff -urN b/cmd/html2article/BUILD.bazel c/cmd/html2article/BUILD.bazel diff -urN b/cmd/present/BUILD.bazel c/cmd/present/BUILD.bazel --- b/cmd/present/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/present/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,40 @@ +@@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( @@ -1576,8 +1477,11 @@ diff -urN b/cmd/present/BUILD.bazel c/cmd/present/BUILD.bazel + "static/dir.js", + "static/favicon.ico", + "static/jquery-ui.js", ++ "static/jquery.js", + "static/notes.css", + "static/notes.js", ++ "static/play.js", ++ "static/playground.js", + "static/slides.js", + "static/styles.css", + "templates/action.tmpl", @@ -1588,7 +1492,6 @@ diff -urN b/cmd/present/BUILD.bazel c/cmd/present/BUILD.bazel + importpath = "golang.org/x/tools/cmd/present", + visibility = ["//visibility:private"], + deps = [ -+ "//godoc/static", + "//playground", + "//playground/socket", + "//present", @@ -1728,7 +1631,7 @@ diff -urN b/cmd/signature-fuzzer/internal/fuzz-generator/BUILD.bazel c/cmd/signa diff -urN b/cmd/splitdwarf/BUILD.bazel c/cmd/splitdwarf/BUILD.bazel --- b/cmd/splitdwarf/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/splitdwarf/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,47 @@ +@@ -0,0 +1,44 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( @@ -1752,9 +1655,6 @@ diff -urN b/cmd/splitdwarf/BUILD.bazel c/cmd/splitdwarf/BUILD.bazel + "@io_bazel_rules_go//go/platform:freebsd": [ + "//cmd/splitdwarf/internal/macho", + ], -+ "@io_bazel_rules_go//go/platform:illumos": [ -+ "//cmd/splitdwarf/internal/macho", -+ ], + "@io_bazel_rules_go//go/platform:ios": [ + "//cmd/splitdwarf/internal/macho", + ], @@ -1835,7 +1735,7 @@ diff -urN b/cmd/ssadump/BUILD.bazel c/cmd/ssadump/BUILD.bazel diff -urN b/cmd/stress/BUILD.bazel c/cmd/stress/BUILD.bazel --- b/cmd/stress/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/cmd/stress/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,56 @@ +@@ -0,0 +1,53 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( @@ -1865,9 +1765,6 @@ diff -urN b/cmd/stress/BUILD.bazel c/cmd/stress/BUILD.bazel + "@io_bazel_rules_go//go/platform:ios": [ + "@org_golang_x_sys//execabs:go_default_library", + ], -+ "@io_bazel_rules_go//go/platform:js": [ -+ "@org_golang_x_sys//execabs:go_default_library", -+ ], + "@io_bazel_rules_go//go/platform:linux": [ + "@org_golang_x_sys//execabs:go_default_library", + ], @@ -2182,7 +2079,7 @@ diff -urN b/go/analysis/BUILD.bazel c/go/analysis/BUILD.bazel diff -urN b/go/analysis/internal/analysisflags/BUILD.bazel c/go/analysis/internal/analysisflags/BUILD.bazel --- b/go/analysis/internal/analysisflags/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/internal/analysisflags/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,27 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -2190,6 +2087,7 @@ diff -urN b/go/analysis/internal/analysisflags/BUILD.bazel c/go/analysis/interna + srcs = [ + "flags.go", + "help.go", ++ "url.go", + ], + importpath = "golang.org/x/tools/go/analysis/internal/analysisflags", + visibility = ["//go/analysis:__subpackages__"], @@ -2204,7 +2102,10 @@ diff -urN b/go/analysis/internal/analysisflags/BUILD.bazel c/go/analysis/interna + +go_test( + name = "analysisflags_test", -+ srcs = ["flags_test.go"], ++ srcs = [ ++ "flags_test.go", ++ "url_test.go", ++ ], + deps = [ + ":analysisflags", + "//go/analysis", @@ -2252,6 +2153,23 @@ diff -urN b/go/analysis/internal/checker/BUILD.bazel c/go/analysis/internal/chec + "//internal/testenv", + ], +) +diff -urN b/go/analysis/internal/versiontest/BUILD.bazel c/go/analysis/internal/versiontest/BUILD.bazel +--- b/go/analysis/internal/versiontest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/internal/versiontest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,13 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_test") ++ ++go_test( ++ name = "versiontest_test", ++ srcs = ["version_test.go"], ++ deps = [ ++ "//go/analysis", ++ "//go/analysis/analysistest", ++ "//go/analysis/multichecker", ++ "//go/analysis/singlechecker", ++ "//internal/testenv", ++ ], ++) diff -urN b/go/analysis/multichecker/BUILD.bazel c/go/analysis/multichecker/BUILD.bazel --- b/go/analysis/multichecker/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/multichecker/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -2355,12 +2273,16 @@ diff -urN b/go/analysis/passes/asmdecl/testdata/src/a/BUILD.bazel c/go/analysis/ diff -urN b/go/analysis/passes/assign/BUILD.bazel c/go/analysis/passes/assign/BUILD.bazel --- b/go/analysis/passes/assign/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/assign/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "assign", -+ srcs = ["assign.go"], ++ srcs = [ ++ "assign.go", ++ "doc.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/assign", + visibility = ["//visibility:public"], + deps = [ @@ -2425,12 +2347,16 @@ diff -urN b/go/analysis/passes/assign/testdata/src/typeparams/BUILD.bazel c/go/a diff -urN b/go/analysis/passes/atomic/BUILD.bazel c/go/analysis/passes/atomic/BUILD.bazel --- b/go/analysis/passes/atomic/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/atomic/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "atomic", -+ srcs = ["atomic.go"], ++ srcs = [ ++ "atomic.go", ++ "doc.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/atomic", + visibility = ["//visibility:public"], + deps = [ @@ -2783,12 +2709,16 @@ diff -urN b/go/analysis/passes/buildtag/testdata/src/a/BUILD.bazel c/go/analysis diff -urN b/go/analysis/passes/cgocall/BUILD.bazel c/go/analysis/passes/cgocall/BUILD.bazel --- b/go/analysis/passes/cgocall/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/cgocall/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,28 @@ +@@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "cgocall", -+ srcs = ["cgocall.go"], ++ srcs = [ ++ "cgocall.go", ++ "cgocall_go120.go", ++ "cgocall_go121.go", ++ ], + importpath = "golang.org/x/tools/go/analysis/passes/cgocall", + visibility = ["//visibility:public"], + deps = [ @@ -3024,7 +2954,7 @@ diff -urN b/go/analysis/passes/copylock/BUILD.bazel c/go/analysis/passes/copyloc diff -urN b/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel c/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel --- b/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ +@@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( @@ -3033,6 +2963,7 @@ diff -urN b/go/analysis/passes/copylock/testdata/src/a/BUILD.bazel c/go/analysis + "copylock.go", + "copylock_func.go", + "copylock_range.go", ++ "issue61678.go", + ], + importpath = "golang.org/x/tools/go/analysis/passes/copylock/testdata/src/a", + visibility = ["//visibility:public"], @@ -3153,7 +3084,7 @@ diff -urN b/go/analysis/passes/ctrlflow/testdata/src/typeparams/BUILD.bazel c/go diff -urN b/go/analysis/passes/deepequalerrors/BUILD.bazel c/go/analysis/passes/deepequalerrors/BUILD.bazel --- b/go/analysis/passes/deepequalerrors/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/deepequalerrors/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3164,6 +3095,7 @@ diff -urN b/go/analysis/passes/deepequalerrors/BUILD.bazel c/go/analysis/passes/ + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/types/typeutil", + ], @@ -3220,51 +3152,76 @@ diff -urN b/go/analysis/passes/deepequalerrors/testdata/src/typeparams/BUILD.baz + actual = ":typeparams", + visibility = ["//visibility:public"], +) -diff -urN b/go/analysis/passes/directive/BUILD.bazel c/go/analysis/passes/directive/BUILD.bazel ---- b/go/analysis/passes/directive/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/go/analysis/passes/directive/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,28 @@ +diff -urN b/go/analysis/passes/defers/BUILD.bazel c/go/analysis/passes/defers/BUILD.bazel +--- b/go/analysis/passes/defers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/defers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( -+ name = "directive", -+ srcs = ["directive.go"], -+ importpath = "golang.org/x/tools/go/analysis/passes/directive", ++ name = "defers", ++ srcs = [ ++ "defer.go", ++ "doc.go", ++ ], ++ embedsrcs = ["doc.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/defers", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", ++ "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/inspector", ++ "//go/types/typeutil", + ], +) + +alias( + name = "go_default_library", -+ actual = ":directive", ++ actual = ":defers", + visibility = ["//visibility:public"], +) + +go_test( -+ name = "directive_test", -+ srcs = ["directive_test.go"], ++ name = "defers_test", ++ srcs = ["defer_test.go"], + deps = [ -+ ":directive", -+ "//go/analysis", ++ ":defers", + "//go/analysis/analysistest", + ], +) -diff -urN b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel c/go/analysis/passes/directive/testdata/src/a/BUILD.bazel ---- b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/go/analysis/passes/directive/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,22 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") +diff -urN b/go/analysis/passes/defers/cmd/defers/BUILD.bazel c/go/analysis/passes/defers/cmd/defers/BUILD.bazel +--- b/go/analysis/passes/defers/cmd/defers/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/defers/cmd/defers/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,18 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( -+ name = "a", -+ srcs = [ -+ "misplaced.s", -+ "p.go", ++ name = "defers_lib", ++ srcs = ["main.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/defers/cmd/defers", ++ visibility = ["//visibility:private"], ++ deps = [ ++ "//go/analysis/passes/defers", ++ "//go/analysis/singlechecker", + ], -+ importpath = "golang.org/x/tools/go/analysis/passes/directive/testdata/src/a", ++) ++ ++go_binary( ++ name = "defers", ++ embed = [":defers_lib"], ++ visibility = ["//visibility:public"], ++) +diff -urN b/go/analysis/passes/defers/testdata/src/a/BUILD.bazel c/go/analysis/passes/defers/testdata/src/a/BUILD.bazel +--- b/go/analysis/passes/defers/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/defers/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "a", ++ srcs = ["a.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/defers/testdata/src/a", + visibility = ["//visibility:public"], +) + @@ -3273,15 +3230,68 @@ diff -urN b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel c/go/analysi + actual = ":a", + visibility = ["//visibility:public"], +) -+ -+go_test( -+ name = "a_test", -+ srcs = ["misplaced_test.go"], +diff -urN b/go/analysis/passes/directive/BUILD.bazel c/go/analysis/passes/directive/BUILD.bazel +--- b/go/analysis/passes/directive/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/directive/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,28 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "directive", ++ srcs = ["directive.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/directive", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "//go/analysis", ++ "//go/analysis/passes/internal/analysisutil", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":directive", ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "directive_test", ++ srcs = ["directive_test.go"], ++ deps = [ ++ ":directive", ++ "//go/analysis", ++ "//go/analysis/analysistest", ++ ], ++) +diff -urN b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel c/go/analysis/passes/directive/testdata/src/a/BUILD.bazel +--- b/go/analysis/passes/directive/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/directive/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,22 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "a", ++ srcs = [ ++ "misplaced.s", ++ "p.go", ++ ], ++ importpath = "golang.org/x/tools/go/analysis/passes/directive/testdata/src/a", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":a", ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "a_test", ++ srcs = ["misplaced_test.go"], +) diff -urN b/go/analysis/passes/errorsas/BUILD.bazel c/go/analysis/passes/errorsas/BUILD.bazel --- b/go/analysis/passes/errorsas/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/errorsas/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,31 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -3292,6 +3302,7 @@ diff -urN b/go/analysis/passes/errorsas/BUILD.bazel c/go/analysis/passes/errorsa + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/types/typeutil", + ], @@ -3620,20 +3631,23 @@ diff -urN b/go/analysis/passes/httpresponse/testdata/src/typeparams/BUILD.bazel diff -urN b/go/analysis/passes/ifaceassert/BUILD.bazel c/go/analysis/passes/ifaceassert/BUILD.bazel --- b/go/analysis/passes/ifaceassert/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/ifaceassert/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,33 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "ifaceassert", + srcs = [ ++ "doc.go", + "ifaceassert.go", + "parameterized.go", + ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/ifaceassert", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//internal/typeparams", + ], @@ -3737,12 +3751,15 @@ diff -urN b/go/analysis/passes/inspect/BUILD.bazel c/go/analysis/passes/inspect/ diff -urN b/go/analysis/passes/internal/analysisutil/BUILD.bazel c/go/analysis/passes/internal/analysisutil/BUILD.bazel --- b/go/analysis/passes/internal/analysisutil/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/internal/analysisutil/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,23 @@ +@@ -0,0 +1,29 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "analysisutil", -+ srcs = ["util.go"], ++ srcs = [ ++ "extractdoc.go", ++ "util.go", ++ ], + importpath = "golang.org/x/tools/go/analysis/passes/internal/analysisutil", + visibility = ["//go/analysis/passes:__subpackages__"], +) @@ -3755,7 +3772,10 @@ diff -urN b/go/analysis/passes/internal/analysisutil/BUILD.bazel c/go/analysis/p + +go_test( + name = "analysisutil_test", -+ srcs = ["util_test.go"], ++ srcs = [ ++ "extractdoc_test.go", ++ "util_test.go", ++ ], + deps = [ + ":analysisutil", + "//internal/typeparams", @@ -3764,17 +3784,22 @@ diff -urN b/go/analysis/passes/internal/analysisutil/BUILD.bazel c/go/analysis/p diff -urN b/go/analysis/passes/loopclosure/BUILD.bazel c/go/analysis/passes/loopclosure/BUILD.bazel --- b/go/analysis/passes/loopclosure/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/loopclosure/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "loopclosure", -+ srcs = ["loopclosure.go"], ++ srcs = [ ++ "doc.go", ++ "loopclosure.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/loopclosure", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/types/typeutil", + ], @@ -3875,18 +3900,23 @@ diff -urN b/go/analysis/passes/loopclosure/testdata/src/typeparams/BUILD.bazel c diff -urN b/go/analysis/passes/lostcancel/BUILD.bazel c/go/analysis/passes/lostcancel/BUILD.bazel --- b/go/analysis/passes/lostcancel/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/lostcancel/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,31 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "lostcancel", -+ srcs = ["lostcancel.go"], ++ srcs = [ ++ "doc.go", ++ "lostcancel.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/lostcancel", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/ctrlflow", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/cfg", + ], @@ -3986,17 +4016,22 @@ diff -urN b/go/analysis/passes/lostcancel/testdata/src/typeparams/BUILD.bazel c/ diff -urN b/go/analysis/passes/nilfunc/BUILD.bazel c/go/analysis/passes/nilfunc/BUILD.bazel --- b/go/analysis/passes/nilfunc/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilfunc/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "nilfunc", -+ srcs = ["nilfunc.go"], ++ srcs = [ ++ "doc.go", ++ "nilfunc.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/nilfunc", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//internal/typeparams", + ], @@ -4056,17 +4091,22 @@ diff -urN b/go/analysis/passes/nilfunc/testdata/src/typeparams/BUILD.bazel c/go/ diff -urN b/go/analysis/passes/nilness/BUILD.bazel c/go/analysis/passes/nilness/BUILD.bazel --- b/go/analysis/passes/nilness/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/nilness/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,33 @@ +@@ -0,0 +1,38 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "nilness", -+ srcs = ["nilness.go"], ++ srcs = [ ++ "doc.go", ++ "nilness.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/nilness", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/buildssa", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ssa", + "//internal/typeparams", + ], @@ -4269,15 +4309,17 @@ diff -urN b/go/analysis/passes/pkgfact/testdata/src/c/BUILD.bazel c/go/analysis/ diff -urN b/go/analysis/passes/printf/BUILD.bazel c/go/analysis/passes/printf/BUILD.bazel --- b/go/analysis/passes/printf/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/printf/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ +@@ -0,0 +1,37 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "printf", + srcs = [ ++ "doc.go", + "printf.go", + "types.go", + ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/printf", + visibility = ["//visibility:public"], + deps = [ @@ -4383,17 +4425,22 @@ diff -urN b/go/analysis/passes/printf/testdata/src/typeparams/BUILD.bazel c/go/a diff -urN b/go/analysis/passes/reflectvaluecompare/BUILD.bazel c/go/analysis/passes/reflectvaluecompare/BUILD.bazel --- b/go/analysis/passes/reflectvaluecompare/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/reflectvaluecompare/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "reflectvaluecompare", -+ srcs = ["reflectvaluecompare.go"], ++ srcs = [ ++ "doc.go", ++ "reflectvaluecompare.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/reflectvaluecompare", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/types/typeutil", + ], @@ -4434,17 +4481,22 @@ diff -urN b/go/analysis/passes/reflectvaluecompare/testdata/src/a/BUILD.bazel c/ diff -urN b/go/analysis/passes/shadow/BUILD.bazel c/go/analysis/passes/shadow/BUILD.bazel --- b/go/analysis/passes/shadow/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/shadow/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,28 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "shadow", -+ srcs = ["shadow.go"], ++ srcs = [ ++ "doc.go", ++ "shadow.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/shadow", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + ], +) @@ -4580,17 +4632,22 @@ diff -urN b/go/analysis/passes/shift/testdata/src/typeparams/BUILD.bazel c/go/an diff -urN b/go/analysis/passes/sigchanyzer/BUILD.bazel c/go/analysis/passes/sigchanyzer/BUILD.bazel --- b/go/analysis/passes/sigchanyzer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/sigchanyzer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,28 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "sigchanyzer", -+ srcs = ["sigchanyzer.go"], ++ srcs = [ ++ "doc.go", ++ "sigchanyzer.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/sigchanyzer", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + ], +) @@ -4627,10 +4684,85 @@ diff -urN b/go/analysis/passes/sigchanyzer/testdata/src/a/BUILD.bazel c/go/analy + actual = ":a", + visibility = ["//visibility:public"], +) +diff -urN b/go/analysis/passes/slog/BUILD.bazel c/go/analysis/passes/slog/BUILD.bazel +--- b/go/analysis/passes/slog/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/slog/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,35 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "slog", ++ srcs = [ ++ "doc.go", ++ "slog.go", ++ ], ++ embedsrcs = ["doc.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/slog", ++ visibility = ["//visibility:public"], ++ deps = [ ++ "//go/analysis", ++ "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", ++ "//go/ast/inspector", ++ "//go/types/typeutil", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":slog", ++ visibility = ["//visibility:public"], ++) ++ ++go_test( ++ name = "slog_test", ++ srcs = ["slog_test.go"], ++ embed = [":slog"], ++ deps = [ ++ "//go/analysis/analysistest", ++ "//internal/testenv", ++ ], ++) +diff -urN b/go/analysis/passes/slog/testdata/src/a/BUILD.bazel c/go/analysis/passes/slog/testdata/src/a/BUILD.bazel +--- b/go/analysis/passes/slog/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/slog/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "a", ++ srcs = ["a.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/slog/testdata/src/a", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":a", ++ visibility = ["//visibility:public"], ++) +diff -urN b/go/analysis/passes/slog/testdata/src/b/BUILD.bazel c/go/analysis/passes/slog/testdata/src/b/BUILD.bazel +--- b/go/analysis/passes/slog/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/slog/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "b", ++ srcs = ["b.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/slog/testdata/src/b", ++ visibility = ["//visibility:public"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":b", ++ visibility = ["//visibility:public"], ++) diff -urN b/go/analysis/passes/sortslice/BUILD.bazel c/go/analysis/passes/sortslice/BUILD.bazel --- b/go/analysis/passes/sortslice/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/sortslice/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,30 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -4641,6 +4773,7 @@ diff -urN b/go/analysis/passes/sortslice/BUILD.bazel c/go/analysis/passes/sortsl + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/types/typeutil", + ], @@ -4681,17 +4814,22 @@ diff -urN b/go/analysis/passes/sortslice/testdata/src/a/BUILD.bazel c/go/analysi diff -urN b/go/analysis/passes/stdmethods/BUILD.bazel c/go/analysis/passes/stdmethods/BUILD.bazel --- b/go/analysis/passes/stdmethods/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stdmethods/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "stdmethods", -+ srcs = ["stdmethods.go"], ++ srcs = [ ++ "doc.go", ++ "stdmethods.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/stdmethods", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + ], +) @@ -4753,17 +4891,22 @@ diff -urN b/go/analysis/passes/stdmethods/testdata/src/typeparams/BUILD.bazel c/ diff -urN b/go/analysis/passes/stringintconv/BUILD.bazel c/go/analysis/passes/stringintconv/BUILD.bazel --- b/go/analysis/passes/stringintconv/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/stringintconv/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "stringintconv", -+ srcs = ["string.go"], ++ srcs = [ ++ "doc.go", ++ "string.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/stringintconv", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//internal/typeparams", + ], @@ -4913,12 +5056,16 @@ diff -urN b/go/analysis/passes/structtag/testdata/src/a/BUILD.bazel c/go/analysi diff -urN b/go/analysis/passes/testinggoroutine/BUILD.bazel c/go/analysis/passes/testinggoroutine/BUILD.bazel --- b/go/analysis/passes/testinggoroutine/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/testinggoroutine/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,31 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "testinggoroutine", -+ srcs = ["testinggoroutine.go"], ++ srcs = [ ++ "doc.go", ++ "testinggoroutine.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/testinggoroutine", + visibility = ["//visibility:public"], + deps = [ @@ -4987,17 +5134,21 @@ diff -urN b/go/analysis/passes/testinggoroutine/testdata/src/typeparams/BUILD.ba diff -urN b/go/analysis/passes/tests/BUILD.bazel c/go/analysis/passes/tests/BUILD.bazel --- b/go/analysis/passes/tests/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/tests/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "tests", -+ srcs = ["tests.go"], ++ srcs = [ ++ "doc.go", ++ "tests.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/tests", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", -+ "//internal/analysisinternal", ++ "//go/analysis/passes/internal/analysisutil", + "//internal/typeparams", + ], +) @@ -5014,7 +5165,6 @@ diff -urN b/go/analysis/passes/tests/BUILD.bazel c/go/analysis/passes/tests/BUIL + deps = [ + ":tests", + "//go/analysis/analysistest", -+ "//internal/analysisinternal", + "//internal/typeparams", + ], +) @@ -5125,17 +5275,22 @@ diff -urN b/go/analysis/passes/tests/testdata/src/typeparams/BUILD.bazel c/go/an diff -urN b/go/analysis/passes/timeformat/BUILD.bazel c/go/analysis/passes/timeformat/BUILD.bazel --- b/go/analysis/passes/timeformat/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/timeformat/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "timeformat", -+ srcs = ["timeformat.go"], ++ srcs = [ ++ "doc.go", ++ "timeformat.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/timeformat", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/types/typeutil", + ], @@ -5194,17 +5349,22 @@ diff -urN b/go/analysis/passes/timeformat/testdata/src/b/BUILD.bazel c/go/analys diff -urN b/go/analysis/passes/unmarshal/BUILD.bazel c/go/analysis/passes/unmarshal/BUILD.bazel --- b/go/analysis/passes/unmarshal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unmarshal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,31 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "unmarshal", -+ srcs = ["unmarshal.go"], ++ srcs = [ ++ "doc.go", ++ "unmarshal.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/unmarshal", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//go/types/typeutil", + "//internal/typeparams", @@ -5287,17 +5447,22 @@ diff -urN b/go/analysis/passes/unmarshal/testdata/src/typeparams/BUILD.bazel c/g diff -urN b/go/analysis/passes/unreachable/BUILD.bazel c/go/analysis/passes/unreachable/BUILD.bazel --- b/go/analysis/passes/unreachable/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unreachable/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,28 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "unreachable", -+ srcs = ["unreachable.go"], ++ srcs = [ ++ "doc.go", ++ "unreachable.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/unreachable", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + ], +) @@ -5337,12 +5502,16 @@ diff -urN b/go/analysis/passes/unreachable/testdata/src/a/BUILD.bazel c/go/analy diff -urN b/go/analysis/passes/unsafeptr/BUILD.bazel c/go/analysis/passes/unsafeptr/BUILD.bazel --- b/go/analysis/passes/unsafeptr/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unsafeptr/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,34 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "unsafeptr", -+ srcs = ["unsafeptr.go"], ++ srcs = [ ++ "doc.go", ++ "unsafeptr.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/unsafeptr", + visibility = ["//visibility:public"], + deps = [ @@ -5410,12 +5579,16 @@ diff -urN b/go/analysis/passes/unsafeptr/testdata/src/typeparams/BUILD.bazel c/g diff -urN b/go/analysis/passes/unusedresult/BUILD.bazel c/go/analysis/passes/unusedresult/BUILD.bazel --- b/go/analysis/passes/unusedresult/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedresult/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,31 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "unusedresult", -+ srcs = ["unusedresult.go"], ++ srcs = [ ++ "doc.go", ++ "unusedresult.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/unusedresult", + visibility = ["//visibility:public"], + deps = [ @@ -5423,7 +5596,7 @@ diff -urN b/go/analysis/passes/unusedresult/BUILD.bazel c/go/analysis/passes/unu + "//go/analysis/passes/inspect", + "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", -+ "//internal/typeparams", ++ "//go/types/typeutil", + ], +) + @@ -5442,6 +5615,28 @@ diff -urN b/go/analysis/passes/unusedresult/BUILD.bazel c/go/analysis/passes/unu + "//internal/typeparams", + ], +) +diff -urN b/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel c/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel +--- b/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/analysis/passes/unusedresult/cmd/unusedresult/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,18 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") ++ ++go_library( ++ name = "unusedresult_lib", ++ srcs = ["main.go"], ++ importpath = "golang.org/x/tools/go/analysis/passes/unusedresult/cmd/unusedresult", ++ visibility = ["//visibility:private"], ++ deps = [ ++ "//go/analysis/passes/unusedresult", ++ "//go/analysis/singlechecker", ++ ], ++) ++ ++go_binary( ++ name = "unusedresult", ++ embed = [":unusedresult_lib"], ++ visibility = ["//visibility:public"], ++) diff -urN b/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel c/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel --- b/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedresult/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -5499,17 +5694,22 @@ diff -urN b/go/analysis/passes/unusedresult/testdata/src/typeparams/userdefs/BUI diff -urN b/go/analysis/passes/unusedwrite/BUILD.bazel c/go/analysis/passes/unusedwrite/BUILD.bazel --- b/go/analysis/passes/unusedwrite/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/unusedwrite/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,28 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "unusedwrite", -+ srcs = ["unusedwrite.go"], ++ srcs = [ ++ "doc.go", ++ "unusedwrite.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/unusedwrite", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/buildssa", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ssa", + ], +) @@ -5549,17 +5749,22 @@ diff -urN b/go/analysis/passes/unusedwrite/testdata/src/a/BUILD.bazel c/go/analy diff -urN b/go/analysis/passes/usesgenerics/BUILD.bazel c/go/analysis/passes/usesgenerics/BUILD.bazel --- b/go/analysis/passes/usesgenerics/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/passes/usesgenerics/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,30 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "usesgenerics", -+ srcs = ["usesgenerics.go"], ++ srcs = [ ++ "doc.go", ++ "usesgenerics.go", ++ ], ++ embedsrcs = ["doc.go"], + importpath = "golang.org/x/tools/go/analysis/passes/usesgenerics", + visibility = ["//visibility:public"], + deps = [ + "//go/analysis", + "//go/analysis/passes/inspect", ++ "//go/analysis/passes/internal/analysisutil", + "//go/ast/inspector", + "//internal/typeparams/genericfeatures", + ], @@ -5679,15 +5884,12 @@ diff -urN b/go/analysis/singlechecker/BUILD.bazel c/go/analysis/singlechecker/BU diff -urN b/go/analysis/unitchecker/BUILD.bazel c/go/analysis/unitchecker/BUILD.bazel --- b/go/analysis/unitchecker/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/analysis/unitchecker/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ +@@ -0,0 +1,68 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "unitchecker", -+ srcs = [ -+ "unitchecker.go", -+ "unitchecker112.go", -+ ], ++ srcs = ["unitchecker.go"], + importpath = "golang.org/x/tools/go/analysis/unitchecker", + visibility = ["//visibility:public"], + deps = [ @@ -5706,13 +5908,49 @@ diff -urN b/go/analysis/unitchecker/BUILD.bazel c/go/analysis/unitchecker/BUILD. + +go_test( + name = "unitchecker_test", -+ srcs = ["unitchecker_test.go"], ++ srcs = [ ++ "export_test.go", ++ "separate_test.go", ++ "unitchecker_test.go", ++ "vet_std_test.go", ++ ], ++ embed = [":unitchecker"], + deps = [ -+ ":unitchecker", ++ "//go/analysis/passes/asmdecl", + "//go/analysis/passes/assign", ++ "//go/analysis/passes/atomic", ++ "//go/analysis/passes/bools", ++ "//go/analysis/passes/buildtag", ++ "//go/analysis/passes/cgocall", ++ "//go/analysis/passes/composite", ++ "//go/analysis/passes/copylock", ++ "//go/analysis/passes/defers", ++ "//go/analysis/passes/directive", ++ "//go/analysis/passes/errorsas", + "//go/analysis/passes/findcall", ++ "//go/analysis/passes/framepointer", ++ "//go/analysis/passes/httpresponse", ++ "//go/analysis/passes/ifaceassert", ++ "//go/analysis/passes/loopclosure", ++ "//go/analysis/passes/lostcancel", ++ "//go/analysis/passes/nilfunc", + "//go/analysis/passes/printf", ++ "//go/analysis/passes/shift", ++ "//go/analysis/passes/sigchanyzer", ++ "//go/analysis/passes/stdmethods", ++ "//go/analysis/passes/stringintconv", ++ "//go/analysis/passes/structtag", ++ "//go/analysis/passes/testinggoroutine", ++ "//go/analysis/passes/tests", ++ "//go/analysis/passes/timeformat", ++ "//go/analysis/passes/unmarshal", ++ "//go/analysis/passes/unreachable", ++ "//go/analysis/passes/unusedresult", ++ "//go/gcexportdata", ++ "//go/packages", + "//go/packages/packagestest", ++ "//internal/testenv", ++ "//txtar", + ], +) diff -urN b/go/ast/astutil/BUILD.bazel c/go/ast/astutil/BUILD.bazel @@ -5823,7 +6061,7 @@ diff -urN b/go/buildutil/BUILD.bazel c/go/buildutil/BUILD.bazel diff -urN b/go/callgraph/BUILD.bazel c/go/callgraph/BUILD.bazel --- b/go/callgraph/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,33 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -5853,7 +6091,6 @@ diff -urN b/go/callgraph/BUILD.bazel c/go/callgraph/BUILD.bazel + "//go/callgraph/static", + "//go/callgraph/vta", + "//go/loader", -+ "//go/pointer", + "//go/ssa", + "//go/ssa/ssautil", + ], @@ -6274,12 +6511,13 @@ diff -urN b/go/callgraph/vta/internal/trie/BUILD.bazel c/go/callgraph/vta/intern diff -urN b/go/callgraph/vta/testdata/src/BUILD.bazel c/go/callgraph/vta/testdata/src/BUILD.bazel --- b/go/callgraph/vta/testdata/src/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/callgraph/vta/testdata/src/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,47 @@ +@@ -0,0 +1,48 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "src", + srcs = [ ++ "arrays_generics.go", + "callgraph_collections.go", + "callgraph_field_funcs.go", + "callgraph_fields.go", @@ -6545,7 +6783,7 @@ diff -urN b/go/internal/cgo/BUILD.bazel c/go/internal/cgo/BUILD.bazel diff -urN b/go/internal/gccgoimporter/BUILD.bazel c/go/internal/gccgoimporter/BUILD.bazel --- b/go/internal/gccgoimporter/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/internal/gccgoimporter/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,35 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -6580,6 +6818,7 @@ diff -urN b/go/internal/gccgoimporter/BUILD.bazel c/go/internal/gccgoimporter/BU + ], + data = glob(["testdata/**"]), + embed = [":gccgoimporter"], ++ deps = ["//internal/testenv"], +) diff -urN b/go/internal/packagesdriver/BUILD.bazel c/go/internal/packagesdriver/BUILD.bazel --- b/go/internal/packagesdriver/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 @@ -6759,6 +6998,25 @@ diff -urN b/go/packages/gopackages/BUILD.bazel c/go/packages/gopackages/BUILD.ba + embed = [":gopackages_lib"], + visibility = ["//visibility:public"], +) +diff -urN b/go/packages/internal/nodecount/BUILD.bazel c/go/packages/internal/nodecount/BUILD.bazel +--- b/go/packages/internal/nodecount/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/packages/internal/nodecount/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,15 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") ++ ++go_library( ++ name = "nodecount_lib", ++ srcs = ["nodecount.go"], ++ importpath = "golang.org/x/tools/go/packages/internal/nodecount", ++ visibility = ["//visibility:private"], ++ deps = ["//go/packages"], ++) ++ ++go_binary( ++ name = "nodecount", ++ embed = [":nodecount_lib"], ++ visibility = ["//go/packages:__subpackages__"], ++) diff -urN b/go/packages/packagestest/BUILD.bazel c/go/packages/packagestest/BUILD.bazel --- b/go/packages/packagestest/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/packages/packagestest/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -7035,156 +7293,6 @@ diff -urN b/go/packages/packagestest/testdata/groups/two/primarymod/expect/BUILD + name = "expect_test", + srcs = ["yo_test.go"], +) -diff -urN b/go/pointer/BUILD.bazel c/go/pointer/BUILD.bazel ---- b/go/pointer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/go/pointer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,124 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "pointer", -+ srcs = [ -+ "analysis.go", -+ "api.go", -+ "callgraph.go", -+ "constraint.go", -+ "doc.go", -+ "gen.go", -+ "hvn.go", -+ "intrinsics.go", -+ "labels.go", -+ "opt.go", -+ "print.go", -+ "query.go", -+ "reflect.go", -+ "solve.go", -+ "util.go", -+ ], -+ importpath = "golang.org/x/tools/go/pointer", -+ visibility = ["//visibility:public"], -+ deps = [ -+ "//container/intsets", -+ "//go/callgraph", -+ "//go/ssa", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ "@org_golang_x_sys//execabs:go_default_library", -+ ], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":pointer", -+ visibility = ["//visibility:public"], -+) -+ -+go_test( -+ name = "pointer_test", -+ srcs = [ -+ "example_test.go", -+ "pointer_go117_test.go", -+ "pointer_race_test.go", -+ "pointer_test.go", -+ "query_test.go", -+ "stdlib_test.go", -+ ], -+ embed = [":pointer"], -+ deps = [ -+ "//go/callgraph", -+ "//go/loader", -+ "//go/ssa", -+ "//go/ssa/ssautil", -+ ] + select({ -+ "@io_bazel_rules_go//go/platform:aix": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:darwin": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:dragonfly": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:freebsd": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:illumos": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:ios": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:js": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:linux": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:netbsd": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:openbsd": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:plan9": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:solaris": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "@io_bazel_rules_go//go/platform:windows": [ -+ "//go/packages", -+ "//go/types/typeutil", -+ "//internal/typeparams", -+ ], -+ "//conditions:default": [], -+ }), -+) -diff -urN b/go/pointer/testdata/BUILD.bazel c/go/pointer/testdata/BUILD.bazel ---- b/go/pointer/testdata/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/go/pointer/testdata/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") -+ -+go_library( -+ name = "testdata_lib", -+ srcs = [ -+ "finalizer.go", -+ "issue9002.go", -+ "rtti.go", -+ ], -+ importpath = "golang.org/x/tools/go/pointer/testdata", -+ visibility = ["//visibility:private"], -+) -+ -+go_binary( -+ name = "testdata", -+ embed = [":testdata_lib"], -+ visibility = ["//visibility:public"], -+) diff -urN b/go/ssa/BUILD.bazel c/go/ssa/BUILD.bazel --- b/go/ssa/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -7309,7 +7417,7 @@ diff -urN b/go/ssa/BUILD.bazel c/go/ssa/BUILD.bazel diff -urN b/go/ssa/interp/BUILD.bazel c/go/ssa/interp/BUILD.bazel --- b/go/ssa/interp/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,41 @@ +@@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -7341,6 +7449,7 @@ diff -urN b/go/ssa/interp/BUILD.bazel c/go/ssa/interp/BUILD.bazel + srcs = [ + "interp_go117_test.go", + "interp_go120_test.go", ++ "interp_go121_test.go", + "interp_test.go", + ], + deps = [ @@ -7354,7 +7463,7 @@ diff -urN b/go/ssa/interp/BUILD.bazel c/go/ssa/interp/BUILD.bazel diff -urN b/go/ssa/interp/testdata/fixedbugs/BUILD.bazel c/go/ssa/interp/testdata/fixedbugs/BUILD.bazel --- b/go/ssa/interp/testdata/fixedbugs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/ssa/interp/testdata/fixedbugs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,18 @@ +@@ -0,0 +1,19 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") + +go_library( @@ -7363,6 +7472,7 @@ diff -urN b/go/ssa/interp/testdata/fixedbugs/BUILD.bazel c/go/ssa/interp/testdat + "issue52342.go", + "issue52835.go", + "issue55086.go", ++ "issue55115.go", + ], + importpath = "golang.org/x/tools/go/ssa/interp/testdata/fixedbugs", + visibility = ["//visibility:private"], @@ -8109,10 +8219,33 @@ diff -urN b/go/ssa/testdata/src/unsafe/BUILD.bazel c/go/ssa/testdata/src/unsafe/ + actual = ":unsafe", + visibility = ["//visibility:public"], +) +diff -urN b/go/types/internal/play/BUILD.bazel c/go/types/internal/play/BUILD.bazel +--- b/go/types/internal/play/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/go/types/internal/play/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,19 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library") ++ ++go_library( ++ name = "play_lib", ++ srcs = ["play.go"], ++ importpath = "golang.org/x/tools/go/types/internal/play", ++ visibility = ["//visibility:private"], ++ deps = [ ++ "//go/ast/astutil", ++ "//go/packages", ++ "//go/types/typeutil", ++ ], ++) ++ ++go_binary( ++ name = "play", ++ embed = [":play_lib"], ++ visibility = ["//go/types:__subpackages__"], ++) diff -urN b/go/types/objectpath/BUILD.bazel c/go/types/objectpath/BUILD.bazel --- b/go/types/objectpath/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/go/types/objectpath/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,29 @@ +@@ -0,0 +1,32 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -8120,7 +8253,10 @@ diff -urN b/go/types/objectpath/BUILD.bazel c/go/types/objectpath/BUILD.bazel + srcs = ["objectpath.go"], + importpath = "golang.org/x/tools/go/types/objectpath", + visibility = ["//visibility:public"], -+ deps = ["//internal/typeparams"], ++ deps = [ ++ "//internal/typeparams", ++ "//internal/typesinternal", ++ ], +) + +alias( @@ -8185,36 +8321,6 @@ diff -urN b/go/types/typeutil/BUILD.bazel c/go/types/typeutil/BUILD.bazel + "//internal/typeparams", + ], +) -diff -urN b/go/vcs/BUILD.bazel c/go/vcs/BUILD.bazel ---- b/go/vcs/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/go/vcs/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,26 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "vcs", -+ srcs = [ -+ "discovery.go", -+ "env.go", -+ "http.go", -+ "vcs.go", -+ ], -+ importpath = "golang.org/x/tools/go/vcs", -+ visibility = ["//visibility:public"], -+ deps = ["@org_golang_x_sys//execabs:go_default_library"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":vcs", -+ visibility = ["//visibility:public"], -+) -+ -+go_test( -+ name = "vcs_test", -+ srcs = ["vcs_test.go"], -+ embed = [":vcs"], -+) diff -urN b/godoc/analysis/BUILD.bazel c/godoc/analysis/BUILD.bazel --- b/godoc/analysis/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/godoc/analysis/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -8624,29 +8730,85 @@ diff -urN b/internal/apidiff/testdata/exported_fields/BUILD.bazel c/internal/api + actual = ":exported_fields", + visibility = ["//:__subpackages__"], +) -diff -urN b/internal/bug/BUILD.bazel c/internal/bug/BUILD.bazel ---- b/internal/bug/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/internal/bug/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +diff -urN b/internal/bisect/BUILD.bazel c/internal/bisect/BUILD.bazel +--- b/internal/bisect/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/bisect/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,20 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( -+ name = "bug", -+ srcs = ["bug.go"], -+ importpath = "golang.org/x/tools/internal/bug", ++ name = "bisect", ++ srcs = ["bisect.go"], ++ importpath = "golang.org/x/tools/internal/bisect", + visibility = ["//:__subpackages__"], +) + +alias( + name = "go_default_library", -+ actual = ":bug", ++ actual = ":bisect", + visibility = ["//:__subpackages__"], +) + +go_test( -+ name = "bug_test", -+ srcs = ["bug_test.go"], -+ embed = [":bug"], ++ name = "bisect_test", ++ srcs = ["bisect_test.go"], ++ embed = [":bisect"], ++) +diff -urN b/internal/cmd/deadcode/BUILD.bazel c/internal/cmd/deadcode/BUILD.bazel +--- b/internal/cmd/deadcode/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/cmd/deadcode/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,34 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test") ++ ++go_library( ++ name = "deadcode_lib", ++ srcs = [ ++ "deadcode.go", ++ "doc.go", ++ ], ++ embedsrcs = ["doc.go"], ++ importpath = "golang.org/x/tools/internal/cmd/deadcode", ++ visibility = ["//visibility:private"], ++ deps = [ ++ "//go/callgraph/rta", ++ "//go/packages", ++ "//go/ssa", ++ "//go/ssa/ssautil", ++ ], ++) ++ ++go_binary( ++ name = "deadcode", ++ embed = [":deadcode_lib"], ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "deadcode_test", ++ srcs = ["deadcode_test.go"], ++ data = glob(["testdata/**"]), ++ deps = [ ++ "//internal/testenv", ++ "//txtar", ++ ], ++) +diff -urN b/internal/constraints/BUILD.bazel c/internal/constraints/BUILD.bazel +--- b/internal/constraints/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/constraints/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "constraints", ++ srcs = ["constraint.go"], ++ importpath = "golang.org/x/tools/internal/constraints", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":constraints", ++ visibility = ["//:__subpackages__"], +) diff -urN b/internal/diff/BUILD.bazel c/internal/diff/BUILD.bazel --- b/internal/diff/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 @@ -8773,6 +8935,56 @@ diff -urN b/internal/diff/myers/BUILD.bazel c/internal/diff/myers/BUILD.bazel + "//internal/diff/difftest", + ], +) +diff -urN b/internal/diffp/BUILD.bazel c/internal/diffp/BUILD.bazel +--- b/internal/diffp/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/diffp/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,22 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "diffp", ++ srcs = ["diff.go"], ++ importpath = "golang.org/x/tools/internal/diffp", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":diffp", ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "diffp_test", ++ srcs = ["diff_test.go"], ++ data = glob(["testdata/**"]), ++ embed = [":diffp"], ++ deps = ["//txtar"], ++) +diff -urN b/internal/edit/BUILD.bazel c/internal/edit/BUILD.bazel +--- b/internal/edit/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/edit/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,20 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "edit", ++ srcs = ["edit.go"], ++ importpath = "golang.org/x/tools/internal/edit", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":edit", ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "edit_test", ++ srcs = ["edit_test.go"], ++ embed = [":edit"], ++) diff -urN b/internal/event/BUILD.bazel c/internal/event/BUILD.bazel --- b/internal/event/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/event/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -9103,7 +9315,7 @@ diff -urN b/internal/event/tag/BUILD.bazel c/internal/event/tag/BUILD.bazel diff -urN b/internal/facts/BUILD.bazel c/internal/facts/BUILD.bazel --- b/internal/facts/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/facts/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,34 @@ +@@ -0,0 +1,35 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -9118,6 +9330,7 @@ diff -urN b/internal/facts/BUILD.bazel c/internal/facts/BUILD.bazel + "//go/analysis", + "//go/types/objectpath", + "//internal/typeparams", ++ "//internal/typesinternal", + ], +) + @@ -9231,7 +9444,6 @@ diff -urN b/internal/gcimporter/BUILD.bazel c/internal/gcimporter/BUILD.bazel +go_library( + name = "gcimporter", + srcs = [ -+ "bexport.go", + "bimport.go", + "exportdata.go", + "gcimporter.go", @@ -9248,6 +9460,7 @@ diff -urN b/internal/gcimporter/BUILD.bazel c/internal/gcimporter/BUILD.bazel + importpath = "golang.org/x/tools/internal/gcimporter", + visibility = ["//:__subpackages__"], + deps = [ ++ "//go/types/objectpath", + "//internal/pkgbits", + "//internal/tokeninternal", + "//internal/typeparams", @@ -9419,7 +9632,7 @@ diff -urN b/internal/gcimporter/testdata/versions/BUILD.bazel c/internal/gcimpor diff -urN b/internal/gocommand/BUILD.bazel c/internal/gocommand/BUILD.bazel --- b/internal/gocommand/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/gocommand/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,32 @@ +@@ -0,0 +1,36 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -9433,6 +9646,9 @@ diff -urN b/internal/gocommand/BUILD.bazel c/internal/gocommand/BUILD.bazel + visibility = ["//:__subpackages__"], + deps = [ + "//internal/event", ++ "//internal/event/keys", ++ "//internal/event/label", ++ "//internal/event/tag", + "@org_golang_x_mod//semver:go_default_library", + "@org_golang_x_sys//execabs:go_default_library", + ], @@ -9451,6 +9667,7 @@ diff -urN b/internal/gocommand/BUILD.bazel c/internal/gocommand/BUILD.bazel + "version_test.go", + ], + embed = [":gocommand"], ++ deps = ["//internal/testenv"], +) diff -urN b/internal/gopathwalk/BUILD.bazel c/internal/gopathwalk/BUILD.bazel --- b/internal/gopathwalk/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 @@ -9498,7 +9715,7 @@ diff -urN b/internal/goroot/BUILD.bazel c/internal/goroot/BUILD.bazel diff -urN b/internal/imports/BUILD.bazel c/internal/imports/BUILD.bazel --- b/internal/imports/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/imports/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,48 @@ +@@ -0,0 +1,49 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -9515,6 +9732,7 @@ diff -urN b/internal/imports/BUILD.bazel c/internal/imports/BUILD.bazel + visibility = ["//:__subpackages__"], + deps = [ + "//go/ast/astutil", ++ "//internal/event", + "//internal/gocommand", + "//internal/gopathwalk", + "@org_golang_x_mod//module:go_default_library", @@ -9550,7 +9768,7 @@ diff -urN b/internal/imports/BUILD.bazel c/internal/imports/BUILD.bazel diff -urN b/internal/jsonrpc2/BUILD.bazel c/internal/jsonrpc2/BUILD.bazel --- b/internal/jsonrpc2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/jsonrpc2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,41 @@ +@@ -0,0 +1,42 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -9590,6 +9808,7 @@ diff -urN b/internal/jsonrpc2/BUILD.bazel c/internal/jsonrpc2/BUILD.bazel + deps = [ + "//internal/event/export/eventtest", + "//internal/stack/stacktest", ++ "//internal/testenv", + ], +) diff -urN b/internal/jsonrpc2/servertest/BUILD.bazel c/internal/jsonrpc2/servertest/BUILD.bazel @@ -9621,7 +9840,7 @@ diff -urN b/internal/jsonrpc2/servertest/BUILD.bazel c/internal/jsonrpc2/servert diff -urN b/internal/jsonrpc2_v2/BUILD.bazel c/internal/jsonrpc2_v2/BUILD.bazel --- b/internal/jsonrpc2_v2/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/jsonrpc2_v2/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,44 @@ +@@ -0,0 +1,45 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( @@ -9664,192 +9883,9 @@ diff -urN b/internal/jsonrpc2_v2/BUILD.bazel c/internal/jsonrpc2_v2/BUILD.bazel + ":jsonrpc2_v2", + "//internal/event/export/eventtest", + "//internal/stack/stacktest", ++ "//internal/testenv", + ], +) -diff -urN b/internal/lockedfile/BUILD.bazel c/internal/lockedfile/BUILD.bazel ---- b/internal/lockedfile/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/internal/lockedfile/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,111 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "lockedfile", -+ srcs = [ -+ "lockedfile.go", -+ "lockedfile_filelock.go", -+ "lockedfile_plan9.go", -+ "mutex.go", -+ ], -+ importpath = "golang.org/x/tools/internal/lockedfile", -+ visibility = ["//:__subpackages__"], -+ deps = select({ -+ "@io_bazel_rules_go//go/platform:aix": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:android": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:darwin": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:dragonfly": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:freebsd": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:illumos": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:ios": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:js": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:linux": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:netbsd": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:openbsd": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:solaris": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:windows": [ -+ "//internal/lockedfile/internal/filelock", -+ ], -+ "//conditions:default": [], -+ }), -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":lockedfile", -+ visibility = ["//:__subpackages__"], -+) -+ -+go_test( -+ name = "lockedfile_test", -+ srcs = [ -+ "lockedfile_test.go", -+ "transform_test.go", -+ ], -+ deps = select({ -+ "@io_bazel_rules_go//go/platform:aix": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:android": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:darwin": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:dragonfly": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:freebsd": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:illumos": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:ios": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:linux": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:netbsd": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:openbsd": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:plan9": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:solaris": [ -+ ":lockedfile", -+ ], -+ "@io_bazel_rules_go//go/platform:windows": [ -+ ":lockedfile", -+ ], -+ "//conditions:default": [], -+ }), -+) -diff -urN b/internal/lockedfile/internal/filelock/BUILD.bazel c/internal/lockedfile/internal/filelock/BUILD.bazel ---- b/internal/lockedfile/internal/filelock/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 -+++ c/internal/lockedfile/internal/filelock/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,65 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") -+ -+go_library( -+ name = "filelock", -+ srcs = [ -+ "filelock.go", -+ "filelock_fcntl.go", -+ "filelock_other.go", -+ "filelock_plan9.go", -+ "filelock_unix.go", -+ "filelock_windows.go", -+ ], -+ importpath = "golang.org/x/tools/internal/lockedfile/internal/filelock", -+ visibility = ["//:__subpackages__"], -+) -+ -+alias( -+ name = "go_default_library", -+ actual = ":filelock", -+ visibility = ["//:__subpackages__"], -+) -+ -+go_test( -+ name = "filelock_test", -+ srcs = ["filelock_test.go"], -+ deps = select({ -+ "@io_bazel_rules_go//go/platform:aix": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:android": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:darwin": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:dragonfly": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:freebsd": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:illumos": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:ios": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:linux": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:netbsd": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:openbsd": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:solaris": [ -+ ":filelock", -+ ], -+ "@io_bazel_rules_go//go/platform:windows": [ -+ ":filelock", -+ ], -+ "//conditions:default": [], -+ }), -+) diff -urN b/internal/memoize/BUILD.bazel c/internal/memoize/BUILD.bazel --- b/internal/memoize/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/memoize/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -9897,14 +9933,18 @@ diff -urN b/internal/packagesinternal/BUILD.bazel c/internal/packagesinternal/BU diff -urN b/internal/persistent/BUILD.bazel c/internal/persistent/BUILD.bazel --- b/internal/persistent/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/persistent/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,20 @@ +@@ -0,0 +1,28 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "persistent", -+ srcs = ["map.go"], ++ srcs = [ ++ "map.go", ++ "set.go", ++ ], + importpath = "golang.org/x/tools/internal/persistent", + visibility = ["//:__subpackages__"], ++ deps = ["//internal/constraints"], +) + +alias( @@ -9915,8 +9955,12 @@ diff -urN b/internal/persistent/BUILD.bazel c/internal/persistent/BUILD.bazel + +go_test( + name = "persistent_test", -+ srcs = ["map_test.go"], ++ srcs = [ ++ "map_test.go", ++ "set_test.go", ++ ], + embed = [":persistent"], ++ deps = ["//internal/constraints"], +) diff -urN b/internal/pkgbits/BUILD.bazel c/internal/pkgbits/BUILD.bazel --- b/internal/pkgbits/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 @@ -9948,6 +9992,31 @@ diff -urN b/internal/pkgbits/BUILD.bazel c/internal/pkgbits/BUILD.bazel + actual = ":pkgbits", + visibility = ["//:__subpackages__"], +) +diff -urN b/internal/pprof/BUILD.bazel c/internal/pprof/BUILD.bazel +--- b/internal/pprof/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/pprof/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,21 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "pprof", ++ srcs = ["pprof.go"], ++ importpath = "golang.org/x/tools/internal/pprof", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":pprof", ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "pprof_test", ++ srcs = ["pprof_test.go"], ++ data = glob(["testdata/**"]), ++ deps = [":pprof"], ++) diff -urN b/internal/proxydir/BUILD.bazel c/internal/proxydir/BUILD.bazel --- b/internal/proxydir/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/proxydir/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -9973,6 +10042,120 @@ diff -urN b/internal/proxydir/BUILD.bazel c/internal/proxydir/BUILD.bazel + srcs = ["proxydir_test.go"], + embed = [":proxydir"], +) +diff -urN b/internal/refactor/inline/analyzer/BUILD.bazel c/internal/refactor/inline/analyzer/BUILD.bazel +--- b/internal/refactor/inline/analyzer/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/refactor/inline/analyzer/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,31 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "analyzer", ++ srcs = ["analyzer.go"], ++ importpath = "golang.org/x/tools/internal/refactor/inline/analyzer", ++ visibility = ["//:__subpackages__"], ++ deps = [ ++ "//go/analysis", ++ "//go/analysis/passes/inspect", ++ "//go/ast/inspector", ++ "//go/types/typeutil", ++ "//internal/diff", ++ "//internal/refactor/inline", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":analyzer", ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "analyzer_test", ++ srcs = ["analyzer_test.go"], ++ deps = [ ++ ":analyzer", ++ "//go/analysis/analysistest", ++ ], ++) +diff -urN b/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel c/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel +--- b/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/refactor/inline/analyzer/testdata/src/a/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "a", ++ srcs = ["a.go"], ++ importpath = "golang.org/x/tools/internal/refactor/inline/analyzer/testdata/src/a", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":a", ++ visibility = ["//:__subpackages__"], ++) +diff -urN b/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel c/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel +--- b/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/refactor/inline/analyzer/testdata/src/b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,14 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library") ++ ++go_library( ++ name = "b", ++ srcs = ["b.go"], ++ importpath = "golang.org/x/tools/internal/refactor/inline/analyzer/testdata/src/b", ++ visibility = ["//:__subpackages__"], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":b", ++ visibility = ["//:__subpackages__"], ++) +diff -urN b/internal/refactor/inline/BUILD.bazel c/internal/refactor/inline/BUILD.bazel +--- b/internal/refactor/inline/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 ++++ c/internal/refactor/inline/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 +@@ -0,0 +1,39 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") ++ ++go_library( ++ name = "inline", ++ srcs = [ ++ "callee.go", ++ "inline.go", ++ ], ++ importpath = "golang.org/x/tools/internal/refactor/inline", ++ visibility = ["//:__subpackages__"], ++ deps = [ ++ "//go/ast/astutil", ++ "//go/types/typeutil", ++ "//imports", ++ "//internal/typeparams", ++ ], ++) ++ ++alias( ++ name = "go_default_library", ++ actual = ":inline", ++ visibility = ["//:__subpackages__"], ++) ++ ++go_test( ++ name = "inline_test", ++ srcs = ["inline_test.go"], ++ data = glob(["testdata/**"]), ++ deps = [ ++ ":inline", ++ "//go/ast/astutil", ++ "//go/expect", ++ "//go/packages", ++ "//go/types/typeutil", ++ "//internal/diff", ++ "//internal/testenv", ++ "//txtar", ++ ], ++) diff -urN b/internal/robustio/BUILD.bazel c/internal/robustio/BUILD.bazel --- b/internal/robustio/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/robustio/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -10075,7 +10258,7 @@ diff -urN b/internal/stack/stacktest/BUILD.bazel c/internal/stack/stacktest/BUIL diff -urN b/internal/testenv/BUILD.bazel c/internal/testenv/BUILD.bazel --- b/internal/testenv/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/testenv/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,23 @@ +@@ -0,0 +1,24 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( @@ -10090,6 +10273,7 @@ diff -urN b/internal/testenv/BUILD.bazel c/internal/testenv/BUILD.bazel + visibility = ["//:__subpackages__"], + deps = [ + "//internal/goroot", ++ "@org_golang_x_mod//modfile:go_default_library", + "@org_golang_x_sys//execabs:go_default_library", + ], +) @@ -10102,8 +10286,8 @@ diff -urN b/internal/testenv/BUILD.bazel c/internal/testenv/BUILD.bazel diff -urN b/internal/tokeninternal/BUILD.bazel c/internal/tokeninternal/BUILD.bazel --- b/internal/tokeninternal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/tokeninternal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 -@@ -0,0 +1,14 @@ -+load("@io_bazel_rules_go//go:def.bzl", "go_library") +@@ -0,0 +1,20 @@ ++load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "tokeninternal", @@ -10117,6 +10301,12 @@ diff -urN b/internal/tokeninternal/BUILD.bazel c/internal/tokeninternal/BUILD.ba + actual = ":tokeninternal", + visibility = ["//:__subpackages__"], +) ++ ++go_test( ++ name = "tokeninternal_test", ++ srcs = ["tokeninternal_test.go"], ++ deps = [":tokeninternal"], ++) diff -urN b/internal/tool/BUILD.bazel c/internal/tool/BUILD.bazel --- b/internal/tool/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ c/internal/tool/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -10211,12 +10401,12 @@ diff -urN b/internal/typesinternal/BUILD.bazel c/internal/typesinternal/BUILD.ba + srcs = [ + "errorcode.go", + "errorcode_string.go", ++ "objectpath.go", + "types.go", + "types_118.go", + ], + importpath = "golang.org/x/tools/internal/typesinternal", + visibility = ["//:__subpackages__"], -+ deps = ["//go/types/objectpath"], +) + +alias( diff --git a/third_party/org_golang_x_xerrors-gazelle.patch b/third_party/org_golang_x_xerrors-gazelle.patch index 157e46299a..07d0c73398 100644 --- a/third_party/org_golang_x_xerrors-gazelle.patch +++ b/third_party/org_golang_x_xerrors-gazelle.patch @@ -1,5 +1,5 @@ diff -urN a/BUILD.bazel b/BUILD.bazel ---- a/BUILD.bazel 1969-12-31 16:00:00 +--- a/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,40 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") @@ -43,7 +43,7 @@ diff -urN a/BUILD.bazel b/BUILD.bazel + deps = ["//internal"], +) diff -urN a/internal/BUILD.bazel b/internal/BUILD.bazel ---- a/internal/BUILD.bazel 1969-12-31 16:00:00 +--- a/internal/BUILD.bazel 1970-01-01 00:00:00.000000000 +0000 +++ b/internal/BUILD.bazel 2000-01-01 00:00:00.000000000 -0000 @@ -0,0 +1,14 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library")