goscript 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/cmd/go_js_wasm_exec/main.go +201 -0
- package/cmd/go_js_wasm_exec/main_test.go +83 -0
- package/cmd/goscript/{cmd_compile.go → cmd-compile.go} +35 -8
- package/cmd/goscript/cmd-test.go +14 -0
- package/cmd/goscript/cmd-test_test.go +1 -1
- package/cmd/goscript/cmd_compile_test.go +105 -6
- package/compiler/build-flags.go +9 -10
- package/compiler/compile-request.go +12 -9
- package/compiler/compliance_test.go +0 -1
- package/compiler/config.go +2 -0
- package/compiler/gotest/request.go +28 -0
- package/compiler/gotest/runner.go +353 -27
- package/compiler/gotest/runner_test.go +400 -1
- package/compiler/gotest/testdata/browserapi/browserapi_test.go +20 -0
- package/compiler/gotest/testdata/browserapi/go.mod +3 -0
- package/compiler/lowered-program.go +24 -17
- package/compiler/lowering.go +988 -263
- package/compiler/lowering_bench_test.go +364 -0
- package/compiler/override-facts.go +15 -0
- package/compiler/override-parity-verifier.go +450 -0
- package/compiler/override-parity.go +122 -0
- package/compiler/override-registry_test.go +559 -0
- package/compiler/package-graph.go +61 -4
- package/compiler/package-graph_test.go +30 -0
- package/compiler/protobuf-ts-binding.go +514 -0
- package/compiler/protobuf-ts-binding_test.go +172 -0
- package/compiler/semantic-model-types.go +17 -4
- package/compiler/semantic-model.go +709 -72
- package/compiler/semantic-model_test.go +219 -0
- package/compiler/service.go +20 -1
- package/compiler/skeleton_test.go +1008 -20
- package/compiler/typescript-emitter.go +147 -15
- package/dist/gs/builtin/builtin.d.ts +2 -2
- package/dist/gs/builtin/builtin.js +20 -0
- package/dist/gs/builtin/builtin.js.map +1 -1
- package/dist/gs/builtin/slice.d.ts +2 -1
- package/dist/gs/builtin/slice.js +34 -4
- package/dist/gs/builtin/slice.js.map +1 -1
- package/dist/gs/builtin/type.d.ts +14 -6
- package/dist/gs/builtin/type.js +224 -64
- package/dist/gs/builtin/type.js.map +1 -1
- package/dist/gs/builtin/varRef.d.ts +11 -0
- package/dist/gs/builtin/varRef.js +57 -2
- package/dist/gs/builtin/varRef.js.map +1 -1
- package/dist/gs/bytes/buffer.gs.js +1 -1
- package/dist/gs/bytes/buffer.gs.js.map +1 -1
- package/dist/gs/bytes/reader.gs.js +1 -1
- package/dist/gs/bytes/reader.gs.js.map +1 -1
- package/dist/gs/compress/zlib/index.d.ts +13 -6
- package/dist/gs/compress/zlib/index.js +131 -35
- package/dist/gs/compress/zlib/index.js.map +1 -1
- package/dist/gs/crypto/sha1/index.js +2 -5
- package/dist/gs/crypto/sha1/index.js.map +1 -1
- package/dist/gs/crypto/sha256/index.js +2 -5
- package/dist/gs/crypto/sha256/index.js.map +1 -1
- package/dist/gs/crypto/sha512/index.js +2 -5
- package/dist/gs/crypto/sha512/index.js.map +1 -1
- package/dist/gs/embed/index.d.ts +6 -0
- package/dist/gs/embed/index.js +210 -5
- package/dist/gs/embed/index.js.map +1 -1
- package/dist/gs/encoding/json/index.d.ts +114 -0
- package/dist/gs/encoding/json/index.js +544 -36
- package/dist/gs/encoding/json/index.js.map +1 -1
- package/dist/gs/fmt/fmt.d.ts +3 -3
- package/dist/gs/fmt/fmt.js +29 -16
- package/dist/gs/fmt/fmt.js.map +1 -1
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.d.ts +100 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js +564 -0
- package/dist/gs/github.com/aperturerobotics/protobuf-go-lite/index.js.map +1 -1
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.d.ts +45 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js +229 -0
- package/dist/gs/github.com/go-git/go-billy/v6/osfs/index.js.map +1 -0
- package/dist/gs/github.com/pkg/errors/errors.js +54 -30
- package/dist/gs/github.com/pkg/errors/errors.js.map +1 -1
- package/dist/gs/go/scanner/index.d.ts +2 -0
- package/dist/gs/go/scanner/index.js +29 -5
- package/dist/gs/go/scanner/index.js.map +1 -1
- package/dist/gs/go/token/index.js +22 -6
- package/dist/gs/go/token/index.js.map +1 -1
- package/dist/gs/hash/index.d.ts +6 -0
- package/dist/gs/hash/index.js +20 -0
- package/dist/gs/hash/index.js.map +1 -1
- package/dist/gs/internal/goarch/index.d.ts +43 -3
- package/dist/gs/internal/goarch/index.js +42 -10
- package/dist/gs/internal/goarch/index.js.map +1 -1
- package/dist/gs/io/fs/fs.js +26 -14
- package/dist/gs/io/fs/fs.js.map +1 -1
- package/dist/gs/io/fs/readdir.js +8 -4
- package/dist/gs/io/fs/readdir.js.map +1 -1
- package/dist/gs/io/fs/sub.js +8 -1
- package/dist/gs/io/fs/sub.js.map +1 -1
- package/dist/gs/io/io.d.ts +12 -6
- package/dist/gs/io/io.js +87 -42
- package/dist/gs/io/io.js.map +1 -1
- package/dist/gs/math/bits/index.d.ts +31 -5
- package/dist/gs/math/bits/index.js +29 -28
- package/dist/gs/math/bits/index.js.map +1 -1
- package/dist/gs/mime/index.d.ts +16 -0
- package/dist/gs/mime/index.js +315 -6
- package/dist/gs/mime/index.js.map +1 -1
- package/dist/gs/net/http/httptest/index.d.ts +12 -0
- package/dist/gs/net/http/httptest/index.js +85 -6
- package/dist/gs/net/http/httptest/index.js.map +1 -1
- package/dist/gs/net/http/index.d.ts +303 -6
- package/dist/gs/net/http/index.js +1615 -58
- package/dist/gs/net/http/index.js.map +1 -1
- package/dist/gs/os/dir_unix.gs.js +1 -1
- package/dist/gs/os/dir_unix.gs.js.map +1 -1
- package/dist/gs/os/error.gs.js +1 -1
- package/dist/gs/os/error.gs.js.map +1 -1
- package/dist/gs/os/exec.gs.d.ts +1 -0
- package/dist/gs/os/exec.gs.js +4 -8
- package/dist/gs/os/exec.gs.js.map +1 -1
- package/dist/gs/os/exec_posix.gs.js +1 -1
- package/dist/gs/os/exec_posix.gs.js.map +1 -1
- package/dist/gs/os/index.d.ts +1 -1
- package/dist/gs/os/index.js +1 -1
- package/dist/gs/os/index.js.map +1 -1
- package/dist/gs/os/proc.gs.d.ts +4 -0
- package/dist/gs/os/proc.gs.js +12 -6
- package/dist/gs/os/proc.gs.js.map +1 -1
- package/dist/gs/os/root_js.gs.js +1 -1
- package/dist/gs/os/root_js.gs.js.map +1 -1
- package/dist/gs/os/types.gs.js +1 -1
- package/dist/gs/os/types.gs.js.map +1 -1
- package/dist/gs/os/types_js.gs.d.ts +6 -2
- package/dist/gs/os/types_js.gs.js +170 -9
- package/dist/gs/os/types_js.gs.js.map +1 -1
- package/dist/gs/os/types_unix.gs.js +1 -1
- package/dist/gs/os/types_unix.gs.js.map +1 -1
- package/dist/gs/path/path.js +11 -7
- package/dist/gs/path/path.js.map +1 -1
- package/dist/gs/reflect/index.d.ts +5 -4
- package/dist/gs/reflect/index.js +4 -3
- package/dist/gs/reflect/index.js.map +1 -1
- package/dist/gs/reflect/map.js +15 -0
- package/dist/gs/reflect/map.js.map +1 -1
- package/dist/gs/reflect/type.d.ts +26 -6
- package/dist/gs/reflect/type.js +1498 -279
- package/dist/gs/reflect/type.js.map +1 -1
- package/dist/gs/reflect/types.d.ts +14 -6
- package/dist/gs/reflect/types.js +35 -1
- package/dist/gs/reflect/types.js.map +1 -1
- package/dist/gs/reflect/value.d.ts +1 -0
- package/dist/gs/reflect/value.js +83 -41
- package/dist/gs/reflect/value.js.map +1 -1
- package/dist/gs/reflect/visiblefields.js +4 -140
- package/dist/gs/reflect/visiblefields.js.map +1 -1
- package/dist/gs/runtime/pprof/index.d.ts +8 -2
- package/dist/gs/runtime/pprof/index.js +50 -30
- package/dist/gs/runtime/pprof/index.js.map +1 -1
- package/dist/gs/runtime/runtime.js +5 -4
- package/dist/gs/runtime/runtime.js.map +1 -1
- package/dist/gs/runtime/trace/index.js +5 -19
- package/dist/gs/runtime/trace/index.js.map +1 -1
- package/dist/gs/strconv/atoi.gs.js +1 -1
- package/dist/gs/strconv/atoi.gs.js.map +1 -1
- package/dist/gs/strconv/complex.gs.d.ts +3 -0
- package/dist/gs/strconv/complex.gs.js +148 -0
- package/dist/gs/strconv/complex.gs.js.map +1 -0
- package/dist/gs/strconv/index.d.ts +1 -0
- package/dist/gs/strconv/index.js +1 -0
- package/dist/gs/strconv/index.js.map +1 -1
- package/dist/gs/strings/builder.js +1 -1
- package/dist/gs/strings/reader.d.ts +1 -1
- package/dist/gs/strings/reader.js +11 -7
- package/dist/gs/strings/reader.js.map +1 -1
- package/dist/gs/strings/replace.js +15 -7
- package/dist/gs/strings/replace.js.map +1 -1
- package/dist/gs/strings/strings.d.ts +5 -0
- package/dist/gs/strings/strings.js +57 -5
- package/dist/gs/strings/strings.js.map +1 -1
- package/dist/gs/sync/atomic/type.gs.js +9 -9
- package/dist/gs/sync/atomic/type.gs.js.map +1 -1
- package/dist/gs/sync/atomic/value.gs.js +2 -2
- package/dist/gs/sync/atomic/value.gs.js.map +1 -1
- package/dist/gs/sync/sync.d.ts +2 -1
- package/dist/gs/sync/sync.js +37 -16
- package/dist/gs/sync/sync.js.map +1 -1
- package/dist/gs/syscall/env.js +22 -14
- package/dist/gs/syscall/env.js.map +1 -1
- package/dist/gs/syscall/js/index.js +9 -0
- package/dist/gs/syscall/js/index.js.map +1 -1
- package/dist/gs/testing/testing.js +59 -15
- package/dist/gs/testing/testing.js.map +1 -1
- package/dist/gs/time/time.d.ts +24 -1
- package/dist/gs/time/time.js +43 -3
- package/dist/gs/time/time.js.map +1 -1
- package/dist/gs/unique/index.js +7 -1
- package/dist/gs/unique/index.js.map +1 -1
- package/go.mod +3 -3
- package/go.sum +16 -0
- package/gs/builtin/builtin.ts +25 -2
- package/gs/builtin/runtime-contract.test.ts +260 -18
- package/gs/builtin/slice.ts +51 -4
- package/gs/builtin/type.ts +310 -63
- package/gs/builtin/varRef.ts +85 -2
- package/gs/bytes/buffer.gs.ts +1 -1
- package/gs/bytes/reader.gs.ts +1 -1
- package/gs/compress/zlib/index.test.ts +159 -1
- package/gs/compress/zlib/index.ts +164 -37
- package/gs/compress/zlib/meta.json +4 -1
- package/gs/compress/zlib/parity.json +51 -0
- package/gs/crypto/sha1/index.test.ts +19 -2
- package/gs/crypto/sha1/index.ts +3 -6
- package/gs/crypto/sha256/index.test.ts +14 -2
- package/gs/crypto/sha256/index.ts +3 -6
- package/gs/crypto/sha512/index.test.ts +17 -2
- package/gs/crypto/sha512/index.ts +3 -6
- package/gs/embed/index.test.ts +87 -0
- package/gs/embed/index.ts +229 -5
- package/gs/encoding/json/index.test.ts +360 -6
- package/gs/encoding/json/index.ts +679 -38
- package/gs/encoding/json/parity.json +81 -0
- package/gs/fmt/fmt.test.ts +41 -3
- package/gs/fmt/fmt.ts +40 -17
- package/gs/fmt/meta.json +6 -1
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.test.ts +211 -3
- package/gs/github.com/aperturerobotics/protobuf-go-lite/index.ts +857 -1
- package/gs/github.com/go-git/go-billy/v6/osfs/index.test.ts +110 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/index.ts +280 -0
- package/gs/github.com/go-git/go-billy/v6/osfs/meta.json +8 -0
- package/gs/github.com/pkg/errors/errors.ts +54 -30
- package/gs/go/scanner/index.test.ts +39 -56
- package/gs/go/scanner/index.ts +33 -5
- package/gs/go/scanner/parity.json +27 -0
- package/gs/go/token/index.ts +22 -6
- package/gs/hash/index.test.ts +20 -33
- package/gs/hash/index.ts +28 -0
- package/gs/hash/parity.json +21 -0
- package/gs/internal/goarch/index.test.ts +32 -0
- package/gs/internal/goarch/index.ts +45 -13
- package/gs/internal/goarch/parity.json +144 -0
- package/gs/io/fs/fs.ts +26 -14
- package/gs/io/fs/readdir.test.ts +38 -0
- package/gs/io/fs/readdir.ts +8 -4
- package/gs/io/fs/sub.ts +8 -1
- package/gs/io/io.test.ts +77 -6
- package/gs/io/io.ts +115 -52
- package/gs/io/meta.json +7 -1
- package/gs/io/parity.json +162 -0
- package/gs/math/bits/index.test.ts +14 -1
- package/gs/math/bits/index.ts +75 -32
- package/gs/math/bits/parity.json +156 -0
- package/gs/mime/index.test.ts +90 -0
- package/gs/mime/index.ts +369 -6
- package/gs/mime/parity.json +36 -0
- package/gs/net/http/httptest/index.test.ts +98 -2
- package/gs/net/http/httptest/index.ts +101 -6
- package/gs/net/http/httptest/parity.json +15 -0
- package/gs/net/http/index.test.ts +797 -12
- package/gs/net/http/index.ts +1874 -136
- package/gs/net/http/meta.json +16 -1
- package/gs/net/http/parity.json +193 -0
- package/gs/os/dir_unix.gs.ts +1 -1
- package/gs/os/error.gs.ts +1 -1
- package/gs/os/exec.gs.ts +4 -8
- package/gs/os/exec_posix.gs.ts +1 -1
- package/gs/os/file_unix_js.test.ts +52 -0
- package/gs/os/index.test.ts +9 -0
- package/gs/os/index.ts +1 -0
- package/gs/os/meta.json +4 -0
- package/gs/os/parity.json +9 -0
- package/gs/os/proc.gs.ts +18 -5
- package/gs/os/proc.test.ts +26 -0
- package/gs/os/readdir.test.ts +56 -0
- package/gs/os/root_js.gs.ts +1 -1
- package/gs/os/types.gs.ts +1 -1
- package/gs/os/types_js.gs.ts +170 -9
- package/gs/os/types_unix.gs.ts +1 -1
- package/gs/path/path.ts +11 -7
- package/gs/reflect/deepequal.test.ts +10 -1
- package/gs/reflect/field.test.ts +37 -15
- package/gs/reflect/function-types.test.ts +518 -22
- package/gs/reflect/index.ts +8 -6
- package/gs/reflect/map.ts +20 -0
- package/gs/reflect/meta.json +6 -4
- package/gs/reflect/parity.json +234 -0
- package/gs/reflect/sliceat.test.ts +156 -0
- package/gs/reflect/structof.test.ts +401 -0
- package/gs/reflect/type.ts +1980 -365
- package/gs/reflect/typefor.test.ts +540 -10
- package/gs/reflect/types.ts +43 -18
- package/gs/reflect/value.ts +105 -45
- package/gs/reflect/visiblefields.ts +5 -168
- package/gs/runtime/parity.json +24 -0
- package/gs/runtime/pprof/index.test.ts +29 -7
- package/gs/runtime/pprof/index.ts +56 -30
- package/gs/runtime/pprof/parity.json +27 -0
- package/gs/runtime/runtime.test.ts +3 -1
- package/gs/runtime/runtime.ts +4 -3
- package/gs/runtime/trace/index.test.ts +5 -3
- package/gs/runtime/trace/index.ts +8 -20
- package/gs/runtime/trace/parity.json +36 -0
- package/gs/strconv/atoi.gs.ts +1 -1
- package/gs/strconv/complex.gs.ts +174 -0
- package/gs/strconv/complex.test.ts +65 -0
- package/gs/strconv/index.ts +1 -0
- package/gs/strconv/parity.json +120 -0
- package/gs/strings/builder.ts +1 -1
- package/gs/strings/meta.json +5 -2
- package/gs/strings/parity.json +186 -0
- package/gs/strings/reader.test.ts +2 -2
- package/gs/strings/reader.ts +11 -7
- package/gs/strings/replace.ts +15 -7
- package/gs/strings/strings.test.ts +22 -2
- package/gs/strings/strings.ts +64 -6
- package/gs/sync/atomic/type.gs.ts +9 -9
- package/gs/sync/atomic/value.gs.ts +2 -2
- package/gs/sync/meta.json +1 -0
- package/gs/sync/sync.test.ts +41 -1
- package/gs/sync/sync.ts +41 -16
- package/gs/syscall/env.ts +29 -14
- package/gs/syscall/js/index.test.ts +18 -0
- package/gs/syscall/js/index.ts +12 -0
- package/gs/testing/testing.test.ts +99 -3
- package/gs/testing/testing.ts +95 -24
- package/gs/time/parity.json +225 -0
- package/gs/time/time.test.ts +20 -2
- package/gs/time/time.ts +49 -7
- package/gs/unique/index.ts +7 -1
- package/package.json +4 -2
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.d.ts +0 -217
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js +0 -814
- package/dist/gs/github.com/aperturerobotics/starpc/srpc/index.js.map +0 -1
- package/gs/github.com/aperturerobotics/starpc/srpc/index.test.ts +0 -31
- package/gs/github.com/aperturerobotics/starpc/srpc/index.ts +0 -1233
- package/gs/github.com/aperturerobotics/starpc/srpc/meta.json +0 -46
- /package/compiler/{wasm_api.go → wasm-api.go} +0 -0
|
@@ -6,7 +6,6 @@ import (
|
|
|
6
6
|
"go/ast"
|
|
7
7
|
"go/token"
|
|
8
8
|
"go/types"
|
|
9
|
-
"maps"
|
|
10
9
|
"slices"
|
|
11
10
|
"strconv"
|
|
12
11
|
"strings"
|
|
@@ -75,6 +74,7 @@ func (o *SemanticModelOwner) Build(ctx context.Context, graph *PackageGraph) (*S
|
|
|
75
74
|
return model, diagnostics
|
|
76
75
|
}
|
|
77
76
|
|
|
77
|
+
model.functionCallers = semanticFunctionCallers(model)
|
|
78
78
|
diagnostics = append(diagnostics, o.propagateFunctionAsync(ctx, model)...)
|
|
79
79
|
if diagnosticsHaveErrors(diagnostics) {
|
|
80
80
|
return model, diagnostics
|
|
@@ -83,17 +83,31 @@ func (o *SemanticModelOwner) Build(ctx context.Context, graph *PackageGraph) (*S
|
|
|
83
83
|
if diagnosticsHaveErrors(diagnostics) {
|
|
84
84
|
return model, diagnostics
|
|
85
85
|
}
|
|
86
|
-
|
|
86
|
+
methodSets, methodSetDiagnostics := o.resolveImplementationMethodSets(ctx, model)
|
|
87
|
+
diagnostics = append(diagnostics, methodSetDiagnostics...)
|
|
88
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
89
|
+
return model, diagnostics
|
|
90
|
+
}
|
|
91
|
+
interfaceGraph, interfaceDiagnostics := o.resolveInterfaceImplementationGraph(ctx, model, methodSets)
|
|
87
92
|
diagnostics = append(diagnostics, interfaceDiagnostics...)
|
|
88
93
|
if diagnosticsHaveErrors(diagnostics) {
|
|
89
94
|
return model, diagnostics
|
|
90
95
|
}
|
|
96
|
+
anonymousInterfaceGraph, anonymousInterfaceDiagnostics := o.resolveAnonymousInterfaceImplementationGraph(ctx, model, methodSets)
|
|
97
|
+
diagnostics = append(diagnostics, anonymousInterfaceDiagnostics...)
|
|
98
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
99
|
+
return model, diagnostics
|
|
100
|
+
}
|
|
91
101
|
for {
|
|
92
102
|
asyncCount := semanticAsyncFunctionCount(model)
|
|
93
103
|
diagnostics = append(diagnostics, o.applyInterfaceAsyncMethods(ctx, model, interfaceGraph)...)
|
|
94
104
|
if diagnosticsHaveErrors(diagnostics) {
|
|
95
105
|
return model, diagnostics
|
|
96
106
|
}
|
|
107
|
+
diagnostics = append(diagnostics, o.applyAnonymousInterfaceAsyncMethods(ctx, model, anonymousInterfaceGraph)...)
|
|
108
|
+
if diagnosticsHaveErrors(diagnostics) {
|
|
109
|
+
return model, diagnostics
|
|
110
|
+
}
|
|
97
111
|
diagnostics = append(diagnostics, o.propagateFunctionAsync(ctx, model)...)
|
|
98
112
|
if diagnosticsHaveErrors(diagnostics) {
|
|
99
113
|
return model, diagnostics
|
|
@@ -107,15 +121,20 @@ func (o *SemanticModelOwner) Build(ctx context.Context, graph *PackageGraph) (*S
|
|
|
107
121
|
|
|
108
122
|
func newSemanticModel() *SemanticModel {
|
|
109
123
|
return &SemanticModel{
|
|
110
|
-
packages:
|
|
111
|
-
addressTaken:
|
|
112
|
-
needsVarRef:
|
|
113
|
-
functions:
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
packages: make(map[string]*semanticPackage),
|
|
125
|
+
addressTaken: make(map[types.Object]bool),
|
|
126
|
+
needsVarRef: make(map[types.Object]bool),
|
|
127
|
+
functions: make(map[*types.Func]*semanticFunction),
|
|
128
|
+
functionCallers: make(map[*types.Func][]*semanticFunction),
|
|
129
|
+
functionsByFullName: make(map[string]*semanticFunction),
|
|
130
|
+
functionLookupMisses: make(map[*types.Func]bool),
|
|
131
|
+
functionFullNames: make(map[*types.Func]string),
|
|
132
|
+
types: make(map[*types.Named]*semanticType),
|
|
133
|
+
values: make(map[types.Object]*semanticValue),
|
|
134
|
+
generatedImports: make(map[string]map[string]bool),
|
|
135
|
+
generatedImportTypes: make(map[string]map[types.Type]bool),
|
|
136
|
+
asyncInterfaceMethods: make(map[string]bool),
|
|
137
|
+
asyncInterfaceMethodObjs: make(map[*types.Func]bool),
|
|
119
138
|
}
|
|
120
139
|
}
|
|
121
140
|
|
|
@@ -207,7 +226,7 @@ func (o *SemanticModelOwner) collectGenDecl(
|
|
|
207
226
|
continue
|
|
208
227
|
}
|
|
209
228
|
position := sourcePos(pkg, typed.Name.Pos())
|
|
210
|
-
o.addType(model, semPkg, obj, position, typed.Type)
|
|
229
|
+
o.addType(model, semPkg, obj, position, typed.Type, pkg.TypesSizes)
|
|
211
230
|
o.recordGeneratedImports(model, semPkg, position.file, pkg.PkgPath, obj.Type())
|
|
212
231
|
semPkg.declarations = append(semPkg.declarations, semanticDeclaration{
|
|
213
232
|
kind: "type",
|
|
@@ -342,7 +361,7 @@ func (o *SemanticModelOwner) recordTypeSpec(
|
|
|
342
361
|
return
|
|
343
362
|
}
|
|
344
363
|
position := sourcePos(pkg, spec.Name.Pos())
|
|
345
|
-
o.addType(model, semPkg, obj, position, spec.Type)
|
|
364
|
+
o.addType(model, semPkg, obj, position, spec.Type, pkg.TypesSizes)
|
|
346
365
|
o.recordGeneratedImports(model, semPkg, position.file, pkg.PkgPath, obj.Type())
|
|
347
366
|
}
|
|
348
367
|
|
|
@@ -380,8 +399,9 @@ func (o *SemanticModelOwner) recordCallSignatureImports(
|
|
|
380
399
|
return
|
|
381
400
|
}
|
|
382
401
|
position := sourcePos(pkg, expr.Pos())
|
|
383
|
-
|
|
384
|
-
o.recordTupleImports(model, semPkg, position.file, pkg.PkgPath, signature.
|
|
402
|
+
seen := model.generatedImportSeen(position.file)
|
|
403
|
+
o.recordTupleImports(model, semPkg, position.file, pkg.PkgPath, signature.Params(), seen)
|
|
404
|
+
o.recordTupleImports(model, semPkg, position.file, pkg.PkgPath, signature.Results(), seen)
|
|
385
405
|
}
|
|
386
406
|
|
|
387
407
|
func (o *SemanticModelOwner) recordAsyncCompatibleFunctionAssignments(
|
|
@@ -466,7 +486,7 @@ func (o *SemanticModelOwner) addDefinedObject(
|
|
|
466
486
|
o.addValue(model, semPkg, typed, position, false)
|
|
467
487
|
o.recordGeneratedImports(model, semPkg, position.file, pkg.PkgPath, typed.Type())
|
|
468
488
|
case *types.TypeName:
|
|
469
|
-
o.addType(model, semPkg, typed, sourcePos(pkg, ident.Pos()), nil)
|
|
489
|
+
o.addType(model, semPkg, typed, sourcePos(pkg, ident.Pos()), nil, pkg.TypesSizes)
|
|
470
490
|
case *types.Func:
|
|
471
491
|
o.addFunction(model, semPkg, typed, sourcePos(pkg, ident.Pos()))
|
|
472
492
|
}
|
|
@@ -478,6 +498,7 @@ func (o *SemanticModelOwner) addType(
|
|
|
478
498
|
obj *types.TypeName,
|
|
479
499
|
position sourcePosition,
|
|
480
500
|
typeExpr ast.Expr,
|
|
501
|
+
sizes types.Sizes,
|
|
481
502
|
) *semanticType {
|
|
482
503
|
named, _ := obj.Type().(*types.Named)
|
|
483
504
|
if named == nil {
|
|
@@ -485,7 +506,7 @@ func (o *SemanticModelOwner) addType(
|
|
|
485
506
|
}
|
|
486
507
|
if existing := model.types[named]; existing != nil {
|
|
487
508
|
if typeExpr != nil && len(existing.fields) == 0 {
|
|
488
|
-
existing.fields = semanticFields(named, typeExpr)
|
|
509
|
+
existing.fields = semanticFields(named, typeExpr, sizes)
|
|
489
510
|
}
|
|
490
511
|
return existing
|
|
491
512
|
}
|
|
@@ -494,7 +515,7 @@ func (o *SemanticModelOwner) addType(
|
|
|
494
515
|
name: obj.Name(),
|
|
495
516
|
named: named,
|
|
496
517
|
isInterface: isInterface,
|
|
497
|
-
fields: semanticFields(named, typeExpr),
|
|
518
|
+
fields: semanticFields(named, typeExpr, sizes),
|
|
498
519
|
position: position,
|
|
499
520
|
}
|
|
500
521
|
model.types[named] = semType
|
|
@@ -555,7 +576,7 @@ func (o *SemanticModelOwner) addFunction(
|
|
|
555
576
|
return existing
|
|
556
577
|
}
|
|
557
578
|
}
|
|
558
|
-
if fullName :=
|
|
579
|
+
if fullName := model.functionFullName(fn); fullName != "" {
|
|
559
580
|
if existing := model.functionsByFullName[fullName]; existing != nil {
|
|
560
581
|
model.functions[fn] = existing
|
|
561
582
|
if origin := fn.Origin(); origin != nil {
|
|
@@ -583,7 +604,7 @@ func (o *SemanticModelOwner) addFunction(
|
|
|
583
604
|
if origin := fn.Origin(); origin != nil {
|
|
584
605
|
model.functions[origin] = semFn
|
|
585
606
|
}
|
|
586
|
-
if fullName :=
|
|
607
|
+
if fullName := model.functionFullName(fn); fullName != "" {
|
|
587
608
|
if existing := model.functionsByFullName[fullName]; existing == nil {
|
|
588
609
|
model.functionsByFullName[fullName] = semFn
|
|
589
610
|
}
|
|
@@ -592,7 +613,7 @@ func (o *SemanticModelOwner) addFunction(
|
|
|
592
613
|
return semFn
|
|
593
614
|
}
|
|
594
615
|
|
|
595
|
-
func semanticFields(named *types.Named, typeExpr ast.Expr) []semanticField {
|
|
616
|
+
func semanticFields(named *types.Named, typeExpr ast.Expr, sizes types.Sizes) []semanticField {
|
|
596
617
|
if named == nil {
|
|
597
618
|
return nil
|
|
598
619
|
}
|
|
@@ -602,19 +623,64 @@ func semanticFields(named *types.Named, typeExpr ast.Expr) []semanticField {
|
|
|
602
623
|
}
|
|
603
624
|
docs := structFieldDocs(typeExpr)
|
|
604
625
|
fields := make([]semanticField, 0, structType.NumFields())
|
|
626
|
+
var vars []*types.Var
|
|
627
|
+
for field := range structType.Fields() {
|
|
628
|
+
vars = append(vars, field)
|
|
629
|
+
}
|
|
630
|
+
offsets := structFieldOffsets(sizes, vars)
|
|
605
631
|
for i := range structType.NumFields() {
|
|
606
632
|
field := structType.Field(i)
|
|
633
|
+
pkgPath := ""
|
|
634
|
+
if !field.Exported() && field.Pkg() != nil {
|
|
635
|
+
pkgPath = field.Pkg().Path()
|
|
636
|
+
}
|
|
607
637
|
fields = append(fields, semanticField{
|
|
608
638
|
name: field.Name(),
|
|
609
639
|
typ: field.Type(),
|
|
610
640
|
doc: docs[field.Name()],
|
|
611
641
|
tag: structType.Tag(i),
|
|
612
642
|
embedded: field.Embedded(),
|
|
643
|
+
pkgPath: pkgPath,
|
|
644
|
+
index: []int{i},
|
|
645
|
+
offset: offsets[i],
|
|
646
|
+
exported: field.Exported(),
|
|
613
647
|
})
|
|
614
648
|
}
|
|
615
649
|
return fields
|
|
616
650
|
}
|
|
617
651
|
|
|
652
|
+
func goScriptTypeSizes() types.Sizes {
|
|
653
|
+
if sizes := types.SizesFor("gc", "wasm"); sizes != nil {
|
|
654
|
+
return sizes
|
|
655
|
+
}
|
|
656
|
+
return types.SizesFor("gc", "amd64")
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
func structFieldOffsets(sizes types.Sizes, fields []*types.Var) (offsets []int64) {
|
|
660
|
+
offsets = make([]int64, len(fields))
|
|
661
|
+
if len(fields) == 0 {
|
|
662
|
+
return offsets
|
|
663
|
+
}
|
|
664
|
+
if sizes == nil {
|
|
665
|
+
sizes = goScriptTypeSizes()
|
|
666
|
+
}
|
|
667
|
+
if sizes == nil {
|
|
668
|
+
return offsets
|
|
669
|
+
}
|
|
670
|
+
defer func() {
|
|
671
|
+
if recover() != nil {
|
|
672
|
+
// Generic field layouts do not have concrete target offsets during
|
|
673
|
+
// package-level metadata emission; keep compiling and leave them zero.
|
|
674
|
+
offsets = make([]int64, len(fields))
|
|
675
|
+
}
|
|
676
|
+
}()
|
|
677
|
+
computed := sizes.Offsetsof(fields)
|
|
678
|
+
if len(computed) == len(fields) {
|
|
679
|
+
copy(offsets, computed)
|
|
680
|
+
}
|
|
681
|
+
return offsets
|
|
682
|
+
}
|
|
683
|
+
|
|
618
684
|
func structFieldDocs(typeExpr ast.Expr) map[string]string {
|
|
619
685
|
structType, _ := typeExpr.(*ast.StructType)
|
|
620
686
|
if structType == nil || structType.Fields == nil {
|
|
@@ -932,7 +998,7 @@ func semanticFunctionFor(model *SemanticModel, fn *types.Func) *semanticFunction
|
|
|
932
998
|
return semFn
|
|
933
999
|
}
|
|
934
1000
|
}
|
|
935
|
-
if fullName :=
|
|
1001
|
+
if fullName := model.functionFullName(fn); fullName != "" {
|
|
936
1002
|
if semFn := model.functionsByFullName[fullName]; semFn != nil {
|
|
937
1003
|
model.functions[fn] = semFn
|
|
938
1004
|
return semFn
|
|
@@ -989,6 +1055,8 @@ func callUsesFunctionValue(pkg *packages.Package, expr ast.Expr) bool {
|
|
|
989
1055
|
switch typed := expr.(type) {
|
|
990
1056
|
case *ast.CallExpr:
|
|
991
1057
|
return true
|
|
1058
|
+
case *ast.TypeAssertExpr:
|
|
1059
|
+
return true
|
|
992
1060
|
case *ast.SelectorExpr:
|
|
993
1061
|
selection := pkg.TypesInfo.Selections[typed]
|
|
994
1062
|
if selection != nil {
|
|
@@ -1114,29 +1182,56 @@ func receiverNamedType(typ types.Type) *types.Named {
|
|
|
1114
1182
|
}
|
|
1115
1183
|
|
|
1116
1184
|
func (o *SemanticModelOwner) propagateFunctionAsync(ctx context.Context, model *SemanticModel) []Diagnostic {
|
|
1117
|
-
|
|
1118
|
-
|
|
1185
|
+
if err := ctx.Err(); err != nil {
|
|
1186
|
+
return []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1187
|
+
}
|
|
1188
|
+
queued := make(map[*types.Func]bool)
|
|
1189
|
+
queue := make([]*types.Func, 0)
|
|
1190
|
+
enqueue := func(fn *types.Func) {
|
|
1191
|
+
fn = functionOriginOrSelf(fn)
|
|
1192
|
+
if fn == nil || queued[fn] {
|
|
1193
|
+
return
|
|
1194
|
+
}
|
|
1195
|
+
queued[fn] = true
|
|
1196
|
+
queue = append(queue, fn)
|
|
1197
|
+
}
|
|
1198
|
+
for called := range model.functionCallers {
|
|
1199
|
+
if model.functionAsync(called) {
|
|
1200
|
+
enqueue(called)
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
for len(queue) != 0 {
|
|
1119
1204
|
if err := ctx.Err(); err != nil {
|
|
1120
1205
|
return []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1121
1206
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1207
|
+
called := queue[0]
|
|
1208
|
+
queue = queue[1:]
|
|
1209
|
+
for _, semFn := range model.functionCallers[called] {
|
|
1124
1210
|
if err := ctx.Err(); err != nil {
|
|
1125
1211
|
return []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1126
1212
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
if calledFn != nil && calledFn.async {
|
|
1130
|
-
if markFunctionAsync(semFn, "call:"+called.FullName()) {
|
|
1131
|
-
changed = true
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1213
|
+
if markFunctionAsync(semFn, "call:"+model.functionFullName(called)) {
|
|
1214
|
+
enqueue(semFn.function)
|
|
1134
1215
|
}
|
|
1135
1216
|
}
|
|
1136
1217
|
}
|
|
1137
1218
|
return nil
|
|
1138
1219
|
}
|
|
1139
1220
|
|
|
1221
|
+
func semanticFunctionCallers(model *SemanticModel) map[*types.Func][]*semanticFunction {
|
|
1222
|
+
callers := make(map[*types.Func][]*semanticFunction)
|
|
1223
|
+
for _, semFn := range model.functions {
|
|
1224
|
+
for called := range semFn.calls {
|
|
1225
|
+
called = functionOriginOrSelf(called)
|
|
1226
|
+
if called == nil {
|
|
1227
|
+
continue
|
|
1228
|
+
}
|
|
1229
|
+
callers[called] = append(callers[called], semFn)
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return callers
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1140
1235
|
func markFunctionAsync(fn *semanticFunction, reason string) bool {
|
|
1141
1236
|
if fn == nil {
|
|
1142
1237
|
return false
|
|
@@ -1166,23 +1261,12 @@ func semanticAsyncFunctionCount(model *SemanticModel) int {
|
|
|
1166
1261
|
func (o *SemanticModelOwner) resolveInterfaceImplementationGraph(
|
|
1167
1262
|
ctx context.Context,
|
|
1168
1263
|
model *SemanticModel,
|
|
1264
|
+
methodSets []semanticImplementationMethodSet,
|
|
1169
1265
|
) ([]semanticInterfaceImplementationGraphEntry, []Diagnostic) {
|
|
1170
|
-
|
|
1171
|
-
var concretes []*types.Named
|
|
1172
|
-
for named, semType := range model.types {
|
|
1173
|
-
if err := ctx.Err(); err != nil {
|
|
1174
|
-
return nil, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1175
|
-
}
|
|
1176
|
-
if semType.isInterface {
|
|
1177
|
-
interfaces = append(interfaces, named)
|
|
1178
|
-
continue
|
|
1179
|
-
}
|
|
1180
|
-
concretes = append(concretes, named)
|
|
1181
|
-
}
|
|
1266
|
+
interfaces := collectInterfaceImplementationCandidates(model)
|
|
1182
1267
|
sortNamedTypes(interfaces)
|
|
1183
|
-
sortNamedTypes(concretes)
|
|
1184
|
-
methodSets := implementationMethodSets(concretes)
|
|
1185
1268
|
|
|
1269
|
+
methodSetIndexByName := indexImplementationMethodSets(methodSets)
|
|
1186
1270
|
implementationGraph := make([]semanticInterfaceImplementationGraphEntry, 0)
|
|
1187
1271
|
for _, ifaceNamed := range interfaces {
|
|
1188
1272
|
if err := ctx.Err(); err != nil {
|
|
@@ -1197,10 +1281,11 @@ func (o *SemanticModelOwner) resolveInterfaceImplementationGraph(
|
|
|
1197
1281
|
if len(ifaceMethods) == 0 {
|
|
1198
1282
|
continue
|
|
1199
1283
|
}
|
|
1200
|
-
for _,
|
|
1284
|
+
for _, methodSetIdx := range implementationMethodSetCandidates(methodSetIndexByName, ifaceMethods) {
|
|
1201
1285
|
if err := ctx.Err(); err != nil {
|
|
1202
1286
|
return nil, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1203
1287
|
}
|
|
1288
|
+
methodSet := methodSets[methodSetIdx]
|
|
1204
1289
|
if implementation, ok := o.interfaceImplementationGraphEntry(methodSet, ifaceNamed, ifaceMethods); ok {
|
|
1205
1290
|
implementationGraph = append(implementationGraph, implementation)
|
|
1206
1291
|
}
|
|
@@ -1209,42 +1294,447 @@ func (o *SemanticModelOwner) resolveInterfaceImplementationGraph(
|
|
|
1209
1294
|
return implementationGraph, nil
|
|
1210
1295
|
}
|
|
1211
1296
|
|
|
1297
|
+
func (o *SemanticModelOwner) resolveAnonymousInterfaceImplementationGraph(
|
|
1298
|
+
ctx context.Context,
|
|
1299
|
+
model *SemanticModel,
|
|
1300
|
+
methodSets []semanticImplementationMethodSet,
|
|
1301
|
+
) ([]semanticAnonymousInterfaceImplementation, []Diagnostic) {
|
|
1302
|
+
interfaces := collectAnonymousInterfaceImplementationCandidates(model)
|
|
1303
|
+
for _, namedIface := range collectNamedInterfaceImplementationCandidates(model) {
|
|
1304
|
+
if err := ctx.Err(); err != nil {
|
|
1305
|
+
return nil, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1306
|
+
}
|
|
1307
|
+
methodSets = append(methodSets, semanticImplementationMethodSet{
|
|
1308
|
+
typ: namedIface,
|
|
1309
|
+
receiver: namedIface,
|
|
1310
|
+
methods: methodSetMap(namedIface),
|
|
1311
|
+
})
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
methodSetIndexByName := indexImplementationMethodSets(methodSets)
|
|
1315
|
+
implementationGraph := make([]semanticAnonymousInterfaceImplementation, 0)
|
|
1316
|
+
for _, iface := range interfaces {
|
|
1317
|
+
if err := ctx.Err(); err != nil {
|
|
1318
|
+
return nil, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1319
|
+
}
|
|
1320
|
+
iface.Complete()
|
|
1321
|
+
ifaceMethods := interfaceMethodMap(iface)
|
|
1322
|
+
if len(ifaceMethods) == 0 {
|
|
1323
|
+
continue
|
|
1324
|
+
}
|
|
1325
|
+
for _, methodSetIdx := range implementationMethodSetCandidates(methodSetIndexByName, ifaceMethods) {
|
|
1326
|
+
if err := ctx.Err(); err != nil {
|
|
1327
|
+
return nil, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1328
|
+
}
|
|
1329
|
+
methodSet := methodSets[methodSetIdx]
|
|
1330
|
+
if !implementationHasMethods(methodSet.methods, ifaceMethods) {
|
|
1331
|
+
continue
|
|
1332
|
+
}
|
|
1333
|
+
if !namedTypeHasParams(methodSet.typ) {
|
|
1334
|
+
if matches, exact := implementationHasExactMethodSignatures(methodSet.methods, ifaceMethods); exact {
|
|
1335
|
+
if !matches {
|
|
1336
|
+
continue
|
|
1337
|
+
}
|
|
1338
|
+
implementationGraph = append(implementationGraph, semanticAnonymousInterfaceImplementation{
|
|
1339
|
+
ifaceMethods: ifaceMethods,
|
|
1340
|
+
implMethods: methodSet.methods,
|
|
1341
|
+
})
|
|
1342
|
+
continue
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
receiver := methodSet.receiver
|
|
1346
|
+
if (methodSet.typ.TypeArgs() == nil || methodSet.typ.TypeArgs().Len() == 0) &&
|
|
1347
|
+
methodSet.typ.TypeParams() != nil && methodSet.typ.TypeParams().Len() != 0 {
|
|
1348
|
+
args := typeParamTypes(methodSet.typ.TypeParams())
|
|
1349
|
+
if instantiated, err := types.Instantiate(nil, methodSet.typ, args, false); err == nil {
|
|
1350
|
+
receiver = instantiated
|
|
1351
|
+
if methodSet.pointer {
|
|
1352
|
+
receiver = types.NewPointer(instantiated)
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
if !types.Implements(receiver, iface) {
|
|
1357
|
+
continue
|
|
1358
|
+
}
|
|
1359
|
+
implementationGraph = append(implementationGraph, semanticAnonymousInterfaceImplementation{
|
|
1360
|
+
ifaceMethods: ifaceMethods,
|
|
1361
|
+
implMethods: methodSet.methods,
|
|
1362
|
+
})
|
|
1363
|
+
}
|
|
1364
|
+
}
|
|
1365
|
+
return implementationGraph, nil
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
func (o *SemanticModelOwner) resolveImplementationMethodSets(
|
|
1369
|
+
ctx context.Context,
|
|
1370
|
+
model *SemanticModel,
|
|
1371
|
+
) ([]semanticImplementationMethodSet, []Diagnostic) {
|
|
1372
|
+
var concretes []*types.Named
|
|
1373
|
+
for named, semType := range model.types {
|
|
1374
|
+
if err := ctx.Err(); err != nil {
|
|
1375
|
+
return nil, []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1376
|
+
}
|
|
1377
|
+
if !semType.isInterface {
|
|
1378
|
+
concretes = append(concretes, namedOriginOrSelf(named))
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
sortNamedTypes(concretes)
|
|
1382
|
+
return implementationMethodSets(concretes), nil
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
func collectInterfaceImplementationCandidates(model *SemanticModel) []*types.Named {
|
|
1386
|
+
if model == nil {
|
|
1387
|
+
return nil
|
|
1388
|
+
}
|
|
1389
|
+
seen := make(map[string]bool)
|
|
1390
|
+
var interfaces []*types.Named
|
|
1391
|
+
add := func(named *types.Named) {
|
|
1392
|
+
if named == nil || named.Obj() == nil || named.Obj().Pkg() == nil {
|
|
1393
|
+
return
|
|
1394
|
+
}
|
|
1395
|
+
named = namedOriginOrSelf(named)
|
|
1396
|
+
if _, ok := types.Unalias(named.Underlying()).(*types.Interface); !ok {
|
|
1397
|
+
return
|
|
1398
|
+
}
|
|
1399
|
+
key := named.Obj().Pkg().Path() + "." + named.Obj().Name()
|
|
1400
|
+
if seen[key] {
|
|
1401
|
+
return
|
|
1402
|
+
}
|
|
1403
|
+
seen[key] = true
|
|
1404
|
+
interfaces = append(interfaces, named)
|
|
1405
|
+
}
|
|
1406
|
+
var collect func(types.Type)
|
|
1407
|
+
seenTypes := make(map[types.Type]bool)
|
|
1408
|
+
collect = func(typ types.Type) {
|
|
1409
|
+
if typ == nil {
|
|
1410
|
+
return
|
|
1411
|
+
}
|
|
1412
|
+
typ = types.Unalias(typ)
|
|
1413
|
+
if seenTypes[typ] {
|
|
1414
|
+
return
|
|
1415
|
+
}
|
|
1416
|
+
seenTypes[typ] = true
|
|
1417
|
+
switch typed := typ.(type) {
|
|
1418
|
+
case *types.Named:
|
|
1419
|
+
add(typed)
|
|
1420
|
+
collect(typed.Underlying())
|
|
1421
|
+
case *types.Pointer:
|
|
1422
|
+
collect(typed.Elem())
|
|
1423
|
+
case *types.Slice:
|
|
1424
|
+
collect(typed.Elem())
|
|
1425
|
+
case *types.Array:
|
|
1426
|
+
collect(typed.Elem())
|
|
1427
|
+
case *types.Map:
|
|
1428
|
+
collect(typed.Key())
|
|
1429
|
+
collect(typed.Elem())
|
|
1430
|
+
case *types.Chan:
|
|
1431
|
+
collect(typed.Elem())
|
|
1432
|
+
case *types.Struct:
|
|
1433
|
+
for field := range typed.Fields() {
|
|
1434
|
+
collect(field.Type())
|
|
1435
|
+
}
|
|
1436
|
+
case *types.Interface:
|
|
1437
|
+
typed.Complete()
|
|
1438
|
+
for method := range typed.Methods() {
|
|
1439
|
+
collect(method.Type())
|
|
1440
|
+
}
|
|
1441
|
+
case *types.Signature:
|
|
1442
|
+
if typed.Recv() != nil {
|
|
1443
|
+
collect(typed.Recv().Type())
|
|
1444
|
+
}
|
|
1445
|
+
collectTuple(collect, typed.Params())
|
|
1446
|
+
collectTuple(collect, typed.Results())
|
|
1447
|
+
}
|
|
1448
|
+
}
|
|
1449
|
+
for _, semType := range model.types {
|
|
1450
|
+
collect(semType.named)
|
|
1451
|
+
for _, field := range semType.fields {
|
|
1452
|
+
collect(field.typ)
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
for _, semFn := range model.functions {
|
|
1456
|
+
collect(semFn.signature)
|
|
1457
|
+
}
|
|
1458
|
+
for _, semValue := range model.values {
|
|
1459
|
+
collect(semValue.typ)
|
|
1460
|
+
}
|
|
1461
|
+
for _, semPkg := range model.packages {
|
|
1462
|
+
for _, assertion := range semPkg.typeAssertions {
|
|
1463
|
+
collect(assertion.source)
|
|
1464
|
+
collect(assertion.target)
|
|
1465
|
+
}
|
|
1466
|
+
for _, fact := range semPkg.nilFacts {
|
|
1467
|
+
collect(fact.typ)
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
return interfaces
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
func collectAnonymousInterfaceImplementationCandidates(model *SemanticModel) []*types.Interface {
|
|
1474
|
+
if model == nil {
|
|
1475
|
+
return nil
|
|
1476
|
+
}
|
|
1477
|
+
seen := make(map[*types.Interface]bool)
|
|
1478
|
+
var interfaces []*types.Interface
|
|
1479
|
+
add := func(iface *types.Interface) {
|
|
1480
|
+
if iface == nil || seen[iface] {
|
|
1481
|
+
return
|
|
1482
|
+
}
|
|
1483
|
+
seen[iface] = true
|
|
1484
|
+
interfaces = append(interfaces, iface)
|
|
1485
|
+
}
|
|
1486
|
+
var collect func(types.Type)
|
|
1487
|
+
seenTypes := make(map[types.Type]bool)
|
|
1488
|
+
collect = func(typ types.Type) {
|
|
1489
|
+
if typ == nil {
|
|
1490
|
+
return
|
|
1491
|
+
}
|
|
1492
|
+
typ = types.Unalias(typ)
|
|
1493
|
+
if seenTypes[typ] {
|
|
1494
|
+
return
|
|
1495
|
+
}
|
|
1496
|
+
seenTypes[typ] = true
|
|
1497
|
+
switch typed := typ.(type) {
|
|
1498
|
+
case *types.Named:
|
|
1499
|
+
collect(typed.Underlying())
|
|
1500
|
+
case *types.Pointer:
|
|
1501
|
+
collect(typed.Elem())
|
|
1502
|
+
case *types.Slice:
|
|
1503
|
+
collect(typed.Elem())
|
|
1504
|
+
case *types.Array:
|
|
1505
|
+
collect(typed.Elem())
|
|
1506
|
+
case *types.Map:
|
|
1507
|
+
collect(typed.Key())
|
|
1508
|
+
collect(typed.Elem())
|
|
1509
|
+
case *types.Chan:
|
|
1510
|
+
collect(typed.Elem())
|
|
1511
|
+
case *types.Struct:
|
|
1512
|
+
for field := range typed.Fields() {
|
|
1513
|
+
collect(field.Type())
|
|
1514
|
+
}
|
|
1515
|
+
case *types.Interface:
|
|
1516
|
+
typed.Complete()
|
|
1517
|
+
add(typed)
|
|
1518
|
+
for method := range typed.Methods() {
|
|
1519
|
+
collect(method.Type())
|
|
1520
|
+
}
|
|
1521
|
+
case *types.Signature:
|
|
1522
|
+
if typed.Recv() != nil {
|
|
1523
|
+
collect(typed.Recv().Type())
|
|
1524
|
+
}
|
|
1525
|
+
collectTuple(collect, typed.Params())
|
|
1526
|
+
collectTuple(collect, typed.Results())
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
for _, semType := range model.types {
|
|
1530
|
+
collect(semType.named)
|
|
1531
|
+
for _, field := range semType.fields {
|
|
1532
|
+
collect(field.typ)
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
for _, semFn := range model.functions {
|
|
1536
|
+
collect(semFn.signature)
|
|
1537
|
+
}
|
|
1538
|
+
for _, semValue := range model.values {
|
|
1539
|
+
collect(semValue.typ)
|
|
1540
|
+
}
|
|
1541
|
+
for _, semPkg := range model.packages {
|
|
1542
|
+
for _, assertion := range semPkg.typeAssertions {
|
|
1543
|
+
collect(assertion.source)
|
|
1544
|
+
collect(assertion.target)
|
|
1545
|
+
}
|
|
1546
|
+
for _, fact := range semPkg.nilFacts {
|
|
1547
|
+
collect(fact.typ)
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
return interfaces
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
func collectNamedInterfaceImplementationCandidates(model *SemanticModel) []*types.Named {
|
|
1554
|
+
if model == nil {
|
|
1555
|
+
return nil
|
|
1556
|
+
}
|
|
1557
|
+
seen := make(map[string]bool)
|
|
1558
|
+
var interfaces []*types.Named
|
|
1559
|
+
add := func(named *types.Named) {
|
|
1560
|
+
if named == nil {
|
|
1561
|
+
return
|
|
1562
|
+
}
|
|
1563
|
+
if _, ok := types.Unalias(named.Underlying()).(*types.Interface); !ok {
|
|
1564
|
+
return
|
|
1565
|
+
}
|
|
1566
|
+
key := types.TypeString(named, func(pkg *types.Package) string {
|
|
1567
|
+
if pkg == nil {
|
|
1568
|
+
return ""
|
|
1569
|
+
}
|
|
1570
|
+
return pkg.Path()
|
|
1571
|
+
})
|
|
1572
|
+
if seen[key] {
|
|
1573
|
+
return
|
|
1574
|
+
}
|
|
1575
|
+
seen[key] = true
|
|
1576
|
+
interfaces = append(interfaces, named)
|
|
1577
|
+
}
|
|
1578
|
+
var collect func(types.Type)
|
|
1579
|
+
seenTypes := make(map[types.Type]bool)
|
|
1580
|
+
collect = func(typ types.Type) {
|
|
1581
|
+
if typ == nil {
|
|
1582
|
+
return
|
|
1583
|
+
}
|
|
1584
|
+
typ = types.Unalias(typ)
|
|
1585
|
+
if seenTypes[typ] {
|
|
1586
|
+
return
|
|
1587
|
+
}
|
|
1588
|
+
seenTypes[typ] = true
|
|
1589
|
+
switch typed := typ.(type) {
|
|
1590
|
+
case *types.Named:
|
|
1591
|
+
add(typed)
|
|
1592
|
+
collect(typed.Underlying())
|
|
1593
|
+
case *types.Pointer:
|
|
1594
|
+
collect(typed.Elem())
|
|
1595
|
+
case *types.Slice:
|
|
1596
|
+
collect(typed.Elem())
|
|
1597
|
+
case *types.Array:
|
|
1598
|
+
collect(typed.Elem())
|
|
1599
|
+
case *types.Map:
|
|
1600
|
+
collect(typed.Key())
|
|
1601
|
+
collect(typed.Elem())
|
|
1602
|
+
case *types.Chan:
|
|
1603
|
+
collect(typed.Elem())
|
|
1604
|
+
case *types.Struct:
|
|
1605
|
+
for field := range typed.Fields() {
|
|
1606
|
+
collect(field.Type())
|
|
1607
|
+
}
|
|
1608
|
+
case *types.Interface:
|
|
1609
|
+
typed.Complete()
|
|
1610
|
+
for method := range typed.Methods() {
|
|
1611
|
+
collect(method.Type())
|
|
1612
|
+
}
|
|
1613
|
+
case *types.Signature:
|
|
1614
|
+
if typed.Recv() != nil {
|
|
1615
|
+
collect(typed.Recv().Type())
|
|
1616
|
+
}
|
|
1617
|
+
collectTuple(collect, typed.Params())
|
|
1618
|
+
collectTuple(collect, typed.Results())
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
for _, semType := range model.types {
|
|
1622
|
+
collect(semType.named)
|
|
1623
|
+
for _, field := range semType.fields {
|
|
1624
|
+
collect(field.typ)
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
for _, semFn := range model.functions {
|
|
1628
|
+
collect(semFn.signature)
|
|
1629
|
+
}
|
|
1630
|
+
for _, semValue := range model.values {
|
|
1631
|
+
collect(semValue.typ)
|
|
1632
|
+
}
|
|
1633
|
+
for _, semPkg := range model.packages {
|
|
1634
|
+
for _, assertion := range semPkg.typeAssertions {
|
|
1635
|
+
collect(assertion.source)
|
|
1636
|
+
collect(assertion.target)
|
|
1637
|
+
}
|
|
1638
|
+
for _, fact := range semPkg.nilFacts {
|
|
1639
|
+
collect(fact.typ)
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
return interfaces
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
func collectTuple(collect func(types.Type), tuple *types.Tuple) {
|
|
1646
|
+
if tuple == nil {
|
|
1647
|
+
return
|
|
1648
|
+
}
|
|
1649
|
+
for v := range tuple.Variables() {
|
|
1650
|
+
collect(v.Type())
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1212
1654
|
func (o *SemanticModelOwner) applyInterfaceAsyncMethods(
|
|
1213
1655
|
ctx context.Context,
|
|
1214
1656
|
model *SemanticModel,
|
|
1215
1657
|
interfaceGraph []semanticInterfaceImplementationGraphEntry,
|
|
1216
1658
|
) []Diagnostic {
|
|
1217
|
-
model.interfaceImplementations
|
|
1659
|
+
if cap(model.interfaceImplementations) < len(interfaceGraph) {
|
|
1660
|
+
model.interfaceImplementations = make([]semanticInterfaceImplementation, 0, len(interfaceGraph))
|
|
1661
|
+
} else {
|
|
1662
|
+
model.interfaceImplementations = model.interfaceImplementations[:0]
|
|
1663
|
+
}
|
|
1218
1664
|
for _, graphEntry := range interfaceGraph {
|
|
1219
1665
|
if err := ctx.Err(); err != nil {
|
|
1220
1666
|
return []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1221
1667
|
}
|
|
1222
1668
|
implementation := semanticInterfaceImplementation{
|
|
1223
|
-
typ:
|
|
1224
|
-
iface:
|
|
1225
|
-
pointer:
|
|
1226
|
-
asyncMethods: make(map[string]bool),
|
|
1669
|
+
typ: graphEntry.typ,
|
|
1670
|
+
iface: graphEntry.iface,
|
|
1671
|
+
pointer: graphEntry.pointer,
|
|
1227
1672
|
}
|
|
1228
|
-
for methodName,
|
|
1229
|
-
|
|
1673
|
+
for methodName, ifaceMethod := range graphEntry.ifaceMethods {
|
|
1674
|
+
implMethod := graphEntry.implMethods[methodName]
|
|
1675
|
+
implFn := semanticFunctionFor(model, implMethod)
|
|
1230
1676
|
if implFn != nil && implFn.async {
|
|
1231
|
-
|
|
1232
|
-
if ifaceFn := model
|
|
1677
|
+
model.markInterfaceMethodAsync(ifaceMethod)
|
|
1678
|
+
if ifaceFn := semanticFunctionFor(model, ifaceMethod); ifaceFn != nil {
|
|
1233
1679
|
markFunctionAsync(ifaceFn, "interface-implementation")
|
|
1234
1680
|
}
|
|
1681
|
+
markFunctionAsync(implFn, "interface-method")
|
|
1235
1682
|
}
|
|
1236
1683
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1684
|
+
model.interfaceImplementations = append(model.interfaceImplementations, implementation)
|
|
1685
|
+
}
|
|
1686
|
+
return nil
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
func (o *SemanticModelOwner) applyAnonymousInterfaceAsyncMethods(
|
|
1690
|
+
ctx context.Context,
|
|
1691
|
+
model *SemanticModel,
|
|
1692
|
+
interfaceGraph []semanticAnonymousInterfaceImplementation,
|
|
1693
|
+
) []Diagnostic {
|
|
1694
|
+
for _, graphEntry := range interfaceGraph {
|
|
1695
|
+
if err := ctx.Err(); err != nil {
|
|
1696
|
+
return []Diagnostic{contextCanceledDiagnostic(err)}
|
|
1697
|
+
}
|
|
1698
|
+
for methodName, ifaceMethod := range graphEntry.ifaceMethods {
|
|
1699
|
+
implMethod := graphEntry.implMethods[methodName]
|
|
1700
|
+
if model.functionAsync(implMethod) {
|
|
1701
|
+
model.markInterfaceMethodAsync(ifaceMethod)
|
|
1240
1702
|
}
|
|
1241
|
-
markFunctionAsync(model.functions[graphEntry.implMethods[methodName]], "interface-method")
|
|
1242
1703
|
}
|
|
1243
|
-
model.interfaceImplementations = append(model.interfaceImplementations, implementation)
|
|
1244
1704
|
}
|
|
1245
1705
|
return nil
|
|
1246
1706
|
}
|
|
1247
1707
|
|
|
1708
|
+
func (m *SemanticModel) functionAsync(fn *types.Func) bool {
|
|
1709
|
+
semFn := semanticFunctionFor(m, fn)
|
|
1710
|
+
if semFn != nil && semFn.async {
|
|
1711
|
+
return true
|
|
1712
|
+
}
|
|
1713
|
+
return m.interfaceMethodAsync(fn)
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
func (m *SemanticModel) markInterfaceMethodAsync(fn *types.Func) {
|
|
1717
|
+
if m == nil || fn == nil {
|
|
1718
|
+
return
|
|
1719
|
+
}
|
|
1720
|
+
m.asyncInterfaceMethodObjs[fn] = true
|
|
1721
|
+
key := m.functionFullName(fn)
|
|
1722
|
+
if key != "" {
|
|
1723
|
+
m.asyncInterfaceMethods[key] = true
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
func (m *SemanticModel) interfaceMethodAsync(fn *types.Func) bool {
|
|
1728
|
+
if m == nil || fn == nil {
|
|
1729
|
+
return false
|
|
1730
|
+
}
|
|
1731
|
+
if m.asyncInterfaceMethodObjs[fn] {
|
|
1732
|
+
return true
|
|
1733
|
+
}
|
|
1734
|
+
key := m.functionFullName(fn)
|
|
1735
|
+
return key != "" && m.asyncInterfaceMethods[key]
|
|
1736
|
+
}
|
|
1737
|
+
|
|
1248
1738
|
func contextCanceledDiagnostic(err error) Diagnostic {
|
|
1249
1739
|
return Diagnostic{
|
|
1250
1740
|
Severity: DiagnosticSeverityError,
|
|
@@ -1262,6 +1752,22 @@ func (o *SemanticModelOwner) interfaceImplementationGraphEntry(
|
|
|
1262
1752
|
return semanticInterfaceImplementationGraphEntry{}, false
|
|
1263
1753
|
}
|
|
1264
1754
|
|
|
1755
|
+
if !namedTypeHasParams(methodSet.typ) && !namedTypeHasParams(ifaceNamed) {
|
|
1756
|
+
if matches, exact := implementationHasExactMethodSignatures(methodSet.methods, ifaceMethods); exact {
|
|
1757
|
+
if !matches {
|
|
1758
|
+
return semanticInterfaceImplementationGraphEntry{}, false
|
|
1759
|
+
}
|
|
1760
|
+
implementation := semanticInterfaceImplementationGraphEntry{
|
|
1761
|
+
typ: methodSet.typ,
|
|
1762
|
+
iface: ifaceNamed,
|
|
1763
|
+
pointer: methodSet.pointer,
|
|
1764
|
+
ifaceMethods: ifaceMethods,
|
|
1765
|
+
implMethods: methodSet.methods,
|
|
1766
|
+
}
|
|
1767
|
+
return implementation, true
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1265
1771
|
implementsReceiver := methodSet.receiver
|
|
1266
1772
|
implementsIface := types.Type(ifaceNamed.Underlying())
|
|
1267
1773
|
if methodSet.typ.TypeParams() != nil && methodSet.typ.TypeParams().Len() != 0 {
|
|
@@ -1286,10 +1792,9 @@ func (o *SemanticModelOwner) interfaceImplementationGraphEntry(
|
|
|
1286
1792
|
typ: methodSet.typ,
|
|
1287
1793
|
iface: ifaceNamed,
|
|
1288
1794
|
pointer: methodSet.pointer,
|
|
1289
|
-
ifaceMethods:
|
|
1290
|
-
implMethods:
|
|
1795
|
+
ifaceMethods: ifaceMethods,
|
|
1796
|
+
implMethods: methodSet.methods,
|
|
1291
1797
|
}
|
|
1292
|
-
maps.Copy(implementation.ifaceMethods, ifaceMethods)
|
|
1293
1798
|
return implementation, true
|
|
1294
1799
|
}
|
|
1295
1800
|
|
|
@@ -1304,6 +1809,56 @@ func interfaceMethodMap(iface *types.Interface) map[string]*types.Func {
|
|
|
1304
1809
|
return methods
|
|
1305
1810
|
}
|
|
1306
1811
|
|
|
1812
|
+
func indexImplementationMethodSets(methodSets []semanticImplementationMethodSet) map[string][]int {
|
|
1813
|
+
index := make(map[string][]int)
|
|
1814
|
+
for methodSetIndex, methodSet := range methodSets {
|
|
1815
|
+
for methodName := range methodSet.methods {
|
|
1816
|
+
index[methodName] = append(index[methodName], methodSetIndex)
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
return index
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
func implementationMethodSetCandidates(
|
|
1823
|
+
index map[string][]int,
|
|
1824
|
+
ifaceMethods map[string]*types.Func,
|
|
1825
|
+
) []int {
|
|
1826
|
+
var candidates []int
|
|
1827
|
+
for methodName := range ifaceMethods {
|
|
1828
|
+
methodSets := index[methodName]
|
|
1829
|
+
if len(methodSets) == 0 {
|
|
1830
|
+
return nil
|
|
1831
|
+
}
|
|
1832
|
+
if candidates == nil || len(methodSets) < len(candidates) {
|
|
1833
|
+
candidates = methodSets
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
return candidates
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
func (m *SemanticModel) functionFullName(fn *types.Func) string {
|
|
1840
|
+
if m == nil || fn == nil {
|
|
1841
|
+
return ""
|
|
1842
|
+
}
|
|
1843
|
+
original := fn
|
|
1844
|
+
if fullName, ok := m.functionFullNames[original]; ok {
|
|
1845
|
+
return fullName
|
|
1846
|
+
}
|
|
1847
|
+
if origin := fn.Origin(); origin != nil && origin != fn {
|
|
1848
|
+
if fullName, ok := m.functionFullNames[origin]; ok {
|
|
1849
|
+
m.functionFullNames[original] = fullName
|
|
1850
|
+
return fullName
|
|
1851
|
+
}
|
|
1852
|
+
fn = origin
|
|
1853
|
+
}
|
|
1854
|
+
fullName := fn.FullName()
|
|
1855
|
+
m.functionFullNames[fn] = fullName
|
|
1856
|
+
if original != fn {
|
|
1857
|
+
m.functionFullNames[original] = fullName
|
|
1858
|
+
}
|
|
1859
|
+
return fullName
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1307
1862
|
func implementationMethodSets(concretes []*types.Named) []semanticImplementationMethodSet {
|
|
1308
1863
|
methodSets := make([]semanticImplementationMethodSet, 0, len(concretes)*2)
|
|
1309
1864
|
for _, concrete := range concretes {
|
|
@@ -1356,15 +1911,78 @@ func implementationHasMethods(
|
|
|
1356
1911
|
return true
|
|
1357
1912
|
}
|
|
1358
1913
|
|
|
1359
|
-
func
|
|
1914
|
+
func implementationHasExactMethodSignatures(
|
|
1360
1915
|
receiverMethods map[string]*types.Func,
|
|
1361
1916
|
ifaceMethods map[string]*types.Func,
|
|
1362
|
-
)
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1917
|
+
) (bool, bool) {
|
|
1918
|
+
for methodName, ifaceMethod := range ifaceMethods {
|
|
1919
|
+
implMethod := receiverMethods[methodName]
|
|
1920
|
+
if implMethod == nil {
|
|
1921
|
+
return false, true
|
|
1922
|
+
}
|
|
1923
|
+
if !methodPackagesCompatible(implMethod, ifaceMethod) {
|
|
1924
|
+
return false, true
|
|
1925
|
+
}
|
|
1926
|
+
implSignature, _ := implMethod.Type().(*types.Signature)
|
|
1927
|
+
ifaceSignature, _ := ifaceMethod.Type().(*types.Signature)
|
|
1928
|
+
if implSignature == nil || ifaceSignature == nil {
|
|
1929
|
+
return false, false
|
|
1930
|
+
}
|
|
1931
|
+
if !methodSignaturesIdentical(implSignature, ifaceSignature) {
|
|
1932
|
+
return false, true
|
|
1933
|
+
}
|
|
1366
1934
|
}
|
|
1367
|
-
return
|
|
1935
|
+
return true, true
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
func methodPackagesCompatible(implMethod *types.Func, ifaceMethod *types.Func) bool {
|
|
1939
|
+
if implMethod == nil || ifaceMethod == nil {
|
|
1940
|
+
return false
|
|
1941
|
+
}
|
|
1942
|
+
if ifaceMethod.Exported() {
|
|
1943
|
+
return true
|
|
1944
|
+
}
|
|
1945
|
+
return packagePathOfObject(implMethod) == packagePathOfObject(ifaceMethod)
|
|
1946
|
+
}
|
|
1947
|
+
|
|
1948
|
+
func packagePathOfObject(obj types.Object) string {
|
|
1949
|
+
if obj == nil || obj.Pkg() == nil {
|
|
1950
|
+
return ""
|
|
1951
|
+
}
|
|
1952
|
+
return obj.Pkg().Path()
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
func methodSignaturesIdentical(implSignature *types.Signature, ifaceSignature *types.Signature) bool {
|
|
1956
|
+
if implSignature == nil || ifaceSignature == nil || implSignature.Variadic() != ifaceSignature.Variadic() {
|
|
1957
|
+
return false
|
|
1958
|
+
}
|
|
1959
|
+
return tupleTypesIdentical(implSignature.Params(), ifaceSignature.Params()) &&
|
|
1960
|
+
tupleTypesIdentical(implSignature.Results(), ifaceSignature.Results())
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
func tupleTypesIdentical(a *types.Tuple, b *types.Tuple) bool {
|
|
1964
|
+
if a == nil || b == nil {
|
|
1965
|
+
return a == b
|
|
1966
|
+
}
|
|
1967
|
+
if a.Len() != b.Len() {
|
|
1968
|
+
return false
|
|
1969
|
+
}
|
|
1970
|
+
for idx := range a.Len() {
|
|
1971
|
+
if !types.IdenticalIgnoreTags(a.At(idx).Type(), b.At(idx).Type()) {
|
|
1972
|
+
return false
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
return true
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
func namedTypeHasParams(named *types.Named) bool {
|
|
1979
|
+
if named == nil {
|
|
1980
|
+
return false
|
|
1981
|
+
}
|
|
1982
|
+
if params := named.TypeParams(); params != nil && params.Len() != 0 {
|
|
1983
|
+
return true
|
|
1984
|
+
}
|
|
1985
|
+
return named.TypeArgs() != nil && named.TypeArgs().Len() != 0
|
|
1368
1986
|
}
|
|
1369
1987
|
|
|
1370
1988
|
func typeParamTypes(params *types.TypeParamList) []types.Type {
|
|
@@ -1378,6 +1996,16 @@ func typeParamTypes(params *types.TypeParamList) []types.Type {
|
|
|
1378
1996
|
return args
|
|
1379
1997
|
}
|
|
1380
1998
|
|
|
1999
|
+
func namedOriginOrSelf(named *types.Named) *types.Named {
|
|
2000
|
+
if named == nil {
|
|
2001
|
+
return nil
|
|
2002
|
+
}
|
|
2003
|
+
if origin := named.Origin(); origin != nil {
|
|
2004
|
+
return origin
|
|
2005
|
+
}
|
|
2006
|
+
return named
|
|
2007
|
+
}
|
|
2008
|
+
|
|
1381
2009
|
func sortNamedTypes(named []*types.Named) {
|
|
1382
2010
|
slices.SortFunc(named, func(a, b *types.Named) int {
|
|
1383
2011
|
return cmp.Compare(namedTypeKey(a), namedTypeKey(b))
|
|
@@ -1526,7 +2154,16 @@ func (o *SemanticModelOwner) recordGeneratedImports(
|
|
|
1526
2154
|
if file == "" || typ == nil {
|
|
1527
2155
|
return
|
|
1528
2156
|
}
|
|
1529
|
-
o.recordTypeImports(model, semPkg, file, currentPkg, typ,
|
|
2157
|
+
o.recordTypeImports(model, semPkg, file, currentPkg, typ, model.generatedImportSeen(file))
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
func (m *SemanticModel) generatedImportSeen(file string) map[types.Type]bool {
|
|
2161
|
+
seen := m.generatedImportTypes[file]
|
|
2162
|
+
if seen == nil {
|
|
2163
|
+
seen = make(map[types.Type]bool)
|
|
2164
|
+
m.generatedImportTypes[file] = seen
|
|
2165
|
+
}
|
|
2166
|
+
return seen
|
|
1530
2167
|
}
|
|
1531
2168
|
|
|
1532
2169
|
func (o *SemanticModelOwner) recordTypeImports(
|