@shortlink-org/portolan 0.1.0 → 0.2.1
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 +69 -205
- package/cli/init.mjs +285 -0
- package/cli/init.test.mjs +158 -0
- package/cli/portolan.mjs +37 -73
- package/index.html +19 -0
- package/package.json +5 -10
- package/plugins/README.md +66 -27
- package/plugins/portolan-go.wasm +0 -0
- package/portolan.json +52 -73
- package/public/landing/cats/bug-hunter.webp +0 -0
- package/public/landing/cats/compass-nap.webp +0 -0
- package/public/landing/cats/diagrammer.webp +0 -0
- package/public/landing/cats/docs-reader.webp +0 -0
- package/public/landing/cats/laptop.webp +0 -0
- package/public/landing/cats/map-inspector.webp +0 -0
- package/public/landing/cats/server-break.webp +0 -0
- package/public/landing/cats/star-mapper.webp +0 -0
- package/public/landing/cats/system-builder.webp +0 -0
- package/public/landing/cats/thread-tangle.webp +0 -0
- package/public/og.png +0 -0
- package/public/readme-header.webp +0 -0
- package/schema/portolan.schema.json +180 -0
- package/scripts/builtin-plugins.mjs +14 -0
- package/scripts/delivery-presets.mjs +353 -0
- package/scripts/gen.mjs +37 -4
- package/scripts/history.mjs +126 -0
- package/scripts/history.test.mjs +110 -0
- package/scripts/host-plugins/fetch-bsr.mjs +351 -0
- package/{plugins/fetch-bsr/options.schema.json → scripts/host-plugins/fetch-bsr.options.json} +4 -0
- package/scripts/host-plugins/fetch-bsr.test.mjs +212 -0
- package/scripts/host-plugins/fetch-csr.mjs +386 -0
- package/scripts/host-plugins/fetch-csr.test.mjs +178 -0
- package/scripts/host-plugins/fetch-git.mjs +379 -0
- package/scripts/host-plugins/fetch-git.test.mjs +210 -0
- package/scripts/local-api.mjs +27 -10
- package/scripts/local-api.test.mjs +85 -2
- package/scripts/manifest.mjs +3 -2
- package/scripts/package-smoke.mjs +24 -3
- package/scripts/plugin-host.mjs +77 -18
- package/scripts/plugin-host.test.mjs +50 -1
- package/scripts/plugin-wasm-worker.mjs +6 -3
- package/scripts/run-builtin.mjs +6 -26
- package/scripts/schema.mjs +6 -1
- package/src/app/App.tsx +24 -429
- package/src/app/Breadcrumbs.test.ts +7 -0
- package/src/app/Breadcrumbs.tsx +15 -2
- package/src/app/CatalogApp.tsx +436 -0
- package/src/app/Sidebar.tsx +0 -1
- package/src/chat/ChatPanel.tsx +98 -41
- package/src/chat/Composer.tsx +4 -2
- package/src/chat/Conversation.tsx +79 -15
- package/src/chat/Header.tsx +43 -9
- package/src/chat/Starter.tsx +64 -3
- package/src/chat/Steps.tsx +1 -1
- package/src/chat/flags.test.ts +51 -14
- package/src/chat/flags.ts +8 -2
- package/src/chat/page-context.test.ts +51 -0
- package/src/chat/page-context.ts +128 -0
- package/src/chat/prompt.test.ts +49 -1
- package/src/chat/prompt.ts +42 -1
- package/src/chat/tools.ts +7 -2
- package/src/chat/transport.ts +16 -4
- package/src/components/ProblemRow.tsx +182 -0
- package/src/data.ts +20 -5
- package/src/er/ErCanvas.tsx +1 -1
- package/src/graph/DependencyGraph.tsx +10 -1
- package/src/graph/FocusedEventGraph.tsx +1 -1
- package/src/graph/GraphToolbar.tsx +2 -4
- package/src/index.css +220 -2
- package/src/landing/DraggableReveal.tsx +168 -0
- package/src/landing/EstateGraph.tsx +28 -0
- package/src/landing/FlowPlayback.tsx +282 -0
- package/src/landing/HeroMap.tsx +128 -0
- package/src/landing/LandingPage.tsx +757 -0
- package/src/landing/ProductFrame.tsx +68 -0
- package/src/landing/ProductTour.tsx +371 -0
- package/src/landing/catalog.ts +25 -0
- package/src/landing/motion.tsx +52 -0
- package/src/lib/all-problems.ts +28 -0
- package/src/lib/local-api.ts +35 -1
- package/src/lib/setup-info.test.ts +8 -0
- package/src/lib/setup-info.ts +3 -2
- package/src/lib/source-code.ts +2 -1
- package/src/likec4/C4View.tsx +5 -0
- package/src/likec4/InteractiveView.tsx +5 -1
- package/src/map/ContextMapGraph.tsx +47 -20
- package/src/pages/ContextMap.tsx +5 -1
- package/src/pages/FlowDetail.tsx +24 -7
- package/src/pages/Overview.tsx +68 -12
- package/src/pages/Problems.tsx +6 -193
- package/src/pages/Settings.tsx +133 -108
- package/src/pages/settings/DeliverySettings.tsx +229 -0
- package/src/pages/settings/PreferencesSettings.tsx +101 -0
- package/src/routes.test.ts +20 -0
- package/src/routes.ts +13 -1
- package/vite.config.ts +17 -9
- package/catalog/enum_test.go +0 -46
- package/catalog/model.go +0 -932
- package/catalog/roundtrip_test.go +0 -185
- package/catalog/via_test.go +0 -38
- package/go.mod +0 -14
- package/go.sum +0 -14
- package/internal/commands/cargo.go +0 -154
- package/internal/commands/commands.go +0 -143
- package/internal/commands/commands_test.go +0 -323
- package/internal/commands/gradle.go +0 -77
- package/internal/commands/justfile.go +0 -82
- package/internal/commands/makefile.go +0 -106
- package/internal/commands/maven.go +0 -93
- package/internal/commands/packagejson.go +0 -159
- package/internal/commands/pyproject.go +0 -169
- package/internal/commands/taskfile.go +0 -101
- package/internal/commands/testdata/estate/.cargo/config.toml +0 -7
- package/internal/commands/testdata/estate/Makefile +0 -33
- package/internal/commands/testdata/estate/Taskfile.yml +0 -21
- package/internal/commands/testdata/estate/build.gradle.kts +0 -21
- package/internal/commands/testdata/estate/justfile +0 -20
- package/internal/commands/testdata/estate/package.json +0 -13
- package/internal/commands/testdata/estate/pom.xml +0 -29
- package/internal/commands/testdata/estate/pyproject.toml +0 -27
- package/internal/commands/testdata/estate/xtask/src/main.rs +0 -27
- package/internal/commands/testdata/golden/commands.json +0 -305
- package/internal/gohttp/analyze.go +0 -2500
- package/internal/gohttp/endpoints.go +0 -1067
- package/internal/gohttp/roots.go +0 -320
- package/internal/gohttp/typed.go +0 -143
- package/internal/goscan/constants.go +0 -85
- package/internal/goscan/goscan_test.go +0 -227
- package/internal/goscan/names.go +0 -52
- package/internal/goscan/parse_test.go +0 -11
- package/internal/goscan/source.go +0 -36
- package/internal/goscan/tree.go +0 -155
- package/internal/goscan/types.go +0 -99
- package/internal/wsdl/ids.go +0 -127
- package/internal/wsdl/ids_test.go +0 -21
- package/internal/wsdl/model.go +0 -62
- package/internal/wsdl/parse.go +0 -920
- package/internal/wsdl/parse_test.go +0 -133
- package/plugin/describe.go +0 -107
- package/plugin/describe_test.go +0 -114
- package/plugin/protocol.go +0 -117
- package/plugin/schematest/schematest.go +0 -126
- package/plugins/extract-adr/describe.go +0 -19
- package/plugins/extract-adr/describe_test.go +0 -11
- package/plugins/extract-adr/extract.go +0 -153
- package/plugins/extract-adr/extract_test.go +0 -350
- package/plugins/extract-adr/history.go +0 -99
- package/plugins/extract-adr/main.go +0 -65
- package/plugins/extract-adr/parse.go +0 -642
- package/plugins/extract-adr/parse_test.go +0 -405
- package/plugins/extract-asyncapi/describe.go +0 -19
- package/plugins/extract-asyncapi/describe_test.go +0 -11
- package/plugins/extract-asyncapi/extract.go +0 -315
- package/plugins/extract-asyncapi/extract_test.go +0 -197
- package/plugins/extract-asyncapi/main.go +0 -48
- package/plugins/extract-asyncapi/spec.go +0 -151
- package/plugins/extract-commands/describe.go +0 -19
- package/plugins/extract-commands/describe_test.go +0 -11
- package/plugins/extract-commands/extract.go +0 -79
- package/plugins/extract-commands/extract_test.go +0 -92
- package/plugins/extract-commands/main.go +0 -55
- package/plugins/extract-csr/avro.go +0 -258
- package/plugins/extract-csr/describe.go +0 -19
- package/plugins/extract-csr/describe_test.go +0 -11
- package/plugins/extract-csr/extract.go +0 -338
- package/plugins/extract-csr/extract_test.go +0 -374
- package/plugins/extract-csr/jsonschema.go +0 -343
- package/plugins/extract-csr/lock.go +0 -25
- package/plugins/extract-csr/main.go +0 -84
- package/plugins/extract-csr/subject.go +0 -102
- package/plugins/extract-flows/describe.go +0 -19
- package/plugins/extract-flows/describe_test.go +0 -11
- package/plugins/extract-flows/extract.go +0 -91
- package/plugins/extract-flows/main.go +0 -45
- package/plugins/extract-flows/parse.go +0 -593
- package/plugins/extract-flows/parse_test.go +0 -204
- package/plugins/extract-glossary/describe.go +0 -19
- package/plugins/extract-glossary/describe_test.go +0 -11
- package/plugins/extract-glossary/extract.go +0 -115
- package/plugins/extract-glossary/extract_test.go +0 -220
- package/plugins/extract-glossary/main.go +0 -59
- package/plugins/extract-glossary/parse.go +0 -214
- package/plugins/extract-glossary/parse_test.go +0 -203
- package/plugins/extract-go/aggregate.go +0 -214
- package/plugins/extract-go/client.go +0 -409
- package/plugins/extract-go/client_test.go +0 -266
- package/plugins/extract-go/describe.go +0 -19
- package/plugins/extract-go/describe_test.go +0 -11
- package/plugins/extract-go/enum.go +0 -195
- package/plugins/extract-go/enum_test.go +0 -82
- package/plugins/extract-go/event.go +0 -99
- package/plugins/extract-go/extract.go +0 -191
- package/plugins/extract-go/extract_test.go +0 -261
- package/plugins/extract-go/flow.go +0 -1441
- package/plugins/extract-go/flow_test.go +0 -609
- package/plugins/extract-go/httpclient.go +0 -174
- package/plugins/extract-go/httpclient_test.go +0 -296
- package/plugins/extract-go/ids.go +0 -92
- package/plugins/extract-go/layout.go +0 -225
- package/plugins/extract-go/layout_test.go +0 -125
- package/plugins/extract-go/lifecycle.go +0 -324
- package/plugins/extract-go/lifecycle_test.go +0 -108
- package/plugins/extract-go/main.go +0 -79
- package/plugins/extract-go/operation.go +0 -157
- package/plugins/extract-go/source.go +0 -316
- package/plugins/extract-go/transport.go +0 -321
- package/plugins/extract-go/transport_test.go +0 -145
- package/plugins/extract-go/wiring.go +0 -434
- package/plugins/extract-go-nats/describe.go +0 -19
- package/plugins/extract-go-nats/describe_test.go +0 -11
- package/plugins/extract-go-nats/extract.go +0 -177
- package/plugins/extract-go-nats/extract_test.go +0 -389
- package/plugins/extract-go-nats/index.go +0 -379
- package/plugins/extract-go-nats/main.go +0 -42
- package/plugins/extract-go-nats/resolve.go +0 -161
- package/plugins/extract-go-nats/sites.go +0 -224
- package/plugins/extract-graphql/describe.go +0 -19
- package/plugins/extract-graphql/describe_test.go +0 -11
- package/plugins/extract-graphql/extract.go +0 -433
- package/plugins/extract-graphql/extract_test.go +0 -256
- package/plugins/extract-graphql/ids.go +0 -49
- package/plugins/extract-graphql/lex.go +0 -237
- package/plugins/extract-graphql/main.go +0 -51
- package/plugins/extract-graphql/parse.go +0 -621
- package/plugins/extract-graphql/parse_test.go +0 -122
- package/plugins/extract-http-clients/describe.go +0 -19
- package/plugins/extract-http-clients/describe_test.go +0 -11
- package/plugins/extract-http-clients/extract.go +0 -705
- package/plugins/extract-http-clients/extract_test.go +0 -1263
- package/plugins/extract-http-clients/main.go +0 -42
- package/plugins/extract-openapi/describe.go +0 -19
- package/plugins/extract-openapi/describe_test.go +0 -11
- package/plugins/extract-openapi/discover.go +0 -243
- package/plugins/extract-openapi/extract.go +0 -526
- package/plugins/extract-openapi/extract_test.go +0 -545
- package/plugins/extract-openapi/main.go +0 -75
- package/plugins/extract-openapi/spec.go +0 -350
- package/plugins/extract-project/describe.go +0 -19
- package/plugins/extract-project/describe_test.go +0 -11
- package/plugins/extract-project/extract.go +0 -221
- package/plugins/extract-project/extract_test.go +0 -109
- package/plugins/extract-project/main.go +0 -41
- package/plugins/extract-proto/ast.go +0 -125
- package/plugins/extract-proto/consumes.go +0 -77
- package/plugins/extract-proto/describe.go +0 -19
- package/plugins/extract-proto/extract.go +0 -293
- package/plugins/extract-proto/extract_test.go +0 -459
- package/plugins/extract-proto/ids.go +0 -89
- package/plugins/extract-proto/ids_test.go +0 -57
- package/plugins/extract-proto/lex.go +0 -285
- package/plugins/extract-proto/main.go +0 -100
- package/plugins/extract-proto/module.go +0 -120
- package/plugins/extract-proto/parse.go +0 -720
- package/plugins/extract-proto/parse_test.go +0 -307
- package/plugins/extract-proto/provides.go +0 -236
- package/plugins/extract-proto/resolve.go +0 -222
- package/plugins/extract-proto/resolve_test.go +0 -119
- package/plugins/extract-redis/describe.go +0 -19
- package/plugins/extract-redis/describe_test.go +0 -11
- package/plugins/extract-redis/extract.go +0 -183
- package/plugins/extract-redis/extract_test.go +0 -168
- package/plugins/extract-redis/keyspaces.go +0 -469
- package/plugins/extract-redis/main.go +0 -44
- package/plugins/extract-river/describe.go +0 -19
- package/plugins/extract-river/describe_test.go +0 -11
- package/plugins/extract-river/extract.go +0 -507
- package/plugins/extract-river/extract_test.go +0 -132
- package/plugins/extract-river/main.go +0 -42
- package/plugins/extract-sql/ddl.go +0 -893
- package/plugins/extract-sql/ddl_test.go +0 -401
- package/plugins/extract-sql/describe.go +0 -19
- package/plugins/extract-sql/describe_test.go +0 -11
- package/plugins/extract-sql/layout.go +0 -221
- package/plugins/extract-sql/layout_test.go +0 -55
- package/plugins/extract-sql/lineage.go +0 -107
- package/plugins/extract-sql/main.go +0 -141
- package/plugins/extract-sql/maps.go +0 -564
- package/plugins/extract-sql/maps_java.go +0 -117
- package/plugins/extract-sql/maps_rust.go +0 -333
- package/plugins/extract-sql/maps_rust_test.go +0 -70
- package/plugins/extract-sql/maps_test.go +0 -204
- package/plugins/extract-sql/maps_ts.go +0 -398
- package/plugins/extract-sql/maps_ts_test.go +0 -136
- package/plugins/extract-sql/projection.go +0 -70
- package/plugins/extract-sql/projection_test.go +0 -50
- package/plugins/extract-sql/store.go +0 -420
- package/plugins/extract-sql/store_test.go +0 -233
- package/plugins/extract-sql/view.go +0 -295
- package/plugins/extract-watermill/describe.go +0 -19
- package/plugins/extract-watermill/describe_test.go +0 -11
- package/plugins/extract-watermill/extract.go +0 -1228
- package/plugins/extract-watermill/extract_test.go +0 -234
- package/plugins/extract-watermill/main.go +0 -41
- package/plugins/extract-wsdl/describe.go +0 -19
- package/plugins/extract-wsdl/describe_test.go +0 -11
- package/plugins/extract-wsdl/extract.go +0 -148
- package/plugins/extract-wsdl/extract_test.go +0 -45
- package/plugins/extract-wsdl/main.go +0 -53
- package/plugins/fetch-bsr/auth.go +0 -114
- package/plugins/fetch-bsr/bsr.go +0 -240
- package/plugins/fetch-bsr/cache.go +0 -66
- package/plugins/fetch-bsr/describe.go +0 -19
- package/plugins/fetch-bsr/fetch.go +0 -192
- package/plugins/fetch-bsr/fetch_test.go +0 -465
- package/plugins/fetch-bsr/lock.go +0 -71
- package/plugins/fetch-bsr/main.go +0 -117
- package/plugins/fetch-csr/auth.go +0 -95
- package/plugins/fetch-csr/cache.go +0 -69
- package/plugins/fetch-csr/describe.go +0 -19
- package/plugins/fetch-csr/describe_test.go +0 -11
- package/plugins/fetch-csr/fetch.go +0 -254
- package/plugins/fetch-csr/fetch_test.go +0 -494
- package/plugins/fetch-csr/lock.go +0 -95
- package/plugins/fetch-csr/main.go +0 -122
- package/plugins/fetch-csr/registry.go +0 -209
- package/plugins/fetch-git/cache.go +0 -65
- package/plugins/fetch-git/describe.go +0 -19
- package/plugins/fetch-git/describe_test.go +0 -11
- package/plugins/fetch-git/fetch.go +0 -181
- package/plugins/fetch-git/fetch_test.go +0 -332
- package/plugins/fetch-git/git.go +0 -169
- package/plugins/fetch-git/lock.go +0 -72
- package/plugins/fetch-git/main.go +0 -127
- package/plugins/fetch-git/offline.go +0 -39
- package/plugins/fetch-git/pin.go +0 -90
- package/plugins/fetch-git/pin_test.go +0 -74
- package/plugins/gen-backstage/describe.go +0 -17
- package/plugins/gen-backstage/main.go +0 -22
- package/plugins/gen-backstage/plugin.go +0 -473
- package/plugins/gen-backstage/plugin_test.go +0 -145
- package/plugins/gen-backstage.wasm +0 -0
- package/plugins/gen-markdown/adr.go +0 -162
- package/plugins/gen-markdown/aggregate.go +0 -362
- package/plugins/gen-markdown/canonical.go +0 -93
- package/plugins/gen-markdown/context.go +0 -90
- package/plugins/gen-markdown/coverage_test.go +0 -89
- package/plugins/gen-markdown/describe.go +0 -19
- package/plugins/gen-markdown/describe_test.go +0 -11
- package/plugins/gen-markdown/external.go +0 -71
- package/plugins/gen-markdown/flow.go +0 -277
- package/plugins/gen-markdown/glossary.go +0 -76
- package/plugins/gen-markdown/glossary_test.go +0 -148
- package/plugins/gen-markdown/llms.go +0 -302
- package/plugins/gen-markdown/main.go +0 -22
- package/plugins/gen-markdown/markdown.go +0 -254
- package/plugins/gen-markdown/markdown_test.go +0 -100
- package/plugins/gen-markdown/module.go +0 -107
- package/plugins/gen-markdown/plugin.go +0 -39
- package/plugins/gen-markdown/quality_test.go +0 -176
- package/plugins/gen-markdown/redis_test.go +0 -38
- package/plugins/gen-markdown/render.go +0 -344
- package/plugins/gen-markdown/render_test.go +0 -186
- package/plugins/gen-markdown/service.go +0 -456
- package/plugins/gen-markdown/source.go +0 -177
- package/plugins/gen-markdown/store.go +0 -201
- package/plugins/gen-markdown.wasm +0 -0
- package/plugins/gen-mermaid/describe.go +0 -17
- package/plugins/gen-mermaid/main.go +0 -22
- package/plugins/gen-mermaid/plugin.go +0 -104
- package/plugins/gen-mermaid/plugin_test.go +0 -33
- package/plugins/gen-mermaid.wasm +0 -0
- package/plugins/openapi/ids.go +0 -261
- package/plugins/openapi/ids_test.go +0 -98
- package/plugins/verify-codeowners/describe.go +0 -19
- package/plugins/verify-codeowners/describe_test.go +0 -11
- package/plugins/verify-codeowners/main.go +0 -75
- package/plugins/verify-codeowners/match.go +0 -85
- package/plugins/verify-codeowners/match_test.go +0 -47
- package/plugins/verify-codeowners/owners.go +0 -164
- package/plugins/verify-codeowners/owners_test.go +0 -225
- package/plugins/verify-codeowners/parse.go +0 -90
- package/plugins/verify-codeowners/parse_test.go +0 -62
- package/plugins/verify-otel/describe.go +0 -19
- package/plugins/verify-otel/describe_test.go +0 -11
- package/plugins/verify-otel/main.go +0 -53
- package/plugins/verify-otel/match.go +0 -336
- package/plugins/verify-otel/otlp.go +0 -200
- package/plugins/verify-otel/verify.go +0 -734
- package/plugins/verify-otel/verify_test.go +0 -460
- /package/{plugins/fetch-csr/options.schema.json → scripts/host-plugins/fetch-csr.options.json} +0 -0
- /package/{plugins/fetch-git/options.schema.json → scripts/host-plugins/fetch-git.options.json} +0 -0
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
package goscan
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"go/ast"
|
|
5
|
-
"os"
|
|
6
|
-
"path/filepath"
|
|
7
|
-
"reflect"
|
|
8
|
-
"strings"
|
|
9
|
-
"testing"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
func write(t *testing.T, root, name, contents string) {
|
|
13
|
-
t.Helper()
|
|
14
|
-
full := filepath.Join(root, name)
|
|
15
|
-
if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
|
|
16
|
-
t.Fatal(err)
|
|
17
|
-
}
|
|
18
|
-
if err := os.WriteFile(full, []byte(contents), 0o644); err != nil {
|
|
19
|
-
t.Fatal(err)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
func tree(t *testing.T) *Tree {
|
|
24
|
-
t.Helper()
|
|
25
|
-
root := t.TempDir()
|
|
26
|
-
write(t, root, "go.mod", "module example.com/m\n\ngo 1.22\n")
|
|
27
|
-
write(t, root, "main.go", `package main
|
|
28
|
-
|
|
29
|
-
import (
|
|
30
|
-
other "example.com/m/sub"
|
|
31
|
-
"example.com/m/vendor/lib"
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
const (
|
|
35
|
-
A = "a"
|
|
36
|
-
B = A
|
|
37
|
-
C = other.D
|
|
38
|
-
Inherited
|
|
39
|
-
Self1 = Self2
|
|
40
|
-
Self2 = Self1
|
|
41
|
-
Foreign = lib.Default
|
|
42
|
-
Number = 3
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
type Args struct {
|
|
46
|
-
ID string `+"`json:\"id\"`"+`
|
|
47
|
-
Secret string `+"`json:\"-\"`"+`
|
|
48
|
-
Plain int
|
|
49
|
-
hidden bool
|
|
50
|
-
}
|
|
51
|
-
`)
|
|
52
|
-
write(t, root, "sub/b.go", "package sub\n\nconst D = \"d\"\n")
|
|
53
|
-
write(t, root, "sub/b_test.go", "package sub\n\nconst Test = \"never\"\n")
|
|
54
|
-
write(t, root, "sub/gen.gen.go", "package sub\n\nconst Generated = \"never\"\n")
|
|
55
|
-
write(t, root, "vendor/lib/lib.go", "package lib\n\nconst Default = \"never\"\n")
|
|
56
|
-
write(t, root, ".hidden/h.go", "package hidden\n\nconst Hidden = \"never\"\n")
|
|
57
|
-
write(t, root, "node_modules/x/x.go", "package x\n\nconst X = \"never\"\n")
|
|
58
|
-
|
|
59
|
-
out, err := Read(root)
|
|
60
|
-
if err != nil {
|
|
61
|
-
t.Fatal(err)
|
|
62
|
-
}
|
|
63
|
-
return out
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
func TestReadKeepsTheSourceAndLeavesTheRest(t *testing.T) {
|
|
67
|
-
out := tree(t)
|
|
68
|
-
|
|
69
|
-
var names []string
|
|
70
|
-
for _, file := range out.Files {
|
|
71
|
-
names = append(names, file.Name+" "+file.Pkg)
|
|
72
|
-
}
|
|
73
|
-
want := []string{"main.go example.com/m", "sub/b.go example.com/m/sub"}
|
|
74
|
-
if !reflect.DeepEqual(names, want) {
|
|
75
|
-
t.Errorf("files: got %v, want %v", names, want)
|
|
76
|
-
}
|
|
77
|
-
if out.Module != "example.com/m" {
|
|
78
|
-
t.Errorf("module: got %q", out.Module)
|
|
79
|
-
}
|
|
80
|
-
for _, key := range []string{"example.com/m/sub.Test", "example.com/m/sub.Generated", "example.com/m/vendor/lib.Default", "example.com/m/.hidden.Hidden"} {
|
|
81
|
-
if _, found := out.Constants[key]; found {
|
|
82
|
-
t.Errorf("%s was read", key)
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
func TestImportsAreByLocalName(t *testing.T) {
|
|
88
|
-
out := tree(t)
|
|
89
|
-
got := out.Files[0].Imports
|
|
90
|
-
want := map[string]string{"other": "example.com/m/sub", "lib": "example.com/m/vendor/lib"}
|
|
91
|
-
if !reflect.DeepEqual(got, want) {
|
|
92
|
-
t.Errorf("imports: got %v, want %v", got, want)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
func TestADottedImportSegmentIsKnownByItsPackageName(t *testing.T) {
|
|
97
|
-
root := t.TempDir()
|
|
98
|
-
write(t, root, "go.mod", "module example.com/m\n")
|
|
99
|
-
write(t, root, "main.go", "package main\n\nimport (\n\t\"github.com/nats-io/nats.go\"\n\t\"gopkg.in/yaml.v3\"\n\t\"github.com/nats-io/nats.go/jetstream\"\n)\n")
|
|
100
|
-
out, err := Read(root)
|
|
101
|
-
if err != nil {
|
|
102
|
-
t.Fatal(err)
|
|
103
|
-
}
|
|
104
|
-
got := out.Files[0].Imports
|
|
105
|
-
want := map[string]string{
|
|
106
|
-
"nats.go": "github.com/nats-io/nats.go",
|
|
107
|
-
"nats": "github.com/nats-io/nats.go",
|
|
108
|
-
"yaml.v3": "gopkg.in/yaml.v3",
|
|
109
|
-
"yaml": "gopkg.in/yaml.v3",
|
|
110
|
-
"jetstream": "github.com/nats-io/nats.go/jetstream",
|
|
111
|
-
}
|
|
112
|
-
if !reflect.DeepEqual(got, want) {
|
|
113
|
-
t.Errorf("imports: got %v, want %v", got, want)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
func TestConstantsResolveThroughEachOther(t *testing.T) {
|
|
118
|
-
out := tree(t)
|
|
119
|
-
cases := map[string]string{
|
|
120
|
-
"example.com/m.A": "a",
|
|
121
|
-
"example.com/m.B": "a",
|
|
122
|
-
"example.com/m.C": "d",
|
|
123
|
-
"example.com/m.Inherited": "d",
|
|
124
|
-
"example.com/m.Self1": "",
|
|
125
|
-
"example.com/m.Foreign": "",
|
|
126
|
-
"example.com/m.Number": "",
|
|
127
|
-
"example.com/m.Missing": "",
|
|
128
|
-
}
|
|
129
|
-
for key, want := range cases {
|
|
130
|
-
if got := out.ConstantString(key, nil); got != want {
|
|
131
|
-
t.Errorf("%s: got %q, want %q", key, got, want)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
func TestForeignAnswersWhatTheTreeCannot(t *testing.T) {
|
|
137
|
-
out := tree(t)
|
|
138
|
-
out.Foreign = func(importPath, name string) (string, bool) {
|
|
139
|
-
if importPath == "example.com/m/vendor/lib" && name == "Default" {
|
|
140
|
-
return "default", true
|
|
141
|
-
}
|
|
142
|
-
return "", false
|
|
143
|
-
}
|
|
144
|
-
if got := out.ConstantString("example.com/m.Foreign", nil); got != "default" {
|
|
145
|
-
t.Errorf("got %q, want %q", got, "default")
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
func TestTypeKey(t *testing.T) {
|
|
150
|
-
out := tree(t)
|
|
151
|
-
file := out.Files[0]
|
|
152
|
-
parse := func(src string) ast.Expr {
|
|
153
|
-
expr, err := parseExpr(src)
|
|
154
|
-
if err != nil {
|
|
155
|
-
t.Fatal(err)
|
|
156
|
-
}
|
|
157
|
-
return expr
|
|
158
|
-
}
|
|
159
|
-
cases := map[string]string{
|
|
160
|
-
"Args": "example.com/m.Args",
|
|
161
|
-
"*Args": "example.com/m.Args",
|
|
162
|
-
"string": "string",
|
|
163
|
-
"other.Thing": "example.com/m/sub.Thing",
|
|
164
|
-
"[]other.Thing": "[]example.com/m/sub.Thing",
|
|
165
|
-
"map[string]Args": "map[string]example.com/m.Args",
|
|
166
|
-
"interface{ M() }": "interface",
|
|
167
|
-
"func()": "",
|
|
168
|
-
"a.b.C": "",
|
|
169
|
-
}
|
|
170
|
-
for src, want := range cases {
|
|
171
|
-
if got := out.TypeKey(parse(src), file); got != want {
|
|
172
|
-
t.Errorf("%s: got %q, want %q", src, got, want)
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
if got := out.TypeKey(nil, file); got != "" {
|
|
176
|
-
t.Errorf("nil: got %q", got)
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
func TestFieldsOfFollowTheJSONTag(t *testing.T) {
|
|
181
|
-
out := tree(t)
|
|
182
|
-
var body *ast.StructType
|
|
183
|
-
ast.Inspect(out.Files[0].Node, func(node ast.Node) bool {
|
|
184
|
-
if spec, ok := node.(*ast.TypeSpec); ok && spec.Name.Name == "Args" {
|
|
185
|
-
body = spec.Type.(*ast.StructType)
|
|
186
|
-
}
|
|
187
|
-
return body == nil
|
|
188
|
-
})
|
|
189
|
-
got := out.FieldsOf(body)
|
|
190
|
-
want := []string{"id string", "Plain int", "hidden bool"}
|
|
191
|
-
if !reflect.DeepEqual(got, want) {
|
|
192
|
-
t.Errorf("got %v, want %v", got, want)
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
func TestAtIsRelativeToTheRoot(t *testing.T) {
|
|
197
|
-
out := tree(t)
|
|
198
|
-
file := out.Files[1]
|
|
199
|
-
at := out.At(file.Node.Decls[0].Pos())
|
|
200
|
-
if at.String() != "sub/b.go:3" {
|
|
201
|
-
t.Errorf("got %q", at.String())
|
|
202
|
-
}
|
|
203
|
-
if (Source{File: "x.go"}).String() != "x.go" {
|
|
204
|
-
t.Error("a source with no line prints its line")
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
func TestNames(t *testing.T) {
|
|
209
|
-
if got := LastSegment("example.com/m.Args"); got != "Args" {
|
|
210
|
-
t.Errorf("LastSegment: %q", got)
|
|
211
|
-
}
|
|
212
|
-
if got := LastSegment("plain"); got != "plain" {
|
|
213
|
-
t.Errorf("LastSegment plain: %q", got)
|
|
214
|
-
}
|
|
215
|
-
if got := Slug(" Send Welcome_Mail!! "); got != "send-welcome-mail" {
|
|
216
|
-
t.Errorf("Slug: %q", got)
|
|
217
|
-
}
|
|
218
|
-
if got := Title("send-welcome_mail.v1"); got != "Send Welcome Mail V1" {
|
|
219
|
-
t.Errorf("Title: %q", got)
|
|
220
|
-
}
|
|
221
|
-
if got := FirstNonEmpty(" ", "", "x", "y"); got != "x" {
|
|
222
|
-
t.Errorf("FirstNonEmpty: %q", got)
|
|
223
|
-
}
|
|
224
|
-
if got := strings.TrimSpace(FirstNonEmpty(" ", "")); got != "" {
|
|
225
|
-
t.Errorf("FirstNonEmpty empty: %q", got)
|
|
226
|
-
}
|
|
227
|
-
}
|
package/internal/goscan/names.go
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
package goscan
|
|
2
|
-
|
|
3
|
-
import "strings"
|
|
4
|
-
|
|
5
|
-
// LastSegment is what follows the last dot: the name off a type key, the
|
|
6
|
-
// event off a wire name.
|
|
7
|
-
func LastSegment(value string) string {
|
|
8
|
-
if at := strings.LastIndex(value, "."); at >= 0 {
|
|
9
|
-
return value[at+1:]
|
|
10
|
-
}
|
|
11
|
-
return value
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Slug is a value as an identifier in a URL or a catalog id: lower case,
|
|
15
|
-
// runs of anything else collapsed to one dash, none at the ends.
|
|
16
|
-
func Slug(value string) string {
|
|
17
|
-
value = strings.ToLower(strings.TrimSpace(value))
|
|
18
|
-
var out strings.Builder
|
|
19
|
-
dash := false
|
|
20
|
-
for _, r := range value {
|
|
21
|
-
if r >= 'a' && r <= 'z' || r >= '0' && r <= '9' {
|
|
22
|
-
out.WriteRune(r)
|
|
23
|
-
dash = false
|
|
24
|
-
} else if out.Len() > 0 && !dash {
|
|
25
|
-
out.WriteByte('-')
|
|
26
|
-
dash = true
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return strings.TrimSuffix(out.String(), "-")
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Title is a slug or an identifier as words: split on dash, underscore and
|
|
33
|
-
// dot, each capitalised.
|
|
34
|
-
func Title(value string) string {
|
|
35
|
-
parts := strings.FieldsFunc(value, func(r rune) bool { return r == '-' || r == '_' || r == '.' })
|
|
36
|
-
for i := range parts {
|
|
37
|
-
if parts[i] != "" {
|
|
38
|
-
parts[i] = strings.ToUpper(parts[i][:1]) + parts[i][1:]
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return strings.Join(parts, " ")
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// FirstNonEmpty is the first value that is more than whitespace.
|
|
45
|
-
func FirstNonEmpty(values ...string) string {
|
|
46
|
-
for _, value := range values {
|
|
47
|
-
if strings.TrimSpace(value) != "" {
|
|
48
|
-
return value
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return ""
|
|
52
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
package goscan
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"fmt"
|
|
5
|
-
"go/ast"
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
// Source is a place in the tree, the way the catalog cites one: the file
|
|
9
|
-
// relative to the root, and the line when there is one.
|
|
10
|
-
type Source struct {
|
|
11
|
-
File string
|
|
12
|
-
Line int
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
func (s Source) String() string {
|
|
16
|
-
if s.Line == 0 {
|
|
17
|
-
return s.File
|
|
18
|
-
}
|
|
19
|
-
return fmt.Sprintf("%s:%d", s.File, s.Line)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// File is one parsed file: its path under the root, the import path of its
|
|
23
|
-
// package, its imports by local name, and the syntax.
|
|
24
|
-
type File struct {
|
|
25
|
-
Name string
|
|
26
|
-
Pkg string
|
|
27
|
-
Imports map[string]string
|
|
28
|
-
Node *ast.File
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// ConstExpr is a constant as it was declared: the expression, and the file it
|
|
32
|
-
// is in, since the expression's names mean what that file's imports say.
|
|
33
|
-
type ConstExpr struct {
|
|
34
|
-
Expr ast.Expr
|
|
35
|
-
File *File
|
|
36
|
-
}
|
package/internal/goscan/tree.go
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
// Package goscan reads a Go source tree the way the extractors need it: every
|
|
2
|
-
// non-test, non-generated file parsed once, each with the import path of its
|
|
3
|
-
// package and its imports by local name, and the string constants of the tree
|
|
4
|
-
// indexed so that a topic, a queue or a subject named by a constant resolves to
|
|
5
|
-
// the literal behind it.
|
|
6
|
-
//
|
|
7
|
-
// It is the part of a Go extractor that has nothing to do with what the
|
|
8
|
-
// extractor is looking for. River and Watermill read the tree this way, and the
|
|
9
|
-
// next Go extractor should not have to copy it a third time.
|
|
10
|
-
package goscan
|
|
11
|
-
|
|
12
|
-
import (
|
|
13
|
-
"fmt"
|
|
14
|
-
"go/ast"
|
|
15
|
-
"go/parser"
|
|
16
|
-
"go/token"
|
|
17
|
-
"io/fs"
|
|
18
|
-
"os"
|
|
19
|
-
"path"
|
|
20
|
-
"path/filepath"
|
|
21
|
-
"sort"
|
|
22
|
-
"strconv"
|
|
23
|
-
"strings"
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
// Tree is one Go module's source, read once.
|
|
27
|
-
type Tree struct {
|
|
28
|
-
Root string
|
|
29
|
-
Module string
|
|
30
|
-
Fset *token.FileSet
|
|
31
|
-
// Files in path order, so that whatever is read off them comes out in the
|
|
32
|
-
// same order every run.
|
|
33
|
-
Files []*File
|
|
34
|
-
// Constants is every constant of the tree by "<import path>.<Name>", as
|
|
35
|
-
// the expression that declared it, so a constant defined through another
|
|
36
|
-
// is followed rather than copied.
|
|
37
|
-
Constants map[string]ConstExpr
|
|
38
|
-
// Foreign is what an identifier from a package outside the tree is worth,
|
|
39
|
-
// when the extractor knows: river.QueueDefault is "default", and nothing
|
|
40
|
-
// in the tree says so. Nil when there is nothing to say.
|
|
41
|
-
Foreign func(importPath, name string) (string, bool)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Read parses the tree under root. Test files, generated files, vendored
|
|
45
|
-
// code and dot-directories are left out: they are not what the service
|
|
46
|
-
// says about itself.
|
|
47
|
-
func Read(root string) (*Tree, error) {
|
|
48
|
-
t := &Tree{Root: root, Module: ModulePath(root), Fset: token.NewFileSet(), Constants: map[string]ConstExpr{}}
|
|
49
|
-
|
|
50
|
-
var names []string
|
|
51
|
-
err := filepath.WalkDir(root, func(name string, entry fs.DirEntry, err error) error {
|
|
52
|
-
if err != nil {
|
|
53
|
-
return err
|
|
54
|
-
}
|
|
55
|
-
if entry.IsDir() {
|
|
56
|
-
if name != root && strings.HasPrefix(entry.Name(), ".") {
|
|
57
|
-
return filepath.SkipDir
|
|
58
|
-
}
|
|
59
|
-
switch entry.Name() {
|
|
60
|
-
case ".git", ".portolan", "node_modules", "vendor":
|
|
61
|
-
if name != root {
|
|
62
|
-
return filepath.SkipDir
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return nil
|
|
66
|
-
}
|
|
67
|
-
base := entry.Name()
|
|
68
|
-
if !strings.HasSuffix(base, ".go") || strings.HasSuffix(base, "_test.go") || strings.HasSuffix(base, ".gen.go") || strings.HasSuffix(base, "_generated.go") {
|
|
69
|
-
return nil
|
|
70
|
-
}
|
|
71
|
-
names = append(names, name)
|
|
72
|
-
return nil
|
|
73
|
-
})
|
|
74
|
-
if err != nil {
|
|
75
|
-
return nil, err
|
|
76
|
-
}
|
|
77
|
-
sort.Strings(names)
|
|
78
|
-
|
|
79
|
-
for _, name := range names {
|
|
80
|
-
node, err := parser.ParseFile(t.Fset, name, nil, parser.ParseComments)
|
|
81
|
-
if err != nil {
|
|
82
|
-
return nil, fmt.Errorf("parse %s: %w", name, err)
|
|
83
|
-
}
|
|
84
|
-
rel, _ := filepath.Rel(root, name)
|
|
85
|
-
t.Files = append(t.Files, &File{
|
|
86
|
-
Name: filepath.ToSlash(rel),
|
|
87
|
-
Pkg: t.PackagePath(filepath.Dir(name)),
|
|
88
|
-
Imports: ImportsOf(node),
|
|
89
|
-
Node: node,
|
|
90
|
-
})
|
|
91
|
-
}
|
|
92
|
-
t.indexConstants()
|
|
93
|
-
|
|
94
|
-
return t, nil
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// PackagePath is the import path of the package in dir: the module path
|
|
98
|
-
// with the directory under it.
|
|
99
|
-
func (t *Tree) PackagePath(dir string) string {
|
|
100
|
-
rel, err := filepath.Rel(t.Root, dir)
|
|
101
|
-
if err != nil || rel == "." {
|
|
102
|
-
return t.Module
|
|
103
|
-
}
|
|
104
|
-
return strings.TrimSuffix(t.Module, "/") + "/" + filepath.ToSlash(rel)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// At is where a node is, relative to the root.
|
|
108
|
-
func (t *Tree) At(pos token.Pos) Source {
|
|
109
|
-
position := t.Fset.Position(pos)
|
|
110
|
-
rel, err := filepath.Rel(t.Root, position.Filename)
|
|
111
|
-
if err != nil {
|
|
112
|
-
rel = position.Filename
|
|
113
|
-
}
|
|
114
|
-
return Source{File: filepath.ToSlash(rel), Line: position.Line}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// ModulePath is what go.mod under root calls the module; the cleaned root
|
|
118
|
-
// when there is no go.mod to ask.
|
|
119
|
-
func ModulePath(root string) string {
|
|
120
|
-
data, err := os.ReadFile(filepath.Join(root, "go.mod"))
|
|
121
|
-
if err == nil {
|
|
122
|
-
for _, line := range strings.Split(string(data), "\n") {
|
|
123
|
-
if value, ok := strings.CutPrefix(strings.TrimSpace(line), "module "); ok {
|
|
124
|
-
return strings.TrimSpace(value)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return filepath.ToSlash(filepath.Clean(root))
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// ImportsOf is a file's imports by the name the file uses for them: the alias
|
|
132
|
-
// when there is one, the last path segment when there is not. Blank and dot
|
|
133
|
-
// imports keep the segment, since nothing in the file refers to them by name.
|
|
134
|
-
//
|
|
135
|
-
// A segment with a dot in it - `nats.go`, `yaml.v3` - is not a Go identifier,
|
|
136
|
-
// and the package behind it is called by what comes before the dot; that name
|
|
137
|
-
// is recorded too, since it is the one the file uses.
|
|
138
|
-
func ImportsOf(node *ast.File) map[string]string {
|
|
139
|
-
out := map[string]string{}
|
|
140
|
-
for _, spec := range node.Imports {
|
|
141
|
-
value, err := strconv.Unquote(spec.Path.Value)
|
|
142
|
-
if err != nil {
|
|
143
|
-
continue
|
|
144
|
-
}
|
|
145
|
-
name := path.Base(value)
|
|
146
|
-
if spec.Name != nil && spec.Name.Name != "_" && spec.Name.Name != "." {
|
|
147
|
-
name = spec.Name.Name
|
|
148
|
-
}
|
|
149
|
-
out[name] = value
|
|
150
|
-
if short, _, dotted := strings.Cut(name, "."); dotted && short != "" {
|
|
151
|
-
out[short] = value
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return out
|
|
155
|
-
}
|
package/internal/goscan/types.go
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
package goscan
|
|
2
|
-
|
|
3
|
-
import (
|
|
4
|
-
"bytes"
|
|
5
|
-
"go/ast"
|
|
6
|
-
"go/printer"
|
|
7
|
-
"reflect"
|
|
8
|
-
"strconv"
|
|
9
|
-
"strings"
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
// Unwrap takes the parentheses, the address-of and the pointer off an
|
|
13
|
-
// expression, down to the thing itself.
|
|
14
|
-
func Unwrap(expr ast.Expr) ast.Expr {
|
|
15
|
-
for {
|
|
16
|
-
switch value := expr.(type) {
|
|
17
|
-
case *ast.ParenExpr:
|
|
18
|
-
expr = value.X
|
|
19
|
-
case *ast.UnaryExpr:
|
|
20
|
-
expr = value.X
|
|
21
|
-
case *ast.StarExpr:
|
|
22
|
-
expr = value.X
|
|
23
|
-
default:
|
|
24
|
-
return expr
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// TypeKey names a type the way the tree indexes types: "<import path>.<Name>"
|
|
30
|
-
// for a named type, whether written bare or through an import; the builtin's
|
|
31
|
-
// own name; "[]T" and "map[K]V" over their parts; "interface" for any
|
|
32
|
-
// interface literal. Empty for a type this reader does not name.
|
|
33
|
-
func (t *Tree) TypeKey(expr ast.Expr, file *File) string {
|
|
34
|
-
if expr == nil {
|
|
35
|
-
return ""
|
|
36
|
-
}
|
|
37
|
-
switch value := Unwrap(expr).(type) {
|
|
38
|
-
case *ast.Ident:
|
|
39
|
-
if IsBuiltin(value.Name) {
|
|
40
|
-
return value.Name
|
|
41
|
-
}
|
|
42
|
-
return file.Pkg + "." + value.Name
|
|
43
|
-
case *ast.SelectorExpr:
|
|
44
|
-
if base, ok := value.X.(*ast.Ident); ok {
|
|
45
|
-
return file.Imports[base.Name] + "." + value.Sel.Name
|
|
46
|
-
}
|
|
47
|
-
case *ast.ArrayType:
|
|
48
|
-
return "[]" + t.TypeKey(value.Elt, file)
|
|
49
|
-
case *ast.MapType:
|
|
50
|
-
return "map[" + t.TypeKey(value.Key, file) + "]" + t.TypeKey(value.Value, file)
|
|
51
|
-
case *ast.InterfaceType:
|
|
52
|
-
return "interface"
|
|
53
|
-
}
|
|
54
|
-
return ""
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// IsBuiltin is whether a bare identifier is one of the language's own types.
|
|
58
|
-
func IsBuiltin(name string) bool {
|
|
59
|
-
switch name {
|
|
60
|
-
case "string", "bool", "byte", "rune", "int", "int8", "int16", "int32", "int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "error", "any":
|
|
61
|
-
return true
|
|
62
|
-
}
|
|
63
|
-
return false
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// FieldsOf lists a struct's named fields as "name type", the name being what
|
|
67
|
-
// the json tag says when it says anything, and a field tagged "-" left out:
|
|
68
|
-
// the fields as they travel, not as the code calls them.
|
|
69
|
-
func (t *Tree) FieldsOf(body *ast.StructType) []string {
|
|
70
|
-
var out []string
|
|
71
|
-
for _, field := range body.Fields.List {
|
|
72
|
-
if len(field.Names) == 0 {
|
|
73
|
-
continue
|
|
74
|
-
}
|
|
75
|
-
typeName := t.PrintNode(field.Type)
|
|
76
|
-
for _, ident := range field.Names {
|
|
77
|
-
name := ident.Name
|
|
78
|
-
if field.Tag != nil {
|
|
79
|
-
tagText, _ := strconv.Unquote(field.Tag.Value)
|
|
80
|
-
jsonName := strings.Split(reflect.StructTag(tagText).Get("json"), ",")[0]
|
|
81
|
-
if jsonName == "-" {
|
|
82
|
-
continue
|
|
83
|
-
}
|
|
84
|
-
if jsonName != "" {
|
|
85
|
-
name = jsonName
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
out = append(out, name+" "+typeName)
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return out
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// PrintNode is a node as source text.
|
|
95
|
-
func (t *Tree) PrintNode(node ast.Node) string {
|
|
96
|
-
var out bytes.Buffer
|
|
97
|
-
_ = printer.Fprint(&out, t.Fset, node)
|
|
98
|
-
return out.String()
|
|
99
|
-
}
|