From 423825695f5b7a5c9997a717a19af4f2d5bbdfaf Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Thu, 25 Jun 2020 23:40:43 +0300 Subject: [PATCH] vendor: `make vendor-update` --- go.mod | 16 +- go.sum | 41 +- vendor/cloud.google.com/go/CHANGES.md | 26 + vendor/cloud.google.com/go/CONTRIBUTING.md | 100 +- vendor/cloud.google.com/go/README.md | 5 +- vendor/cloud.google.com/go/RELEASING.md | 73 +- .../go/compute/metadata/metadata.go | 2 +- vendor/cloud.google.com/go/go.mod | 7 +- vendor/cloud.google.com/go/go.sum | 12 +- .../go/internal/.repo-metadata-full.json | 18 +- .../go/internal/version/version.go | 2 +- vendor/cloud.google.com/go/tools.go | 1 - vendor/github.com/BurntSushi/toml/.gitignore | 5 - vendor/github.com/BurntSushi/toml/.travis.yml | 15 - vendor/github.com/BurntSushi/toml/COMPATIBLE | 3 - vendor/github.com/BurntSushi/toml/COPYING | 21 - vendor/github.com/BurntSushi/toml/Makefile | 19 - vendor/github.com/BurntSushi/toml/README.md | 218 - vendor/github.com/BurntSushi/toml/decode.go | 509 --- .../github.com/BurntSushi/toml/decode_meta.go | 121 - vendor/github.com/BurntSushi/toml/doc.go | 27 - vendor/github.com/BurntSushi/toml/encode.go | 568 --- .../BurntSushi/toml/encoding_types.go | 19 - .../BurntSushi/toml/encoding_types_1.1.go | 18 - vendor/github.com/BurntSushi/toml/lex.go | 953 ---- vendor/github.com/BurntSushi/toml/parse.go | 592 --- vendor/github.com/BurntSushi/toml/session.vim | 1 - .../github.com/BurntSushi/toml/type_check.go | 91 - .../github.com/BurntSushi/toml/type_fields.go | 242 -- .../aws/aws-sdk-go/aws/endpoints/defaults.go | 78 +- .../github.com/aws/aws-sdk-go/aws/version.go | 2 +- vendor/golang.org/x/sys/unix/syscall_linux.go | 16 +- .../x/sys/unix/ztypes_freebsd_arm.go | 12 +- .../x/tools/cmd/goimports/goimports.go | 11 +- .../x/tools/go/analysis/analysis.go | 237 - .../x/tools/go/analysis/diagnostic.go | 61 - vendor/golang.org/x/tools/go/analysis/doc.go | 310 -- .../go/analysis/passes/inspect/inspect.go | 49 - .../x/tools/go/analysis/validate.go | 97 - .../x/tools/go/ast/inspector/inspector.go | 186 - .../x/tools/go/ast/inspector/typeof.go | 216 - .../x/tools/go/buildutil/allpackages.go | 198 - .../x/tools/go/buildutil/fakecontext.go | 109 - .../x/tools/go/buildutil/overlay.go | 103 - .../golang.org/x/tools/go/buildutil/tags.go | 75 - .../golang.org/x/tools/go/buildutil/util.go | 212 - .../golang.org/x/tools/go/internal/cgo/cgo.go | 220 - .../x/tools/go/internal/cgo/cgo_pkgconfig.go | 39 - .../tools/go/internal/packagesdriver/sizes.go | 117 - vendor/golang.org/x/tools/go/loader/doc.go | 204 - vendor/golang.org/x/tools/go/loader/loader.go | 1086 ----- vendor/golang.org/x/tools/go/loader/util.go | 124 - vendor/golang.org/x/tools/go/packages/doc.go | 221 - .../x/tools/go/packages/external.go | 101 - .../golang.org/x/tools/go/packages/golist.go | 907 ---- .../x/tools/go/packages/golist_overlay.go | 465 -- .../x/tools/go/packages/loadmode_string.go | 57 - .../x/tools/go/packages/packages.go | 1212 ------ .../golang.org/x/tools/go/packages/visit.go | 55 - .../x/tools/go/types/objectpath/objectpath.go | 524 --- .../x/tools/go/types/typeutil/callee.go | 46 - .../x/tools/go/types/typeutil/imports.go | 31 - .../x/tools/go/types/typeutil/map.go | 313 -- .../tools/go/types/typeutil/methodsetcache.go | 72 - .../x/tools/go/types/typeutil/ui.go | 52 - .../internal/analysisinternal/analysis.go | 118 - .../x/tools/internal/gocommand/invoke.go | 120 +- .../x/tools/internal/imports/fix.go | 86 +- .../x/tools/internal/imports/imports.go | 15 +- .../x/tools/internal/imports/mod.go | 8 +- .../internal/packagesinternal/packages.go | 14 - .../x/tools/internal/typesinternal/types.go | 28 - vendor/google.golang.org/grpc/.travis.yml | 14 +- vendor/google.golang.org/grpc/README.md | 5 +- .../grpc/attributes/attributes.go | 6 + vendor/google.golang.org/grpc/balancer.go | 391 -- .../grpc/balancer/balancer.go | 172 +- .../grpc/balancer/base/balancer.go | 109 +- .../grpc/balancer/base/base.go | 37 +- .../grpc/balancer/grpclb/state/state.go | 51 + .../grpc/balancer/roundrobin/roundrobin.go | 6 +- .../grpc/balancer_conn_wrappers.go | 37 +- .../grpc/balancer_v1_wrapper.go | 334 -- .../grpc_binarylog_v1/binarylog.pb.go | 320 +- vendor/google.golang.org/grpc/clientconn.go | 46 +- .../grpc/credentials/credentials.go | 56 +- vendor/google.golang.org/grpc/dialoptions.go | 52 +- vendor/google.golang.org/grpc/doc.go | 2 + vendor/google.golang.org/grpc/go.mod | 3 +- vendor/google.golang.org/grpc/go.sum | 4 + .../grpc/internal/binarylog/binarylog.go | 3 +- .../grpc/internal/binarylog/regenerate.sh | 33 - .../grpc/internal/envconfig/envconfig.go | 2 +- .../{binarylog/util.go => grpcutil/method.go} | 7 +- .../grpc/internal/internal.go | 9 + .../internal/resolver/dns/dns_resolver.go | 11 +- .../internal/serviceconfig/serviceconfig.go | 90 + .../grpc/internal/status/status.go | 23 +- .../grpc/internal/syscall/syscall_nonlinux.go | 2 + .../grpc/internal/transport/controlbuf.go | 64 +- .../grpc/internal/transport/http2_client.go | 44 +- .../grpc/internal/transport/http2_server.go | 7 - .../grpc/internal/transport/transport.go | 12 +- .../grpc/naming/dns_resolver.go | 293 -- .../google.golang.org/grpc/naming/naming.go | 68 - .../google.golang.org/grpc/picker_wrapper.go | 71 +- vendor/google.golang.org/grpc/pickfirst.go | 36 +- vendor/google.golang.org/grpc/regenerate.sh | 79 + .../grpc/resolver/resolver.go | 5 +- vendor/google.golang.org/grpc/rpc_util.go | 45 +- vendor/google.golang.org/grpc/server.go | 102 +- .../google.golang.org/grpc/service_config.go | 78 +- vendor/google.golang.org/grpc/stats/stats.go | 2 - vendor/google.golang.org/grpc/stream.go | 51 +- vendor/google.golang.org/grpc/version.go | 2 +- vendor/google.golang.org/grpc/vet.sh | 52 +- .../cmd/protoc-gen-go/internal_gengo/main.go | 59 +- .../internal_gengo/well_known_types.go | 1077 +++++ .../protobuf/compiler/protogen/protogen.go | 24 +- .../protobuf/encoding/prototext/decode.go | 65 +- .../protobuf/encoding/prototext/encode.go | 12 +- .../protobuf/internal/fieldnum/any_gen.go | 13 - .../protobuf/internal/fieldnum/api_gen.go | 35 - .../internal/fieldnum/descriptor_gen.go | 240 -- .../protobuf/internal/fieldnum/doc.go | 7 - .../internal/fieldnum/duration_gen.go | 13 - .../protobuf/internal/fieldnum/empty_gen.go | 10 - .../internal/fieldnum/field_mask_gen.go | 12 - .../internal/fieldnum/source_context_gen.go | 12 - .../protobuf/internal/fieldnum/struct_gen.go | 33 - .../internal/fieldnum/timestamp_gen.go | 13 - .../protobuf/internal/fieldnum/type_gen.go | 53 - .../internal/fieldnum/wrappers_gen.go | 52 - .../protobuf/internal/filedesc/build.go | 16 +- .../protobuf/internal/filedesc/desc.go | 5 +- .../protobuf/internal/filedesc/desc_init.go | 62 +- .../protobuf/internal/filedesc/desc_lazy.go | 124 +- .../protobuf/internal/filedesc/desc_list.go | 6 +- .../protobuf/internal/genid/any_gen.go | 34 + .../protobuf/internal/genid/api_gen.go | 106 + .../protobuf/internal/genid/descriptor_gen.go | 829 ++++ .../protobuf/internal/genid/doc.go | 11 + .../protobuf/internal/genid/duration_gen.go | 34 + .../protobuf/internal/genid/empty_gen.go | 19 + .../protobuf/internal/genid/field_mask_gen.go | 31 + .../protobuf/internal/genid/goname.go | 25 + .../protobuf/internal/genid/map_entry.go | 16 + .../internal/genid/source_context_gen.go | 31 + .../protobuf/internal/genid/struct_gen.go | 116 + .../protobuf/internal/genid/timestamp_gen.go | 34 + .../protobuf/internal/genid/type_gen.go | 184 + .../protobuf/internal/genid/wrappers.go | 13 + .../protobuf/internal/genid/wrappers_gen.go | 175 + .../protobuf/internal/genname/name.go | 25 - .../protobuf/internal/impl/api_export.go | 7 + .../protobuf/internal/impl/codec_map.go | 5 +- .../protobuf/internal/impl/message.go | 10 +- .../protobuf/internal/impl/validate.go | 5 +- .../protobuf/internal/version/version.go | 2 +- .../protobuf/proto/decode.go | 5 +- .../reflect/protodesc/desc_validate.go | 5 +- .../protobuf/reflect/protoreflect/proto.go | 50 +- .../protobuf/types/known/anypb/any.pb.go | 207 + .../types/known/durationpb/duration.pb.go | 130 + .../types/known/timestamppb/timestamp.pb.go | 110 + vendor/honnef.co/go/tools/LICENSE | 20 - vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY | 284 -- vendor/honnef.co/go/tools/arg/arg.go | 48 - .../go/tools/cmd/staticcheck/README.md | 15 - .../go/tools/cmd/staticcheck/staticcheck.go | 44 - vendor/honnef.co/go/tools/code/code.go | 481 --- vendor/honnef.co/go/tools/config/config.go | 245 -- vendor/honnef.co/go/tools/config/example.conf | 10 - .../honnef.co/go/tools/deprecated/stdlib.go | 119 - vendor/honnef.co/go/tools/edit/edit.go | 67 - vendor/honnef.co/go/tools/facts/deprecated.go | 144 - vendor/honnef.co/go/tools/facts/generated.go | 93 - vendor/honnef.co/go/tools/facts/purity.go | 177 - vendor/honnef.co/go/tools/facts/token.go | 24 - vendor/honnef.co/go/tools/functions/loops.go | 54 - vendor/honnef.co/go/tools/functions/stub.go | 32 - .../go/tools/functions/terminates.go | 70 - .../go/tools/go/types/typeutil/callee.go | 46 - .../go/tools/go/types/typeutil/identical.go | 75 - .../go/tools/go/types/typeutil/imports.go | 31 - .../go/tools/go/types/typeutil/map.go | 319 -- .../tools/go/types/typeutil/methodsetcache.go | 72 - .../go/tools/go/types/typeutil/ui.go | 52 - .../go/tools/internal/cache/cache.go | 496 --- .../go/tools/internal/cache/default.go | 85 - .../honnef.co/go/tools/internal/cache/hash.go | 176 - .../tools/internal/passes/buildir/buildir.go | 113 - .../go/tools/internal/renameio/renameio.go | 93 - .../go/tools/internal/robustio/robustio.go | 53 - .../internal/robustio/robustio_darwin.go | 29 - .../tools/internal/robustio/robustio_flaky.go | 93 - .../tools/internal/robustio/robustio_other.go | 28 - .../internal/robustio/robustio_windows.go | 33 - .../go/tools/internal/sharedcheck/lint.go | 71 - vendor/honnef.co/go/tools/ir/LICENSE | 28 - vendor/honnef.co/go/tools/ir/blockopt.go | 209 - vendor/honnef.co/go/tools/ir/builder.go | 2474 ----------- vendor/honnef.co/go/tools/ir/const.go | 153 - vendor/honnef.co/go/tools/ir/create.go | 275 -- vendor/honnef.co/go/tools/ir/doc.go | 129 - vendor/honnef.co/go/tools/ir/dom.go | 461 -- vendor/honnef.co/go/tools/ir/emit.go | 450 -- vendor/honnef.co/go/tools/ir/exits.go | 271 -- vendor/honnef.co/go/tools/ir/func.go | 961 ----- vendor/honnef.co/go/tools/ir/html.go | 1124 ----- vendor/honnef.co/go/tools/ir/identical.go | 7 - vendor/honnef.co/go/tools/ir/identical_17.go | 7 - vendor/honnef.co/go/tools/ir/irutil/load.go | 183 - vendor/honnef.co/go/tools/ir/irutil/switch.go | 264 -- vendor/honnef.co/go/tools/ir/irutil/util.go | 70 - vendor/honnef.co/go/tools/ir/irutil/visit.go | 79 - vendor/honnef.co/go/tools/ir/lift.go | 1063 ----- vendor/honnef.co/go/tools/ir/lvalue.go | 116 - vendor/honnef.co/go/tools/ir/methods.go | 239 - vendor/honnef.co/go/tools/ir/mode.go | 98 - vendor/honnef.co/go/tools/ir/print.go | 472 -- vendor/honnef.co/go/tools/ir/sanity.go | 555 --- vendor/honnef.co/go/tools/ir/source.go | 270 -- vendor/honnef.co/go/tools/ir/ssa.go | 1856 -------- vendor/honnef.co/go/tools/ir/staticcheck.conf | 3 - vendor/honnef.co/go/tools/ir/util.go | 89 - vendor/honnef.co/go/tools/ir/wrappers.go | 292 -- vendor/honnef.co/go/tools/ir/write.go | 5 - vendor/honnef.co/go/tools/lint/LICENSE | 28 - vendor/honnef.co/go/tools/lint/lint.go | 539 --- .../go/tools/lint/lintdsl/lintdsl.go | 58 - .../go/tools/lint/lintutil/format/format.go | 162 - .../honnef.co/go/tools/lint/lintutil/stats.go | 7 - .../go/tools/lint/lintutil/stats_bsd.go | 10 - .../go/tools/lint/lintutil/stats_posix.go | 10 - .../honnef.co/go/tools/lint/lintutil/util.go | 444 -- vendor/honnef.co/go/tools/lint/runner.go | 1114 ----- vendor/honnef.co/go/tools/lint/stats.go | 38 - vendor/honnef.co/go/tools/loader/loader.go | 210 - vendor/honnef.co/go/tools/pattern/convert.go | 242 -- vendor/honnef.co/go/tools/pattern/doc.go | 273 -- vendor/honnef.co/go/tools/pattern/fuzz.go | 50 - vendor/honnef.co/go/tools/pattern/lexer.go | 221 - vendor/honnef.co/go/tools/pattern/match.go | 513 --- vendor/honnef.co/go/tools/pattern/parser.go | 455 -- vendor/honnef.co/go/tools/pattern/pattern.go | 497 --- vendor/honnef.co/go/tools/printf/fuzz.go | 11 - vendor/honnef.co/go/tools/printf/printf.go | 197 - vendor/honnef.co/go/tools/report/report.go | 184 - vendor/honnef.co/go/tools/simple/analysis.go | 148 - vendor/honnef.co/go/tools/simple/doc.go | 485 --- vendor/honnef.co/go/tools/simple/lint.go | 1868 -------- .../go/tools/staticcheck/analysis.go | 267 -- .../go/tools/staticcheck/buildtag.go | 21 - vendor/honnef.co/go/tools/staticcheck/doc.go | 880 ---- vendor/honnef.co/go/tools/staticcheck/lint.go | 3825 ----------------- .../honnef.co/go/tools/staticcheck/rules.go | 315 -- .../go/tools/staticcheck/structtag.go | 58 - .../honnef.co/go/tools/stylecheck/analysis.go | 81 - vendor/honnef.co/go/tools/stylecheck/doc.go | 231 - vendor/honnef.co/go/tools/stylecheck/lint.go | 914 ---- vendor/honnef.co/go/tools/stylecheck/names.go | 276 -- vendor/honnef.co/go/tools/unused/edge.go | 54 - .../go/tools/unused/edgekind_string.go | 109 - .../honnef.co/go/tools/unused/implements.go | 82 - vendor/honnef.co/go/tools/unused/unused.go | 1978 --------- .../honnef.co/go/tools/version/buildinfo.go | 46 - .../go/tools/version/buildinfo111.go | 6 - vendor/honnef.co/go/tools/version/version.go | 42 - vendor/modules.txt | 69 +- 270 files changed, 4719 insertions(+), 47224 deletions(-) delete mode 100644 vendor/github.com/BurntSushi/toml/.gitignore delete mode 100644 vendor/github.com/BurntSushi/toml/.travis.yml delete mode 100644 vendor/github.com/BurntSushi/toml/COMPATIBLE delete mode 100644 vendor/github.com/BurntSushi/toml/COPYING delete mode 100644 vendor/github.com/BurntSushi/toml/Makefile delete mode 100644 vendor/github.com/BurntSushi/toml/README.md delete mode 100644 vendor/github.com/BurntSushi/toml/decode.go delete mode 100644 vendor/github.com/BurntSushi/toml/decode_meta.go delete mode 100644 vendor/github.com/BurntSushi/toml/doc.go delete mode 100644 vendor/github.com/BurntSushi/toml/encode.go delete mode 100644 vendor/github.com/BurntSushi/toml/encoding_types.go delete mode 100644 vendor/github.com/BurntSushi/toml/encoding_types_1.1.go delete mode 100644 vendor/github.com/BurntSushi/toml/lex.go delete mode 100644 vendor/github.com/BurntSushi/toml/parse.go delete mode 100644 vendor/github.com/BurntSushi/toml/session.vim delete mode 100644 vendor/github.com/BurntSushi/toml/type_check.go delete mode 100644 vendor/github.com/BurntSushi/toml/type_fields.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/analysis.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/diagnostic.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/doc.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go delete mode 100644 vendor/golang.org/x/tools/go/analysis/validate.go delete mode 100644 vendor/golang.org/x/tools/go/ast/inspector/inspector.go delete mode 100644 vendor/golang.org/x/tools/go/ast/inspector/typeof.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/allpackages.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/fakecontext.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/overlay.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/tags.go delete mode 100644 vendor/golang.org/x/tools/go/buildutil/util.go delete mode 100644 vendor/golang.org/x/tools/go/internal/cgo/cgo.go delete mode 100644 vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go delete mode 100644 vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go delete mode 100644 vendor/golang.org/x/tools/go/loader/doc.go delete mode 100644 vendor/golang.org/x/tools/go/loader/loader.go delete mode 100644 vendor/golang.org/x/tools/go/loader/util.go delete mode 100644 vendor/golang.org/x/tools/go/packages/doc.go delete mode 100644 vendor/golang.org/x/tools/go/packages/external.go delete mode 100644 vendor/golang.org/x/tools/go/packages/golist.go delete mode 100644 vendor/golang.org/x/tools/go/packages/golist_overlay.go delete mode 100644 vendor/golang.org/x/tools/go/packages/loadmode_string.go delete mode 100644 vendor/golang.org/x/tools/go/packages/packages.go delete mode 100644 vendor/golang.org/x/tools/go/packages/visit.go delete mode 100644 vendor/golang.org/x/tools/go/types/objectpath/objectpath.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/callee.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/imports.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/map.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go delete mode 100644 vendor/golang.org/x/tools/go/types/typeutil/ui.go delete mode 100644 vendor/golang.org/x/tools/internal/analysisinternal/analysis.go delete mode 100644 vendor/golang.org/x/tools/internal/packagesinternal/packages.go delete mode 100644 vendor/golang.org/x/tools/internal/typesinternal/types.go delete mode 100644 vendor/google.golang.org/grpc/balancer.go create mode 100644 vendor/google.golang.org/grpc/balancer/grpclb/state/state.go delete mode 100644 vendor/google.golang.org/grpc/balancer_v1_wrapper.go delete mode 100644 vendor/google.golang.org/grpc/internal/binarylog/regenerate.sh rename vendor/google.golang.org/grpc/internal/{binarylog/util.go => grpcutil/method.go} (82%) create mode 100644 vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go delete mode 100644 vendor/google.golang.org/grpc/naming/dns_resolver.go delete mode 100644 vendor/google.golang.org/grpc/naming/naming.go create mode 100644 vendor/google.golang.org/grpc/regenerate.sh create mode 100644 vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/any_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/api_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/doc.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/duration_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/empty_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/field_mask_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/source_context_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/struct_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/timestamp_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/type_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/fieldnum/wrappers_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/any_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/api_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/doc.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/duration_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/empty_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/goname.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/map_entry.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/struct_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/type_gen.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers.go create mode 100644 vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go delete mode 100644 vendor/google.golang.org/protobuf/internal/genname/name.go delete mode 100644 vendor/honnef.co/go/tools/LICENSE delete mode 100644 vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY delete mode 100644 vendor/honnef.co/go/tools/arg/arg.go delete mode 100644 vendor/honnef.co/go/tools/cmd/staticcheck/README.md delete mode 100644 vendor/honnef.co/go/tools/cmd/staticcheck/staticcheck.go delete mode 100644 vendor/honnef.co/go/tools/code/code.go delete mode 100644 vendor/honnef.co/go/tools/config/config.go delete mode 100644 vendor/honnef.co/go/tools/config/example.conf delete mode 100644 vendor/honnef.co/go/tools/deprecated/stdlib.go delete mode 100644 vendor/honnef.co/go/tools/edit/edit.go delete mode 100644 vendor/honnef.co/go/tools/facts/deprecated.go delete mode 100644 vendor/honnef.co/go/tools/facts/generated.go delete mode 100644 vendor/honnef.co/go/tools/facts/purity.go delete mode 100644 vendor/honnef.co/go/tools/facts/token.go delete mode 100644 vendor/honnef.co/go/tools/functions/loops.go delete mode 100644 vendor/honnef.co/go/tools/functions/stub.go delete mode 100644 vendor/honnef.co/go/tools/functions/terminates.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/callee.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/identical.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/imports.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/map.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/methodsetcache.go delete mode 100644 vendor/honnef.co/go/tools/go/types/typeutil/ui.go delete mode 100644 vendor/honnef.co/go/tools/internal/cache/cache.go delete mode 100644 vendor/honnef.co/go/tools/internal/cache/default.go delete mode 100644 vendor/honnef.co/go/tools/internal/cache/hash.go delete mode 100644 vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go delete mode 100644 vendor/honnef.co/go/tools/internal/renameio/renameio.go delete mode 100644 vendor/honnef.co/go/tools/internal/robustio/robustio.go delete mode 100644 vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go delete mode 100644 vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go delete mode 100644 vendor/honnef.co/go/tools/internal/robustio/robustio_other.go delete mode 100644 vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go delete mode 100644 vendor/honnef.co/go/tools/internal/sharedcheck/lint.go delete mode 100644 vendor/honnef.co/go/tools/ir/LICENSE delete mode 100644 vendor/honnef.co/go/tools/ir/blockopt.go delete mode 100644 vendor/honnef.co/go/tools/ir/builder.go delete mode 100644 vendor/honnef.co/go/tools/ir/const.go delete mode 100644 vendor/honnef.co/go/tools/ir/create.go delete mode 100644 vendor/honnef.co/go/tools/ir/doc.go delete mode 100644 vendor/honnef.co/go/tools/ir/dom.go delete mode 100644 vendor/honnef.co/go/tools/ir/emit.go delete mode 100644 vendor/honnef.co/go/tools/ir/exits.go delete mode 100644 vendor/honnef.co/go/tools/ir/func.go delete mode 100644 vendor/honnef.co/go/tools/ir/html.go delete mode 100644 vendor/honnef.co/go/tools/ir/identical.go delete mode 100644 vendor/honnef.co/go/tools/ir/identical_17.go delete mode 100644 vendor/honnef.co/go/tools/ir/irutil/load.go delete mode 100644 vendor/honnef.co/go/tools/ir/irutil/switch.go delete mode 100644 vendor/honnef.co/go/tools/ir/irutil/util.go delete mode 100644 vendor/honnef.co/go/tools/ir/irutil/visit.go delete mode 100644 vendor/honnef.co/go/tools/ir/lift.go delete mode 100644 vendor/honnef.co/go/tools/ir/lvalue.go delete mode 100644 vendor/honnef.co/go/tools/ir/methods.go delete mode 100644 vendor/honnef.co/go/tools/ir/mode.go delete mode 100644 vendor/honnef.co/go/tools/ir/print.go delete mode 100644 vendor/honnef.co/go/tools/ir/sanity.go delete mode 100644 vendor/honnef.co/go/tools/ir/source.go delete mode 100644 vendor/honnef.co/go/tools/ir/ssa.go delete mode 100644 vendor/honnef.co/go/tools/ir/staticcheck.conf delete mode 100644 vendor/honnef.co/go/tools/ir/util.go delete mode 100644 vendor/honnef.co/go/tools/ir/wrappers.go delete mode 100644 vendor/honnef.co/go/tools/ir/write.go delete mode 100644 vendor/honnef.co/go/tools/lint/LICENSE delete mode 100644 vendor/honnef.co/go/tools/lint/lint.go delete mode 100644 vendor/honnef.co/go/tools/lint/lintdsl/lintdsl.go delete mode 100644 vendor/honnef.co/go/tools/lint/lintutil/format/format.go delete mode 100644 vendor/honnef.co/go/tools/lint/lintutil/stats.go delete mode 100644 vendor/honnef.co/go/tools/lint/lintutil/stats_bsd.go delete mode 100644 vendor/honnef.co/go/tools/lint/lintutil/stats_posix.go delete mode 100644 vendor/honnef.co/go/tools/lint/lintutil/util.go delete mode 100644 vendor/honnef.co/go/tools/lint/runner.go delete mode 100644 vendor/honnef.co/go/tools/lint/stats.go delete mode 100644 vendor/honnef.co/go/tools/loader/loader.go delete mode 100644 vendor/honnef.co/go/tools/pattern/convert.go delete mode 100644 vendor/honnef.co/go/tools/pattern/doc.go delete mode 100644 vendor/honnef.co/go/tools/pattern/fuzz.go delete mode 100644 vendor/honnef.co/go/tools/pattern/lexer.go delete mode 100644 vendor/honnef.co/go/tools/pattern/match.go delete mode 100644 vendor/honnef.co/go/tools/pattern/parser.go delete mode 100644 vendor/honnef.co/go/tools/pattern/pattern.go delete mode 100644 vendor/honnef.co/go/tools/printf/fuzz.go delete mode 100644 vendor/honnef.co/go/tools/printf/printf.go delete mode 100644 vendor/honnef.co/go/tools/report/report.go delete mode 100644 vendor/honnef.co/go/tools/simple/analysis.go delete mode 100644 vendor/honnef.co/go/tools/simple/doc.go delete mode 100644 vendor/honnef.co/go/tools/simple/lint.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/analysis.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/buildtag.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/doc.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/lint.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/rules.go delete mode 100644 vendor/honnef.co/go/tools/staticcheck/structtag.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/analysis.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/doc.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/lint.go delete mode 100644 vendor/honnef.co/go/tools/stylecheck/names.go delete mode 100644 vendor/honnef.co/go/tools/unused/edge.go delete mode 100644 vendor/honnef.co/go/tools/unused/edgekind_string.go delete mode 100644 vendor/honnef.co/go/tools/unused/implements.go delete mode 100644 vendor/honnef.co/go/tools/unused/unused.go delete mode 100644 vendor/honnef.co/go/tools/version/buildinfo.go delete mode 100644 vendor/honnef.co/go/tools/version/buildinfo111.go delete mode 100644 vendor/honnef.co/go/tools/version/version.go diff --git a/go.mod b/go.mod index b7ba72bf8..21e6b3099 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/VictoriaMetrics/VictoriaMetrics require ( - cloud.google.com/go v0.58.0 // indirect + cloud.google.com/go v0.59.0 // indirect cloud.google.com/go/storage v1.10.0 github.com/VictoriaMetrics/fastcache v1.5.7 @@ -10,23 +10,25 @@ require ( github.com/VictoriaMetrics/fasthttp v1.0.1 github.com/VictoriaMetrics/metrics v1.11.3 github.com/VictoriaMetrics/metricsql v0.2.3 - github.com/aws/aws-sdk-go v1.32.5 + github.com/aws/aws-sdk-go v1.32.10 github.com/cespare/xxhash/v2 v2.1.1 github.com/golang/snappy v0.0.1 github.com/klauspost/compress v1.10.10 - github.com/valyala/fastjson v1.5.2 + github.com/valyala/fastjson v1.5.3 github.com/valyala/fastrand v1.0.0 github.com/valyala/gozstd v1.7.0 github.com/valyala/histogram v1.0.1 github.com/valyala/quicktemplate v1.5.0 go.opencensus.io v0.22.4 // indirect - golang.org/x/net v0.0.0-20200602114024-627f9648deb9 // indirect + golang.org/x/net v0.0.0-20200625001655-4c5254603344 // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d - golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 + golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 golang.org/x/text v0.3.3 // indirect - golang.org/x/tools v0.0.0-20200618155944-c7475b9d7fb2 // indirect + golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d // indirect google.golang.org/api v0.28.0 - google.golang.org/genproto v0.0.0-20200618215128-cebbd7a98dcc // indirect + google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad // indirect + google.golang.org/grpc v1.30.0 // indirect + google.golang.org/protobuf v1.25.0 // indirect gopkg.in/yaml.v2 v2.3.0 ) diff --git a/go.sum b/go.sum index bcece9f6e..3da44827b 100644 --- a/go.sum +++ b/go.sum @@ -13,8 +13,8 @@ cloud.google.com/go v0.56.0 h1:WRz29PgAsVEyPSDHyk+0fpEkwEFyfhHn+JbksT6gIL4= cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0 h1:EpMNVUorLiZIELdMZbCYX/ByTFCdoYopYAGxaGVz9ms= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.58.0 h1:vtAfVc723K3xKq1BQydk/FyCldnaNFhGhpJxaJzgRMQ= -cloud.google.com/go v0.58.0/go.mod h1:W+9FnSUw6nhVwXlFcp1eL+krq5+HQUJeUogSeJZZiWg= +cloud.google.com/go v0.59.0 h1:BM3svUDU3itpc2m5cu5wCyThIYNDlFlts9GASw31GW8= +cloud.google.com/go v0.59.0/go.mod h1:qJxNOVCRTxHfwLhvDxxSI9vQc1zI59b9pEglp1Iv60E= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU= @@ -57,8 +57,8 @@ github.com/VictoriaMetrics/metricsql v0.2.3 h1:xGscDmLoeIV7+8qX/mdHnOY0vu4m+wHIV github.com/VictoriaMetrics/metricsql v0.2.3/go.mod h1:UIjd9S0W1UnTWlJdM0wLS+2pfuPqjwqKoK8yTos+WyE= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/aws/aws-sdk-go v1.32.5 h1:Sz0C7deIoMu5lFGTVkIN92IEZrUz1AWIDDW+9p6n1Rk= -github.com/aws/aws-sdk-go v1.32.5/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.32.10 h1:cEJTxGcBGlsM2tN36MZQKhlK93O9HrnaRs+lq2f0zN8= +github.com/aws/aws-sdk-go v1.32.10/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -116,6 +116,8 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -161,8 +163,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.12.0/go.mod h1:229t1eWu9UXTPmoUkbpN/fctKPBY4IJoFXQnxHGXy6E= -github.com/valyala/fastjson v1.5.2 h1:VTbMfG0sCyXqC66PS+ME1cHXy5ClW085avDoy28t4Uo= -github.com/valyala/fastjson v1.5.2/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= +github.com/valyala/fastjson v1.5.3 h1:z4Z1Bll4WaXo+FXJoiCdW8ss7sKY2d/jYfE2ZzoT284= +github.com/valyala/fastjson v1.5.3/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/valyala/fastrand v1.0.0 h1:LUKT9aKer2dVQNUi3waewTbKV+7H17kvWFNKs2ObdkI= github.com/valyala/fastrand v1.0.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ= github.com/valyala/gozstd v1.7.0 h1:Ljh5c9zboqLhwTI33al32R72iCZfn0mCbVGcFWbGwRQ= @@ -185,6 +187,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -243,8 +246,8 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -285,8 +288,8 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -333,10 +336,10 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200606014950-c42cb6316fb6/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618155944-c7475b9d7fb2 h1:5uj2ldj1KKGFXJexeG65UpexxnZYU4d1Q6en50MewmU= -golang.org/x/tools v0.0.0-20200618155944-c7475b9d7fb2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d h1:V1BGE5ZHrUIYZYNEm0i7jrPwSo3ks0HSn1TrartSqME= +golang.org/x/tools v0.0.0-20200625195345-7480c7b4547d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -355,8 +358,6 @@ google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.26.0 h1:VJZ8h6E8ip82FRpQl848c5vAadxlTXrUh8RzQzSRm08= -google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0 h1:jMF5hhVfMkTZwHW1SDpKq5CkgWLXOb31Foaca9Zr3oM= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -393,10 +394,10 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380 h1:xriR1EgvKfkKxIo google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200618215128-cebbd7a98dcc h1:Xrg3/DpLwfPwEJr6eXoNtM30WUfACuiYhc14vYB4ea0= -google.golang.org/genproto v0.0.0-20200618215128-cebbd7a98dcc/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200623002339-fbb79eadd5eb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad h1:uAwc13+y0Y8QZLTYhLCu6lHhnG99ecQU5FYTj8zxAng= +google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -408,6 +409,8 @@ google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -421,6 +424,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/vendor/cloud.google.com/go/CHANGES.md b/vendor/cloud.google.com/go/CHANGES.md index 5868db4c2..ae1a82581 100644 --- a/vendor/cloud.google.com/go/CHANGES.md +++ b/vendor/cloud.google.com/go/CHANGES.md @@ -1,5 +1,31 @@ # Changes +## v0.59.0 + +### Announcements + +goolgeapis/google-cloud-go has moved its source of truth to GitHub and is no longer a mirror. This means that our +contributing process has changed a bit. We will now be conducting all code reviews on GitHub which means we now accept +pull requests! If you have a version of the codebase previously checked out you may wish to update your git remote to +point to GitHub. + +### Changes + +- all: + - Remove dependency on honnef.co/go/tools. + - Update our contributing instructions now that we use GitHub for reviews. + - Remove some un-inclusive terminology. +- compute/metadata: + - Pass cancelable context to DNS lookup. +- .github: + - Update templates issue/PR templates. +- internal: + - Bump several clients to GA. + - Fix GoDoc badge source. + - Several automation changes related to the move to GitHub. + - Start generating a client for asset v1p5beta1. +- Various updates to autogenerated clients. + ## v0.58.0 ### Deprecation notice diff --git a/vendor/cloud.google.com/go/CONTRIBUTING.md b/vendor/cloud.google.com/go/CONTRIBUTING.md index 1e45441d1..109ca5c43 100644 --- a/vendor/cloud.google.com/go/CONTRIBUTING.md +++ b/vendor/cloud.google.com/go/CONTRIBUTING.md @@ -14,94 +14,34 @@ 1. Sign one of the [contributor license agreements](#contributor-license-agreements) below. -1. Run `go get golang.org/x/review/git-codereview && go install golang.org/x/review/git-codereview` -to install the code reviewing tool. +1. Clone the repo: + `git clone https://github.com/googleapis/google-cloud-go` - 1. Ensure it's working by running `git codereview` (check your `PATH` if - not). +1. Change into the checked out source: + `cd google-cloud-go` - 1. If you would like, you may want to set up aliases for `git-codereview`, - such that `git codereview change` becomes `git change`. See the - [godoc](https://pkg.go.dev/golang.org/x/review/git-codereview) for details. +1. Fork the repo. + +1. Set your fork as a remote: + `git remote add fork git@github.com:GITHUB_USERNAME/google-cloud-go.git` - * Should you run into issues with the `git-codereview` tool, please note - that all error messages will assume that you have set up these aliases. +1. Make changes (see [Formatting](#formatting) and [Style](#style)), commit to + your fork. -1. Change to a directory of your choosing and clone the repo. + Commit messages should follow the + [Go project style](https://github.com/golang/go/wiki/CommitMessage). For example: + ``` + functions: add gophers codelab + ``` - ``` - cd ~/code - git clone https://code.googlesource.com/gocloud - ``` +1. Send a pull request with your changes. - * If you have already checked out the source, make sure that the remote - `git` `origin` is https://code.googlesource.com/gocloud: +1. A maintainer will review the pull request and make comments. - ``` - git remote -v - # ... - git remote set-url origin https://code.googlesource.com/gocloud - ``` - - * The project uses [Go Modules](https://blog.golang.org/using-go-modules) - for dependency management See - [`gopls`](https://github.com/golang/go/wiki/gopls) for making your editor - work with modules. - -1. Change to the project directory: - - ``` - cd ~/code/gocloud - ``` - -1. Make sure your `git` auth is configured correctly by visiting -https://code.googlesource.com, clicking "Generate Password" at the top-right, -and following the directions. Otherwise, `git codereview mail` in the next step -will fail. - -1. Now you are ready to make changes. Don't create a new branch or make commits in the traditional -way. Use the following`git codereview` commands to create a commit and create a Gerrit CL: - - ``` - git codereview change # Use this instead of git checkout -b - # Make changes. - git add ... - git codereview change # Use this instead of git commit - git codereview mail # If this fails, the error message will contain instructions to fix it. - ``` - - * This will create a new `git` branch for you to develop on. Once your - change is merged, you can delete this branch. - -1. As you make changes for code review, ammend the commit and re-mail the -change: - - ``` - # Make more changes. - git add ... - git codereview change - git codereview mail - ``` - - * **Warning**: do not change the `Change-Id` at the bottom of the commit - message - it's how Gerrit knows which change this is (or if it's new). - - * When you fixes issues from code review, respond to each code review - message then click **Reply** at the top of the page. - - * Each new mailed amendment will create a new patch set for - your change in Gerrit. Patch sets can be compared and reviewed. - - * **Note**: if your change includes a breaking change, our breaking change - detector will cause CI/CD to fail. If your breaking change is acceptable - in some way, add a `BREAKING_CHANGE_ACCEPTABLE=` line to the commit - message to cause the detector not to be run and to make it clear why that is - acceptable. - -1. Finally, add reviewers to your CL when it's ready for review. Reviewers will -not be added automatically. If you're not sure who to add for your code review, -add tbp@, cbro@, and codyoss@. + Prefer adding additional commits over amending and force-pushing since it can + be difficult to follow code reviews when the commit history changes. + Commits will be squashed when they're merged. ## Integration Tests diff --git a/vendor/cloud.google.com/go/README.md b/vendor/cloud.google.com/go/README.md index bad1afa07..b115812c2 100644 --- a/vendor/cloud.google.com/go/README.md +++ b/vendor/cloud.google.com/go/README.md @@ -1,6 +1,6 @@ # Google Cloud Client Libraries for Go -[![GoDoc](https://pkg.go.dev/cloud.google.com/go?status.svg)](https://pkg.go.dev/cloud.google.com/go) +[![GoDoc](https://godoc.org/cloud.google.com/go?status.svg)](https://pkg.go.dev/cloud.google.com/go) Go packages for [Google Cloud Platform](https://cloud.google.com) services. @@ -127,8 +127,7 @@ client, err := storage.NewClient(ctx, option.WithTokenSource(tokenSource)) Contributions are welcome. Please, see the [CONTRIBUTING](https://github.com/GoogleCloudPlatform/google-cloud-go/blob/master/CONTRIBUTING.md) -document for details. We're using Gerrit for our code reviews. Please don't open pull -requests against this repo, new pull requests will be automatically closed. +document for details. Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. diff --git a/vendor/cloud.google.com/go/RELEASING.md b/vendor/cloud.google.com/go/RELEASING.md index 7a8a5fb33..c8c7f9335 100644 --- a/vendor/cloud.google.com/go/RELEASING.md +++ b/vendor/cloud.google.com/go/RELEASING.md @@ -10,51 +10,14 @@ 1. Sign one of the [contributor license agreements](#contributor-license-agreements) below. -1. Run `go get golang.org/x/review/git-codereview && go install golang.org/x/review/git-codereview` -to install the code reviewing tool. +1. Clone the repo: + `git clone https://github.com/googleapis/google-cloud-go` - 1. Ensure it's working by running `git codereview` (check your `PATH` if - not). +1. Change into the checked out source: + `cd google-cloud-go` - 1. If you would like, you may want to set up aliases for `git-codereview`, - such that `git codereview change` becomes `git change`. See the - [godoc](https://pkg.go.dev/golang.org/x/review/git-codereview) for details. - - * Should you run into issues with the `git-codereview` tool, please note - that all error messages will assume that you have set up these aliases. - -1. Change to a directory of your choosing and clone the repo. - - ``` - cd ~/code - git clone https://code.googlesource.com/gocloud - ``` - - * If you have already checked out the source, make sure that the remote - `git` `origin` is https://code.googlesource.com/gocloud: - - ``` - git remote -v - # ... - git remote set-url origin https://code.googlesource.com/gocloud - ``` - - * The project uses [Go Modules](https://blog.golang.org/using-go-modules) - for dependency management See - [`gopls`](https://github.com/golang/go/wiki/gopls) for making your editor - work with modules. - -1. Change to the project directory and add the github remote: - - ``` - cd ~/code/gocloud - git remote add github https://github.com/googleapis/google-cloud-go - ``` - -1. Make sure your `git` auth is configured correctly by visiting -https://code.googlesource.com, clicking "Generate Password" at the top-right, -and following the directions. Otherwise, `git codereview mail` in the next step -will fail. +1. Fork the repo and add your fork as a secondary remote (this is necessary in + order to create PRs). # Which module to release? @@ -98,7 +61,7 @@ the failures have been resolved. # How to release `cloud.google.com/go` 1. Check for failures in the - [continuous Kokoro build](go/google-cloud-go-continuous). If there are any + [continuous Kokoro build](http://go/google-cloud-go-continuous). If there are any failures in the most recent build, address them before proceeding with the release. 1. Navigate to `~/code/gocloud/` and switch to master. @@ -114,16 +77,15 @@ the failures have been resolved. to be part of your release). 1. Edit `CHANGES.md` to include a summary of the changes. 1. `cd internal/version && go generate && cd -` -1. Mail the CL: `git add -A && git change && git mail` -1. Wait for the CL to be submitted. Once it's submitted, and without submitting - any other CLs in the meantime: +1. Commit the changes, push to your fork, and create a PR. +1. Wait for the PR to be reviewed and merged. Once it's merged, and without + merging any other PRs in the meantime: a. Switch to master. b. `git pull` c. Tag the repo with the next version: `git tag $NV`. - d. Push the tag to both remotes: + d. Push the tag to origin: `git push origin $NV` - `git push github $NV` -1. Update [the releases page](https://github.com/googleapis/google-cloud-go/releases) +2. Update [the releases page](https://github.com/googleapis/google-cloud-go/releases) with the new release, copying the contents of `CHANGES.md`. # How to release a submodule @@ -136,7 +98,7 @@ To release a submodule: (these instructions assume we're releasing `cloud.google.com/go/datastore` - adjust accordingly) 1. Check for failures in the - [continuous Kokoro build](go/google-cloud-go-continuous). If there are any + [continuous Kokoro build](http://go/google-cloud-go-continuous). If there are any failures in the most recent build, address them before proceeding with the release. (This applies even if the failures are in a different submodule from the one being released.) @@ -150,15 +112,14 @@ To release a submodule: submodule directory since the last release. 1. Edit `datastore/CHANGES.md` to include a summary of the changes. 1. `cd internal/version && go generate && cd -` -1. Mail the CL: `git add -A && git change && git mail` -1. Wait for the CL to be submitted. Once it's submitted, and without submitting - any other CLs in the meantime: +1. Commit the changes, push to your fork, and create a PR. +1. Wait for the PR to be reviewed and merged. Once it's merged, and without + merging any other PRs in the meantime: a. Switch to master. b. `git pull` c. Tag the repo with the next version: `git tag $NV`. - d. Push the tag to both remotes: + d. Push the tag to origin: `git push origin $NV` - `git push github $NV` 1. Update [the releases page](https://github.com/googleapis/google-cloud-go/releases) with the new release, copying the contents of `datastore/CHANGES.md`. diff --git a/vendor/cloud.google.com/go/compute/metadata/metadata.go b/vendor/cloud.google.com/go/compute/metadata/metadata.go index 1a7a4c7e5..6b13424fd 100644 --- a/vendor/cloud.google.com/go/compute/metadata/metadata.go +++ b/vendor/cloud.google.com/go/compute/metadata/metadata.go @@ -140,7 +140,7 @@ func testOnGCE() bool { }() go func() { - addrs, err := net.LookupHost("metadata.google.internal") + addrs, err := net.DefaultResolver.LookupHost(ctx, "metadata.google.internal") if err != nil || len(addrs) == 0 { resc <- false return diff --git a/vendor/cloud.google.com/go/go.mod b/vendor/cloud.google.com/go/go.mod index bac1f2859..4aff09af7 100644 --- a/vendor/cloud.google.com/go/go.mod +++ b/vendor/cloud.google.com/go/go.mod @@ -20,9 +20,8 @@ require ( golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sys v0.0.0-20200523222454-059865788121 // indirect golang.org/x/text v0.3.2 - golang.org/x/tools v0.0.0-20200606014950-c42cb6316fb6 - google.golang.org/api v0.26.0 - google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 + golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa + google.golang.org/api v0.28.0 + google.golang.org/genproto v0.0.0-20200623002339-fbb79eadd5eb google.golang.org/grpc v1.29.1 - honnef.co/go/tools v0.0.1-2020.1.4 ) diff --git a/vendor/cloud.google.com/go/go.sum b/vendor/cloud.google.com/go/go.sum index be48f559b..ec762fcb1 100644 --- a/vendor/cloud.google.com/go/go.sum +++ b/vendor/cloud.google.com/go/go.sum @@ -334,8 +334,8 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88 h1:4j84u0sokprDu3IdSYHJMmou+YSLflMz8p7yAx/QI4g= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200606014950-c42cb6316fb6 h1:5Y8c5HBW6hBYnGEE3AbJPV0R8RsQmg1/eaJrpvasns0= -golang.org/x/tools v0.0.0-20200606014950-c42cb6316fb6/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa h1:mMXQKlWCw9mIWgVLLfiycDZjMHMMYqiuakI4E/l2xcA= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= @@ -359,8 +359,8 @@ google.golang.org/api v0.22.0 h1:J1Pl9P2lnmYFSJvgs70DKELqHNh8CNWXPbud4njEE2s= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0 h1:cG03eaksBzhfSIk7JRGctfp3lanklcOM/mTGvow7BbQ= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.26.0 h1:VJZ8h6E8ip82FRpQl848c5vAadxlTXrUh8RzQzSRm08= -google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0 h1:jMF5hhVfMkTZwHW1SDpKq5CkgWLXOb31Foaca9Zr3oM= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -404,8 +404,8 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380 h1:xriR1EgvKfkKxIo google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482 h1:i+Aiej6cta/Frzp13/swvwz5O00kYcSe0A/C5Wd7zX8= -google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200623002339-fbb79eadd5eb h1:PUcq6RTy8Gp9xukBme8m2+2Z8pQCmJ7TbPpQd6xNDvk= +google.golang.org/genproto v0.0.0-20200623002339-fbb79eadd5eb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= diff --git a/vendor/cloud.google.com/go/internal/.repo-metadata-full.json b/vendor/cloud.google.com/go/internal/.repo-metadata-full.json index 5d2b759d1..882b11ebf 100644 --- a/vendor/cloud.google.com/go/internal/.repo-metadata-full.json +++ b/vendor/cloud.google.com/go/internal/.repo-metadata-full.json @@ -23,6 +23,14 @@ "docs_url": "https://pkg.go.dev/cloud.google.com/go/asset/apiv1p2beta1", "release_level": "beta" }, + "cloud.google.com/go/asset/apiv1p5beta1": { + "distribution_name": "cloud.google.com/go/asset/apiv1p5beta1", + "description": "Cloud Asset API", + "language": "Go", + "client_library_type": "generated", + "docs_url": "https://pkg.go.dev/cloud.google.com/go/asset/apiv1p5beta1", + "release_level": "beta" + }, "cloud.google.com/go/automl/apiv1": { "distribution_name": "cloud.google.com/go/automl/apiv1", "description": "Cloud AutoML API", @@ -53,7 +61,7 @@ "language": "Go", "client_library_type": "generated", "docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/connection/apiv1", - "release_level": "beta" + "release_level": "ga" }, "cloud.google.com/go/bigquery/connection/apiv1beta1": { "distribution_name": "cloud.google.com/go/bigquery/connection/apiv1beta1", @@ -397,7 +405,7 @@ "language": "Go", "client_library_type": "generated", "docs_url": "https://pkg.go.dev/cloud.google.com/go/osconfig/agentendpoint/apiv1", - "release_level": "beta" + "release_level": "ga" }, "cloud.google.com/go/osconfig/agentendpoint/apiv1beta": { "distribution_name": "cloud.google.com/go/osconfig/agentendpoint/apiv1beta", @@ -553,7 +561,7 @@ }, "cloud.google.com/go/securitycenter/apiv1": { "distribution_name": "cloud.google.com/go/securitycenter/apiv1", - "description": "Cloud Security Command Center API", + "description": "Security Command Center API", "language": "Go", "client_library_type": "generated", "docs_url": "https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1", @@ -569,7 +577,7 @@ }, "cloud.google.com/go/securitycenter/apiv1p1beta1": { "distribution_name": "cloud.google.com/go/securitycenter/apiv1p1beta1", - "description": "Cloud Security Command Center API", + "description": "Security Command Center API", "language": "Go", "client_library_type": "generated", "docs_url": "https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1p1beta1", @@ -733,7 +741,7 @@ "language": "Go", "client_library_type": "generated", "docs_url": "https://pkg.go.dev/cloud.google.com/go/webrisk/apiv1", - "release_level": "beta" + "release_level": "ga" }, "cloud.google.com/go/webrisk/apiv1beta1": { "distribution_name": "cloud.google.com/go/webrisk/apiv1beta1", diff --git a/vendor/cloud.google.com/go/internal/version/version.go b/vendor/cloud.google.com/go/internal/version/version.go index c37b16155..7664a1e5a 100644 --- a/vendor/cloud.google.com/go/internal/version/version.go +++ b/vendor/cloud.google.com/go/internal/version/version.go @@ -26,7 +26,7 @@ import ( // Repo is the current version of the client libraries in this // repo. It should be a date in YYYYMMDD format. -const Repo = "20200602" +const Repo = "20200618" // Go returns the Go runtime version. The returned string // has no whitespace. diff --git a/vendor/cloud.google.com/go/tools.go b/vendor/cloud.google.com/go/tools.go index 5c91f8a38..da5ca585d 100644 --- a/vendor/cloud.google.com/go/tools.go +++ b/vendor/cloud.google.com/go/tools.go @@ -28,5 +28,4 @@ import ( _ "github.com/jstemmer/go-junit-report" _ "golang.org/x/lint/golint" _ "golang.org/x/tools/cmd/goimports" - _ "honnef.co/go/tools/cmd/staticcheck" ) diff --git a/vendor/github.com/BurntSushi/toml/.gitignore b/vendor/github.com/BurntSushi/toml/.gitignore deleted file mode 100644 index 0cd380037..000000000 --- a/vendor/github.com/BurntSushi/toml/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -TAGS -tags -.*.swp -tomlcheck/tomlcheck -toml.test diff --git a/vendor/github.com/BurntSushi/toml/.travis.yml b/vendor/github.com/BurntSushi/toml/.travis.yml deleted file mode 100644 index 8b8afc4f0..000000000 --- a/vendor/github.com/BurntSushi/toml/.travis.yml +++ /dev/null @@ -1,15 +0,0 @@ -language: go -go: - - 1.1 - - 1.2 - - 1.3 - - 1.4 - - 1.5 - - 1.6 - - tip -install: - - go install ./... - - go get github.com/BurntSushi/toml-test -script: - - export PATH="$PATH:$HOME/gopath/bin" - - make test diff --git a/vendor/github.com/BurntSushi/toml/COMPATIBLE b/vendor/github.com/BurntSushi/toml/COMPATIBLE deleted file mode 100644 index 6efcfd0ce..000000000 --- a/vendor/github.com/BurntSushi/toml/COMPATIBLE +++ /dev/null @@ -1,3 +0,0 @@ -Compatible with TOML version -[v0.4.0](https://github.com/toml-lang/toml/blob/v0.4.0/versions/en/toml-v0.4.0.md) - diff --git a/vendor/github.com/BurntSushi/toml/COPYING b/vendor/github.com/BurntSushi/toml/COPYING deleted file mode 100644 index 01b574320..000000000 --- a/vendor/github.com/BurntSushi/toml/COPYING +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 TOML authors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/vendor/github.com/BurntSushi/toml/Makefile b/vendor/github.com/BurntSushi/toml/Makefile deleted file mode 100644 index 3600848d3..000000000 --- a/vendor/github.com/BurntSushi/toml/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -install: - go install ./... - -test: install - go test -v - toml-test toml-test-decoder - toml-test -encoder toml-test-encoder - -fmt: - gofmt -w *.go */*.go - colcheck *.go */*.go - -tags: - find ./ -name '*.go' -print0 | xargs -0 gotags > TAGS - -push: - git push origin master - git push github master - diff --git a/vendor/github.com/BurntSushi/toml/README.md b/vendor/github.com/BurntSushi/toml/README.md deleted file mode 100644 index 7c1b37ecc..000000000 --- a/vendor/github.com/BurntSushi/toml/README.md +++ /dev/null @@ -1,218 +0,0 @@ -## TOML parser and encoder for Go with reflection - -TOML stands for Tom's Obvious, Minimal Language. This Go package provides a -reflection interface similar to Go's standard library `json` and `xml` -packages. This package also supports the `encoding.TextUnmarshaler` and -`encoding.TextMarshaler` interfaces so that you can define custom data -representations. (There is an example of this below.) - -Spec: https://github.com/toml-lang/toml - -Compatible with TOML version -[v0.4.0](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md) - -Documentation: https://godoc.org/github.com/BurntSushi/toml - -Installation: - -```bash -go get github.com/BurntSushi/toml -``` - -Try the toml validator: - -```bash -go get github.com/BurntSushi/toml/cmd/tomlv -tomlv some-toml-file.toml -``` - -[![Build Status](https://travis-ci.org/BurntSushi/toml.svg?branch=master)](https://travis-ci.org/BurntSushi/toml) [![GoDoc](https://godoc.org/github.com/BurntSushi/toml?status.svg)](https://godoc.org/github.com/BurntSushi/toml) - -### Testing - -This package passes all tests in -[toml-test](https://github.com/BurntSushi/toml-test) for both the decoder -and the encoder. - -### Examples - -This package works similarly to how the Go standard library handles `XML` -and `JSON`. Namely, data is loaded into Go values via reflection. - -For the simplest example, consider some TOML file as just a list of keys -and values: - -```toml -Age = 25 -Cats = [ "Cauchy", "Plato" ] -Pi = 3.14 -Perfection = [ 6, 28, 496, 8128 ] -DOB = 1987-07-05T05:45:00Z -``` - -Which could be defined in Go as: - -```go -type Config struct { - Age int - Cats []string - Pi float64 - Perfection []int - DOB time.Time // requires `import time` -} -``` - -And then decoded with: - -```go -var conf Config -if _, err := toml.Decode(tomlData, &conf); err != nil { - // handle error -} -``` - -You can also use struct tags if your struct field name doesn't map to a TOML -key value directly: - -```toml -some_key_NAME = "wat" -``` - -```go -type TOML struct { - ObscureKey string `toml:"some_key_NAME"` -} -``` - -### Using the `encoding.TextUnmarshaler` interface - -Here's an example that automatically parses duration strings into -`time.Duration` values: - -```toml -[[song]] -name = "Thunder Road" -duration = "4m49s" - -[[song]] -name = "Stairway to Heaven" -duration = "8m03s" -``` - -Which can be decoded with: - -```go -type song struct { - Name string - Duration duration -} -type songs struct { - Song []song -} -var favorites songs -if _, err := toml.Decode(blob, &favorites); err != nil { - log.Fatal(err) -} - -for _, s := range favorites.Song { - fmt.Printf("%s (%s)\n", s.Name, s.Duration) -} -``` - -And you'll also need a `duration` type that satisfies the -`encoding.TextUnmarshaler` interface: - -```go -type duration struct { - time.Duration -} - -func (d *duration) UnmarshalText(text []byte) error { - var err error - d.Duration, err = time.ParseDuration(string(text)) - return err -} -``` - -### More complex usage - -Here's an example of how to load the example from the official spec page: - -```toml -# This is a TOML document. Boom. - -title = "TOML Example" - -[owner] -name = "Tom Preston-Werner" -organization = "GitHub" -bio = "GitHub Cofounder & CEO\nLikes tater tots and beer." -dob = 1979-05-27T07:32:00Z # First class dates? Why not? - -[database] -server = "192.168.1.1" -ports = [ 8001, 8001, 8002 ] -connection_max = 5000 -enabled = true - -[servers] - - # You can indent as you please. Tabs or spaces. TOML don't care. - [servers.alpha] - ip = "10.0.0.1" - dc = "eqdc10" - - [servers.beta] - ip = "10.0.0.2" - dc = "eqdc10" - -[clients] -data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it - -# Line breaks are OK when inside arrays -hosts = [ - "alpha", - "omega" -] -``` - -And the corresponding Go types are: - -```go -type tomlConfig struct { - Title string - Owner ownerInfo - DB database `toml:"database"` - Servers map[string]server - Clients clients -} - -type ownerInfo struct { - Name string - Org string `toml:"organization"` - Bio string - DOB time.Time -} - -type database struct { - Server string - Ports []int - ConnMax int `toml:"connection_max"` - Enabled bool -} - -type server struct { - IP string - DC string -} - -type clients struct { - Data [][]interface{} - Hosts []string -} -``` - -Note that a case insensitive match will be tried if an exact match can't be -found. - -A working example of the above can be found in `_examples/example.{go,toml}`. diff --git a/vendor/github.com/BurntSushi/toml/decode.go b/vendor/github.com/BurntSushi/toml/decode.go deleted file mode 100644 index b0fd51d5b..000000000 --- a/vendor/github.com/BurntSushi/toml/decode.go +++ /dev/null @@ -1,509 +0,0 @@ -package toml - -import ( - "fmt" - "io" - "io/ioutil" - "math" - "reflect" - "strings" - "time" -) - -func e(format string, args ...interface{}) error { - return fmt.Errorf("toml: "+format, args...) -} - -// Unmarshaler is the interface implemented by objects that can unmarshal a -// TOML description of themselves. -type Unmarshaler interface { - UnmarshalTOML(interface{}) error -} - -// Unmarshal decodes the contents of `p` in TOML format into a pointer `v`. -func Unmarshal(p []byte, v interface{}) error { - _, err := Decode(string(p), v) - return err -} - -// Primitive is a TOML value that hasn't been decoded into a Go value. -// When using the various `Decode*` functions, the type `Primitive` may -// be given to any value, and its decoding will be delayed. -// -// A `Primitive` value can be decoded using the `PrimitiveDecode` function. -// -// The underlying representation of a `Primitive` value is subject to change. -// Do not rely on it. -// -// N.B. Primitive values are still parsed, so using them will only avoid -// the overhead of reflection. They can be useful when you don't know the -// exact type of TOML data until run time. -type Primitive struct { - undecoded interface{} - context Key -} - -// DEPRECATED! -// -// Use MetaData.PrimitiveDecode instead. -func PrimitiveDecode(primValue Primitive, v interface{}) error { - md := MetaData{decoded: make(map[string]bool)} - return md.unify(primValue.undecoded, rvalue(v)) -} - -// PrimitiveDecode is just like the other `Decode*` functions, except it -// decodes a TOML value that has already been parsed. Valid primitive values -// can *only* be obtained from values filled by the decoder functions, -// including this method. (i.e., `v` may contain more `Primitive` -// values.) -// -// Meta data for primitive values is included in the meta data returned by -// the `Decode*` functions with one exception: keys returned by the Undecoded -// method will only reflect keys that were decoded. Namely, any keys hidden -// behind a Primitive will be considered undecoded. Executing this method will -// update the undecoded keys in the meta data. (See the example.) -func (md *MetaData) PrimitiveDecode(primValue Primitive, v interface{}) error { - md.context = primValue.context - defer func() { md.context = nil }() - return md.unify(primValue.undecoded, rvalue(v)) -} - -// Decode will decode the contents of `data` in TOML format into a pointer -// `v`. -// -// TOML hashes correspond to Go structs or maps. (Dealer's choice. They can be -// used interchangeably.) -// -// TOML arrays of tables correspond to either a slice of structs or a slice -// of maps. -// -// TOML datetimes correspond to Go `time.Time` values. -// -// All other TOML types (float, string, int, bool and array) correspond -// to the obvious Go types. -// -// An exception to the above rules is if a type implements the -// encoding.TextUnmarshaler interface. In this case, any primitive TOML value -// (floats, strings, integers, booleans and datetimes) will be converted to -// a byte string and given to the value's UnmarshalText method. See the -// Unmarshaler example for a demonstration with time duration strings. -// -// Key mapping -// -// TOML keys can map to either keys in a Go map or field names in a Go -// struct. The special `toml` struct tag may be used to map TOML keys to -// struct fields that don't match the key name exactly. (See the example.) -// A case insensitive match to struct names will be tried if an exact match -// can't be found. -// -// The mapping between TOML values and Go values is loose. That is, there -// may exist TOML values that cannot be placed into your representation, and -// there may be parts of your representation that do not correspond to -// TOML values. This loose mapping can be made stricter by using the IsDefined -// and/or Undecoded methods on the MetaData returned. -// -// This decoder will not handle cyclic types. If a cyclic type is passed, -// `Decode` will not terminate. -func Decode(data string, v interface{}) (MetaData, error) { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - return MetaData{}, e("Decode of non-pointer %s", reflect.TypeOf(v)) - } - if rv.IsNil() { - return MetaData{}, e("Decode of nil %s", reflect.TypeOf(v)) - } - p, err := parse(data) - if err != nil { - return MetaData{}, err - } - md := MetaData{ - p.mapping, p.types, p.ordered, - make(map[string]bool, len(p.ordered)), nil, - } - return md, md.unify(p.mapping, indirect(rv)) -} - -// DecodeFile is just like Decode, except it will automatically read the -// contents of the file at `fpath` and decode it for you. -func DecodeFile(fpath string, v interface{}) (MetaData, error) { - bs, err := ioutil.ReadFile(fpath) - if err != nil { - return MetaData{}, err - } - return Decode(string(bs), v) -} - -// DecodeReader is just like Decode, except it will consume all bytes -// from the reader and decode it for you. -func DecodeReader(r io.Reader, v interface{}) (MetaData, error) { - bs, err := ioutil.ReadAll(r) - if err != nil { - return MetaData{}, err - } - return Decode(string(bs), v) -} - -// unify performs a sort of type unification based on the structure of `rv`, -// which is the client representation. -// -// Any type mismatch produces an error. Finding a type that we don't know -// how to handle produces an unsupported type error. -func (md *MetaData) unify(data interface{}, rv reflect.Value) error { - - // Special case. Look for a `Primitive` value. - if rv.Type() == reflect.TypeOf((*Primitive)(nil)).Elem() { - // Save the undecoded data and the key context into the primitive - // value. - context := make(Key, len(md.context)) - copy(context, md.context) - rv.Set(reflect.ValueOf(Primitive{ - undecoded: data, - context: context, - })) - return nil - } - - // Special case. Unmarshaler Interface support. - if rv.CanAddr() { - if v, ok := rv.Addr().Interface().(Unmarshaler); ok { - return v.UnmarshalTOML(data) - } - } - - // Special case. Handle time.Time values specifically. - // TODO: Remove this code when we decide to drop support for Go 1.1. - // This isn't necessary in Go 1.2 because time.Time satisfies the encoding - // interfaces. - if rv.Type().AssignableTo(rvalue(time.Time{}).Type()) { - return md.unifyDatetime(data, rv) - } - - // Special case. Look for a value satisfying the TextUnmarshaler interface. - if v, ok := rv.Interface().(TextUnmarshaler); ok { - return md.unifyText(data, v) - } - // BUG(burntsushi) - // The behavior here is incorrect whenever a Go type satisfies the - // encoding.TextUnmarshaler interface but also corresponds to a TOML - // hash or array. In particular, the unmarshaler should only be applied - // to primitive TOML values. But at this point, it will be applied to - // all kinds of values and produce an incorrect error whenever those values - // are hashes or arrays (including arrays of tables). - - k := rv.Kind() - - // laziness - if k >= reflect.Int && k <= reflect.Uint64 { - return md.unifyInt(data, rv) - } - switch k { - case reflect.Ptr: - elem := reflect.New(rv.Type().Elem()) - err := md.unify(data, reflect.Indirect(elem)) - if err != nil { - return err - } - rv.Set(elem) - return nil - case reflect.Struct: - return md.unifyStruct(data, rv) - case reflect.Map: - return md.unifyMap(data, rv) - case reflect.Array: - return md.unifyArray(data, rv) - case reflect.Slice: - return md.unifySlice(data, rv) - case reflect.String: - return md.unifyString(data, rv) - case reflect.Bool: - return md.unifyBool(data, rv) - case reflect.Interface: - // we only support empty interfaces. - if rv.NumMethod() > 0 { - return e("unsupported type %s", rv.Type()) - } - return md.unifyAnything(data, rv) - case reflect.Float32: - fallthrough - case reflect.Float64: - return md.unifyFloat64(data, rv) - } - return e("unsupported type %s", rv.Kind()) -} - -func (md *MetaData) unifyStruct(mapping interface{}, rv reflect.Value) error { - tmap, ok := mapping.(map[string]interface{}) - if !ok { - if mapping == nil { - return nil - } - return e("type mismatch for %s: expected table but found %T", - rv.Type().String(), mapping) - } - - for key, datum := range tmap { - var f *field - fields := cachedTypeFields(rv.Type()) - for i := range fields { - ff := &fields[i] - if ff.name == key { - f = ff - break - } - if f == nil && strings.EqualFold(ff.name, key) { - f = ff - } - } - if f != nil { - subv := rv - for _, i := range f.index { - subv = indirect(subv.Field(i)) - } - if isUnifiable(subv) { - md.decoded[md.context.add(key).String()] = true - md.context = append(md.context, key) - if err := md.unify(datum, subv); err != nil { - return err - } - md.context = md.context[0 : len(md.context)-1] - } else if f.name != "" { - // Bad user! No soup for you! - return e("cannot write unexported field %s.%s", - rv.Type().String(), f.name) - } - } - } - return nil -} - -func (md *MetaData) unifyMap(mapping interface{}, rv reflect.Value) error { - tmap, ok := mapping.(map[string]interface{}) - if !ok { - if tmap == nil { - return nil - } - return badtype("map", mapping) - } - if rv.IsNil() { - rv.Set(reflect.MakeMap(rv.Type())) - } - for k, v := range tmap { - md.decoded[md.context.add(k).String()] = true - md.context = append(md.context, k) - - rvkey := indirect(reflect.New(rv.Type().Key())) - rvval := reflect.Indirect(reflect.New(rv.Type().Elem())) - if err := md.unify(v, rvval); err != nil { - return err - } - md.context = md.context[0 : len(md.context)-1] - - rvkey.SetString(k) - rv.SetMapIndex(rvkey, rvval) - } - return nil -} - -func (md *MetaData) unifyArray(data interface{}, rv reflect.Value) error { - datav := reflect.ValueOf(data) - if datav.Kind() != reflect.Slice { - if !datav.IsValid() { - return nil - } - return badtype("slice", data) - } - sliceLen := datav.Len() - if sliceLen != rv.Len() { - return e("expected array length %d; got TOML array of length %d", - rv.Len(), sliceLen) - } - return md.unifySliceArray(datav, rv) -} - -func (md *MetaData) unifySlice(data interface{}, rv reflect.Value) error { - datav := reflect.ValueOf(data) - if datav.Kind() != reflect.Slice { - if !datav.IsValid() { - return nil - } - return badtype("slice", data) - } - n := datav.Len() - if rv.IsNil() || rv.Cap() < n { - rv.Set(reflect.MakeSlice(rv.Type(), n, n)) - } - rv.SetLen(n) - return md.unifySliceArray(datav, rv) -} - -func (md *MetaData) unifySliceArray(data, rv reflect.Value) error { - sliceLen := data.Len() - for i := 0; i < sliceLen; i++ { - v := data.Index(i).Interface() - sliceval := indirect(rv.Index(i)) - if err := md.unify(v, sliceval); err != nil { - return err - } - } - return nil -} - -func (md *MetaData) unifyDatetime(data interface{}, rv reflect.Value) error { - if _, ok := data.(time.Time); ok { - rv.Set(reflect.ValueOf(data)) - return nil - } - return badtype("time.Time", data) -} - -func (md *MetaData) unifyString(data interface{}, rv reflect.Value) error { - if s, ok := data.(string); ok { - rv.SetString(s) - return nil - } - return badtype("string", data) -} - -func (md *MetaData) unifyFloat64(data interface{}, rv reflect.Value) error { - if num, ok := data.(float64); ok { - switch rv.Kind() { - case reflect.Float32: - fallthrough - case reflect.Float64: - rv.SetFloat(num) - default: - panic("bug") - } - return nil - } - return badtype("float", data) -} - -func (md *MetaData) unifyInt(data interface{}, rv reflect.Value) error { - if num, ok := data.(int64); ok { - if rv.Kind() >= reflect.Int && rv.Kind() <= reflect.Int64 { - switch rv.Kind() { - case reflect.Int, reflect.Int64: - // No bounds checking necessary. - case reflect.Int8: - if num < math.MinInt8 || num > math.MaxInt8 { - return e("value %d is out of range for int8", num) - } - case reflect.Int16: - if num < math.MinInt16 || num > math.MaxInt16 { - return e("value %d is out of range for int16", num) - } - case reflect.Int32: - if num < math.MinInt32 || num > math.MaxInt32 { - return e("value %d is out of range for int32", num) - } - } - rv.SetInt(num) - } else if rv.Kind() >= reflect.Uint && rv.Kind() <= reflect.Uint64 { - unum := uint64(num) - switch rv.Kind() { - case reflect.Uint, reflect.Uint64: - // No bounds checking necessary. - case reflect.Uint8: - if num < 0 || unum > math.MaxUint8 { - return e("value %d is out of range for uint8", num) - } - case reflect.Uint16: - if num < 0 || unum > math.MaxUint16 { - return e("value %d is out of range for uint16", num) - } - case reflect.Uint32: - if num < 0 || unum > math.MaxUint32 { - return e("value %d is out of range for uint32", num) - } - } - rv.SetUint(unum) - } else { - panic("unreachable") - } - return nil - } - return badtype("integer", data) -} - -func (md *MetaData) unifyBool(data interface{}, rv reflect.Value) error { - if b, ok := data.(bool); ok { - rv.SetBool(b) - return nil - } - return badtype("boolean", data) -} - -func (md *MetaData) unifyAnything(data interface{}, rv reflect.Value) error { - rv.Set(reflect.ValueOf(data)) - return nil -} - -func (md *MetaData) unifyText(data interface{}, v TextUnmarshaler) error { - var s string - switch sdata := data.(type) { - case TextMarshaler: - text, err := sdata.MarshalText() - if err != nil { - return err - } - s = string(text) - case fmt.Stringer: - s = sdata.String() - case string: - s = sdata - case bool: - s = fmt.Sprintf("%v", sdata) - case int64: - s = fmt.Sprintf("%d", sdata) - case float64: - s = fmt.Sprintf("%f", sdata) - default: - return badtype("primitive (string-like)", data) - } - if err := v.UnmarshalText([]byte(s)); err != nil { - return err - } - return nil -} - -// rvalue returns a reflect.Value of `v`. All pointers are resolved. -func rvalue(v interface{}) reflect.Value { - return indirect(reflect.ValueOf(v)) -} - -// indirect returns the value pointed to by a pointer. -// Pointers are followed until the value is not a pointer. -// New values are allocated for each nil pointer. -// -// An exception to this rule is if the value satisfies an interface of -// interest to us (like encoding.TextUnmarshaler). -func indirect(v reflect.Value) reflect.Value { - if v.Kind() != reflect.Ptr { - if v.CanSet() { - pv := v.Addr() - if _, ok := pv.Interface().(TextUnmarshaler); ok { - return pv - } - } - return v - } - if v.IsNil() { - v.Set(reflect.New(v.Type().Elem())) - } - return indirect(reflect.Indirect(v)) -} - -func isUnifiable(rv reflect.Value) bool { - if rv.CanSet() { - return true - } - if _, ok := rv.Interface().(TextUnmarshaler); ok { - return true - } - return false -} - -func badtype(expected string, data interface{}) error { - return e("cannot load TOML value of type %T into a Go %s", data, expected) -} diff --git a/vendor/github.com/BurntSushi/toml/decode_meta.go b/vendor/github.com/BurntSushi/toml/decode_meta.go deleted file mode 100644 index b9914a679..000000000 --- a/vendor/github.com/BurntSushi/toml/decode_meta.go +++ /dev/null @@ -1,121 +0,0 @@ -package toml - -import "strings" - -// MetaData allows access to meta information about TOML data that may not -// be inferrable via reflection. In particular, whether a key has been defined -// and the TOML type of a key. -type MetaData struct { - mapping map[string]interface{} - types map[string]tomlType - keys []Key - decoded map[string]bool - context Key // Used only during decoding. -} - -// IsDefined returns true if the key given exists in the TOML data. The key -// should be specified hierarchially. e.g., -// -// // access the TOML key 'a.b.c' -// IsDefined("a", "b", "c") -// -// IsDefined will return false if an empty key given. Keys are case sensitive. -func (md *MetaData) IsDefined(key ...string) bool { - if len(key) == 0 { - return false - } - - var hash map[string]interface{} - var ok bool - var hashOrVal interface{} = md.mapping - for _, k := range key { - if hash, ok = hashOrVal.(map[string]interface{}); !ok { - return false - } - if hashOrVal, ok = hash[k]; !ok { - return false - } - } - return true -} - -// Type returns a string representation of the type of the key specified. -// -// Type will return the empty string if given an empty key or a key that -// does not exist. Keys are case sensitive. -func (md *MetaData) Type(key ...string) string { - fullkey := strings.Join(key, ".") - if typ, ok := md.types[fullkey]; ok { - return typ.typeString() - } - return "" -} - -// Key is the type of any TOML key, including key groups. Use (MetaData).Keys -// to get values of this type. -type Key []string - -func (k Key) String() string { - return strings.Join(k, ".") -} - -func (k Key) maybeQuotedAll() string { - var ss []string - for i := range k { - ss = append(ss, k.maybeQuoted(i)) - } - return strings.Join(ss, ".") -} - -func (k Key) maybeQuoted(i int) string { - quote := false - for _, c := range k[i] { - if !isBareKeyChar(c) { - quote = true - break - } - } - if quote { - return "\"" + strings.Replace(k[i], "\"", "\\\"", -1) + "\"" - } - return k[i] -} - -func (k Key) add(piece string) Key { - newKey := make(Key, len(k)+1) - copy(newKey, k) - newKey[len(k)] = piece - return newKey -} - -// Keys returns a slice of every key in the TOML data, including key groups. -// Each key is itself a slice, where the first element is the top of the -// hierarchy and the last is the most specific. -// -// The list will have the same order as the keys appeared in the TOML data. -// -// All keys returned are non-empty. -func (md *MetaData) Keys() []Key { - return md.keys -} - -// Undecoded returns all keys that have not been decoded in the order in which -// they appear in the original TOML document. -// -// This includes keys that haven't been decoded because of a Primitive value. -// Once the Primitive value is decoded, the keys will be considered decoded. -// -// Also note that decoding into an empty interface will result in no decoding, -// and so no keys will be considered decoded. -// -// In this sense, the Undecoded keys correspond to keys in the TOML document -// that do not have a concrete type in your representation. -func (md *MetaData) Undecoded() []Key { - undecoded := make([]Key, 0, len(md.keys)) - for _, key := range md.keys { - if !md.decoded[key.String()] { - undecoded = append(undecoded, key) - } - } - return undecoded -} diff --git a/vendor/github.com/BurntSushi/toml/doc.go b/vendor/github.com/BurntSushi/toml/doc.go deleted file mode 100644 index b371f396e..000000000 --- a/vendor/github.com/BurntSushi/toml/doc.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Package toml provides facilities for decoding and encoding TOML configuration -files via reflection. There is also support for delaying decoding with -the Primitive type, and querying the set of keys in a TOML document with the -MetaData type. - -The specification implemented: https://github.com/toml-lang/toml - -The sub-command github.com/BurntSushi/toml/cmd/tomlv can be used to verify -whether a file is a valid TOML document. It can also be used to print the -type of each key in a TOML document. - -Testing - -There are two important types of tests used for this package. The first is -contained inside '*_test.go' files and uses the standard Go unit testing -framework. These tests are primarily devoted to holistically testing the -decoder and encoder. - -The second type of testing is used to verify the implementation's adherence -to the TOML specification. These tests have been factored into their own -project: https://github.com/BurntSushi/toml-test - -The reason the tests are in a separate project is so that they can be used by -any implementation of TOML. Namely, it is language agnostic. -*/ -package toml diff --git a/vendor/github.com/BurntSushi/toml/encode.go b/vendor/github.com/BurntSushi/toml/encode.go deleted file mode 100644 index d905c21a2..000000000 --- a/vendor/github.com/BurntSushi/toml/encode.go +++ /dev/null @@ -1,568 +0,0 @@ -package toml - -import ( - "bufio" - "errors" - "fmt" - "io" - "reflect" - "sort" - "strconv" - "strings" - "time" -) - -type tomlEncodeError struct{ error } - -var ( - errArrayMixedElementTypes = errors.New( - "toml: cannot encode array with mixed element types") - errArrayNilElement = errors.New( - "toml: cannot encode array with nil element") - errNonString = errors.New( - "toml: cannot encode a map with non-string key type") - errAnonNonStruct = errors.New( - "toml: cannot encode an anonymous field that is not a struct") - errArrayNoTable = errors.New( - "toml: TOML array element cannot contain a table") - errNoKey = errors.New( - "toml: top-level values must be Go maps or structs") - errAnything = errors.New("") // used in testing -) - -var quotedReplacer = strings.NewReplacer( - "\t", "\\t", - "\n", "\\n", - "\r", "\\r", - "\"", "\\\"", - "\\", "\\\\", -) - -// Encoder controls the encoding of Go values to a TOML document to some -// io.Writer. -// -// The indentation level can be controlled with the Indent field. -type Encoder struct { - // A single indentation level. By default it is two spaces. - Indent string - - // hasWritten is whether we have written any output to w yet. - hasWritten bool - w *bufio.Writer -} - -// NewEncoder returns a TOML encoder that encodes Go values to the io.Writer -// given. By default, a single indentation level is 2 spaces. -func NewEncoder(w io.Writer) *Encoder { - return &Encoder{ - w: bufio.NewWriter(w), - Indent: " ", - } -} - -// Encode writes a TOML representation of the Go value to the underlying -// io.Writer. If the value given cannot be encoded to a valid TOML document, -// then an error is returned. -// -// The mapping between Go values and TOML values should be precisely the same -// as for the Decode* functions. Similarly, the TextMarshaler interface is -// supported by encoding the resulting bytes as strings. (If you want to write -// arbitrary binary data then you will need to use something like base64 since -// TOML does not have any binary types.) -// -// When encoding TOML hashes (i.e., Go maps or structs), keys without any -// sub-hashes are encoded first. -// -// If a Go map is encoded, then its keys are sorted alphabetically for -// deterministic output. More control over this behavior may be provided if -// there is demand for it. -// -// Encoding Go values without a corresponding TOML representation---like map -// types with non-string keys---will cause an error to be returned. Similarly -// for mixed arrays/slices, arrays/slices with nil elements, embedded -// non-struct types and nested slices containing maps or structs. -// (e.g., [][]map[string]string is not allowed but []map[string]string is OK -// and so is []map[string][]string.) -func (enc *Encoder) Encode(v interface{}) error { - rv := eindirect(reflect.ValueOf(v)) - if err := enc.safeEncode(Key([]string{}), rv); err != nil { - return err - } - return enc.w.Flush() -} - -func (enc *Encoder) safeEncode(key Key, rv reflect.Value) (err error) { - defer func() { - if r := recover(); r != nil { - if terr, ok := r.(tomlEncodeError); ok { - err = terr.error - return - } - panic(r) - } - }() - enc.encode(key, rv) - return nil -} - -func (enc *Encoder) encode(key Key, rv reflect.Value) { - // Special case. Time needs to be in ISO8601 format. - // Special case. If we can marshal the type to text, then we used that. - // Basically, this prevents the encoder for handling these types as - // generic structs (or whatever the underlying type of a TextMarshaler is). - switch rv.Interface().(type) { - case time.Time, TextMarshaler: - enc.keyEqElement(key, rv) - return - } - - k := rv.Kind() - switch k { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64, - reflect.Float32, reflect.Float64, reflect.String, reflect.Bool: - enc.keyEqElement(key, rv) - case reflect.Array, reflect.Slice: - if typeEqual(tomlArrayHash, tomlTypeOfGo(rv)) { - enc.eArrayOfTables(key, rv) - } else { - enc.keyEqElement(key, rv) - } - case reflect.Interface: - if rv.IsNil() { - return - } - enc.encode(key, rv.Elem()) - case reflect.Map: - if rv.IsNil() { - return - } - enc.eTable(key, rv) - case reflect.Ptr: - if rv.IsNil() { - return - } - enc.encode(key, rv.Elem()) - case reflect.Struct: - enc.eTable(key, rv) - default: - panic(e("unsupported type for key '%s': %s", key, k)) - } -} - -// eElement encodes any value that can be an array element (primitives and -// arrays). -func (enc *Encoder) eElement(rv reflect.Value) { - switch v := rv.Interface().(type) { - case time.Time: - // Special case time.Time as a primitive. Has to come before - // TextMarshaler below because time.Time implements - // encoding.TextMarshaler, but we need to always use UTC. - enc.wf(v.UTC().Format("2006-01-02T15:04:05Z")) - return - case TextMarshaler: - // Special case. Use text marshaler if it's available for this value. - if s, err := v.MarshalText(); err != nil { - encPanic(err) - } else { - enc.writeQuoted(string(s)) - } - return - } - switch rv.Kind() { - case reflect.Bool: - enc.wf(strconv.FormatBool(rv.Bool())) - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64: - enc.wf(strconv.FormatInt(rv.Int(), 10)) - case reflect.Uint, reflect.Uint8, reflect.Uint16, - reflect.Uint32, reflect.Uint64: - enc.wf(strconv.FormatUint(rv.Uint(), 10)) - case reflect.Float32: - enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 32))) - case reflect.Float64: - enc.wf(floatAddDecimal(strconv.FormatFloat(rv.Float(), 'f', -1, 64))) - case reflect.Array, reflect.Slice: - enc.eArrayOrSliceElement(rv) - case reflect.Interface: - enc.eElement(rv.Elem()) - case reflect.String: - enc.writeQuoted(rv.String()) - default: - panic(e("unexpected primitive type: %s", rv.Kind())) - } -} - -// By the TOML spec, all floats must have a decimal with at least one -// number on either side. -func floatAddDecimal(fstr string) string { - if !strings.Contains(fstr, ".") { - return fstr + ".0" - } - return fstr -} - -func (enc *Encoder) writeQuoted(s string) { - enc.wf("\"%s\"", quotedReplacer.Replace(s)) -} - -func (enc *Encoder) eArrayOrSliceElement(rv reflect.Value) { - length := rv.Len() - enc.wf("[") - for i := 0; i < length; i++ { - elem := rv.Index(i) - enc.eElement(elem) - if i != length-1 { - enc.wf(", ") - } - } - enc.wf("]") -} - -func (enc *Encoder) eArrayOfTables(key Key, rv reflect.Value) { - if len(key) == 0 { - encPanic(errNoKey) - } - for i := 0; i < rv.Len(); i++ { - trv := rv.Index(i) - if isNil(trv) { - continue - } - panicIfInvalidKey(key) - enc.newline() - enc.wf("%s[[%s]]", enc.indentStr(key), key.maybeQuotedAll()) - enc.newline() - enc.eMapOrStruct(key, trv) - } -} - -func (enc *Encoder) eTable(key Key, rv reflect.Value) { - panicIfInvalidKey(key) - if len(key) == 1 { - // Output an extra newline between top-level tables. - // (The newline isn't written if nothing else has been written though.) - enc.newline() - } - if len(key) > 0 { - enc.wf("%s[%s]", enc.indentStr(key), key.maybeQuotedAll()) - enc.newline() - } - enc.eMapOrStruct(key, rv) -} - -func (enc *Encoder) eMapOrStruct(key Key, rv reflect.Value) { - switch rv := eindirect(rv); rv.Kind() { - case reflect.Map: - enc.eMap(key, rv) - case reflect.Struct: - enc.eStruct(key, rv) - default: - panic("eTable: unhandled reflect.Value Kind: " + rv.Kind().String()) - } -} - -func (enc *Encoder) eMap(key Key, rv reflect.Value) { - rt := rv.Type() - if rt.Key().Kind() != reflect.String { - encPanic(errNonString) - } - - // Sort keys so that we have deterministic output. And write keys directly - // underneath this key first, before writing sub-structs or sub-maps. - var mapKeysDirect, mapKeysSub []string - for _, mapKey := range rv.MapKeys() { - k := mapKey.String() - if typeIsHash(tomlTypeOfGo(rv.MapIndex(mapKey))) { - mapKeysSub = append(mapKeysSub, k) - } else { - mapKeysDirect = append(mapKeysDirect, k) - } - } - - var writeMapKeys = func(mapKeys []string) { - sort.Strings(mapKeys) - for _, mapKey := range mapKeys { - mrv := rv.MapIndex(reflect.ValueOf(mapKey)) - if isNil(mrv) { - // Don't write anything for nil fields. - continue - } - enc.encode(key.add(mapKey), mrv) - } - } - writeMapKeys(mapKeysDirect) - writeMapKeys(mapKeysSub) -} - -func (enc *Encoder) eStruct(key Key, rv reflect.Value) { - // Write keys for fields directly under this key first, because if we write - // a field that creates a new table, then all keys under it will be in that - // table (not the one we're writing here). - rt := rv.Type() - var fieldsDirect, fieldsSub [][]int - var addFields func(rt reflect.Type, rv reflect.Value, start []int) - addFields = func(rt reflect.Type, rv reflect.Value, start []int) { - for i := 0; i < rt.NumField(); i++ { - f := rt.Field(i) - // skip unexported fields - if f.PkgPath != "" && !f.Anonymous { - continue - } - frv := rv.Field(i) - if f.Anonymous { - t := f.Type - switch t.Kind() { - case reflect.Struct: - // Treat anonymous struct fields with - // tag names as though they are not - // anonymous, like encoding/json does. - if getOptions(f.Tag).name == "" { - addFields(t, frv, f.Index) - continue - } - case reflect.Ptr: - if t.Elem().Kind() == reflect.Struct && - getOptions(f.Tag).name == "" { - if !frv.IsNil() { - addFields(t.Elem(), frv.Elem(), f.Index) - } - continue - } - // Fall through to the normal field encoding logic below - // for non-struct anonymous fields. - } - } - - if typeIsHash(tomlTypeOfGo(frv)) { - fieldsSub = append(fieldsSub, append(start, f.Index...)) - } else { - fieldsDirect = append(fieldsDirect, append(start, f.Index...)) - } - } - } - addFields(rt, rv, nil) - - var writeFields = func(fields [][]int) { - for _, fieldIndex := range fields { - sft := rt.FieldByIndex(fieldIndex) - sf := rv.FieldByIndex(fieldIndex) - if isNil(sf) { - // Don't write anything for nil fields. - continue - } - - opts := getOptions(sft.Tag) - if opts.skip { - continue - } - keyName := sft.Name - if opts.name != "" { - keyName = opts.name - } - if opts.omitempty && isEmpty(sf) { - continue - } - if opts.omitzero && isZero(sf) { - continue - } - - enc.encode(key.add(keyName), sf) - } - } - writeFields(fieldsDirect) - writeFields(fieldsSub) -} - -// tomlTypeName returns the TOML type name of the Go value's type. It is -// used to determine whether the types of array elements are mixed (which is -// forbidden). If the Go value is nil, then it is illegal for it to be an array -// element, and valueIsNil is returned as true. - -// Returns the TOML type of a Go value. The type may be `nil`, which means -// no concrete TOML type could be found. -func tomlTypeOfGo(rv reflect.Value) tomlType { - if isNil(rv) || !rv.IsValid() { - return nil - } - switch rv.Kind() { - case reflect.Bool: - return tomlBool - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, - reflect.Int64, - reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, - reflect.Uint64: - return tomlInteger - case reflect.Float32, reflect.Float64: - return tomlFloat - case reflect.Array, reflect.Slice: - if typeEqual(tomlHash, tomlArrayType(rv)) { - return tomlArrayHash - } - return tomlArray - case reflect.Ptr, reflect.Interface: - return tomlTypeOfGo(rv.Elem()) - case reflect.String: - return tomlString - case reflect.Map: - return tomlHash - case reflect.Struct: - switch rv.Interface().(type) { - case time.Time: - return tomlDatetime - case TextMarshaler: - return tomlString - default: - return tomlHash - } - default: - panic("unexpected reflect.Kind: " + rv.Kind().String()) - } -} - -// tomlArrayType returns the element type of a TOML array. The type returned -// may be nil if it cannot be determined (e.g., a nil slice or a zero length -// slize). This function may also panic if it finds a type that cannot be -// expressed in TOML (such as nil elements, heterogeneous arrays or directly -// nested arrays of tables). -func tomlArrayType(rv reflect.Value) tomlType { - if isNil(rv) || !rv.IsValid() || rv.Len() == 0 { - return nil - } - firstType := tomlTypeOfGo(rv.Index(0)) - if firstType == nil { - encPanic(errArrayNilElement) - } - - rvlen := rv.Len() - for i := 1; i < rvlen; i++ { - elem := rv.Index(i) - switch elemType := tomlTypeOfGo(elem); { - case elemType == nil: - encPanic(errArrayNilElement) - case !typeEqual(firstType, elemType): - encPanic(errArrayMixedElementTypes) - } - } - // If we have a nested array, then we must make sure that the nested - // array contains ONLY primitives. - // This checks arbitrarily nested arrays. - if typeEqual(firstType, tomlArray) || typeEqual(firstType, tomlArrayHash) { - nest := tomlArrayType(eindirect(rv.Index(0))) - if typeEqual(nest, tomlHash) || typeEqual(nest, tomlArrayHash) { - encPanic(errArrayNoTable) - } - } - return firstType -} - -type tagOptions struct { - skip bool // "-" - name string - omitempty bool - omitzero bool -} - -func getOptions(tag reflect.StructTag) tagOptions { - t := tag.Get("toml") - if t == "-" { - return tagOptions{skip: true} - } - var opts tagOptions - parts := strings.Split(t, ",") - opts.name = parts[0] - for _, s := range parts[1:] { - switch s { - case "omitempty": - opts.omitempty = true - case "omitzero": - opts.omitzero = true - } - } - return opts -} - -func isZero(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return rv.Int() == 0 - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return rv.Uint() == 0 - case reflect.Float32, reflect.Float64: - return rv.Float() == 0.0 - } - return false -} - -func isEmpty(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Array, reflect.Slice, reflect.Map, reflect.String: - return rv.Len() == 0 - case reflect.Bool: - return !rv.Bool() - } - return false -} - -func (enc *Encoder) newline() { - if enc.hasWritten { - enc.wf("\n") - } -} - -func (enc *Encoder) keyEqElement(key Key, val reflect.Value) { - if len(key) == 0 { - encPanic(errNoKey) - } - panicIfInvalidKey(key) - enc.wf("%s%s = ", enc.indentStr(key), key.maybeQuoted(len(key)-1)) - enc.eElement(val) - enc.newline() -} - -func (enc *Encoder) wf(format string, v ...interface{}) { - if _, err := fmt.Fprintf(enc.w, format, v...); err != nil { - encPanic(err) - } - enc.hasWritten = true -} - -func (enc *Encoder) indentStr(key Key) string { - return strings.Repeat(enc.Indent, len(key)-1) -} - -func encPanic(err error) { - panic(tomlEncodeError{err}) -} - -func eindirect(v reflect.Value) reflect.Value { - switch v.Kind() { - case reflect.Ptr, reflect.Interface: - return eindirect(v.Elem()) - default: - return v - } -} - -func isNil(rv reflect.Value) bool { - switch rv.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return rv.IsNil() - default: - return false - } -} - -func panicIfInvalidKey(key Key) { - for _, k := range key { - if len(k) == 0 { - encPanic(e("Key '%s' is not a valid table name. Key names "+ - "cannot be empty.", key.maybeQuotedAll())) - } - } -} - -func isValidKeyName(s string) bool { - return len(s) != 0 -} diff --git a/vendor/github.com/BurntSushi/toml/encoding_types.go b/vendor/github.com/BurntSushi/toml/encoding_types.go deleted file mode 100644 index d36e1dd60..000000000 --- a/vendor/github.com/BurntSushi/toml/encoding_types.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build go1.2 - -package toml - -// In order to support Go 1.1, we define our own TextMarshaler and -// TextUnmarshaler types. For Go 1.2+, we just alias them with the -// standard library interfaces. - -import ( - "encoding" -) - -// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here -// so that Go 1.1 can be supported. -type TextMarshaler encoding.TextMarshaler - -// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined -// here so that Go 1.1 can be supported. -type TextUnmarshaler encoding.TextUnmarshaler diff --git a/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go b/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go deleted file mode 100644 index e8d503d04..000000000 --- a/vendor/github.com/BurntSushi/toml/encoding_types_1.1.go +++ /dev/null @@ -1,18 +0,0 @@ -// +build !go1.2 - -package toml - -// These interfaces were introduced in Go 1.2, so we add them manually when -// compiling for Go 1.1. - -// TextMarshaler is a synonym for encoding.TextMarshaler. It is defined here -// so that Go 1.1 can be supported. -type TextMarshaler interface { - MarshalText() (text []byte, err error) -} - -// TextUnmarshaler is a synonym for encoding.TextUnmarshaler. It is defined -// here so that Go 1.1 can be supported. -type TextUnmarshaler interface { - UnmarshalText(text []byte) error -} diff --git a/vendor/github.com/BurntSushi/toml/lex.go b/vendor/github.com/BurntSushi/toml/lex.go deleted file mode 100644 index e0a742a88..000000000 --- a/vendor/github.com/BurntSushi/toml/lex.go +++ /dev/null @@ -1,953 +0,0 @@ -package toml - -import ( - "fmt" - "strings" - "unicode" - "unicode/utf8" -) - -type itemType int - -const ( - itemError itemType = iota - itemNIL // used in the parser to indicate no type - itemEOF - itemText - itemString - itemRawString - itemMultilineString - itemRawMultilineString - itemBool - itemInteger - itemFloat - itemDatetime - itemArray // the start of an array - itemArrayEnd - itemTableStart - itemTableEnd - itemArrayTableStart - itemArrayTableEnd - itemKeyStart - itemCommentStart - itemInlineTableStart - itemInlineTableEnd -) - -const ( - eof = 0 - comma = ',' - tableStart = '[' - tableEnd = ']' - arrayTableStart = '[' - arrayTableEnd = ']' - tableSep = '.' - keySep = '=' - arrayStart = '[' - arrayEnd = ']' - commentStart = '#' - stringStart = '"' - stringEnd = '"' - rawStringStart = '\'' - rawStringEnd = '\'' - inlineTableStart = '{' - inlineTableEnd = '}' -) - -type stateFn func(lx *lexer) stateFn - -type lexer struct { - input string - start int - pos int - line int - state stateFn - items chan item - - // Allow for backing up up to three runes. - // This is necessary because TOML contains 3-rune tokens (""" and '''). - prevWidths [3]int - nprev int // how many of prevWidths are in use - // If we emit an eof, we can still back up, but it is not OK to call - // next again. - atEOF bool - - // A stack of state functions used to maintain context. - // The idea is to reuse parts of the state machine in various places. - // For example, values can appear at the top level or within arbitrarily - // nested arrays. The last state on the stack is used after a value has - // been lexed. Similarly for comments. - stack []stateFn -} - -type item struct { - typ itemType - val string - line int -} - -func (lx *lexer) nextItem() item { - for { - select { - case item := <-lx.items: - return item - default: - lx.state = lx.state(lx) - } - } -} - -func lex(input string) *lexer { - lx := &lexer{ - input: input, - state: lexTop, - line: 1, - items: make(chan item, 10), - stack: make([]stateFn, 0, 10), - } - return lx -} - -func (lx *lexer) push(state stateFn) { - lx.stack = append(lx.stack, state) -} - -func (lx *lexer) pop() stateFn { - if len(lx.stack) == 0 { - return lx.errorf("BUG in lexer: no states to pop") - } - last := lx.stack[len(lx.stack)-1] - lx.stack = lx.stack[0 : len(lx.stack)-1] - return last -} - -func (lx *lexer) current() string { - return lx.input[lx.start:lx.pos] -} - -func (lx *lexer) emit(typ itemType) { - lx.items <- item{typ, lx.current(), lx.line} - lx.start = lx.pos -} - -func (lx *lexer) emitTrim(typ itemType) { - lx.items <- item{typ, strings.TrimSpace(lx.current()), lx.line} - lx.start = lx.pos -} - -func (lx *lexer) next() (r rune) { - if lx.atEOF { - panic("next called after EOF") - } - if lx.pos >= len(lx.input) { - lx.atEOF = true - return eof - } - - if lx.input[lx.pos] == '\n' { - lx.line++ - } - lx.prevWidths[2] = lx.prevWidths[1] - lx.prevWidths[1] = lx.prevWidths[0] - if lx.nprev < 3 { - lx.nprev++ - } - r, w := utf8.DecodeRuneInString(lx.input[lx.pos:]) - lx.prevWidths[0] = w - lx.pos += w - return r -} - -// ignore skips over the pending input before this point. -func (lx *lexer) ignore() { - lx.start = lx.pos -} - -// backup steps back one rune. Can be called only twice between calls to next. -func (lx *lexer) backup() { - if lx.atEOF { - lx.atEOF = false - return - } - if lx.nprev < 1 { - panic("backed up too far") - } - w := lx.prevWidths[0] - lx.prevWidths[0] = lx.prevWidths[1] - lx.prevWidths[1] = lx.prevWidths[2] - lx.nprev-- - lx.pos -= w - if lx.pos < len(lx.input) && lx.input[lx.pos] == '\n' { - lx.line-- - } -} - -// accept consumes the next rune if it's equal to `valid`. -func (lx *lexer) accept(valid rune) bool { - if lx.next() == valid { - return true - } - lx.backup() - return false -} - -// peek returns but does not consume the next rune in the input. -func (lx *lexer) peek() rune { - r := lx.next() - lx.backup() - return r -} - -// skip ignores all input that matches the given predicate. -func (lx *lexer) skip(pred func(rune) bool) { - for { - r := lx.next() - if pred(r) { - continue - } - lx.backup() - lx.ignore() - return - } -} - -// errorf stops all lexing by emitting an error and returning `nil`. -// Note that any value that is a character is escaped if it's a special -// character (newlines, tabs, etc.). -func (lx *lexer) errorf(format string, values ...interface{}) stateFn { - lx.items <- item{ - itemError, - fmt.Sprintf(format, values...), - lx.line, - } - return nil -} - -// lexTop consumes elements at the top level of TOML data. -func lexTop(lx *lexer) stateFn { - r := lx.next() - if isWhitespace(r) || isNL(r) { - return lexSkip(lx, lexTop) - } - switch r { - case commentStart: - lx.push(lexTop) - return lexCommentStart - case tableStart: - return lexTableStart - case eof: - if lx.pos > lx.start { - return lx.errorf("unexpected EOF") - } - lx.emit(itemEOF) - return nil - } - - // At this point, the only valid item can be a key, so we back up - // and let the key lexer do the rest. - lx.backup() - lx.push(lexTopEnd) - return lexKeyStart -} - -// lexTopEnd is entered whenever a top-level item has been consumed. (A value -// or a table.) It must see only whitespace, and will turn back to lexTop -// upon a newline. If it sees EOF, it will quit the lexer successfully. -func lexTopEnd(lx *lexer) stateFn { - r := lx.next() - switch { - case r == commentStart: - // a comment will read to a newline for us. - lx.push(lexTop) - return lexCommentStart - case isWhitespace(r): - return lexTopEnd - case isNL(r): - lx.ignore() - return lexTop - case r == eof: - lx.emit(itemEOF) - return nil - } - return lx.errorf("expected a top-level item to end with a newline, "+ - "comment, or EOF, but got %q instead", r) -} - -// lexTable lexes the beginning of a table. Namely, it makes sure that -// it starts with a character other than '.' and ']'. -// It assumes that '[' has already been consumed. -// It also handles the case that this is an item in an array of tables. -// e.g., '[[name]]'. -func lexTableStart(lx *lexer) stateFn { - if lx.peek() == arrayTableStart { - lx.next() - lx.emit(itemArrayTableStart) - lx.push(lexArrayTableEnd) - } else { - lx.emit(itemTableStart) - lx.push(lexTableEnd) - } - return lexTableNameStart -} - -func lexTableEnd(lx *lexer) stateFn { - lx.emit(itemTableEnd) - return lexTopEnd -} - -func lexArrayTableEnd(lx *lexer) stateFn { - if r := lx.next(); r != arrayTableEnd { - return lx.errorf("expected end of table array name delimiter %q, "+ - "but got %q instead", arrayTableEnd, r) - } - lx.emit(itemArrayTableEnd) - return lexTopEnd -} - -func lexTableNameStart(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.peek(); { - case r == tableEnd || r == eof: - return lx.errorf("unexpected end of table name " + - "(table names cannot be empty)") - case r == tableSep: - return lx.errorf("unexpected table separator " + - "(table names cannot be empty)") - case r == stringStart || r == rawStringStart: - lx.ignore() - lx.push(lexTableNameEnd) - return lexValue // reuse string lexing - default: - return lexBareTableName - } -} - -// lexBareTableName lexes the name of a table. It assumes that at least one -// valid character for the table has already been read. -func lexBareTableName(lx *lexer) stateFn { - r := lx.next() - if isBareKeyChar(r) { - return lexBareTableName - } - lx.backup() - lx.emit(itemText) - return lexTableNameEnd -} - -// lexTableNameEnd reads the end of a piece of a table name, optionally -// consuming whitespace. -func lexTableNameEnd(lx *lexer) stateFn { - lx.skip(isWhitespace) - switch r := lx.next(); { - case isWhitespace(r): - return lexTableNameEnd - case r == tableSep: - lx.ignore() - return lexTableNameStart - case r == tableEnd: - return lx.pop() - default: - return lx.errorf("expected '.' or ']' to end table name, "+ - "but got %q instead", r) - } -} - -// lexKeyStart consumes a key name up until the first non-whitespace character. -// lexKeyStart will ignore whitespace. -func lexKeyStart(lx *lexer) stateFn { - r := lx.peek() - switch { - case r == keySep: - return lx.errorf("unexpected key separator %q", keySep) - case isWhitespace(r) || isNL(r): - lx.next() - return lexSkip(lx, lexKeyStart) - case r == stringStart || r == rawStringStart: - lx.ignore() - lx.emit(itemKeyStart) - lx.push(lexKeyEnd) - return lexValue // reuse string lexing - default: - lx.ignore() - lx.emit(itemKeyStart) - return lexBareKey - } -} - -// lexBareKey consumes the text of a bare key. Assumes that the first character -// (which is not whitespace) has not yet been consumed. -func lexBareKey(lx *lexer) stateFn { - switch r := lx.next(); { - case isBareKeyChar(r): - return lexBareKey - case isWhitespace(r): - lx.backup() - lx.emit(itemText) - return lexKeyEnd - case r == keySep: - lx.backup() - lx.emit(itemText) - return lexKeyEnd - default: - return lx.errorf("bare keys cannot contain %q", r) - } -} - -// lexKeyEnd consumes the end of a key and trims whitespace (up to the key -// separator). -func lexKeyEnd(lx *lexer) stateFn { - switch r := lx.next(); { - case r == keySep: - return lexSkip(lx, lexValue) - case isWhitespace(r): - return lexSkip(lx, lexKeyEnd) - default: - return lx.errorf("expected key separator %q, but got %q instead", - keySep, r) - } -} - -// lexValue starts the consumption of a value anywhere a value is expected. -// lexValue will ignore whitespace. -// After a value is lexed, the last state on the next is popped and returned. -func lexValue(lx *lexer) stateFn { - // We allow whitespace to precede a value, but NOT newlines. - // In array syntax, the array states are responsible for ignoring newlines. - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexValue) - case isDigit(r): - lx.backup() // avoid an extra state and use the same as above - return lexNumberOrDateStart - } - switch r { - case arrayStart: - lx.ignore() - lx.emit(itemArray) - return lexArrayValue - case inlineTableStart: - lx.ignore() - lx.emit(itemInlineTableStart) - return lexInlineTableValue - case stringStart: - if lx.accept(stringStart) { - if lx.accept(stringStart) { - lx.ignore() // Ignore """ - return lexMultilineString - } - lx.backup() - } - lx.ignore() // ignore the '"' - return lexString - case rawStringStart: - if lx.accept(rawStringStart) { - if lx.accept(rawStringStart) { - lx.ignore() // Ignore """ - return lexMultilineRawString - } - lx.backup() - } - lx.ignore() // ignore the "'" - return lexRawString - case '+', '-': - return lexNumberStart - case '.': // special error case, be kind to users - return lx.errorf("floats must start with a digit, not '.'") - } - if unicode.IsLetter(r) { - // Be permissive here; lexBool will give a nice error if the - // user wrote something like - // x = foo - // (i.e. not 'true' or 'false' but is something else word-like.) - lx.backup() - return lexBool - } - return lx.errorf("expected value but found %q instead", r) -} - -// lexArrayValue consumes one value in an array. It assumes that '[' or ',' -// have already been consumed. All whitespace and newlines are ignored. -func lexArrayValue(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r) || isNL(r): - return lexSkip(lx, lexArrayValue) - case r == commentStart: - lx.push(lexArrayValue) - return lexCommentStart - case r == comma: - return lx.errorf("unexpected comma") - case r == arrayEnd: - // NOTE(caleb): The spec isn't clear about whether you can have - // a trailing comma or not, so we'll allow it. - return lexArrayEnd - } - - lx.backup() - lx.push(lexArrayValueEnd) - return lexValue -} - -// lexArrayValueEnd consumes everything between the end of an array value and -// the next value (or the end of the array): it ignores whitespace and newlines -// and expects either a ',' or a ']'. -func lexArrayValueEnd(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r) || isNL(r): - return lexSkip(lx, lexArrayValueEnd) - case r == commentStart: - lx.push(lexArrayValueEnd) - return lexCommentStart - case r == comma: - lx.ignore() - return lexArrayValue // move on to the next value - case r == arrayEnd: - return lexArrayEnd - } - return lx.errorf( - "expected a comma or array terminator %q, but got %q instead", - arrayEnd, r, - ) -} - -// lexArrayEnd finishes the lexing of an array. -// It assumes that a ']' has just been consumed. -func lexArrayEnd(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemArrayEnd) - return lx.pop() -} - -// lexInlineTableValue consumes one key/value pair in an inline table. -// It assumes that '{' or ',' have already been consumed. Whitespace is ignored. -func lexInlineTableValue(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexInlineTableValue) - case isNL(r): - return lx.errorf("newlines not allowed within inline tables") - case r == commentStart: - lx.push(lexInlineTableValue) - return lexCommentStart - case r == comma: - return lx.errorf("unexpected comma") - case r == inlineTableEnd: - return lexInlineTableEnd - } - lx.backup() - lx.push(lexInlineTableValueEnd) - return lexKeyStart -} - -// lexInlineTableValueEnd consumes everything between the end of an inline table -// key/value pair and the next pair (or the end of the table): -// it ignores whitespace and expects either a ',' or a '}'. -func lexInlineTableValueEnd(lx *lexer) stateFn { - r := lx.next() - switch { - case isWhitespace(r): - return lexSkip(lx, lexInlineTableValueEnd) - case isNL(r): - return lx.errorf("newlines not allowed within inline tables") - case r == commentStart: - lx.push(lexInlineTableValueEnd) - return lexCommentStart - case r == comma: - lx.ignore() - return lexInlineTableValue - case r == inlineTableEnd: - return lexInlineTableEnd - } - return lx.errorf("expected a comma or an inline table terminator %q, "+ - "but got %q instead", inlineTableEnd, r) -} - -// lexInlineTableEnd finishes the lexing of an inline table. -// It assumes that a '}' has just been consumed. -func lexInlineTableEnd(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemInlineTableEnd) - return lx.pop() -} - -// lexString consumes the inner contents of a string. It assumes that the -// beginning '"' has already been consumed and ignored. -func lexString(lx *lexer) stateFn { - r := lx.next() - switch { - case r == eof: - return lx.errorf("unexpected EOF") - case isNL(r): - return lx.errorf("strings cannot contain newlines") - case r == '\\': - lx.push(lexString) - return lexStringEscape - case r == stringEnd: - lx.backup() - lx.emit(itemString) - lx.next() - lx.ignore() - return lx.pop() - } - return lexString -} - -// lexMultilineString consumes the inner contents of a string. It assumes that -// the beginning '"""' has already been consumed and ignored. -func lexMultilineString(lx *lexer) stateFn { - switch lx.next() { - case eof: - return lx.errorf("unexpected EOF") - case '\\': - return lexMultilineStringEscape - case stringEnd: - if lx.accept(stringEnd) { - if lx.accept(stringEnd) { - lx.backup() - lx.backup() - lx.backup() - lx.emit(itemMultilineString) - lx.next() - lx.next() - lx.next() - lx.ignore() - return lx.pop() - } - lx.backup() - } - } - return lexMultilineString -} - -// lexRawString consumes a raw string. Nothing can be escaped in such a string. -// It assumes that the beginning "'" has already been consumed and ignored. -func lexRawString(lx *lexer) stateFn { - r := lx.next() - switch { - case r == eof: - return lx.errorf("unexpected EOF") - case isNL(r): - return lx.errorf("strings cannot contain newlines") - case r == rawStringEnd: - lx.backup() - lx.emit(itemRawString) - lx.next() - lx.ignore() - return lx.pop() - } - return lexRawString -} - -// lexMultilineRawString consumes a raw string. Nothing can be escaped in such -// a string. It assumes that the beginning "'''" has already been consumed and -// ignored. -func lexMultilineRawString(lx *lexer) stateFn { - switch lx.next() { - case eof: - return lx.errorf("unexpected EOF") - case rawStringEnd: - if lx.accept(rawStringEnd) { - if lx.accept(rawStringEnd) { - lx.backup() - lx.backup() - lx.backup() - lx.emit(itemRawMultilineString) - lx.next() - lx.next() - lx.next() - lx.ignore() - return lx.pop() - } - lx.backup() - } - } - return lexMultilineRawString -} - -// lexMultilineStringEscape consumes an escaped character. It assumes that the -// preceding '\\' has already been consumed. -func lexMultilineStringEscape(lx *lexer) stateFn { - // Handle the special case first: - if isNL(lx.next()) { - return lexMultilineString - } - lx.backup() - lx.push(lexMultilineString) - return lexStringEscape(lx) -} - -func lexStringEscape(lx *lexer) stateFn { - r := lx.next() - switch r { - case 'b': - fallthrough - case 't': - fallthrough - case 'n': - fallthrough - case 'f': - fallthrough - case 'r': - fallthrough - case '"': - fallthrough - case '\\': - return lx.pop() - case 'u': - return lexShortUnicodeEscape - case 'U': - return lexLongUnicodeEscape - } - return lx.errorf("invalid escape character %q; only the following "+ - "escape characters are allowed: "+ - `\b, \t, \n, \f, \r, \", \\, \uXXXX, and \UXXXXXXXX`, r) -} - -func lexShortUnicodeEscape(lx *lexer) stateFn { - var r rune - for i := 0; i < 4; i++ { - r = lx.next() - if !isHexadecimal(r) { - return lx.errorf(`expected four hexadecimal digits after '\u', `+ - "but got %q instead", lx.current()) - } - } - return lx.pop() -} - -func lexLongUnicodeEscape(lx *lexer) stateFn { - var r rune - for i := 0; i < 8; i++ { - r = lx.next() - if !isHexadecimal(r) { - return lx.errorf(`expected eight hexadecimal digits after '\U', `+ - "but got %q instead", lx.current()) - } - } - return lx.pop() -} - -// lexNumberOrDateStart consumes either an integer, a float, or datetime. -func lexNumberOrDateStart(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexNumberOrDate - } - switch r { - case '_': - return lexNumber - case 'e', 'E': - return lexFloat - case '.': - return lx.errorf("floats must start with a digit, not '.'") - } - return lx.errorf("expected a digit but got %q", r) -} - -// lexNumberOrDate consumes either an integer, float or datetime. -func lexNumberOrDate(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexNumberOrDate - } - switch r { - case '-': - return lexDatetime - case '_': - return lexNumber - case '.', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexDatetime consumes a Datetime, to a first approximation. -// The parser validates that it matches one of the accepted formats. -func lexDatetime(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexDatetime - } - switch r { - case '-', 'T', ':', '.', 'Z', '+': - return lexDatetime - } - - lx.backup() - lx.emit(itemDatetime) - return lx.pop() -} - -// lexNumberStart consumes either an integer or a float. It assumes that a sign -// has already been read, but that *no* digits have been consumed. -// lexNumberStart will move to the appropriate integer or float states. -func lexNumberStart(lx *lexer) stateFn { - // We MUST see a digit. Even floats have to start with a digit. - r := lx.next() - if !isDigit(r) { - if r == '.' { - return lx.errorf("floats must start with a digit, not '.'") - } - return lx.errorf("expected a digit but got %q", r) - } - return lexNumber -} - -// lexNumber consumes an integer or a float after seeing the first digit. -func lexNumber(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexNumber - } - switch r { - case '_': - return lexNumber - case '.', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemInteger) - return lx.pop() -} - -// lexFloat consumes the elements of a float. It allows any sequence of -// float-like characters, so floats emitted by the lexer are only a first -// approximation and must be validated by the parser. -func lexFloat(lx *lexer) stateFn { - r := lx.next() - if isDigit(r) { - return lexFloat - } - switch r { - case '_', '.', '-', '+', 'e', 'E': - return lexFloat - } - - lx.backup() - lx.emit(itemFloat) - return lx.pop() -} - -// lexBool consumes a bool string: 'true' or 'false. -func lexBool(lx *lexer) stateFn { - var rs []rune - for { - r := lx.next() - if !unicode.IsLetter(r) { - lx.backup() - break - } - rs = append(rs, r) - } - s := string(rs) - switch s { - case "true", "false": - lx.emit(itemBool) - return lx.pop() - } - return lx.errorf("expected value but found %q instead", s) -} - -// lexCommentStart begins the lexing of a comment. It will emit -// itemCommentStart and consume no characters, passing control to lexComment. -func lexCommentStart(lx *lexer) stateFn { - lx.ignore() - lx.emit(itemCommentStart) - return lexComment -} - -// lexComment lexes an entire comment. It assumes that '#' has been consumed. -// It will consume *up to* the first newline character, and pass control -// back to the last state on the stack. -func lexComment(lx *lexer) stateFn { - r := lx.peek() - if isNL(r) || r == eof { - lx.emit(itemText) - return lx.pop() - } - lx.next() - return lexComment -} - -// lexSkip ignores all slurped input and moves on to the next state. -func lexSkip(lx *lexer, nextState stateFn) stateFn { - return func(lx *lexer) stateFn { - lx.ignore() - return nextState - } -} - -// isWhitespace returns true if `r` is a whitespace character according -// to the spec. -func isWhitespace(r rune) bool { - return r == '\t' || r == ' ' -} - -func isNL(r rune) bool { - return r == '\n' || r == '\r' -} - -func isDigit(r rune) bool { - return r >= '0' && r <= '9' -} - -func isHexadecimal(r rune) bool { - return (r >= '0' && r <= '9') || - (r >= 'a' && r <= 'f') || - (r >= 'A' && r <= 'F') -} - -func isBareKeyChar(r rune) bool { - return (r >= 'A' && r <= 'Z') || - (r >= 'a' && r <= 'z') || - (r >= '0' && r <= '9') || - r == '_' || - r == '-' -} - -func (itype itemType) String() string { - switch itype { - case itemError: - return "Error" - case itemNIL: - return "NIL" - case itemEOF: - return "EOF" - case itemText: - return "Text" - case itemString, itemRawString, itemMultilineString, itemRawMultilineString: - return "String" - case itemBool: - return "Bool" - case itemInteger: - return "Integer" - case itemFloat: - return "Float" - case itemDatetime: - return "DateTime" - case itemTableStart: - return "TableStart" - case itemTableEnd: - return "TableEnd" - case itemKeyStart: - return "KeyStart" - case itemArray: - return "Array" - case itemArrayEnd: - return "ArrayEnd" - case itemCommentStart: - return "CommentStart" - } - panic(fmt.Sprintf("BUG: Unknown type '%d'.", int(itype))) -} - -func (item item) String() string { - return fmt.Sprintf("(%s, %s)", item.typ.String(), item.val) -} diff --git a/vendor/github.com/BurntSushi/toml/parse.go b/vendor/github.com/BurntSushi/toml/parse.go deleted file mode 100644 index 50869ef92..000000000 --- a/vendor/github.com/BurntSushi/toml/parse.go +++ /dev/null @@ -1,592 +0,0 @@ -package toml - -import ( - "fmt" - "strconv" - "strings" - "time" - "unicode" - "unicode/utf8" -) - -type parser struct { - mapping map[string]interface{} - types map[string]tomlType - lx *lexer - - // A list of keys in the order that they appear in the TOML data. - ordered []Key - - // the full key for the current hash in scope - context Key - - // the base key name for everything except hashes - currentKey string - - // rough approximation of line number - approxLine int - - // A map of 'key.group.names' to whether they were created implicitly. - implicits map[string]bool -} - -type parseError string - -func (pe parseError) Error() string { - return string(pe) -} - -func parse(data string) (p *parser, err error) { - defer func() { - if r := recover(); r != nil { - var ok bool - if err, ok = r.(parseError); ok { - return - } - panic(r) - } - }() - - p = &parser{ - mapping: make(map[string]interface{}), - types: make(map[string]tomlType), - lx: lex(data), - ordered: make([]Key, 0), - implicits: make(map[string]bool), - } - for { - item := p.next() - if item.typ == itemEOF { - break - } - p.topLevel(item) - } - - return p, nil -} - -func (p *parser) panicf(format string, v ...interface{}) { - msg := fmt.Sprintf("Near line %d (last key parsed '%s'): %s", - p.approxLine, p.current(), fmt.Sprintf(format, v...)) - panic(parseError(msg)) -} - -func (p *parser) next() item { - it := p.lx.nextItem() - if it.typ == itemError { - p.panicf("%s", it.val) - } - return it -} - -func (p *parser) bug(format string, v ...interface{}) { - panic(fmt.Sprintf("BUG: "+format+"\n\n", v...)) -} - -func (p *parser) expect(typ itemType) item { - it := p.next() - p.assertEqual(typ, it.typ) - return it -} - -func (p *parser) assertEqual(expected, got itemType) { - if expected != got { - p.bug("Expected '%s' but got '%s'.", expected, got) - } -} - -func (p *parser) topLevel(item item) { - switch item.typ { - case itemCommentStart: - p.approxLine = item.line - p.expect(itemText) - case itemTableStart: - kg := p.next() - p.approxLine = kg.line - - var key Key - for ; kg.typ != itemTableEnd && kg.typ != itemEOF; kg = p.next() { - key = append(key, p.keyString(kg)) - } - p.assertEqual(itemTableEnd, kg.typ) - - p.establishContext(key, false) - p.setType("", tomlHash) - p.ordered = append(p.ordered, key) - case itemArrayTableStart: - kg := p.next() - p.approxLine = kg.line - - var key Key - for ; kg.typ != itemArrayTableEnd && kg.typ != itemEOF; kg = p.next() { - key = append(key, p.keyString(kg)) - } - p.assertEqual(itemArrayTableEnd, kg.typ) - - p.establishContext(key, true) - p.setType("", tomlArrayHash) - p.ordered = append(p.ordered, key) - case itemKeyStart: - kname := p.next() - p.approxLine = kname.line - p.currentKey = p.keyString(kname) - - val, typ := p.value(p.next()) - p.setValue(p.currentKey, val) - p.setType(p.currentKey, typ) - p.ordered = append(p.ordered, p.context.add(p.currentKey)) - p.currentKey = "" - default: - p.bug("Unexpected type at top level: %s", item.typ) - } -} - -// Gets a string for a key (or part of a key in a table name). -func (p *parser) keyString(it item) string { - switch it.typ { - case itemText: - return it.val - case itemString, itemMultilineString, - itemRawString, itemRawMultilineString: - s, _ := p.value(it) - return s.(string) - default: - p.bug("Unexpected key type: %s", it.typ) - panic("unreachable") - } -} - -// value translates an expected value from the lexer into a Go value wrapped -// as an empty interface. -func (p *parser) value(it item) (interface{}, tomlType) { - switch it.typ { - case itemString: - return p.replaceEscapes(it.val), p.typeOfPrimitive(it) - case itemMultilineString: - trimmed := stripFirstNewline(stripEscapedWhitespace(it.val)) - return p.replaceEscapes(trimmed), p.typeOfPrimitive(it) - case itemRawString: - return it.val, p.typeOfPrimitive(it) - case itemRawMultilineString: - return stripFirstNewline(it.val), p.typeOfPrimitive(it) - case itemBool: - switch it.val { - case "true": - return true, p.typeOfPrimitive(it) - case "false": - return false, p.typeOfPrimitive(it) - } - p.bug("Expected boolean value, but got '%s'.", it.val) - case itemInteger: - if !numUnderscoresOK(it.val) { - p.panicf("Invalid integer %q: underscores must be surrounded by digits", - it.val) - } - val := strings.Replace(it.val, "_", "", -1) - num, err := strconv.ParseInt(val, 10, 64) - if err != nil { - // Distinguish integer values. Normally, it'd be a bug if the lexer - // provides an invalid integer, but it's possible that the number is - // out of range of valid values (which the lexer cannot determine). - // So mark the former as a bug but the latter as a legitimate user - // error. - if e, ok := err.(*strconv.NumError); ok && - e.Err == strconv.ErrRange { - - p.panicf("Integer '%s' is out of the range of 64-bit "+ - "signed integers.", it.val) - } else { - p.bug("Expected integer value, but got '%s'.", it.val) - } - } - return num, p.typeOfPrimitive(it) - case itemFloat: - parts := strings.FieldsFunc(it.val, func(r rune) bool { - switch r { - case '.', 'e', 'E': - return true - } - return false - }) - for _, part := range parts { - if !numUnderscoresOK(part) { - p.panicf("Invalid float %q: underscores must be "+ - "surrounded by digits", it.val) - } - } - if !numPeriodsOK(it.val) { - // As a special case, numbers like '123.' or '1.e2', - // which are valid as far as Go/strconv are concerned, - // must be rejected because TOML says that a fractional - // part consists of '.' followed by 1+ digits. - p.panicf("Invalid float %q: '.' must be followed "+ - "by one or more digits", it.val) - } - val := strings.Replace(it.val, "_", "", -1) - num, err := strconv.ParseFloat(val, 64) - if err != nil { - if e, ok := err.(*strconv.NumError); ok && - e.Err == strconv.ErrRange { - - p.panicf("Float '%s' is out of the range of 64-bit "+ - "IEEE-754 floating-point numbers.", it.val) - } else { - p.panicf("Invalid float value: %q", it.val) - } - } - return num, p.typeOfPrimitive(it) - case itemDatetime: - var t time.Time - var ok bool - var err error - for _, format := range []string{ - "2006-01-02T15:04:05Z07:00", - "2006-01-02T15:04:05", - "2006-01-02", - } { - t, err = time.ParseInLocation(format, it.val, time.Local) - if err == nil { - ok = true - break - } - } - if !ok { - p.panicf("Invalid TOML Datetime: %q.", it.val) - } - return t, p.typeOfPrimitive(it) - case itemArray: - array := make([]interface{}, 0) - types := make([]tomlType, 0) - - for it = p.next(); it.typ != itemArrayEnd; it = p.next() { - if it.typ == itemCommentStart { - p.expect(itemText) - continue - } - - val, typ := p.value(it) - array = append(array, val) - types = append(types, typ) - } - return array, p.typeOfArray(types) - case itemInlineTableStart: - var ( - hash = make(map[string]interface{}) - outerContext = p.context - outerKey = p.currentKey - ) - - p.context = append(p.context, p.currentKey) - p.currentKey = "" - for it := p.next(); it.typ != itemInlineTableEnd; it = p.next() { - if it.typ != itemKeyStart { - p.bug("Expected key start but instead found %q, around line %d", - it.val, p.approxLine) - } - if it.typ == itemCommentStart { - p.expect(itemText) - continue - } - - // retrieve key - k := p.next() - p.approxLine = k.line - kname := p.keyString(k) - - // retrieve value - p.currentKey = kname - val, typ := p.value(p.next()) - // make sure we keep metadata up to date - p.setType(kname, typ) - p.ordered = append(p.ordered, p.context.add(p.currentKey)) - hash[kname] = val - } - p.context = outerContext - p.currentKey = outerKey - return hash, tomlHash - } - p.bug("Unexpected value type: %s", it.typ) - panic("unreachable") -} - -// numUnderscoresOK checks whether each underscore in s is surrounded by -// characters that are not underscores. -func numUnderscoresOK(s string) bool { - accept := false - for _, r := range s { - if r == '_' { - if !accept { - return false - } - accept = false - continue - } - accept = true - } - return accept -} - -// numPeriodsOK checks whether every period in s is followed by a digit. -func numPeriodsOK(s string) bool { - period := false - for _, r := range s { - if period && !isDigit(r) { - return false - } - period = r == '.' - } - return !period -} - -// establishContext sets the current context of the parser, -// where the context is either a hash or an array of hashes. Which one is -// set depends on the value of the `array` parameter. -// -// Establishing the context also makes sure that the key isn't a duplicate, and -// will create implicit hashes automatically. -func (p *parser) establishContext(key Key, array bool) { - var ok bool - - // Always start at the top level and drill down for our context. - hashContext := p.mapping - keyContext := make(Key, 0) - - // We only need implicit hashes for key[0:-1] - for _, k := range key[0 : len(key)-1] { - _, ok = hashContext[k] - keyContext = append(keyContext, k) - - // No key? Make an implicit hash and move on. - if !ok { - p.addImplicit(keyContext) - hashContext[k] = make(map[string]interface{}) - } - - // If the hash context is actually an array of tables, then set - // the hash context to the last element in that array. - // - // Otherwise, it better be a table, since this MUST be a key group (by - // virtue of it not being the last element in a key). - switch t := hashContext[k].(type) { - case []map[string]interface{}: - hashContext = t[len(t)-1] - case map[string]interface{}: - hashContext = t - default: - p.panicf("Key '%s' was already created as a hash.", keyContext) - } - } - - p.context = keyContext - if array { - // If this is the first element for this array, then allocate a new - // list of tables for it. - k := key[len(key)-1] - if _, ok := hashContext[k]; !ok { - hashContext[k] = make([]map[string]interface{}, 0, 5) - } - - // Add a new table. But make sure the key hasn't already been used - // for something else. - if hash, ok := hashContext[k].([]map[string]interface{}); ok { - hashContext[k] = append(hash, make(map[string]interface{})) - } else { - p.panicf("Key '%s' was already created and cannot be used as "+ - "an array.", keyContext) - } - } else { - p.setValue(key[len(key)-1], make(map[string]interface{})) - } - p.context = append(p.context, key[len(key)-1]) -} - -// setValue sets the given key to the given value in the current context. -// It will make sure that the key hasn't already been defined, account for -// implicit key groups. -func (p *parser) setValue(key string, value interface{}) { - var tmpHash interface{} - var ok bool - - hash := p.mapping - keyContext := make(Key, 0) - for _, k := range p.context { - keyContext = append(keyContext, k) - if tmpHash, ok = hash[k]; !ok { - p.bug("Context for key '%s' has not been established.", keyContext) - } - switch t := tmpHash.(type) { - case []map[string]interface{}: - // The context is a table of hashes. Pick the most recent table - // defined as the current hash. - hash = t[len(t)-1] - case map[string]interface{}: - hash = t - default: - p.bug("Expected hash to have type 'map[string]interface{}', but "+ - "it has '%T' instead.", tmpHash) - } - } - keyContext = append(keyContext, key) - - if _, ok := hash[key]; ok { - // Typically, if the given key has already been set, then we have - // to raise an error since duplicate keys are disallowed. However, - // it's possible that a key was previously defined implicitly. In this - // case, it is allowed to be redefined concretely. (See the - // `tests/valid/implicit-and-explicit-after.toml` test in `toml-test`.) - // - // But we have to make sure to stop marking it as an implicit. (So that - // another redefinition provokes an error.) - // - // Note that since it has already been defined (as a hash), we don't - // want to overwrite it. So our business is done. - if p.isImplicit(keyContext) { - p.removeImplicit(keyContext) - return - } - - // Otherwise, we have a concrete key trying to override a previous - // key, which is *always* wrong. - p.panicf("Key '%s' has already been defined.", keyContext) - } - hash[key] = value -} - -// setType sets the type of a particular value at a given key. -// It should be called immediately AFTER setValue. -// -// Note that if `key` is empty, then the type given will be applied to the -// current context (which is either a table or an array of tables). -func (p *parser) setType(key string, typ tomlType) { - keyContext := make(Key, 0, len(p.context)+1) - for _, k := range p.context { - keyContext = append(keyContext, k) - } - if len(key) > 0 { // allow type setting for hashes - keyContext = append(keyContext, key) - } - p.types[keyContext.String()] = typ -} - -// addImplicit sets the given Key as having been created implicitly. -func (p *parser) addImplicit(key Key) { - p.implicits[key.String()] = true -} - -// removeImplicit stops tagging the given key as having been implicitly -// created. -func (p *parser) removeImplicit(key Key) { - p.implicits[key.String()] = false -} - -// isImplicit returns true if the key group pointed to by the key was created -// implicitly. -func (p *parser) isImplicit(key Key) bool { - return p.implicits[key.String()] -} - -// current returns the full key name of the current context. -func (p *parser) current() string { - if len(p.currentKey) == 0 { - return p.context.String() - } - if len(p.context) == 0 { - return p.currentKey - } - return fmt.Sprintf("%s.%s", p.context, p.currentKey) -} - -func stripFirstNewline(s string) string { - if len(s) == 0 || s[0] != '\n' { - return s - } - return s[1:] -} - -func stripEscapedWhitespace(s string) string { - esc := strings.Split(s, "\\\n") - if len(esc) > 1 { - for i := 1; i < len(esc); i++ { - esc[i] = strings.TrimLeftFunc(esc[i], unicode.IsSpace) - } - } - return strings.Join(esc, "") -} - -func (p *parser) replaceEscapes(str string) string { - var replaced []rune - s := []byte(str) - r := 0 - for r < len(s) { - if s[r] != '\\' { - c, size := utf8.DecodeRune(s[r:]) - r += size - replaced = append(replaced, c) - continue - } - r += 1 - if r >= len(s) { - p.bug("Escape sequence at end of string.") - return "" - } - switch s[r] { - default: - p.bug("Expected valid escape code after \\, but got %q.", s[r]) - return "" - case 'b': - replaced = append(replaced, rune(0x0008)) - r += 1 - case 't': - replaced = append(replaced, rune(0x0009)) - r += 1 - case 'n': - replaced = append(replaced, rune(0x000A)) - r += 1 - case 'f': - replaced = append(replaced, rune(0x000C)) - r += 1 - case 'r': - replaced = append(replaced, rune(0x000D)) - r += 1 - case '"': - replaced = append(replaced, rune(0x0022)) - r += 1 - case '\\': - replaced = append(replaced, rune(0x005C)) - r += 1 - case 'u': - // At this point, we know we have a Unicode escape of the form - // `uXXXX` at [r, r+5). (Because the lexer guarantees this - // for us.) - escaped := p.asciiEscapeToUnicode(s[r+1 : r+5]) - replaced = append(replaced, escaped) - r += 5 - case 'U': - // At this point, we know we have a Unicode escape of the form - // `uXXXX` at [r, r+9). (Because the lexer guarantees this - // for us.) - escaped := p.asciiEscapeToUnicode(s[r+1 : r+9]) - replaced = append(replaced, escaped) - r += 9 - } - } - return string(replaced) -} - -func (p *parser) asciiEscapeToUnicode(bs []byte) rune { - s := string(bs) - hex, err := strconv.ParseUint(strings.ToLower(s), 16, 32) - if err != nil { - p.bug("Could not parse '%s' as a hexadecimal number, but the "+ - "lexer claims it's OK: %s", s, err) - } - if !utf8.ValidRune(rune(hex)) { - p.panicf("Escaped character '\\u%s' is not valid UTF-8.", s) - } - return rune(hex) -} - -func isStringType(ty itemType) bool { - return ty == itemString || ty == itemMultilineString || - ty == itemRawString || ty == itemRawMultilineString -} diff --git a/vendor/github.com/BurntSushi/toml/session.vim b/vendor/github.com/BurntSushi/toml/session.vim deleted file mode 100644 index 562164be0..000000000 --- a/vendor/github.com/BurntSushi/toml/session.vim +++ /dev/null @@ -1 +0,0 @@ -au BufWritePost *.go silent!make tags > /dev/null 2>&1 diff --git a/vendor/github.com/BurntSushi/toml/type_check.go b/vendor/github.com/BurntSushi/toml/type_check.go deleted file mode 100644 index c73f8afc1..000000000 --- a/vendor/github.com/BurntSushi/toml/type_check.go +++ /dev/null @@ -1,91 +0,0 @@ -package toml - -// tomlType represents any Go type that corresponds to a TOML type. -// While the first draft of the TOML spec has a simplistic type system that -// probably doesn't need this level of sophistication, we seem to be militating -// toward adding real composite types. -type tomlType interface { - typeString() string -} - -// typeEqual accepts any two types and returns true if they are equal. -func typeEqual(t1, t2 tomlType) bool { - if t1 == nil || t2 == nil { - return false - } - return t1.typeString() == t2.typeString() -} - -func typeIsHash(t tomlType) bool { - return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash) -} - -type tomlBaseType string - -func (btype tomlBaseType) typeString() string { - return string(btype) -} - -func (btype tomlBaseType) String() string { - return btype.typeString() -} - -var ( - tomlInteger tomlBaseType = "Integer" - tomlFloat tomlBaseType = "Float" - tomlDatetime tomlBaseType = "Datetime" - tomlString tomlBaseType = "String" - tomlBool tomlBaseType = "Bool" - tomlArray tomlBaseType = "Array" - tomlHash tomlBaseType = "Hash" - tomlArrayHash tomlBaseType = "ArrayHash" -) - -// typeOfPrimitive returns a tomlType of any primitive value in TOML. -// Primitive values are: Integer, Float, Datetime, String and Bool. -// -// Passing a lexer item other than the following will cause a BUG message -// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime. -func (p *parser) typeOfPrimitive(lexItem item) tomlType { - switch lexItem.typ { - case itemInteger: - return tomlInteger - case itemFloat: - return tomlFloat - case itemDatetime: - return tomlDatetime - case itemString: - return tomlString - case itemMultilineString: - return tomlString - case itemRawString: - return tomlString - case itemRawMultilineString: - return tomlString - case itemBool: - return tomlBool - } - p.bug("Cannot infer primitive type of lex item '%s'.", lexItem) - panic("unreachable") -} - -// typeOfArray returns a tomlType for an array given a list of types of its -// values. -// -// In the current spec, if an array is homogeneous, then its type is always -// "Array". If the array is not homogeneous, an error is generated. -func (p *parser) typeOfArray(types []tomlType) tomlType { - // Empty arrays are cool. - if len(types) == 0 { - return tomlArray - } - - theType := types[0] - for _, t := range types[1:] { - if !typeEqual(theType, t) { - p.panicf("Array contains values of type '%s' and '%s', but "+ - "arrays must be homogeneous.", theType, t) - } - } - return tomlArray -} diff --git a/vendor/github.com/BurntSushi/toml/type_fields.go b/vendor/github.com/BurntSushi/toml/type_fields.go deleted file mode 100644 index 608997c22..000000000 --- a/vendor/github.com/BurntSushi/toml/type_fields.go +++ /dev/null @@ -1,242 +0,0 @@ -package toml - -// Struct field handling is adapted from code in encoding/json: -// -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the Go distribution. - -import ( - "reflect" - "sort" - "sync" -) - -// A field represents a single field found in a struct. -type field struct { - name string // the name of the field (`toml` tag included) - tag bool // whether field has a `toml` tag - index []int // represents the depth of an anonymous field - typ reflect.Type // the type of the field -} - -// byName sorts field by name, breaking ties with depth, -// then breaking ties with "name came from toml tag", then -// breaking ties with index sequence. -type byName []field - -func (x byName) Len() int { return len(x) } - -func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byName) Less(i, j int) bool { - if x[i].name != x[j].name { - return x[i].name < x[j].name - } - if len(x[i].index) != len(x[j].index) { - return len(x[i].index) < len(x[j].index) - } - if x[i].tag != x[j].tag { - return x[i].tag - } - return byIndex(x).Less(i, j) -} - -// byIndex sorts field by index sequence. -type byIndex []field - -func (x byIndex) Len() int { return len(x) } - -func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] } - -func (x byIndex) Less(i, j int) bool { - for k, xik := range x[i].index { - if k >= len(x[j].index) { - return false - } - if xik != x[j].index[k] { - return xik < x[j].index[k] - } - } - return len(x[i].index) < len(x[j].index) -} - -// typeFields returns a list of fields that TOML should recognize for the given -// type. The algorithm is breadth-first search over the set of structs to -// include - the top struct and then any reachable anonymous structs. -func typeFields(t reflect.Type) []field { - // Anonymous fields to explore at the current level and the next. - current := []field{} - next := []field{{typ: t}} - - // Count of queued names for current level and the next. - count := map[reflect.Type]int{} - nextCount := map[reflect.Type]int{} - - // Types already visited at an earlier level. - visited := map[reflect.Type]bool{} - - // Fields found. - var fields []field - - for len(next) > 0 { - current, next = next, current[:0] - count, nextCount = nextCount, map[reflect.Type]int{} - - for _, f := range current { - if visited[f.typ] { - continue - } - visited[f.typ] = true - - // Scan f.typ for fields to include. - for i := 0; i < f.typ.NumField(); i++ { - sf := f.typ.Field(i) - if sf.PkgPath != "" && !sf.Anonymous { // unexported - continue - } - opts := getOptions(sf.Tag) - if opts.skip { - continue - } - index := make([]int, len(f.index)+1) - copy(index, f.index) - index[len(f.index)] = i - - ft := sf.Type - if ft.Name() == "" && ft.Kind() == reflect.Ptr { - // Follow pointer. - ft = ft.Elem() - } - - // Record found field and index sequence. - if opts.name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct { - tagged := opts.name != "" - name := opts.name - if name == "" { - name = sf.Name - } - fields = append(fields, field{name, tagged, index, ft}) - if count[f.typ] > 1 { - // If there were multiple instances, add a second, - // so that the annihilation code will see a duplicate. - // It only cares about the distinction between 1 or 2, - // so don't bother generating any more copies. - fields = append(fields, fields[len(fields)-1]) - } - continue - } - - // Record new anonymous struct to explore in next round. - nextCount[ft]++ - if nextCount[ft] == 1 { - f := field{name: ft.Name(), index: index, typ: ft} - next = append(next, f) - } - } - } - } - - sort.Sort(byName(fields)) - - // Delete all fields that are hidden by the Go rules for embedded fields, - // except that fields with TOML tags are promoted. - - // The fields are sorted in primary order of name, secondary order - // of field index length. Loop over names; for each name, delete - // hidden fields by choosing the one dominant field that survives. - out := fields[:0] - for advance, i := 0, 0; i < len(fields); i += advance { - // One iteration per name. - // Find the sequence of fields with the name of this first field. - fi := fields[i] - name := fi.name - for advance = 1; i+advance < len(fields); advance++ { - fj := fields[i+advance] - if fj.name != name { - break - } - } - if advance == 1 { // Only one field with this name - out = append(out, fi) - continue - } - dominant, ok := dominantField(fields[i : i+advance]) - if ok { - out = append(out, dominant) - } - } - - fields = out - sort.Sort(byIndex(fields)) - - return fields -} - -// dominantField looks through the fields, all of which are known to -// have the same name, to find the single field that dominates the -// others using Go's embedding rules, modified by the presence of -// TOML tags. If there are multiple top-level fields, the boolean -// will be false: This condition is an error in Go and we skip all -// the fields. -func dominantField(fields []field) (field, bool) { - // The fields are sorted in increasing index-length order. The winner - // must therefore be one with the shortest index length. Drop all - // longer entries, which is easy: just truncate the slice. - length := len(fields[0].index) - tagged := -1 // Index of first tagged field. - for i, f := range fields { - if len(f.index) > length { - fields = fields[:i] - break - } - if f.tag { - if tagged >= 0 { - // Multiple tagged fields at the same level: conflict. - // Return no field. - return field{}, false - } - tagged = i - } - } - if tagged >= 0 { - return fields[tagged], true - } - // All remaining fields have the same length. If there's more than one, - // we have a conflict (two fields named "X" at the same level) and we - // return no field. - if len(fields) > 1 { - return field{}, false - } - return fields[0], true -} - -var fieldCache struct { - sync.RWMutex - m map[reflect.Type][]field -} - -// cachedTypeFields is like typeFields but uses a cache to avoid repeated work. -func cachedTypeFields(t reflect.Type) []field { - fieldCache.RLock() - f := fieldCache.m[t] - fieldCache.RUnlock() - if f != nil { - return f - } - - // Compute fields without lock. - // Might duplicate effort but won't hold other computations back. - f = typeFields(t) - if f == nil { - f = []field{} - } - - fieldCache.Lock() - if fieldCache.m == nil { - fieldCache.m = map[reflect.Type][]field{} - } - fieldCache.m[t] = f - fieldCache.Unlock() - return f -} diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go index 7351e56f4..7585fc600 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go @@ -3473,12 +3473,36 @@ var awsPartition = partition{ "eu-west-1": endpoint{}, "eu-west-2": endpoint{}, "eu-west-3": endpoint{}, - "me-south-1": endpoint{}, - "sa-east-1": endpoint{}, - "us-east-1": endpoint{}, - "us-east-2": endpoint{}, - "us-west-1": endpoint{}, - "us-west-2": endpoint{}, + "fips-us-east-1": endpoint{ + Hostname: "logs-fips.us-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-1", + }, + }, + "fips-us-east-2": endpoint{ + Hostname: "logs-fips.us-east-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-east-2", + }, + }, + "fips-us-west-1": endpoint{ + Hostname: "logs-fips.us-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-1", + }, + }, + "fips-us-west-2": endpoint{ + Hostname: "logs-fips.us-west-2.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-west-2", + }, + }, + "me-south-1": endpoint{}, + "sa-east-1": endpoint{}, + "us-east-1": endpoint{}, + "us-east-2": endpoint{}, + "us-west-1": endpoint{}, + "us-west-2": endpoint{}, }, }, "machinelearning": service{ @@ -6649,6 +6673,25 @@ var awscnPartition = partition{ }, }, }, + "organizations": service{ + PartitionEndpoint: "aws-cn-global", + IsRegionalized: boxedFalse, + + Endpoints: endpoints{ + "aws-cn-global": endpoint{ + Hostname: "organizations.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + "fips-aws-cn-global": endpoint{ + Hostname: "organizations.cn-northwest-1.amazonaws.com.cn", + CredentialScope: credentialScope{ + Region: "cn-northwest-1", + }, + }, + }, + }, "polly": service{ Endpoints: endpoints{ @@ -7404,7 +7447,7 @@ var awsusgovPartition = partition{ Endpoints: endpoints{ "fips": endpoint{ - Hostname: "elasticache-fips.us-gov-west-1.amazonaws.com", + Hostname: "elasticache.us-gov-west-1.amazonaws.com", CredentialScope: credentialScope{ Region: "us-gov-west-1", }, @@ -7704,6 +7747,13 @@ var awsusgovPartition = partition{ "us-gov-west-1": endpoint{}, }, }, + "kinesisanalytics": service{ + + Endpoints: endpoints{ + "us-gov-east-1": endpoint{}, + "us-gov-west-1": endpoint{}, + }, + }, "kms": service{ Endpoints: endpoints{ @@ -7758,8 +7808,18 @@ var awsusgovPartition = partition{ "logs": service{ Endpoints: endpoints{ - "us-gov-east-1": endpoint{}, - "us-gov-west-1": endpoint{}, + "us-gov-east-1": endpoint{ + Hostname: "logs.us-gov-east-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-east-1", + }, + }, + "us-gov-west-1": endpoint{ + Hostname: "logs.us-gov-west-1.amazonaws.com", + CredentialScope: credentialScope{ + Region: "us-gov-west-1", + }, + }, }, }, "mediaconvert": service{ diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go index b8f4fbea6..f7f45e640 100644 --- a/vendor/github.com/aws/aws-sdk-go/aws/version.go +++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go @@ -5,4 +5,4 @@ package aws const SDKName = "aws-sdk-go" // SDKVersion is the version of this SDK -const SDKVersion = "1.32.5" +const SDKVersion = "1.32.10" diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 7b7c72752..e50e4cb27 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1950,6 +1950,20 @@ func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) { return int(n), nil } +func isGroupMember(gid int) bool { + groups, err := Getgroups() + if err != nil { + return false + } + + for _, g := range groups { + if g == gid { + return true + } + } + return false +} + //sys faccessat(dirfd int, path string, mode uint32) (err error) func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { @@ -2007,7 +2021,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { gid = Getgid() } - if uint32(gid) == st.Gid { + if uint32(gid) == st.Gid || isGroupMember(gid) { fmode = (st.Mode >> 3) & 7 } else { fmode = st.Mode & 7 diff --git a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go index 6f79227d7..b91c2ae0f 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/ztypes_freebsd_arm.go @@ -125,9 +125,9 @@ type Statfs_t struct { Owner uint32 Fsid Fsid Charspare [80]int8 - Fstypename [16]int8 - Mntfromname [1024]int8 - Mntonname [1024]int8 + Fstypename [16]byte + Mntfromname [1024]byte + Mntonname [1024]byte } type statfs_freebsd11_t struct { @@ -150,9 +150,9 @@ type statfs_freebsd11_t struct { Owner uint32 Fsid Fsid Charspare [80]int8 - Fstypename [16]int8 - Mntfromname [88]int8 - Mntonname [88]int8 + Fstypename [16]byte + Mntfromname [88]byte + Mntonname [88]byte } type Flock_t struct { diff --git a/vendor/golang.org/x/tools/cmd/goimports/goimports.go b/vendor/golang.org/x/tools/cmd/goimports/goimports.go index c195caaf8..f177b2d9a 100644 --- a/vendor/golang.org/x/tools/cmd/goimports/goimports.go +++ b/vendor/golang.org/x/tools/cmd/goimports/goimports.go @@ -10,7 +10,6 @@ import ( "errors" "flag" "fmt" - "go/build" "go/scanner" "io" "io/ioutil" @@ -43,15 +42,7 @@ var ( TabIndent: true, Comments: true, Fragment: true, - // This environment, and its caches, will be reused for the whole run. - Env: &imports.ProcessEnv{ - GOPATH: build.Default.GOPATH, - GOROOT: build.Default.GOROOT, - GOFLAGS: os.Getenv("GOFLAGS"), - GO111MODULE: os.Getenv("GO111MODULE"), - GOPROXY: os.Getenv("GOPROXY"), - GOSUMDB: os.Getenv("GOSUMDB"), - }, + Env: &imports.ProcessEnv{}, } exitCode = 0 ) diff --git a/vendor/golang.org/x/tools/go/analysis/analysis.go b/vendor/golang.org/x/tools/go/analysis/analysis.go deleted file mode 100644 index 8c9977355..000000000 --- a/vendor/golang.org/x/tools/go/analysis/analysis.go +++ /dev/null @@ -1,237 +0,0 @@ -package analysis - -import ( - "flag" - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" - - "golang.org/x/tools/internal/analysisinternal" -) - -// An Analyzer describes an analysis function and its options. -type Analyzer struct { - // The Name of the analyzer must be a valid Go identifier - // as it may appear in command-line flags, URLs, and so on. - Name string - - // Doc is the documentation for the analyzer. - // The part before the first "\n\n" is the title - // (no capital or period, max ~60 letters). - Doc string - - // Flags defines any flags accepted by the analyzer. - // The manner in which these flags are exposed to the user - // depends on the driver which runs the analyzer. - Flags flag.FlagSet - - // Run applies the analyzer to a package. - // It returns an error if the analyzer failed. - // - // On success, the Run function may return a result - // computed by the Analyzer; its type must match ResultType. - // The driver makes this result available as an input to - // another Analyzer that depends directly on this one (see - // Requires) when it analyzes the same package. - // - // To pass analysis results between packages (and thus - // potentially between address spaces), use Facts, which are - // serializable. - Run func(*Pass) (interface{}, error) - - // RunDespiteErrors allows the driver to invoke - // the Run method of this analyzer even on a - // package that contains parse or type errors. - RunDespiteErrors bool - - // Requires is a set of analyzers that must run successfully - // before this one on a given package. This analyzer may inspect - // the outputs produced by each analyzer in Requires. - // The graph over analyzers implied by Requires edges must be acyclic. - // - // Requires establishes a "horizontal" dependency between - // analysis passes (different analyzers, same package). - Requires []*Analyzer - - // ResultType is the type of the optional result of the Run function. - ResultType reflect.Type - - // FactTypes indicates that this analyzer imports and exports - // Facts of the specified concrete types. - // An analyzer that uses facts may assume that its import - // dependencies have been similarly analyzed before it runs. - // Facts must be pointers. - // - // FactTypes establishes a "vertical" dependency between - // analysis passes (same analyzer, different packages). - FactTypes []Fact -} - -func (a *Analyzer) String() string { return a.Name } - -func init() { - // Set the analysisinternal functions to be able to pass type errors - // to the Pass type without modifying the go/analysis API. - analysisinternal.SetTypeErrors = func(p interface{}, errors []types.Error) { - p.(*Pass).typeErrors = errors - } - analysisinternal.GetTypeErrors = func(p interface{}) []types.Error { - return p.(*Pass).typeErrors - } -} - -// A Pass provides information to the Run function that -// applies a specific analyzer to a single Go package. -// -// It forms the interface between the analysis logic and the driver -// program, and has both input and an output components. -// -// As in a compiler, one pass may depend on the result computed by another. -// -// The Run function should not call any of the Pass functions concurrently. -type Pass struct { - Analyzer *Analyzer // the identity of the current analyzer - - // syntax and type information - Fset *token.FileSet // file position information - Files []*ast.File // the abstract syntax tree of each file - OtherFiles []string // names of non-Go files of this package - Pkg *types.Package // type information about the package - TypesInfo *types.Info // type information about the syntax trees - TypesSizes types.Sizes // function for computing sizes of types - - // Report reports a Diagnostic, a finding about a specific location - // in the analyzed source code such as a potential mistake. - // It may be called by the Run function. - Report func(Diagnostic) - - // ResultOf provides the inputs to this analysis pass, which are - // the corresponding results of its prerequisite analyzers. - // The map keys are the elements of Analysis.Required, - // and the type of each corresponding value is the required - // analysis's ResultType. - ResultOf map[*Analyzer]interface{} - - // -- facts -- - - // ImportObjectFact retrieves a fact associated with obj. - // Given a value ptr of type *T, where *T satisfies Fact, - // ImportObjectFact copies the value to *ptr. - // - // ImportObjectFact panics if called after the pass is complete. - // ImportObjectFact is not concurrency-safe. - ImportObjectFact func(obj types.Object, fact Fact) bool - - // ImportPackageFact retrieves a fact associated with package pkg, - // which must be this package or one of its dependencies. - // See comments for ImportObjectFact. - ImportPackageFact func(pkg *types.Package, fact Fact) bool - - // ExportObjectFact associates a fact of type *T with the obj, - // replacing any previous fact of that type. - // - // ExportObjectFact panics if it is called after the pass is - // complete, or if obj does not belong to the package being analyzed. - // ExportObjectFact is not concurrency-safe. - ExportObjectFact func(obj types.Object, fact Fact) - - // ExportPackageFact associates a fact with the current package. - // See comments for ExportObjectFact. - ExportPackageFact func(fact Fact) - - // AllPackageFacts returns a new slice containing all package facts of the analysis's FactTypes - // in unspecified order. - // WARNING: This is an experimental API and may change in the future. - AllPackageFacts func() []PackageFact - - // AllObjectFacts returns a new slice containing all object facts of the analysis's FactTypes - // in unspecified order. - // WARNING: This is an experimental API and may change in the future. - AllObjectFacts func() []ObjectFact - - // typeErrors contains types.Errors that are associated with the pkg. - typeErrors []types.Error - - /* Further fields may be added in future. */ - // For example, suggested or applied refactorings. -} - -// PackageFact is a package together with an associated fact. -// WARNING: This is an experimental API and may change in the future. -type PackageFact struct { - Package *types.Package - Fact Fact -} - -// ObjectFact is an object together with an associated fact. -// WARNING: This is an experimental API and may change in the future. -type ObjectFact struct { - Object types.Object - Fact Fact -} - -// Reportf is a helper function that reports a Diagnostic using the -// specified position and formatted error message. -func (pass *Pass) Reportf(pos token.Pos, format string, args ...interface{}) { - msg := fmt.Sprintf(format, args...) - pass.Report(Diagnostic{Pos: pos, Message: msg}) -} - -// The Range interface provides a range. It's equivalent to and satisfied by -// ast.Node. -type Range interface { - Pos() token.Pos // position of first character belonging to the node - End() token.Pos // position of first character immediately after the node -} - -// ReportRangef is a helper function that reports a Diagnostic using the -// range provided. ast.Node values can be passed in as the range because -// they satisfy the Range interface. -func (pass *Pass) ReportRangef(rng Range, format string, args ...interface{}) { - msg := fmt.Sprintf(format, args...) - pass.Report(Diagnostic{Pos: rng.Pos(), End: rng.End(), Message: msg}) -} - -func (pass *Pass) String() string { - return fmt.Sprintf("%s@%s", pass.Analyzer.Name, pass.Pkg.Path()) -} - -// A Fact is an intermediate fact produced during analysis. -// -// Each fact is associated with a named declaration (a types.Object) or -// with a package as a whole. A single object or package may have -// multiple associated facts, but only one of any particular fact type. -// -// A Fact represents a predicate such as "never returns", but does not -// represent the subject of the predicate such as "function F" or "package P". -// -// Facts may be produced in one analysis pass and consumed by another -// analysis pass even if these are in different address spaces. -// If package P imports Q, all facts about Q produced during -// analysis of that package will be available during later analysis of P. -// Facts are analogous to type export data in a build system: -// just as export data enables separate compilation of several passes, -// facts enable "separate analysis". -// -// Each pass (a, p) starts with the set of facts produced by the -// same analyzer a applied to the packages directly imported by p. -// The analysis may add facts to the set, and they may be exported in turn. -// An analysis's Run function may retrieve facts by calling -// Pass.Import{Object,Package}Fact and update them using -// Pass.Export{Object,Package}Fact. -// -// A fact is logically private to its Analysis. To pass values -// between different analyzers, use the results mechanism; -// see Analyzer.Requires, Analyzer.ResultType, and Pass.ResultOf. -// -// A Fact type must be a pointer. -// Facts are encoded and decoded using encoding/gob. -// A Fact may implement the GobEncoder/GobDecoder interfaces -// to customize its encoding. Fact encoding should not fail. -// -// A Fact should not be modified once exported. -type Fact interface { - AFact() // dummy method to avoid type errors -} diff --git a/vendor/golang.org/x/tools/go/analysis/diagnostic.go b/vendor/golang.org/x/tools/go/analysis/diagnostic.go deleted file mode 100644 index 57eaf6faa..000000000 --- a/vendor/golang.org/x/tools/go/analysis/diagnostic.go +++ /dev/null @@ -1,61 +0,0 @@ -package analysis - -import "go/token" - -// A Diagnostic is a message associated with a source location or range. -// -// An Analyzer may return a variety of diagnostics; the optional Category, -// which should be a constant, may be used to classify them. -// It is primarily intended to make it easy to look up documentation. -// -// If End is provided, the diagnostic is specified to apply to the range between -// Pos and End. -type Diagnostic struct { - Pos token.Pos - End token.Pos // optional - Category string // optional - Message string - - // SuggestedFixes contains suggested fixes for a diagnostic which can be used to perform - // edits to a file that address the diagnostic. - // TODO(matloob): Should multiple SuggestedFixes be allowed for a diagnostic? - // Diagnostics should not contain SuggestedFixes that overlap. - // Experimental: This API is experimental and may change in the future. - SuggestedFixes []SuggestedFix // optional - - // Experimental: This API is experimental and may change in the future. - Related []RelatedInformation // optional -} - -// RelatedInformation contains information related to a diagnostic. -// For example, a diagnostic that flags duplicated declarations of a -// variable may include one RelatedInformation per existing -// declaration. -type RelatedInformation struct { - Pos token.Pos - End token.Pos - Message string -} - -// A SuggestedFix is a code change associated with a Diagnostic that a user can choose -// to apply to their code. Usually the SuggestedFix is meant to fix the issue flagged -// by the diagnostic. -// TextEdits for a SuggestedFix should not overlap. TextEdits for a SuggestedFix -// should not contain edits for other packages. -// Experimental: This API is experimental and may change in the future. -type SuggestedFix struct { - // A description for this suggested fix to be shown to a user deciding - // whether to accept it. - Message string - TextEdits []TextEdit -} - -// A TextEdit represents the replacement of the code between Pos and End with the new text. -// Each TextEdit should apply to a single file. End should not be earlier in the file than Pos. -// Experimental: This API is experimental and may change in the future. -type TextEdit struct { - // For a pure insertion, End can either be set to Pos or token.NoPos. - Pos token.Pos - End token.Pos - NewText []byte -} diff --git a/vendor/golang.org/x/tools/go/analysis/doc.go b/vendor/golang.org/x/tools/go/analysis/doc.go deleted file mode 100644 index fb17a0e41..000000000 --- a/vendor/golang.org/x/tools/go/analysis/doc.go +++ /dev/null @@ -1,310 +0,0 @@ -/* - -Package analysis defines the interface between a modular static -analysis and an analysis driver program. - - -Background - -A static analysis is a function that inspects a package of Go code and -reports a set of diagnostics (typically mistakes in the code), and -perhaps produces other results as well, such as suggested refactorings -or other facts. An analysis that reports mistakes is informally called a -"checker". For example, the printf checker reports mistakes in -fmt.Printf format strings. - -A "modular" analysis is one that inspects one package at a time but can -save information from a lower-level package and use it when inspecting a -higher-level package, analogous to separate compilation in a toolchain. -The printf checker is modular: when it discovers that a function such as -log.Fatalf delegates to fmt.Printf, it records this fact, and checks -calls to that function too, including calls made from another package. - -By implementing a common interface, checkers from a variety of sources -can be easily selected, incorporated, and reused in a wide range of -driver programs including command-line tools (such as vet), text editors and -IDEs, build and test systems (such as go build, Bazel, or Buck), test -frameworks, code review tools, code-base indexers (such as SourceGraph), -documentation viewers (such as godoc), batch pipelines for large code -bases, and so on. - - -Analyzer - -The primary type in the API is Analyzer. An Analyzer statically -describes an analysis function: its name, documentation, flags, -relationship to other analyzers, and of course, its logic. - -To define an analysis, a user declares a (logically constant) variable -of type Analyzer. Here is a typical example from one of the analyzers in -the go/analysis/passes/ subdirectory: - - package unusedresult - - var Analyzer = &analysis.Analyzer{ - Name: "unusedresult", - Doc: "check for unused results of calls to some functions", - Run: run, - ... - } - - func run(pass *analysis.Pass) (interface{}, error) { - ... - } - -An analysis driver is a program such as vet that runs a set of -analyses and prints the diagnostics that they report. -The driver program must import the list of Analyzers it needs. -Typically each Analyzer resides in a separate package. -To add a new Analyzer to an existing driver, add another item to the list: - - import ( "unusedresult"; "nilness"; "printf" ) - - var analyses = []*analysis.Analyzer{ - unusedresult.Analyzer, - nilness.Analyzer, - printf.Analyzer, - } - -A driver may use the name, flags, and documentation to provide on-line -help that describes the analyses it performs. -The doc comment contains a brief one-line summary, -optionally followed by paragraphs of explanation. - -The Analyzer type has more fields besides those shown above: - - type Analyzer struct { - Name string - Doc string - Flags flag.FlagSet - Run func(*Pass) (interface{}, error) - RunDespiteErrors bool - ResultType reflect.Type - Requires []*Analyzer - FactTypes []Fact - } - -The Flags field declares a set of named (global) flag variables that -control analysis behavior. Unlike vet, analysis flags are not declared -directly in the command line FlagSet; it is up to the driver to set the -flag variables. A driver for a single analysis, a, might expose its flag -f directly on the command line as -f, whereas a driver for multiple -analyses might prefix the flag name by the analysis name (-a.f) to avoid -ambiguity. An IDE might expose the flags through a graphical interface, -and a batch pipeline might configure them from a config file. -See the "findcall" analyzer for an example of flags in action. - -The RunDespiteErrors flag indicates whether the analysis is equipped to -handle ill-typed code. If not, the driver will skip the analysis if -there were parse or type errors. -The optional ResultType field specifies the type of the result value -computed by this analysis and made available to other analyses. -The Requires field specifies a list of analyses upon which -this one depends and whose results it may access, and it constrains the -order in which a driver may run analyses. -The FactTypes field is discussed in the section on Modularity. -The analysis package provides a Validate function to perform basic -sanity checks on an Analyzer, such as that its Requires graph is -acyclic, its fact and result types are unique, and so on. - -Finally, the Run field contains a function to be called by the driver to -execute the analysis on a single package. The driver passes it an -instance of the Pass type. - - -Pass - -A Pass describes a single unit of work: the application of a particular -Analyzer to a particular package of Go code. -The Pass provides information to the Analyzer's Run function about the -package being analyzed, and provides operations to the Run function for -reporting diagnostics and other information back to the driver. - - type Pass struct { - Fset *token.FileSet - Files []*ast.File - OtherFiles []string - Pkg *types.Package - TypesInfo *types.Info - ResultOf map[*Analyzer]interface{} - Report func(Diagnostic) - ... - } - -The Fset, Files, Pkg, and TypesInfo fields provide the syntax trees, -type information, and source positions for a single package of Go code. - -The OtherFiles field provides the names, but not the contents, of non-Go -files such as assembly that are part of this package. See the "asmdecl" -or "buildtags" analyzers for examples of loading non-Go files and reporting -diagnostics against them. - -The ResultOf field provides the results computed by the analyzers -required by this one, as expressed in its Analyzer.Requires field. The -driver runs the required analyzers first and makes their results -available in this map. Each Analyzer must return a value of the type -described in its Analyzer.ResultType field. -For example, the "ctrlflow" analyzer returns a *ctrlflow.CFGs, which -provides a control-flow graph for each function in the package (see -golang.org/x/tools/go/cfg); the "inspect" analyzer returns a value that -enables other Analyzers to traverse the syntax trees of the package more -efficiently; and the "buildssa" analyzer constructs an SSA-form -intermediate representation. -Each of these Analyzers extends the capabilities of later Analyzers -without adding a dependency to the core API, so an analysis tool pays -only for the extensions it needs. - -The Report function emits a diagnostic, a message associated with a -source position. For most analyses, diagnostics are their primary -result. -For convenience, Pass provides a helper method, Reportf, to report a new -diagnostic by formatting a string. -Diagnostic is defined as: - - type Diagnostic struct { - Pos token.Pos - Category string // optional - Message string - } - -The optional Category field is a short identifier that classifies the -kind of message when an analysis produces several kinds of diagnostic. - -Many analyses want to associate diagnostics with a severity level. -Because Diagnostic does not have a severity level field, an Analyzer's -diagnostics effectively all have the same severity level. To separate which -diagnostics are high severity and which are low severity, expose multiple -Analyzers instead. Analyzers should also be separated when their -diagnostics belong in different groups, or could be tagged differently -before being shown to the end user. Analyzers should document their severity -level to help downstream tools surface diagnostics properly. - -Most Analyzers inspect typed Go syntax trees, but a few, such as asmdecl -and buildtag, inspect the raw text of Go source files or even non-Go -files such as assembly. To report a diagnostic against a line of a -raw text file, use the following sequence: - - content, err := ioutil.ReadFile(filename) - if err != nil { ... } - tf := fset.AddFile(filename, -1, len(content)) - tf.SetLinesForContent(content) - ... - pass.Reportf(tf.LineStart(line), "oops") - - -Modular analysis with Facts - -To improve efficiency and scalability, large programs are routinely -built using separate compilation: units of the program are compiled -separately, and recompiled only when one of their dependencies changes; -independent modules may be compiled in parallel. The same technique may -be applied to static analyses, for the same benefits. Such analyses are -described as "modular". - -A compiler’s type checker is an example of a modular static analysis. -Many other checkers we would like to apply to Go programs can be -understood as alternative or non-standard type systems. For example, -vet's printf checker infers whether a function has the "printf wrapper" -type, and it applies stricter checks to calls of such functions. In -addition, it records which functions are printf wrappers for use by -later analysis passes to identify other printf wrappers by induction. -A result such as “f is a printf wrapper” that is not interesting by -itself but serves as a stepping stone to an interesting result (such as -a diagnostic) is called a "fact". - -The analysis API allows an analysis to define new types of facts, to -associate facts of these types with objects (named entities) declared -within the current package, or with the package as a whole, and to query -for an existing fact of a given type associated with an object or -package. - -An Analyzer that uses facts must declare their types: - - var Analyzer = &analysis.Analyzer{ - Name: "printf", - FactTypes: []analysis.Fact{new(isWrapper)}, - ... - } - - type isWrapper struct{} // => *types.Func f “is a printf wrapper” - -The driver program ensures that facts for a pass’s dependencies are -generated before analyzing the package and is responsible for propagating -facts from one package to another, possibly across address spaces. -Consequently, Facts must be serializable. The API requires that drivers -use the gob encoding, an efficient, robust, self-describing binary -protocol. A fact type may implement the GobEncoder/GobDecoder interfaces -if the default encoding is unsuitable. Facts should be stateless. - -The Pass type has functions to import and export facts, -associated either with an object or with a package: - - type Pass struct { - ... - ExportObjectFact func(types.Object, Fact) - ImportObjectFact func(types.Object, Fact) bool - - ExportPackageFact func(fact Fact) - ImportPackageFact func(*types.Package, Fact) bool - } - -An Analyzer may only export facts associated with the current package or -its objects, though it may import facts from any package or object that -is an import dependency of the current package. - -Conceptually, ExportObjectFact(obj, fact) inserts fact into a hidden map keyed by -the pair (obj, TypeOf(fact)), and the ImportObjectFact function -retrieves the entry from this map and copies its value into the variable -pointed to by fact. This scheme assumes that the concrete type of fact -is a pointer; this assumption is checked by the Validate function. -See the "printf" analyzer for an example of object facts in action. - -Some driver implementations (such as those based on Bazel and Blaze) do -not currently apply analyzers to packages of the standard library. -Therefore, for best results, analyzer authors should not rely on -analysis facts being available for standard packages. -For example, although the printf checker is capable of deducing during -analysis of the log package that log.Printf is a printf wrapper, -this fact is built in to the analyzer so that it correctly checks -calls to log.Printf even when run in a driver that does not apply -it to standard packages. We would like to remove this limitation in future. - - -Testing an Analyzer - -The analysistest subpackage provides utilities for testing an Analyzer. -In a few lines of code, it is possible to run an analyzer on a package -of testdata files and check that it reported all the expected -diagnostics and facts (and no more). Expectations are expressed using -"// want ..." comments in the input code. - - -Standalone commands - -Analyzers are provided in the form of packages that a driver program is -expected to import. The vet command imports a set of several analyzers, -but users may wish to define their own analysis commands that perform -additional checks. To simplify the task of creating an analysis command, -either for a single analyzer or for a whole suite, we provide the -singlechecker and multichecker subpackages. - -The singlechecker package provides the main function for a command that -runs one analyzer. By convention, each analyzer such as -go/passes/findcall should be accompanied by a singlechecker-based -command such as go/analysis/passes/findcall/cmd/findcall, defined in its -entirety as: - - package main - - import ( - "golang.org/x/tools/go/analysis/passes/findcall" - "golang.org/x/tools/go/analysis/singlechecker" - ) - - func main() { singlechecker.Main(findcall.Analyzer) } - -A tool that provides multiple analyzers can use multichecker in a -similar way, giving it the list of Analyzers. - -*/ -package analysis diff --git a/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go b/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go deleted file mode 100644 index 2856df137..000000000 --- a/vendor/golang.org/x/tools/go/analysis/passes/inspect/inspect.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package inspect defines an Analyzer that provides an AST inspector -// (golang.org/x/tools/go/ast/inspect.Inspect) for the syntax trees of a -// package. It is only a building block for other analyzers. -// -// Example of use in another analysis: -// -// import ( -// "golang.org/x/tools/go/analysis" -// "golang.org/x/tools/go/analysis/passes/inspect" -// "golang.org/x/tools/go/ast/inspector" -// ) -// -// var Analyzer = &analysis.Analyzer{ -// ... -// Requires: []*analysis.Analyzer{inspect.Analyzer}, -// } -// -// func run(pass *analysis.Pass) (interface{}, error) { -// inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) -// inspect.Preorder(nil, func(n ast.Node) { -// ... -// }) -// return nil -// } -// -package inspect - -import ( - "reflect" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/ast/inspector" -) - -var Analyzer = &analysis.Analyzer{ - Name: "inspect", - Doc: "optimize AST traversal for later passes", - Run: run, - RunDespiteErrors: true, - ResultType: reflect.TypeOf(new(inspector.Inspector)), -} - -func run(pass *analysis.Pass) (interface{}, error) { - return inspector.New(pass.Files), nil -} diff --git a/vendor/golang.org/x/tools/go/analysis/validate.go b/vendor/golang.org/x/tools/go/analysis/validate.go deleted file mode 100644 index be9814346..000000000 --- a/vendor/golang.org/x/tools/go/analysis/validate.go +++ /dev/null @@ -1,97 +0,0 @@ -package analysis - -import ( - "fmt" - "reflect" - "unicode" -) - -// Validate reports an error if any of the analyzers are misconfigured. -// Checks include: -// that the name is a valid identifier; -// that the Requires graph is acyclic; -// that analyzer fact types are unique; -// that each fact type is a pointer. -func Validate(analyzers []*Analyzer) error { - // Map each fact type to its sole generating analyzer. - factTypes := make(map[reflect.Type]*Analyzer) - - // Traverse the Requires graph, depth first. - const ( - white = iota - grey - black - finished - ) - color := make(map[*Analyzer]uint8) - var visit func(a *Analyzer) error - visit = func(a *Analyzer) error { - if a == nil { - return fmt.Errorf("nil *Analyzer") - } - if color[a] == white { - color[a] = grey - - // names - if !validIdent(a.Name) { - return fmt.Errorf("invalid analyzer name %q", a) - } - - if a.Doc == "" { - return fmt.Errorf("analyzer %q is undocumented", a) - } - - // fact types - for _, f := range a.FactTypes { - if f == nil { - return fmt.Errorf("analyzer %s has nil FactType", a) - } - t := reflect.TypeOf(f) - if prev := factTypes[t]; prev != nil { - return fmt.Errorf("fact type %s registered by two analyzers: %v, %v", - t, a, prev) - } - if t.Kind() != reflect.Ptr { - return fmt.Errorf("%s: fact type %s is not a pointer", a, t) - } - factTypes[t] = a - } - - // recursion - for i, req := range a.Requires { - if err := visit(req); err != nil { - return fmt.Errorf("%s.Requires[%d]: %v", a.Name, i, err) - } - } - color[a] = black - } - - return nil - } - for _, a := range analyzers { - if err := visit(a); err != nil { - return err - } - } - - // Reject duplicates among analyzers. - // Precondition: color[a] == black. - // Postcondition: color[a] == finished. - for _, a := range analyzers { - if color[a] == finished { - return fmt.Errorf("duplicate analyzer: %s", a.Name) - } - color[a] = finished - } - - return nil -} - -func validIdent(name string) bool { - for i, r := range name { - if !(r == '_' || unicode.IsLetter(r) || i > 0 && unicode.IsDigit(r)) { - return false - } - } - return name != "" -} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go b/vendor/golang.org/x/tools/go/ast/inspector/inspector.go deleted file mode 100644 index af5e17fee..000000000 --- a/vendor/golang.org/x/tools/go/ast/inspector/inspector.go +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package inspector provides helper functions for traversal over the -// syntax trees of a package, including node filtering by type, and -// materialization of the traversal stack. -// -// During construction, the inspector does a complete traversal and -// builds a list of push/pop events and their node type. Subsequent -// method calls that request a traversal scan this list, rather than walk -// the AST, and perform type filtering using efficient bit sets. -// -// Experiments suggest the inspector's traversals are about 2.5x faster -// than ast.Inspect, but it may take around 5 traversals for this -// benefit to amortize the inspector's construction cost. -// If efficiency is the primary concern, do not use Inspector for -// one-off traversals. -package inspector - -// There are four orthogonal features in a traversal: -// 1 type filtering -// 2 pruning -// 3 postorder calls to f -// 4 stack -// Rather than offer all of them in the API, -// only a few combinations are exposed: -// - Preorder is the fastest and has fewest features, -// but is the most commonly needed traversal. -// - Nodes and WithStack both provide pruning and postorder calls, -// even though few clients need it, because supporting two versions -// is not justified. -// More combinations could be supported by expressing them as -// wrappers around a more generic traversal, but this was measured -// and found to degrade performance significantly (30%). - -import ( - "go/ast" -) - -// An Inspector provides methods for inspecting -// (traversing) the syntax trees of a package. -type Inspector struct { - events []event -} - -// New returns an Inspector for the specified syntax trees. -func New(files []*ast.File) *Inspector { - return &Inspector{traverse(files)} -} - -// An event represents a push or a pop -// of an ast.Node during a traversal. -type event struct { - node ast.Node - typ uint64 // typeOf(node) - index int // 1 + index of corresponding pop event, or 0 if this is a pop -} - -// Preorder visits all the nodes of the files supplied to New in -// depth-first order. It calls f(n) for each node n before it visits -// n's children. -// -// The types argument, if non-empty, enables type-based filtering of -// events. The function f if is called only for nodes whose type -// matches an element of the types slice. -func (in *Inspector) Preorder(types []ast.Node, f func(ast.Node)) { - // Because it avoids postorder calls to f, and the pruning - // check, Preorder is almost twice as fast as Nodes. The two - // features seem to contribute similar slowdowns (~1.4x each). - - mask := maskOf(types) - for i := 0; i < len(in.events); { - ev := in.events[i] - if ev.typ&mask != 0 { - if ev.index > 0 { - f(ev.node) - } - } - i++ - } -} - -// Nodes visits the nodes of the files supplied to New in depth-first -// order. It calls f(n, true) for each node n before it visits n's -// children. If f returns true, Nodes invokes f recursively for each -// of the non-nil children of the node, followed by a call of -// f(n, false). -// -// The types argument, if non-empty, enables type-based filtering of -// events. The function f if is called only for nodes whose type -// matches an element of the types slice. -func (in *Inspector) Nodes(types []ast.Node, f func(n ast.Node, push bool) (proceed bool)) { - mask := maskOf(types) - for i := 0; i < len(in.events); { - ev := in.events[i] - if ev.typ&mask != 0 { - if ev.index > 0 { - // push - if !f(ev.node, true) { - i = ev.index // jump to corresponding pop + 1 - continue - } - } else { - // pop - f(ev.node, false) - } - } - i++ - } -} - -// WithStack visits nodes in a similar manner to Nodes, but it -// supplies each call to f an additional argument, the current -// traversal stack. The stack's first element is the outermost node, -// an *ast.File; its last is the innermost, n. -func (in *Inspector) WithStack(types []ast.Node, f func(n ast.Node, push bool, stack []ast.Node) (proceed bool)) { - mask := maskOf(types) - var stack []ast.Node - for i := 0; i < len(in.events); { - ev := in.events[i] - if ev.index > 0 { - // push - stack = append(stack, ev.node) - if ev.typ&mask != 0 { - if !f(ev.node, true, stack) { - i = ev.index - stack = stack[:len(stack)-1] - continue - } - } - } else { - // pop - if ev.typ&mask != 0 { - f(ev.node, false, stack) - } - stack = stack[:len(stack)-1] - } - i++ - } -} - -// traverse builds the table of events representing a traversal. -func traverse(files []*ast.File) []event { - // Preallocate approximate number of events - // based on source file extent. - // This makes traverse faster by 4x (!). - var extent int - for _, f := range files { - extent += int(f.End() - f.Pos()) - } - // This estimate is based on the net/http package. - capacity := extent * 33 / 100 - if capacity > 1e6 { - capacity = 1e6 // impose some reasonable maximum - } - events := make([]event, 0, capacity) - - var stack []event - for _, f := range files { - ast.Inspect(f, func(n ast.Node) bool { - if n != nil { - // push - ev := event{ - node: n, - typ: typeOf(n), - index: len(events), // push event temporarily holds own index - } - stack = append(stack, ev) - events = append(events, ev) - } else { - // pop - ev := stack[len(stack)-1] - stack = stack[:len(stack)-1] - - events[ev.index].index = len(events) + 1 // make push refer to pop - - ev.index = 0 // turn ev into a pop event - events = append(events, ev) - } - return true - }) - } - - return events -} diff --git a/vendor/golang.org/x/tools/go/ast/inspector/typeof.go b/vendor/golang.org/x/tools/go/ast/inspector/typeof.go deleted file mode 100644 index d61301b13..000000000 --- a/vendor/golang.org/x/tools/go/ast/inspector/typeof.go +++ /dev/null @@ -1,216 +0,0 @@ -package inspector - -// This file defines func typeOf(ast.Node) uint64. -// -// The initial map-based implementation was too slow; -// see https://go-review.googlesource.com/c/tools/+/135655/1/go/ast/inspector/inspector.go#196 - -import "go/ast" - -const ( - nArrayType = iota - nAssignStmt - nBadDecl - nBadExpr - nBadStmt - nBasicLit - nBinaryExpr - nBlockStmt - nBranchStmt - nCallExpr - nCaseClause - nChanType - nCommClause - nComment - nCommentGroup - nCompositeLit - nDeclStmt - nDeferStmt - nEllipsis - nEmptyStmt - nExprStmt - nField - nFieldList - nFile - nForStmt - nFuncDecl - nFuncLit - nFuncType - nGenDecl - nGoStmt - nIdent - nIfStmt - nImportSpec - nIncDecStmt - nIndexExpr - nInterfaceType - nKeyValueExpr - nLabeledStmt - nMapType - nPackage - nParenExpr - nRangeStmt - nReturnStmt - nSelectStmt - nSelectorExpr - nSendStmt - nSliceExpr - nStarExpr - nStructType - nSwitchStmt - nTypeAssertExpr - nTypeSpec - nTypeSwitchStmt - nUnaryExpr - nValueSpec -) - -// typeOf returns a distinct single-bit value that represents the type of n. -// -// Various implementations were benchmarked with BenchmarkNewInspector: -// GOGC=off -// - type switch 4.9-5.5ms 2.1ms -// - binary search over a sorted list of types 5.5-5.9ms 2.5ms -// - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms -// - linear scan, unordered list 6.4ms 2.7ms -// - hash table 6.5ms 3.1ms -// A perfect hash seemed like overkill. -// -// The compiler's switch statement is the clear winner -// as it produces a binary tree in code, -// with constant conditions and good branch prediction. -// (Sadly it is the most verbose in source code.) -// Binary search suffered from poor branch prediction. -// -func typeOf(n ast.Node) uint64 { - // Fast path: nearly half of all nodes are identifiers. - if _, ok := n.(*ast.Ident); ok { - return 1 << nIdent - } - - // These cases include all nodes encountered by ast.Inspect. - switch n.(type) { - case *ast.ArrayType: - return 1 << nArrayType - case *ast.AssignStmt: - return 1 << nAssignStmt - case *ast.BadDecl: - return 1 << nBadDecl - case *ast.BadExpr: - return 1 << nBadExpr - case *ast.BadStmt: - return 1 << nBadStmt - case *ast.BasicLit: - return 1 << nBasicLit - case *ast.BinaryExpr: - return 1 << nBinaryExpr - case *ast.BlockStmt: - return 1 << nBlockStmt - case *ast.BranchStmt: - return 1 << nBranchStmt - case *ast.CallExpr: - return 1 << nCallExpr - case *ast.CaseClause: - return 1 << nCaseClause - case *ast.ChanType: - return 1 << nChanType - case *ast.CommClause: - return 1 << nCommClause - case *ast.Comment: - return 1 << nComment - case *ast.CommentGroup: - return 1 << nCommentGroup - case *ast.CompositeLit: - return 1 << nCompositeLit - case *ast.DeclStmt: - return 1 << nDeclStmt - case *ast.DeferStmt: - return 1 << nDeferStmt - case *ast.Ellipsis: - return 1 << nEllipsis - case *ast.EmptyStmt: - return 1 << nEmptyStmt - case *ast.ExprStmt: - return 1 << nExprStmt - case *ast.Field: - return 1 << nField - case *ast.FieldList: - return 1 << nFieldList - case *ast.File: - return 1 << nFile - case *ast.ForStmt: - return 1 << nForStmt - case *ast.FuncDecl: - return 1 << nFuncDecl - case *ast.FuncLit: - return 1 << nFuncLit - case *ast.FuncType: - return 1 << nFuncType - case *ast.GenDecl: - return 1 << nGenDecl - case *ast.GoStmt: - return 1 << nGoStmt - case *ast.Ident: - return 1 << nIdent - case *ast.IfStmt: - return 1 << nIfStmt - case *ast.ImportSpec: - return 1 << nImportSpec - case *ast.IncDecStmt: - return 1 << nIncDecStmt - case *ast.IndexExpr: - return 1 << nIndexExpr - case *ast.InterfaceType: - return 1 << nInterfaceType - case *ast.KeyValueExpr: - return 1 << nKeyValueExpr - case *ast.LabeledStmt: - return 1 << nLabeledStmt - case *ast.MapType: - return 1 << nMapType - case *ast.Package: - return 1 << nPackage - case *ast.ParenExpr: - return 1 << nParenExpr - case *ast.RangeStmt: - return 1 << nRangeStmt - case *ast.ReturnStmt: - return 1 << nReturnStmt - case *ast.SelectStmt: - return 1 << nSelectStmt - case *ast.SelectorExpr: - return 1 << nSelectorExpr - case *ast.SendStmt: - return 1 << nSendStmt - case *ast.SliceExpr: - return 1 << nSliceExpr - case *ast.StarExpr: - return 1 << nStarExpr - case *ast.StructType: - return 1 << nStructType - case *ast.SwitchStmt: - return 1 << nSwitchStmt - case *ast.TypeAssertExpr: - return 1 << nTypeAssertExpr - case *ast.TypeSpec: - return 1 << nTypeSpec - case *ast.TypeSwitchStmt: - return 1 << nTypeSwitchStmt - case *ast.UnaryExpr: - return 1 << nUnaryExpr - case *ast.ValueSpec: - return 1 << nValueSpec - } - return 0 -} - -func maskOf(nodes []ast.Node) uint64 { - if nodes == nil { - return 1<<64 - 1 // match all node types - } - var mask uint64 - for _, n := range nodes { - mask |= typeOf(n) - } - return mask -} diff --git a/vendor/golang.org/x/tools/go/buildutil/allpackages.go b/vendor/golang.org/x/tools/go/buildutil/allpackages.go deleted file mode 100644 index c0cb03e7b..000000000 --- a/vendor/golang.org/x/tools/go/buildutil/allpackages.go +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package buildutil provides utilities related to the go/build -// package in the standard library. -// -// All I/O is done via the build.Context file system interface, which must -// be concurrency-safe. -package buildutil // import "golang.org/x/tools/go/buildutil" - -import ( - "go/build" - "os" - "path/filepath" - "sort" - "strings" - "sync" -) - -// AllPackages returns the package path of each Go package in any source -// directory of the specified build context (e.g. $GOROOT or an element -// of $GOPATH). Errors are ignored. The results are sorted. -// All package paths are canonical, and thus may contain "/vendor/". -// -// The result may include import paths for directories that contain no -// *.go files, such as "archive" (in $GOROOT/src). -// -// All I/O is done via the build.Context file system interface, -// which must be concurrency-safe. -// -func AllPackages(ctxt *build.Context) []string { - var list []string - ForEachPackage(ctxt, func(pkg string, _ error) { - list = append(list, pkg) - }) - sort.Strings(list) - return list -} - -// ForEachPackage calls the found function with the package path of -// each Go package it finds in any source directory of the specified -// build context (e.g. $GOROOT or an element of $GOPATH). -// All package paths are canonical, and thus may contain "/vendor/". -// -// If the package directory exists but could not be read, the second -// argument to the found function provides the error. -// -// All I/O is done via the build.Context file system interface, -// which must be concurrency-safe. -// -func ForEachPackage(ctxt *build.Context, found func(importPath string, err error)) { - ch := make(chan item) - - var wg sync.WaitGroup - for _, root := range ctxt.SrcDirs() { - root := root - wg.Add(1) - go func() { - allPackages(ctxt, root, ch) - wg.Done() - }() - } - go func() { - wg.Wait() - close(ch) - }() - - // All calls to found occur in the caller's goroutine. - for i := range ch { - found(i.importPath, i.err) - } -} - -type item struct { - importPath string - err error // (optional) -} - -// We use a process-wide counting semaphore to limit -// the number of parallel calls to ReadDir. -var ioLimit = make(chan bool, 20) - -func allPackages(ctxt *build.Context, root string, ch chan<- item) { - root = filepath.Clean(root) + string(os.PathSeparator) - - var wg sync.WaitGroup - - var walkDir func(dir string) - walkDir = func(dir string) { - // Avoid .foo, _foo, and testdata directory trees. - base := filepath.Base(dir) - if base == "" || base[0] == '.' || base[0] == '_' || base == "testdata" { - return - } - - pkg := filepath.ToSlash(strings.TrimPrefix(dir, root)) - - // Prune search if we encounter any of these import paths. - switch pkg { - case "builtin": - return - } - - ioLimit <- true - files, err := ReadDir(ctxt, dir) - <-ioLimit - if pkg != "" || err != nil { - ch <- item{pkg, err} - } - for _, fi := range files { - fi := fi - if fi.IsDir() { - wg.Add(1) - go func() { - walkDir(filepath.Join(dir, fi.Name())) - wg.Done() - }() - } - } - } - - walkDir(root) - wg.Wait() -} - -// ExpandPatterns returns the set of packages matched by patterns, -// which may have the following forms: -// -// golang.org/x/tools/cmd/guru # a single package -// golang.org/x/tools/... # all packages beneath dir -// ... # the entire workspace. -// -// Order is significant: a pattern preceded by '-' removes matching -// packages from the set. For example, these patterns match all encoding -// packages except encoding/xml: -// -// encoding/... -encoding/xml -// -// A trailing slash in a pattern is ignored. (Path components of Go -// package names are separated by slash, not the platform's path separator.) -// -func ExpandPatterns(ctxt *build.Context, patterns []string) map[string]bool { - // TODO(adonovan): support other features of 'go list': - // - "std"/"cmd"/"all" meta-packages - // - "..." not at the end of a pattern - // - relative patterns using "./" or "../" prefix - - pkgs := make(map[string]bool) - doPkg := func(pkg string, neg bool) { - if neg { - delete(pkgs, pkg) - } else { - pkgs[pkg] = true - } - } - - // Scan entire workspace if wildcards are present. - // TODO(adonovan): opt: scan only the necessary subtrees of the workspace. - var all []string - for _, arg := range patterns { - if strings.HasSuffix(arg, "...") { - all = AllPackages(ctxt) - break - } - } - - for _, arg := range patterns { - if arg == "" { - continue - } - - neg := arg[0] == '-' - if neg { - arg = arg[1:] - } - - if arg == "..." { - // ... matches all packages - for _, pkg := range all { - doPkg(pkg, neg) - } - } else if dir := strings.TrimSuffix(arg, "/..."); dir != arg { - // dir/... matches all packages beneath dir - for _, pkg := range all { - if strings.HasPrefix(pkg, dir) && - (len(pkg) == len(dir) || pkg[len(dir)] == '/') { - doPkg(pkg, neg) - } - } - } else { - // single package - doPkg(strings.TrimSuffix(arg, "/"), neg) - } - } - - return pkgs -} diff --git a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go b/vendor/golang.org/x/tools/go/buildutil/fakecontext.go deleted file mode 100644 index 8b7f06673..000000000 --- a/vendor/golang.org/x/tools/go/buildutil/fakecontext.go +++ /dev/null @@ -1,109 +0,0 @@ -package buildutil - -import ( - "fmt" - "go/build" - "io" - "io/ioutil" - "os" - "path" - "path/filepath" - "sort" - "strings" - "time" -) - -// FakeContext returns a build.Context for the fake file tree specified -// by pkgs, which maps package import paths to a mapping from file base -// names to contents. -// -// The fake Context has a GOROOT of "/go" and no GOPATH, and overrides -// the necessary file access methods to read from memory instead of the -// real file system. -// -// Unlike a real file tree, the fake one has only two levels---packages -// and files---so ReadDir("/go/src/") returns all packages under -// /go/src/ including, for instance, "math" and "math/big". -// ReadDir("/go/src/math/big") would return all the files in the -// "math/big" package. -// -func FakeContext(pkgs map[string]map[string]string) *build.Context { - clean := func(filename string) string { - f := path.Clean(filepath.ToSlash(filename)) - // Removing "/go/src" while respecting segment - // boundaries has this unfortunate corner case: - if f == "/go/src" { - return "" - } - return strings.TrimPrefix(f, "/go/src/") - } - - ctxt := build.Default // copy - ctxt.GOROOT = "/go" - ctxt.GOPATH = "" - ctxt.Compiler = "gc" - ctxt.IsDir = func(dir string) bool { - dir = clean(dir) - if dir == "" { - return true // needed by (*build.Context).SrcDirs - } - return pkgs[dir] != nil - } - ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) { - dir = clean(dir) - var fis []os.FileInfo - if dir == "" { - // enumerate packages - for importPath := range pkgs { - fis = append(fis, fakeDirInfo(importPath)) - } - } else { - // enumerate files of package - for basename := range pkgs[dir] { - fis = append(fis, fakeFileInfo(basename)) - } - } - sort.Sort(byName(fis)) - return fis, nil - } - ctxt.OpenFile = func(filename string) (io.ReadCloser, error) { - filename = clean(filename) - dir, base := path.Split(filename) - content, ok := pkgs[path.Clean(dir)][base] - if !ok { - return nil, fmt.Errorf("file not found: %s", filename) - } - return ioutil.NopCloser(strings.NewReader(content)), nil - } - ctxt.IsAbsPath = func(path string) bool { - path = filepath.ToSlash(path) - // Don't rely on the default (filepath.Path) since on - // Windows, it reports virtual paths as non-absolute. - return strings.HasPrefix(path, "/") - } - return &ctxt -} - -type byName []os.FileInfo - -func (s byName) Len() int { return len(s) } -func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() } - -type fakeFileInfo string - -func (fi fakeFileInfo) Name() string { return string(fi) } -func (fakeFileInfo) Sys() interface{} { return nil } -func (fakeFileInfo) ModTime() time.Time { return time.Time{} } -func (fakeFileInfo) IsDir() bool { return false } -func (fakeFileInfo) Size() int64 { return 0 } -func (fakeFileInfo) Mode() os.FileMode { return 0644 } - -type fakeDirInfo string - -func (fd fakeDirInfo) Name() string { return string(fd) } -func (fakeDirInfo) Sys() interface{} { return nil } -func (fakeDirInfo) ModTime() time.Time { return time.Time{} } -func (fakeDirInfo) IsDir() bool { return true } -func (fakeDirInfo) Size() int64 { return 0 } -func (fakeDirInfo) Mode() os.FileMode { return 0755 } diff --git a/vendor/golang.org/x/tools/go/buildutil/overlay.go b/vendor/golang.org/x/tools/go/buildutil/overlay.go deleted file mode 100644 index 8e239086b..000000000 --- a/vendor/golang.org/x/tools/go/buildutil/overlay.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package buildutil - -import ( - "bufio" - "bytes" - "fmt" - "go/build" - "io" - "io/ioutil" - "path/filepath" - "strconv" - "strings" -) - -// OverlayContext overlays a build.Context with additional files from -// a map. Files in the map take precedence over other files. -// -// In addition to plain string comparison, two file names are -// considered equal if their base names match and their directory -// components point at the same directory on the file system. That is, -// symbolic links are followed for directories, but not files. -// -// A common use case for OverlayContext is to allow editors to pass in -// a set of unsaved, modified files. -// -// Currently, only the Context.OpenFile function will respect the -// overlay. This may change in the future. -func OverlayContext(orig *build.Context, overlay map[string][]byte) *build.Context { - // TODO(dominikh): Implement IsDir, HasSubdir and ReadDir - - rc := func(data []byte) (io.ReadCloser, error) { - return ioutil.NopCloser(bytes.NewBuffer(data)), nil - } - - copy := *orig // make a copy - ctxt := © - ctxt.OpenFile = func(path string) (io.ReadCloser, error) { - // Fast path: names match exactly. - if content, ok := overlay[path]; ok { - return rc(content) - } - - // Slow path: check for same file under a different - // alias, perhaps due to a symbolic link. - for filename, content := range overlay { - if sameFile(path, filename) { - return rc(content) - } - } - - return OpenFile(orig, path) - } - return ctxt -} - -// ParseOverlayArchive parses an archive containing Go files and their -// contents. The result is intended to be used with OverlayContext. -// -// -// Archive format -// -// The archive consists of a series of files. Each file consists of a -// name, a decimal file size and the file contents, separated by -// newlines. No newline follows after the file contents. -func ParseOverlayArchive(archive io.Reader) (map[string][]byte, error) { - overlay := make(map[string][]byte) - r := bufio.NewReader(archive) - for { - // Read file name. - filename, err := r.ReadString('\n') - if err != nil { - if err == io.EOF { - break // OK - } - return nil, fmt.Errorf("reading archive file name: %v", err) - } - filename = filepath.Clean(strings.TrimSpace(filename)) - - // Read file size. - sz, err := r.ReadString('\n') - if err != nil { - return nil, fmt.Errorf("reading size of archive file %s: %v", filename, err) - } - sz = strings.TrimSpace(sz) - size, err := strconv.ParseUint(sz, 10, 32) - if err != nil { - return nil, fmt.Errorf("parsing size of archive file %s: %v", filename, err) - } - - // Read file content. - content := make([]byte, size) - if _, err := io.ReadFull(r, content); err != nil { - return nil, fmt.Errorf("reading archive file %s: %v", filename, err) - } - overlay[filename] = content - } - - return overlay, nil -} diff --git a/vendor/golang.org/x/tools/go/buildutil/tags.go b/vendor/golang.org/x/tools/go/buildutil/tags.go deleted file mode 100644 index 486606f37..000000000 --- a/vendor/golang.org/x/tools/go/buildutil/tags.go +++ /dev/null @@ -1,75 +0,0 @@ -package buildutil - -// This logic was copied from stringsFlag from $GOROOT/src/cmd/go/build.go. - -import "fmt" - -const TagsFlagDoc = "a list of `build tags` to consider satisfied during the build. " + - "For more information about build tags, see the description of " + - "build constraints in the documentation for the go/build package" - -// TagsFlag is an implementation of the flag.Value and flag.Getter interfaces that parses -// a flag value in the same manner as go build's -tags flag and -// populates a []string slice. -// -// See $GOROOT/src/go/build/doc.go for description of build tags. -// See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag. -// -// Example: -// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc) -type TagsFlag []string - -func (v *TagsFlag) Set(s string) error { - var err error - *v, err = splitQuotedFields(s) - if *v == nil { - *v = []string{} - } - return err -} - -func (v *TagsFlag) Get() interface{} { return *v } - -func splitQuotedFields(s string) ([]string, error) { - // Split fields allowing '' or "" around elements. - // Quotes further inside the string do not count. - var f []string - for len(s) > 0 { - for len(s) > 0 && isSpaceByte(s[0]) { - s = s[1:] - } - if len(s) == 0 { - break - } - // Accepted quoted string. No unescaping inside. - if s[0] == '"' || s[0] == '\'' { - quote := s[0] - s = s[1:] - i := 0 - for i < len(s) && s[i] != quote { - i++ - } - if i >= len(s) { - return nil, fmt.Errorf("unterminated %c string", quote) - } - f = append(f, s[:i]) - s = s[i+1:] - continue - } - i := 0 - for i < len(s) && !isSpaceByte(s[i]) { - i++ - } - f = append(f, s[:i]) - s = s[i:] - } - return f, nil -} - -func (v *TagsFlag) String() string { - return "" -} - -func isSpaceByte(c byte) bool { - return c == ' ' || c == '\t' || c == '\n' || c == '\r' -} diff --git a/vendor/golang.org/x/tools/go/buildutil/util.go b/vendor/golang.org/x/tools/go/buildutil/util.go deleted file mode 100644 index fc923d7a7..000000000 --- a/vendor/golang.org/x/tools/go/buildutil/util.go +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package buildutil - -import ( - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "io" - "io/ioutil" - "os" - "path" - "path/filepath" - "strings" -) - -// ParseFile behaves like parser.ParseFile, -// but uses the build context's file system interface, if any. -// -// If file is not absolute (as defined by IsAbsPath), the (dir, file) -// components are joined using JoinPath; dir must be absolute. -// -// The displayPath function, if provided, is used to transform the -// filename that will be attached to the ASTs. -// -// TODO(adonovan): call this from go/loader.parseFiles when the tree thaws. -// -func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, file string, mode parser.Mode) (*ast.File, error) { - if !IsAbsPath(ctxt, file) { - file = JoinPath(ctxt, dir, file) - } - rd, err := OpenFile(ctxt, file) - if err != nil { - return nil, err - } - defer rd.Close() // ignore error - if displayPath != nil { - file = displayPath(file) - } - return parser.ParseFile(fset, file, rd, mode) -} - -// ContainingPackage returns the package containing filename. -// -// If filename is not absolute, it is interpreted relative to working directory dir. -// All I/O is via the build context's file system interface, if any. -// -// The '...Files []string' fields of the resulting build.Package are not -// populated (build.FindOnly mode). -// -func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Package, error) { - if !IsAbsPath(ctxt, filename) { - filename = JoinPath(ctxt, dir, filename) - } - - // We must not assume the file tree uses - // "/" always, - // `\` always, - // or os.PathSeparator (which varies by platform), - // but to make any progress, we are forced to assume that - // paths will not use `\` unless the PathSeparator - // is also `\`, thus we can rely on filepath.ToSlash for some sanity. - - dirSlash := path.Dir(filepath.ToSlash(filename)) + "/" - - // We assume that no source root (GOPATH[i] or GOROOT) contains any other. - for _, srcdir := range ctxt.SrcDirs() { - srcdirSlash := filepath.ToSlash(srcdir) + "/" - if importPath, ok := HasSubdir(ctxt, srcdirSlash, dirSlash); ok { - return ctxt.Import(importPath, dir, build.FindOnly) - } - } - - return nil, fmt.Errorf("can't find package containing %s", filename) -} - -// -- Effective methods of file system interface ------------------------- - -// (go/build.Context defines these as methods, but does not export them.) - -// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses -// the local file system to answer the question. -func HasSubdir(ctxt *build.Context, root, dir string) (rel string, ok bool) { - if f := ctxt.HasSubdir; f != nil { - return f(root, dir) - } - - // Try using paths we received. - if rel, ok = hasSubdir(root, dir); ok { - return - } - - // Try expanding symlinks and comparing - // expanded against unexpanded and - // expanded against expanded. - rootSym, _ := filepath.EvalSymlinks(root) - dirSym, _ := filepath.EvalSymlinks(dir) - - if rel, ok = hasSubdir(rootSym, dir); ok { - return - } - if rel, ok = hasSubdir(root, dirSym); ok { - return - } - return hasSubdir(rootSym, dirSym) -} - -func hasSubdir(root, dir string) (rel string, ok bool) { - const sep = string(filepath.Separator) - root = filepath.Clean(root) - if !strings.HasSuffix(root, sep) { - root += sep - } - - dir = filepath.Clean(dir) - if !strings.HasPrefix(dir, root) { - return "", false - } - - return filepath.ToSlash(dir[len(root):]), true -} - -// FileExists returns true if the specified file exists, -// using the build context's file system interface. -func FileExists(ctxt *build.Context, path string) bool { - if ctxt.OpenFile != nil { - r, err := ctxt.OpenFile(path) - if err != nil { - return false - } - r.Close() // ignore error - return true - } - _, err := os.Stat(path) - return err == nil -} - -// OpenFile behaves like os.Open, -// but uses the build context's file system interface, if any. -func OpenFile(ctxt *build.Context, path string) (io.ReadCloser, error) { - if ctxt.OpenFile != nil { - return ctxt.OpenFile(path) - } - return os.Open(path) -} - -// IsAbsPath behaves like filepath.IsAbs, -// but uses the build context's file system interface, if any. -func IsAbsPath(ctxt *build.Context, path string) bool { - if ctxt.IsAbsPath != nil { - return ctxt.IsAbsPath(path) - } - return filepath.IsAbs(path) -} - -// JoinPath behaves like filepath.Join, -// but uses the build context's file system interface, if any. -func JoinPath(ctxt *build.Context, path ...string) string { - if ctxt.JoinPath != nil { - return ctxt.JoinPath(path...) - } - return filepath.Join(path...) -} - -// IsDir behaves like os.Stat plus IsDir, -// but uses the build context's file system interface, if any. -func IsDir(ctxt *build.Context, path string) bool { - if ctxt.IsDir != nil { - return ctxt.IsDir(path) - } - fi, err := os.Stat(path) - return err == nil && fi.IsDir() -} - -// ReadDir behaves like ioutil.ReadDir, -// but uses the build context's file system interface, if any. -func ReadDir(ctxt *build.Context, path string) ([]os.FileInfo, error) { - if ctxt.ReadDir != nil { - return ctxt.ReadDir(path) - } - return ioutil.ReadDir(path) -} - -// SplitPathList behaves like filepath.SplitList, -// but uses the build context's file system interface, if any. -func SplitPathList(ctxt *build.Context, s string) []string { - if ctxt.SplitPathList != nil { - return ctxt.SplitPathList(s) - } - return filepath.SplitList(s) -} - -// sameFile returns true if x and y have the same basename and denote -// the same file. -// -func sameFile(x, y string) bool { - if path.Clean(x) == path.Clean(y) { - return true - } - if filepath.Base(x) == filepath.Base(y) { // (optimisation) - if xi, err := os.Stat(x); err == nil { - if yi, err := os.Stat(y); err == nil { - return os.SameFile(xi, yi) - } - } - } - return false -} diff --git a/vendor/golang.org/x/tools/go/internal/cgo/cgo.go b/vendor/golang.org/x/tools/go/internal/cgo/cgo.go deleted file mode 100644 index 5db8b3096..000000000 --- a/vendor/golang.org/x/tools/go/internal/cgo/cgo.go +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cgo handles cgo preprocessing of files containing `import "C"`. -// -// DESIGN -// -// The approach taken is to run the cgo processor on the package's -// CgoFiles and parse the output, faking the filenames of the -// resulting ASTs so that the synthetic file containing the C types is -// called "C" (e.g. "~/go/src/net/C") and the preprocessed files -// have their original names (e.g. "~/go/src/net/cgo_unix.go"), -// not the names of the actual temporary files. -// -// The advantage of this approach is its fidelity to 'go build'. The -// downside is that the token.Position.Offset for each AST node is -// incorrect, being an offset within the temporary file. Line numbers -// should still be correct because of the //line comments. -// -// The logic of this file is mostly plundered from the 'go build' -// tool, which also invokes the cgo preprocessor. -// -// -// REJECTED ALTERNATIVE -// -// An alternative approach that we explored is to extend go/types' -// Importer mechanism to provide the identity of the importing package -// so that each time `import "C"` appears it resolves to a different -// synthetic package containing just the objects needed in that case. -// The loader would invoke cgo but parse only the cgo_types.go file -// defining the package-level objects, discarding the other files -// resulting from preprocessing. -// -// The benefit of this approach would have been that source-level -// syntax information would correspond exactly to the original cgo -// file, with no preprocessing involved, making source tools like -// godoc, guru, and eg happy. However, the approach was rejected -// due to the additional complexity it would impose on go/types. (It -// made for a beautiful demo, though.) -// -// cgo files, despite their *.go extension, are not legal Go source -// files per the specification since they may refer to unexported -// members of package "C" such as C.int. Also, a function such as -// C.getpwent has in effect two types, one matching its C type and one -// which additionally returns (errno C.int). The cgo preprocessor -// uses name mangling to distinguish these two functions in the -// processed code, but go/types would need to duplicate this logic in -// its handling of function calls, analogous to the treatment of map -// lookups in which y=m[k] and y,ok=m[k] are both legal. - -package cgo - -import ( - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "io/ioutil" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" - "strings" -) - -// ProcessFiles invokes the cgo preprocessor on bp.CgoFiles, parses -// the output and returns the resulting ASTs. -// -func ProcessFiles(bp *build.Package, fset *token.FileSet, DisplayPath func(path string) string, mode parser.Mode) ([]*ast.File, error) { - tmpdir, err := ioutil.TempDir("", strings.Replace(bp.ImportPath, "/", "_", -1)+"_C") - if err != nil { - return nil, err - } - defer os.RemoveAll(tmpdir) - - pkgdir := bp.Dir - if DisplayPath != nil { - pkgdir = DisplayPath(pkgdir) - } - - cgoFiles, cgoDisplayFiles, err := Run(bp, pkgdir, tmpdir, false) - if err != nil { - return nil, err - } - var files []*ast.File - for i := range cgoFiles { - rd, err := os.Open(cgoFiles[i]) - if err != nil { - return nil, err - } - display := filepath.Join(bp.Dir, cgoDisplayFiles[i]) - f, err := parser.ParseFile(fset, display, rd, mode) - rd.Close() - if err != nil { - return nil, err - } - files = append(files, f) - } - return files, nil -} - -var cgoRe = regexp.MustCompile(`[/\\:]`) - -// Run invokes the cgo preprocessor on bp.CgoFiles and returns two -// lists of files: the resulting processed files (in temporary -// directory tmpdir) and the corresponding names of the unprocessed files. -// -// Run is adapted from (*builder).cgo in -// $GOROOT/src/cmd/go/build.go, but these features are unsupported: -// Objective C, CGOPKGPATH, CGO_FLAGS. -// -// If useabs is set to true, absolute paths of the bp.CgoFiles will be passed in -// to the cgo preprocessor. This in turn will set the // line comments -// referring to those files to use absolute paths. This is needed for -// go/packages using the legacy go list support so it is able to find -// the original files. -func Run(bp *build.Package, pkgdir, tmpdir string, useabs bool) (files, displayFiles []string, err error) { - cgoCPPFLAGS, _, _, _ := cflags(bp, true) - _, cgoexeCFLAGS, _, _ := cflags(bp, false) - - if len(bp.CgoPkgConfig) > 0 { - pcCFLAGS, err := pkgConfigFlags(bp) - if err != nil { - return nil, nil, err - } - cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) - } - - // Allows including _cgo_export.h from .[ch] files in the package. - cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", tmpdir) - - // _cgo_gotypes.go (displayed "C") contains the type definitions. - files = append(files, filepath.Join(tmpdir, "_cgo_gotypes.go")) - displayFiles = append(displayFiles, "C") - for _, fn := range bp.CgoFiles { - // "foo.cgo1.go" (displayed "foo.go") is the processed Go source. - f := cgoRe.ReplaceAllString(fn[:len(fn)-len("go")], "_") - files = append(files, filepath.Join(tmpdir, f+"cgo1.go")) - displayFiles = append(displayFiles, fn) - } - - var cgoflags []string - if bp.Goroot && bp.ImportPath == "runtime/cgo" { - cgoflags = append(cgoflags, "-import_runtime_cgo=false") - } - if bp.Goroot && bp.ImportPath == "runtime/race" || bp.ImportPath == "runtime/cgo" { - cgoflags = append(cgoflags, "-import_syscall=false") - } - - var cgoFiles []string = bp.CgoFiles - if useabs { - cgoFiles = make([]string, len(bp.CgoFiles)) - for i := range cgoFiles { - cgoFiles[i] = filepath.Join(pkgdir, bp.CgoFiles[i]) - } - } - - args := stringList( - "go", "tool", "cgo", "-objdir", tmpdir, cgoflags, "--", - cgoCPPFLAGS, cgoexeCFLAGS, cgoFiles, - ) - if false { - log.Printf("Running cgo for package %q: %s (dir=%s)", bp.ImportPath, args, pkgdir) - } - cmd := exec.Command(args[0], args[1:]...) - cmd.Dir = pkgdir - cmd.Stdout = os.Stderr - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - return nil, nil, fmt.Errorf("cgo failed: %s: %s", args, err) - } - - return files, displayFiles, nil -} - -// -- unmodified from 'go build' --------------------------------------- - -// Return the flags to use when invoking the C or C++ compilers, or cgo. -func cflags(p *build.Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) { - var defaults string - if def { - defaults = "-g -O2" - } - - cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS) - cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS) - cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS) - ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS) - return -} - -// envList returns the value of the given environment variable broken -// into fields, using the default value when the variable is empty. -func envList(key, def string) []string { - v := os.Getenv(key) - if v == "" { - v = def - } - return strings.Fields(v) -} - -// stringList's arguments should be a sequence of string or []string values. -// stringList flattens them into a single []string. -func stringList(args ...interface{}) []string { - var x []string - for _, arg := range args { - switch arg := arg.(type) { - case []string: - x = append(x, arg...) - case string: - x = append(x, arg) - default: - panic("stringList: invalid argument") - } - } - return x -} diff --git a/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go b/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go deleted file mode 100644 index b5bb95a63..000000000 --- a/vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cgo - -import ( - "errors" - "fmt" - "go/build" - "os/exec" - "strings" -) - -// pkgConfig runs pkg-config with the specified arguments and returns the flags it prints. -func pkgConfig(mode string, pkgs []string) (flags []string, err error) { - cmd := exec.Command("pkg-config", append([]string{mode}, pkgs...)...) - out, err := cmd.CombinedOutput() - if err != nil { - s := fmt.Sprintf("%s failed: %v", strings.Join(cmd.Args, " "), err) - if len(out) > 0 { - s = fmt.Sprintf("%s: %s", s, out) - } - return nil, errors.New(s) - } - if len(out) > 0 { - flags = strings.Fields(string(out)) - } - return -} - -// pkgConfigFlags calls pkg-config if needed and returns the cflags -// needed to build the package. -func pkgConfigFlags(p *build.Package) (cflags []string, err error) { - if len(p.CgoPkgConfig) == 0 { - return nil, nil - } - return pkgConfig("--cflags", p.CgoPkgConfig) -} diff --git a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go b/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go deleted file mode 100644 index dc6177c12..000000000 --- a/vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package packagesdriver fetches type sizes for go/packages and go/analysis. -package packagesdriver - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "go/types" - "os/exec" - "strings" - - "golang.org/x/tools/internal/gocommand" -) - -var debug = false - -func GetSizes(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) { - // TODO(matloob): Clean this up. This code is mostly a copy of packages.findExternalDriver. - const toolPrefix = "GOPACKAGESDRIVER=" - tool := "" - for _, env := range env { - if val := strings.TrimPrefix(env, toolPrefix); val != env { - tool = val - } - } - - if tool == "" { - var err error - tool, err = exec.LookPath("gopackagesdriver") - if err != nil { - // We did not find the driver, so use "go list". - tool = "off" - } - } - - if tool == "off" { - return GetSizesGolist(ctx, buildFlags, env, gocmdRunner, dir) - } - - req, err := json.Marshal(struct { - Command string `json:"command"` - Env []string `json:"env"` - BuildFlags []string `json:"build_flags"` - }{ - Command: "sizes", - Env: env, - BuildFlags: buildFlags, - }) - if err != nil { - return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) - } - - buf := new(bytes.Buffer) - cmd := exec.CommandContext(ctx, tool) - cmd.Dir = dir - cmd.Env = env - cmd.Stdin = bytes.NewReader(req) - cmd.Stdout = buf - cmd.Stderr = new(bytes.Buffer) - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) - } - var response struct { - // Sizes, if not nil, is the types.Sizes to use when type checking. - Sizes *types.StdSizes - } - if err := json.Unmarshal(buf.Bytes(), &response); err != nil { - return nil, err - } - return response.Sizes, nil -} - -func GetSizesGolist(ctx context.Context, buildFlags, env []string, gocmdRunner *gocommand.Runner, dir string) (types.Sizes, error) { - inv := gocommand.Invocation{ - Verb: "list", - Args: []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"}, - Env: env, - BuildFlags: buildFlags, - WorkingDir: dir, - } - stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) - var goarch, compiler string - if rawErr != nil { - if strings.Contains(rawErr.Error(), "cannot find main module") { - // User's running outside of a module. All bets are off. Get GOARCH and guess compiler is gc. - // TODO(matloob): Is this a problem in practice? - inv := gocommand.Invocation{ - Verb: "env", - Args: []string{"GOARCH"}, - Env: env, - WorkingDir: dir, - } - envout, enverr := gocmdRunner.Run(ctx, inv) - if enverr != nil { - return nil, enverr - } - goarch = strings.TrimSpace(envout.String()) - compiler = "gc" - } else { - return nil, friendlyErr - } - } else { - fields := strings.Fields(stdout.String()) - if len(fields) < 2 { - return nil, fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", - stdout.String(), stderr.String()) - } - goarch = fields[0] - compiler = fields[1] - } - return types.SizesFor(compiler, goarch), nil -} diff --git a/vendor/golang.org/x/tools/go/loader/doc.go b/vendor/golang.org/x/tools/go/loader/doc.go deleted file mode 100644 index c5aa31c1a..000000000 --- a/vendor/golang.org/x/tools/go/loader/doc.go +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package loader loads a complete Go program from source code, parsing -// and type-checking the initial packages plus their transitive closure -// of dependencies. The ASTs and the derived facts are retained for -// later use. -// -// Deprecated: This is an older API and does not have support -// for modules. Use golang.org/x/tools/go/packages instead. -// -// The package defines two primary types: Config, which specifies a -// set of initial packages to load and various other options; and -// Program, which is the result of successfully loading the packages -// specified by a configuration. -// -// The configuration can be set directly, but *Config provides various -// convenience methods to simplify the common cases, each of which can -// be called any number of times. Finally, these are followed by a -// call to Load() to actually load and type-check the program. -// -// var conf loader.Config -// -// // Use the command-line arguments to specify -// // a set of initial packages to load from source. -// // See FromArgsUsage for help. -// rest, err := conf.FromArgs(os.Args[1:], wantTests) -// -// // Parse the specified files and create an ad hoc package with path "foo". -// // All files must have the same 'package' declaration. -// conf.CreateFromFilenames("foo", "foo.go", "bar.go") -// -// // Create an ad hoc package with path "foo" from -// // the specified already-parsed files. -// // All ASTs must have the same 'package' declaration. -// conf.CreateFromFiles("foo", parsedFiles) -// -// // Add "runtime" to the set of packages to be loaded. -// conf.Import("runtime") -// -// // Adds "fmt" and "fmt_test" to the set of packages -// // to be loaded. "fmt" will include *_test.go files. -// conf.ImportWithTests("fmt") -// -// // Finally, load all the packages specified by the configuration. -// prog, err := conf.Load() -// -// See examples_test.go for examples of API usage. -// -// -// CONCEPTS AND TERMINOLOGY -// -// The WORKSPACE is the set of packages accessible to the loader. The -// workspace is defined by Config.Build, a *build.Context. The -// default context treats subdirectories of $GOROOT and $GOPATH as -// packages, but this behavior may be overridden. -// -// An AD HOC package is one specified as a set of source files on the -// command line. In the simplest case, it may consist of a single file -// such as $GOROOT/src/net/http/triv.go. -// -// EXTERNAL TEST packages are those comprised of a set of *_test.go -// files all with the same 'package foo_test' declaration, all in the -// same directory. (go/build.Package calls these files XTestFiles.) -// -// An IMPORTABLE package is one that can be referred to by some import -// spec. Every importable package is uniquely identified by its -// PACKAGE PATH or just PATH, a string such as "fmt", "encoding/json", -// or "cmd/vendor/golang.org/x/arch/x86/x86asm". A package path -// typically denotes a subdirectory of the workspace. -// -// An import declaration uses an IMPORT PATH to refer to a package. -// Most import declarations use the package path as the import path. -// -// Due to VENDORING (https://golang.org/s/go15vendor), the -// interpretation of an import path may depend on the directory in which -// it appears. To resolve an import path to a package path, go/build -// must search the enclosing directories for a subdirectory named -// "vendor". -// -// ad hoc packages and external test packages are NON-IMPORTABLE. The -// path of an ad hoc package is inferred from the package -// declarations of its files and is therefore not a unique package key. -// For example, Config.CreatePkgs may specify two initial ad hoc -// packages, both with path "main". -// -// An AUGMENTED package is an importable package P plus all the -// *_test.go files with same 'package foo' declaration as P. -// (go/build.Package calls these files TestFiles.) -// -// The INITIAL packages are those specified in the configuration. A -// DEPENDENCY is a package loaded to satisfy an import in an initial -// package or another dependency. -// -package loader - -// IMPLEMENTATION NOTES -// -// 'go test', in-package test files, and import cycles -// --------------------------------------------------- -// -// An external test package may depend upon members of the augmented -// package that are not in the unaugmented package, such as functions -// that expose internals. (See bufio/export_test.go for an example.) -// So, the loader must ensure that for each external test package -// it loads, it also augments the corresponding non-test package. -// -// The import graph over n unaugmented packages must be acyclic; the -// import graph over n-1 unaugmented packages plus one augmented -// package must also be acyclic. ('go test' relies on this.) But the -// import graph over n augmented packages may contain cycles. -// -// First, all the (unaugmented) non-test packages and their -// dependencies are imported in the usual way; the loader reports an -// error if it detects an import cycle. -// -// Then, each package P for which testing is desired is augmented by -// the list P' of its in-package test files, by calling -// (*types.Checker).Files. This arrangement ensures that P' may -// reference definitions within P, but P may not reference definitions -// within P'. Furthermore, P' may import any other package, including -// ones that depend upon P, without an import cycle error. -// -// Consider two packages A and B, both of which have lists of -// in-package test files we'll call A' and B', and which have the -// following import graph edges: -// B imports A -// B' imports A -// A' imports B -// This last edge would be expected to create an error were it not -// for the special type-checking discipline above. -// Cycles of size greater than two are possible. For example: -// compress/bzip2/bzip2_test.go (package bzip2) imports "io/ioutil" -// io/ioutil/tempfile_test.go (package ioutil) imports "regexp" -// regexp/exec_test.go (package regexp) imports "compress/bzip2" -// -// -// Concurrency -// ----------- -// -// Let us define the import dependency graph as follows. Each node is a -// list of files passed to (Checker).Files at once. Many of these lists -// are the production code of an importable Go package, so those nodes -// are labelled by the package's path. The remaining nodes are -// ad hoc packages and lists of in-package *_test.go files that augment -// an importable package; those nodes have no label. -// -// The edges of the graph represent import statements appearing within a -// file. An edge connects a node (a list of files) to the node it -// imports, which is importable and thus always labelled. -// -// Loading is controlled by this dependency graph. -// -// To reduce I/O latency, we start loading a package's dependencies -// asynchronously as soon as we've parsed its files and enumerated its -// imports (scanImports). This performs a preorder traversal of the -// import dependency graph. -// -// To exploit hardware parallelism, we type-check unrelated packages in -// parallel, where "unrelated" means not ordered by the partial order of -// the import dependency graph. -// -// We use a concurrency-safe non-blocking cache (importer.imported) to -// record the results of type-checking, whether success or failure. An -// entry is created in this cache by startLoad the first time the -// package is imported. The first goroutine to request an entry becomes -// responsible for completing the task and broadcasting completion to -// subsequent requestors, which block until then. -// -// Type checking occurs in (parallel) postorder: we cannot type-check a -// set of files until we have loaded and type-checked all of their -// immediate dependencies (and thus all of their transitive -// dependencies). If the input were guaranteed free of import cycles, -// this would be trivial: we could simply wait for completion of the -// dependencies and then invoke the typechecker. -// -// But as we saw in the 'go test' section above, some cycles in the -// import graph over packages are actually legal, so long as the -// cycle-forming edge originates in the in-package test files that -// augment the package. This explains why the nodes of the import -// dependency graph are not packages, but lists of files: the unlabelled -// nodes avoid the cycles. Consider packages A and B where B imports A -// and A's in-package tests AT import B. The naively constructed import -// graph over packages would contain a cycle (A+AT) --> B --> (A+AT) but -// the graph over lists of files is AT --> B --> A, where AT is an -// unlabelled node. -// -// Awaiting completion of the dependencies in a cyclic graph would -// deadlock, so we must materialize the import dependency graph (as -// importer.graph) and check whether each import edge forms a cycle. If -// x imports y, and the graph already contains a path from y to x, then -// there is an import cycle, in which case the processing of x must not -// wait for the completion of processing of y. -// -// When the type-checker makes a callback (doImport) to the loader for a -// given import edge, there are two possible cases. In the normal case, -// the dependency has already been completely type-checked; doImport -// does a cache lookup and returns it. In the cyclic case, the entry in -// the cache is still necessarily incomplete, indicating a cycle. We -// perform the cycle check again to obtain the error message, and return -// the error. -// -// The result of using concurrency is about a 2.5x speedup for stdlib_test. diff --git a/vendor/golang.org/x/tools/go/loader/loader.go b/vendor/golang.org/x/tools/go/loader/loader.go deleted file mode 100644 index bc12ca33d..000000000 --- a/vendor/golang.org/x/tools/go/loader/loader.go +++ /dev/null @@ -1,1086 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package loader - -// See doc.go for package documentation and implementation notes. - -import ( - "errors" - "fmt" - "go/ast" - "go/build" - "go/parser" - "go/token" - "go/types" - "os" - "path/filepath" - "sort" - "strings" - "sync" - "time" - - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/go/internal/cgo" -) - -var ignoreVendor build.ImportMode - -const trace = false // show timing info for type-checking - -// Config specifies the configuration for loading a whole program from -// Go source code. -// The zero value for Config is a ready-to-use default configuration. -type Config struct { - // Fset is the file set for the parser to use when loading the - // program. If nil, it may be lazily initialized by any - // method of Config. - Fset *token.FileSet - - // ParserMode specifies the mode to be used by the parser when - // loading source packages. - ParserMode parser.Mode - - // TypeChecker contains options relating to the type checker. - // - // The supplied IgnoreFuncBodies is not used; the effective - // value comes from the TypeCheckFuncBodies func below. - // The supplied Import function is not used either. - TypeChecker types.Config - - // TypeCheckFuncBodies is a predicate over package paths. - // A package for which the predicate is false will - // have its package-level declarations type checked, but not - // its function bodies; this can be used to quickly load - // dependencies from source. If nil, all func bodies are type - // checked. - TypeCheckFuncBodies func(path string) bool - - // If Build is non-nil, it is used to locate source packages. - // Otherwise &build.Default is used. - // - // By default, cgo is invoked to preprocess Go files that - // import the fake package "C". This behaviour can be - // disabled by setting CGO_ENABLED=0 in the environment prior - // to startup, or by setting Build.CgoEnabled=false. - Build *build.Context - - // The current directory, used for resolving relative package - // references such as "./go/loader". If empty, os.Getwd will be - // used instead. - Cwd string - - // If DisplayPath is non-nil, it is used to transform each - // file name obtained from Build.Import(). This can be used - // to prevent a virtualized build.Config's file names from - // leaking into the user interface. - DisplayPath func(path string) string - - // If AllowErrors is true, Load will return a Program even - // if some of the its packages contained I/O, parser or type - // errors; such errors are accessible via PackageInfo.Errors. If - // false, Load will fail if any package had an error. - AllowErrors bool - - // CreatePkgs specifies a list of non-importable initial - // packages to create. The resulting packages will appear in - // the corresponding elements of the Program.Created slice. - CreatePkgs []PkgSpec - - // ImportPkgs specifies a set of initial packages to load. - // The map keys are package paths. - // - // The map value indicates whether to load tests. If true, Load - // will add and type-check two lists of files to the package: - // non-test files followed by in-package *_test.go files. In - // addition, it will append the external test package (if any) - // to Program.Created. - ImportPkgs map[string]bool - - // FindPackage is called during Load to create the build.Package - // for a given import path from a given directory. - // If FindPackage is nil, (*build.Context).Import is used. - // A client may use this hook to adapt to a proprietary build - // system that does not follow the "go build" layout - // conventions, for example. - // - // It must be safe to call concurrently from multiple goroutines. - FindPackage func(ctxt *build.Context, importPath, fromDir string, mode build.ImportMode) (*build.Package, error) - - // AfterTypeCheck is called immediately after a list of files - // has been type-checked and appended to info.Files. - // - // This optional hook function is the earliest opportunity for - // the client to observe the output of the type checker, - // which may be useful to reduce analysis latency when loading - // a large program. - // - // The function is permitted to modify info.Info, for instance - // to clear data structures that are no longer needed, which can - // dramatically reduce peak memory consumption. - // - // The function may be called twice for the same PackageInfo: - // once for the files of the package and again for the - // in-package test files. - // - // It must be safe to call concurrently from multiple goroutines. - AfterTypeCheck func(info *PackageInfo, files []*ast.File) -} - -// A PkgSpec specifies a non-importable package to be created by Load. -// Files are processed first, but typically only one of Files and -// Filenames is provided. The path needn't be globally unique. -// -// For vendoring purposes, the package's directory is the one that -// contains the first file. -type PkgSpec struct { - Path string // package path ("" => use package declaration) - Files []*ast.File // ASTs of already-parsed files - Filenames []string // names of files to be parsed -} - -// A Program is a Go program loaded from source as specified by a Config. -type Program struct { - Fset *token.FileSet // the file set for this program - - // Created[i] contains the initial package whose ASTs or - // filenames were supplied by Config.CreatePkgs[i], followed by - // the external test package, if any, of each package in - // Config.ImportPkgs ordered by ImportPath. - // - // NOTE: these files must not import "C". Cgo preprocessing is - // only performed on imported packages, not ad hoc packages. - // - // TODO(adonovan): we need to copy and adapt the logic of - // goFilesPackage (from $GOROOT/src/cmd/go/build.go) and make - // Config.Import and Config.Create methods return the same kind - // of entity, essentially a build.Package. - // Perhaps we can even reuse that type directly. - Created []*PackageInfo - - // Imported contains the initially imported packages, - // as specified by Config.ImportPkgs. - Imported map[string]*PackageInfo - - // AllPackages contains the PackageInfo of every package - // encountered by Load: all initial packages and all - // dependencies, including incomplete ones. - AllPackages map[*types.Package]*PackageInfo - - // importMap is the canonical mapping of package paths to - // packages. It contains all Imported initial packages, but not - // Created ones, and all imported dependencies. - importMap map[string]*types.Package -} - -// PackageInfo holds the ASTs and facts derived by the type-checker -// for a single package. -// -// Not mutated once exposed via the API. -// -type PackageInfo struct { - Pkg *types.Package - Importable bool // true if 'import "Pkg.Path()"' would resolve to this - TransitivelyErrorFree bool // true if Pkg and all its dependencies are free of errors - Files []*ast.File // syntax trees for the package's files - Errors []error // non-nil if the package had errors - types.Info // type-checker deductions. - dir string // package directory - - checker *types.Checker // transient type-checker state - errorFunc func(error) -} - -func (info *PackageInfo) String() string { return info.Pkg.Path() } - -func (info *PackageInfo) appendError(err error) { - if info.errorFunc != nil { - info.errorFunc(err) - } else { - fmt.Fprintln(os.Stderr, err) - } - info.Errors = append(info.Errors, err) -} - -func (conf *Config) fset() *token.FileSet { - if conf.Fset == nil { - conf.Fset = token.NewFileSet() - } - return conf.Fset -} - -// ParseFile is a convenience function (intended for testing) that invokes -// the parser using the Config's FileSet, which is initialized if nil. -// -// src specifies the parser input as a string, []byte, or io.Reader, and -// filename is its apparent name. If src is nil, the contents of -// filename are read from the file system. -// -func (conf *Config) ParseFile(filename string, src interface{}) (*ast.File, error) { - // TODO(adonovan): use conf.build() etc like parseFiles does. - return parser.ParseFile(conf.fset(), filename, src, conf.ParserMode) -} - -// FromArgsUsage is a partial usage message that applications calling -// FromArgs may wish to include in their -help output. -const FromArgsUsage = ` - is a list of arguments denoting a set of initial packages. -It may take one of two forms: - -1. A list of *.go source files. - - All of the specified files are loaded, parsed and type-checked - as a single package. All the files must belong to the same directory. - -2. A list of import paths, each denoting a package. - - The package's directory is found relative to the $GOROOT and - $GOPATH using similar logic to 'go build', and the *.go files in - that directory are loaded, parsed and type-checked as a single - package. - - In addition, all *_test.go files in the directory are then loaded - and parsed. Those files whose package declaration equals that of - the non-*_test.go files are included in the primary package. Test - files whose package declaration ends with "_test" are type-checked - as another package, the 'external' test package, so that a single - import path may denote two packages. (Whether this behaviour is - enabled is tool-specific, and may depend on additional flags.) - -A '--' argument terminates the list of packages. -` - -// FromArgs interprets args as a set of initial packages to load from -// source and updates the configuration. It returns the list of -// unconsumed arguments. -// -// It is intended for use in command-line interfaces that require a -// set of initial packages to be specified; see FromArgsUsage message -// for details. -// -// Only superficial errors are reported at this stage; errors dependent -// on I/O are detected during Load. -// -func (conf *Config) FromArgs(args []string, xtest bool) ([]string, error) { - var rest []string - for i, arg := range args { - if arg == "--" { - rest = args[i+1:] - args = args[:i] - break // consume "--" and return the remaining args - } - } - - if len(args) > 0 && strings.HasSuffix(args[0], ".go") { - // Assume args is a list of a *.go files - // denoting a single ad hoc package. - for _, arg := range args { - if !strings.HasSuffix(arg, ".go") { - return nil, fmt.Errorf("named files must be .go files: %s", arg) - } - } - conf.CreateFromFilenames("", args...) - } else { - // Assume args are directories each denoting a - // package and (perhaps) an external test, iff xtest. - for _, arg := range args { - if xtest { - conf.ImportWithTests(arg) - } else { - conf.Import(arg) - } - } - } - - return rest, nil -} - -// CreateFromFilenames is a convenience function that adds -// a conf.CreatePkgs entry to create a package of the specified *.go -// files. -// -func (conf *Config) CreateFromFilenames(path string, filenames ...string) { - conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Filenames: filenames}) -} - -// CreateFromFiles is a convenience function that adds a conf.CreatePkgs -// entry to create package of the specified path and parsed files. -// -func (conf *Config) CreateFromFiles(path string, files ...*ast.File) { - conf.CreatePkgs = append(conf.CreatePkgs, PkgSpec{Path: path, Files: files}) -} - -// ImportWithTests is a convenience function that adds path to -// ImportPkgs, the set of initial source packages located relative to -// $GOPATH. The package will be augmented by any *_test.go files in -// its directory that contain a "package x" (not "package x_test") -// declaration. -// -// In addition, if any *_test.go files contain a "package x_test" -// declaration, an additional package comprising just those files will -// be added to CreatePkgs. -// -func (conf *Config) ImportWithTests(path string) { conf.addImport(path, true) } - -// Import is a convenience function that adds path to ImportPkgs, the -// set of initial packages that will be imported from source. -// -func (conf *Config) Import(path string) { conf.addImport(path, false) } - -func (conf *Config) addImport(path string, tests bool) { - if path == "C" { - return // ignore; not a real package - } - if conf.ImportPkgs == nil { - conf.ImportPkgs = make(map[string]bool) - } - conf.ImportPkgs[path] = conf.ImportPkgs[path] || tests -} - -// PathEnclosingInterval returns the PackageInfo and ast.Node that -// contain source interval [start, end), and all the node's ancestors -// up to the AST root. It searches all ast.Files of all packages in prog. -// exact is defined as for astutil.PathEnclosingInterval. -// -// The zero value is returned if not found. -// -func (prog *Program) PathEnclosingInterval(start, end token.Pos) (pkg *PackageInfo, path []ast.Node, exact bool) { - for _, info := range prog.AllPackages { - for _, f := range info.Files { - if f.Pos() == token.NoPos { - // This can happen if the parser saw - // too many errors and bailed out. - // (Use parser.AllErrors to prevent that.) - continue - } - if !tokenFileContainsPos(prog.Fset.File(f.Pos()), start) { - continue - } - if path, exact := astutil.PathEnclosingInterval(f, start, end); path != nil { - return info, path, exact - } - } - } - return nil, nil, false -} - -// InitialPackages returns a new slice containing the set of initial -// packages (Created + Imported) in unspecified order. -// -func (prog *Program) InitialPackages() []*PackageInfo { - infos := make([]*PackageInfo, 0, len(prog.Created)+len(prog.Imported)) - infos = append(infos, prog.Created...) - for _, info := range prog.Imported { - infos = append(infos, info) - } - return infos -} - -// Package returns the ASTs and results of type checking for the -// specified package. -func (prog *Program) Package(path string) *PackageInfo { - if info, ok := prog.AllPackages[prog.importMap[path]]; ok { - return info - } - for _, info := range prog.Created { - if path == info.Pkg.Path() { - return info - } - } - return nil -} - -// ---------- Implementation ---------- - -// importer holds the working state of the algorithm. -type importer struct { - conf *Config // the client configuration - start time.Time // for logging - - progMu sync.Mutex // guards prog - prog *Program // the resulting program - - // findpkg is a memoization of FindPackage. - findpkgMu sync.Mutex // guards findpkg - findpkg map[findpkgKey]*findpkgValue - - importedMu sync.Mutex // guards imported - imported map[string]*importInfo // all imported packages (incl. failures) by import path - - // import dependency graph: graph[x][y] => x imports y - // - // Since non-importable packages cannot be cyclic, we ignore - // their imports, thus we only need the subgraph over importable - // packages. Nodes are identified by their import paths. - graphMu sync.Mutex - graph map[string]map[string]bool -} - -type findpkgKey struct { - importPath string - fromDir string - mode build.ImportMode -} - -type findpkgValue struct { - ready chan struct{} // closed to broadcast readiness - bp *build.Package - err error -} - -// importInfo tracks the success or failure of a single import. -// -// Upon completion, exactly one of info and err is non-nil: -// info on successful creation of a package, err otherwise. -// A successful package may still contain type errors. -// -type importInfo struct { - path string // import path - info *PackageInfo // results of typechecking (including errors) - complete chan struct{} // closed to broadcast that info is set. -} - -// awaitCompletion blocks until ii is complete, -// i.e. the info field is safe to inspect. -func (ii *importInfo) awaitCompletion() { - <-ii.complete // wait for close -} - -// Complete marks ii as complete. -// Its info and err fields will not be subsequently updated. -func (ii *importInfo) Complete(info *PackageInfo) { - if info == nil { - panic("info == nil") - } - ii.info = info - close(ii.complete) -} - -type importError struct { - path string // import path - err error // reason for failure to create a package -} - -// Load creates the initial packages specified by conf.{Create,Import}Pkgs, -// loading their dependencies packages as needed. -// -// On success, Load returns a Program containing a PackageInfo for -// each package. On failure, it returns an error. -// -// If AllowErrors is true, Load will return a Program even if some -// packages contained I/O, parser or type errors, or if dependencies -// were missing. (Such errors are accessible via PackageInfo.Errors. If -// false, Load will fail if any package had an error. -// -// It is an error if no packages were loaded. -// -func (conf *Config) Load() (*Program, error) { - // Create a simple default error handler for parse/type errors. - if conf.TypeChecker.Error == nil { - conf.TypeChecker.Error = func(e error) { fmt.Fprintln(os.Stderr, e) } - } - - // Set default working directory for relative package references. - if conf.Cwd == "" { - var err error - conf.Cwd, err = os.Getwd() - if err != nil { - return nil, err - } - } - - // Install default FindPackage hook using go/build logic. - if conf.FindPackage == nil { - conf.FindPackage = (*build.Context).Import - } - - prog := &Program{ - Fset: conf.fset(), - Imported: make(map[string]*PackageInfo), - importMap: make(map[string]*types.Package), - AllPackages: make(map[*types.Package]*PackageInfo), - } - - imp := importer{ - conf: conf, - prog: prog, - findpkg: make(map[findpkgKey]*findpkgValue), - imported: make(map[string]*importInfo), - start: time.Now(), - graph: make(map[string]map[string]bool), - } - - // -- loading proper (concurrent phase) -------------------------------- - - var errpkgs []string // packages that contained errors - - // Load the initially imported packages and their dependencies, - // in parallel. - // No vendor check on packages imported from the command line. - infos, importErrors := imp.importAll("", conf.Cwd, conf.ImportPkgs, ignoreVendor) - for _, ie := range importErrors { - conf.TypeChecker.Error(ie.err) // failed to create package - errpkgs = append(errpkgs, ie.path) - } - for _, info := range infos { - prog.Imported[info.Pkg.Path()] = info - } - - // Augment the designated initial packages by their tests. - // Dependencies are loaded in parallel. - var xtestPkgs []*build.Package - for importPath, augment := range conf.ImportPkgs { - if !augment { - continue - } - - // No vendor check on packages imported from command line. - bp, err := imp.findPackage(importPath, conf.Cwd, ignoreVendor) - if err != nil { - // Package not found, or can't even parse package declaration. - // Already reported by previous loop; ignore it. - continue - } - - // Needs external test package? - if len(bp.XTestGoFiles) > 0 { - xtestPkgs = append(xtestPkgs, bp) - } - - // Consult the cache using the canonical package path. - path := bp.ImportPath - imp.importedMu.Lock() // (unnecessary, we're sequential here) - ii, ok := imp.imported[path] - // Paranoid checks added due to issue #11012. - if !ok { - // Unreachable. - // The previous loop called importAll and thus - // startLoad for each path in ImportPkgs, which - // populates imp.imported[path] with a non-zero value. - panic(fmt.Sprintf("imported[%q] not found", path)) - } - if ii == nil { - // Unreachable. - // The ii values in this loop are the same as in - // the previous loop, which enforced the invariant - // that at least one of ii.err and ii.info is non-nil. - panic(fmt.Sprintf("imported[%q] == nil", path)) - } - if ii.info == nil { - // Unreachable. - // awaitCompletion has the postcondition - // ii.info != nil. - panic(fmt.Sprintf("imported[%q].info = nil", path)) - } - info := ii.info - imp.importedMu.Unlock() - - // Parse the in-package test files. - files, errs := imp.conf.parsePackageFiles(bp, 't') - for _, err := range errs { - info.appendError(err) - } - - // The test files augmenting package P cannot be imported, - // but may import packages that import P, - // so we must disable the cycle check. - imp.addFiles(info, files, false) - } - - createPkg := func(path, dir string, files []*ast.File, errs []error) { - info := imp.newPackageInfo(path, dir) - for _, err := range errs { - info.appendError(err) - } - - // Ad hoc packages are non-importable, - // so no cycle check is needed. - // addFiles loads dependencies in parallel. - imp.addFiles(info, files, false) - prog.Created = append(prog.Created, info) - } - - // Create packages specified by conf.CreatePkgs. - for _, cp := range conf.CreatePkgs { - files, errs := parseFiles(conf.fset(), conf.build(), nil, conf.Cwd, cp.Filenames, conf.ParserMode) - files = append(files, cp.Files...) - - path := cp.Path - if path == "" { - if len(files) > 0 { - path = files[0].Name.Name - } else { - path = "(unnamed)" - } - } - - dir := conf.Cwd - if len(files) > 0 && files[0].Pos().IsValid() { - dir = filepath.Dir(conf.fset().File(files[0].Pos()).Name()) - } - createPkg(path, dir, files, errs) - } - - // Create external test packages. - sort.Sort(byImportPath(xtestPkgs)) - for _, bp := range xtestPkgs { - files, errs := imp.conf.parsePackageFiles(bp, 'x') - createPkg(bp.ImportPath+"_test", bp.Dir, files, errs) - } - - // -- finishing up (sequential) ---------------------------------------- - - if len(prog.Imported)+len(prog.Created) == 0 { - return nil, errors.New("no initial packages were loaded") - } - - // Create infos for indirectly imported packages. - // e.g. incomplete packages without syntax, loaded from export data. - for _, obj := range prog.importMap { - info := prog.AllPackages[obj] - if info == nil { - prog.AllPackages[obj] = &PackageInfo{Pkg: obj, Importable: true} - } else { - // finished - info.checker = nil - info.errorFunc = nil - } - } - - if !conf.AllowErrors { - // Report errors in indirectly imported packages. - for _, info := range prog.AllPackages { - if len(info.Errors) > 0 { - errpkgs = append(errpkgs, info.Pkg.Path()) - } - } - if errpkgs != nil { - var more string - if len(errpkgs) > 3 { - more = fmt.Sprintf(" and %d more", len(errpkgs)-3) - errpkgs = errpkgs[:3] - } - return nil, fmt.Errorf("couldn't load packages due to errors: %s%s", - strings.Join(errpkgs, ", "), more) - } - } - - markErrorFreePackages(prog.AllPackages) - - return prog, nil -} - -type byImportPath []*build.Package - -func (b byImportPath) Len() int { return len(b) } -func (b byImportPath) Less(i, j int) bool { return b[i].ImportPath < b[j].ImportPath } -func (b byImportPath) Swap(i, j int) { b[i], b[j] = b[j], b[i] } - -// markErrorFreePackages sets the TransitivelyErrorFree flag on all -// applicable packages. -func markErrorFreePackages(allPackages map[*types.Package]*PackageInfo) { - // Build the transpose of the import graph. - importedBy := make(map[*types.Package]map[*types.Package]bool) - for P := range allPackages { - for _, Q := range P.Imports() { - clients, ok := importedBy[Q] - if !ok { - clients = make(map[*types.Package]bool) - importedBy[Q] = clients - } - clients[P] = true - } - } - - // Find all packages reachable from some error package. - reachable := make(map[*types.Package]bool) - var visit func(*types.Package) - visit = func(p *types.Package) { - if !reachable[p] { - reachable[p] = true - for q := range importedBy[p] { - visit(q) - } - } - } - for _, info := range allPackages { - if len(info.Errors) > 0 { - visit(info.Pkg) - } - } - - // Mark the others as "transitively error-free". - for _, info := range allPackages { - if !reachable[info.Pkg] { - info.TransitivelyErrorFree = true - } - } -} - -// build returns the effective build context. -func (conf *Config) build() *build.Context { - if conf.Build != nil { - return conf.Build - } - return &build.Default -} - -// parsePackageFiles enumerates the files belonging to package path, -// then loads, parses and returns them, plus a list of I/O or parse -// errors that were encountered. -// -// 'which' indicates which files to include: -// 'g': include non-test *.go source files (GoFiles + processed CgoFiles) -// 't': include in-package *_test.go source files (TestGoFiles) -// 'x': include external *_test.go source files. (XTestGoFiles) -// -func (conf *Config) parsePackageFiles(bp *build.Package, which rune) ([]*ast.File, []error) { - if bp.ImportPath == "unsafe" { - return nil, nil - } - var filenames []string - switch which { - case 'g': - filenames = bp.GoFiles - case 't': - filenames = bp.TestGoFiles - case 'x': - filenames = bp.XTestGoFiles - default: - panic(which) - } - - files, errs := parseFiles(conf.fset(), conf.build(), conf.DisplayPath, bp.Dir, filenames, conf.ParserMode) - - // Preprocess CgoFiles and parse the outputs (sequentially). - if which == 'g' && bp.CgoFiles != nil { - cgofiles, err := cgo.ProcessFiles(bp, conf.fset(), conf.DisplayPath, conf.ParserMode) - if err != nil { - errs = append(errs, err) - } else { - files = append(files, cgofiles...) - } - } - - return files, errs -} - -// doImport imports the package denoted by path. -// It implements the types.Importer signature. -// -// It returns an error if a package could not be created -// (e.g. go/build or parse error), but type errors are reported via -// the types.Config.Error callback (the first of which is also saved -// in the package's PackageInfo). -// -// Idempotent. -// -func (imp *importer) doImport(from *PackageInfo, to string) (*types.Package, error) { - if to == "C" { - // This should be unreachable, but ad hoc packages are - // not currently subject to cgo preprocessing. - // See https://golang.org/issue/11627. - return nil, fmt.Errorf(`the loader doesn't cgo-process ad hoc packages like %q; see Go issue 11627`, - from.Pkg.Path()) - } - - bp, err := imp.findPackage(to, from.dir, 0) - if err != nil { - return nil, err - } - - // The standard unsafe package is handled specially, - // and has no PackageInfo. - if bp.ImportPath == "unsafe" { - return types.Unsafe, nil - } - - // Look for the package in the cache using its canonical path. - path := bp.ImportPath - imp.importedMu.Lock() - ii := imp.imported[path] - imp.importedMu.Unlock() - if ii == nil { - panic("internal error: unexpected import: " + path) - } - if ii.info != nil { - return ii.info.Pkg, nil - } - - // Import of incomplete package: this indicates a cycle. - fromPath := from.Pkg.Path() - if cycle := imp.findPath(path, fromPath); cycle != nil { - // Normalize cycle: start from alphabetically largest node. - pos, start := -1, "" - for i, s := range cycle { - if pos < 0 || s > start { - pos, start = i, s - } - } - cycle = append(cycle, cycle[:pos]...)[pos:] // rotate cycle to start from largest - cycle = append(cycle, cycle[0]) // add start node to end to show cycliness - return nil, fmt.Errorf("import cycle: %s", strings.Join(cycle, " -> ")) - } - - panic("internal error: import of incomplete (yet acyclic) package: " + fromPath) -} - -// findPackage locates the package denoted by the importPath in the -// specified directory. -func (imp *importer) findPackage(importPath, fromDir string, mode build.ImportMode) (*build.Package, error) { - // We use a non-blocking duplicate-suppressing cache (gopl.io §9.7) - // to avoid holding the lock around FindPackage. - key := findpkgKey{importPath, fromDir, mode} - imp.findpkgMu.Lock() - v, ok := imp.findpkg[key] - if ok { - // cache hit - imp.findpkgMu.Unlock() - - <-v.ready // wait for entry to become ready - } else { - // Cache miss: this goroutine becomes responsible for - // populating the map entry and broadcasting its readiness. - v = &findpkgValue{ready: make(chan struct{})} - imp.findpkg[key] = v - imp.findpkgMu.Unlock() - - ioLimit <- true - v.bp, v.err = imp.conf.FindPackage(imp.conf.build(), importPath, fromDir, mode) - <-ioLimit - - if _, ok := v.err.(*build.NoGoError); ok { - v.err = nil // empty directory is not an error - } - - close(v.ready) // broadcast ready condition - } - return v.bp, v.err -} - -// importAll loads, parses, and type-checks the specified packages in -// parallel and returns their completed importInfos in unspecified order. -// -// fromPath is the package path of the importing package, if it is -// importable, "" otherwise. It is used for cycle detection. -// -// fromDir is the directory containing the import declaration that -// caused these imports. -// -func (imp *importer) importAll(fromPath, fromDir string, imports map[string]bool, mode build.ImportMode) (infos []*PackageInfo, errors []importError) { - // TODO(adonovan): opt: do the loop in parallel once - // findPackage is non-blocking. - var pending []*importInfo - for importPath := range imports { - bp, err := imp.findPackage(importPath, fromDir, mode) - if err != nil { - errors = append(errors, importError{ - path: importPath, - err: err, - }) - continue - } - pending = append(pending, imp.startLoad(bp)) - } - - if fromPath != "" { - // We're loading a set of imports. - // - // We must record graph edges from the importing package - // to its dependencies, and check for cycles. - imp.graphMu.Lock() - deps, ok := imp.graph[fromPath] - if !ok { - deps = make(map[string]bool) - imp.graph[fromPath] = deps - } - for _, ii := range pending { - deps[ii.path] = true - } - imp.graphMu.Unlock() - } - - for _, ii := range pending { - if fromPath != "" { - if cycle := imp.findPath(ii.path, fromPath); cycle != nil { - // Cycle-forming import: we must not await its - // completion since it would deadlock. - // - // We don't record the error in ii since - // the error is really associated with the - // cycle-forming edge, not the package itself. - // (Also it would complicate the - // invariants of importPath completion.) - if trace { - fmt.Fprintf(os.Stderr, "import cycle: %q\n", cycle) - } - continue - } - } - ii.awaitCompletion() - infos = append(infos, ii.info) - } - - return infos, errors -} - -// findPath returns an arbitrary path from 'from' to 'to' in the import -// graph, or nil if there was none. -func (imp *importer) findPath(from, to string) []string { - imp.graphMu.Lock() - defer imp.graphMu.Unlock() - - seen := make(map[string]bool) - var search func(stack []string, importPath string) []string - search = func(stack []string, importPath string) []string { - if !seen[importPath] { - seen[importPath] = true - stack = append(stack, importPath) - if importPath == to { - return stack - } - for x := range imp.graph[importPath] { - if p := search(stack, x); p != nil { - return p - } - } - } - return nil - } - return search(make([]string, 0, 20), from) -} - -// startLoad initiates the loading, parsing and type-checking of the -// specified package and its dependencies, if it has not already begun. -// -// It returns an importInfo, not necessarily in a completed state. The -// caller must call awaitCompletion() before accessing its info field. -// -// startLoad is concurrency-safe and idempotent. -// -func (imp *importer) startLoad(bp *build.Package) *importInfo { - path := bp.ImportPath - imp.importedMu.Lock() - ii, ok := imp.imported[path] - if !ok { - ii = &importInfo{path: path, complete: make(chan struct{})} - imp.imported[path] = ii - go func() { - info := imp.load(bp) - ii.Complete(info) - }() - } - imp.importedMu.Unlock() - - return ii -} - -// load implements package loading by parsing Go source files -// located by go/build. -func (imp *importer) load(bp *build.Package) *PackageInfo { - info := imp.newPackageInfo(bp.ImportPath, bp.Dir) - info.Importable = true - files, errs := imp.conf.parsePackageFiles(bp, 'g') - for _, err := range errs { - info.appendError(err) - } - - imp.addFiles(info, files, true) - - imp.progMu.Lock() - imp.prog.importMap[bp.ImportPath] = info.Pkg - imp.progMu.Unlock() - - return info -} - -// addFiles adds and type-checks the specified files to info, loading -// their dependencies if needed. The order of files determines the -// package initialization order. It may be called multiple times on the -// same package. Errors are appended to the info.Errors field. -// -// cycleCheck determines whether the imports within files create -// dependency edges that should be checked for potential cycles. -// -func (imp *importer) addFiles(info *PackageInfo, files []*ast.File, cycleCheck bool) { - // Ensure the dependencies are loaded, in parallel. - var fromPath string - if cycleCheck { - fromPath = info.Pkg.Path() - } - // TODO(adonovan): opt: make the caller do scanImports. - // Callers with a build.Package can skip it. - imp.importAll(fromPath, info.dir, scanImports(files), 0) - - if trace { - fmt.Fprintf(os.Stderr, "%s: start %q (%d)\n", - time.Since(imp.start), info.Pkg.Path(), len(files)) - } - - // Don't call checker.Files on Unsafe, even with zero files, - // because it would mutate the package, which is a global. - if info.Pkg == types.Unsafe { - if len(files) > 0 { - panic(`"unsafe" package contains unexpected files`) - } - } else { - // Ignore the returned (first) error since we - // already collect them all in the PackageInfo. - info.checker.Files(files) - info.Files = append(info.Files, files...) - } - - if imp.conf.AfterTypeCheck != nil { - imp.conf.AfterTypeCheck(info, files) - } - - if trace { - fmt.Fprintf(os.Stderr, "%s: stop %q\n", - time.Since(imp.start), info.Pkg.Path()) - } -} - -func (imp *importer) newPackageInfo(path, dir string) *PackageInfo { - var pkg *types.Package - if path == "unsafe" { - pkg = types.Unsafe - } else { - pkg = types.NewPackage(path, "") - } - info := &PackageInfo{ - Pkg: pkg, - Info: types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - }, - errorFunc: imp.conf.TypeChecker.Error, - dir: dir, - } - - // Copy the types.Config so we can vary it across PackageInfos. - tc := imp.conf.TypeChecker - tc.IgnoreFuncBodies = false - if f := imp.conf.TypeCheckFuncBodies; f != nil { - tc.IgnoreFuncBodies = !f(path) - } - tc.Importer = closure{imp, info} - tc.Error = info.appendError // appendError wraps the user's Error function - - info.checker = types.NewChecker(&tc, imp.conf.fset(), pkg, &info.Info) - imp.progMu.Lock() - imp.prog.AllPackages[pkg] = info - imp.progMu.Unlock() - return info -} - -type closure struct { - imp *importer - info *PackageInfo -} - -func (c closure) Import(to string) (*types.Package, error) { return c.imp.doImport(c.info, to) } diff --git a/vendor/golang.org/x/tools/go/loader/util.go b/vendor/golang.org/x/tools/go/loader/util.go deleted file mode 100644 index 7f38dd740..000000000 --- a/vendor/golang.org/x/tools/go/loader/util.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package loader - -import ( - "go/ast" - "go/build" - "go/parser" - "go/token" - "io" - "os" - "strconv" - "sync" - - "golang.org/x/tools/go/buildutil" -) - -// We use a counting semaphore to limit -// the number of parallel I/O calls per process. -var ioLimit = make(chan bool, 10) - -// parseFiles parses the Go source files within directory dir and -// returns the ASTs of the ones that could be at least partially parsed, -// along with a list of I/O and parse errors encountered. -// -// I/O is done via ctxt, which may specify a virtual file system. -// displayPath is used to transform the filenames attached to the ASTs. -// -func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, []error) { - if displayPath == nil { - displayPath = func(path string) string { return path } - } - var wg sync.WaitGroup - n := len(files) - parsed := make([]*ast.File, n) - errors := make([]error, n) - for i, file := range files { - if !buildutil.IsAbsPath(ctxt, file) { - file = buildutil.JoinPath(ctxt, dir, file) - } - wg.Add(1) - go func(i int, file string) { - ioLimit <- true // wait - defer func() { - wg.Done() - <-ioLimit // signal - }() - var rd io.ReadCloser - var err error - if ctxt.OpenFile != nil { - rd, err = ctxt.OpenFile(file) - } else { - rd, err = os.Open(file) - } - if err != nil { - errors[i] = err // open failed - return - } - - // ParseFile may return both an AST and an error. - parsed[i], errors[i] = parser.ParseFile(fset, displayPath(file), rd, mode) - rd.Close() - }(i, file) - } - wg.Wait() - - // Eliminate nils, preserving order. - var o int - for _, f := range parsed { - if f != nil { - parsed[o] = f - o++ - } - } - parsed = parsed[:o] - - o = 0 - for _, err := range errors { - if err != nil { - errors[o] = err - o++ - } - } - errors = errors[:o] - - return parsed, errors -} - -// scanImports returns the set of all import paths from all -// import specs in the specified files. -func scanImports(files []*ast.File) map[string]bool { - imports := make(map[string]bool) - for _, f := range files { - for _, decl := range f.Decls { - if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.IMPORT { - for _, spec := range decl.Specs { - spec := spec.(*ast.ImportSpec) - - // NB: do not assume the program is well-formed! - path, err := strconv.Unquote(spec.Path.Value) - if err != nil { - continue // quietly ignore the error - } - if path == "C" { - continue // skip pseudopackage - } - imports[path] = true - } - } - } - } - return imports -} - -// ---------- Internal helpers ---------- - -// TODO(adonovan): make this a method: func (*token.File) Contains(token.Pos) -func tokenFileContainsPos(f *token.File, pos token.Pos) bool { - p := int(pos) - base := f.Base() - return base <= p && p < base+f.Size() -} diff --git a/vendor/golang.org/x/tools/go/packages/doc.go b/vendor/golang.org/x/tools/go/packages/doc.go deleted file mode 100644 index 4bfe28a51..000000000 --- a/vendor/golang.org/x/tools/go/packages/doc.go +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* -Package packages loads Go packages for inspection and analysis. - -The Load function takes as input a list of patterns and return a list of Package -structs describing individual packages matched by those patterns. -The LoadMode controls the amount of detail in the loaded packages. - -Load passes most patterns directly to the underlying build tool, -but all patterns with the prefix "query=", where query is a -non-empty string of letters from [a-z], are reserved and may be -interpreted as query operators. - -Two query operators are currently supported: "file" and "pattern". - -The query "file=path/to/file.go" matches the package or packages enclosing -the Go source file path/to/file.go. For example "file=~/go/src/fmt/print.go" -might return the packages "fmt" and "fmt [fmt.test]". - -The query "pattern=string" causes "string" to be passed directly to -the underlying build tool. In most cases this is unnecessary, -but an application can use Load("pattern=" + x) as an escaping mechanism -to ensure that x is not interpreted as a query operator if it contains '='. - -All other query operators are reserved for future use and currently -cause Load to report an error. - -The Package struct provides basic information about the package, including - - - ID, a unique identifier for the package in the returned set; - - GoFiles, the names of the package's Go source files; - - Imports, a map from source import strings to the Packages they name; - - Types, the type information for the package's exported symbols; - - Syntax, the parsed syntax trees for the package's source code; and - - TypeInfo, the result of a complete type-check of the package syntax trees. - -(See the documentation for type Package for the complete list of fields -and more detailed descriptions.) - -For example, - - Load(nil, "bytes", "unicode...") - -returns four Package structs describing the standard library packages -bytes, unicode, unicode/utf16, and unicode/utf8. Note that one pattern -can match multiple packages and that a package might be matched by -multiple patterns: in general it is not possible to determine which -packages correspond to which patterns. - -Note that the list returned by Load contains only the packages matched -by the patterns. Their dependencies can be found by walking the import -graph using the Imports fields. - -The Load function can be configured by passing a pointer to a Config as -the first argument. A nil Config is equivalent to the zero Config, which -causes Load to run in LoadFiles mode, collecting minimal information. -See the documentation for type Config for details. - -As noted earlier, the Config.Mode controls the amount of detail -reported about the loaded packages. See the documentation for type LoadMode -for details. - -Most tools should pass their command-line arguments (after any flags) -uninterpreted to the loader, so that the loader can interpret them -according to the conventions of the underlying build system. -See the Example function for typical usage. - -*/ -package packages // import "golang.org/x/tools/go/packages" - -/* - -Motivation and design considerations - -The new package's design solves problems addressed by two existing -packages: go/build, which locates and describes packages, and -golang.org/x/tools/go/loader, which loads, parses and type-checks them. -The go/build.Package structure encodes too much of the 'go build' way -of organizing projects, leaving us in need of a data type that describes a -package of Go source code independent of the underlying build system. -We wanted something that works equally well with go build and vgo, and -also other build systems such as Bazel and Blaze, making it possible to -construct analysis tools that work in all these environments. -Tools such as errcheck and staticcheck were essentially unavailable to -the Go community at Google, and some of Google's internal tools for Go -are unavailable externally. -This new package provides a uniform way to obtain package metadata by -querying each of these build systems, optionally supporting their -preferred command-line notations for packages, so that tools integrate -neatly with users' build environments. The Metadata query function -executes an external query tool appropriate to the current workspace. - -Loading packages always returns the complete import graph "all the way down", -even if all you want is information about a single package, because the query -mechanisms of all the build systems we currently support ({go,vgo} list, and -blaze/bazel aspect-based query) cannot provide detailed information -about one package without visiting all its dependencies too, so there is -no additional asymptotic cost to providing transitive information. -(This property might not be true of a hypothetical 5th build system.) - -In calls to TypeCheck, all initial packages, and any package that -transitively depends on one of them, must be loaded from source. -Consider A->B->C->D->E: if A,C are initial, A,B,C must be loaded from -source; D may be loaded from export data, and E may not be loaded at all -(though it's possible that D's export data mentions it, so a -types.Package may be created for it and exposed.) - -The old loader had a feature to suppress type-checking of function -bodies on a per-package basis, primarily intended to reduce the work of -obtaining type information for imported packages. Now that imports are -satisfied by export data, the optimization no longer seems necessary. - -Despite some early attempts, the old loader did not exploit export data, -instead always using the equivalent of WholeProgram mode. This was due -to the complexity of mixing source and export data packages (now -resolved by the upward traversal mentioned above), and because export data -files were nearly always missing or stale. Now that 'go build' supports -caching, all the underlying build systems can guarantee to produce -export data in a reasonable (amortized) time. - -Test "main" packages synthesized by the build system are now reported as -first-class packages, avoiding the need for clients (such as go/ssa) to -reinvent this generation logic. - -One way in which go/packages is simpler than the old loader is in its -treatment of in-package tests. In-package tests are packages that -consist of all the files of the library under test, plus the test files. -The old loader constructed in-package tests by a two-phase process of -mutation called "augmentation": first it would construct and type check -all the ordinary library packages and type-check the packages that -depend on them; then it would add more (test) files to the package and -type-check again. This two-phase approach had four major problems: -1) in processing the tests, the loader modified the library package, - leaving no way for a client application to see both the test - package and the library package; one would mutate into the other. -2) because test files can declare additional methods on types defined in - the library portion of the package, the dispatch of method calls in - the library portion was affected by the presence of the test files. - This should have been a clue that the packages were logically - different. -3) this model of "augmentation" assumed at most one in-package test - per library package, which is true of projects using 'go build', - but not other build systems. -4) because of the two-phase nature of test processing, all packages that - import the library package had to be processed before augmentation, - forcing a "one-shot" API and preventing the client from calling Load - in several times in sequence as is now possible in WholeProgram mode. - (TypeCheck mode has a similar one-shot restriction for a different reason.) - -Early drafts of this package supported "multi-shot" operation. -Although it allowed clients to make a sequence of calls (or concurrent -calls) to Load, building up the graph of Packages incrementally, -it was of marginal value: it complicated the API -(since it allowed some options to vary across calls but not others), -it complicated the implementation, -it cannot be made to work in Types mode, as explained above, -and it was less efficient than making one combined call (when this is possible). -Among the clients we have inspected, none made multiple calls to load -but could not be easily and satisfactorily modified to make only a single call. -However, applications changes may be required. -For example, the ssadump command loads the user-specified packages -and in addition the runtime package. It is tempting to simply append -"runtime" to the user-provided list, but that does not work if the user -specified an ad-hoc package such as [a.go b.go]. -Instead, ssadump no longer requests the runtime package, -but seeks it among the dependencies of the user-specified packages, -and emits an error if it is not found. - -Overlays: The Overlay field in the Config allows providing alternate contents -for Go source files, by providing a mapping from file path to contents. -go/packages will pull in new imports added in overlay files when go/packages -is run in LoadImports mode or greater. -Overlay support for the go list driver isn't complete yet: if the file doesn't -exist on disk, it will only be recognized in an overlay if it is a non-test file -and the package would be reported even without the overlay. - -Questions & Tasks - -- Add GOARCH/GOOS? - They are not portable concepts, but could be made portable. - Our goal has been to allow users to express themselves using the conventions - of the underlying build system: if the build system honors GOARCH - during a build and during a metadata query, then so should - applications built atop that query mechanism. - Conversely, if the target architecture of the build is determined by - command-line flags, the application can pass the relevant - flags through to the build system using a command such as: - myapp -query_flag="--cpu=amd64" -query_flag="--os=darwin" - However, this approach is low-level, unwieldy, and non-portable. - GOOS and GOARCH seem important enough to warrant a dedicated option. - -- How should we handle partial failures such as a mixture of good and - malformed patterns, existing and non-existent packages, successful and - failed builds, import failures, import cycles, and so on, in a call to - Load? - -- Support bazel, blaze, and go1.10 list, not just go1.11 list. - -- Handle (and test) various partial success cases, e.g. - a mixture of good packages and: - invalid patterns - nonexistent packages - empty packages - packages with malformed package or import declarations - unreadable files - import cycles - other parse errors - type errors - Make sure we record errors at the correct place in the graph. - -- Missing packages among initial arguments are not reported. - Return bogus packages for them, like golist does. - -- "undeclared name" errors (for example) are reported out of source file - order. I suspect this is due to the breadth-first resolution now used - by go/types. Is that a bug? Discuss with gri. - -*/ diff --git a/vendor/golang.org/x/tools/go/packages/external.go b/vendor/golang.org/x/tools/go/packages/external.go deleted file mode 100644 index 8c8473fd0..000000000 --- a/vendor/golang.org/x/tools/go/packages/external.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file enables an external tool to intercept package requests. -// If the tool is present then its results are used in preference to -// the go list command. - -package packages - -import ( - "bytes" - "encoding/json" - "fmt" - "os" - "os/exec" - "strings" -) - -// The Driver Protocol -// -// The driver, given the inputs to a call to Load, returns metadata about the packages specified. -// This allows for different build systems to support go/packages by telling go/packages how the -// packages' source is organized. -// The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in -// the path as gopackagesdriver. It's given the inputs to load in its argv. See the package -// documentation in doc.go for the full description of the patterns that need to be supported. -// A driver receives as a JSON-serialized driverRequest struct in standard input and will -// produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output. - -// driverRequest is used to provide the portion of Load's Config that is needed by a driver. -type driverRequest struct { - Mode LoadMode `json:"mode"` - // Env specifies the environment the underlying build system should be run in. - Env []string `json:"env"` - // BuildFlags are flags that should be passed to the underlying build system. - BuildFlags []string `json:"build_flags"` - // Tests specifies whether the patterns should also return test packages. - Tests bool `json:"tests"` - // Overlay maps file paths (relative to the driver's working directory) to the byte contents - // of overlay files. - Overlay map[string][]byte `json:"overlay"` -} - -// findExternalDriver returns the file path of a tool that supplies -// the build system package structure, or "" if not found." -// If GOPACKAGESDRIVER is set in the environment findExternalTool returns its -// value, otherwise it searches for a binary named gopackagesdriver on the PATH. -func findExternalDriver(cfg *Config) driver { - const toolPrefix = "GOPACKAGESDRIVER=" - tool := "" - for _, env := range cfg.Env { - if val := strings.TrimPrefix(env, toolPrefix); val != env { - tool = val - } - } - if tool != "" && tool == "off" { - return nil - } - if tool == "" { - var err error - tool, err = exec.LookPath("gopackagesdriver") - if err != nil { - return nil - } - } - return func(cfg *Config, words ...string) (*driverResponse, error) { - req, err := json.Marshal(driverRequest{ - Mode: cfg.Mode, - Env: cfg.Env, - BuildFlags: cfg.BuildFlags, - Tests: cfg.Tests, - Overlay: cfg.Overlay, - }) - if err != nil { - return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) - } - - buf := new(bytes.Buffer) - stderr := new(bytes.Buffer) - cmd := exec.CommandContext(cfg.Context, tool, words...) - cmd.Dir = cfg.Dir - cmd.Env = cfg.Env - cmd.Stdin = bytes.NewReader(req) - cmd.Stdout = buf - cmd.Stderr = stderr - - if err := cmd.Run(); err != nil { - return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) - } - if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { - fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd, words...), stderr) - } - - var response driverResponse - if err := json.Unmarshal(buf.Bytes(), &response); err != nil { - return nil, err - } - return &response, nil - } -} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go deleted file mode 100644 index 6e91391ce..000000000 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ /dev/null @@ -1,907 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "go/types" - "log" - "os" - "os/exec" - "path" - "path/filepath" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "unicode" - - "golang.org/x/tools/go/internal/packagesdriver" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/xerrors" -) - -// debug controls verbose logging. -var debug, _ = strconv.ParseBool(os.Getenv("GOPACKAGESDEBUG")) - -// A goTooOldError reports that the go command -// found by exec.LookPath is too old to use the new go list behavior. -type goTooOldError struct { - error -} - -// responseDeduper wraps a driverResponse, deduplicating its contents. -type responseDeduper struct { - seenRoots map[string]bool - seenPackages map[string]*Package - dr *driverResponse -} - -func newDeduper() *responseDeduper { - return &responseDeduper{ - dr: &driverResponse{}, - seenRoots: map[string]bool{}, - seenPackages: map[string]*Package{}, - } -} - -// addAll fills in r with a driverResponse. -func (r *responseDeduper) addAll(dr *driverResponse) { - for _, pkg := range dr.Packages { - r.addPackage(pkg) - } - for _, root := range dr.Roots { - r.addRoot(root) - } -} - -func (r *responseDeduper) addPackage(p *Package) { - if r.seenPackages[p.ID] != nil { - return - } - r.seenPackages[p.ID] = p - r.dr.Packages = append(r.dr.Packages, p) -} - -func (r *responseDeduper) addRoot(id string) { - if r.seenRoots[id] { - return - } - r.seenRoots[id] = true - r.dr.Roots = append(r.dr.Roots, id) -} - -type golistState struct { - cfg *Config - ctx context.Context - - envOnce sync.Once - goEnvError error - goEnv map[string]string - - rootsOnce sync.Once - rootDirsError error - rootDirs map[string]string - - // vendorDirs caches the (non)existence of vendor directories. - vendorDirs map[string]bool -} - -// getEnv returns Go environment variables. Only specific variables are -// populated -- computing all of them is slow. -func (state *golistState) getEnv() (map[string]string, error) { - state.envOnce.Do(func() { - var b *bytes.Buffer - b, state.goEnvError = state.invokeGo("env", "-json", "GOMOD", "GOPATH") - if state.goEnvError != nil { - return - } - - state.goEnv = make(map[string]string) - decoder := json.NewDecoder(b) - if state.goEnvError = decoder.Decode(&state.goEnv); state.goEnvError != nil { - return - } - }) - return state.goEnv, state.goEnvError -} - -// mustGetEnv is a convenience function that can be used if getEnv has already succeeded. -func (state *golistState) mustGetEnv() map[string]string { - env, err := state.getEnv() - if err != nil { - panic(fmt.Sprintf("mustGetEnv: %v", err)) - } - return env -} - -// goListDriver uses the go list command to interpret the patterns and produce -// the build system package structure. -// See driver for more details. -func goListDriver(cfg *Config, patterns ...string) (*driverResponse, error) { - // Make sure that any asynchronous go commands are killed when we return. - parentCtx := cfg.Context - if parentCtx == nil { - parentCtx = context.Background() - } - ctx, cancel := context.WithCancel(parentCtx) - defer cancel() - - response := newDeduper() - - // Fill in response.Sizes asynchronously if necessary. - var sizeserr error - var sizeswg sync.WaitGroup - if cfg.Mode&NeedTypesSizes != 0 || cfg.Mode&NeedTypes != 0 { - sizeswg.Add(1) - go func() { - var sizes types.Sizes - sizes, sizeserr = packagesdriver.GetSizesGolist(ctx, cfg.BuildFlags, cfg.Env, cfg.gocmdRunner, cfg.Dir) - // types.SizesFor always returns nil or a *types.StdSizes. - response.dr.Sizes, _ = sizes.(*types.StdSizes) - sizeswg.Done() - }() - } - - state := &golistState{ - cfg: cfg, - ctx: ctx, - vendorDirs: map[string]bool{}, - } - - // Determine files requested in contains patterns - var containFiles []string - restPatterns := make([]string, 0, len(patterns)) - // Extract file= and other [querytype]= patterns. Report an error if querytype - // doesn't exist. -extractQueries: - for _, pattern := range patterns { - eqidx := strings.Index(pattern, "=") - if eqidx < 0 { - restPatterns = append(restPatterns, pattern) - } else { - query, value := pattern[:eqidx], pattern[eqidx+len("="):] - switch query { - case "file": - containFiles = append(containFiles, value) - case "pattern": - restPatterns = append(restPatterns, value) - case "": // not a reserved query - restPatterns = append(restPatterns, pattern) - default: - for _, rune := range query { - if rune < 'a' || rune > 'z' { // not a reserved query - restPatterns = append(restPatterns, pattern) - continue extractQueries - } - } - // Reject all other patterns containing "=" - return nil, fmt.Errorf("invalid query type %q in query pattern %q", query, pattern) - } - } - } - - // See if we have any patterns to pass through to go list. Zero initial - // patterns also requires a go list call, since it's the equivalent of - // ".". - if len(restPatterns) > 0 || len(patterns) == 0 { - dr, err := state.createDriverResponse(restPatterns...) - if err != nil { - return nil, err - } - response.addAll(dr) - } - - if len(containFiles) != 0 { - if err := state.runContainsQueries(response, containFiles); err != nil { - return nil, err - } - } - - modifiedPkgs, needPkgs, err := state.processGolistOverlay(response) - if err != nil { - return nil, err - } - - var containsCandidates []string - if len(containFiles) > 0 { - containsCandidates = append(containsCandidates, modifiedPkgs...) - containsCandidates = append(containsCandidates, needPkgs...) - } - if err := state.addNeededOverlayPackages(response, needPkgs); err != nil { - return nil, err - } - // Check candidate packages for containFiles. - if len(containFiles) > 0 { - for _, id := range containsCandidates { - pkg, ok := response.seenPackages[id] - if !ok { - response.addPackage(&Package{ - ID: id, - Errors: []Error{ - { - Kind: ListError, - Msg: fmt.Sprintf("package %s expected but not seen", id), - }, - }, - }) - continue - } - for _, f := range containFiles { - for _, g := range pkg.GoFiles { - if sameFile(f, g) { - response.addRoot(id) - } - } - } - } - } - - sizeswg.Wait() - if sizeserr != nil { - return nil, sizeserr - } - return response.dr, nil -} - -func (state *golistState) addNeededOverlayPackages(response *responseDeduper, pkgs []string) error { - if len(pkgs) == 0 { - return nil - } - dr, err := state.createDriverResponse(pkgs...) - if err != nil { - return err - } - for _, pkg := range dr.Packages { - response.addPackage(pkg) - } - _, needPkgs, err := state.processGolistOverlay(response) - if err != nil { - return err - } - return state.addNeededOverlayPackages(response, needPkgs) -} - -func (state *golistState) runContainsQueries(response *responseDeduper, queries []string) error { - for _, query := range queries { - // TODO(matloob): Do only one query per directory. - fdir := filepath.Dir(query) - // Pass absolute path of directory to go list so that it knows to treat it as a directory, - // not a package path. - pattern, err := filepath.Abs(fdir) - if err != nil { - return fmt.Errorf("could not determine absolute path of file= query path %q: %v", query, err) - } - dirResponse, err := state.createDriverResponse(pattern) - - // If there was an error loading the package, or the package is returned - // with errors, try to load the file as an ad-hoc package. - // Usually the error will appear in a returned package, but may not if we're - // in module mode and the ad-hoc is located outside a module. - if err != nil || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && - len(dirResponse.Packages[0].Errors) == 1 { - var queryErr error - if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { - return err // return the original error - } - } - isRoot := make(map[string]bool, len(dirResponse.Roots)) - for _, root := range dirResponse.Roots { - isRoot[root] = true - } - for _, pkg := range dirResponse.Packages { - // Add any new packages to the main set - // We don't bother to filter packages that will be dropped by the changes of roots, - // that will happen anyway during graph construction outside this function. - // Over-reporting packages is not a problem. - response.addPackage(pkg) - // if the package was not a root one, it cannot have the file - if !isRoot[pkg.ID] { - continue - } - for _, pkgFile := range pkg.GoFiles { - if filepath.Base(query) == filepath.Base(pkgFile) { - response.addRoot(pkg.ID) - break - } - } - } - } - return nil -} - -// adhocPackage attempts to load or construct an ad-hoc package for a given -// query, if the original call to the driver produced inadequate results. -func (state *golistState) adhocPackage(pattern, query string) (*driverResponse, error) { - response, err := state.createDriverResponse(query) - if err != nil { - return nil, err - } - // If we get nothing back from `go list`, - // try to make this file into its own ad-hoc package. - // TODO(rstambler): Should this check against the original response? - if len(response.Packages) == 0 { - response.Packages = append(response.Packages, &Package{ - ID: "command-line-arguments", - PkgPath: query, - GoFiles: []string{query}, - CompiledGoFiles: []string{query}, - Imports: make(map[string]*Package), - }) - response.Roots = append(response.Roots, "command-line-arguments") - } - // Handle special cases. - if len(response.Packages) == 1 { - // golang/go#33482: If this is a file= query for ad-hoc packages where - // the file only exists on an overlay, and exists outside of a module, - // add the file to the package and remove the errors. - if response.Packages[0].ID == "command-line-arguments" || - filepath.ToSlash(response.Packages[0].PkgPath) == filepath.ToSlash(query) { - if len(response.Packages[0].GoFiles) == 0 { - filename := filepath.Join(pattern, filepath.Base(query)) // avoid recomputing abspath - // TODO(matloob): check if the file is outside of a root dir? - for path := range state.cfg.Overlay { - if path == filename { - response.Packages[0].Errors = nil - response.Packages[0].GoFiles = []string{path} - response.Packages[0].CompiledGoFiles = []string{path} - } - } - } - } - } - return response, nil -} - -// Fields must match go list; -// see $GOROOT/src/cmd/go/internal/load/pkg.go. -type jsonPackage struct { - ImportPath string - Dir string - Name string - Export string - GoFiles []string - CompiledGoFiles []string - CFiles []string - CgoFiles []string - CXXFiles []string - MFiles []string - HFiles []string - FFiles []string - SFiles []string - SwigFiles []string - SwigCXXFiles []string - SysoFiles []string - Imports []string - ImportMap map[string]string - Deps []string - Module *Module - TestGoFiles []string - TestImports []string - XTestGoFiles []string - XTestImports []string - ForTest string // q in a "p [q.test]" package, else "" - DepOnly bool - - Error *jsonPackageError -} - -type jsonPackageError struct { - ImportStack []string - Pos string - Err string -} - -func otherFiles(p *jsonPackage) [][]string { - return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles} -} - -// createDriverResponse uses the "go list" command to expand the pattern -// words and return a response for the specified packages. -func (state *golistState) createDriverResponse(words ...string) (*driverResponse, error) { - // go list uses the following identifiers in ImportPath and Imports: - // - // "p" -- importable package or main (command) - // "q.test" -- q's test executable - // "p [q.test]" -- variant of p as built for q's test executable - // "q_test [q.test]" -- q's external test package - // - // The packages p that are built differently for a test q.test - // are q itself, plus any helpers used by the external test q_test, - // typically including "testing" and all its dependencies. - - // Run "go list" for complete - // information on the specified packages. - buf, err := state.invokeGo("list", golistargs(state.cfg, words)...) - if err != nil { - return nil, err - } - seen := make(map[string]*jsonPackage) - pkgs := make(map[string]*Package) - additionalErrors := make(map[string][]Error) - // Decode the JSON and convert it to Package form. - var response driverResponse - for dec := json.NewDecoder(buf); dec.More(); { - p := new(jsonPackage) - if err := dec.Decode(p); err != nil { - return nil, fmt.Errorf("JSON decoding failed: %v", err) - } - - if p.ImportPath == "" { - // The documentation for go list says that “[e]rroneous packages will have - // a non-empty ImportPath”. If for some reason it comes back empty, we - // prefer to error out rather than silently discarding data or handing - // back a package without any way to refer to it. - if p.Error != nil { - return nil, Error{ - Pos: p.Error.Pos, - Msg: p.Error.Err, - } - } - return nil, fmt.Errorf("package missing import path: %+v", p) - } - - // Work around https://golang.org/issue/33157: - // go list -e, when given an absolute path, will find the package contained at - // that directory. But when no package exists there, it will return a fake package - // with an error and the ImportPath set to the absolute path provided to go list. - // Try to convert that absolute path to what its package path would be if it's - // contained in a known module or GOPATH entry. This will allow the package to be - // properly "reclaimed" when overlays are processed. - if filepath.IsAbs(p.ImportPath) && p.Error != nil { - pkgPath, ok, err := state.getPkgPath(p.ImportPath) - if err != nil { - return nil, err - } - if ok { - p.ImportPath = pkgPath - } - } - - if old, found := seen[p.ImportPath]; found { - // If one version of the package has an error, and the other doesn't, assume - // that this is a case where go list is reporting a fake dependency variant - // of the imported package: When a package tries to invalidly import another - // package, go list emits a variant of the imported package (with the same - // import path, but with an error on it, and the package will have a - // DepError set on it). An example of when this can happen is for imports of - // main packages: main packages can not be imported, but they may be - // separately matched and listed by another pattern. - // See golang.org/issue/36188 for more details. - - // The plan is that eventually, hopefully in Go 1.15, the error will be - // reported on the importing package rather than the duplicate "fake" - // version of the imported package. Once all supported versions of Go - // have the new behavior this logic can be deleted. - // TODO(matloob): delete the workaround logic once all supported versions of - // Go return the errors on the proper package. - - // There should be exactly one version of a package that doesn't have an - // error. - if old.Error == nil && p.Error == nil { - if !reflect.DeepEqual(p, old) { - return nil, fmt.Errorf("internal error: go list gives conflicting information for package %v", p.ImportPath) - } - continue - } - - // Determine if this package's error needs to be bubbled up. - // This is a hack, and we expect for go list to eventually set the error - // on the package. - if old.Error != nil { - var errkind string - if strings.Contains(old.Error.Err, "not an importable package") { - errkind = "not an importable package" - } else if strings.Contains(old.Error.Err, "use of internal package") && strings.Contains(old.Error.Err, "not allowed") { - errkind = "use of internal package not allowed" - } - if errkind != "" { - if len(old.Error.ImportStack) < 1 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with empty import stack`, errkind) - } - importingPkg := old.Error.ImportStack[len(old.Error.ImportStack)-1] - if importingPkg == old.ImportPath { - // Using an older version of Go which put this package itself on top of import - // stack, instead of the importer. Look for importer in second from top - // position. - if len(old.Error.ImportStack) < 2 { - return nil, fmt.Errorf(`internal error: go list gave a %q error with an import stack without importing package`, errkind) - } - importingPkg = old.Error.ImportStack[len(old.Error.ImportStack)-2] - } - additionalErrors[importingPkg] = append(additionalErrors[importingPkg], Error{ - Pos: old.Error.Pos, - Msg: old.Error.Err, - Kind: ListError, - }) - } - } - - // Make sure that if there's a version of the package without an error, - // that's the one reported to the user. - if old.Error == nil { - continue - } - - // This package will replace the old one at the end of the loop. - } - seen[p.ImportPath] = p - - pkg := &Package{ - Name: p.Name, - ID: p.ImportPath, - GoFiles: absJoin(p.Dir, p.GoFiles, p.CgoFiles), - CompiledGoFiles: absJoin(p.Dir, p.CompiledGoFiles), - OtherFiles: absJoin(p.Dir, otherFiles(p)...), - forTest: p.ForTest, - Module: p.Module, - } - - if (state.cfg.Mode&typecheckCgo) != 0 && len(p.CgoFiles) != 0 { - if len(p.CompiledGoFiles) > len(p.GoFiles) { - // We need the cgo definitions, which are in the first - // CompiledGoFile after the non-cgo ones. This is a hack but there - // isn't currently a better way to find it. We also need the pure - // Go files and unprocessed cgo files, all of which are already - // in pkg.GoFiles. - cgoTypes := p.CompiledGoFiles[len(p.GoFiles)] - pkg.CompiledGoFiles = append([]string{cgoTypes}, pkg.GoFiles...) - } else { - // golang/go#38990: go list silently fails to do cgo processing - pkg.CompiledGoFiles = nil - pkg.Errors = append(pkg.Errors, Error{ - Msg: "go list failed to return CompiledGoFiles; https://golang.org/issue/38990?", - Kind: ListError, - }) - } - } - - // Work around https://golang.org/issue/28749: - // cmd/go puts assembly, C, and C++ files in CompiledGoFiles. - // Filter out any elements of CompiledGoFiles that are also in OtherFiles. - // We have to keep this workaround in place until go1.12 is a distant memory. - if len(pkg.OtherFiles) > 0 { - other := make(map[string]bool, len(pkg.OtherFiles)) - for _, f := range pkg.OtherFiles { - other[f] = true - } - - out := pkg.CompiledGoFiles[:0] - for _, f := range pkg.CompiledGoFiles { - if other[f] { - continue - } - out = append(out, f) - } - pkg.CompiledGoFiles = out - } - - // Extract the PkgPath from the package's ID. - if i := strings.IndexByte(pkg.ID, ' '); i >= 0 { - pkg.PkgPath = pkg.ID[:i] - } else { - pkg.PkgPath = pkg.ID - } - - if pkg.PkgPath == "unsafe" { - pkg.GoFiles = nil // ignore fake unsafe.go file - } - - // Assume go list emits only absolute paths for Dir. - if p.Dir != "" && !filepath.IsAbs(p.Dir) { - log.Fatalf("internal error: go list returned non-absolute Package.Dir: %s", p.Dir) - } - - if p.Export != "" && !filepath.IsAbs(p.Export) { - pkg.ExportFile = filepath.Join(p.Dir, p.Export) - } else { - pkg.ExportFile = p.Export - } - - // imports - // - // Imports contains the IDs of all imported packages. - // ImportsMap records (path, ID) only where they differ. - ids := make(map[string]bool) - for _, id := range p.Imports { - ids[id] = true - } - pkg.Imports = make(map[string]*Package) - for path, id := range p.ImportMap { - pkg.Imports[path] = &Package{ID: id} // non-identity import - delete(ids, id) - } - for id := range ids { - if id == "C" { - continue - } - - pkg.Imports[id] = &Package{ID: id} // identity import - } - if !p.DepOnly { - response.Roots = append(response.Roots, pkg.ID) - } - - // Work around for pre-go.1.11 versions of go list. - // TODO(matloob): they should be handled by the fallback. - // Can we delete this? - if len(pkg.CompiledGoFiles) == 0 { - pkg.CompiledGoFiles = pkg.GoFiles - } - - if p.Error != nil { - msg := strings.TrimSpace(p.Error.Err) // Trim to work around golang.org/issue/32363. - // Address golang.org/issue/35964 by appending import stack to error message. - if msg == "import cycle not allowed" && len(p.Error.ImportStack) != 0 { - msg += fmt.Sprintf(": import stack: %v", p.Error.ImportStack) - } - pkg.Errors = append(pkg.Errors, Error{ - Pos: p.Error.Pos, - Msg: msg, - Kind: ListError, - }) - } - - pkgs[pkg.ID] = pkg - } - - for id, errs := range additionalErrors { - if p, ok := pkgs[id]; ok { - p.Errors = append(p.Errors, errs...) - } - } - for _, pkg := range pkgs { - response.Packages = append(response.Packages, pkg) - } - sort.Slice(response.Packages, func(i, j int) bool { return response.Packages[i].ID < response.Packages[j].ID }) - - return &response, nil -} - -// getPkgPath finds the package path of a directory if it's relative to a root directory. -func (state *golistState) getPkgPath(dir string) (string, bool, error) { - absDir, err := filepath.Abs(dir) - if err != nil { - return "", false, err - } - roots, err := state.determineRootDirs() - if err != nil { - return "", false, err - } - - for rdir, rpath := range roots { - // Make sure that the directory is in the module, - // to avoid creating a path relative to another module. - if !strings.HasPrefix(absDir, rdir) { - continue - } - // TODO(matloob): This doesn't properly handle symlinks. - r, err := filepath.Rel(rdir, dir) - if err != nil { - continue - } - if rpath != "" { - // We choose only one root even though the directory even it can belong in multiple modules - // or GOPATH entries. This is okay because we only need to work with absolute dirs when a - // file is missing from disk, for instance when gopls calls go/packages in an overlay. - // Once the file is saved, gopls, or the next invocation of the tool will get the correct - // result straight from golist. - // TODO(matloob): Implement module tiebreaking? - return path.Join(rpath, filepath.ToSlash(r)), true, nil - } - return filepath.ToSlash(r), true, nil - } - return "", false, nil -} - -// absJoin absolutizes and flattens the lists of files. -func absJoin(dir string, fileses ...[]string) (res []string) { - for _, files := range fileses { - for _, file := range files { - if !filepath.IsAbs(file) { - file = filepath.Join(dir, file) - } - res = append(res, file) - } - } - return res -} - -func golistargs(cfg *Config, words []string) []string { - const findFlags = NeedImports | NeedTypes | NeedSyntax | NeedTypesInfo - fullargs := []string{ - "-e", "-json", - fmt.Sprintf("-compiled=%t", cfg.Mode&(NeedCompiledGoFiles|NeedSyntax|NeedTypes|NeedTypesInfo|NeedTypesSizes) != 0), - fmt.Sprintf("-test=%t", cfg.Tests), - fmt.Sprintf("-export=%t", usesExportData(cfg)), - fmt.Sprintf("-deps=%t", cfg.Mode&NeedImports != 0), - // go list doesn't let you pass -test and -find together, - // probably because you'd just get the TestMain. - fmt.Sprintf("-find=%t", !cfg.Tests && cfg.Mode&findFlags == 0), - } - fullargs = append(fullargs, cfg.BuildFlags...) - fullargs = append(fullargs, "--") - fullargs = append(fullargs, words...) - return fullargs -} - -// invokeGo returns the stdout of a go command invocation. -func (state *golistState) invokeGo(verb string, args ...string) (*bytes.Buffer, error) { - cfg := state.cfg - - inv := gocommand.Invocation{ - Verb: verb, - Args: args, - BuildFlags: cfg.BuildFlags, - Env: cfg.Env, - Logf: cfg.Logf, - WorkingDir: cfg.Dir, - } - gocmdRunner := cfg.gocmdRunner - if gocmdRunner == nil { - gocmdRunner = &gocommand.Runner{} - } - stdout, stderr, _, err := gocmdRunner.RunRaw(cfg.Context, inv) - if err != nil { - // Check for 'go' executable not being found. - if ee, ok := err.(*exec.Error); ok && ee.Err == exec.ErrNotFound { - return nil, fmt.Errorf("'go list' driver requires 'go', but %s", exec.ErrNotFound) - } - - exitErr, ok := err.(*exec.ExitError) - if !ok { - // Catastrophic error: - // - context cancellation - return nil, xerrors.Errorf("couldn't run 'go': %w", err) - } - - // Old go version? - if strings.Contains(stderr.String(), "flag provided but not defined") { - return nil, goTooOldError{fmt.Errorf("unsupported version of go: %s: %s", exitErr, stderr)} - } - - // Related to #24854 - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "unexpected directory layout") { - return nil, fmt.Errorf("%s", stderr.String()) - } - - // Is there an error running the C compiler in cgo? This will be reported in the "Error" field - // and should be suppressed by go list -e. - // - // This condition is not perfect yet because the error message can include other error messages than runtime/cgo. - isPkgPathRune := func(r rune) bool { - // From https://golang.org/ref/spec#Import_declarations: - // Implementation restriction: A compiler may restrict ImportPaths to non-empty strings - // using only characters belonging to Unicode's L, M, N, P, and S general categories - // (the Graphic characters without spaces) and may also exclude the - // characters !"#$%&'()*,:;<=>?[\]^`{|} and the Unicode replacement character U+FFFD. - return unicode.IsOneOf([]*unicode.RangeTable{unicode.L, unicode.M, unicode.N, unicode.P, unicode.S}, r) && - !strings.ContainsRune("!\"#$%&'()*,:;<=>?[\\]^`{|}\uFFFD", r) - } - if len(stderr.String()) > 0 && strings.HasPrefix(stderr.String(), "# ") { - msg := stderr.String()[len("# "):] - if strings.HasPrefix(strings.TrimLeftFunc(msg, isPkgPathRune), "\n") { - return stdout, nil - } - // Treat pkg-config errors as a special case (golang.org/issue/36770). - if strings.HasPrefix(msg, "pkg-config") { - return stdout, nil - } - } - - // This error only appears in stderr. See golang.org/cl/166398 for a fix in go list to show - // the error in the Err section of stdout in case -e option is provided. - // This fix is provided for backwards compatibility. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must be .go files") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Similar to the previous error, but currently lacks a fix in Go. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "named files must all be in one directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Backwards compatibility for Go 1.11 because 1.12 and 1.13 put the directory in the ImportPath. - // If the package doesn't exist, put the absolute path of the directory into the error message, - // as Go 1.13 list does. - const noSuchDirectory = "no such directory" - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), noSuchDirectory) { - errstr := stderr.String() - abspath := strings.TrimSpace(errstr[strings.Index(errstr, noSuchDirectory)+len(noSuchDirectory):]) - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - abspath, strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #29280: go list -e has incorrect behavior when an ad-hoc package doesn't exist. - // Note that the error message we look for in this case is different that the one looked for above. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no such file or directory") { - output := fmt.Sprintf(`{"ImportPath": "command-line-arguments","Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for #34273. go list -e with GO111MODULE=on has incorrect behavior when listing a - // directory outside any module. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside available modules") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Another variation of the previous error - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "outside module root") { - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - // TODO(matloob): command-line-arguments isn't correct here. - "command-line-arguments", strings.Trim(stderr.String(), "\n")) - return bytes.NewBufferString(output), nil - } - - // Workaround for an instance of golang.org/issue/26755: go list -e will return a non-zero exit - // status if there's a dependency on a package that doesn't exist. But it should return - // a zero exit status and set an error on that package. - if len(stderr.String()) > 0 && strings.Contains(stderr.String(), "no Go files in") { - // Don't clobber stdout if `go list` actually returned something. - if len(stdout.String()) > 0 { - return stdout, nil - } - // try to extract package name from string - stderrStr := stderr.String() - var importPath string - colon := strings.Index(stderrStr, ":") - if colon > 0 && strings.HasPrefix(stderrStr, "go build ") { - importPath = stderrStr[len("go build "):colon] - } - output := fmt.Sprintf(`{"ImportPath": %q,"Incomplete": true,"Error": {"Pos": "","Err": %q}}`, - importPath, strings.Trim(stderrStr, "\n")) - return bytes.NewBufferString(output), nil - } - - // Export mode entails a build. - // If that build fails, errors appear on stderr - // (despite the -e flag) and the Export field is blank. - // Do not fail in that case. - // The same is true if an ad-hoc package given to go list doesn't exist. - // TODO(matloob): Remove these once we can depend on go list to exit with a zero status with -e even when - // packages don't exist or a build fails. - if !usesExportData(cfg) && !containsGoFile(args) { - return nil, fmt.Errorf("go %v: %s: %s", args, exitErr, stderr) - } - } - return stdout, nil -} - -func containsGoFile(s []string) bool { - for _, f := range s { - if strings.HasSuffix(f, ".go") { - return true - } - } - return false -} - -func cmdDebugStr(cmd *exec.Cmd, args ...string) string { - env := make(map[string]string) - for _, kv := range cmd.Env { - split := strings.Split(kv, "=") - k, v := split[0], split[1] - env[k] = v - } - var quotedArgs []string - for _, arg := range args { - quotedArgs = append(quotedArgs, strconv.Quote(arg)) - } - - return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v PWD=%v go %s", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["PWD"], strings.Join(quotedArgs, " ")) -} diff --git a/vendor/golang.org/x/tools/go/packages/golist_overlay.go b/vendor/golang.org/x/tools/go/packages/golist_overlay.go deleted file mode 100644 index 338d6f623..000000000 --- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go +++ /dev/null @@ -1,465 +0,0 @@ -package packages - -import ( - "encoding/json" - "fmt" - "go/parser" - "go/token" - "log" - "os" - "path/filepath" - "sort" - "strconv" - "strings" -) - -// processGolistOverlay provides rudimentary support for adding -// files that don't exist on disk to an overlay. The results can be -// sometimes incorrect. -// TODO(matloob): Handle unsupported cases, including the following: -// - determining the correct package to add given a new import path -func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) { - havePkgs := make(map[string]string) // importPath -> non-test package ID - needPkgsSet := make(map[string]bool) - modifiedPkgsSet := make(map[string]bool) - - pkgOfDir := make(map[string][]*Package) - for _, pkg := range response.dr.Packages { - // This is an approximation of import path to id. This can be - // wrong for tests, vendored packages, and a number of other cases. - havePkgs[pkg.PkgPath] = pkg.ID - x := commonDir(pkg.GoFiles) - if x != "" { - pkgOfDir[x] = append(pkgOfDir[x], pkg) - } - } - - // If no new imports are added, it is safe to avoid loading any needPkgs. - // Otherwise, it's hard to tell which package is actually being loaded - // (due to vendoring) and whether any modified package will show up - // in the transitive set of dependencies (because new imports are added, - // potentially modifying the transitive set of dependencies). - var overlayAddsImports bool - - // If both a package and its test package are created by the overlay, we - // need the real package first. Process all non-test files before test - // files, and make the whole process deterministic while we're at it. - var overlayFiles []string - for opath := range state.cfg.Overlay { - overlayFiles = append(overlayFiles, opath) - } - sort.Slice(overlayFiles, func(i, j int) bool { - iTest := strings.HasSuffix(overlayFiles[i], "_test.go") - jTest := strings.HasSuffix(overlayFiles[j], "_test.go") - if iTest != jTest { - return !iTest // non-tests are before tests. - } - return overlayFiles[i] < overlayFiles[j] - }) - for _, opath := range overlayFiles { - contents := state.cfg.Overlay[opath] - base := filepath.Base(opath) - dir := filepath.Dir(opath) - var pkg *Package // if opath belongs to both a package and its test variant, this will be the test variant - var testVariantOf *Package // if opath is a test file, this is the package it is testing - var fileExists bool - isTestFile := strings.HasSuffix(opath, "_test.go") - pkgName, ok := extractPackageName(opath, contents) - if !ok { - // Don't bother adding a file that doesn't even have a parsable package statement - // to the overlay. - continue - } - // If all the overlay files belong to a different package, change the - // package name to that package. - maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir]) - nextPackage: - for _, p := range response.dr.Packages { - if pkgName != p.Name && p.ID != "command-line-arguments" { - continue - } - for _, f := range p.GoFiles { - if !sameFile(filepath.Dir(f), dir) { - continue - } - // Make sure to capture information on the package's test variant, if needed. - if isTestFile && !hasTestFiles(p) { - // TODO(matloob): Are there packages other than the 'production' variant - // of a package that this can match? This shouldn't match the test main package - // because the file is generated in another directory. - testVariantOf = p - continue nextPackage - } - // We must have already seen the package of which this is a test variant. - if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath { - if hasTestFiles(p) { - testVariantOf = pkg - } - } - pkg = p - if filepath.Base(f) == base { - fileExists = true - } - } - } - // The overlay could have included an entirely new package. - if pkg == nil { - // Try to find the module or gopath dir the file is contained in. - // Then for modules, add the module opath to the beginning. - pkgPath, ok, err := state.getPkgPath(dir) - if err != nil { - return nil, nil, err - } - if !ok { - break - } - var forTest string // only set for x tests - isXTest := strings.HasSuffix(pkgName, "_test") - if isXTest { - forTest = pkgPath - pkgPath += "_test" - } - id := pkgPath - if isTestFile { - if isXTest { - id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest) - } else { - id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath) - } - } - // Try to reclaim a package with the same ID, if it exists in the response. - for _, p := range response.dr.Packages { - if reclaimPackage(p, id, opath, contents) { - pkg = p - break - } - } - // Otherwise, create a new package. - if pkg == nil { - pkg = &Package{ - PkgPath: pkgPath, - ID: id, - Name: pkgName, - Imports: make(map[string]*Package), - } - response.addPackage(pkg) - havePkgs[pkg.PkgPath] = id - // Add the production package's sources for a test variant. - if isTestFile && !isXTest && testVariantOf != nil { - pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...) - pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...) - // Add the package under test and its imports to the test variant. - pkg.forTest = testVariantOf.PkgPath - for k, v := range testVariantOf.Imports { - pkg.Imports[k] = &Package{ID: v.ID} - } - } - if isXTest { - pkg.forTest = forTest - } - } - } - if !fileExists { - pkg.GoFiles = append(pkg.GoFiles, opath) - // TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior - // if the file will be ignored due to its build tags. - pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath) - modifiedPkgsSet[pkg.ID] = true - } - imports, err := extractImports(opath, contents) - if err != nil { - // Let the parser or type checker report errors later. - continue - } - for _, imp := range imports { - // TODO(rstambler): If the package is an x test and the import has - // a test variant, make sure to replace it. - if _, found := pkg.Imports[imp]; found { - continue - } - overlayAddsImports = true - id, ok := havePkgs[imp] - if !ok { - var err error - id, err = state.resolveImport(dir, imp) - if err != nil { - return nil, nil, err - } - } - pkg.Imports[imp] = &Package{ID: id} - // Add dependencies to the non-test variant version of this package as well. - if testVariantOf != nil { - testVariantOf.Imports[imp] = &Package{ID: id} - } - } - } - - // toPkgPath guesses the package path given the id. - toPkgPath := func(sourceDir, id string) (string, error) { - if i := strings.IndexByte(id, ' '); i >= 0 { - return state.resolveImport(sourceDir, id[:i]) - } - return state.resolveImport(sourceDir, id) - } - - // Now that new packages have been created, do another pass to determine - // the new set of missing packages. - for _, pkg := range response.dr.Packages { - for _, imp := range pkg.Imports { - if len(pkg.GoFiles) == 0 { - return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath) - } - pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID) - if err != nil { - return nil, nil, err - } - if _, ok := havePkgs[pkgPath]; !ok { - needPkgsSet[pkgPath] = true - } - } - } - - if overlayAddsImports { - needPkgs = make([]string, 0, len(needPkgsSet)) - for pkg := range needPkgsSet { - needPkgs = append(needPkgs, pkg) - } - } - modifiedPkgs = make([]string, 0, len(modifiedPkgsSet)) - for pkg := range modifiedPkgsSet { - modifiedPkgs = append(modifiedPkgs, pkg) - } - return modifiedPkgs, needPkgs, err -} - -// resolveImport finds the the ID of a package given its import path. -// In particular, it will find the right vendored copy when in GOPATH mode. -func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) { - env, err := state.getEnv() - if err != nil { - return "", err - } - if env["GOMOD"] != "" { - return importPath, nil - } - - searchDir := sourceDir - for { - vendorDir := filepath.Join(searchDir, "vendor") - exists, ok := state.vendorDirs[vendorDir] - if !ok { - info, err := os.Stat(vendorDir) - exists = err == nil && info.IsDir() - state.vendorDirs[vendorDir] = exists - } - - if exists { - vendoredPath := filepath.Join(vendorDir, importPath) - if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() { - // We should probably check for .go files here, but shame on anyone who fools us. - path, ok, err := state.getPkgPath(vendoredPath) - if err != nil { - return "", err - } - if ok { - return path, nil - } - } - } - - // We know we've hit the top of the filesystem when we Dir / and get /, - // or C:\ and get C:\, etc. - next := filepath.Dir(searchDir) - if next == searchDir { - break - } - searchDir = next - } - return importPath, nil -} - -func hasTestFiles(p *Package) bool { - for _, f := range p.GoFiles { - if strings.HasSuffix(f, "_test.go") { - return true - } - } - return false -} - -// determineRootDirs returns a mapping from absolute directories that could -// contain code to their corresponding import path prefixes. -func (state *golistState) determineRootDirs() (map[string]string, error) { - env, err := state.getEnv() - if err != nil { - return nil, err - } - if env["GOMOD"] != "" { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsModules() - }) - } else { - state.rootsOnce.Do(func() { - state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() - }) - } - return state.rootDirs, state.rootDirsError -} - -func (state *golistState) determineRootDirsModules() (map[string]string, error) { - // This will only return the root directory for the main module. - // For now we only support overlays in main modules. - // Editing files in the module cache isn't a great idea, so we don't - // plan to ever support that, but editing files in replaced modules - // is something we may want to support. To do that, we'll want to - // do a go list -m to determine the replaced module's module path and - // directory, and then a go list -m {{with .Replace}}{{.Dir}}{{end}} - // from the main module to determine if that module is actually a replacement. - // See bcmills's comment here: https://github.com/golang/go/issues/37629#issuecomment-594179751 - // for more information. - out, err := state.invokeGo("list", "-m", "-json") - if err != nil { - return nil, err - } - m := map[string]string{} - type jsonMod struct{ Path, Dir string } - for dec := json.NewDecoder(out); dec.More(); { - mod := new(jsonMod) - if err := dec.Decode(mod); err != nil { - return nil, err - } - if mod.Dir != "" && mod.Path != "" { - // This is a valid module; add it to the map. - absDir, err := filepath.Abs(mod.Dir) - if err != nil { - return nil, err - } - m[absDir] = mod.Path - } - } - return m, nil -} - -func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { - m := map[string]string{} - for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { - absDir, err := filepath.Abs(dir) - if err != nil { - return nil, err - } - m[filepath.Join(absDir, "src")] = "" - } - return m, nil -} - -func extractImports(filename string, contents []byte) ([]string, error) { - f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset? - if err != nil { - return nil, err - } - var res []string - for _, imp := range f.Imports { - quotedPath := imp.Path.Value - path, err := strconv.Unquote(quotedPath) - if err != nil { - return nil, err - } - res = append(res, path) - } - return res, nil -} - -// reclaimPackage attempts to reuse a package that failed to load in an overlay. -// -// If the package has errors and has no Name, GoFiles, or Imports, -// then it's possible that it doesn't yet exist on disk. -func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool { - // TODO(rstambler): Check the message of the actual error? - // It differs between $GOPATH and module mode. - if pkg.ID != id { - return false - } - if len(pkg.Errors) != 1 { - return false - } - if pkg.Name != "" || pkg.ExportFile != "" { - return false - } - if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 { - return false - } - if len(pkg.Imports) > 0 { - return false - } - pkgName, ok := extractPackageName(filename, contents) - if !ok { - return false - } - pkg.Name = pkgName - pkg.Errors = nil - return true -} - -func extractPackageName(filename string, contents []byte) (string, bool) { - // TODO(rstambler): Check the message of the actual error? - // It differs between $GOPATH and module mode. - f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset? - if err != nil { - return "", false - } - return f.Name.Name, true -} - -func commonDir(a []string) string { - seen := make(map[string]bool) - x := append([]string{}, a...) - for _, f := range x { - seen[filepath.Dir(f)] = true - } - if len(seen) > 1 { - log.Fatalf("commonDir saw %v for %v", seen, x) - } - for k := range seen { - // len(seen) == 1 - return k - } - return "" // no files -} - -// It is possible that the files in the disk directory dir have a different package -// name from newName, which is deduced from the overlays. If they all have a different -// package name, and they all have the same package name, then that name becomes -// the package name. -// It returns true if it changes the package name, false otherwise. -func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) { - names := make(map[string]int) - for _, p := range pkgsOfDir { - names[p.Name]++ - } - if len(names) != 1 { - // some files are in different packages - return - } - var oldName string - for k := range names { - oldName = k - } - if newName == oldName { - return - } - // We might have a case where all of the package names in the directory are - // the same, but the overlay file is for an x test, which belongs to its - // own package. If the x test does not yet exist on disk, we may not yet - // have its package name on disk, but we should not rename the packages. - // - // We use a heuristic to determine if this file belongs to an x test: - // The test file should have a package name whose package name has a _test - // suffix or looks like "newName_test". - maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test") - if isTestFile && maybeXTest { - return - } - for _, p := range pkgsOfDir { - p.Name = newName - } -} diff --git a/vendor/golang.org/x/tools/go/packages/loadmode_string.go b/vendor/golang.org/x/tools/go/packages/loadmode_string.go deleted file mode 100644 index 7ea37e7ee..000000000 --- a/vendor/golang.org/x/tools/go/packages/loadmode_string.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -import ( - "fmt" - "strings" -) - -var allModes = []LoadMode{ - NeedName, - NeedFiles, - NeedCompiledGoFiles, - NeedImports, - NeedDeps, - NeedExportsFile, - NeedTypes, - NeedSyntax, - NeedTypesInfo, - NeedTypesSizes, -} - -var modeStrings = []string{ - "NeedName", - "NeedFiles", - "NeedCompiledGoFiles", - "NeedImports", - "NeedDeps", - "NeedExportsFile", - "NeedTypes", - "NeedSyntax", - "NeedTypesInfo", - "NeedTypesSizes", -} - -func (mod LoadMode) String() string { - m := mod - if m == 0 { - return "LoadMode(0)" - } - var out []string - for i, x := range allModes { - if x > m { - break - } - if (m & x) != 0 { - out = append(out, modeStrings[i]) - m = m ^ x - } - } - if m != 0 { - out = append(out, "Unknown") - } - return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|")) -} diff --git a/vendor/golang.org/x/tools/go/packages/packages.go b/vendor/golang.org/x/tools/go/packages/packages.go deleted file mode 100644 index 04053f1e7..000000000 --- a/vendor/golang.org/x/tools/go/packages/packages.go +++ /dev/null @@ -1,1212 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package packages - -// See doc.go for package documentation and implementation notes. - -import ( - "context" - "encoding/json" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "io/ioutil" - "log" - "os" - "path/filepath" - "strings" - "sync" - "time" - - "golang.org/x/tools/go/gcexportdata" - "golang.org/x/tools/internal/gocommand" - "golang.org/x/tools/internal/packagesinternal" - "golang.org/x/tools/internal/typesinternal" -) - -// A LoadMode controls the amount of detail to return when loading. -// The bits below can be combined to specify which fields should be -// filled in the result packages. -// The zero value is a special case, equivalent to combining -// the NeedName, NeedFiles, and NeedCompiledGoFiles bits. -// ID and Errors (if present) will always be filled. -// Load may return more information than requested. -type LoadMode int - -// TODO(matloob): When a V2 of go/packages is released, rename NeedExportsFile to -// NeedExportFile to make it consistent with the Package field it's adding. - -const ( - // NeedName adds Name and PkgPath. - NeedName LoadMode = 1 << iota - - // NeedFiles adds GoFiles and OtherFiles. - NeedFiles - - // NeedCompiledGoFiles adds CompiledGoFiles. - NeedCompiledGoFiles - - // NeedImports adds Imports. If NeedDeps is not set, the Imports field will contain - // "placeholder" Packages with only the ID set. - NeedImports - - // NeedDeps adds the fields requested by the LoadMode in the packages in Imports. - NeedDeps - - // NeedExportsFile adds ExportFile. - NeedExportsFile - - // NeedTypes adds Types, Fset, and IllTyped. - NeedTypes - - // NeedSyntax adds Syntax. - NeedSyntax - - // NeedTypesInfo adds TypesInfo. - NeedTypesInfo - - // NeedTypesSizes adds TypesSizes. - NeedTypesSizes - - // typecheckCgo enables full support for type checking cgo. Requires Go 1.15+. - // Modifies CompiledGoFiles and Types, and has no effect on its own. - typecheckCgo - - // NeedModule adds Module. - NeedModule -) - -const ( - // Deprecated: LoadFiles exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadFiles = NeedName | NeedFiles | NeedCompiledGoFiles - - // Deprecated: LoadImports exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadImports = LoadFiles | NeedImports - - // Deprecated: LoadTypes exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadTypes = LoadImports | NeedTypes | NeedTypesSizes - - // Deprecated: LoadSyntax exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadSyntax = LoadTypes | NeedSyntax | NeedTypesInfo - - // Deprecated: LoadAllSyntax exists for historical compatibility - // and should not be used. Please directly specify the needed fields using the Need values. - LoadAllSyntax = LoadSyntax | NeedDeps -) - -// A Config specifies details about how packages should be loaded. -// The zero value is a valid configuration. -// Calls to Load do not modify this struct. -type Config struct { - // Mode controls the level of information returned for each package. - Mode LoadMode - - // Context specifies the context for the load operation. - // If the context is cancelled, the loader may stop early - // and return an ErrCancelled error. - // If Context is nil, the load cannot be cancelled. - Context context.Context - - // Logf is the logger for the config. - // If the user provides a logger, debug logging is enabled. - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the logger is nil, default to log.Printf. - Logf func(format string, args ...interface{}) - - // Dir is the directory in which to run the build system's query tool - // that provides information about the packages. - // If Dir is empty, the tool is run in the current directory. - Dir string - - // Env is the environment to use when invoking the build system's query tool. - // If Env is nil, the current environment is used. - // As in os/exec's Cmd, only the last value in the slice for - // each environment key is used. To specify the setting of only - // a few variables, append to the current environment, as in: - // - // opt.Env = append(os.Environ(), "GOOS=plan9", "GOARCH=386") - // - Env []string - - // gocmdRunner guards go command calls from concurrency errors. - gocmdRunner *gocommand.Runner - - // BuildFlags is a list of command-line flags to be passed through to - // the build system's query tool. - BuildFlags []string - - // Fset provides source position information for syntax trees and types. - // If Fset is nil, Load will use a new fileset, but preserve Fset's value. - Fset *token.FileSet - - // ParseFile is called to read and parse each file - // when preparing a package's type-checked syntax tree. - // It must be safe to call ParseFile simultaneously from multiple goroutines. - // If ParseFile is nil, the loader will uses parser.ParseFile. - // - // ParseFile should parse the source from src and use filename only for - // recording position information. - // - // An application may supply a custom implementation of ParseFile - // to change the effective file contents or the behavior of the parser, - // or to modify the syntax tree. For example, selectively eliminating - // unwanted function bodies can significantly accelerate type checking. - ParseFile func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) - - // If Tests is set, the loader includes not just the packages - // matching a particular pattern but also any related test packages, - // including test-only variants of the package and the test executable. - // - // For example, when using the go command, loading "fmt" with Tests=true - // returns four packages, with IDs "fmt" (the standard package), - // "fmt [fmt.test]" (the package as compiled for the test), - // "fmt_test" (the test functions from source files in package fmt_test), - // and "fmt.test" (the test binary). - // - // In build systems with explicit names for tests, - // setting Tests may have no effect. - Tests bool - - // Overlay provides a mapping of absolute file paths to file contents. - // If the file with the given path already exists, the parser will use the - // alternative file contents provided by the map. - // - // Overlays provide incomplete support for when a given file doesn't - // already exist on disk. See the package doc above for more details. - Overlay map[string][]byte -} - -// driver is the type for functions that query the build system for the -// packages named by the patterns. -type driver func(cfg *Config, patterns ...string) (*driverResponse, error) - -// driverResponse contains the results for a driver query. -type driverResponse struct { - // NotHandled is returned if the request can't be handled by the current - // driver. If an external driver returns a response with NotHandled, the - // rest of the driverResponse is ignored, and go/packages will fallback - // to the next driver. If go/packages is extended in the future to support - // lists of multiple drivers, go/packages will fall back to the next driver. - NotHandled bool - - // Sizes, if not nil, is the types.Sizes to use when type checking. - Sizes *types.StdSizes - - // Roots is the set of package IDs that make up the root packages. - // We have to encode this separately because when we encode a single package - // we cannot know if it is one of the roots as that requires knowledge of the - // graph it is part of. - Roots []string `json:",omitempty"` - - // Packages is the full set of packages in the graph. - // The packages are not connected into a graph. - // The Imports if populated will be stubs that only have their ID set. - // Imports will be connected and then type and syntax information added in a - // later pass (see refine). - Packages []*Package -} - -// Load loads and returns the Go packages named by the given patterns. -// -// Config specifies loading options; -// nil behaves the same as an empty Config. -// -// Load returns an error if any of the patterns was invalid -// as defined by the underlying build system. -// It may return an empty list of packages without an error, -// for instance for an empty expansion of a valid wildcard. -// Errors associated with a particular package are recorded in the -// corresponding Package's Errors list, and do not cause Load to -// return an error. Clients may need to handle such errors before -// proceeding with further analysis. The PrintErrors function is -// provided for convenient display of all errors. -func Load(cfg *Config, patterns ...string) ([]*Package, error) { - l := newLoader(cfg) - response, err := defaultDriver(&l.Config, patterns...) - if err != nil { - return nil, err - } - l.sizes = response.Sizes - return l.refine(response.Roots, response.Packages...) -} - -// defaultDriver is a driver that implements go/packages' fallback behavior. -// It will try to request to an external driver, if one exists. If there's -// no external driver, or the driver returns a response with NotHandled set, -// defaultDriver will fall back to the go list driver. -func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) { - driver := findExternalDriver(cfg) - if driver == nil { - driver = goListDriver - } - response, err := driver(cfg, patterns...) - if err != nil { - return response, err - } else if response.NotHandled { - return goListDriver(cfg, patterns...) - } - return response, nil -} - -// A Package describes a loaded Go package. -type Package struct { - // ID is a unique identifier for a package, - // in a syntax provided by the underlying build system. - // - // Because the syntax varies based on the build system, - // clients should treat IDs as opaque and not attempt to - // interpret them. - ID string - - // Name is the package name as it appears in the package source code. - Name string - - // PkgPath is the package path as used by the go/types package. - PkgPath string - - // Errors contains any errors encountered querying the metadata - // of the package, or while parsing or type-checking its files. - Errors []Error - - // GoFiles lists the absolute file paths of the package's Go source files. - GoFiles []string - - // CompiledGoFiles lists the absolute file paths of the package's source - // files that are suitable for type checking. - // This may differ from GoFiles if files are processed before compilation. - CompiledGoFiles []string - - // OtherFiles lists the absolute file paths of the package's non-Go source files, - // including assembly, C, C++, Fortran, Objective-C, SWIG, and so on. - OtherFiles []string - - // ExportFile is the absolute path to a file containing type - // information for the package as provided by the build system. - ExportFile string - - // Imports maps import paths appearing in the package's Go source files - // to corresponding loaded Packages. - Imports map[string]*Package - - // Types provides type information for the package. - // The NeedTypes LoadMode bit sets this field for packages matching the - // patterns; type information for dependencies may be missing or incomplete, - // unless NeedDeps and NeedImports are also set. - Types *types.Package - - // Fset provides position information for Types, TypesInfo, and Syntax. - // It is set only when Types is set. - Fset *token.FileSet - - // IllTyped indicates whether the package or any dependency contains errors. - // It is set only when Types is set. - IllTyped bool - - // Syntax is the package's syntax trees, for the files listed in CompiledGoFiles. - // - // The NeedSyntax LoadMode bit populates this field for packages matching the patterns. - // If NeedDeps and NeedImports are also set, this field will also be populated - // for dependencies. - Syntax []*ast.File - - // TypesInfo provides type information about the package's syntax trees. - // It is set only when Syntax is set. - TypesInfo *types.Info - - // TypesSizes provides the effective size function for types in TypesInfo. - TypesSizes types.Sizes - - // forTest is the package under test, if any. - forTest string - - // module is the module information for the package if it exists. - Module *Module -} - -// Module provides module information for a package. -type Module struct { - Path string // module path - Version string // module version - Replace *Module // replaced by this module - Time *time.Time // time version was created - Main bool // is this the main module? - Indirect bool // is this module only an indirect dependency of main module? - Dir string // directory holding files for this module, if any - GoMod string // path to go.mod file used when loading this module, if any - GoVersion string // go version used in module - Error *ModuleError // error loading module -} - -// ModuleError holds errors loading a module. -type ModuleError struct { - Err string // the error itself -} - -func init() { - packagesinternal.GetForTest = func(p interface{}) string { - return p.(*Package).forTest - } - packagesinternal.GetGoCmdRunner = func(config interface{}) *gocommand.Runner { - return config.(*Config).gocmdRunner - } - packagesinternal.SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) { - config.(*Config).gocmdRunner = runner - } - packagesinternal.TypecheckCgo = int(typecheckCgo) -} - -// An Error describes a problem with a package's metadata, syntax, or types. -type Error struct { - Pos string // "file:line:col" or "file:line" or "" or "-" - Msg string - Kind ErrorKind -} - -// ErrorKind describes the source of the error, allowing the user to -// differentiate between errors generated by the driver, the parser, or the -// type-checker. -type ErrorKind int - -const ( - UnknownError ErrorKind = iota - ListError - ParseError - TypeError -) - -func (err Error) Error() string { - pos := err.Pos - if pos == "" { - pos = "-" // like token.Position{}.String() - } - return pos + ": " + err.Msg -} - -// flatPackage is the JSON form of Package -// It drops all the type and syntax fields, and transforms the Imports -// -// TODO(adonovan): identify this struct with Package, effectively -// publishing the JSON protocol. -type flatPackage struct { - ID string - Name string `json:",omitempty"` - PkgPath string `json:",omitempty"` - Errors []Error `json:",omitempty"` - GoFiles []string `json:",omitempty"` - CompiledGoFiles []string `json:",omitempty"` - OtherFiles []string `json:",omitempty"` - ExportFile string `json:",omitempty"` - Imports map[string]string `json:",omitempty"` -} - -// MarshalJSON returns the Package in its JSON form. -// For the most part, the structure fields are written out unmodified, and -// the type and syntax fields are skipped. -// The imports are written out as just a map of path to package id. -// The errors are written using a custom type that tries to preserve the -// structure of error types we know about. -// -// This method exists to enable support for additional build systems. It is -// not intended for use by clients of the API and we may change the format. -func (p *Package) MarshalJSON() ([]byte, error) { - flat := &flatPackage{ - ID: p.ID, - Name: p.Name, - PkgPath: p.PkgPath, - Errors: p.Errors, - GoFiles: p.GoFiles, - CompiledGoFiles: p.CompiledGoFiles, - OtherFiles: p.OtherFiles, - ExportFile: p.ExportFile, - } - if len(p.Imports) > 0 { - flat.Imports = make(map[string]string, len(p.Imports)) - for path, ipkg := range p.Imports { - flat.Imports[path] = ipkg.ID - } - } - return json.Marshal(flat) -} - -// UnmarshalJSON reads in a Package from its JSON format. -// See MarshalJSON for details about the format accepted. -func (p *Package) UnmarshalJSON(b []byte) error { - flat := &flatPackage{} - if err := json.Unmarshal(b, &flat); err != nil { - return err - } - *p = Package{ - ID: flat.ID, - Name: flat.Name, - PkgPath: flat.PkgPath, - Errors: flat.Errors, - GoFiles: flat.GoFiles, - CompiledGoFiles: flat.CompiledGoFiles, - OtherFiles: flat.OtherFiles, - ExportFile: flat.ExportFile, - } - if len(flat.Imports) > 0 { - p.Imports = make(map[string]*Package, len(flat.Imports)) - for path, id := range flat.Imports { - p.Imports[path] = &Package{ID: id} - } - } - return nil -} - -func (p *Package) String() string { return p.ID } - -// loaderPackage augments Package with state used during the loading phase -type loaderPackage struct { - *Package - importErrors map[string]error // maps each bad import to its error - loadOnce sync.Once - color uint8 // for cycle detection - needsrc bool // load from source (Mode >= LoadTypes) - needtypes bool // type information is either requested or depended on - initial bool // package was matched by a pattern -} - -// loader holds the working state of a single call to load. -type loader struct { - pkgs map[string]*loaderPackage - Config - sizes types.Sizes - parseCache map[string]*parseValue - parseCacheMu sync.Mutex - exportMu sync.Mutex // enforces mutual exclusion of exportdata operations - - // Config.Mode contains the implied mode (see impliedLoadMode). - // Implied mode contains all the fields we need the data for. - // In requestedMode there are the actually requested fields. - // We'll zero them out before returning packages to the user. - // This makes it easier for us to get the conditions where - // we need certain modes right. - requestedMode LoadMode -} - -type parseValue struct { - f *ast.File - err error - ready chan struct{} -} - -func newLoader(cfg *Config) *loader { - ld := &loader{ - parseCache: map[string]*parseValue{}, - } - if cfg != nil { - ld.Config = *cfg - // If the user has provided a logger, use it. - ld.Config.Logf = cfg.Logf - } - if ld.Config.Logf == nil { - // If the GOPACKAGESDEBUG environment variable is set to true, - // but the user has not provided a logger, default to log.Printf. - if debug { - ld.Config.Logf = log.Printf - } else { - ld.Config.Logf = func(format string, args ...interface{}) {} - } - } - if ld.Config.Mode == 0 { - ld.Config.Mode = NeedName | NeedFiles | NeedCompiledGoFiles // Preserve zero behavior of Mode for backwards compatibility. - } - if ld.Config.Env == nil { - ld.Config.Env = os.Environ() - } - if ld.Config.gocmdRunner == nil { - ld.Config.gocmdRunner = &gocommand.Runner{} - } - if ld.Context == nil { - ld.Context = context.Background() - } - if ld.Dir == "" { - if dir, err := os.Getwd(); err == nil { - ld.Dir = dir - } - } - - // Save the actually requested fields. We'll zero them out before returning packages to the user. - ld.requestedMode = ld.Mode - ld.Mode = impliedLoadMode(ld.Mode) - - if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { - if ld.Fset == nil { - ld.Fset = token.NewFileSet() - } - - // ParseFile is required even in LoadTypes mode - // because we load source if export data is missing. - if ld.ParseFile == nil { - ld.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { - const mode = parser.AllErrors | parser.ParseComments - return parser.ParseFile(fset, filename, src, mode) - } - } - } - - return ld -} - -// refine connects the supplied packages into a graph and then adds type and -// and syntax information as requested by the LoadMode. -func (ld *loader) refine(roots []string, list ...*Package) ([]*Package, error) { - rootMap := make(map[string]int, len(roots)) - for i, root := range roots { - rootMap[root] = i - } - ld.pkgs = make(map[string]*loaderPackage) - // first pass, fixup and build the map and roots - var initial = make([]*loaderPackage, len(roots)) - for _, pkg := range list { - rootIndex := -1 - if i, found := rootMap[pkg.ID]; found { - rootIndex = i - } - - // Overlays can invalidate export data. - // TODO(matloob): make this check fine-grained based on dependencies on overlaid files - exportDataInvalid := len(ld.Overlay) > 0 || pkg.ExportFile == "" && pkg.PkgPath != "unsafe" - // This package needs type information if the caller requested types and the package is - // either a root, or it's a non-root and the user requested dependencies ... - needtypes := (ld.Mode&NeedTypes|NeedTypesInfo != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) - // This package needs source if the call requested source (or types info, which implies source) - // and the package is either a root, or itas a non- root and the user requested dependencies... - needsrc := ((ld.Mode&(NeedSyntax|NeedTypesInfo) != 0 && (rootIndex >= 0 || ld.Mode&NeedDeps != 0)) || - // ... or if we need types and the exportData is invalid. We fall back to (incompletely) - // typechecking packages from source if they fail to compile. - (ld.Mode&NeedTypes|NeedTypesInfo != 0 && exportDataInvalid)) && pkg.PkgPath != "unsafe" - lpkg := &loaderPackage{ - Package: pkg, - needtypes: needtypes, - needsrc: needsrc, - } - ld.pkgs[lpkg.ID] = lpkg - if rootIndex >= 0 { - initial[rootIndex] = lpkg - lpkg.initial = true - } - } - for i, root := range roots { - if initial[i] == nil { - return nil, fmt.Errorf("root package %v is missing", root) - } - } - - // Materialize the import graph. - - const ( - white = 0 // new - grey = 1 // in progress - black = 2 // complete - ) - - // visit traverses the import graph, depth-first, - // and materializes the graph as Packages.Imports. - // - // Valid imports are saved in the Packages.Import map. - // Invalid imports (cycles and missing nodes) are saved in the importErrors map. - // Thus, even in the presence of both kinds of errors, the Import graph remains a DAG. - // - // visit returns whether the package needs src or has a transitive - // dependency on a package that does. These are the only packages - // for which we load source code. - var stack []*loaderPackage - var visit func(lpkg *loaderPackage) bool - var srcPkgs []*loaderPackage - visit = func(lpkg *loaderPackage) bool { - switch lpkg.color { - case black: - return lpkg.needsrc - case grey: - panic("internal error: grey node") - } - lpkg.color = grey - stack = append(stack, lpkg) // push - stubs := lpkg.Imports // the structure form has only stubs with the ID in the Imports - // If NeedImports isn't set, the imports fields will all be zeroed out. - if ld.Mode&NeedImports != 0 { - lpkg.Imports = make(map[string]*Package, len(stubs)) - for importPath, ipkg := range stubs { - var importErr error - imp := ld.pkgs[ipkg.ID] - if imp == nil { - // (includes package "C" when DisableCgo) - importErr = fmt.Errorf("missing package: %q", ipkg.ID) - } else if imp.color == grey { - importErr = fmt.Errorf("import cycle: %s", stack) - } - if importErr != nil { - if lpkg.importErrors == nil { - lpkg.importErrors = make(map[string]error) - } - lpkg.importErrors[importPath] = importErr - continue - } - - if visit(imp) { - lpkg.needsrc = true - } - lpkg.Imports[importPath] = imp.Package - } - } - if lpkg.needsrc { - srcPkgs = append(srcPkgs, lpkg) - } - if ld.Mode&NeedTypesSizes != 0 { - lpkg.TypesSizes = ld.sizes - } - stack = stack[:len(stack)-1] // pop - lpkg.color = black - - return lpkg.needsrc - } - - if ld.Mode&NeedImports == 0 { - // We do this to drop the stub import packages that we are not even going to try to resolve. - for _, lpkg := range initial { - lpkg.Imports = nil - } - } else { - // For each initial package, create its import DAG. - for _, lpkg := range initial { - visit(lpkg) - } - } - if ld.Mode&NeedImports != 0 && ld.Mode&NeedTypes != 0 { - for _, lpkg := range srcPkgs { - // Complete type information is required for the - // immediate dependencies of each source package. - for _, ipkg := range lpkg.Imports { - imp := ld.pkgs[ipkg.ID] - imp.needtypes = true - } - } - } - // Load type data and syntax if needed, starting at - // the initial packages (roots of the import DAG). - if ld.Mode&NeedTypes != 0 || ld.Mode&NeedSyntax != 0 { - var wg sync.WaitGroup - for _, lpkg := range initial { - wg.Add(1) - go func(lpkg *loaderPackage) { - ld.loadRecursive(lpkg) - wg.Done() - }(lpkg) - } - wg.Wait() - } - - result := make([]*Package, len(initial)) - for i, lpkg := range initial { - result[i] = lpkg.Package - } - for i := range ld.pkgs { - // Clear all unrequested fields, for extra de-Hyrum-ization. - if ld.requestedMode&NeedName == 0 { - ld.pkgs[i].Name = "" - ld.pkgs[i].PkgPath = "" - } - if ld.requestedMode&NeedFiles == 0 { - ld.pkgs[i].GoFiles = nil - ld.pkgs[i].OtherFiles = nil - } - if ld.requestedMode&NeedCompiledGoFiles == 0 { - ld.pkgs[i].CompiledGoFiles = nil - } - if ld.requestedMode&NeedImports == 0 { - ld.pkgs[i].Imports = nil - } - if ld.requestedMode&NeedExportsFile == 0 { - ld.pkgs[i].ExportFile = "" - } - if ld.requestedMode&NeedTypes == 0 { - ld.pkgs[i].Types = nil - ld.pkgs[i].Fset = nil - ld.pkgs[i].IllTyped = false - } - if ld.requestedMode&NeedSyntax == 0 { - ld.pkgs[i].Syntax = nil - } - if ld.requestedMode&NeedTypesInfo == 0 { - ld.pkgs[i].TypesInfo = nil - } - if ld.requestedMode&NeedTypesSizes == 0 { - ld.pkgs[i].TypesSizes = nil - } - if ld.requestedMode&NeedModule == 0 { - ld.pkgs[i].Module = nil - } - } - - return result, nil -} - -// loadRecursive loads the specified package and its dependencies, -// recursively, in parallel, in topological order. -// It is atomic and idempotent. -// Precondition: ld.Mode&NeedTypes. -func (ld *loader) loadRecursive(lpkg *loaderPackage) { - lpkg.loadOnce.Do(func() { - // Load the direct dependencies, in parallel. - var wg sync.WaitGroup - for _, ipkg := range lpkg.Imports { - imp := ld.pkgs[ipkg.ID] - wg.Add(1) - go func(imp *loaderPackage) { - ld.loadRecursive(imp) - wg.Done() - }(imp) - } - wg.Wait() - ld.loadPackage(lpkg) - }) -} - -// loadPackage loads the specified package. -// It must be called only once per Package, -// after immediate dependencies are loaded. -// Precondition: ld.Mode & NeedTypes. -func (ld *loader) loadPackage(lpkg *loaderPackage) { - if lpkg.PkgPath == "unsafe" { - // Fill in the blanks to avoid surprises. - lpkg.Types = types.Unsafe - lpkg.Fset = ld.Fset - lpkg.Syntax = []*ast.File{} - lpkg.TypesInfo = new(types.Info) - lpkg.TypesSizes = ld.sizes - return - } - - // Call NewPackage directly with explicit name. - // This avoids skew between golist and go/types when the files' - // package declarations are inconsistent. - lpkg.Types = types.NewPackage(lpkg.PkgPath, lpkg.Name) - lpkg.Fset = ld.Fset - - // Subtle: we populate all Types fields with an empty Package - // before loading export data so that export data processing - // never has to create a types.Package for an indirect dependency, - // which would then require that such created packages be explicitly - // inserted back into the Import graph as a final step after export data loading. - // The Diamond test exercises this case. - if !lpkg.needtypes && !lpkg.needsrc { - return - } - if !lpkg.needsrc { - ld.loadFromExportData(lpkg) - return // not a source package, don't get syntax trees - } - - appendError := func(err error) { - // Convert various error types into the one true Error. - var errs []Error - switch err := err.(type) { - case Error: - // from driver - errs = append(errs, err) - - case *os.PathError: - // from parser - errs = append(errs, Error{ - Pos: err.Path + ":1", - Msg: err.Err.Error(), - Kind: ParseError, - }) - - case scanner.ErrorList: - // from parser - for _, err := range err { - errs = append(errs, Error{ - Pos: err.Pos.String(), - Msg: err.Msg, - Kind: ParseError, - }) - } - - case types.Error: - // from type checker - errs = append(errs, Error{ - Pos: err.Fset.Position(err.Pos).String(), - Msg: err.Msg, - Kind: TypeError, - }) - - default: - // unexpected impoverished error from parser? - errs = append(errs, Error{ - Pos: "-", - Msg: err.Error(), - Kind: UnknownError, - }) - - // If you see this error message, please file a bug. - log.Printf("internal error: error %q (%T) without position", err, err) - } - - lpkg.Errors = append(lpkg.Errors, errs...) - } - - if ld.Config.Mode&NeedTypes != 0 && len(lpkg.CompiledGoFiles) == 0 && lpkg.ExportFile != "" { - // The config requested loading sources and types, but sources are missing. - // Add an error to the package and fall back to loading from export data. - appendError(Error{"-", fmt.Sprintf("sources missing for package %s", lpkg.ID), ParseError}) - ld.loadFromExportData(lpkg) - return // can't get syntax trees for this package - } - - files, errs := ld.parseFiles(lpkg.CompiledGoFiles) - for _, err := range errs { - appendError(err) - } - - lpkg.Syntax = files - if ld.Config.Mode&NeedTypes == 0 { - return - } - - lpkg.TypesInfo = &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - } - lpkg.TypesSizes = ld.sizes - - importer := importerFunc(func(path string) (*types.Package, error) { - if path == "unsafe" { - return types.Unsafe, nil - } - - // The imports map is keyed by import path. - ipkg := lpkg.Imports[path] - if ipkg == nil { - if err := lpkg.importErrors[path]; err != nil { - return nil, err - } - // There was skew between the metadata and the - // import declarations, likely due to an edit - // race, or because the ParseFile feature was - // used to supply alternative file contents. - return nil, fmt.Errorf("no metadata for %s", path) - } - - if ipkg.Types != nil && ipkg.Types.Complete() { - return ipkg.Types, nil - } - log.Fatalf("internal error: package %q without types was imported from %q", path, lpkg) - panic("unreachable") - }) - - // type-check - tc := &types.Config{ - Importer: importer, - - // Type-check bodies of functions only in non-initial packages. - // Example: for import graph A->B->C and initial packages {A,C}, - // we can ignore function bodies in B. - IgnoreFuncBodies: ld.Mode&NeedDeps == 0 && !lpkg.initial, - - Error: appendError, - Sizes: ld.sizes, - } - if (ld.Mode & typecheckCgo) != 0 { - if !typesinternal.SetUsesCgo(tc) { - appendError(Error{ - Msg: "typecheckCgo requires Go 1.15+", - Kind: ListError, - }) - return - } - } - types.NewChecker(tc, ld.Fset, lpkg.Types, lpkg.TypesInfo).Files(lpkg.Syntax) - - lpkg.importErrors = nil // no longer needed - - // If !Cgo, the type-checker uses FakeImportC mode, so - // it doesn't invoke the importer for import "C", - // nor report an error for the import, - // or for any undefined C.f reference. - // We must detect this explicitly and correctly - // mark the package as IllTyped (by reporting an error). - // TODO(adonovan): if these errors are annoying, - // we could just set IllTyped quietly. - if tc.FakeImportC { - outer: - for _, f := range lpkg.Syntax { - for _, imp := range f.Imports { - if imp.Path.Value == `"C"` { - err := types.Error{Fset: ld.Fset, Pos: imp.Pos(), Msg: `import "C" ignored`} - appendError(err) - break outer - } - } - } - } - - // Record accumulated errors. - illTyped := len(lpkg.Errors) > 0 - if !illTyped { - for _, imp := range lpkg.Imports { - if imp.IllTyped { - illTyped = true - break - } - } - } - lpkg.IllTyped = illTyped -} - -// An importFunc is an implementation of the single-method -// types.Importer interface based on a function value. -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } - -// We use a counting semaphore to limit -// the number of parallel I/O calls per process. -var ioLimit = make(chan bool, 20) - -func (ld *loader) parseFile(filename string) (*ast.File, error) { - ld.parseCacheMu.Lock() - v, ok := ld.parseCache[filename] - if ok { - // cache hit - ld.parseCacheMu.Unlock() - <-v.ready - } else { - // cache miss - v = &parseValue{ready: make(chan struct{})} - ld.parseCache[filename] = v - ld.parseCacheMu.Unlock() - - var src []byte - for f, contents := range ld.Config.Overlay { - if sameFile(f, filename) { - src = contents - } - } - var err error - if src == nil { - ioLimit <- true // wait - src, err = ioutil.ReadFile(filename) - <-ioLimit // signal - } - if err != nil { - v.err = err - } else { - v.f, v.err = ld.ParseFile(ld.Fset, filename, src) - } - - close(v.ready) - } - return v.f, v.err -} - -// parseFiles reads and parses the Go source files and returns the ASTs -// of the ones that could be at least partially parsed, along with a -// list of I/O and parse errors encountered. -// -// Because files are scanned in parallel, the token.Pos -// positions of the resulting ast.Files are not ordered. -// -func (ld *loader) parseFiles(filenames []string) ([]*ast.File, []error) { - var wg sync.WaitGroup - n := len(filenames) - parsed := make([]*ast.File, n) - errors := make([]error, n) - for i, file := range filenames { - if ld.Config.Context.Err() != nil { - parsed[i] = nil - errors[i] = ld.Config.Context.Err() - continue - } - wg.Add(1) - go func(i int, filename string) { - parsed[i], errors[i] = ld.parseFile(filename) - wg.Done() - }(i, file) - } - wg.Wait() - - // Eliminate nils, preserving order. - var o int - for _, f := range parsed { - if f != nil { - parsed[o] = f - o++ - } - } - parsed = parsed[:o] - - o = 0 - for _, err := range errors { - if err != nil { - errors[o] = err - o++ - } - } - errors = errors[:o] - - return parsed, errors -} - -// sameFile returns true if x and y have the same basename and denote -// the same file. -// -func sameFile(x, y string) bool { - if x == y { - // It could be the case that y doesn't exist. - // For instance, it may be an overlay file that - // hasn't been written to disk. To handle that case - // let x == y through. (We added the exact absolute path - // string to the CompiledGoFiles list, so the unwritten - // overlay case implies x==y.) - return true - } - if strings.EqualFold(filepath.Base(x), filepath.Base(y)) { // (optimisation) - if xi, err := os.Stat(x); err == nil { - if yi, err := os.Stat(y); err == nil { - return os.SameFile(xi, yi) - } - } - } - return false -} - -// loadFromExportData returns type information for the specified -// package, loading it from an export data file on the first request. -func (ld *loader) loadFromExportData(lpkg *loaderPackage) (*types.Package, error) { - if lpkg.PkgPath == "" { - log.Fatalf("internal error: Package %s has no PkgPath", lpkg) - } - - // Because gcexportdata.Read has the potential to create or - // modify the types.Package for each node in the transitive - // closure of dependencies of lpkg, all exportdata operations - // must be sequential. (Finer-grained locking would require - // changes to the gcexportdata API.) - // - // The exportMu lock guards the Package.Pkg field and the - // types.Package it points to, for each Package in the graph. - // - // Not all accesses to Package.Pkg need to be protected by exportMu: - // graph ordering ensures that direct dependencies of source - // packages are fully loaded before the importer reads their Pkg field. - ld.exportMu.Lock() - defer ld.exportMu.Unlock() - - if tpkg := lpkg.Types; tpkg != nil && tpkg.Complete() { - return tpkg, nil // cache hit - } - - lpkg.IllTyped = true // fail safe - - if lpkg.ExportFile == "" { - // Errors while building export data will have been printed to stderr. - return nil, fmt.Errorf("no export data file") - } - f, err := os.Open(lpkg.ExportFile) - if err != nil { - return nil, err - } - defer f.Close() - - // Read gc export data. - // - // We don't currently support gccgo export data because all - // underlying workspaces use the gc toolchain. (Even build - // systems that support gccgo don't use it for workspace - // queries.) - r, err := gcexportdata.NewReader(f) - if err != nil { - return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - - // Build the view. - // - // The gcexportdata machinery has no concept of package ID. - // It identifies packages by their PkgPath, which although not - // globally unique is unique within the scope of one invocation - // of the linker, type-checker, or gcexportdata. - // - // So, we must build a PkgPath-keyed view of the global - // (conceptually ID-keyed) cache of packages and pass it to - // gcexportdata. The view must contain every existing - // package that might possibly be mentioned by the - // current package---its transitive closure. - // - // In loadPackage, we unconditionally create a types.Package for - // each dependency so that export data loading does not - // create new ones. - // - // TODO(adonovan): it would be simpler and more efficient - // if the export data machinery invoked a callback to - // get-or-create a package instead of a map. - // - view := make(map[string]*types.Package) // view seen by gcexportdata - seen := make(map[*loaderPackage]bool) // all visited packages - var visit func(pkgs map[string]*Package) - visit = func(pkgs map[string]*Package) { - for _, p := range pkgs { - lpkg := ld.pkgs[p.ID] - if !seen[lpkg] { - seen[lpkg] = true - view[lpkg.PkgPath] = lpkg.Types - visit(lpkg.Imports) - } - } - } - visit(lpkg.Imports) - - viewLen := len(view) + 1 // adding the self package - // Parse the export data. - // (May modify incomplete packages in view but not create new ones.) - tpkg, err := gcexportdata.Read(r, ld.Fset, view, lpkg.PkgPath) - if err != nil { - return nil, fmt.Errorf("reading %s: %v", lpkg.ExportFile, err) - } - if viewLen != len(view) { - log.Fatalf("Unexpected package creation during export data loading") - } - - lpkg.Types = tpkg - lpkg.IllTyped = false - - return tpkg, nil -} - -// impliedLoadMode returns loadMode with its dependencies. -func impliedLoadMode(loadMode LoadMode) LoadMode { - if loadMode&NeedTypesInfo != 0 && loadMode&NeedImports == 0 { - // If NeedTypesInfo, go/packages needs to do typechecking itself so it can - // associate type info with the AST. To do so, we need the export data - // for dependencies, which means we need to ask for the direct dependencies. - // NeedImports is used to ask for the direct dependencies. - loadMode |= NeedImports - } - - if loadMode&NeedDeps != 0 && loadMode&NeedImports == 0 { - // With NeedDeps we need to load at least direct dependencies. - // NeedImports is used to ask for the direct dependencies. - loadMode |= NeedImports - } - - return loadMode -} - -func usesExportData(cfg *Config) bool { - return cfg.Mode&NeedExportsFile != 0 || cfg.Mode&NeedTypes != 0 && cfg.Mode&NeedDeps == 0 -} diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go deleted file mode 100644 index b13cb081f..000000000 --- a/vendor/golang.org/x/tools/go/packages/visit.go +++ /dev/null @@ -1,55 +0,0 @@ -package packages - -import ( - "fmt" - "os" - "sort" -) - -// Visit visits all the packages in the import graph whose roots are -// pkgs, calling the optional pre function the first time each package -// is encountered (preorder), and the optional post function after a -// package's dependencies have been visited (postorder). -// The boolean result of pre(pkg) determines whether -// the imports of package pkg are visited. -func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { - seen := make(map[*Package]bool) - var visit func(*Package) - visit = func(pkg *Package) { - if !seen[pkg] { - seen[pkg] = true - - if pre == nil || pre(pkg) { - paths := make([]string, 0, len(pkg.Imports)) - for path := range pkg.Imports { - paths = append(paths, path) - } - sort.Strings(paths) // Imports is a map, this makes visit stable - for _, path := range paths { - visit(pkg.Imports[path]) - } - } - - if post != nil { - post(pkg) - } - } - } - for _, pkg := range pkgs { - visit(pkg) - } -} - -// PrintErrors prints to os.Stderr the accumulated errors of all -// packages in the import graph rooted at pkgs, dependencies first. -// PrintErrors returns the number of errors printed. -func PrintErrors(pkgs []*Package) int { - var n int - Visit(pkgs, nil, func(pkg *Package) { - for _, err := range pkg.Errors { - fmt.Fprintln(os.Stderr, err) - n++ - } - }) - return n -} diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go deleted file mode 100644 index cffd7acbe..000000000 --- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go +++ /dev/null @@ -1,524 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package objectpath defines a naming scheme for types.Objects -// (that is, named entities in Go programs) relative to their enclosing -// package. -// -// Type-checker objects are canonical, so they are usually identified by -// their address in memory (a pointer), but a pointer has meaning only -// within one address space. By contrast, objectpath names allow the -// identity of an object to be sent from one program to another, -// establishing a correspondence between types.Object variables that are -// distinct but logically equivalent. -// -// A single object may have multiple paths. In this example, -// type A struct{ X int } -// type B A -// the field X has two paths due to its membership of both A and B. -// The For(obj) function always returns one of these paths, arbitrarily -// but consistently. -package objectpath - -import ( - "fmt" - "strconv" - "strings" - - "go/types" -) - -// A Path is an opaque name that identifies a types.Object -// relative to its package. Conceptually, the name consists of a -// sequence of destructuring operations applied to the package scope -// to obtain the original object. -// The name does not include the package itself. -type Path string - -// Encoding -// -// An object path is a textual and (with training) human-readable encoding -// of a sequence of destructuring operators, starting from a types.Package. -// The sequences represent a path through the package/object/type graph. -// We classify these operators by their type: -// -// PO package->object Package.Scope.Lookup -// OT object->type Object.Type -// TT type->type Type.{Elem,Key,Params,Results,Underlying} [EKPRU] -// TO type->object Type.{At,Field,Method,Obj} [AFMO] -// -// All valid paths start with a package and end at an object -// and thus may be defined by the regular language: -// -// objectpath = PO (OT TT* TO)* -// -// The concrete encoding follows directly: -// - The only PO operator is Package.Scope.Lookup, which requires an identifier. -// - The only OT operator is Object.Type, -// which we encode as '.' because dot cannot appear in an identifier. -// - The TT operators are encoded as [EKPRU]. -// - The OT operators are encoded as [AFMO]; -// three of these (At,Field,Method) require an integer operand, -// which is encoded as a string of decimal digits. -// These indices are stable across different representations -// of the same package, even source and export data. -// -// In the example below, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// field X has the path "T.UM0.RA1.F0", -// representing the following sequence of operations: -// -// p.Lookup("T") T -// .Type().Underlying().Method(0). f -// .Type().Results().At(1) b -// .Type().Field(0) X -// -// The encoding is not maximally compact---every R or P is -// followed by an A, for example---but this simplifies the -// encoder and decoder. -// -const ( - // object->type operators - opType = '.' // .Type() (Object) - - // type->type operators - opElem = 'E' // .Elem() (Pointer, Slice, Array, Chan, Map) - opKey = 'K' // .Key() (Map) - opParams = 'P' // .Params() (Signature) - opResults = 'R' // .Results() (Signature) - opUnderlying = 'U' // .Underlying() (Named) - - // type->object operators - opAt = 'A' // .At(i) (Tuple) - opField = 'F' // .Field(i) (Struct) - opMethod = 'M' // .Method(i) (Named or Interface; not Struct: "promoted" names are ignored) - opObj = 'O' // .Obj() (Named) -) - -// The For function returns the path to an object relative to its package, -// or an error if the object is not accessible from the package's Scope. -// -// The For function guarantees to return a path only for the following objects: -// - package-level types -// - exported package-level non-types -// - methods -// - parameter and result variables -// - struct fields -// These objects are sufficient to define the API of their package. -// The objects described by a package's export data are drawn from this set. -// -// For does not return a path for predeclared names, imported package -// names, local names, and unexported package-level names (except -// types). -// -// Example: given this definition, -// -// package p -// -// type T interface { -// f() (a string, b struct{ X int }) -// } -// -// For(X) would return a path that denotes the following sequence of operations: -// -// p.Scope().Lookup("T") (TypeName T) -// .Type().Underlying().Method(0). (method Func f) -// .Type().Results().At(1) (field Var b) -// .Type().Field(0) (field Var X) -// -// where p is the package (*types.Package) to which X belongs. -func For(obj types.Object) (Path, error) { - pkg := obj.Pkg() - - // This table lists the cases of interest. - // - // Object Action - // ------ ------ - // nil reject - // builtin reject - // pkgname reject - // label reject - // var - // package-level accept - // func param/result accept - // local reject - // struct field accept - // const - // package-level accept - // local reject - // func - // package-level accept - // init functions reject - // concrete method accept - // interface method accept - // type - // package-level accept - // local reject - // - // The only accessible package-level objects are members of pkg itself. - // - // The cases are handled in four steps: - // - // 1. reject nil and builtin - // 2. accept package-level objects - // 3. reject obviously invalid objects - // 4. search the API for the path to the param/result/field/method. - - // 1. reference to nil or builtin? - if pkg == nil { - return "", fmt.Errorf("predeclared %s has no path", obj) - } - scope := pkg.Scope() - - // 2. package-level object? - if scope.Lookup(obj.Name()) == obj { - // Only exported objects (and non-exported types) have a path. - // Non-exported types may be referenced by other objects. - if _, ok := obj.(*types.TypeName); !ok && !obj.Exported() { - return "", fmt.Errorf("no path for non-exported %v", obj) - } - return Path(obj.Name()), nil - } - - // 3. Not a package-level object. - // Reject obviously non-viable cases. - switch obj := obj.(type) { - case *types.Const, // Only package-level constants have a path. - *types.TypeName, // Only package-level types have a path. - *types.Label, // Labels are function-local. - *types.PkgName: // PkgNames are file-local. - return "", fmt.Errorf("no path for %v", obj) - - case *types.Var: - // Could be: - // - a field (obj.IsField()) - // - a func parameter or result - // - a local var. - // Sadly there is no way to distinguish - // a param/result from a local - // so we must proceed to the find. - - case *types.Func: - // A func, if not package-level, must be a method. - if recv := obj.Type().(*types.Signature).Recv(); recv == nil { - return "", fmt.Errorf("func is not a method: %v", obj) - } - // TODO(adonovan): opt: if the method is concrete, - // do a specialized version of the rest of this function so - // that it's O(1) not O(|scope|). Basically 'find' is needed - // only for struct fields and interface methods. - - default: - panic(obj) - } - - // 4. Search the API for the path to the var (field/param/result) or method. - - // First inspect package-level named types. - // In the presence of path aliases, these give - // the best paths because non-types may - // refer to types, but not the reverse. - empty := make([]byte, 0, 48) // initial space - names := scope.Names() - for _, name := range names { - o := scope.Lookup(name) - tname, ok := o.(*types.TypeName) - if !ok { - continue // handle non-types in second pass - } - - path := append(empty, name...) - path = append(path, opType) - - T := o.Type() - - if tname.IsAlias() { - // type alias - if r := find(obj, T, path); r != nil { - return Path(r), nil - } - } else { - // defined (named) type - if r := find(obj, T.Underlying(), append(path, opUnderlying)); r != nil { - return Path(r), nil - } - } - } - - // Then inspect everything else: - // non-types, and declared methods of defined types. - for _, name := range names { - o := scope.Lookup(name) - path := append(empty, name...) - if _, ok := o.(*types.TypeName); !ok { - if o.Exported() { - // exported non-type (const, var, func) - if r := find(obj, o.Type(), append(path, opType)); r != nil { - return Path(r), nil - } - } - continue - } - - // Inspect declared methods of defined types. - if T, ok := o.Type().(*types.Named); ok { - path = append(path, opType) - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return Path(path2), nil // found declared method - } - if r := find(obj, m.Type(), append(path2, opType)); r != nil { - return Path(r), nil - } - } - } - } - - return "", fmt.Errorf("can't find path for %v in %s", obj, pkg.Path()) -} - -func appendOpArg(path []byte, op byte, arg int) []byte { - path = append(path, op) - path = strconv.AppendInt(path, int64(arg), 10) - return path -} - -// find finds obj within type T, returning the path to it, or nil if not found. -func find(obj types.Object, T types.Type, path []byte) []byte { - switch T := T.(type) { - case *types.Basic, *types.Named: - // Named types belonging to pkg were handled already, - // so T must belong to another package. No path. - return nil - case *types.Pointer: - return find(obj, T.Elem(), append(path, opElem)) - case *types.Slice: - return find(obj, T.Elem(), append(path, opElem)) - case *types.Array: - return find(obj, T.Elem(), append(path, opElem)) - case *types.Chan: - return find(obj, T.Elem(), append(path, opElem)) - case *types.Map: - if r := find(obj, T.Key(), append(path, opKey)); r != nil { - return r - } - return find(obj, T.Elem(), append(path, opElem)) - case *types.Signature: - if r := find(obj, T.Params(), append(path, opParams)); r != nil { - return r - } - return find(obj, T.Results(), append(path, opResults)) - case *types.Struct: - for i := 0; i < T.NumFields(); i++ { - f := T.Field(i) - path2 := appendOpArg(path, opField, i) - if f == obj { - return path2 // found field var - } - if r := find(obj, f.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.Tuple: - for i := 0; i < T.Len(); i++ { - v := T.At(i) - path2 := appendOpArg(path, opAt, i) - if v == obj { - return path2 // found param/result var - } - if r := find(obj, v.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - case *types.Interface: - for i := 0; i < T.NumMethods(); i++ { - m := T.Method(i) - path2 := appendOpArg(path, opMethod, i) - if m == obj { - return path2 // found interface method - } - if r := find(obj, m.Type(), append(path2, opType)); r != nil { - return r - } - } - return nil - } - panic(T) -} - -// Object returns the object denoted by path p within the package pkg. -func Object(pkg *types.Package, p Path) (types.Object, error) { - if p == "" { - return nil, fmt.Errorf("empty path") - } - - pathstr := string(p) - var pkgobj, suffix string - if dot := strings.IndexByte(pathstr, opType); dot < 0 { - pkgobj = pathstr - } else { - pkgobj = pathstr[:dot] - suffix = pathstr[dot:] // suffix starts with "." - } - - obj := pkg.Scope().Lookup(pkgobj) - if obj == nil { - return nil, fmt.Errorf("package %s does not contain %q", pkg.Path(), pkgobj) - } - - // abstraction of *types.{Pointer,Slice,Array,Chan,Map} - type hasElem interface { - Elem() types.Type - } - // abstraction of *types.{Interface,Named} - type hasMethods interface { - Method(int) *types.Func - NumMethods() int - } - - // The loop state is the pair (t, obj), - // exactly one of which is non-nil, initially obj. - // All suffixes start with '.' (the only object->type operation), - // followed by optional type->type operations, - // then a type->object operation. - // The cycle then repeats. - var t types.Type - for suffix != "" { - code := suffix[0] - suffix = suffix[1:] - - // Codes [AFM] have an integer operand. - var index int - switch code { - case opAt, opField, opMethod: - rest := strings.TrimLeft(suffix, "0123456789") - numerals := suffix[:len(suffix)-len(rest)] - suffix = rest - i, err := strconv.Atoi(numerals) - if err != nil { - return nil, fmt.Errorf("invalid path: bad numeric operand %q for code %q", numerals, code) - } - index = int(i) - case opObj: - // no operand - default: - // The suffix must end with a type->object operation. - if suffix == "" { - return nil, fmt.Errorf("invalid path: ends with %q, want [AFMO]", code) - } - } - - if code == opType { - if t != nil { - return nil, fmt.Errorf("invalid path: unexpected %q in type context", opType) - } - t = obj.Type() - obj = nil - continue - } - - if t == nil { - return nil, fmt.Errorf("invalid path: code %q in object context", code) - } - - // Inv: t != nil, obj == nil - - switch code { - case opElem: - hasElem, ok := t.(hasElem) // Pointer, Slice, Array, Chan, Map - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want pointer, slice, array, chan or map)", code, t, t) - } - t = hasElem.Elem() - - case opKey: - mapType, ok := t.(*types.Map) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want map)", code, t, t) - } - t = mapType.Key() - - case opParams: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Params() - - case opResults: - sig, ok := t.(*types.Signature) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want signature)", code, t, t) - } - t = sig.Results() - - case opUnderlying: - named, ok := t.(*types.Named) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %s, want named)", code, t, t) - } - t = named.Underlying() - - case opAt: - tuple, ok := t.(*types.Tuple) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %s, want tuple)", code, t, t) - } - if n := tuple.Len(); index >= n { - return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n) - } - obj = tuple.At(index) - t = nil - - case opField: - structType, ok := t.(*types.Struct) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %T, want struct)", code, t, t) - } - if n := structType.NumFields(); index >= n { - return nil, fmt.Errorf("field index %d out of range [0-%d)", index, n) - } - obj = structType.Field(index) - t = nil - - case opMethod: - hasMethods, ok := t.(hasMethods) // Interface or Named - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %s, want interface or named)", code, t, t) - } - if n := hasMethods.NumMethods(); index >= n { - return nil, fmt.Errorf("method index %d out of range [0-%d)", index, n) - } - obj = hasMethods.Method(index) - t = nil - - case opObj: - named, ok := t.(*types.Named) - if !ok { - return nil, fmt.Errorf("cannot apply %q to %s (got %s, want named)", code, t, t) - } - obj = named.Obj() - t = nil - - default: - return nil, fmt.Errorf("invalid path: unknown code %q", code) - } - } - - if obj.Pkg() != pkg { - return nil, fmt.Errorf("path denotes %s, which belongs to a different package", obj) - } - - return obj, nil // success -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/callee.go b/vendor/golang.org/x/tools/go/types/typeutil/callee.go deleted file mode 100644 index 38f596daf..000000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/callee.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeutil - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/ast/astutil" -) - -// Callee returns the named target of a function call, if any: -// a function, method, builtin, or variable. -func Callee(info *types.Info, call *ast.CallExpr) types.Object { - var obj types.Object - switch fun := astutil.Unparen(call.Fun).(type) { - case *ast.Ident: - obj = info.Uses[fun] // type, var, builtin, or declared func - case *ast.SelectorExpr: - if sel, ok := info.Selections[fun]; ok { - obj = sel.Obj() // method or field - } else { - obj = info.Uses[fun.Sel] // qualified identifier? - } - } - if _, ok := obj.(*types.TypeName); ok { - return nil // T(x) is a conversion, not a call - } - return obj -} - -// StaticCallee returns the target (function or method) of a static -// function call, if any. It returns nil for calls to builtins. -func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { - if f, ok := Callee(info, call).(*types.Func); ok && !interfaceMethod(f) { - return f - } - return nil -} - -func interfaceMethod(f *types.Func) bool { - recv := f.Type().(*types.Signature).Recv() - return recv != nil && types.IsInterface(recv.Type()) -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/imports.go b/vendor/golang.org/x/tools/go/types/typeutil/imports.go deleted file mode 100644 index 9c441dba9..000000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/imports.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeutil - -import "go/types" - -// Dependencies returns all dependencies of the specified packages. -// -// Dependent packages appear in topological order: if package P imports -// package Q, Q appears earlier than P in the result. -// The algorithm follows import statements in the order they -// appear in the source code, so the result is a total order. -// -func Dependencies(pkgs ...*types.Package) []*types.Package { - var result []*types.Package - seen := make(map[*types.Package]bool) - var visit func(pkgs []*types.Package) - visit = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !seen[p] { - seen[p] = true - visit(p.Imports()) - result = append(result, p) - } - } - } - visit(pkgs) - return result -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go deleted file mode 100644 index c7f754500..000000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/map.go +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package typeutil defines various utilities for types, such as Map, -// a mapping from types.Type to interface{} values. -package typeutil // import "golang.org/x/tools/go/types/typeutil" - -import ( - "bytes" - "fmt" - "go/types" - "reflect" -) - -// Map is a hash-table-based mapping from types (types.Type) to -// arbitrary interface{} values. The concrete types that implement -// the Type interface are pointers. Since they are not canonicalized, -// == cannot be used to check for equivalence, and thus we cannot -// simply use a Go map. -// -// Just as with map[K]V, a nil *Map is a valid empty map. -// -// Not thread-safe. -// -type Map struct { - hasher Hasher // shared by many Maps - table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused - length int // number of map entries -} - -// entry is an entry (key/value association) in a hash bucket. -type entry struct { - key types.Type - value interface{} -} - -// SetHasher sets the hasher used by Map. -// -// All Hashers are functionally equivalent but contain internal state -// used to cache the results of hashing previously seen types. -// -// A single Hasher created by MakeHasher() may be shared among many -// Maps. This is recommended if the instances have many keys in -// common, as it will amortize the cost of hash computation. -// -// A Hasher may grow without bound as new types are seen. Even when a -// type is deleted from the map, the Hasher never shrinks, since other -// types in the map may reference the deleted type indirectly. -// -// Hashers are not thread-safe, and read-only operations such as -// Map.Lookup require updates to the hasher, so a full Mutex lock (not a -// read-lock) is require around all Map operations if a shared -// hasher is accessed from multiple threads. -// -// If SetHasher is not called, the Map will create a private hasher at -// the first call to Insert. -// -func (m *Map) SetHasher(hasher Hasher) { - m.hasher = hasher -} - -// Delete removes the entry with the given key, if any. -// It returns true if the entry was found. -// -func (m *Map) Delete(key types.Type) bool { - if m != nil && m.table != nil { - hash := m.hasher.Hash(key) - bucket := m.table[hash] - for i, e := range bucket { - if e.key != nil && types.Identical(key, e.key) { - // We can't compact the bucket as it - // would disturb iterators. - bucket[i] = entry{} - m.length-- - return true - } - } - } - return false -} - -// At returns the map entry for the given key. -// The result is nil if the entry is not present. -// -func (m *Map) At(key types.Type) interface{} { - if m != nil && m.table != nil { - for _, e := range m.table[m.hasher.Hash(key)] { - if e.key != nil && types.Identical(key, e.key) { - return e.value - } - } - } - return nil -} - -// Set sets the map entry for key to val, -// and returns the previous entry, if any. -func (m *Map) Set(key types.Type, value interface{}) (prev interface{}) { - if m.table != nil { - hash := m.hasher.Hash(key) - bucket := m.table[hash] - var hole *entry - for i, e := range bucket { - if e.key == nil { - hole = &bucket[i] - } else if types.Identical(key, e.key) { - prev = e.value - bucket[i].value = value - return - } - } - - if hole != nil { - *hole = entry{key, value} // overwrite deleted entry - } else { - m.table[hash] = append(bucket, entry{key, value}) - } - } else { - if m.hasher.memo == nil { - m.hasher = MakeHasher() - } - hash := m.hasher.Hash(key) - m.table = map[uint32][]entry{hash: {entry{key, value}}} - } - - m.length++ - return -} - -// Len returns the number of map entries. -func (m *Map) Len() int { - if m != nil { - return m.length - } - return 0 -} - -// Iterate calls function f on each entry in the map in unspecified order. -// -// If f should mutate the map, Iterate provides the same guarantees as -// Go maps: if f deletes a map entry that Iterate has not yet reached, -// f will not be invoked for it, but if f inserts a map entry that -// Iterate has not yet reached, whether or not f will be invoked for -// it is unspecified. -// -func (m *Map) Iterate(f func(key types.Type, value interface{})) { - if m != nil { - for _, bucket := range m.table { - for _, e := range bucket { - if e.key != nil { - f(e.key, e.value) - } - } - } - } -} - -// Keys returns a new slice containing the set of map keys. -// The order is unspecified. -func (m *Map) Keys() []types.Type { - keys := make([]types.Type, 0, m.Len()) - m.Iterate(func(key types.Type, _ interface{}) { - keys = append(keys, key) - }) - return keys -} - -func (m *Map) toString(values bool) string { - if m == nil { - return "{}" - } - var buf bytes.Buffer - fmt.Fprint(&buf, "{") - sep := "" - m.Iterate(func(key types.Type, value interface{}) { - fmt.Fprint(&buf, sep) - sep = ", " - fmt.Fprint(&buf, key) - if values { - fmt.Fprintf(&buf, ": %q", value) - } - }) - fmt.Fprint(&buf, "}") - return buf.String() -} - -// String returns a string representation of the map's entries. -// Values are printed using fmt.Sprintf("%v", v). -// Order is unspecified. -// -func (m *Map) String() string { - return m.toString(true) -} - -// KeysString returns a string representation of the map's key set. -// Order is unspecified. -// -func (m *Map) KeysString() string { - return m.toString(false) -} - -//////////////////////////////////////////////////////////////////////// -// Hasher - -// A Hasher maps each type to its hash value. -// For efficiency, a hasher uses memoization; thus its memory -// footprint grows monotonically over time. -// Hashers are not thread-safe. -// Hashers have reference semantics. -// Call MakeHasher to create a Hasher. -type Hasher struct { - memo map[types.Type]uint32 -} - -// MakeHasher returns a new Hasher instance. -func MakeHasher() Hasher { - return Hasher{make(map[types.Type]uint32)} -} - -// Hash computes a hash value for the given type t such that -// Identical(t, t') => Hash(t) == Hash(t'). -func (h Hasher) Hash(t types.Type) uint32 { - hash, ok := h.memo[t] - if !ok { - hash = h.hashFor(t) - h.memo[t] = hash - } - return hash -} - -// hashString computes the Fowler–Noll–Vo hash of s. -func hashString(s string) uint32 { - var h uint32 - for i := 0; i < len(s); i++ { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -// hashFor computes the hash of t. -func (h Hasher) hashFor(t types.Type) uint32 { - // See Identical for rationale. - switch t := t.(type) { - case *types.Basic: - return uint32(t.Kind()) - - case *types.Array: - return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem()) - - case *types.Slice: - return 9049 + 2*h.Hash(t.Elem()) - - case *types.Struct: - var hash uint32 = 9059 - for i, n := 0, t.NumFields(); i < n; i++ { - f := t.Field(i) - if f.Anonymous() { - hash += 8861 - } - hash += hashString(t.Tag(i)) - hash += hashString(f.Name()) // (ignore f.Pkg) - hash += h.Hash(f.Type()) - } - return hash - - case *types.Pointer: - return 9067 + 2*h.Hash(t.Elem()) - - case *types.Signature: - var hash uint32 = 9091 - if t.Variadic() { - hash *= 8863 - } - return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) - - case *types.Interface: - var hash uint32 = 9103 - for i, n := 0, t.NumMethods(); i < n; i++ { - // See go/types.identicalMethods for rationale. - // Method order is not significant. - // Ignore m.Pkg(). - m := t.Method(i) - hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type()) - } - return hash - - case *types.Map: - return 9109 + 2*h.Hash(t.Key()) + 3*h.Hash(t.Elem()) - - case *types.Chan: - return 9127 + 2*uint32(t.Dir()) + 3*h.Hash(t.Elem()) - - case *types.Named: - // Not safe with a copying GC; objects may move. - return uint32(reflect.ValueOf(t.Obj()).Pointer()) - - case *types.Tuple: - return h.hashTuple(t) - } - panic(t) -} - -func (h Hasher) hashTuple(tuple *types.Tuple) uint32 { - // See go/types.identicalTypes for rationale. - n := tuple.Len() - var hash uint32 = 9137 + 2*uint32(n) - for i := 0; i < n; i++ { - hash += 3 * h.Hash(tuple.At(i).Type()) - } - return hash -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go b/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go deleted file mode 100644 index 32084610f..000000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/methodsetcache.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements a cache of method sets. - -package typeutil - -import ( - "go/types" - "sync" -) - -// A MethodSetCache records the method set of each type T for which -// MethodSet(T) is called so that repeat queries are fast. -// The zero value is a ready-to-use cache instance. -type MethodSetCache struct { - mu sync.Mutex - named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N - others map[types.Type]*types.MethodSet // all other types -} - -// MethodSet returns the method set of type T. It is thread-safe. -// -// If cache is nil, this function is equivalent to types.NewMethodSet(T). -// Utility functions can thus expose an optional *MethodSetCache -// parameter to clients that care about performance. -// -func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { - if cache == nil { - return types.NewMethodSet(T) - } - cache.mu.Lock() - defer cache.mu.Unlock() - - switch T := T.(type) { - case *types.Named: - return cache.lookupNamed(T).value - - case *types.Pointer: - if N, ok := T.Elem().(*types.Named); ok { - return cache.lookupNamed(N).pointer - } - } - - // all other types - // (The map uses pointer equivalence, not type identity.) - mset := cache.others[T] - if mset == nil { - mset = types.NewMethodSet(T) - if cache.others == nil { - cache.others = make(map[types.Type]*types.MethodSet) - } - cache.others[T] = mset - } - return mset -} - -func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { - if cache.named == nil { - cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) - } - // Avoid recomputing mset(*T) for each distinct Pointer - // instance whose underlying type is a named type. - msets, ok := cache.named[named] - if !ok { - msets.value = types.NewMethodSet(named) - msets.pointer = types.NewMethodSet(types.NewPointer(named)) - cache.named[named] = msets - } - return msets -} diff --git a/vendor/golang.org/x/tools/go/types/typeutil/ui.go b/vendor/golang.org/x/tools/go/types/typeutil/ui.go deleted file mode 100644 index 9849c24ce..000000000 --- a/vendor/golang.org/x/tools/go/types/typeutil/ui.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeutil - -// This file defines utilities for user interfaces that display types. - -import "go/types" - -// IntuitiveMethodSet returns the intuitive method set of a type T, -// which is the set of methods you can call on an addressable value of -// that type. -// -// The result always contains MethodSet(T), and is exactly MethodSet(T) -// for interface types and for pointer-to-concrete types. -// For all other concrete types T, the result additionally -// contains each method belonging to *T if there is no identically -// named method on T itself. -// -// This corresponds to user intuition about method sets; -// this function is intended only for user interfaces. -// -// The order of the result is as for types.MethodSet(T). -// -func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { - isPointerToConcrete := func(T types.Type) bool { - ptr, ok := T.(*types.Pointer) - return ok && !types.IsInterface(ptr.Elem()) - } - - var result []*types.Selection - mset := msets.MethodSet(T) - if types.IsInterface(T) || isPointerToConcrete(T) { - for i, n := 0, mset.Len(); i < n; i++ { - result = append(result, mset.At(i)) - } - } else { - // T is some other concrete type. - // Report methods of T and *T, preferring those of T. - pmset := msets.MethodSet(types.NewPointer(T)) - for i, n := 0, pmset.Len(); i < n; i++ { - meth := pmset.At(i) - if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { - meth = m - } - result = append(result, meth) - } - - } - return result -} diff --git a/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go b/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go deleted file mode 100644 index 26586810c..000000000 --- a/vendor/golang.org/x/tools/internal/analysisinternal/analysis.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package analysisinternal exposes internal-only fields from go/analysis. -package analysisinternal - -import ( - "bytes" - "fmt" - "go/ast" - "go/token" - "go/types" - "strings" - - "golang.org/x/tools/go/ast/astutil" -) - -func TypeErrorEndPos(fset *token.FileSet, src []byte, start token.Pos) token.Pos { - // Get the end position for the type error. - offset, end := fset.PositionFor(start, false).Offset, start - if offset >= len(src) { - return end - } - if width := bytes.IndexAny(src[offset:], " \n,():;[]+-*"); width > 0 { - end = start + token.Pos(width) - } - return end -} - -func ZeroValue(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { - under := typ - if n, ok := typ.(*types.Named); ok { - under = n.Underlying() - } - switch u := under.(type) { - case *types.Basic: - switch { - case u.Info()&types.IsNumeric != 0: - return &ast.BasicLit{Kind: token.INT, Value: "0"} - case u.Info()&types.IsBoolean != 0: - return &ast.Ident{Name: "false"} - case u.Info()&types.IsString != 0: - return &ast.BasicLit{Kind: token.STRING, Value: `""`} - default: - panic("unknown basic type") - } - case *types.Chan, *types.Interface, *types.Map, *types.Pointer, *types.Signature, *types.Slice: - return ast.NewIdent("nil") - case *types.Struct: - texpr := typeExpr(fset, f, pkg, typ) // typ because we want the name here. - if texpr == nil { - return nil - } - return &ast.CompositeLit{ - Type: texpr, - } - case *types.Array: - texpr := typeExpr(fset, f, pkg, u.Elem()) - if texpr == nil { - return nil - } - return &ast.CompositeLit{ - Type: &ast.ArrayType{ - Elt: texpr, - Len: &ast.BasicLit{Kind: token.INT, Value: fmt.Sprintf("%v", u.Len())}, - }, - } - } - return nil -} - -func typeExpr(fset *token.FileSet, f *ast.File, pkg *types.Package, typ types.Type) ast.Expr { - switch t := typ.(type) { - case *types.Basic: - switch t.Kind() { - case types.UnsafePointer: - return &ast.SelectorExpr{X: ast.NewIdent("unsafe"), Sel: ast.NewIdent("Pointer")} - default: - return ast.NewIdent(t.Name()) - } - case *types.Named: - if t.Obj().Pkg() == pkg { - return ast.NewIdent(t.Obj().Name()) - } - pkgName := t.Obj().Pkg().Name() - // If the file already imports the package under another name, use that. - for _, group := range astutil.Imports(fset, f) { - for _, cand := range group { - if strings.Trim(cand.Path.Value, `"`) == t.Obj().Pkg().Path() { - if cand.Name != nil && cand.Name.Name != "" { - pkgName = cand.Name.Name - } - } - } - } - if pkgName == "." { - return ast.NewIdent(t.Obj().Name()) - } - return &ast.SelectorExpr{ - X: ast.NewIdent(pkgName), - Sel: ast.NewIdent(t.Obj().Name()), - } - default: - return nil // TODO: anonymous structs, but who does that - } -} - -var GetTypeErrors = func(p interface{}) []types.Error { return nil } -var SetTypeErrors = func(p interface{}, errors []types.Error) {} - -type TypeErrorPass string - -const ( - NoNewVars TypeErrorPass = "nonewvars" - NoResultValues TypeErrorPass = "noresultvalues" - UndeclaredName TypeErrorPass = "undeclaredname" -) diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go index ff4f9d5aa..f516e1762 100644 --- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go +++ b/vendor/golang.org/x/tools/internal/gocommand/invoke.go @@ -23,9 +23,24 @@ import ( // An Runner will run go command invocations and serialize // them if it sees a concurrency error. type Runner struct { - // LoadMu guards packages.Load calls and associated state. - loadMu sync.Mutex - serializeLoads int + // once guards the runner initialization. + once sync.Once + + // inFlight tracks available workers. + inFlight chan struct{} + + // serialized guards the ability to run a go command serially, + // to avoid deadlocks when claiming workers. + serialized chan struct{} +} + +const maxInFlight = 10 + +func (runner *Runner) initialize() { + runner.once.Do(func() { + runner.inFlight = make(chan struct{}, maxInFlight) + runner.serialized = make(chan struct{}, 1) + }) } // 1.13: go: updates to go.mod needed, but contents have changed @@ -35,7 +50,7 @@ var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed // Run is a convenience wrapper around RunRaw. // It returns only stdout and a "friendly" error. func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) { - stdout, _, friendly, _ := runner.runRaw(ctx, inv) + stdout, _, friendly, _ := runner.RunRaw(ctx, inv) return stdout, friendly } @@ -49,57 +64,67 @@ func (runner *Runner) RunPiped(ctx context.Context, inv Invocation, stdout, stde // RunRaw runs the invocation, serializing requests only if they fight over // go.mod changes. func (runner *Runner) RunRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - return runner.runRaw(ctx, inv) + // Make sure the runner is always initialized. + runner.initialize() + + // First, try to run the go command concurrently. + stdout, stderr, friendlyErr, err := runner.runConcurrent(ctx, inv) + + // If we encounter a load concurrency error, we need to retry serially. + if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) { + return stdout, stderr, friendlyErr, err + } + event.Error(ctx, "Load concurrency error, will retry serially", err) + + // Run serially by calling runPiped. + stdout.Reset() + stderr.Reset() + friendlyErr, err = runner.runPiped(ctx, inv, stdout, stderr) + return stdout, stderr, friendlyErr, err +} + +func (runner *Runner) runConcurrent(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { + // Wait for 1 worker to become available. + select { + case <-ctx.Done(): + return nil, nil, nil, ctx.Err() + case runner.inFlight <- struct{}{}: + defer func() { <-runner.inFlight }() + } + + stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} + friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) + return stdout, stderr, friendlyErr, err } func (runner *Runner) runPiped(ctx context.Context, inv Invocation, stdout, stderr io.Writer) (error, error) { - runner.loadMu.Lock() - runner.serializeLoads++ + // Make sure the runner is always initialized. + runner.initialize() - defer func() { - runner.serializeLoads-- - runner.loadMu.Unlock() - }() + // Acquire the serialization lock. This avoids deadlocks between two + // runPiped commands. + select { + case <-ctx.Done(): + return nil, ctx.Err() + case runner.serialized <- struct{}{}: + defer func() { <-runner.serialized }() + } + + // Wait for all in-progress go commands to return before proceeding, + // to avoid load concurrency errors. + for i := 0; i < maxInFlight; i++ { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case runner.inFlight <- struct{}{}: + // Make sure we always "return" any workers we took. + defer func() { <-runner.inFlight }() + } + } return inv.runWithFriendlyError(ctx, stdout, stderr) } -func (runner *Runner) runRaw(ctx context.Context, inv Invocation) (*bytes.Buffer, *bytes.Buffer, error, error) { - // We want to run invocations concurrently as much as possible. However, - // if go.mod updates are needed, only one can make them and the others will - // fail. We need to retry in those cases, but we don't want to thrash so - // badly we never recover. To avoid that, once we've seen one concurrency - // error, start serializing everything until the backlog has cleared out. - runner.loadMu.Lock() - var locked bool // If true, we hold the mutex and have incremented. - if runner.serializeLoads == 0 { - runner.loadMu.Unlock() - } else { - locked = true - runner.serializeLoads++ - } - defer func() { - if locked { - locked = false - runner.serializeLoads-- - runner.loadMu.Unlock() - } - }() - - for { - stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{} - friendlyErr, err := inv.runWithFriendlyError(ctx, stdout, stderr) - if friendlyErr == nil || !modConcurrencyError.MatchString(friendlyErr.Error()) { - return stdout, stderr, friendlyErr, err - } - event.Error(ctx, "Load concurrency error, will retry serially", err) - if !locked { - runner.loadMu.Lock() - runner.serializeLoads++ - } - } -} - // An Invocation represents a call to the go command. type Invocation struct { Verb string @@ -160,7 +185,6 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error { cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir) cmd.Dir = i.WorkingDir } - defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now()) return runCmdContext(ctx, cmd) diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go index 36292d79a..2c7030765 100644 --- a/vendor/golang.org/x/tools/internal/imports/fix.go +++ b/vendor/golang.org/x/tools/internal/imports/fix.go @@ -7,6 +7,7 @@ package imports import ( "bytes" "context" + "encoding/json" "fmt" "go/ast" "go/build" @@ -598,7 +599,7 @@ func getCandidatePkgs(ctx context.Context, wrappedCallback *scanCallback, filena // Start off with the standard library. for importPath, exports := range stdlib { p := &pkg{ - dir: filepath.Join(env.GOROOT, "src", importPath), + dir: filepath.Join(env.goroot(), "src", importPath), importPathShort: importPath, packageName: path.Base(importPath), relevance: MaxRelevance, @@ -743,6 +744,8 @@ func getPackageExports(ctx context.Context, wrapped func(PackageExport), searchP return getCandidatePkgs(ctx, callback, filename, filePkg, env) } +var RequiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB"} + // ProcessEnv contains environment variables and settings that affect the use of // the go command, the go/build package, etc. type ProcessEnv struct { @@ -752,10 +755,13 @@ type ProcessEnv struct { BuildFlags []string - // If non-empty, these will be used instead of the - // process-wide values. - GOPATH, GOROOT, GO111MODULE, GOPROXY, GOFLAGS, GOSUMDB string - WorkingDir string + // Env overrides the OS environment, and can be used to specify + // GOPROXY, GO111MODULE, etc. PATH cannot be set here, because + // exec.Command will not honor it. + // Specifying all of RequiredGoEnvVars avoids a call to `go env`. + Env map[string]string + + WorkingDir string // If Logf is non-nil, debug logging is enabled through this function. Logf func(format string, args ...interface{}) @@ -763,6 +769,22 @@ type ProcessEnv struct { resolver Resolver } +func (e *ProcessEnv) goroot() string { + return e.mustGetEnv("GOROOT") +} + +func (e *ProcessEnv) gopath() string { + return e.mustGetEnv("GOPATH") +} + +func (e *ProcessEnv) mustGetEnv(k string) string { + v, ok := e.Env[k] + if !ok { + panic(fmt.Sprintf("%v not set in evaluated environment", k)) + } + return v +} + // CopyConfig copies the env's configuration into a new env. func (e *ProcessEnv) CopyConfig() *ProcessEnv { copy := *e @@ -770,21 +792,40 @@ func (e *ProcessEnv) CopyConfig() *ProcessEnv { return © } -func (e *ProcessEnv) env() []string { - env := os.Environ() - add := func(k, v string) { - if v != "" { - env = append(env, k+"="+v) +func (e *ProcessEnv) init() error { + foundAllRequired := true + for _, k := range RequiredGoEnvVars { + if _, ok := e.Env[k]; !ok { + foundAllRequired = false + break } } - add("GOPATH", e.GOPATH) - add("GOROOT", e.GOROOT) - add("GO111MODULE", e.GO111MODULE) - add("GOPROXY", e.GOPROXY) - add("GOFLAGS", e.GOFLAGS) - add("GOSUMDB", e.GOSUMDB) - if e.WorkingDir != "" { - add("PWD", e.WorkingDir) + if foundAllRequired { + return nil + } + + if e.Env == nil { + e.Env = map[string]string{} + } + + goEnv := map[string]string{} + stdout, err := e.invokeGo(context.TODO(), "env", append([]string{"-json"}, RequiredGoEnvVars...)...) + if err != nil { + return err + } + if err := json.Unmarshal(stdout.Bytes(), &goEnv); err != nil { + return err + } + for k, v := range goEnv { + e.Env[k] = v + } + return nil +} + +func (e *ProcessEnv) env() []string { + var env []string // the gocommand package will prepend os.Environ. + for k, v := range e.Env { + env = append(env, k+"="+v) } return env } @@ -793,8 +834,7 @@ func (e *ProcessEnv) GetResolver() Resolver { if e.resolver != nil { return e.resolver } - out, err := e.invokeGo(context.TODO(), "env", "GOMOD") - if err != nil || len(bytes.TrimSpace(out.Bytes())) == 0 { + if len(e.Env["GOMOD"]) == 0 { e.resolver = newGopathResolver(e) return e.resolver } @@ -804,8 +844,8 @@ func (e *ProcessEnv) GetResolver() Resolver { func (e *ProcessEnv) buildContext() *build.Context { ctx := build.Default - ctx.GOROOT = e.GOROOT - ctx.GOPATH = e.GOPATH + ctx.GOROOT = e.goroot() + ctx.GOPATH = e.gopath() // As of Go 1.14, build.Context has a Dir field // (see golang.org/issue/34860). @@ -839,7 +879,7 @@ func (e *ProcessEnv) invokeGo(ctx context.Context, verb string, args ...string) func addStdlibCandidates(pass *pass, refs references) { add := func(pkg string) { // Prevent self-imports. - if path.Base(pkg) == pass.f.Name.Name && filepath.Join(pass.env.GOROOT, "src", pkg) == pass.srcDir { + if path.Base(pkg) == pass.f.Name.Name && filepath.Join(pass.env.goroot(), "src", pkg) == pass.srcDir { return } exports := copyExports(stdlib[pkg]) diff --git a/vendor/golang.org/x/tools/internal/imports/imports.go b/vendor/golang.org/x/tools/internal/imports/imports.go index f43d6b22e..04ecdfda3 100644 --- a/vendor/golang.org/x/tools/internal/imports/imports.go +++ b/vendor/golang.org/x/tools/internal/imports/imports.go @@ -14,14 +14,12 @@ import ( "context" "fmt" "go/ast" - "go/build" "go/format" "go/parser" "go/printer" "go/token" "io" "io/ioutil" - "os" "regexp" "strconv" "strings" @@ -146,19 +144,16 @@ func initialize(filename string, src []byte, opt *Options) ([]byte, *Options, er // Set the env if the user has not provided it. if opt.Env == nil { - opt.Env = &ProcessEnv{ - GOPATH: build.Default.GOPATH, - GOROOT: build.Default.GOROOT, - GOFLAGS: os.Getenv("GOFLAGS"), - GO111MODULE: os.Getenv("GO111MODULE"), - GOPROXY: os.Getenv("GOPROXY"), - GOSUMDB: os.Getenv("GOSUMDB"), - } + opt.Env = &ProcessEnv{} } // Set the gocmdRunner if the user has not provided it. if opt.Env.GocmdRunner == nil { opt.Env.GocmdRunner = &gocommand.Runner{} } + if err := opt.Env.init(); err != nil { + return nil, nil, err + } + if src == nil { b, err := ioutil.ReadFile(filename) if err != nil { diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go index 4e816e8bc..664fbbf5b 100644 --- a/vendor/golang.org/x/tools/internal/imports/mod.go +++ b/vendor/golang.org/x/tools/internal/imports/mod.go @@ -79,7 +79,11 @@ func (r *ModuleResolver) init() error { r.initAllMods() } - r.moduleCacheDir = filepath.Join(filepath.SplitList(r.env.GOPATH)[0], "/pkg/mod") + if gmc := r.env.Env["GOMODCACHE"]; gmc != "" { + r.moduleCacheDir = gmc + } else { + r.moduleCacheDir = filepath.Join(filepath.SplitList(r.env.gopath())[0], "/pkg/mod") + } sort.Slice(r.modsByModPath, func(i, j int) bool { count := func(x int) int { @@ -95,7 +99,7 @@ func (r *ModuleResolver) init() error { }) r.roots = []gopathwalk.Root{ - {filepath.Join(r.env.GOROOT, "/src"), gopathwalk.RootGOROOT}, + {filepath.Join(r.env.goroot(), "/src"), gopathwalk.RootGOROOT}, } if r.main != nil { r.roots = append(r.roots, gopathwalk.Root{r.main.Dir, gopathwalk.RootCurrentModule}) diff --git a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go b/vendor/golang.org/x/tools/internal/packagesinternal/packages.go deleted file mode 100644 index 2c4527f24..000000000 --- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go +++ /dev/null @@ -1,14 +0,0 @@ -// Package packagesinternal exposes internal-only fields from go/packages. -package packagesinternal - -import ( - "golang.org/x/tools/internal/gocommand" -) - -var GetForTest = func(p interface{}) string { return "" } - -var GetGoCmdRunner = func(config interface{}) *gocommand.Runner { return nil } - -var SetGoCmdRunner = func(config interface{}, runner *gocommand.Runner) {} - -var TypecheckCgo int diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go deleted file mode 100644 index a5bb408e2..000000000 --- a/vendor/golang.org/x/tools/internal/typesinternal/types.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typesinternal - -import ( - "go/types" - "reflect" - "unsafe" -) - -func SetUsesCgo(conf *types.Config) bool { - v := reflect.ValueOf(conf).Elem() - - f := v.FieldByName("go115UsesCgo") - if !f.IsValid() { - f = v.FieldByName("UsesCgo") - if !f.IsValid() { - return false - } - } - - addr := unsafe.Pointer(f.UnsafeAddr()) - *(*bool)(addr) = true - - return true -} diff --git a/vendor/google.golang.org/grpc/.travis.yml b/vendor/google.golang.org/grpc/.travis.yml index a11e8cbca..0e24e59f0 100644 --- a/vendor/google.golang.org/grpc/.travis.yml +++ b/vendor/google.golang.org/grpc/.travis.yml @@ -2,19 +2,19 @@ language: go matrix: include: - - go: 1.13.x + - go: 1.14.x env: VET=1 GO111MODULE=on - - go: 1.13.x + - go: 1.14.x env: RACE=1 GO111MODULE=on - - go: 1.13.x + - go: 1.14.x env: RUN386=1 - - go: 1.13.x + - go: 1.14.x env: GRPC_GO_RETRY=on - - go: 1.13.x + - go: 1.14.x env: TESTEXTRAS=1 - - go: 1.12.x + - go: 1.13.x env: GO111MODULE=on - - go: 1.11.x + - go: 1.12.x env: GO111MODULE=on - go: 1.9.x env: GAE=1 diff --git a/vendor/google.golang.org/grpc/README.md b/vendor/google.golang.org/grpc/README.md index 800e7bd4c..249cd2063 100644 --- a/vendor/google.golang.org/grpc/README.md +++ b/vendor/google.golang.org/grpc/README.md @@ -7,7 +7,7 @@ The Go implementation of [gRPC](https://grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start: -Go](https://grpc.io/docs/quickstart/go.html) guide. +Go](https://grpc.io/docs/languages/go/quickstart/) guide. Installation ------------ @@ -29,7 +29,8 @@ If you are trying to access grpc-go from within China, please see the Prerequisites ------------- -gRPC-Go requires Go 1.9 or later. +gRPC-Go officially supports the +[three latest major releases of Go](https://golang.org/doc/devel/release.html). Documentation ------------- diff --git a/vendor/google.golang.org/grpc/attributes/attributes.go b/vendor/google.golang.org/grpc/attributes/attributes.go index 68ffc6201..ee5c51e6c 100644 --- a/vendor/google.golang.org/grpc/attributes/attributes.go +++ b/vendor/google.golang.org/grpc/attributes/attributes.go @@ -50,6 +50,9 @@ func New(kvs ...interface{}) *Attributes { // times, the last value overwrites all previous values for that key. To // remove an existing key, use a nil value. func (a *Attributes) WithValues(kvs ...interface{}) *Attributes { + if a == nil { + return New(kvs...) + } if len(kvs)%2 != 0 { panic(fmt.Sprintf("attributes.New called with unexpected input: len(kvs) = %v", len(kvs))) } @@ -66,5 +69,8 @@ func (a *Attributes) WithValues(kvs ...interface{}) *Attributes { // Value returns the value associated with these attributes for key, or nil if // no value is associated with key. func (a *Attributes) Value(key interface{}) interface{} { + if a == nil { + return nil + } return a.m[key] } diff --git a/vendor/google.golang.org/grpc/balancer.go b/vendor/google.golang.org/grpc/balancer.go deleted file mode 100644 index a8eb0f476..000000000 --- a/vendor/google.golang.org/grpc/balancer.go +++ /dev/null @@ -1,391 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "context" - "net" - "sync" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/credentials" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/naming" - "google.golang.org/grpc/status" -) - -// Address represents a server the client connects to. -// -// Deprecated: please use package balancer. -type Address struct { - // Addr is the server address on which a connection will be established. - Addr string - // Metadata is the information associated with Addr, which may be used - // to make load balancing decision. - Metadata interface{} -} - -// BalancerConfig specifies the configurations for Balancer. -// -// Deprecated: please use package balancer. May be removed in a future 1.x release. -type BalancerConfig struct { - // DialCreds is the transport credential the Balancer implementation can - // use to dial to a remote load balancer server. The Balancer implementations - // can ignore this if it does not need to talk to another party securely. - DialCreds credentials.TransportCredentials - // Dialer is the custom dialer the Balancer implementation can use to dial - // to a remote load balancer server. The Balancer implementations - // can ignore this if it doesn't need to talk to remote balancer. - Dialer func(context.Context, string) (net.Conn, error) -} - -// BalancerGetOptions configures a Get call. -// -// Deprecated: please use package balancer. May be removed in a future 1.x release. -type BalancerGetOptions struct { - // BlockingWait specifies whether Get should block when there is no - // connected address. - BlockingWait bool -} - -// Balancer chooses network addresses for RPCs. -// -// Deprecated: please use package balancer. May be removed in a future 1.x release. -type Balancer interface { - // Start does the initialization work to bootstrap a Balancer. For example, - // this function may start the name resolution and watch the updates. It will - // be called when dialing. - Start(target string, config BalancerConfig) error - // Up informs the Balancer that gRPC has a connection to the server at - // addr. It returns down which is called once the connection to addr gets - // lost or closed. - // TODO: It is not clear how to construct and take advantage of the meaningful error - // parameter for down. Need realistic demands to guide. - Up(addr Address) (down func(error)) - // Get gets the address of a server for the RPC corresponding to ctx. - // i) If it returns a connected address, gRPC internals issues the RPC on the - // connection to this address; - // ii) If it returns an address on which the connection is under construction - // (initiated by Notify(...)) but not connected, gRPC internals - // * fails RPC if the RPC is fail-fast and connection is in the TransientFailure or - // Shutdown state; - // or - // * issues RPC on the connection otherwise. - // iii) If it returns an address on which the connection does not exist, gRPC - // internals treats it as an error and will fail the corresponding RPC. - // - // Therefore, the following is the recommended rule when writing a custom Balancer. - // If opts.BlockingWait is true, it should return a connected address or - // block if there is no connected address. It should respect the timeout or - // cancellation of ctx when blocking. If opts.BlockingWait is false (for fail-fast - // RPCs), it should return an address it has notified via Notify(...) immediately - // instead of blocking. - // - // The function returns put which is called once the rpc has completed or failed. - // put can collect and report RPC stats to a remote load balancer. - // - // This function should only return the errors Balancer cannot recover by itself. - // gRPC internals will fail the RPC if an error is returned. - Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) - // Notify returns a channel that is used by gRPC internals to watch the addresses - // gRPC needs to connect. The addresses might be from a name resolver or remote - // load balancer. gRPC internals will compare it with the existing connected - // addresses. If the address Balancer notified is not in the existing connected - // addresses, gRPC starts to connect the address. If an address in the existing - // connected addresses is not in the notification list, the corresponding connection - // is shutdown gracefully. Otherwise, there are no operations to take. Note that - // the Address slice must be the full list of the Addresses which should be connected. - // It is NOT delta. - Notify() <-chan []Address - // Close shuts down the balancer. - Close() error -} - -// RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch -// the name resolution updates and updates the addresses available correspondingly. -// -// Deprecated: please use package balancer/roundrobin. May be removed in a future 1.x release. -func RoundRobin(r naming.Resolver) Balancer { - return &roundRobin{r: r} -} - -type addrInfo struct { - addr Address - connected bool -} - -type roundRobin struct { - r naming.Resolver - w naming.Watcher - addrs []*addrInfo // all the addresses the client should potentially connect - mu sync.Mutex - addrCh chan []Address // the channel to notify gRPC internals the list of addresses the client should connect to. - next int // index of the next address to return for Get() - waitCh chan struct{} // the channel to block when there is no connected address available - done bool // The Balancer is closed. -} - -func (rr *roundRobin) watchAddrUpdates() error { - updates, err := rr.w.Next() - if err != nil { - grpclog.Warningf("grpc: the naming watcher stops working due to %v.", err) - return err - } - rr.mu.Lock() - defer rr.mu.Unlock() - for _, update := range updates { - addr := Address{ - Addr: update.Addr, - Metadata: update.Metadata, - } - switch update.Op { - case naming.Add: - var exist bool - for _, v := range rr.addrs { - if addr == v.addr { - exist = true - grpclog.Infoln("grpc: The name resolver wanted to add an existing address: ", addr) - break - } - } - if exist { - continue - } - rr.addrs = append(rr.addrs, &addrInfo{addr: addr}) - case naming.Delete: - for i, v := range rr.addrs { - if addr == v.addr { - copy(rr.addrs[i:], rr.addrs[i+1:]) - rr.addrs = rr.addrs[:len(rr.addrs)-1] - break - } - } - default: - grpclog.Errorln("Unknown update.Op ", update.Op) - } - } - // Make a copy of rr.addrs and write it onto rr.addrCh so that gRPC internals gets notified. - open := make([]Address, len(rr.addrs)) - for i, v := range rr.addrs { - open[i] = v.addr - } - if rr.done { - return ErrClientConnClosing - } - select { - case <-rr.addrCh: - default: - } - rr.addrCh <- open - return nil -} - -func (rr *roundRobin) Start(target string, config BalancerConfig) error { - rr.mu.Lock() - defer rr.mu.Unlock() - if rr.done { - return ErrClientConnClosing - } - if rr.r == nil { - // If there is no name resolver installed, it is not needed to - // do name resolution. In this case, target is added into rr.addrs - // as the only address available and rr.addrCh stays nil. - rr.addrs = append(rr.addrs, &addrInfo{addr: Address{Addr: target}}) - return nil - } - w, err := rr.r.Resolve(target) - if err != nil { - return err - } - rr.w = w - rr.addrCh = make(chan []Address, 1) - go func() { - for { - if err := rr.watchAddrUpdates(); err != nil { - return - } - } - }() - return nil -} - -// Up sets the connected state of addr and sends notification if there are pending -// Get() calls. -func (rr *roundRobin) Up(addr Address) func(error) { - rr.mu.Lock() - defer rr.mu.Unlock() - var cnt int - for _, a := range rr.addrs { - if a.addr == addr { - if a.connected { - return nil - } - a.connected = true - } - if a.connected { - cnt++ - } - } - // addr is only one which is connected. Notify the Get() callers who are blocking. - if cnt == 1 && rr.waitCh != nil { - close(rr.waitCh) - rr.waitCh = nil - } - return func(err error) { - rr.down(addr, err) - } -} - -// down unsets the connected state of addr. -func (rr *roundRobin) down(addr Address, err error) { - rr.mu.Lock() - defer rr.mu.Unlock() - for _, a := range rr.addrs { - if addr == a.addr { - a.connected = false - break - } - } -} - -// Get returns the next addr in the rotation. -func (rr *roundRobin) Get(ctx context.Context, opts BalancerGetOptions) (addr Address, put func(), err error) { - var ch chan struct{} - rr.mu.Lock() - if rr.done { - rr.mu.Unlock() - err = ErrClientConnClosing - return - } - - if len(rr.addrs) > 0 { - if rr.next >= len(rr.addrs) { - rr.next = 0 - } - next := rr.next - for { - a := rr.addrs[next] - next = (next + 1) % len(rr.addrs) - if a.connected { - addr = a.addr - rr.next = next - rr.mu.Unlock() - return - } - if next == rr.next { - // Has iterated all the possible address but none is connected. - break - } - } - } - if !opts.BlockingWait { - if len(rr.addrs) == 0 { - rr.mu.Unlock() - err = status.Errorf(codes.Unavailable, "there is no address available") - return - } - // Returns the next addr on rr.addrs for failfast RPCs. - addr = rr.addrs[rr.next].addr - rr.next++ - rr.mu.Unlock() - return - } - // Wait on rr.waitCh for non-failfast RPCs. - if rr.waitCh == nil { - ch = make(chan struct{}) - rr.waitCh = ch - } else { - ch = rr.waitCh - } - rr.mu.Unlock() - for { - select { - case <-ctx.Done(): - err = ctx.Err() - return - case <-ch: - rr.mu.Lock() - if rr.done { - rr.mu.Unlock() - err = ErrClientConnClosing - return - } - - if len(rr.addrs) > 0 { - if rr.next >= len(rr.addrs) { - rr.next = 0 - } - next := rr.next - for { - a := rr.addrs[next] - next = (next + 1) % len(rr.addrs) - if a.connected { - addr = a.addr - rr.next = next - rr.mu.Unlock() - return - } - if next == rr.next { - // Has iterated all the possible address but none is connected. - break - } - } - } - // The newly added addr got removed by Down() again. - if rr.waitCh == nil { - ch = make(chan struct{}) - rr.waitCh = ch - } else { - ch = rr.waitCh - } - rr.mu.Unlock() - } - } -} - -func (rr *roundRobin) Notify() <-chan []Address { - return rr.addrCh -} - -func (rr *roundRobin) Close() error { - rr.mu.Lock() - defer rr.mu.Unlock() - if rr.done { - return errBalancerClosed - } - rr.done = true - if rr.w != nil { - rr.w.Close() - } - if rr.waitCh != nil { - close(rr.waitCh) - rr.waitCh = nil - } - if rr.addrCh != nil { - close(rr.addrCh) - } - return nil -} - -// pickFirst is used to test multi-addresses in one addrConn in which all addresses share the same addrConn. -// It is a wrapper around roundRobin balancer. The logic of all methods works fine because balancer.Get() -// returns the only address Up by resetTransport(). -type pickFirst struct { - *roundRobin -} diff --git a/vendor/google.golang.org/grpc/balancer/balancer.go b/vendor/google.golang.org/grpc/balancer/balancer.go index 9258858ed..e75b28436 100644 --- a/vendor/google.golang.org/grpc/balancer/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/balancer.go @@ -111,6 +111,9 @@ type NewSubConnOptions struct { // CredsBundle is the credentials bundle that will be used in the created // SubConn. If it's nil, the original creds from grpc DialOptions will be // used. + // + // Deprecated: Use the Attributes field in resolver.Address to pass + // arbitrary data to the credential handshaker. CredsBundle credentials.Bundle // HealthCheckEnabled indicates whether health check service should be // enabled on this SubConn @@ -123,7 +126,7 @@ type State struct { // determine the state of the ClientConn. ConnectivityState connectivity.State // Picker is used to choose connections (SubConns) for RPCs. - Picker V2Picker + Picker Picker } // ClientConn represents a gRPC ClientConn. @@ -141,20 +144,11 @@ type ClientConn interface { // The SubConn will be shutdown. RemoveSubConn(SubConn) - // UpdateBalancerState is called by balancer to notify gRPC that some internal - // state in balancer has changed. - // - // gRPC will update the connectivity state of the ClientConn, and will call pick - // on the new picker to pick new SubConn. - // - // Deprecated: use UpdateState instead - UpdateBalancerState(s connectivity.State, p Picker) - // UpdateState notifies gRPC that the balancer's internal state has // changed. // - // gRPC will update the connectivity state of the ClientConn, and will call pick - // on the new picker to pick new SubConns. + // gRPC will update the connectivity state of the ClientConn, and will call + // Pick on the new Picker to pick new SubConns. UpdateState(State) // ResolveNow is called by balancer to notify gRPC to do a name resolving. @@ -232,56 +226,17 @@ type DoneInfo struct { var ( // ErrNoSubConnAvailable indicates no SubConn is available for pick(). - // gRPC will block the RPC until a new picker is available via UpdateBalancerState(). + // gRPC will block the RPC until a new picker is available via UpdateState(). ErrNoSubConnAvailable = errors.New("no SubConn is available") // ErrTransientFailure indicates all SubConns are in TransientFailure. // WaitForReady RPCs will block, non-WaitForReady RPCs will fail. - ErrTransientFailure = TransientFailureError(errors.New("all SubConns are in TransientFailure")) + // + // Deprecated: return an appropriate error based on the last resolution or + // connection attempt instead. The behavior is the same for any non-gRPC + // status error. + ErrTransientFailure = errors.New("all SubConns are in TransientFailure") ) -// Picker is used by gRPC to pick a SubConn to send an RPC. -// Balancer is expected to generate a new picker from its snapshot every time its -// internal state has changed. -// -// The pickers used by gRPC can be updated by ClientConn.UpdateBalancerState(). -// -// Deprecated: use V2Picker instead -type Picker interface { - // Pick returns the SubConn to be used to send the RPC. - // The returned SubConn must be one returned by NewSubConn(). - // - // This functions is expected to return: - // - a SubConn that is known to be READY; - // - ErrNoSubConnAvailable if no SubConn is available, but progress is being - // made (for example, some SubConn is in CONNECTING mode); - // - other errors if no active connecting is happening (for example, all SubConn - // are in TRANSIENT_FAILURE mode). - // - // If a SubConn is returned: - // - If it is READY, gRPC will send the RPC on it; - // - If it is not ready, or becomes not ready after it's returned, gRPC will - // block until UpdateBalancerState() is called and will call pick on the - // new picker. The done function returned from Pick(), if not nil, will be - // called with nil error, no bytes sent and no bytes received. - // - // If the returned error is not nil: - // - If the error is ErrNoSubConnAvailable, gRPC will block until UpdateBalancerState() - // - If the error is ErrTransientFailure or implements IsTransientFailure() - // bool, returning true: - // - If the RPC is wait-for-ready, gRPC will block until UpdateBalancerState() - // is called to pick again; - // - Otherwise, RPC will fail with unavailable error. - // - Else (error is other non-nil error): - // - The RPC will fail with the error's status code, or Unknown if it is - // not a status error. - // - // The returned done() function will be called once the rpc has finished, - // with the final status of that RPC. If the SubConn returned is not a - // valid SubConn type, done may not be called. done may be nil if balancer - // doesn't care about the RPC status. - Pick(ctx context.Context, info PickInfo) (conn SubConn, done func(DoneInfo), err error) -} - // PickResult contains information related to a connection chosen for an RPC. type PickResult struct { // SubConn is the connection to use for this pick, if its state is Ready. @@ -297,24 +252,19 @@ type PickResult struct { Done func(DoneInfo) } -type transientFailureError struct { - error -} +// TransientFailureError returns e. It exists for backward compatibility and +// will be deleted soon. +// +// Deprecated: no longer necessary, picker errors are treated this way by +// default. +func TransientFailureError(e error) error { return e } -func (e *transientFailureError) IsTransientFailure() bool { return true } - -// TransientFailureError wraps err in an error implementing -// IsTransientFailure() bool, returning true. -func TransientFailureError(err error) error { - return &transientFailureError{error: err} -} - -// V2Picker is used by gRPC to pick a SubConn to send an RPC. +// Picker is used by gRPC to pick a SubConn to send an RPC. // Balancer is expected to generate a new picker from its snapshot every time its // internal state has changed. // -// The pickers used by gRPC can be updated by ClientConn.UpdateBalancerState(). -type V2Picker interface { +// The pickers used by gRPC can be updated by ClientConn.UpdateState(). +type Picker interface { // Pick returns the connection to use for this RPC and related information. // // Pick should not block. If the balancer needs to do I/O or any blocking @@ -327,14 +277,13 @@ type V2Picker interface { // - If the error is ErrNoSubConnAvailable, gRPC will block until a new // Picker is provided by the balancer (using ClientConn.UpdateState). // - // - If the error implements IsTransientFailure() bool, returning true, - // wait for ready RPCs will wait, but non-wait for ready RPCs will be - // terminated with this error's Error() string and status code - // Unavailable. + // - If the error is a status error (implemented by the grpc/status + // package), gRPC will terminate the RPC with the code and message + // provided. // - // - Any other errors terminate all RPCs with the code and message - // provided. If the error is not a status error, it will be converted by - // gRPC to a status error with code Unknown. + // - For all other errors, wait for ready RPCs will wait, but non-wait for + // ready RPCs will be terminated with this error's Error() string and + // status code Unavailable. Pick(info PickInfo) (PickResult, error) } @@ -343,34 +292,36 @@ type V2Picker interface { // // It also generates and updates the Picker used by gRPC to pick SubConns for RPCs. // -// HandleSubConnectionStateChange, HandleResolvedAddrs and Close are guaranteed -// to be called synchronously from the same goroutine. -// There's no guarantee on picker.Pick, it may be called anytime. +// UpdateClientConnState, ResolverError, UpdateSubConnState, and Close are +// guaranteed to be called synchronously from the same goroutine. There's no +// guarantee on picker.Pick, it may be called anytime. type Balancer interface { - // HandleSubConnStateChange is called by gRPC when the connectivity state - // of sc has changed. - // Balancer is expected to aggregate all the state of SubConn and report - // that back to gRPC. - // Balancer should also generate and update Pickers when its internal state has - // been changed by the new state. - // - // Deprecated: if V2Balancer is implemented by the Balancer, - // UpdateSubConnState will be called instead. - HandleSubConnStateChange(sc SubConn, state connectivity.State) - // HandleResolvedAddrs is called by gRPC to send updated resolved addresses to - // balancers. - // Balancer can create new SubConn or remove SubConn with the addresses. - // An empty address slice and a non-nil error will be passed if the resolver returns - // non-nil error to gRPC. - // - // Deprecated: if V2Balancer is implemented by the Balancer, - // UpdateClientConnState will be called instead. - HandleResolvedAddrs([]resolver.Address, error) + // UpdateClientConnState is called by gRPC when the state of the ClientConn + // changes. If the error returned is ErrBadResolverState, the ClientConn + // will begin calling ResolveNow on the active name resolver with + // exponential backoff until a subsequent call to UpdateClientConnState + // returns a nil error. Any other errors are currently ignored. + UpdateClientConnState(ClientConnState) error + // ResolverError is called by gRPC when the name resolver reports an error. + ResolverError(error) + // UpdateSubConnState is called by gRPC when the state of a SubConn + // changes. + UpdateSubConnState(SubConn, SubConnState) // Close closes the balancer. The balancer is not required to call // ClientConn.RemoveSubConn for its existing SubConns. Close() } +// V2Balancer is temporarily defined for backward compatibility reasons. +// +// Deprecated: use Balancer directly instead. +type V2Balancer = Balancer + +// V2Picker is temporarily defined for backward compatibility reasons. +// +// Deprecated: use Picker directly instead. +type V2Picker = Picker + // SubConnState describes the state of a SubConn. type SubConnState struct { // ConnectivityState is the connectivity state of the SubConn. @@ -393,27 +344,6 @@ type ClientConnState struct { // problem with the provided name resolver data. var ErrBadResolverState = errors.New("bad resolver state") -// V2Balancer is defined for documentation purposes. If a Balancer also -// implements V2Balancer, its UpdateClientConnState method will be called -// instead of HandleResolvedAddrs and its UpdateSubConnState will be called -// instead of HandleSubConnStateChange. -type V2Balancer interface { - // UpdateClientConnState is called by gRPC when the state of the ClientConn - // changes. If the error returned is ErrBadResolverState, the ClientConn - // will begin calling ResolveNow on the active name resolver with - // exponential backoff until a subsequent call to UpdateClientConnState - // returns a nil error. Any other errors are currently ignored. - UpdateClientConnState(ClientConnState) error - // ResolverError is called by gRPC when the name resolver reports an error. - ResolverError(error) - // UpdateSubConnState is called by gRPC when the state of a SubConn - // changes. - UpdateSubConnState(SubConn, SubConnState) - // Close closes the balancer. The balancer is not required to call - // ClientConn.RemoveSubConn for its existing SubConns. - Close() -} - // ConnectivityStateEvaluator takes the connectivity states of multiple SubConns // and returns one aggregated connectivity state. // diff --git a/vendor/google.golang.org/grpc/balancer/base/balancer.go b/vendor/google.golang.org/grpc/balancer/base/balancer.go index 80559b80a..d62b4b606 100644 --- a/vendor/google.golang.org/grpc/balancer/base/balancer.go +++ b/vendor/google.golang.org/grpc/balancer/base/balancer.go @@ -19,7 +19,6 @@ package base import ( - "context" "errors" "fmt" @@ -30,17 +29,15 @@ import ( ) type baseBuilder struct { - name string - pickerBuilder PickerBuilder - v2PickerBuilder V2PickerBuilder - config Config + name string + pickerBuilder PickerBuilder + config Config } func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) balancer.Balancer { bal := &baseBalancer{ - cc: cc, - pickerBuilder: bb.pickerBuilder, - v2PickerBuilder: bb.v2PickerBuilder, + cc: cc, + pickerBuilder: bb.pickerBuilder, subConns: make(map[resolver.Address]balancer.SubConn), scStates: make(map[balancer.SubConn]connectivity.State), @@ -50,11 +47,7 @@ func (bb *baseBuilder) Build(cc balancer.ClientConn, opt balancer.BuildOptions) // Initialize picker to a picker that always returns // ErrNoSubConnAvailable, because when state of a SubConn changes, we // may call UpdateState with this picker. - if bb.pickerBuilder != nil { - bal.picker = NewErrPicker(balancer.ErrNoSubConnAvailable) - } else { - bal.v2Picker = NewErrPickerV2(balancer.ErrNoSubConnAvailable) - } + bal.picker = NewErrPicker(balancer.ErrNoSubConnAvailable) return bal } @@ -62,12 +55,9 @@ func (bb *baseBuilder) Name() string { return bb.name } -var _ balancer.V2Balancer = (*baseBalancer)(nil) // Assert that we implement V2Balancer - type baseBalancer struct { - cc balancer.ClientConn - pickerBuilder PickerBuilder - v2PickerBuilder V2PickerBuilder + cc balancer.ClientConn + pickerBuilder PickerBuilder csEvltr *balancer.ConnectivityStateEvaluator state connectivity.State @@ -75,40 +65,31 @@ type baseBalancer struct { subConns map[resolver.Address]balancer.SubConn scStates map[balancer.SubConn]connectivity.State picker balancer.Picker - v2Picker balancer.V2Picker config Config resolverErr error // the last error reported by the resolver; cleared on successful resolution connErr error // the last connection error; cleared upon leaving TransientFailure } -func (b *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) { - panic("not implemented") -} - func (b *baseBalancer) ResolverError(err error) { b.resolverErr = err if len(b.subConns) == 0 { b.state = connectivity.TransientFailure } + if b.state != connectivity.TransientFailure { // The picker will not change since the balancer does not currently // report an error. return } b.regeneratePicker() - if b.picker != nil { - b.cc.UpdateBalancerState(b.state, b.picker) - } else { - b.cc.UpdateState(balancer.State{ - ConnectivityState: b.state, - Picker: b.v2Picker, - }) - } + b.cc.UpdateState(balancer.State{ + ConnectivityState: b.state, + Picker: b.picker, + }) } func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error { - // TODO: handle s.ResolverState.Err (log if not nil) once implemented. // TODO: handle s.ResolverState.ServiceConfig? if grpclog.V(2) { grpclog.Infoln("base.baseBalancer: got new ClientConn state: ", s) @@ -137,7 +118,7 @@ func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) error { b.cc.RemoveSubConn(sc) delete(b.subConns, a) // Keep the state of this sc in b.scStates until sc's state becomes Shutdown. - // The entry will be deleted in HandleSubConnStateChange. + // The entry will be deleted in UpdateSubConnState. } } // If resolver state contains no addresses, return an error so ClientConn @@ -171,38 +152,18 @@ func (b *baseBalancer) mergeErrors() error { // - built by the pickerBuilder with all READY SubConns otherwise. func (b *baseBalancer) regeneratePicker() { if b.state == connectivity.TransientFailure { - if b.pickerBuilder != nil { - b.picker = NewErrPicker(balancer.ErrTransientFailure) - } else { - b.v2Picker = NewErrPickerV2(balancer.TransientFailureError(b.mergeErrors())) - } + b.picker = NewErrPicker(b.mergeErrors()) return } - if b.pickerBuilder != nil { - readySCs := make(map[resolver.Address]balancer.SubConn) + readySCs := make(map[balancer.SubConn]SubConnInfo) - // Filter out all ready SCs from full subConn map. - for addr, sc := range b.subConns { - if st, ok := b.scStates[sc]; ok && st == connectivity.Ready { - readySCs[addr] = sc - } + // Filter out all ready SCs from full subConn map. + for addr, sc := range b.subConns { + if st, ok := b.scStates[sc]; ok && st == connectivity.Ready { + readySCs[sc] = SubConnInfo{Address: addr} } - b.picker = b.pickerBuilder.Build(readySCs) - } else { - readySCs := make(map[balancer.SubConn]SubConnInfo) - - // Filter out all ready SCs from full subConn map. - for addr, sc := range b.subConns { - if st, ok := b.scStates[sc]; ok && st == connectivity.Ready { - readySCs[sc] = SubConnInfo{Address: addr} - } - } - b.v2Picker = b.v2PickerBuilder.Build(PickerBuildInfo{ReadySCs: readySCs}) } -} - -func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { - panic("not implemented") + b.picker = b.pickerBuilder.Build(PickerBuildInfo{ReadySCs: readySCs}) } func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { @@ -247,11 +208,7 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su b.regeneratePicker() } - if b.picker != nil { - b.cc.UpdateBalancerState(b.state, b.picker) - } else { - b.cc.UpdateState(balancer.State{ConnectivityState: b.state, Picker: b.v2Picker}) - } + b.cc.UpdateState(balancer.State{ConnectivityState: b.state, Picker: b.picker}) } // Close is a nop because base balancer doesn't have internal state to clean up, @@ -259,28 +216,20 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su func (b *baseBalancer) Close() { } -// NewErrPicker returns a picker that always returns err on Pick(). +// NewErrPicker returns a Picker that always returns err on Pick(). func NewErrPicker(err error) balancer.Picker { return &errPicker{err: err} } +// NewErrPickerV2 is temporarily defined for backward compatibility reasons. +// +// Deprecated: use NewErrPicker instead. +var NewErrPickerV2 = NewErrPicker + type errPicker struct { err error // Pick() always returns this err. } -func (p *errPicker) Pick(context.Context, balancer.PickInfo) (balancer.SubConn, func(balancer.DoneInfo), error) { - return nil, nil, p.err -} - -// NewErrPickerV2 returns a V2Picker that always returns err on Pick(). -func NewErrPickerV2(err error) balancer.V2Picker { - return &errPickerV2{err: err} -} - -type errPickerV2 struct { - err error // Pick() always returns this err. -} - -func (p *errPickerV2) Pick(info balancer.PickInfo) (balancer.PickResult, error) { +func (p *errPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) { return balancer.PickResult{}, p.err } diff --git a/vendor/google.golang.org/grpc/balancer/base/base.go b/vendor/google.golang.org/grpc/balancer/base/base.go index 4192918b9..c4fc89111 100644 --- a/vendor/google.golang.org/grpc/balancer/base/base.go +++ b/vendor/google.golang.org/grpc/balancer/base/base.go @@ -37,15 +37,8 @@ import ( // PickerBuilder creates balancer.Picker. type PickerBuilder interface { - // Build takes a slice of ready SubConns, and returns a picker that will be - // used by gRPC to pick a SubConn. - Build(readySCs map[resolver.Address]balancer.SubConn) balancer.Picker -} - -// V2PickerBuilder creates balancer.V2Picker. -type V2PickerBuilder interface { // Build returns a picker that will be used by gRPC to pick a SubConn. - Build(info PickerBuildInfo) balancer.V2Picker + Build(info PickerBuildInfo) balancer.Picker } // PickerBuildInfo contains information needed by the picker builder to @@ -62,20 +55,14 @@ type SubConnInfo struct { Address resolver.Address // the address used to create this SubConn } -// NewBalancerBuilder returns a balancer builder. The balancers -// built by this builder will use the picker builder to build pickers. -func NewBalancerBuilder(name string, pb PickerBuilder) balancer.Builder { - return NewBalancerBuilderWithConfig(name, pb, Config{}) -} - // Config contains the config info about the base balancer builder. type Config struct { // HealthCheck indicates whether health checking should be enabled for this specific balancer. HealthCheck bool } -// NewBalancerBuilderWithConfig returns a base balancer builder configured by the provided config. -func NewBalancerBuilderWithConfig(name string, pb PickerBuilder, config Config) balancer.Builder { +// NewBalancerBuilder returns a base balancer builder configured by the provided config. +func NewBalancerBuilder(name string, pb PickerBuilder, config Config) balancer.Builder { return &baseBuilder{ name: name, pickerBuilder: pb, @@ -83,11 +70,13 @@ func NewBalancerBuilderWithConfig(name string, pb PickerBuilder, config Config) } } -// NewBalancerBuilderV2 returns a base balancer builder configured by the provided config. -func NewBalancerBuilderV2(name string, pb V2PickerBuilder, config Config) balancer.Builder { - return &baseBuilder{ - name: name, - v2PickerBuilder: pb, - config: config, - } -} +// NewBalancerBuilderV2 is temporarily defined for backward compatibility +// reasons. +// +// Deprecated: use NewBalancerBuilder instead. +var NewBalancerBuilderV2 = NewBalancerBuilder + +// V2PickerBuilder is temporarily defined for backward compatibility reasons. +// +// Deprecated: use PickerBuilder instead. +type V2PickerBuilder = PickerBuilder diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go b/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go new file mode 100644 index 000000000..a24264a34 --- /dev/null +++ b/vendor/google.golang.org/grpc/balancer/grpclb/state/state.go @@ -0,0 +1,51 @@ +/* + * + * Copyright 2020 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package state declares grpclb types to be set by resolvers wishing to pass +// information to grpclb via resolver.State Attributes. +package state + +import ( + "google.golang.org/grpc/resolver" +) + +// keyType is the key to use for storing State in Attributes. +type keyType string + +const key = keyType("grpc.grpclb.state") + +// State contains gRPCLB-relevant data passed from the name resolver. +type State struct { + // BalancerAddresses contains the remote load balancer address(es). If + // set, overrides any resolver-provided addresses with Type of GRPCLB. + BalancerAddresses []resolver.Address +} + +// Set returns a copy of the provided state with attributes containing s. s's +// data should not be mutated after calling Set. +func Set(state resolver.State, s *State) resolver.State { + state.Attributes = state.Attributes.WithValues(key, s) + return state +} + +// Get returns the grpclb State in the resolver.State, or nil if not present. +// The returned data should not be mutated. +func Get(state resolver.State) *State { + s, _ := state.Attributes.Value(key).(*State) + return s +} diff --git a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go index d4d645501..a02b372cf 100644 --- a/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go +++ b/vendor/google.golang.org/grpc/balancer/roundrobin/roundrobin.go @@ -35,7 +35,7 @@ const Name = "round_robin" // newBuilder creates a new roundrobin balancer builder. func newBuilder() balancer.Builder { - return base.NewBalancerBuilderV2(Name, &rrPickerBuilder{}, base.Config{HealthCheck: true}) + return base.NewBalancerBuilder(Name, &rrPickerBuilder{}, base.Config{HealthCheck: true}) } func init() { @@ -44,10 +44,10 @@ func init() { type rrPickerBuilder struct{} -func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.V2Picker { +func (*rrPickerBuilder) Build(info base.PickerBuildInfo) balancer.Picker { grpclog.Infof("roundrobinPicker: newPicker called with info: %v", info) if len(info.ReadySCs) == 0 { - return base.NewErrPickerV2(balancer.ErrNoSubConnAvailable) + return base.NewErrPicker(balancer.ErrNoSubConnAvailable) } var scs []balancer.SubConn for sc := range info.ReadySCs { diff --git a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go index f8667a23f..807d19197 100644 --- a/vendor/google.golang.org/grpc/balancer_conn_wrappers.go +++ b/vendor/google.golang.org/grpc/balancer_conn_wrappers.go @@ -74,11 +74,7 @@ func (ccb *ccBalancerWrapper) watcher() { } ccb.balancerMu.Lock() su := t.(*scStateUpdate) - if ub, ok := ccb.balancer.(balancer.V2Balancer); ok { - ub.UpdateSubConnState(su.sc, balancer.SubConnState{ConnectivityState: su.state, ConnectionError: su.err}) - } else { - ccb.balancer.HandleSubConnStateChange(su.sc, su.state) - } + ccb.balancer.UpdateSubConnState(su.sc, balancer.SubConnState{ConnectivityState: su.state, ConnectionError: su.err}) ccb.balancerMu.Unlock() case <-ccb.done.Done(): } @@ -123,19 +119,13 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) error { ccb.balancerMu.Lock() defer ccb.balancerMu.Unlock() - if ub, ok := ccb.balancer.(balancer.V2Balancer); ok { - return ub.UpdateClientConnState(*ccs) - } - ccb.balancer.HandleResolvedAddrs(ccs.ResolverState.Addresses, nil) - return nil + return ccb.balancer.UpdateClientConnState(*ccs) } func (ccb *ccBalancerWrapper) resolverError(err error) { - if ub, ok := ccb.balancer.(balancer.V2Balancer); ok { - ccb.balancerMu.Lock() - ub.ResolverError(err) - ccb.balancerMu.Unlock() - } + ccb.balancerMu.Lock() + ccb.balancer.ResolverError(err) + ccb.balancerMu.Unlock() } func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) { @@ -173,21 +163,6 @@ func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) { ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain) } -func (ccb *ccBalancerWrapper) UpdateBalancerState(s connectivity.State, p balancer.Picker) { - ccb.mu.Lock() - defer ccb.mu.Unlock() - if ccb.subConns == nil { - return - } - // Update picker before updating state. Even though the ordering here does - // not matter, it can lead to multiple calls of Pick in the common start-up - // case where we wait for ready and then perform an RPC. If the picker is - // updated later, we could call the "connecting" picker when the state is - // updated, and then call the "ready" picker after the picker gets updated. - ccb.cc.blockingpicker.updatePicker(p) - ccb.cc.csMgr.updateState(s) -} - func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { ccb.mu.Lock() defer ccb.mu.Unlock() @@ -199,7 +174,7 @@ func (ccb *ccBalancerWrapper) UpdateState(s balancer.State) { // case where we wait for ready and then perform an RPC. If the picker is // updated later, we could call the "connecting" picker when the state is // updated, and then call the "ready" picker after the picker gets updated. - ccb.cc.blockingpicker.updatePickerV2(s.Picker) + ccb.cc.blockingpicker.updatePicker(s.Picker) ccb.cc.csMgr.updateState(s.ConnectivityState) } diff --git a/vendor/google.golang.org/grpc/balancer_v1_wrapper.go b/vendor/google.golang.org/grpc/balancer_v1_wrapper.go deleted file mode 100644 index db04b08b8..000000000 --- a/vendor/google.golang.org/grpc/balancer_v1_wrapper.go +++ /dev/null @@ -1,334 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package grpc - -import ( - "sync" - - "google.golang.org/grpc/balancer" - "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/resolver" -) - -type balancerWrapperBuilder struct { - b Balancer // The v1 balancer. -} - -func (bwb *balancerWrapperBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer { - bwb.b.Start(opts.Target.Endpoint, BalancerConfig{ - DialCreds: opts.DialCreds, - Dialer: opts.Dialer, - }) - _, pickfirst := bwb.b.(*pickFirst) - bw := &balancerWrapper{ - balancer: bwb.b, - pickfirst: pickfirst, - cc: cc, - targetAddr: opts.Target.Endpoint, - startCh: make(chan struct{}), - conns: make(map[resolver.Address]balancer.SubConn), - connSt: make(map[balancer.SubConn]*scState), - csEvltr: &balancer.ConnectivityStateEvaluator{}, - state: connectivity.Idle, - } - cc.UpdateState(balancer.State{ConnectivityState: connectivity.Idle, Picker: bw}) - go bw.lbWatcher() - return bw -} - -func (bwb *balancerWrapperBuilder) Name() string { - return "wrapper" -} - -type scState struct { - addr Address // The v1 address type. - s connectivity.State - down func(error) -} - -type balancerWrapper struct { - balancer Balancer // The v1 balancer. - pickfirst bool - - cc balancer.ClientConn - targetAddr string // Target without the scheme. - - mu sync.Mutex - conns map[resolver.Address]balancer.SubConn - connSt map[balancer.SubConn]*scState - // This channel is closed when handling the first resolver result. - // lbWatcher blocks until this is closed, to avoid race between - // - NewSubConn is created, cc wants to notify balancer of state changes; - // - Build hasn't return, cc doesn't have access to balancer. - startCh chan struct{} - - // To aggregate the connectivity state. - csEvltr *balancer.ConnectivityStateEvaluator - state connectivity.State -} - -// lbWatcher watches the Notify channel of the balancer and manages -// connections accordingly. -func (bw *balancerWrapper) lbWatcher() { - <-bw.startCh - notifyCh := bw.balancer.Notify() - if notifyCh == nil { - // There's no resolver in the balancer. Connect directly. - a := resolver.Address{ - Addr: bw.targetAddr, - Type: resolver.Backend, - } - sc, err := bw.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{}) - if err != nil { - grpclog.Warningf("Error creating connection to %v. Err: %v", a, err) - } else { - bw.mu.Lock() - bw.conns[a] = sc - bw.connSt[sc] = &scState{ - addr: Address{Addr: bw.targetAddr}, - s: connectivity.Idle, - } - bw.mu.Unlock() - sc.Connect() - } - return - } - - for addrs := range notifyCh { - grpclog.Infof("balancerWrapper: got update addr from Notify: %v", addrs) - if bw.pickfirst { - var ( - oldA resolver.Address - oldSC balancer.SubConn - ) - bw.mu.Lock() - for oldA, oldSC = range bw.conns { - break - } - bw.mu.Unlock() - if len(addrs) <= 0 { - if oldSC != nil { - // Teardown old sc. - bw.mu.Lock() - delete(bw.conns, oldA) - delete(bw.connSt, oldSC) - bw.mu.Unlock() - bw.cc.RemoveSubConn(oldSC) - } - continue - } - - var newAddrs []resolver.Address - for _, a := range addrs { - newAddr := resolver.Address{ - Addr: a.Addr, - Type: resolver.Backend, // All addresses from balancer are all backends. - ServerName: "", - Metadata: a.Metadata, - } - newAddrs = append(newAddrs, newAddr) - } - if oldSC == nil { - // Create new sc. - sc, err := bw.cc.NewSubConn(newAddrs, balancer.NewSubConnOptions{}) - if err != nil { - grpclog.Warningf("Error creating connection to %v. Err: %v", newAddrs, err) - } else { - bw.mu.Lock() - // For pickfirst, there should be only one SubConn, so the - // address doesn't matter. All states updating (up and down) - // and picking should all happen on that only SubConn. - bw.conns[resolver.Address{}] = sc - bw.connSt[sc] = &scState{ - addr: addrs[0], // Use the first address. - s: connectivity.Idle, - } - bw.mu.Unlock() - sc.Connect() - } - } else { - bw.mu.Lock() - bw.connSt[oldSC].addr = addrs[0] - bw.mu.Unlock() - oldSC.UpdateAddresses(newAddrs) - } - } else { - var ( - add []resolver.Address // Addresses need to setup connections. - del []balancer.SubConn // Connections need to tear down. - ) - resAddrs := make(map[resolver.Address]Address) - for _, a := range addrs { - resAddrs[resolver.Address{ - Addr: a.Addr, - Type: resolver.Backend, // All addresses from balancer are all backends. - ServerName: "", - Metadata: a.Metadata, - }] = a - } - bw.mu.Lock() - for a := range resAddrs { - if _, ok := bw.conns[a]; !ok { - add = append(add, a) - } - } - for a, c := range bw.conns { - if _, ok := resAddrs[a]; !ok { - del = append(del, c) - delete(bw.conns, a) - // Keep the state of this sc in bw.connSt until its state becomes Shutdown. - } - } - bw.mu.Unlock() - for _, a := range add { - sc, err := bw.cc.NewSubConn([]resolver.Address{a}, balancer.NewSubConnOptions{}) - if err != nil { - grpclog.Warningf("Error creating connection to %v. Err: %v", a, err) - } else { - bw.mu.Lock() - bw.conns[a] = sc - bw.connSt[sc] = &scState{ - addr: resAddrs[a], - s: connectivity.Idle, - } - bw.mu.Unlock() - sc.Connect() - } - } - for _, c := range del { - bw.cc.RemoveSubConn(c) - } - } - } -} - -func (bw *balancerWrapper) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { - bw.mu.Lock() - defer bw.mu.Unlock() - scSt, ok := bw.connSt[sc] - if !ok { - return - } - if s == connectivity.Idle { - sc.Connect() - } - oldS := scSt.s - scSt.s = s - if oldS != connectivity.Ready && s == connectivity.Ready { - scSt.down = bw.balancer.Up(scSt.addr) - } else if oldS == connectivity.Ready && s != connectivity.Ready { - if scSt.down != nil { - scSt.down(errConnClosing) - } - } - sa := bw.csEvltr.RecordTransition(oldS, s) - if bw.state != sa { - bw.state = sa - } - bw.cc.UpdateState(balancer.State{ConnectivityState: bw.state, Picker: bw}) - if s == connectivity.Shutdown { - // Remove state for this sc. - delete(bw.connSt, sc) - } -} - -func (bw *balancerWrapper) HandleResolvedAddrs([]resolver.Address, error) { - bw.mu.Lock() - defer bw.mu.Unlock() - select { - case <-bw.startCh: - default: - close(bw.startCh) - } - // There should be a resolver inside the balancer. - // All updates here, if any, are ignored. -} - -func (bw *balancerWrapper) Close() { - bw.mu.Lock() - defer bw.mu.Unlock() - select { - case <-bw.startCh: - default: - close(bw.startCh) - } - bw.balancer.Close() -} - -// The picker is the balancerWrapper itself. -// It either blocks or returns error, consistent with v1 balancer Get(). -func (bw *balancerWrapper) Pick(info balancer.PickInfo) (result balancer.PickResult, err error) { - failfast := true // Default failfast is true. - if ss, ok := rpcInfoFromContext(info.Ctx); ok { - failfast = ss.failfast - } - a, p, err := bw.balancer.Get(info.Ctx, BalancerGetOptions{BlockingWait: !failfast}) - if err != nil { - return balancer.PickResult{}, toRPCErr(err) - } - if p != nil { - result.Done = func(balancer.DoneInfo) { p() } - defer func() { - if err != nil { - p() - } - }() - } - - bw.mu.Lock() - defer bw.mu.Unlock() - if bw.pickfirst { - // Get the first sc in conns. - for _, result.SubConn = range bw.conns { - return result, nil - } - return balancer.PickResult{}, balancer.ErrNoSubConnAvailable - } - var ok1 bool - result.SubConn, ok1 = bw.conns[resolver.Address{ - Addr: a.Addr, - Type: resolver.Backend, - ServerName: "", - Metadata: a.Metadata, - }] - s, ok2 := bw.connSt[result.SubConn] - if !ok1 || !ok2 { - // This can only happen due to a race where Get() returned an address - // that was subsequently removed by Notify. In this case we should - // retry always. - return balancer.PickResult{}, balancer.ErrNoSubConnAvailable - } - switch s.s { - case connectivity.Ready, connectivity.Idle: - return result, nil - case connectivity.Shutdown, connectivity.TransientFailure: - // If the returned sc has been shut down or is in transient failure, - // return error, and this RPC will fail or wait for another picker (if - // non-failfast). - return balancer.PickResult{}, balancer.ErrTransientFailure - default: - // For other states (connecting or unknown), the v1 balancer would - // traditionally wait until ready and then issue the RPC. Returning - // ErrNoSubConnAvailable will be a slight improvement in that it will - // allow the balancer to choose another address in case others are - // connected. - return balancer.PickResult{}, balancer.ErrNoSubConnAvailable - } -} diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index f393bb661..f826ec769 100644 --- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -1,13 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: grpc/binarylog/grpc_binarylog_v1/binarylog.proto +// source: grpc/binlog/v1/binarylog.proto -package grpc_binarylog_v1 // import "google.golang.org/grpc/binarylog/grpc_binarylog_v1" +package grpc_binarylog_v1 -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import duration "github.com/golang/protobuf/ptypes/duration" -import timestamp "github.com/golang/protobuf/ptypes/timestamp" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + duration "github.com/golang/protobuf/ptypes/duration" + timestamp "github.com/golang/protobuf/ptypes/timestamp" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -18,7 +20,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package // Enumerates the type of event // Note the terminology is different from the RPC semantics @@ -64,6 +66,7 @@ var GrpcLogEntry_EventType_name = map[int32]string{ 6: "EVENT_TYPE_SERVER_TRAILER", 7: "EVENT_TYPE_CANCEL", } + var GrpcLogEntry_EventType_value = map[string]int32{ "EVENT_TYPE_UNKNOWN": 0, "EVENT_TYPE_CLIENT_HEADER": 1, @@ -78,8 +81,9 @@ var GrpcLogEntry_EventType_value = map[string]int32{ func (x GrpcLogEntry_EventType) String() string { return proto.EnumName(GrpcLogEntry_EventType_name, int32(x)) } + func (GrpcLogEntry_EventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{0, 0} + return fileDescriptor_b7972e58de45083a, []int{0, 0} } // Enumerates the entity that generates the log entry @@ -96,6 +100,7 @@ var GrpcLogEntry_Logger_name = map[int32]string{ 1: "LOGGER_CLIENT", 2: "LOGGER_SERVER", } + var GrpcLogEntry_Logger_value = map[string]int32{ "LOGGER_UNKNOWN": 0, "LOGGER_CLIENT": 1, @@ -105,8 +110,9 @@ var GrpcLogEntry_Logger_value = map[string]int32{ func (x GrpcLogEntry_Logger) String() string { return proto.EnumName(GrpcLogEntry_Logger_name, int32(x)) } + func (GrpcLogEntry_Logger) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{0, 1} + return fileDescriptor_b7972e58de45083a, []int{0, 1} } type Address_Type int32 @@ -128,6 +134,7 @@ var Address_Type_name = map[int32]string{ 2: "TYPE_IPV6", 3: "TYPE_UNIX", } + var Address_Type_value = map[string]int32{ "TYPE_UNKNOWN": 0, "TYPE_IPV4": 1, @@ -138,8 +145,9 @@ var Address_Type_value = map[string]int32{ func (x Address_Type) String() string { return proto.EnumName(Address_Type_name, int32(x)) } + func (Address_Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{7, 0} + return fileDescriptor_b7972e58de45083a, []int{7, 0} } // Log entry we store in binary logs @@ -185,16 +193,17 @@ func (m *GrpcLogEntry) Reset() { *m = GrpcLogEntry{} } func (m *GrpcLogEntry) String() string { return proto.CompactTextString(m) } func (*GrpcLogEntry) ProtoMessage() {} func (*GrpcLogEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{0} + return fileDescriptor_b7972e58de45083a, []int{0} } + func (m *GrpcLogEntry) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_GrpcLogEntry.Unmarshal(m, b) } func (m *GrpcLogEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_GrpcLogEntry.Marshal(b, m, deterministic) } -func (dst *GrpcLogEntry) XXX_Merge(src proto.Message) { - xxx_messageInfo_GrpcLogEntry.Merge(dst, src) +func (m *GrpcLogEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_GrpcLogEntry.Merge(m, src) } func (m *GrpcLogEntry) XXX_Size() int { return xxx_messageInfo_GrpcLogEntry.Size(m) @@ -317,9 +326,9 @@ func (m *GrpcLogEntry) GetPeer() *Address { return nil } -// XXX_OneofFuncs is for the internal use of the proto package. -func (*GrpcLogEntry) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _GrpcLogEntry_OneofMarshaler, _GrpcLogEntry_OneofUnmarshaler, _GrpcLogEntry_OneofSizer, []interface{}{ +// XXX_OneofWrappers is for the internal use of the proto package. +func (*GrpcLogEntry) XXX_OneofWrappers() []interface{} { + return []interface{}{ (*GrpcLogEntry_ClientHeader)(nil), (*GrpcLogEntry_ServerHeader)(nil), (*GrpcLogEntry_Message)(nil), @@ -327,108 +336,6 @@ func (*GrpcLogEntry) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) } } -func _GrpcLogEntry_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*GrpcLogEntry) - // payload - switch x := m.Payload.(type) { - case *GrpcLogEntry_ClientHeader: - b.EncodeVarint(6<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.ClientHeader); err != nil { - return err - } - case *GrpcLogEntry_ServerHeader: - b.EncodeVarint(7<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.ServerHeader); err != nil { - return err - } - case *GrpcLogEntry_Message: - b.EncodeVarint(8<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Message); err != nil { - return err - } - case *GrpcLogEntry_Trailer: - b.EncodeVarint(9<<3 | proto.WireBytes) - if err := b.EncodeMessage(x.Trailer); err != nil { - return err - } - case nil: - default: - return fmt.Errorf("GrpcLogEntry.Payload has unexpected type %T", x) - } - return nil -} - -func _GrpcLogEntry_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*GrpcLogEntry) - switch tag { - case 6: // payload.client_header - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(ClientHeader) - err := b.DecodeMessage(msg) - m.Payload = &GrpcLogEntry_ClientHeader{msg} - return true, err - case 7: // payload.server_header - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(ServerHeader) - err := b.DecodeMessage(msg) - m.Payload = &GrpcLogEntry_ServerHeader{msg} - return true, err - case 8: // payload.message - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Message) - err := b.DecodeMessage(msg) - m.Payload = &GrpcLogEntry_Message{msg} - return true, err - case 9: // payload.trailer - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - msg := new(Trailer) - err := b.DecodeMessage(msg) - m.Payload = &GrpcLogEntry_Trailer{msg} - return true, err - default: - return false, nil - } -} - -func _GrpcLogEntry_OneofSizer(msg proto.Message) (n int) { - m := msg.(*GrpcLogEntry) - // payload - switch x := m.Payload.(type) { - case *GrpcLogEntry_ClientHeader: - s := proto.Size(x.ClientHeader) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *GrpcLogEntry_ServerHeader: - s := proto.Size(x.ServerHeader) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *GrpcLogEntry_Message: - s := proto.Size(x.Message) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case *GrpcLogEntry_Trailer: - s := proto.Size(x.Trailer) - n += 1 // tag and wire - n += proto.SizeVarint(uint64(s)) - n += s - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - type ClientHeader struct { // This contains only the metadata from the application. Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` @@ -453,16 +360,17 @@ func (m *ClientHeader) Reset() { *m = ClientHeader{} } func (m *ClientHeader) String() string { return proto.CompactTextString(m) } func (*ClientHeader) ProtoMessage() {} func (*ClientHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{1} + return fileDescriptor_b7972e58de45083a, []int{1} } + func (m *ClientHeader) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ClientHeader.Unmarshal(m, b) } func (m *ClientHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ClientHeader.Marshal(b, m, deterministic) } -func (dst *ClientHeader) XXX_Merge(src proto.Message) { - xxx_messageInfo_ClientHeader.Merge(dst, src) +func (m *ClientHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_ClientHeader.Merge(m, src) } func (m *ClientHeader) XXX_Size() int { return xxx_messageInfo_ClientHeader.Size(m) @@ -513,16 +421,17 @@ func (m *ServerHeader) Reset() { *m = ServerHeader{} } func (m *ServerHeader) String() string { return proto.CompactTextString(m) } func (*ServerHeader) ProtoMessage() {} func (*ServerHeader) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{2} + return fileDescriptor_b7972e58de45083a, []int{2} } + func (m *ServerHeader) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_ServerHeader.Unmarshal(m, b) } func (m *ServerHeader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_ServerHeader.Marshal(b, m, deterministic) } -func (dst *ServerHeader) XXX_Merge(src proto.Message) { - xxx_messageInfo_ServerHeader.Merge(dst, src) +func (m *ServerHeader) XXX_Merge(src proto.Message) { + xxx_messageInfo_ServerHeader.Merge(m, src) } func (m *ServerHeader) XXX_Size() int { return xxx_messageInfo_ServerHeader.Size(m) @@ -560,16 +469,17 @@ func (m *Trailer) Reset() { *m = Trailer{} } func (m *Trailer) String() string { return proto.CompactTextString(m) } func (*Trailer) ProtoMessage() {} func (*Trailer) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{3} + return fileDescriptor_b7972e58de45083a, []int{3} } + func (m *Trailer) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Trailer.Unmarshal(m, b) } func (m *Trailer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Trailer.Marshal(b, m, deterministic) } -func (dst *Trailer) XXX_Merge(src proto.Message) { - xxx_messageInfo_Trailer.Merge(dst, src) +func (m *Trailer) XXX_Merge(src proto.Message) { + xxx_messageInfo_Trailer.Merge(m, src) } func (m *Trailer) XXX_Size() int { return xxx_messageInfo_Trailer.Size(m) @@ -624,16 +534,17 @@ func (m *Message) Reset() { *m = Message{} } func (m *Message) String() string { return proto.CompactTextString(m) } func (*Message) ProtoMessage() {} func (*Message) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{4} + return fileDescriptor_b7972e58de45083a, []int{4} } + func (m *Message) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Message.Unmarshal(m, b) } func (m *Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Message.Marshal(b, m, deterministic) } -func (dst *Message) XXX_Merge(src proto.Message) { - xxx_messageInfo_Message.Merge(dst, src) +func (m *Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Message.Merge(m, src) } func (m *Message) XXX_Size() int { return xxx_messageInfo_Message.Size(m) @@ -690,16 +601,17 @@ func (m *Metadata) Reset() { *m = Metadata{} } func (m *Metadata) String() string { return proto.CompactTextString(m) } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{5} + return fileDescriptor_b7972e58de45083a, []int{5} } + func (m *Metadata) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Metadata.Unmarshal(m, b) } func (m *Metadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Metadata.Marshal(b, m, deterministic) } -func (dst *Metadata) XXX_Merge(src proto.Message) { - xxx_messageInfo_Metadata.Merge(dst, src) +func (m *Metadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metadata.Merge(m, src) } func (m *Metadata) XXX_Size() int { return xxx_messageInfo_Metadata.Size(m) @@ -730,16 +642,17 @@ func (m *MetadataEntry) Reset() { *m = MetadataEntry{} } func (m *MetadataEntry) String() string { return proto.CompactTextString(m) } func (*MetadataEntry) ProtoMessage() {} func (*MetadataEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{6} + return fileDescriptor_b7972e58de45083a, []int{6} } + func (m *MetadataEntry) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_MetadataEntry.Unmarshal(m, b) } func (m *MetadataEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_MetadataEntry.Marshal(b, m, deterministic) } -func (dst *MetadataEntry) XXX_Merge(src proto.Message) { - xxx_messageInfo_MetadataEntry.Merge(dst, src) +func (m *MetadataEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_MetadataEntry.Merge(m, src) } func (m *MetadataEntry) XXX_Size() int { return xxx_messageInfo_MetadataEntry.Size(m) @@ -779,16 +692,17 @@ func (m *Address) Reset() { *m = Address{} } func (m *Address) String() string { return proto.CompactTextString(m) } func (*Address) ProtoMessage() {} func (*Address) Descriptor() ([]byte, []int) { - return fileDescriptor_binarylog_264c8c9c551ce911, []int{7} + return fileDescriptor_b7972e58de45083a, []int{7} } + func (m *Address) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Address.Unmarshal(m, b) } func (m *Address) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Address.Marshal(b, m, deterministic) } -func (dst *Address) XXX_Merge(src proto.Message) { - xxx_messageInfo_Address.Merge(dst, src) +func (m *Address) XXX_Merge(src proto.Message) { + xxx_messageInfo_Address.Merge(m, src) } func (m *Address) XXX_Size() int { return xxx_messageInfo_Address.Size(m) @@ -821,6 +735,9 @@ func (m *Address) GetIpPort() uint32 { } func init() { + proto.RegisterEnum("grpc.binarylog.v1.GrpcLogEntry_EventType", GrpcLogEntry_EventType_name, GrpcLogEntry_EventType_value) + proto.RegisterEnum("grpc.binarylog.v1.GrpcLogEntry_Logger", GrpcLogEntry_Logger_name, GrpcLogEntry_Logger_value) + proto.RegisterEnum("grpc.binarylog.v1.Address_Type", Address_Type_name, Address_Type_value) proto.RegisterType((*GrpcLogEntry)(nil), "grpc.binarylog.v1.GrpcLogEntry") proto.RegisterType((*ClientHeader)(nil), "grpc.binarylog.v1.ClientHeader") proto.RegisterType((*ServerHeader)(nil), "grpc.binarylog.v1.ServerHeader") @@ -829,72 +746,67 @@ func init() { proto.RegisterType((*Metadata)(nil), "grpc.binarylog.v1.Metadata") proto.RegisterType((*MetadataEntry)(nil), "grpc.binarylog.v1.MetadataEntry") proto.RegisterType((*Address)(nil), "grpc.binarylog.v1.Address") - proto.RegisterEnum("grpc.binarylog.v1.GrpcLogEntry_EventType", GrpcLogEntry_EventType_name, GrpcLogEntry_EventType_value) - proto.RegisterEnum("grpc.binarylog.v1.GrpcLogEntry_Logger", GrpcLogEntry_Logger_name, GrpcLogEntry_Logger_value) - proto.RegisterEnum("grpc.binarylog.v1.Address_Type", Address_Type_name, Address_Type_value) } -func init() { - proto.RegisterFile("grpc/binarylog/grpc_binarylog_v1/binarylog.proto", fileDescriptor_binarylog_264c8c9c551ce911) -} +func init() { proto.RegisterFile("grpc/binlog/v1/binarylog.proto", fileDescriptor_b7972e58de45083a) } -var fileDescriptor_binarylog_264c8c9c551ce911 = []byte{ - // 900 bytes of a gzipped FileDescriptorProto +var fileDescriptor_b7972e58de45083a = []byte{ + // 904 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x51, 0x6f, 0xe3, 0x44, - 0x10, 0x3e, 0x37, 0x69, 0xdc, 0x4c, 0x92, 0xca, 0x5d, 0x95, 0x3b, 0x5f, 0x29, 0x34, 0xb2, 0x04, - 0x0a, 0x42, 0x72, 0xb9, 0x94, 0xeb, 0xf1, 0x02, 0x52, 0x92, 0xfa, 0xd2, 0x88, 0x5c, 0x1a, 0x6d, - 0x72, 0x3d, 0x40, 0x48, 0xd6, 0x36, 0x5e, 0x1c, 0x0b, 0xc7, 0x6b, 0xd6, 0x9b, 0xa0, 0xfc, 0x2c, - 0xde, 0x90, 0xee, 0x77, 0xf1, 0x8e, 0xbc, 0x6b, 0x27, 0xa6, 0x69, 0x0f, 0x09, 0xde, 0x3c, 0xdf, - 0x7c, 0xf3, 0xcd, 0xee, 0x78, 0x66, 0x16, 0xbe, 0xf2, 0x79, 0x3c, 0x3b, 0xbf, 0x0b, 0x22, 0xc2, - 0xd7, 0x21, 0xf3, 0xcf, 0x53, 0xd3, 0xdd, 0x98, 0xee, 0xea, 0xc5, 0xd6, 0x67, 0xc7, 0x9c, 0x09, - 0x86, 0x8e, 0x52, 0x8a, 0xbd, 0x45, 0x57, 0x2f, 0x4e, 0x3e, 0xf5, 0x19, 0xf3, 0x43, 0x7a, 0x2e, - 0x09, 0x77, 0xcb, 0x5f, 0xce, 0xbd, 0x25, 0x27, 0x22, 0x60, 0x91, 0x0a, 0x39, 0x39, 0xbb, 0xef, - 0x17, 0xc1, 0x82, 0x26, 0x82, 0x2c, 0x62, 0x45, 0xb0, 0xde, 0xeb, 0x50, 0xef, 0xf3, 0x78, 0x36, - 0x64, 0xbe, 0x13, 0x09, 0xbe, 0x46, 0xdf, 0x40, 0x75, 0xc3, 0x31, 0xb5, 0xa6, 0xd6, 0xaa, 0xb5, - 0x4f, 0x6c, 0xa5, 0x62, 0xe7, 0x2a, 0xf6, 0x34, 0x67, 0xe0, 0x2d, 0x19, 0x3d, 0x03, 0x7d, 0x46, - 0xc2, 0xd0, 0x0d, 0x3c, 0x73, 0xaf, 0xa9, 0xb5, 0xca, 0xb8, 0x92, 0x9a, 0x03, 0x0f, 0xbd, 0x84, - 0x67, 0x09, 0xfd, 0x6d, 0x49, 0xa3, 0x19, 0x75, 0x03, 0xcf, 0xfd, 0x3d, 0x10, 0xf3, 0x20, 0x72, - 0x53, 0xa7, 0x59, 0x92, 0xc4, 0xe3, 0xdc, 0x3d, 0xf0, 0xde, 0x49, 0x67, 0x8f, 0x84, 0x21, 0xfa, - 0x16, 0xca, 0x62, 0x1d, 0x53, 0xb3, 0xdc, 0xd4, 0x5a, 0x87, 0xed, 0x2f, 0xec, 0x9d, 0xdb, 0xdb, - 0xc5, 0x83, 0xdb, 0xce, 0x8a, 0x46, 0x62, 0xba, 0x8e, 0x29, 0x96, 0x61, 0xe8, 0x3b, 0xa8, 0x84, - 0xcc, 0xf7, 0x29, 0x37, 0xf7, 0xa5, 0xc0, 0xe7, 0xff, 0x26, 0x30, 0x94, 0x6c, 0x9c, 0x45, 0xa1, - 0xd7, 0xd0, 0x98, 0x85, 0x01, 0x8d, 0x84, 0x3b, 0xa7, 0xc4, 0xa3, 0xdc, 0xac, 0xc8, 0x62, 0x9c, - 0x3d, 0x20, 0xd3, 0x93, 0xbc, 0x6b, 0x49, 0xbb, 0x7e, 0x82, 0xeb, 0xb3, 0x82, 0x9d, 0xea, 0x24, - 0x94, 0xaf, 0x28, 0xcf, 0x75, 0xf4, 0x47, 0x75, 0x26, 0x92, 0xb7, 0xd5, 0x49, 0x0a, 0x36, 0xba, - 0x04, 0x7d, 0x41, 0x93, 0x84, 0xf8, 0xd4, 0x3c, 0xc8, 0x7f, 0xcb, 0x8e, 0xc2, 0x1b, 0xc5, 0xb8, - 0x7e, 0x82, 0x73, 0x72, 0x1a, 0x27, 0x38, 0x09, 0x42, 0xca, 0xcd, 0xea, 0xa3, 0x71, 0x53, 0xc5, - 0x48, 0xe3, 0x32, 0x32, 0xfa, 0x12, 0x8e, 0x62, 0xb2, 0x0e, 0x19, 0xf1, 0x5c, 0xc1, 0x97, 0xd1, - 0x8c, 0x08, 0xea, 0x99, 0xd0, 0xd4, 0x5a, 0x07, 0xd8, 0xc8, 0x1c, 0xd3, 0x1c, 0x47, 0x36, 0x94, - 0x63, 0x4a, 0xb9, 0x59, 0x7b, 0x34, 0x43, 0xc7, 0xf3, 0x38, 0x4d, 0x12, 0x2c, 0x79, 0xd6, 0x5f, - 0x1a, 0x54, 0x37, 0x3f, 0x0c, 0x3d, 0x05, 0xe4, 0xdc, 0x3a, 0xa3, 0xa9, 0x3b, 0xfd, 0x71, 0xec, - 0xb8, 0x6f, 0x47, 0xdf, 0x8f, 0x6e, 0xde, 0x8d, 0x8c, 0x27, 0xe8, 0x14, 0xcc, 0x02, 0xde, 0x1b, - 0x0e, 0xd2, 0xef, 0x6b, 0xa7, 0x73, 0xe5, 0x60, 0x43, 0xbb, 0xe7, 0x9d, 0x38, 0xf8, 0xd6, 0xc1, - 0xb9, 0x77, 0x0f, 0x7d, 0x02, 0xcf, 0x77, 0x63, 0xdf, 0x38, 0x93, 0x49, 0xa7, 0xef, 0x18, 0xa5, - 0x7b, 0xee, 0x2c, 0x38, 0x77, 0x97, 0x51, 0x13, 0x4e, 0x1f, 0xc8, 0xdc, 0x19, 0xbe, 0x76, 0x7b, - 0xc3, 0x9b, 0x89, 0x63, 0xec, 0x3f, 0x2c, 0x30, 0xc5, 0x9d, 0xc1, 0xd0, 0xc1, 0x46, 0x05, 0x7d, - 0x04, 0x47, 0x45, 0x81, 0xce, 0xa8, 0xe7, 0x0c, 0x0d, 0xdd, 0xea, 0x42, 0x45, 0xb5, 0x19, 0x42, - 0x70, 0x38, 0xbc, 0xe9, 0xf7, 0x1d, 0x5c, 0xb8, 0xef, 0x11, 0x34, 0x32, 0x4c, 0x65, 0x34, 0xb4, - 0x02, 0xa4, 0x52, 0x18, 0x7b, 0xdd, 0x2a, 0xe8, 0x59, 0xfd, 0xad, 0xf7, 0x1a, 0xd4, 0x8b, 0xcd, - 0x87, 0x5e, 0xc1, 0xc1, 0x82, 0x0a, 0xe2, 0x11, 0x41, 0xb2, 0xe1, 0xfd, 0xf8, 0xc1, 0x2e, 0x51, - 0x14, 0xbc, 0x21, 0xa3, 0x33, 0xa8, 0x2d, 0xa8, 0x98, 0x33, 0xcf, 0x8d, 0xc8, 0x82, 0xca, 0x01, - 0xae, 0x62, 0x50, 0xd0, 0x88, 0x2c, 0x28, 0x3a, 0x85, 0x2a, 0x59, 0x8a, 0x39, 0xe3, 0x81, 0x58, - 0xcb, 0xb1, 0xad, 0xe2, 0x2d, 0x80, 0x2e, 0x40, 0x4f, 0x17, 0x01, 0x5b, 0x0a, 0x39, 0xae, 0xb5, - 0xf6, 0xf3, 0x9d, 0x9d, 0x71, 0x95, 0x6d, 0x26, 0x9c, 0x33, 0xad, 0x3e, 0xd4, 0x8b, 0x1d, 0xff, - 0x9f, 0x0f, 0x6f, 0xfd, 0xa1, 0x81, 0x9e, 0x75, 0xf0, 0xff, 0xaa, 0x40, 0x22, 0x88, 0x58, 0x26, - 0xee, 0x8c, 0x79, 0xaa, 0x02, 0x0d, 0x0c, 0x0a, 0xea, 0x31, 0x8f, 0xa2, 0xcf, 0xe0, 0x30, 0x23, - 0xe4, 0x73, 0xa8, 0xca, 0xd0, 0x50, 0x68, 0x36, 0x7a, 0x05, 0x9a, 0x47, 0x05, 0x09, 0xc2, 0x44, - 0x56, 0xa4, 0x9e, 0xd3, 0xae, 0x14, 0x68, 0xbd, 0x04, 0x3d, 0x8f, 0x78, 0x0a, 0x95, 0x90, 0x46, - 0xbe, 0x98, 0xcb, 0x03, 0x37, 0x70, 0x66, 0x21, 0x04, 0x65, 0x79, 0x8d, 0x3d, 0x19, 0x2f, 0xbf, - 0xad, 0x2e, 0x1c, 0xe4, 0x67, 0x47, 0x97, 0xb0, 0x4f, 0xd3, 0xcd, 0x65, 0x6a, 0xcd, 0x52, 0xab, - 0xd6, 0x6e, 0x7e, 0xe0, 0x9e, 0x72, 0xc3, 0x61, 0x45, 0xb7, 0x5e, 0x41, 0xe3, 0x1f, 0x38, 0x32, - 0xa0, 0xf4, 0x2b, 0x5d, 0xcb, 0xec, 0x55, 0x9c, 0x7e, 0xa2, 0x63, 0xd8, 0x5f, 0x91, 0x70, 0x49, - 0xb3, 0xdc, 0xca, 0xb0, 0xfe, 0xd4, 0x40, 0xcf, 0xe6, 0x18, 0x5d, 0x64, 0xdb, 0x59, 0x93, 0xcb, - 0xf5, 0xec, 0xf1, 0x89, 0xb7, 0x0b, 0x3b, 0xd9, 0x04, 0x9d, 0x28, 0x34, 0xeb, 0xb0, 0xdc, 0x4c, - 0x1f, 0x8f, 0x20, 0x76, 0x63, 0xc6, 0x85, 0xac, 0x6a, 0x03, 0x57, 0x82, 0x78, 0xcc, 0xb8, 0xb0, - 0x1c, 0x28, 0xcb, 0x1d, 0x61, 0x40, 0xfd, 0xde, 0x76, 0x68, 0x40, 0x55, 0x22, 0x83, 0xf1, 0xed, - 0xd7, 0x86, 0x56, 0x34, 0x2f, 0x8d, 0xbd, 0x8d, 0xf9, 0x76, 0x34, 0xf8, 0xc1, 0x28, 0x75, 0x7f, - 0x86, 0xe3, 0x80, 0xed, 0x1e, 0xb2, 0x7b, 0xd8, 0x95, 0xd6, 0x90, 0xf9, 0xe3, 0xb4, 0x51, 0xc7, - 0xda, 0x4f, 0xed, 0xac, 0x71, 0x7d, 0x16, 0x92, 0xc8, 0xb7, 0x19, 0x57, 0x4f, 0xf3, 0x87, 0x5e, - 0xea, 0xbb, 0x8a, 0xec, 0xf2, 0x8b, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xf6, 0x4b, 0x50, - 0xd4, 0x07, 0x00, 0x00, + 0x10, 0xae, 0xdb, 0x34, 0x6e, 0x26, 0x49, 0xe5, 0xae, 0xca, 0x9d, 0xaf, 0x94, 0x6b, 0x64, 0x09, + 0x14, 0x84, 0xe4, 0xa8, 0x29, 0xd7, 0xe3, 0x05, 0xa4, 0x24, 0xf5, 0xa5, 0x11, 0xb9, 0x34, 0xda, + 0xe4, 0x7a, 0x80, 0x90, 0xac, 0x6d, 0xbc, 0x38, 0x16, 0x8e, 0xd7, 0xac, 0x37, 0x41, 0xf9, 0x59, + 0xbc, 0x21, 0xdd, 0xef, 0xe2, 0x1d, 0x79, 0xd7, 0x4e, 0x4d, 0xd3, 0x82, 0xc4, 0xbd, 0xed, 0x7c, + 0xf3, 0xcd, 0x37, 0xbb, 0xe3, 0x99, 0x31, 0xbc, 0xf4, 0x79, 0x3c, 0x6b, 0xdd, 0x05, 0x51, 0xc8, + 0xfc, 0xd6, 0xea, 0x3c, 0x3d, 0x11, 0xbe, 0x0e, 0x99, 0x6f, 0xc7, 0x9c, 0x09, 0x86, 0x8e, 0x52, + 0xbf, 0x7d, 0x8f, 0xae, 0xce, 0x4f, 0x5e, 0xfa, 0x8c, 0xf9, 0x21, 0x6d, 0x49, 0xc2, 0xdd, 0xf2, + 0x97, 0x96, 0xb7, 0xe4, 0x44, 0x04, 0x2c, 0x52, 0x21, 0x27, 0x67, 0x0f, 0xfd, 0x22, 0x58, 0xd0, + 0x44, 0x90, 0x45, 0xac, 0x08, 0xd6, 0x07, 0x1d, 0x6a, 0x7d, 0x1e, 0xcf, 0x86, 0xcc, 0x77, 0x22, + 0xc1, 0xd7, 0xe8, 0x1b, 0xa8, 0x6c, 0x38, 0xa6, 0xd6, 0xd0, 0x9a, 0xd5, 0xf6, 0x89, 0xad, 0x54, + 0xec, 0x5c, 0xc5, 0x9e, 0xe6, 0x0c, 0x7c, 0x4f, 0x46, 0xcf, 0x41, 0x9f, 0x91, 0x30, 0x74, 0x03, + 0xcf, 0xdc, 0x6d, 0x68, 0xcd, 0x12, 0x2e, 0xa7, 0xe6, 0xc0, 0x43, 0xaf, 0xe0, 0x79, 0x42, 0x7f, + 0x5b, 0xd2, 0x68, 0x46, 0xdd, 0xc0, 0x73, 0x7f, 0x0f, 0xc4, 0x3c, 0x88, 0xdc, 0xd4, 0x69, 0xee, + 0x49, 0xe2, 0x71, 0xee, 0x1e, 0x78, 0xef, 0xa5, 0xb3, 0x47, 0xc2, 0x10, 0x7d, 0x0b, 0x25, 0xb1, + 0x8e, 0xa9, 0x59, 0x6a, 0x68, 0xcd, 0xc3, 0xf6, 0x97, 0xf6, 0xd6, 0xeb, 0xed, 0xe2, 0xc5, 0x6d, + 0x67, 0x45, 0x23, 0x31, 0x5d, 0xc7, 0x14, 0xcb, 0x30, 0xf4, 0x1d, 0x94, 0x43, 0xe6, 0xfb, 0x94, + 0x9b, 0xfb, 0x52, 0xe0, 0x8b, 0xff, 0x12, 0x18, 0x4a, 0x36, 0xce, 0xa2, 0xd0, 0x1b, 0xa8, 0xcf, + 0xc2, 0x80, 0x46, 0xc2, 0x9d, 0x53, 0xe2, 0x51, 0x6e, 0x96, 0x65, 0x31, 0xce, 0x1e, 0x91, 0xe9, + 0x49, 0xde, 0xb5, 0xa4, 0x5d, 0xef, 0xe0, 0xda, 0xac, 0x60, 0xa7, 0x3a, 0x09, 0xe5, 0x2b, 0xca, + 0x73, 0x1d, 0xfd, 0x49, 0x9d, 0x89, 0xe4, 0xdd, 0xeb, 0x24, 0x05, 0x1b, 0x5d, 0x82, 0xbe, 0xa0, + 0x49, 0x42, 0x7c, 0x6a, 0x1e, 0xe4, 0x9f, 0x65, 0x4b, 0xe1, 0xad, 0x62, 0x5c, 0xef, 0xe0, 0x9c, + 0x9c, 0xc6, 0x09, 0x4e, 0x82, 0x90, 0x72, 0xb3, 0xf2, 0x64, 0xdc, 0x54, 0x31, 0xd2, 0xb8, 0x8c, + 0x8c, 0xbe, 0x82, 0xa3, 0x98, 0xac, 0x43, 0x46, 0x3c, 0x57, 0xf0, 0x65, 0x34, 0x23, 0x82, 0x7a, + 0x26, 0x34, 0xb4, 0xe6, 0x01, 0x36, 0x32, 0xc7, 0x34, 0xc7, 0x91, 0x0d, 0xa5, 0x98, 0x52, 0x6e, + 0x56, 0x9f, 0xcc, 0xd0, 0xf1, 0x3c, 0x4e, 0x93, 0x04, 0x4b, 0x9e, 0xf5, 0x97, 0x06, 0x95, 0xcd, + 0x07, 0x43, 0xcf, 0x00, 0x39, 0xb7, 0xce, 0x68, 0xea, 0x4e, 0x7f, 0x1c, 0x3b, 0xee, 0xbb, 0xd1, + 0xf7, 0xa3, 0x9b, 0xf7, 0x23, 0x63, 0x07, 0x9d, 0x82, 0x59, 0xc0, 0x7b, 0xc3, 0x41, 0x7a, 0xbe, + 0x76, 0x3a, 0x57, 0x0e, 0x36, 0xb4, 0x07, 0xde, 0x89, 0x83, 0x6f, 0x1d, 0x9c, 0x7b, 0x77, 0xd1, + 0x67, 0xf0, 0x62, 0x3b, 0xf6, 0xad, 0x33, 0x99, 0x74, 0xfa, 0x8e, 0xb1, 0xf7, 0xc0, 0x9d, 0x05, + 0xe7, 0xee, 0x12, 0x6a, 0xc0, 0xe9, 0x23, 0x99, 0x3b, 0xc3, 0x37, 0x6e, 0x6f, 0x78, 0x33, 0x71, + 0x8c, 0xfd, 0xc7, 0x05, 0xa6, 0xb8, 0x33, 0x18, 0x3a, 0xd8, 0x28, 0xa3, 0x4f, 0xe0, 0xa8, 0x28, + 0xd0, 0x19, 0xf5, 0x9c, 0xa1, 0xa1, 0x5b, 0x5d, 0x28, 0xab, 0x36, 0x43, 0x08, 0x0e, 0x87, 0x37, + 0xfd, 0xbe, 0x83, 0x0b, 0xef, 0x3d, 0x82, 0x7a, 0x86, 0xa9, 0x8c, 0x86, 0x56, 0x80, 0x54, 0x0a, + 0x63, 0xb7, 0x5b, 0x01, 0x3d, 0xab, 0xbf, 0xf5, 0x41, 0x83, 0x5a, 0xb1, 0xf9, 0xd0, 0x6b, 0x38, + 0x58, 0x50, 0x41, 0x3c, 0x22, 0x48, 0x36, 0xbc, 0x9f, 0x3e, 0xda, 0x25, 0x8a, 0x82, 0x37, 0x64, + 0x74, 0x06, 0xd5, 0x05, 0x15, 0x73, 0xe6, 0xb9, 0x11, 0x59, 0x50, 0x39, 0xc0, 0x15, 0x0c, 0x0a, + 0x1a, 0x91, 0x05, 0x45, 0xa7, 0x50, 0x21, 0x4b, 0x31, 0x67, 0x3c, 0x10, 0x6b, 0x39, 0xb6, 0x15, + 0x7c, 0x0f, 0xa0, 0x0b, 0xd0, 0xd3, 0x45, 0xc0, 0x96, 0x42, 0x8e, 0x6b, 0xb5, 0xfd, 0x62, 0x6b, + 0x67, 0x5c, 0x65, 0x9b, 0x09, 0xe7, 0x4c, 0xab, 0x0f, 0xb5, 0x62, 0xc7, 0xff, 0xef, 0xcb, 0x5b, + 0x7f, 0x68, 0xa0, 0x67, 0x1d, 0xfc, 0x51, 0x15, 0x48, 0x04, 0x11, 0xcb, 0xc4, 0x9d, 0x31, 0x4f, + 0x55, 0xa0, 0x8e, 0x41, 0x41, 0x3d, 0xe6, 0x51, 0xf4, 0x39, 0x1c, 0x66, 0x84, 0x7c, 0x0e, 0x55, + 0x19, 0xea, 0x0a, 0xcd, 0x46, 0xaf, 0x40, 0xf3, 0xa8, 0x20, 0x41, 0x98, 0xc8, 0x8a, 0xd4, 0x72, + 0xda, 0x95, 0x02, 0xad, 0x57, 0xa0, 0xe7, 0x11, 0xcf, 0xa0, 0x1c, 0xd2, 0xc8, 0x17, 0x73, 0x79, + 0xe1, 0x3a, 0xce, 0x2c, 0x84, 0xa0, 0x24, 0x9f, 0xb1, 0x2b, 0xe3, 0xe5, 0xd9, 0xea, 0xc2, 0x41, + 0x7e, 0x77, 0x74, 0x09, 0xfb, 0x34, 0xdd, 0x5c, 0xa6, 0xd6, 0xd8, 0x6b, 0x56, 0xdb, 0x8d, 0x7f, + 0x79, 0xa7, 0xdc, 0x70, 0x58, 0xd1, 0xad, 0xd7, 0x50, 0xff, 0x07, 0x8e, 0x0c, 0xd8, 0xfb, 0x95, + 0xae, 0x65, 0xf6, 0x0a, 0x4e, 0x8f, 0xe8, 0x18, 0xf6, 0x57, 0x24, 0x5c, 0xd2, 0x2c, 0xb7, 0x32, + 0xac, 0x3f, 0x35, 0xd0, 0xb3, 0x39, 0x46, 0x17, 0xd9, 0x76, 0xd6, 0xe4, 0x72, 0x3d, 0x7b, 0x7a, + 0xe2, 0xed, 0xc2, 0x4e, 0x36, 0x41, 0x27, 0x0a, 0xcd, 0x3a, 0x2c, 0x37, 0xd3, 0x9f, 0x47, 0x10, + 0xbb, 0x31, 0xe3, 0x42, 0x56, 0xb5, 0x8e, 0xcb, 0x41, 0x3c, 0x66, 0x5c, 0x58, 0x0e, 0x94, 0xe4, + 0x8e, 0x30, 0xa0, 0xf6, 0x60, 0x3b, 0xd4, 0xa1, 0x22, 0x91, 0xc1, 0xf8, 0xf6, 0x6b, 0x43, 0x2b, + 0x9a, 0x97, 0xc6, 0xee, 0xc6, 0x7c, 0x37, 0x1a, 0xfc, 0x60, 0xec, 0x75, 0x7f, 0x86, 0xe3, 0x80, + 0x6d, 0x5f, 0xb2, 0x7b, 0xd8, 0x95, 0xd6, 0x90, 0xf9, 0xe3, 0xb4, 0x51, 0xc7, 0xda, 0x4f, 0xed, + 0xac, 0x71, 0x7d, 0x16, 0x92, 0xc8, 0xb7, 0x19, 0xf7, 0x5b, 0xf9, 0x7f, 0x59, 0x85, 0x49, 0xd3, + 0xdd, 0x98, 0xee, 0xea, 0xfc, 0xae, 0x2c, 0xbb, 0xfc, 0xe2, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x10, 0x93, 0x68, 0x41, 0xc2, 0x07, 0x00, 0x00, } diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index 0740693b7..ef327e8af 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -68,8 +68,6 @@ var ( errConnDrain = errors.New("grpc: the connection is drained") // errConnClosing indicates that the connection is closing. errConnClosing = errors.New("grpc: the connection is closing") - // errBalancerClosed indicates that the balancer is closed. - errBalancerClosed = errors.New("grpc: balancer is closed") // invalidDefaultServiceConfigErrPrefix is used to prefix the json parsing error for the default // service config. invalidDefaultServiceConfigErrPrefix = "grpc: the provided default service config is invalid" @@ -217,7 +215,14 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * defer func() { select { case <-ctx.Done(): - conn, err = nil, ctx.Err() + switch { + case ctx.Err() == err: + conn = nil + case err == nil || !cc.dopts.returnLastError: + conn, err = nil, ctx.Err() + default: + conn, err = nil, fmt.Errorf("%v: %v", ctx.Err(), err) + } default: } }() @@ -311,7 +316,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * if s == connectivity.Ready { break } else if cc.dopts.copts.FailOnNonTempDialError && s == connectivity.TransientFailure { - if err = cc.blockingpicker.connectionError(); err != nil { + if err = cc.connectionError(); err != nil { terr, ok := err.(interface { Temporary() bool }) @@ -322,6 +327,9 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn * } if !cc.WaitForStateChange(ctx, s) { // ctx got timeout or canceled. + if err = cc.connectionError(); err != nil && cc.dopts.returnLastError { + return nil, err + } return nil, ctx.Err() } } @@ -490,6 +498,9 @@ type ClientConn struct { channelzID int64 // channelz unique identification number czData *channelzData + + lceMu sync.Mutex // protects lastConnectionError + lastConnectionError error } // WaitForStateChange waits until the connectivity.State of ClientConn changes from sourceState or @@ -1199,7 +1210,7 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T if firstConnErr == nil { firstConnErr = err } - ac.cc.blockingpicker.updateConnectionError(err) + ac.cc.updateConnectionError(err) } // Couldn't connect to any address. @@ -1214,16 +1225,9 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne onCloseCalled := make(chan struct{}) reconnect := grpcsync.NewEvent() - authority := ac.cc.authority // addr.ServerName takes precedent over ClientConn authority, if present. - if addr.ServerName != "" { - authority = addr.ServerName - } - - target := transport.TargetInfo{ - Addr: addr.Addr, - Metadata: addr.Metadata, - Authority: authority, + if addr.ServerName == "" { + addr.ServerName = ac.cc.authority } once := sync.Once{} @@ -1269,7 +1273,7 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne copts.ChannelzParentID = ac.channelzID } - newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, target, copts, onPrefaceReceipt, onGoAway, onClose) + newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, addr, copts, onPrefaceReceipt, onGoAway, onClose) if err != nil { // newTr is either nil, or closed. channelz.Warningf(ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v. Err: %v. Reconnecting...", addr, err) @@ -1532,3 +1536,15 @@ func (cc *ClientConn) getResolver(scheme string) resolver.Builder { } return resolver.Get(scheme) } + +func (cc *ClientConn) updateConnectionError(err error) { + cc.lceMu.Lock() + cc.lastConnectionError = err + cc.lceMu.Unlock() +} + +func (cc *ClientConn) connectionError() error { + cc.lceMu.Lock() + defer cc.lceMu.Unlock() + return cc.lastConnectionError +} diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index e438fda22..02766443a 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -29,6 +29,7 @@ import ( "net" "github.com/golang/protobuf/proto" + "google.golang.org/grpc/attributes" "google.golang.org/grpc/internal" ) @@ -57,9 +58,11 @@ type PerRPCCredentials interface { type SecurityLevel int const ( - // NoSecurity indicates a connection is insecure. + // Invalid indicates an invalid security level. // The zero SecurityLevel value is invalid for backward compatibility. - NoSecurity SecurityLevel = iota + 1 + Invalid SecurityLevel = iota + // NoSecurity indicates a connection is insecure. + NoSecurity // IntegrityOnly indicates a connection only provides integrity protection. IntegrityOnly // PrivacyAndIntegrity indicates a connection provides both privacy and integrity protection. @@ -124,15 +127,18 @@ var ErrConnDispatched = errors.New("credentials: rawConn is dispatched out of gR // TransportCredentials defines the common interface for all the live gRPC wire // protocols and supported transport security protocols (e.g., TLS, SSL). type TransportCredentials interface { - // ClientHandshake does the authentication handshake specified by the corresponding - // authentication protocol on rawConn for clients. It returns the authenticated - // connection and the corresponding auth information about the connection. - // The auth information should embed CommonAuthInfo to return additional information about - // the credentials. Implementations must use the provided context to implement timely cancellation. - // gRPC will try to reconnect if the error returned is a temporary error - // (io.EOF, context.DeadlineExceeded or err.Temporary() == true). - // If the returned error is a wrapper error, implementations should make sure that + // ClientHandshake does the authentication handshake specified by the + // corresponding authentication protocol on rawConn for clients. It returns + // the authenticated connection and the corresponding auth information + // about the connection. The auth information should embed CommonAuthInfo + // to return additional information about the credentials. Implementations + // must use the provided context to implement timely cancellation. gRPC + // will try to reconnect if the error returned is a temporary error + // (io.EOF, context.DeadlineExceeded or err.Temporary() == true). If the + // returned error is a wrapper error, implementations should make sure that // the error implements Temporary() to have the correct retry behaviors. + // Additionally, ClientHandshakeInfo data will be available via the context + // passed to this call. // // If the returned net.Conn is closed, it MUST close the net.Conn provided. ClientHandshake(context.Context, string, net.Conn) (net.Conn, AuthInfo, error) @@ -193,6 +199,31 @@ func RequestInfoFromContext(ctx context.Context) (ri RequestInfo, ok bool) { return } +// ClientHandshakeInfo holds data to be passed to ClientHandshake. This makes +// it possible to pass arbitrary data to the handshaker from gRPC, resolver, +// balancer etc. Individual credential implementations control the actual +// format of the data that they are willing to receive. +// +// This API is experimental. +type ClientHandshakeInfo struct { + // Attributes contains the attributes for the address. It could be provided + // by the gRPC, resolver, balancer etc. + Attributes *attributes.Attributes +} + +// clientHandshakeInfoKey is a struct used as the key to store +// ClientHandshakeInfo in a context. +type clientHandshakeInfoKey struct{} + +// ClientHandshakeInfoFromContext returns the ClientHandshakeInfo struct stored +// in ctx. +// +// This API is experimental. +func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo { + chi, _ := ctx.Value(clientHandshakeInfoKey{}).(ClientHandshakeInfo) + return chi +} + // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one. // It returns success if 1) the condition is satisified or 2) AuthInfo struct does not implement GetCommonAuthInfo() method // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility. @@ -208,7 +239,7 @@ func CheckSecurityLevel(ctx context.Context, level SecurityLevel) error { } if ci, ok := ri.AuthInfo.(internalInfo); ok { // CommonAuthInfo.SecurityLevel has an invalid value. - if ci.GetCommonAuthInfo().SecurityLevel == 0 { + if ci.GetCommonAuthInfo().SecurityLevel == Invalid { return nil } if ci.GetCommonAuthInfo().SecurityLevel < level { @@ -223,6 +254,9 @@ func init() { internal.NewRequestInfoContext = func(ctx context.Context, ri RequestInfo) context.Context { return context.WithValue(ctx, requestInfoKey{}, ri) } + internal.NewClientHandshakeInfoContext = func(ctx context.Context, chi ClientHandshakeInfo) context.Context { + return context.WithValue(ctx, clientHandshakeInfoKey{}, chi) + } } // ChannelzSecurityInfo defines the interface that security protocols should implement diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 35bde1033..d5030c076 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -46,18 +46,18 @@ type dialOptions struct { chainUnaryInts []UnaryClientInterceptor chainStreamInts []StreamClientInterceptor - cp Compressor - dc Decompressor - bs internalbackoff.Strategy - block bool - insecure bool - timeout time.Duration - scChan <-chan ServiceConfig - authority string - copts transport.ConnectOptions - callOptions []CallOption - // This is used by v1 balancer dial option WithBalancer to support v1 - // balancer, and also by WithBalancerName dial option. + cp Compressor + dc Decompressor + bs internalbackoff.Strategy + block bool + returnLastError bool + insecure bool + timeout time.Duration + scChan <-chan ServiceConfig + authority string + copts transport.ConnectOptions + callOptions []CallOption + // This is used by WithBalancerName dial option. balancerBuilder balancer.Builder channelzParentID int64 disableServiceConfig bool @@ -199,19 +199,6 @@ func WithDecompressor(dc Decompressor) DialOption { }) } -// WithBalancer returns a DialOption which sets a load balancer with the v1 API. -// Name resolver will be ignored if this DialOption is specified. -// -// Deprecated: use the new balancer APIs in balancer package and -// WithBalancerName. Will be removed in a future 1.x release. -func WithBalancer(b Balancer) DialOption { - return newFuncDialOption(func(o *dialOptions) { - o.balancerBuilder = &balancerWrapperBuilder{ - b: b, - } - }) -} - // WithBalancerName sets the balancer that the ClientConn will be initialized // with. Balancer registered with balancerName will be used. This function // panics if no balancer was registered by balancerName. @@ -299,6 +286,19 @@ func WithBlock() DialOption { }) } +// WithReturnConnectionError returns a DialOption which makes the client connection +// return a string containing both the last connection error that occurred and +// the context.DeadlineExceeded error. +// Implies WithBlock() +// +// This API is EXPERIMENTAL. +func WithReturnConnectionError() DialOption { + return newFuncDialOption(func(o *dialOptions) { + o.block = true + o.returnLastError = true + }) +} + // WithInsecure returns a DialOption which disables transport security for this // ClientConn. Note that transport security is required unless WithInsecure is // set. @@ -459,7 +459,7 @@ func WithStreamInterceptor(f StreamClientInterceptor) DialOption { } // WithChainStreamInterceptor returns a DialOption that specifies the chained -// interceptor for unary RPCs. The first interceptor will be the outer most, +// interceptor for streaming RPCs. The first interceptor will be the outer most, // while the last interceptor will be the inner most wrapper around the real call. // All interceptors added by this method will be chained, and the interceptor // defined by WithStreamInterceptor will always be prepended to the chain. diff --git a/vendor/google.golang.org/grpc/doc.go b/vendor/google.golang.org/grpc/doc.go index 187adbb11..0022859ad 100644 --- a/vendor/google.golang.org/grpc/doc.go +++ b/vendor/google.golang.org/grpc/doc.go @@ -16,6 +16,8 @@ * */ +//go:generate ./regenerate.sh + /* Package grpc implements an RPC system called gRPC. diff --git a/vendor/google.golang.org/grpc/go.mod b/vendor/google.golang.org/grpc/go.mod index ecef1ab0c..31f2b01f6 100644 --- a/vendor/google.golang.org/grpc/go.mod +++ b/vendor/google.golang.org/grpc/go.mod @@ -6,9 +6,8 @@ require ( github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f github.com/envoyproxy/go-control-plane v0.9.4 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/golang/mock v1.1.1 github.com/golang/protobuf v1.3.3 - github.com/google/go-cmp v0.2.0 + github.com/google/go-cmp v0.4.0 golang.org/x/net v0.0.0-20190311183353-d8887717615a golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a diff --git a/vendor/google.golang.org/grpc/go.sum b/vendor/google.golang.org/grpc/go.sum index 0bf9f0747..be8078eac 100644 --- a/vendor/google.golang.org/grpc/go.sum +++ b/vendor/google.golang.org/grpc/go.sum @@ -23,6 +23,8 @@ github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -50,6 +52,8 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= diff --git a/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go index 8b1051674..b7a3dd8f9 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/binarylog.go @@ -25,6 +25,7 @@ import ( "os" "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/internal/grpcutil" ) // Logger is the global binary logger. It can be used to get binary logger for @@ -146,7 +147,7 @@ func (l *logger) setBlacklist(method string) error { // Each methodLogger returned by this method is a new instance. This is to // generate sequence id within the call. func (l *logger) getMethodLogger(methodName string) *MethodLogger { - s, m, err := parseMethodName(methodName) + s, m, err := grpcutil.ParseMethod(methodName) if err != nil { grpclog.Infof("binarylogging: failed to parse %q: %v", methodName, err) return nil diff --git a/vendor/google.golang.org/grpc/internal/binarylog/regenerate.sh b/vendor/google.golang.org/grpc/internal/binarylog/regenerate.sh deleted file mode 100644 index 113d40cbe..000000000 --- a/vendor/google.golang.org/grpc/internal/binarylog/regenerate.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# Copyright 2018 gRPC authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -eux -o pipefail - -TMP=$(mktemp -d) - -function finish { - rm -rf "$TMP" -} -trap finish EXIT - -pushd "$TMP" -mkdir -p grpc/binarylog/grpc_binarylog_v1 -curl https://raw.githubusercontent.com/grpc/grpc-proto/master/grpc/binlog/v1/binarylog.proto > grpc/binarylog/grpc_binarylog_v1/binarylog.proto - -protoc --go_out=plugins=grpc,paths=source_relative:. -I. grpc/binarylog/grpc_binarylog_v1/*.proto -popd -rm -f ./grpc_binarylog_v1/*.pb.go -cp "$TMP"/grpc/binarylog/grpc_binarylog_v1/*.pb.go ../../binarylog/grpc_binarylog_v1/ - diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index ae6c8972f..73931a94b 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -34,5 +34,5 @@ var ( // Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on". Retry = strings.EqualFold(os.Getenv(retryStr), "on") // TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false"). - TXTErrIgnore = !strings.EqualFold(os.Getenv(retryStr), "false") + TXTErrIgnore = !strings.EqualFold(os.Getenv(txtErrIgnoreStr), "false") ) diff --git a/vendor/google.golang.org/grpc/internal/binarylog/util.go b/vendor/google.golang.org/grpc/internal/grpcutil/method.go similarity index 82% rename from vendor/google.golang.org/grpc/internal/binarylog/util.go rename to vendor/google.golang.org/grpc/internal/grpcutil/method.go index 15dc7803d..2c2ff7732 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/util.go +++ b/vendor/google.golang.org/grpc/internal/grpcutil/method.go @@ -16,18 +16,17 @@ * */ -package binarylog +package grpcutil import ( "errors" "strings" ) -// parseMethodName splits service and method from the input. It expects format +// ParseMethod splits service and method from the input. It expects format // "/service/method". // -// TODO: move to internal/grpcutil. -func parseMethodName(methodName string) (service, method string, _ error) { +func ParseMethod(methodName string) (service, method string, _ error) { if !strings.HasPrefix(methodName, "/") { return "", "", errors.New("invalid method name: should start with /") } diff --git a/vendor/google.golang.org/grpc/internal/internal.go b/vendor/google.golang.org/grpc/internal/internal.go index c6fbe8bb1..818ca8579 100644 --- a/vendor/google.golang.org/grpc/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/internal.go @@ -25,6 +25,7 @@ import ( "time" "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/serviceconfig" ) var ( @@ -40,9 +41,17 @@ var ( // NewRequestInfoContext creates a new context based on the argument context attaching // the passed in RequestInfo to the new context. NewRequestInfoContext interface{} // func(context.Context, credentials.RequestInfo) context.Context + // NewClientHandshakeInfoContext returns a copy of the input context with + // the passed in ClientHandshakeInfo struct added to it. + NewClientHandshakeInfoContext interface{} // func(context.Context, credentials.ClientHandshakeInfo) context.Context // ParseServiceConfigForTesting is for creating a fake // ClientConn for resolver testing only ParseServiceConfigForTesting interface{} // func(string) *serviceconfig.ParseResult + // EqualServiceConfigForTesting is for testing service config generation and + // parsing. Both a and b should be returned by ParseServiceConfigForTesting. + // This function compares the config without rawJSON stripped, in case the + // there's difference in white space. + EqualServiceConfigForTesting func(a, b serviceconfig.Config) bool ) // HealthChecker defines the signature of the client-side LB channel health checking function. diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index c368db62e..9d08dd8ab 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -32,6 +32,7 @@ import ( "sync" "time" + grpclbstate "google.golang.org/grpc/balancer/grpclb/state" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal/envconfig" "google.golang.org/grpc/internal/grpcrand" @@ -251,7 +252,7 @@ func (d *dnsResolver) lookupSRV() ([]resolver.Address, error) { return nil, fmt.Errorf("dns: error parsing A record IP address %v", a) } addr := ip + ":" + strconv.Itoa(int(s.Port)) - newAddrs = append(newAddrs, resolver.Address{Addr: addr, Type: resolver.GRPCLB, ServerName: s.Target}) + newAddrs = append(newAddrs, resolver.Address{Addr: addr, ServerName: s.Target}) } } return newAddrs, nil @@ -326,13 +327,15 @@ func (d *dnsResolver) lookup() (*resolver.State, error) { if hostErr != nil && (srvErr != nil || len(srv) == 0) { return nil, hostErr } - state := &resolver.State{ - Addresses: append(addrs, srv...), + + state := resolver.State{Addresses: addrs} + if len(srv) > 0 { + state = grpclbstate.Set(state, &grpclbstate.State{BalancerAddresses: srv}) } if !d.disableServiceConfig { state.ServiceConfig = d.lookupTXT() } - return state, nil + return &state, nil } // formatIP returns ok = false if addr is not a valid textual representation of an IP address. diff --git a/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go new file mode 100644 index 000000000..9b26414d4 --- /dev/null +++ b/vendor/google.golang.org/grpc/internal/serviceconfig/serviceconfig.go @@ -0,0 +1,90 @@ +/* + * + * Copyright 2020 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// Package serviceconfig contains utility functions to parse service config. +package serviceconfig + +import ( + "encoding/json" + "fmt" + + "google.golang.org/grpc/balancer" + "google.golang.org/grpc/grpclog" + externalserviceconfig "google.golang.org/grpc/serviceconfig" +) + +// BalancerConfig is the balancer config part that service config's +// loadBalancingConfig fields can be unmarshalled to. It's a json unmarshaller. +// +// https://github.com/grpc/grpc-proto/blob/54713b1e8bc6ed2d4f25fb4dff527842150b91b2/grpc/service_config/service_config.proto#L247 +type BalancerConfig struct { + Name string + Config externalserviceconfig.LoadBalancingConfig +} + +type intermediateBalancerConfig []map[string]json.RawMessage + +// UnmarshalJSON implements json unmarshaller. +func (bc *BalancerConfig) UnmarshalJSON(b []byte) error { + var ir intermediateBalancerConfig + err := json.Unmarshal(b, &ir) + if err != nil { + return err + } + + for i, lbcfg := range ir { + if len(lbcfg) != 1 { + return fmt.Errorf("invalid loadBalancingConfig: entry %v does not contain exactly 1 policy/config pair: %q", i, lbcfg) + } + var ( + name string + jsonCfg json.RawMessage + ) + // Get the key:value pair from the map. + for name, jsonCfg = range lbcfg { + } + builder := balancer.Get(name) + if builder == nil { + // If the balancer is not registered, move on to the next config. + // This is not an error. + continue + } + bc.Name = name + + parser, ok := builder.(balancer.ConfigParser) + if !ok { + if string(jsonCfg) != "{}" { + grpclog.Warningf("non-empty balancer configuration %q, but balancer does not implement ParseConfig", string(jsonCfg)) + } + // Stop at this, though the builder doesn't support parsing config. + return nil + } + + cfg, err := parser.ParseConfig(jsonCfg) + if err != nil { + return fmt.Errorf("error parsing loadBalancingConfig for policy %q: %v", name, err) + } + bc.Config = cfg + return nil + } + // This is reached when the for loop iterates over all entries, but didn't + // return. This means we had a loadBalancingConfig slice but did not + // encounter a registered policy. The config is considered invalid in this + // case. + return fmt.Errorf("invalid loadBalancingConfig: no supported policies found") +} diff --git a/vendor/google.golang.org/grpc/internal/status/status.go b/vendor/google.golang.org/grpc/internal/status/status.go index 681260692..710223b8d 100644 --- a/vendor/google.golang.org/grpc/internal/status/status.go +++ b/vendor/google.golang.org/grpc/internal/status/status.go @@ -97,7 +97,7 @@ func (s *Status) Err() error { if s.Code() == codes.OK { return nil } - return (*Error)(s.Proto()) + return &Error{e: s.Proto()} } // WithDetails returns a new status with the provided details messages appended to the status. @@ -136,26 +136,27 @@ func (s *Status) Details() []interface{} { return details } -// Error is an alias of a status proto. It implements error and Status, -// and a nil Error should never be returned by this package. -type Error spb.Status +// Error wraps a pointer of a status proto. It implements error and Status, +// and a nil *Error should never be returned by this package. +type Error struct { + e *spb.Status +} -func (se *Error) Error() string { - p := (*spb.Status)(se) - return fmt.Sprintf("rpc error: code = %s desc = %s", codes.Code(p.GetCode()), p.GetMessage()) +func (e *Error) Error() string { + return fmt.Sprintf("rpc error: code = %s desc = %s", codes.Code(e.e.GetCode()), e.e.GetMessage()) } // GRPCStatus returns the Status represented by se. -func (se *Error) GRPCStatus() *Status { - return FromProto((*spb.Status)(se)) +func (e *Error) GRPCStatus() *Status { + return FromProto(e.e) } // Is implements future error.Is functionality. // A Error is equivalent if the code and message are identical. -func (se *Error) Is(target error) bool { +func (e *Error) Is(target error) bool { tse, ok := target.(*Error) if !ok { return false } - return proto.Equal((*spb.Status)(se), (*spb.Status)(tse)) + return proto.Equal(e.e, tse.e) } diff --git a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go index d3fd9dab3..ae0a9117e 100644 --- a/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go +++ b/vendor/google.golang.org/grpc/internal/syscall/syscall_nonlinux.go @@ -18,6 +18,8 @@ * */ +// Package syscall provides functionalities that grpc uses to get low-level +// operating system stats/info. package syscall import ( diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index ddee20b6b..d4bb19c3b 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -857,38 +857,45 @@ func (l *loopyWriter) processData() (bool, error) { return false, nil } var ( - idx int buf []byte ) - if len(dataItem.h) != 0 { // data header has not been written out yet. - buf = dataItem.h - } else { - idx = 1 - buf = dataItem.d - } - size := http2MaxFrameLen - if len(buf) < size { - size = len(buf) - } + // Figure out the maximum size we can send + maxSize := http2MaxFrameLen if strQuota := int(l.oiws) - str.bytesOutStanding; strQuota <= 0 { // stream-level flow control. str.state = waitingOnStreamQuota return false, nil - } else if strQuota < size { - size = strQuota + } else if maxSize > strQuota { + maxSize = strQuota + } + if maxSize > int(l.sendQuota) { // connection-level flow control. + maxSize = int(l.sendQuota) + } + // Compute how much of the header and data we can send within quota and max frame length + hSize := min(maxSize, len(dataItem.h)) + dSize := min(maxSize-hSize, len(dataItem.d)) + if hSize != 0 { + if dSize == 0 { + buf = dataItem.h + } else { + // We can add some data to grpc message header to distribute bytes more equally across frames. + // Copy on the stack to avoid generating garbage + var localBuf [http2MaxFrameLen]byte + copy(localBuf[:hSize], dataItem.h) + copy(localBuf[hSize:], dataItem.d[:dSize]) + buf = localBuf[:hSize+dSize] + } + } else { + buf = dataItem.d } - if l.sendQuota < uint32(size) { // connection-level flow control. - size = int(l.sendQuota) - } + size := hSize + dSize + // Now that outgoing flow controls are checked we can replenish str's write quota str.wq.replenish(size) var endStream bool // If this is the last data message on this stream and all of it can be written in this iteration. - if dataItem.endStream && size == len(buf) { - // buf contains either data or it contains header but data is empty. - if idx == 1 || len(dataItem.d) == 0 { - endStream = true - } + if dataItem.endStream && len(dataItem.h)+len(dataItem.d) <= size { + endStream = true } if dataItem.onEachWrite != nil { dataItem.onEachWrite() @@ -896,14 +903,10 @@ func (l *loopyWriter) processData() (bool, error) { if err := l.framer.fr.WriteData(dataItem.streamID, endStream, buf[:size]); err != nil { return false, err } - buf = buf[size:] str.bytesOutStanding += size l.sendQuota -= uint32(size) - if idx == 0 { - dataItem.h = buf - } else { - dataItem.d = buf - } + dataItem.h = dataItem.h[hSize:] + dataItem.d = dataItem.d[dSize:] if len(dataItem.h) == 0 && len(dataItem.d) == 0 { // All the data from that message was written out. str.itl.dequeue() @@ -924,3 +927,10 @@ func (l *loopyWriter) processData() (bool, error) { } return false, nil } + +func min(a, b int) int { + if a < b { + return a + } + return b +} diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index 1cc586f73..b43e21ffa 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -41,6 +41,7 @@ import ( "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" + "google.golang.org/grpc/resolver" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" ) @@ -161,7 +162,7 @@ func isTemporary(err error) bool { // newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2 // and starts to receive messages on it. Non-nil error returns if construction // fails. -func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { +func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (_ *http2Client, err error) { scheme := "http" ctx, cancel := context.WithCancel(ctx) defer func() { @@ -214,12 +215,20 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr TargetInfo, opts Conne } } if transportCreds != nil { - scheme = "https" - conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.Authority, conn) + // gRPC, resolver, balancer etc. can specify arbitrary data in the + // Attributes field of resolver.Address, which is shoved into connectCtx + // and passed to the credential handshaker. This makes it possible for + // address specific arbitrary data to reach the credential handshaker. + contextWithHandshakeInfo := internal.NewClientHandshakeInfoContext.(func(context.Context, credentials.ClientHandshakeInfo) context.Context) + connectCtx = contextWithHandshakeInfo(connectCtx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes}) + conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.ServerName, conn) if err != nil { return nil, connectionErrorf(isTemporary(err), err, "transport: authentication handshake failed: %v", err) } isSecure = true + if transportCreds.Info().SecurityProtocol == "tls" { + scheme = "https" + } } dynamicWindow := true icwz := int32(initialWindowSize) @@ -554,13 +563,26 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call return callAuthData, nil } +// PerformedIOError wraps an error to indicate IO may have been performed +// before the error occurred. +type PerformedIOError struct { + Err error +} + +// Error implements error. +func (p PerformedIOError) Error() string { + return p.Err.Error() +} + // NewStream creates a stream and registers it into the transport as "active" // streams. func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { ctx = peer.NewContext(ctx, t.getPeer()) headerFields, err := t.createHeaderFields(ctx, callHdr) if err != nil { - return nil, err + // We may have performed I/O in the per-RPC creds callback, so do not + // allow transparent retry. + return nil, PerformedIOError{err} } s := t.newStream(ctx, callHdr) cleanup := func(err error) { @@ -854,18 +876,10 @@ func (t *http2Client) Write(s *Stream, hdr []byte, data []byte, opts *Options) e df := &dataFrame{ streamID: s.id, endStream: opts.Last, + h: hdr, + d: data, } - if hdr != nil || data != nil { // If it's not an empty data frame. - // Add some data to grpc message header so that we can equally - // distribute bytes across frames. - emptyLen := http2MaxFrameLen - len(hdr) - if emptyLen > len(data) { - emptyLen = len(data) - } - hdr = append(hdr, data[:emptyLen]...) - data = data[emptyLen:] - df.h, df.d = hdr, data - // TODO(mmukhi): The above logic in this if can be moved to loopyWriter's data handler. + if hdr != nil || data != nil { // If it's not an empty data frame, check quota. if err := s.wq.get(int32(len(hdr) + len(data))); err != nil { return err } diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index fa33ffb18..e8c757321 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -909,13 +909,6 @@ func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) e return ContextErr(s.ctx.Err()) } } - // Add some data to header frame so that we can equally distribute bytes across frames. - emptyLen := http2MaxFrameLen - len(hdr) - if emptyLen > len(data) { - emptyLen = len(data) - } - hdr = append(hdr, data[:emptyLen]...) - data = data[emptyLen:] df := &dataFrame{ streamID: s.id, h: hdr, diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index a30da9eb3..1ffd96ff4 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -35,6 +35,7 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" + "google.golang.org/grpc/resolver" "google.golang.org/grpc/stats" "google.golang.org/grpc/status" "google.golang.org/grpc/tap" @@ -568,17 +569,10 @@ type ConnectOptions struct { MaxHeaderListSize *uint32 } -// TargetInfo contains the information of the target such as network address and metadata. -type TargetInfo struct { - Addr string - Metadata interface{} - Authority string -} - // NewClientTransport establishes the transport with the required ConnectOptions // and returns it to the caller. -func NewClientTransport(connectCtx, ctx context.Context, target TargetInfo, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { - return newHTTP2Client(connectCtx, ctx, target, opts, onPrefaceReceipt, onGoAway, onClose) +func NewClientTransport(connectCtx, ctx context.Context, addr resolver.Address, opts ConnectOptions, onPrefaceReceipt func(), onGoAway func(GoAwayReason), onClose func()) (ClientTransport, error) { + return newHTTP2Client(connectCtx, ctx, addr, opts, onPrefaceReceipt, onGoAway, onClose) } // Options provides additional hints and information for message diff --git a/vendor/google.golang.org/grpc/naming/dns_resolver.go b/vendor/google.golang.org/grpc/naming/dns_resolver.go deleted file mode 100644 index c9f79dc53..000000000 --- a/vendor/google.golang.org/grpc/naming/dns_resolver.go +++ /dev/null @@ -1,293 +0,0 @@ -/* - * - * Copyright 2017 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package naming - -import ( - "context" - "errors" - "fmt" - "net" - "strconv" - "time" - - "google.golang.org/grpc/grpclog" -) - -const ( - defaultPort = "443" - defaultFreq = time.Minute * 30 -) - -var ( - errMissingAddr = errors.New("missing address") - errWatcherClose = errors.New("watcher has been closed") - - lookupHost = net.DefaultResolver.LookupHost - lookupSRV = net.DefaultResolver.LookupSRV -) - -// NewDNSResolverWithFreq creates a DNS Resolver that can resolve DNS names, and -// create watchers that poll the DNS server using the frequency set by freq. -func NewDNSResolverWithFreq(freq time.Duration) (Resolver, error) { - return &dnsResolver{freq: freq}, nil -} - -// NewDNSResolver creates a DNS Resolver that can resolve DNS names, and create -// watchers that poll the DNS server using the default frequency defined by defaultFreq. -func NewDNSResolver() (Resolver, error) { - return NewDNSResolverWithFreq(defaultFreq) -} - -// dnsResolver handles name resolution for names following the DNS scheme -type dnsResolver struct { - // frequency of polling the DNS server that the watchers created by this resolver will use. - freq time.Duration -} - -// formatIP returns ok = false if addr is not a valid textual representation of an IP address. -// If addr is an IPv4 address, return the addr and ok = true. -// If addr is an IPv6 address, return the addr enclosed in square brackets and ok = true. -func formatIP(addr string) (addrIP string, ok bool) { - ip := net.ParseIP(addr) - if ip == nil { - return "", false - } - if ip.To4() != nil { - return addr, true - } - return "[" + addr + "]", true -} - -// parseTarget takes the user input target string, returns formatted host and port info. -// If target doesn't specify a port, set the port to be the defaultPort. -// If target is in IPv6 format and host-name is enclosed in square brackets, brackets -// are stripped when setting the host. -// examples: -// target: "www.google.com" returns host: "www.google.com", port: "443" -// target: "ipv4-host:80" returns host: "ipv4-host", port: "80" -// target: "[ipv6-host]" returns host: "ipv6-host", port: "443" -// target: ":80" returns host: "localhost", port: "80" -// target: ":" returns host: "localhost", port: "443" -func parseTarget(target string) (host, port string, err error) { - if target == "" { - return "", "", errMissingAddr - } - - if ip := net.ParseIP(target); ip != nil { - // target is an IPv4 or IPv6(without brackets) address - return target, defaultPort, nil - } - if host, port, err := net.SplitHostPort(target); err == nil { - // target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port - if host == "" { - // Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed. - host = "localhost" - } - if port == "" { - // If the port field is empty(target ends with colon), e.g. "[::1]:", defaultPort is used. - port = defaultPort - } - return host, port, nil - } - if host, port, err := net.SplitHostPort(target + ":" + defaultPort); err == nil { - // target doesn't have port - return host, port, nil - } - return "", "", fmt.Errorf("invalid target address %v", target) -} - -// Resolve creates a watcher that watches the name resolution of the target. -func (r *dnsResolver) Resolve(target string) (Watcher, error) { - host, port, err := parseTarget(target) - if err != nil { - return nil, err - } - - if net.ParseIP(host) != nil { - ipWatcher := &ipWatcher{ - updateChan: make(chan *Update, 1), - } - host, _ = formatIP(host) - ipWatcher.updateChan <- &Update{Op: Add, Addr: host + ":" + port} - return ipWatcher, nil - } - - ctx, cancel := context.WithCancel(context.Background()) - return &dnsWatcher{ - r: r, - host: host, - port: port, - ctx: ctx, - cancel: cancel, - t: time.NewTimer(0), - }, nil -} - -// dnsWatcher watches for the name resolution update for a specific target -type dnsWatcher struct { - r *dnsResolver - host string - port string - // The latest resolved address set - curAddrs map[string]*Update - ctx context.Context - cancel context.CancelFunc - t *time.Timer -} - -// ipWatcher watches for the name resolution update for an IP address. -type ipWatcher struct { - updateChan chan *Update -} - -// Next returns the address resolution Update for the target. For IP address, -// the resolution is itself, thus polling name server is unnecessary. Therefore, -// Next() will return an Update the first time it is called, and will be blocked -// for all following calls as no Update exists until watcher is closed. -func (i *ipWatcher) Next() ([]*Update, error) { - u, ok := <-i.updateChan - if !ok { - return nil, errWatcherClose - } - return []*Update{u}, nil -} - -// Close closes the ipWatcher. -func (i *ipWatcher) Close() { - close(i.updateChan) -} - -// AddressType indicates the address type returned by name resolution. -type AddressType uint8 - -const ( - // Backend indicates the server is a backend server. - Backend AddressType = iota - // GRPCLB indicates the server is a grpclb load balancer. - GRPCLB -) - -// AddrMetadataGRPCLB contains the information the name resolver for grpclb should provide. The -// name resolver used by the grpclb balancer is required to provide this type of metadata in -// its address updates. -type AddrMetadataGRPCLB struct { - // AddrType is the type of server (grpc load balancer or backend). - AddrType AddressType - // ServerName is the name of the grpc load balancer. Used for authentication. - ServerName string -} - -// compileUpdate compares the old resolved addresses and newly resolved addresses, -// and generates an update list -func (w *dnsWatcher) compileUpdate(newAddrs map[string]*Update) []*Update { - var res []*Update - for a, u := range w.curAddrs { - if _, ok := newAddrs[a]; !ok { - u.Op = Delete - res = append(res, u) - } - } - for a, u := range newAddrs { - if _, ok := w.curAddrs[a]; !ok { - res = append(res, u) - } - } - return res -} - -func (w *dnsWatcher) lookupSRV() map[string]*Update { - newAddrs := make(map[string]*Update) - _, srvs, err := lookupSRV(w.ctx, "grpclb", "tcp", w.host) - if err != nil { - grpclog.Infof("grpc: failed dns SRV record lookup due to %v.\n", err) - return nil - } - for _, s := range srvs { - lbAddrs, err := lookupHost(w.ctx, s.Target) - if err != nil { - grpclog.Warningf("grpc: failed load balancer address dns lookup due to %v.\n", err) - continue - } - for _, a := range lbAddrs { - a, ok := formatIP(a) - if !ok { - grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err) - continue - } - addr := a + ":" + strconv.Itoa(int(s.Port)) - newAddrs[addr] = &Update{Addr: addr, - Metadata: AddrMetadataGRPCLB{AddrType: GRPCLB, ServerName: s.Target}} - } - } - return newAddrs -} - -func (w *dnsWatcher) lookupHost() map[string]*Update { - newAddrs := make(map[string]*Update) - addrs, err := lookupHost(w.ctx, w.host) - if err != nil { - grpclog.Warningf("grpc: failed dns A record lookup due to %v.\n", err) - return nil - } - for _, a := range addrs { - a, ok := formatIP(a) - if !ok { - grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err) - continue - } - addr := a + ":" + w.port - newAddrs[addr] = &Update{Addr: addr} - } - return newAddrs -} - -func (w *dnsWatcher) lookup() []*Update { - newAddrs := w.lookupSRV() - if newAddrs == nil { - // If failed to get any balancer address (either no corresponding SRV for the - // target, or caused by failure during resolution/parsing of the balancer target), - // return any A record info available. - newAddrs = w.lookupHost() - } - result := w.compileUpdate(newAddrs) - w.curAddrs = newAddrs - return result -} - -// Next returns the resolved address update(delta) for the target. If there's no -// change, it will sleep for 30 mins and try to resolve again after that. -func (w *dnsWatcher) Next() ([]*Update, error) { - for { - select { - case <-w.ctx.Done(): - return nil, errWatcherClose - case <-w.t.C: - } - result := w.lookup() - // Next lookup should happen after an interval defined by w.r.freq. - w.t.Reset(w.r.freq) - if len(result) > 0 { - return result, nil - } - } -} - -func (w *dnsWatcher) Close() { - w.cancel() -} diff --git a/vendor/google.golang.org/grpc/naming/naming.go b/vendor/google.golang.org/grpc/naming/naming.go deleted file mode 100644 index f4c1c8b68..000000000 --- a/vendor/google.golang.org/grpc/naming/naming.go +++ /dev/null @@ -1,68 +0,0 @@ -/* - * - * Copyright 2014 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// Package naming defines the naming API and related data structures for gRPC. -// -// This package is deprecated: please use package resolver instead. -package naming - -// Operation defines the corresponding operations for a name resolution change. -// -// Deprecated: please use package resolver. -type Operation uint8 - -const ( - // Add indicates a new address is added. - Add Operation = iota - // Delete indicates an existing address is deleted. - Delete -) - -// Update defines a name resolution update. Notice that it is not valid having both -// empty string Addr and nil Metadata in an Update. -// -// Deprecated: please use package resolver. -type Update struct { - // Op indicates the operation of the update. - Op Operation - // Addr is the updated address. It is empty string if there is no address update. - Addr string - // Metadata is the updated metadata. It is nil if there is no metadata update. - // Metadata is not required for a custom naming implementation. - Metadata interface{} -} - -// Resolver creates a Watcher for a target to track its resolution changes. -// -// Deprecated: please use package resolver. -type Resolver interface { - // Resolve creates a Watcher for target. - Resolve(target string) (Watcher, error) -} - -// Watcher watches for the updates on the specified target. -// -// Deprecated: please use package resolver. -type Watcher interface { - // Next blocks until an update or error happens. It may return one or more - // updates. The first call should get the full set of the results. It should - // return an error if and only if Watcher cannot recover. - Next() ([]*Update, error) - // Close closes the Watcher. - Close() -} diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index 00447894f..7f3edaaed 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -20,7 +20,6 @@ package grpc import ( "context" - "fmt" "io" "sync" @@ -32,68 +31,21 @@ import ( "google.golang.org/grpc/status" ) -// v2PickerWrapper wraps a balancer.Picker while providing the -// balancer.V2Picker API. It requires a pickerWrapper to generate errors -// including the latest connectionError. To be deleted when balancer.Picker is -// updated to the balancer.V2Picker API. -type v2PickerWrapper struct { - picker balancer.Picker - connErr *connErr -} - -func (v *v2PickerWrapper) Pick(info balancer.PickInfo) (balancer.PickResult, error) { - sc, done, err := v.picker.Pick(info.Ctx, info) - if err != nil { - if err == balancer.ErrTransientFailure { - return balancer.PickResult{}, balancer.TransientFailureError(fmt.Errorf("%v, latest connection error: %v", err, v.connErr.connectionError())) - } - return balancer.PickResult{}, err - } - return balancer.PickResult{SubConn: sc, Done: done}, nil -} - // pickerWrapper is a wrapper of balancer.Picker. It blocks on certain pick // actions and unblock when there's a picker update. type pickerWrapper struct { mu sync.Mutex done bool blockingCh chan struct{} - picker balancer.V2Picker - - // The latest connection error. TODO: remove when V1 picker is deprecated; - // balancer should be responsible for providing the error. - *connErr -} - -type connErr struct { - mu sync.Mutex - err error -} - -func (c *connErr) updateConnectionError(err error) { - c.mu.Lock() - c.err = err - c.mu.Unlock() -} - -func (c *connErr) connectionError() error { - c.mu.Lock() - err := c.err - c.mu.Unlock() - return err + picker balancer.Picker } func newPickerWrapper() *pickerWrapper { - return &pickerWrapper{blockingCh: make(chan struct{}), connErr: &connErr{}} + return &pickerWrapper{blockingCh: make(chan struct{})} } // updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. func (pw *pickerWrapper) updatePicker(p balancer.Picker) { - pw.updatePickerV2(&v2PickerWrapper{picker: p, connErr: pw.connErr}) -} - -// updatePicker is called by UpdateBalancerState. It unblocks all blocked pick. -func (pw *pickerWrapper) updatePickerV2(p balancer.V2Picker) { pw.mu.Lock() if pw.done { pw.mu.Unlock() @@ -154,8 +106,6 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. var errStr string if lastPickErr != nil { errStr = "latest balancer error: " + lastPickErr.Error() - } else if connectionErr := pw.connectionError(); connectionErr != nil { - errStr = "latest connection error: " + connectionErr.Error() } else { errStr = ctx.Err().Error() } @@ -180,18 +130,17 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. if err == balancer.ErrNoSubConnAvailable { continue } - if tfe, ok := err.(interface{ IsTransientFailure() bool }); ok && tfe.IsTransientFailure() { - if !failfast { - lastPickErr = err - continue - } - return nil, nil, status.Error(codes.Unavailable, err.Error()) - } if _, ok := status.FromError(err); ok { + // Status error: end the RPC unconditionally with this status. return nil, nil, err } - // err is some other error. - return nil, nil, status.Error(codes.Unknown, err.Error()) + // For all other errors, wait for ready RPCs should block and other + // RPCs should fail with unavailable. + if !failfast { + lastPickErr = err + continue + } + return nil, nil, status.Error(codes.Unavailable, err.Error()) } acw, ok := pickResult.SubConn.(*acBalancerWrapper) diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index c43dac9ad..4b7340ad3 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -20,13 +20,11 @@ package grpc import ( "errors" + "fmt" "google.golang.org/grpc/balancer" - "google.golang.org/grpc/codes" "google.golang.org/grpc/connectivity" "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/resolver" - "google.golang.org/grpc/status" ) // PickFirstBalancerName is the name of the pick_first balancer. @@ -52,27 +50,13 @@ type pickfirstBalancer struct { sc balancer.SubConn } -var _ balancer.V2Balancer = &pickfirstBalancer{} // Assert we implement v2 - -func (b *pickfirstBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) { - if err != nil { - b.ResolverError(err) - return - } - b.UpdateClientConnState(balancer.ClientConnState{ResolverState: resolver.State{Addresses: addrs}}) // Ignore error -} - -func (b *pickfirstBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { - b.UpdateSubConnState(sc, balancer.SubConnState{ConnectivityState: s}) -} - func (b *pickfirstBalancer) ResolverError(err error) { switch b.state { case connectivity.TransientFailure, connectivity.Idle, connectivity.Connecting: // Set a failing picker if we don't have a good picker. b.cc.UpdateState(balancer.State{ConnectivityState: connectivity.TransientFailure, - Picker: &picker{err: status.Errorf(codes.Unavailable, "name resolver error: %v", err)}}, - ) + Picker: &picker{err: fmt.Errorf("name resolver error: %v", err)}, + }) } if grpclog.V(2) { grpclog.Infof("pickfirstBalancer: ResolverError called with error %v", err) @@ -93,8 +77,8 @@ func (b *pickfirstBalancer) UpdateClientConnState(cs balancer.ClientConnState) e } b.state = connectivity.TransientFailure b.cc.UpdateState(balancer.State{ConnectivityState: connectivity.TransientFailure, - Picker: &picker{err: status.Errorf(codes.Unavailable, "error creating connection: %v", err)}}, - ) + Picker: &picker{err: fmt.Errorf("error creating connection: %v", err)}, + }) return balancer.ErrBadResolverState } b.state = connectivity.Idle @@ -109,7 +93,7 @@ func (b *pickfirstBalancer) UpdateClientConnState(cs balancer.ClientConnState) e func (b *pickfirstBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.SubConnState) { if grpclog.V(2) { - grpclog.Infof("pickfirstBalancer: HandleSubConnStateChange: %p, %v", sc, s) + grpclog.Infof("pickfirstBalancer: UpdateSubConnState: %p, %v", sc, s) } if b.sc != sc { if grpclog.V(2) { @@ -129,15 +113,9 @@ func (b *pickfirstBalancer) UpdateSubConnState(sc balancer.SubConn, s balancer.S case connectivity.Connecting: b.cc.UpdateState(balancer.State{ConnectivityState: s.ConnectivityState, Picker: &picker{err: balancer.ErrNoSubConnAvailable}}) case connectivity.TransientFailure: - err := balancer.ErrTransientFailure - // TODO: this can be unconditional after the V1 API is removed, as - // SubConnState will always contain a connection error. - if s.ConnectionError != nil { - err = balancer.TransientFailureError(s.ConnectionError) - } b.cc.UpdateState(balancer.State{ ConnectivityState: s.ConnectivityState, - Picker: &picker{err: err}, + Picker: &picker{err: s.ConnectionError}, }) } } diff --git a/vendor/google.golang.org/grpc/regenerate.sh b/vendor/google.golang.org/grpc/regenerate.sh new file mode 100644 index 000000000..987bc2025 --- /dev/null +++ b/vendor/google.golang.org/grpc/regenerate.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Copyright 2020 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -eu -o pipefail + +WORKDIR=$(mktemp -d) + +function finish { + rm -rf "$WORKDIR" +} +trap finish EXIT + +export GOBIN=${WORKDIR}/bin +export PATH=${GOBIN}:${PATH} +mkdir -p ${GOBIN} + +echo "go install github.com/golang/protobuf/protoc-gen-go" +(cd test/tools && go install github.com/golang/protobuf/protoc-gen-go) + +echo "go install cmd/protoc-gen-go-grpc" +(cd cmd/protoc-gen-go-grpc && go install .) + +echo "git clone https://github.com/grpc/grpc-proto" +git clone --quiet https://github.com/grpc/grpc-proto ${WORKDIR}/grpc-proto + +mkdir -p ${WORKDIR}/googleapis/google/rpc +echo "curl https://raw.githubusercontent.com/googleapis/googleapis/master/google/rpc/code.proto" +curl --silent https://raw.githubusercontent.com/googleapis/googleapis/master/google/rpc/code.proto > ${WORKDIR}/googleapis/google/rpc/code.proto + +mkdir -p ${WORKDIR}/out + +SOURCES=( + ${WORKDIR}/googleapis/google/rpc/code.proto + ${WORKDIR}/grpc-proto/grpc/binlog/v1/binarylog.proto + ${WORKDIR}/grpc-proto/grpc/channelz/v1/channelz.proto + ${WORKDIR}/grpc-proto/grpc/gcp/altscontext.proto + ${WORKDIR}/grpc-proto/grpc/gcp/handshaker.proto + ${WORKDIR}/grpc-proto/grpc/gcp/transport_security_common.proto + ${WORKDIR}/grpc-proto/grpc/health/v1/health.proto + ${WORKDIR}/grpc-proto/grpc/lb/v1/load_balancer.proto + ${WORKDIR}/grpc-proto/grpc/lookup/v1/rls.proto + ${WORKDIR}/grpc-proto/grpc/service_config/service_config.proto + $(git ls-files --exclude-standard --cached --others "*.proto") +) +OPTS=Mgrpc/service_config/service_config.proto=/internal/proto/grpc_service_config +for src in ${SOURCES[@]}; do + echo "protoc ${src}" + protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS},requireUnimplementedServers=false:${WORKDIR}/out \ + -I"." \ + -I${WORKDIR}/grpc-proto \ + -I${WORKDIR}/googleapis \ + ${src} +done + +# The go_package option in grpc/lookup/v1/rls.proto doesn't match the +# current location. Move it into the right place. +mkdir -p ${WORKDIR}/out/google.golang.org/grpc/balancer/rls/internal/proto/grpc_lookup_v1 +mv ${WORKDIR}/out/google.golang.org/grpc/lookup/grpc_lookup_v1/* ${WORKDIR}/out/google.golang.org/grpc/balancer/rls/internal/proto/grpc_lookup_v1 + +# grpc_testingv3/testv3.pb.go is not re-generated because it was +# intentionally generated by an older version of protoc-gen-go. +rm ${WORKDIR}/out/google.golang.org/grpc/reflection/grpc_testingv3/*.pb.go + +# grpc/service_config/service_config.proto does not have a go_package option. +cp ${WORKDIR}/out/grpc/service_config/service_config.pb.go internal/proto/grpc_service_config + +cp -R ${WORKDIR}/out/google.golang.org/grpc/* . diff --git a/vendor/google.golang.org/grpc/resolver/resolver.go b/vendor/google.golang.org/grpc/resolver/resolver.go index fe14b2fb9..379275a2d 100644 --- a/vendor/google.golang.org/grpc/resolver/resolver.go +++ b/vendor/google.golang.org/grpc/resolver/resolver.go @@ -85,7 +85,10 @@ const ( Backend AddressType = iota // GRPCLB indicates the address is for a grpclb load balancer. // - // Deprecated: use Attributes in Address instead. + // Deprecated: to select the GRPCLB load balancing policy, use a service + // config with a corresponding loadBalancingConfig. To supply balancer + // addresses to the GRPCLB load balancing policy, set State.Attributes + // using balancer/grpclb/state.Set. GRPCLB ) diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index cf9dbe7fd..8644b8a7d 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -155,7 +155,6 @@ func (d *gzipDecompressor) Type() string { type callInfo struct { compressorType string failFast bool - stream ClientStream maxReceiveMessageSize *int maxSendMessageSize *int creds credentials.PerRPCCredentials @@ -180,7 +179,7 @@ type CallOption interface { // after is called after the call has completed. after cannot return an // error, so any failures should be reported via output parameters. - after(*callInfo) + after(*callInfo, *csAttempt) } // EmptyCallOption does not alter the Call configuration. @@ -188,8 +187,8 @@ type CallOption interface { // by interceptors. type EmptyCallOption struct{} -func (EmptyCallOption) before(*callInfo) error { return nil } -func (EmptyCallOption) after(*callInfo) {} +func (EmptyCallOption) before(*callInfo) error { return nil } +func (EmptyCallOption) after(*callInfo, *csAttempt) {} // Header returns a CallOptions that retrieves the header metadata // for a unary RPC. @@ -205,10 +204,8 @@ type HeaderCallOption struct { } func (o HeaderCallOption) before(c *callInfo) error { return nil } -func (o HeaderCallOption) after(c *callInfo) { - if c.stream != nil { - *o.HeaderAddr, _ = c.stream.Header() - } +func (o HeaderCallOption) after(c *callInfo, attempt *csAttempt) { + *o.HeaderAddr, _ = attempt.s.Header() } // Trailer returns a CallOptions that retrieves the trailer metadata @@ -225,10 +222,8 @@ type TrailerCallOption struct { } func (o TrailerCallOption) before(c *callInfo) error { return nil } -func (o TrailerCallOption) after(c *callInfo) { - if c.stream != nil { - *o.TrailerAddr = c.stream.Trailer() - } +func (o TrailerCallOption) after(c *callInfo, attempt *csAttempt) { + *o.TrailerAddr = attempt.s.Trailer() } // Peer returns a CallOption that retrieves peer information for a unary RPC. @@ -245,11 +240,9 @@ type PeerCallOption struct { } func (o PeerCallOption) before(c *callInfo) error { return nil } -func (o PeerCallOption) after(c *callInfo) { - if c.stream != nil { - if x, ok := peer.FromContext(c.stream.Context()); ok { - *o.PeerAddr = *x - } +func (o PeerCallOption) after(c *callInfo, attempt *csAttempt) { + if x, ok := peer.FromContext(attempt.s.Context()); ok { + *o.PeerAddr = *x } } @@ -285,7 +278,7 @@ func (o FailFastCallOption) before(c *callInfo) error { c.failFast = o.FailFast return nil } -func (o FailFastCallOption) after(c *callInfo) {} +func (o FailFastCallOption) after(c *callInfo, attempt *csAttempt) {} // MaxCallRecvMsgSize returns a CallOption which sets the maximum message size // in bytes the client can receive. @@ -304,7 +297,7 @@ func (o MaxRecvMsgSizeCallOption) before(c *callInfo) error { c.maxReceiveMessageSize = &o.MaxRecvMsgSize return nil } -func (o MaxRecvMsgSizeCallOption) after(c *callInfo) {} +func (o MaxRecvMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {} // MaxCallSendMsgSize returns a CallOption which sets the maximum message size // in bytes the client can send. @@ -323,7 +316,7 @@ func (o MaxSendMsgSizeCallOption) before(c *callInfo) error { c.maxSendMessageSize = &o.MaxSendMsgSize return nil } -func (o MaxSendMsgSizeCallOption) after(c *callInfo) {} +func (o MaxSendMsgSizeCallOption) after(c *callInfo, attempt *csAttempt) {} // PerRPCCredentials returns a CallOption that sets credentials.PerRPCCredentials // for a call. @@ -342,7 +335,7 @@ func (o PerRPCCredsCallOption) before(c *callInfo) error { c.creds = o.Creds return nil } -func (o PerRPCCredsCallOption) after(c *callInfo) {} +func (o PerRPCCredsCallOption) after(c *callInfo, attempt *csAttempt) {} // UseCompressor returns a CallOption which sets the compressor used when // sending the request. If WithCompressor is also set, UseCompressor has @@ -363,7 +356,7 @@ func (o CompressorCallOption) before(c *callInfo) error { c.compressorType = o.CompressorType return nil } -func (o CompressorCallOption) after(c *callInfo) {} +func (o CompressorCallOption) after(c *callInfo, attempt *csAttempt) {} // CallContentSubtype returns a CallOption that will set the content-subtype // for a call. For example, if content-subtype is "json", the Content-Type over @@ -396,7 +389,7 @@ func (o ContentSubtypeCallOption) before(c *callInfo) error { c.contentSubtype = o.ContentSubtype return nil } -func (o ContentSubtypeCallOption) after(c *callInfo) {} +func (o ContentSubtypeCallOption) after(c *callInfo, attempt *csAttempt) {} // ForceCodec returns a CallOption that will set the given Codec to be // used for all request and response messages for a call. The result of calling @@ -428,7 +421,7 @@ func (o ForceCodecCallOption) before(c *callInfo) error { c.codec = o.Codec return nil } -func (o ForceCodecCallOption) after(c *callInfo) {} +func (o ForceCodecCallOption) after(c *callInfo, attempt *csAttempt) {} // CallCustomCodec behaves like ForceCodec, but accepts a grpc.Codec instead of // an encoding.Codec. @@ -450,7 +443,7 @@ func (o CustomCodecCallOption) before(c *callInfo) error { c.codec = o.Codec return nil } -func (o CustomCodecCallOption) after(c *callInfo) {} +func (o CustomCodecCallOption) after(c *callInfo, attempt *csAttempt) {} // MaxRetryRPCBufferSize returns a CallOption that limits the amount of memory // used for buffering this RPC's requests for retry purposes. @@ -471,7 +464,7 @@ func (o MaxRetryRPCBufferSizeCallOption) before(c *callInfo) error { c.maxRetryRPCBufferSize = o.MaxRetryRPCBufferSize return nil } -func (o MaxRetryRPCBufferSizeCallOption) after(c *callInfo) {} +func (o MaxRetryRPCBufferSizeCallOption) after(c *callInfo, attempt *csAttempt) {} // The format of the payload: compressed or not? type payloadFormat uint8 diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index edfcdcaee..c2c7cae6c 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -42,6 +42,7 @@ import ( "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/channelz" + "google.golang.org/grpc/internal/grpcrand" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" @@ -87,6 +88,12 @@ type service struct { mdata interface{} } +type serverWorkerData struct { + st transport.ServerTransport + wg *sync.WaitGroup + stream *transport.Stream +} + // Server is a gRPC server to serve RPC requests. type Server struct { opts serverOptions @@ -107,6 +114,8 @@ type Server struct { channelzID int64 // channelz unique identification number czData *channelzData + + serverWorkerChannels []chan *serverWorkerData } type serverOptions struct { @@ -133,6 +142,7 @@ type serverOptions struct { connectionTimeout time.Duration maxHeaderListSize *uint32 headerTableSize *uint32 + numServerWorkers uint32 } var defaultServerOptions = serverOptions{ @@ -335,7 +345,7 @@ func StreamInterceptor(i StreamServerInterceptor) ServerOption { } // ChainStreamInterceptor returns a ServerOption that specifies the chained interceptor -// for stream RPCs. The first interceptor will be the outer most, +// for streaming RPCs. The first interceptor will be the outer most, // while the last interceptor will be the inner most wrapper around the real call. // All stream interceptors added by this method will be chained. func ChainStreamInterceptor(interceptors ...StreamServerInterceptor) ServerOption { @@ -410,6 +420,66 @@ func HeaderTableSize(s uint32) ServerOption { }) } +// NumStreamWorkers returns a ServerOption that sets the number of worker +// goroutines that should be used to process incoming streams. Setting this to +// zero (default) will disable workers and spawn a new goroutine for each +// stream. +// +// This API is EXPERIMENTAL. +func NumStreamWorkers(numServerWorkers uint32) ServerOption { + // TODO: If/when this API gets stabilized (i.e. stream workers become the + // only way streams are processed), change the behavior of the zero value to + // a sane default. Preliminary experiments suggest that a value equal to the + // number of CPUs available is most performant; requires thorough testing. + return newFuncServerOption(func(o *serverOptions) { + o.numServerWorkers = numServerWorkers + }) +} + +// serverWorkerResetThreshold defines how often the stack must be reset. Every +// N requests, by spawning a new goroutine in its place, a worker can reset its +// stack so that large stacks don't live in memory forever. 2^16 should allow +// each goroutine stack to live for at least a few seconds in a typical +// workload (assuming a QPS of a few thousand requests/sec). +const serverWorkerResetThreshold = 1 << 16 + +// serverWorkers blocks on a *transport.Stream channel forever and waits for +// data to be fed by serveStreams. This allows different requests to be +// processed by the same goroutine, removing the need for expensive stack +// re-allocations (see the runtime.morestack problem [1]). +// +// [1] https://github.com/golang/go/issues/18138 +func (s *Server) serverWorker(ch chan *serverWorkerData) { + // To make sure all server workers don't reset at the same time, choose a + // random number of iterations before resetting. + threshold := serverWorkerResetThreshold + grpcrand.Intn(serverWorkerResetThreshold) + for completed := 0; completed < threshold; completed++ { + data, ok := <-ch + if !ok { + return + } + s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream)) + data.wg.Done() + } + go s.serverWorker(ch) +} + +// initServerWorkers creates worker goroutines and channels to process incoming +// connections to reduce the time spent overall on runtime.morestack. +func (s *Server) initServerWorkers() { + s.serverWorkerChannels = make([]chan *serverWorkerData, s.opts.numServerWorkers) + for i := uint32(0); i < s.opts.numServerWorkers; i++ { + s.serverWorkerChannels[i] = make(chan *serverWorkerData) + go s.serverWorker(s.serverWorkerChannels[i]) + } +} + +func (s *Server) stopServerWorkers() { + for i := uint32(0); i < s.opts.numServerWorkers; i++ { + close(s.serverWorkerChannels[i]) + } +} + // NewServer creates a gRPC server which has no service registered and has not // started to accept requests yet. func NewServer(opt ...ServerOption) *Server { @@ -434,6 +504,10 @@ func NewServer(opt ...ServerOption) *Server { s.events = trace.NewEventLog("grpc.Server", fmt.Sprintf("%s:%d", file, line)) } + if s.opts.numServerWorkers > 0 { + s.initServerWorkers() + } + if channelz.IsOn() { s.channelzID = channelz.RegisterServer(&channelzServer{s}, "") } @@ -739,12 +813,27 @@ func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) tr func (s *Server) serveStreams(st transport.ServerTransport) { defer st.Close() var wg sync.WaitGroup + + var roundRobinCounter uint32 st.HandleStreams(func(stream *transport.Stream) { wg.Add(1) - go func() { - defer wg.Done() - s.handleStream(st, stream, s.traceInfo(st, stream)) - }() + if s.opts.numServerWorkers > 0 { + data := &serverWorkerData{st: st, wg: &wg, stream: stream} + select { + case s.serverWorkerChannels[atomic.AddUint32(&roundRobinCounter, 1)%s.opts.numServerWorkers] <- data: + default: + // If all stream workers are busy, fallback to the default code path. + go func() { + s.handleStream(st, stream, s.traceInfo(st, stream)) + wg.Done() + }() + } + } else { + go func() { + defer wg.Done() + s.handleStream(st, stream, s.traceInfo(st, stream)) + }() + } }, func(ctx context.Context, method string) context.Context { if !EnableTracing { return ctx @@ -1507,6 +1596,9 @@ func (s *Server) Stop() { for c := range st { c.Close() } + if s.opts.numServerWorkers > 0 { + s.stopServerWorkers() + } s.mu.Lock() if s.events != nil { diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 5a80a575a..3132a66cd 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -21,14 +21,15 @@ package grpc import ( "encoding/json" "fmt" + "reflect" "strconv" "strings" "time" - "google.golang.org/grpc/balancer" "google.golang.org/grpc/codes" "google.golang.org/grpc/grpclog" "google.golang.org/grpc/internal" + internalserviceconfig "google.golang.org/grpc/internal/serviceconfig" "google.golang.org/grpc/serviceconfig" ) @@ -79,7 +80,7 @@ type ServiceConfig struct { serviceconfig.Config // LB is the load balancer the service providers recommends. The balancer - // specified via grpc.WithBalancer will override this. This is deprecated; + // specified via grpc.WithBalancerName will override this. This is deprecated; // lbConfigs is preferred. If lbConfig and LB are both present, lbConfig // will be used. LB *string @@ -249,12 +250,10 @@ type jsonMC struct { RetryPolicy *jsonRetryPolicy } -type loadBalancingConfig map[string]json.RawMessage - // TODO(lyuxuan): delete this struct after cleaning up old service config implementation. type jsonSC struct { LoadBalancingPolicy *string - LoadBalancingConfig *[]loadBalancingConfig + LoadBalancingConfig *internalserviceconfig.BalancerConfig MethodConfig *[]jsonMC RetryThrottling *retryThrottlingPolicy HealthCheckConfig *healthCheckConfig @@ -280,40 +279,10 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { healthCheckConfig: rsc.HealthCheckConfig, rawJSONString: js, } - if rsc.LoadBalancingConfig != nil { - for i, lbcfg := range *rsc.LoadBalancingConfig { - if len(lbcfg) != 1 { - err := fmt.Errorf("invalid loadBalancingConfig: entry %v does not contain exactly 1 policy/config pair: %q", i, lbcfg) - grpclog.Warningf(err.Error()) - return &serviceconfig.ParseResult{Err: err} - } - var name string - var jsonCfg json.RawMessage - for name, jsonCfg = range lbcfg { - } - builder := balancer.Get(name) - if builder == nil { - continue - } - sc.lbConfig = &lbConfig{name: name} - if parser, ok := builder.(balancer.ConfigParser); ok { - var err error - sc.lbConfig.cfg, err = parser.ParseConfig(jsonCfg) - if err != nil { - return &serviceconfig.ParseResult{Err: fmt.Errorf("error parsing loadBalancingConfig for policy %q: %v", name, err)} - } - } else if string(jsonCfg) != "{}" { - grpclog.Warningf("non-empty balancer configuration %q, but balancer does not implement ParseConfig", string(jsonCfg)) - } - break - } - if sc.lbConfig == nil { - // We had a loadBalancingConfig field but did not encounter a - // supported policy. The config is considered invalid in this - // case. - err := fmt.Errorf("invalid loadBalancingConfig: no supported policies found") - grpclog.Warningf(err.Error()) - return &serviceconfig.ParseResult{Err: err} + if c := rsc.LoadBalancingConfig; c != nil { + sc.lbConfig = &lbConfig{ + name: c.Name, + cfg: c.Config, } } @@ -432,3 +401,34 @@ func getMaxSize(mcMax, doptMax *int, defaultVal int) *int { func newInt(b int) *int { return &b } + +func init() { + internal.EqualServiceConfigForTesting = equalServiceConfig +} + +// equalServiceConfig compares two configs. The rawJSONString field is ignored, +// because they may diff in white spaces. +// +// If any of them is NOT *ServiceConfig, return false. +func equalServiceConfig(a, b serviceconfig.Config) bool { + aa, ok := a.(*ServiceConfig) + if !ok { + return false + } + bb, ok := b.(*ServiceConfig) + if !ok { + return false + } + aaRaw := aa.rawJSONString + aa.rawJSONString = "" + bbRaw := bb.rawJSONString + bb.rawJSONString = "" + defer func() { + aa.rawJSONString = aaRaw + bb.rawJSONString = bbRaw + }() + // Using reflect.DeepEqual instead of cmp.Equal because many balancer + // configs are unexported, and cmp.Equal cannot compare unexported fields + // from unexported structs. + return reflect.DeepEqual(aa, bb) +} diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index a7970c79a..63e476ee7 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -16,8 +16,6 @@ * */ -//go:generate protoc --go_out=plugins=grpc:. grpc_testing/test.proto - // Package stats is for collecting and reporting various network and RPC stats. // This package is for monitoring purpose only. All fields are read-only. // All APIs are experimental. diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index 934ef6832..629af76bd 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -277,7 +277,6 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth } cs.binlog = binarylog.GetMethodLogger(method) - cs.callInfo.stream = cs // Only this initial attempt has stats/tracing. // TODO(dfawley): move to newAttempt when per-attempt stats are implemented. if err := cs.newAttemptLocked(sh, trInfo); err != nil { @@ -365,6 +364,11 @@ func (a *csAttempt) newStream() error { cs.callHdr.PreviousAttempts = cs.numRetries s, err := a.t.NewStream(cs.ctx, cs.callHdr) if err != nil { + if _, ok := err.(transport.PerformedIOError); ok { + // Return without converting to an RPC error so retry code can + // inspect. + return err + } return toRPCErr(err) } cs.attempt.s = s @@ -460,11 +464,21 @@ func (cs *clientStream) commitAttempt() { // shouldRetry returns nil if the RPC should be retried; otherwise it returns // the error that should be returned by the operation. func (cs *clientStream) shouldRetry(err error) error { - if cs.attempt.s == nil && !cs.callInfo.failFast { - // In the event of any error from NewStream (attempt.s == nil), we - // never attempted to write anything to the wire, so we can retry - // indefinitely for non-fail-fast RPCs. - return nil + unprocessed := false + if cs.attempt.s == nil { + pioErr, ok := err.(transport.PerformedIOError) + if ok { + // Unwrap error. + err = toRPCErr(pioErr.Err) + } else { + unprocessed = true + } + if !ok && !cs.callInfo.failFast { + // In the event of a non-IO operation error from NewStream, we + // never attempted to write anything to the wire, so we can retry + // indefinitely for non-fail-fast RPCs. + return nil + } } if cs.finished || cs.committed { // RPC is finished or committed; cannot retry. @@ -473,13 +487,12 @@ func (cs *clientStream) shouldRetry(err error) error { // Wait for the trailers. if cs.attempt.s != nil { <-cs.attempt.s.Done() + unprocessed = cs.attempt.s.Unprocessed() } - if cs.firstAttempt && (cs.attempt.s == nil || cs.attempt.s.Unprocessed()) { + if cs.firstAttempt && unprocessed { // First attempt, stream unprocessed: transparently retry. - cs.firstAttempt = false return nil } - cs.firstAttempt = false if cs.cc.dopts.disableRetry { return err } @@ -565,6 +578,7 @@ func (cs *clientStream) retryLocked(lastErr error) error { cs.commitAttemptLocked() return err } + cs.firstAttempt = false if err := cs.newAttemptLocked(nil, nil); err != nil { return err } @@ -799,6 +813,15 @@ func (cs *clientStream) finish(err error) { } cs.finished = true cs.commitAttemptLocked() + if cs.attempt != nil { + cs.attempt.finish(err) + // after functions all rely upon having a stream. + if cs.attempt.s != nil { + for _, o := range cs.opts { + o.after(cs.callInfo, cs.attempt) + } + } + } cs.mu.Unlock() // For binary logging. only log cancel in finish (could be caused by RPC ctx // canceled or ClientConn closed). Trailer will be logged in RecvMsg. @@ -820,15 +843,6 @@ func (cs *clientStream) finish(err error) { cs.cc.incrCallsSucceeded() } } - if cs.attempt != nil { - cs.attempt.finish(err) - // after functions all rely upon having a stream. - if cs.attempt.s != nil { - for _, o := range cs.opts { - o.after(cs.callInfo) - } - } - } cs.cancel() } @@ -1066,7 +1080,6 @@ func newNonRetryClientStream(ctx context.Context, desc *StreamDesc, method strin t: t, } - as.callInfo.stream = as s, err := as.t.NewStream(as.ctx, as.callHdr) if err != nil { err = toRPCErr(err) diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index ca5d55fdd..c7e67b847 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.29.1" +const Version = "1.30.0" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh index e12024fb8..f0a67298a 100644 --- a/vendor/google.golang.org/grpc/vet.sh +++ b/vendor/google.golang.org/grpc/vet.sh @@ -39,8 +39,7 @@ if [[ "$1" = "-install" ]]; then golang.org/x/lint/golint \ golang.org/x/tools/cmd/goimports \ honnef.co/go/tools/cmd/staticcheck \ - github.com/client9/misspell/cmd/misspell \ - github.com/golang/protobuf/protoc-gen-go + github.com/client9/misspell/cmd/misspell popd else # Ye olde `go get` incantation. @@ -50,8 +49,7 @@ if [[ "$1" = "-install" ]]; then golang.org/x/lint/golint \ golang.org/x/tools/cmd/goimports \ honnef.co/go/tools/cmd/staticcheck \ - github.com/client9/misspell/cmd/misspell \ - github.com/golang/protobuf/protoc-gen-go + github.com/client9/misspell/cmd/misspell fi if [[ -z "${VET_SKIP_PROTO}" ]]; then if [[ "${TRAVIS}" = "true" ]]; then @@ -88,6 +86,9 @@ git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^stress\|grpc # - Ensure all ptypes proto packages are renamed when importing. not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" +# - Ensure all xds proto imports are renamed to *pb or *grpc. +git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' | not grep -v 'pb "\|grpc "' + # - Check imports that are illegal in appengine (until Go 1.11). # TODO: Remove when we drop Go 1.10 support go list -f {{.Dir}} ./... | xargs go run test/go_vet/vet.go @@ -123,14 +124,13 @@ staticcheck -go 1.9 -checks 'inherit,-ST1015' ./... > "${SC_OUT}" || true # Error if anything other than deprecation warnings are printed. not grep -v "is deprecated:.*SA1019" "${SC_OUT}" # Only ignore the following deprecated types/fields/functions. -not grep -Fv '.HandleResolvedAddrs -.HandleSubConnStateChange +not grep -Fv '.CredsBundle .HeaderMap +.Metadata is deprecated: use Attributes .NewAddress .NewServiceConfig -.Metadata is deprecated: use Attributes .Type is deprecated: use Attributes -.UpdateBalancerState +balancer.ErrTransientFailure balancer.Picker grpc.CallCustomCodec grpc.Code @@ -142,9 +142,7 @@ grpc.NewGZIPCompressor grpc.NewGZIPDecompressor grpc.RPCCompressor grpc.RPCDecompressor -grpc.RoundRobin grpc.ServiceConfig -grpc.WithBalancer grpc.WithBalancerName grpc.WithCompressor grpc.WithDecompressor @@ -154,10 +152,38 @@ grpc.WithServiceConfig grpc.WithTimeout http.CloseNotifier info.SecurityVersion -naming.Resolver -naming.Update -naming.Watcher resolver.Backend resolver.GRPCLB' "${SC_OUT}" +# - special golint on package comments. +lint_package_comment_per_package() { + # Number of files in this go package. + fileCount=$(go list -f '{{len .GoFiles}}' $1) + if [ ${fileCount} -eq 0 ]; then + return 0 + fi + # Number of package errors generated by golint. + lintPackageCommentErrorsCount=$(golint --min_confidence 0 $1 | grep -c "should have a package comment") + # golint complains about every file that's missing the package comment. If the + # number of files for this package is greater than the number of errors, there's + # at least one file with package comment, good. Otherwise, fail. + if [ ${fileCount} -le ${lintPackageCommentErrorsCount} ]; then + echo "Package $1 (with ${fileCount} files) is missing package comment" + return 1 + fi +} +lint_package_comment() { + set +ex + + count=0 + for i in $(go list ./...); do + lint_package_comment_per_package "$i" + ((count += $?)) + done + + set -ex + return $count +} +lint_package_comment + echo SUCCESS diff --git a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go index d8f86c05d..b2e3930fb 100644 --- a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go +++ b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go @@ -19,8 +19,7 @@ import ( "google.golang.org/protobuf/compiler/protogen" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/tag" - "google.golang.org/protobuf/internal/fieldnum" - "google.golang.org/protobuf/internal/genname" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/version" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/runtime/protoimpl" @@ -37,9 +36,14 @@ var GenerateVersionMarkers = true // Standard library dependencies. const ( + base64Package = protogen.GoImportPath("encoding/base64") mathPackage = protogen.GoImportPath("math") reflectPackage = protogen.GoImportPath("reflect") + sortPackage = protogen.GoImportPath("sort") + stringsPackage = protogen.GoImportPath("strings") syncPackage = protogen.GoImportPath("sync") + timePackage = protogen.GoImportPath("time") + utf8Package = protogen.GoImportPath("unicode/utf8") ) // Protobuf library dependencies. @@ -48,11 +52,13 @@ const ( // patched to support unique build environments that impose restrictions // on the dependencies of generated source code. var ( - protoPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/proto") - protoifacePackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/runtime/protoiface") - protoimplPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/runtime/protoimpl") - protoreflectPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/reflect/protoreflect") - protoV1Package goImportPath = protogen.GoImportPath("github.com/golang/protobuf/proto") + protoPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/proto") + protoifacePackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/runtime/protoiface") + protoimplPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/runtime/protoimpl") + protojsonPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/encoding/protojson") + protoreflectPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/reflect/protoreflect") + protoregistryPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/reflect/protoregistry") + protoV1Package goImportPath = protogen.GoImportPath("github.com/golang/protobuf/proto") ) type goImportPath interface { @@ -66,10 +72,12 @@ func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.Generated g := gen.NewGeneratedFile(filename, file.GoImportPath) f := newFileInfo(file) - genStandaloneComments(g, f, fieldnum.FileDescriptorProto_Syntax) + genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Syntax_field_number)) genGeneratedHeader(gen, g, f) - genStandaloneComments(g, f, fieldnum.FileDescriptorProto_Package) - g.P("package ", f.GoPackageName) + genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Package_field_number)) + + packageDoc := genPackageKnownComment(f) + g.P(packageDoc, "package ", f.GoPackageName) g.P() // Emit a static check that enforces a minimum version of the proto package. @@ -329,6 +337,7 @@ func genMessage(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) { g.P("}") g.P() + genMessageKnownFunctions(g, f, m) genMessageDefaultDecls(g, f, m) genMessageMethods(g, f, m) genMessageOneofWrapperTypes(g, f, m) @@ -343,19 +352,19 @@ func genMessageFields(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) { } func genMessageInternalFields(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, sf *structFields) { - g.P(genname.State, " ", protoimplPackage.Ident("MessageState")) - sf.append(genname.State) - g.P(genname.SizeCache, " ", protoimplPackage.Ident("SizeCache")) - sf.append(genname.SizeCache) + g.P(genid.State_goname, " ", protoimplPackage.Ident("MessageState")) + sf.append(genid.State_goname) + g.P(genid.SizeCache_goname, " ", protoimplPackage.Ident("SizeCache")) + sf.append(genid.SizeCache_goname) if m.hasWeak { - g.P(genname.WeakFields, " ", protoimplPackage.Ident("WeakFields")) - sf.append(genname.WeakFields) + g.P(genid.WeakFields_goname, " ", protoimplPackage.Ident("WeakFields")) + sf.append(genid.WeakFields_goname) } - g.P(genname.UnknownFields, " ", protoimplPackage.Ident("UnknownFields")) - sf.append(genname.UnknownFields) + g.P(genid.UnknownFields_goname, " ", protoimplPackage.Ident("UnknownFields")) + sf.append(genid.UnknownFields_goname) if m.Desc.ExtensionRanges().Len() > 0 { - g.P(genname.ExtensionFields, " ", protoimplPackage.Ident("ExtensionFields")) - sf.append(genname.ExtensionFields) + g.P(genid.ExtensionFields_goname, " ", protoimplPackage.Ident("ExtensionFields")) + sf.append(genid.ExtensionFields_goname) } if sf.count > 0 { g.P() @@ -416,7 +425,7 @@ func genMessageField(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, fie name := field.GoName if field.Desc.IsWeak() { - name = genname.WeakFieldPrefix + name + name = genid.WeakFieldPrefix_goname + name } g.Annotate(m.GoIdent.GoName+"."+name, field.Location) leadingComments := appendDeprecationSuffix(field.Comments.Leading, @@ -577,9 +586,9 @@ func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageI g.P(leadingComments, "func (x *", m.GoIdent, ") Get", field.GoName, "() ", protoPackage.Ident("Message"), "{") g.P("var w ", protoimplPackage.Ident("WeakFields")) g.P("if x != nil {") - g.P("w = x.", genname.WeakFields) + g.P("w = x.", genid.WeakFields_goname) if m.isTracked { - g.P("_ = x.", genname.WeakFieldPrefix+field.GoName) + g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName) } g.P("}") g.P("return ", protoimplPackage.Ident("X"), ".GetWeak(w, ", field.Desc.Number(), ", ", strconv.Quote(string(field.Message.Desc.FullName())), ")") @@ -625,9 +634,9 @@ func genMessageSetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageI g.P(leadingComments, "func (x *", m.GoIdent, ") Set", field.GoName, "(v ", protoPackage.Ident("Message"), ") {") g.P("var w *", protoimplPackage.Ident("WeakFields")) g.P("if x != nil {") - g.P("w = &x.", genname.WeakFields) + g.P("w = &x.", genid.WeakFields_goname) if m.isTracked { - g.P("_ = x.", genname.WeakFieldPrefix+field.GoName) + g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName) } g.P("}") g.P(protoimplPackage.Ident("X"), ".SetWeak(w, ", field.Desc.Number(), ", ", strconv.Quote(string(field.Message.Desc.FullName())), ", v)") diff --git a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go new file mode 100644 index 000000000..9a1b7bdfa --- /dev/null +++ b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go @@ -0,0 +1,1077 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package internal_gengo + +import ( + "strings" + + "google.golang.org/protobuf/compiler/protogen" + "google.golang.org/protobuf/internal/genid" +) + +// Specialized support for well-known types are hard-coded into the generator +// as opposed to being injected in adjacent .go sources in the generated package +// in order to support specialized build systems like Bazel that always generate +// dynamically from the source .proto files. + +func genPackageKnownComment(f *fileInfo) protogen.Comments { + switch f.Desc.Path() { + case genid.File_google_protobuf_any_proto: + return ` Package anypb contains generated types for ` + genid.File_google_protobuf_any_proto + `. + + The Any message is a dynamic representation of any other message value. + It is functionally a tuple of the full name of the remote message type and + the serialized bytes of the remote message value. + + + Constructing an Any + + An Any message containing another message value is constructed using New: + + any, err := anypb.New(m) + if err != nil { + ... // handle error + } + ... // make use of any + + + Unmarshaling an Any + + With a populated Any message, the underlying message can be serialized into + a remote concrete message value in a few ways. + + If the exact concrete type is known, then a new (or pre-existing) instance + of that message can be passed to the UnmarshalTo method: + + m := new(foopb.MyMessage) + if err := any.UnmarshalTo(m); err != nil { + ... // handle error + } + ... // make use of m + + If the exact concrete type is not known, then the UnmarshalNew method can be + used to unmarshal the contents into a new instance of the remote message type: + + m, err := any.UnmarshalNew() + if err != nil { + ... // handle error + } + ... // make use of m + + UnmarshalNew uses the global type registry to resolve the message type and + construct a new instance of that message to unmarshal into. In order for a + message type to appear in the global registry, the Go type representing that + protobuf message type must be linked into the Go binary. For messages + generated by protoc-gen-go, this is achieved through an import of the + generated Go package representing a .proto file. + + A common pattern with UnmarshalNew is to use a type switch with the resulting + proto.Message value: + + switch m := m.(type) { + case *foopb.MyMessage: + ... // make use of m as a *foopb.MyMessage + case *barpb.OtherMessage: + ... // make use of m as a *barpb.OtherMessage + case *bazpb.SomeMessage: + ... // make use of m as a *bazpb.SomeMessage + } + + This pattern ensures that the generated packages containing the message types + listed in the case clauses are linked into the Go binary and therefore also + registered in the global registry. + + + Type checking an Any + + In order to type check whether an Any message represents some other message, + then use the MessageIs method: + + if any.MessageIs((*foopb.MyMessage)(nil)) { + ... // make use of any, knowing that it contains a foopb.MyMessage + } + + The MessageIs method can also be used with an allocated instance of the target + message type if the intention is to unmarshal into it if the type matches: + + m := new(foopb.MyMessage) + if any.MessageIs(m) { + if err := any.UnmarshalTo(m); err != nil { + ... // handle error + } + ... // make use of m + } + +` + case genid.File_google_protobuf_timestamp_proto: + return ` Package timestamppb contains generated types for ` + genid.File_google_protobuf_timestamp_proto + `. + + The Timestamp message represents a timestamp, + an instant in time since the Unix epoch (January 1st, 1970). + + + Conversion to a Go Time + + The AsTime method can be used to convert a Timestamp message to a + standard Go time.Time value in UTC: + + t := ts.AsTime() + ... // make use of t as a time.Time + + Converting to a time.Time is a common operation so that the extensive + set of time-based operations provided by the time package can be leveraged. + See https://golang.org/pkg/time for more information. + + The AsTime method performs the conversion on a best-effort basis. Timestamps + with denormal values (e.g., nanoseconds beyond 0 and 99999999, inclusive) + are normalized during the conversion to a time.Time. To manually check for + invalid Timestamps per the documented limitations in timestamp.proto, + additionally call the CheckValid method: + + if err := ts.CheckValid(); err != nil { + ... // handle error + } + + + Conversion from a Go Time + + The timestamppb.New function can be used to construct a Timestamp message + from a standard Go time.Time value: + + ts := timestamppb.New(t) + ... // make use of ts as a *timestamppb.Timestamp + + In order to construct a Timestamp representing the current time, use Now: + + ts := timestamppb.Now() + ... // make use of ts as a *timestamppb.Timestamp + +` + case genid.File_google_protobuf_duration_proto: + return ` Package durationpb contains generated types for ` + genid.File_google_protobuf_duration_proto + `. + + The Duration message represents a signed span of time. + + + Conversion to a Go Duration + + The AsDuration method can be used to convert a Duration message to a + standard Go time.Duration value: + + d := dur.AsDuration() + ... // make use of d as a time.Duration + + Converting to a time.Duration is a common operation so that the extensive + set of time-based operations provided by the time package can be leveraged. + See https://golang.org/pkg/time for more information. + + The AsDuration method performs the conversion on a best-effort basis. + Durations with denormal values (e.g., nanoseconds beyond -99999999 and + +99999999, inclusive; or seconds and nanoseconds with opposite signs) + are normalized during the conversion to a time.Duration. To manually check for + invalid Duration per the documented limitations in duration.proto, + additionally call the CheckValid method: + + if err := dur.CheckValid(); err != nil { + ... // handle error + } + + Note that the documented limitations in duration.proto does not protect a + Duration from overflowing the representable range of a time.Duration in Go. + The AsDuration method uses saturation arithmetic such that an overflow clamps + the resulting value to the closest representable value (e.g., math.MaxInt64 + for positive overflow and math.MinInt64 for negative overflow). + + + Conversion from a Go Duration + + The durationpb.New function can be used to construct a Duration message + from a standard Go time.Duration value: + + dur := durationpb.New(d) + ... // make use of d as a *durationpb.Duration + +` + case genid.File_google_protobuf_struct_proto: + return ` Package structpb contains generated types for ` + genid.File_google_protobuf_struct_proto + `. + + The messages (i.e., Value, Struct, and ListValue) defined in struct.proto are + used to represent arbitrary JSON. The Value message represents a JSON value, + the Struct message represents a JSON object, and the ListValue message + represents a JSON array. See https://json.org for more information. + + The Value, Struct, and ListValue types have generated MarshalJSON and + UnmarshalJSON methods such that they serialize JSON equivalent to what the + messages themselves represent. Use of these types with the + "google.golang.org/protobuf/encoding/protojson" package + ensures that they will be serialized as their JSON equivalent. + + + Conversion to and from a Go interface + + The standard Go "encoding/json" package has functionality to serialize + arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and + ListValue.AsSlice methods can convert the protobuf message representation into + a form represented by interface{}, map[string]interface{}, and []interface{}. + This form can be used with other packages that operate on such data structures + and also directly with the standard json package. + + In order to convert the interface{}, map[string]interface{}, and []interface{} + forms back as Value, Struct, and ListValue messages, use the NewStruct, + NewList, and NewValue constructor functions. + + + Example usage + + Consider the following example JSON object: + + { + "firstName": "John", + "lastName": "Smith", + "isAlive": true, + "age": 27, + "address": { + "streetAddress": "21 2nd Street", + "city": "New York", + "state": "NY", + "postalCode": "10021-3100" + }, + "phoneNumbers": [ + { + "type": "home", + "number": "212 555-1234" + }, + { + "type": "office", + "number": "646 555-4567" + } + ], + "children": [], + "spouse": null + } + + To construct a Value message representing the above JSON object: + + m, err := structpb.NewValue(map[string]interface{}{ + "firstName": "John", + "lastName": "Smith", + "isAlive": true, + "age": 27, + "address": map[string]interface{}{ + "streetAddress": "21 2nd Street", + "city": "New York", + "state": "NY", + "postalCode": "10021-3100", + }, + "phoneNumbers": []interface{}{ + map[string]interface{}{ + "type": "home", + "number": "212 555-1234", + }, + map[string]interface{}{ + "type": "office", + "number": "646 555-4567", + }, + }, + "children": []interface{}{}, + "spouse": nil, + }) + if err != nil { + ... // handle error + } + ... // make use of m as a *structpb.Value + +` + case genid.File_google_protobuf_field_mask_proto: + return ` Package fieldmaskpb contains generated types for ` + genid.File_google_protobuf_field_mask_proto + `. + + The FieldMask message represents a set of symbolic field paths. + The paths are specific to some target message type, + which is not stored within the FieldMask message itself. + + + Constructing a FieldMask + + The New function is used construct a FieldMask: + + var messageType *descriptorpb.DescriptorProto + fm, err := fieldmaskpb.New(messageType, "field.name", "field.number") + if err != nil { + ... // handle error + } + ... // make use of fm + + The "field.name" and "field.number" paths are valid paths according to the + google.protobuf.DescriptorProto message. Use of a path that does not correlate + to valid fields reachable from DescriptorProto would result in an error. + + Once a FieldMask message has been constructed, + the Append method can be used to insert additional paths to the path set: + + var messageType *descriptorpb.DescriptorProto + if err := fm.Append(messageType, "options"); err != nil { + ... // handle error + } + + + Type checking a FieldMask + + In order to verify that a FieldMask represents a set of fields that are + reachable from some target message type, use the IsValid method: + + var messageType *descriptorpb.DescriptorProto + if fm.IsValid(messageType) { + ... // make use of fm + } + + IsValid needs to be passed the target message type as an input since the + FieldMask message itself does not store the message type that the set of paths + are for. +` + default: + return "" + } +} + +func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) { + switch m.Desc.FullName() { + case genid.Any_message_fullname: + g.P("// New marshals src into a new Any instance.") + g.P("func New(src ", protoPackage.Ident("Message"), ") (*Any, error) {") + g.P(" dst := new(Any)") + g.P(" if err := dst.MarshalFrom(src); err != nil {") + g.P(" return nil, err") + g.P(" }") + g.P(" return dst, nil") + g.P("}") + g.P() + + g.P("// MarshalFrom marshals src into dst as the underlying message") + g.P("// using the provided marshal options.") + g.P("//") + g.P("// If no options are specified, call dst.MarshalFrom instead.") + g.P("func MarshalFrom(dst *Any, src ", protoPackage.Ident("Message"), ", opts ", protoPackage.Ident("MarshalOptions"), ") error {") + g.P(" const urlPrefix = \"type.googleapis.com/\"") + g.P(" if src == nil {") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil source message\")") + g.P(" }") + g.P(" b, err := opts.Marshal(src)") + g.P(" if err != nil {") + g.P(" return err") + g.P(" }") + g.P(" dst.TypeUrl = urlPrefix + string(src.ProtoReflect().Descriptor().FullName())") + g.P(" dst.Value = b") + g.P(" return nil") + g.P("}") + g.P() + + g.P("// UnmarshalTo unmarshals the underlying message from src into dst") + g.P("// using the provided unmarshal options.") + g.P("// It reports an error if dst is not of the right message type.") + g.P("//") + g.P("// If no options are specified, call src.UnmarshalTo instead.") + g.P("func UnmarshalTo(src *Any, dst ", protoPackage.Ident("Message"), ", opts ", protoPackage.Ident("UnmarshalOptions"), ") error {") + g.P(" if src == nil {") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil source message\")") + g.P(" }") + g.P(" if !src.MessageIs(dst) {") + g.P(" got := dst.ProtoReflect().Descriptor().FullName()") + g.P(" want := src.MessageName()") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"mismatched message type: got %q, want %q\", got, want)") + g.P(" }") + g.P(" return opts.Unmarshal(src.GetValue(), dst)") + g.P("}") + g.P() + + g.P("// UnmarshalNew unmarshals the underlying message from src into dst,") + g.P("// which is newly created message using a type resolved from the type URL.") + g.P("// The message type is resolved according to opt.Resolver,") + g.P("// which should implement protoregistry.MessageTypeResolver.") + g.P("// It reports an error if the underlying message type could not be resolved.") + g.P("//") + g.P("// If no options are specified, call src.UnmarshalNew instead.") + g.P("func UnmarshalNew(src *Any, opts ", protoPackage.Ident("UnmarshalOptions"), ") (dst ", protoPackage.Ident("Message"), ", err error) {") + g.P(" if src.GetTypeUrl() == \"\" {") + g.P(" return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid empty type URL\")") + g.P(" }") + g.P(" if opts.Resolver == nil {") + g.P(" opts.Resolver = ", protoregistryPackage.Ident("GlobalTypes")) + g.P(" }") + g.P(" r, ok := opts.Resolver.(", protoregistryPackage.Ident("MessageTypeResolver"), ")") + g.P(" if !ok {") + g.P(" return nil, ", protoregistryPackage.Ident("NotFound")) + g.P(" }") + g.P(" mt, err := r.FindMessageByURL(src.GetTypeUrl())") + g.P(" if err != nil {") + g.P(" if err == ", protoregistryPackage.Ident("NotFound"), " {") + g.P(" return nil, err") + g.P(" }") + g.P(" return nil, ", protoimplPackage.Ident("X"), ".NewError(\"could not resolve %q: %v\", src.GetTypeUrl(), err)") + g.P(" }") + g.P(" dst = mt.New().Interface()") + g.P(" return dst, opts.Unmarshal(src.GetValue(), dst)") + g.P("}") + g.P() + + g.P("// MessageIs reports whether the underlying message is of the same type as m.") + g.P("func (x *Any) MessageIs(m ", protoPackage.Ident("Message"), ") bool {") + g.P(" if m == nil {") + g.P(" return false") + g.P(" }") + g.P(" url := x.GetTypeUrl()") + g.P(" name := string(m.ProtoReflect().Descriptor().FullName())") + g.P(" if !", stringsPackage.Ident("HasSuffix"), "(url, name) {") + g.P(" return false") + g.P(" }") + g.P(" return len(url) == len(name) || url[len(url)-len(name)-1] == '/'") + g.P("}") + g.P() + + g.P("// MessageName reports the full name of the underlying message,") + g.P("// returning an empty string if invalid.") + g.P("func (x *Any) MessageName() ", protoreflectPackage.Ident("FullName"), " {") + g.P(" url := x.GetTypeUrl()") + g.P(" name := ", protoreflectPackage.Ident("FullName"), "(url)") + g.P(" if i := ", stringsPackage.Ident("LastIndexByte"), "(url, '/'); i >= 0 {") + g.P(" name = name[i+len(\"/\"):]") + g.P(" }") + g.P(" if !name.IsValid() {") + g.P(" return \"\"") + g.P(" }") + g.P(" return name") + g.P("}") + g.P() + + g.P("// MarshalFrom marshals m into x as the underlying message.") + g.P("func (x *Any) MarshalFrom(m ", protoPackage.Ident("Message"), ") error {") + g.P(" return MarshalFrom(x, m, ", protoPackage.Ident("MarshalOptions"), "{})") + g.P("}") + g.P() + + g.P("// UnmarshalTo unmarshals the contents of the underlying message of x into m.") + g.P("// It resets m before performing the unmarshal operation.") + g.P("// It reports an error if m is not of the right message type.") + g.P("func (x *Any) UnmarshalTo(m ", protoPackage.Ident("Message"), ") error {") + g.P(" return UnmarshalTo(x, m, ", protoPackage.Ident("UnmarshalOptions"), "{})") + g.P("}") + g.P() + + g.P("// UnmarshalNew unmarshals the contents of the underlying message of x into") + g.P("// a newly allocated message of the specified type.") + g.P("// It reports an error if the underlying message type could not be resolved.") + g.P("func (x *Any) UnmarshalNew() (", protoPackage.Ident("Message"), ", error) {") + g.P(" return UnmarshalNew(x, ", protoPackage.Ident("UnmarshalOptions"), "{})") + g.P("}") + g.P() + + case genid.Timestamp_message_fullname: + g.P("// Now constructs a new Timestamp from the current time.") + g.P("func Now() *Timestamp {") + g.P(" return New(", timePackage.Ident("Now"), "())") + g.P("}") + g.P() + + g.P("// New constructs a new Timestamp from the provided time.Time.") + g.P("func New(t ", timePackage.Ident("Time"), ") *Timestamp {") + g.P(" return &Timestamp{Seconds: int64(t.Unix()), Nanos: int32(t.Nanosecond())}") + g.P("}") + g.P() + + g.P("// AsTime converts x to a time.Time.") + g.P("func (x *Timestamp) AsTime() ", timePackage.Ident("Time"), " {") + g.P(" return ", timePackage.Ident("Unix"), "(int64(x.GetSeconds()), int64(x.GetNanos())).UTC()") + g.P("}") + g.P() + + g.P("// IsValid reports whether the timestamp is valid.") + g.P("// It is equivalent to CheckValid == nil.") + g.P("func (x *Timestamp) IsValid() bool {") + g.P(" return x.check() == 0") + g.P("}") + g.P() + + g.P("// CheckValid returns an error if the timestamp is invalid.") + g.P("// In particular, it checks whether the value represents a date that is") + g.P("// in the range of 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.") + g.P("// An error is reported for a nil Timestamp.") + g.P("func (x *Timestamp) CheckValid() error {") + g.P(" switch x.check() {") + g.P(" case invalidNil:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil Timestamp\")") + g.P(" case invalidUnderflow:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"timestamp (%v) before 0001-01-01\", x)") + g.P(" case invalidOverflow:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"timestamp (%v) after 9999-12-31\", x)") + g.P(" case invalidNanos:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"timestamp (%v) has out-of-range nanos\", x)") + g.P(" default:") + g.P(" return nil") + g.P(" }") + g.P("}") + g.P() + + g.P("const (") + g.P(" _ = iota") + g.P(" invalidNil") + g.P(" invalidUnderflow") + g.P(" invalidOverflow") + g.P(" invalidNanos") + g.P(")") + g.P() + + g.P("func (x *Timestamp) check() uint {") + g.P(" const minTimestamp = -62135596800 // Seconds between 1970-01-01T00:00:00Z and 0001-01-01T00:00:00Z, inclusive") + g.P(" const maxTimestamp = +253402300799 // Seconds between 1970-01-01T00:00:00Z and 9999-12-31T23:59:59Z, inclusive") + g.P(" secs := x.GetSeconds()") + g.P(" nanos := x.GetNanos()") + g.P(" switch {") + g.P(" case x == nil:") + g.P(" return invalidNil") + g.P(" case secs < minTimestamp:") + g.P(" return invalidUnderflow") + g.P(" case secs > maxTimestamp:") + g.P(" return invalidOverflow") + g.P(" case nanos < 0 || nanos >= 1e9:") + g.P(" return invalidNanos") + g.P(" default:") + g.P(" return 0") + g.P(" }") + g.P("}") + g.P() + + case genid.Duration_message_fullname: + g.P("// New constructs a new Duration from the provided time.Duration.") + g.P("func New(d ", timePackage.Ident("Duration"), ") *Duration {") + g.P(" nanos := d.Nanoseconds()") + g.P(" secs := nanos / 1e9") + g.P(" nanos -= secs * 1e9") + g.P(" return &Duration{Seconds: int64(secs), Nanos: int32(nanos)}") + g.P("}") + g.P() + + g.P("// AsDuration converts x to a time.Duration,") + g.P("// returning the closest duration value in the event of overflow.") + g.P("func (x *Duration) AsDuration() ", timePackage.Ident("Duration"), " {") + g.P(" secs := x.GetSeconds()") + g.P(" nanos := x.GetNanos()") + g.P(" d := ", timePackage.Ident("Duration"), "(secs) * ", timePackage.Ident("Second")) + g.P(" overflow := d/", timePackage.Ident("Second"), " != ", timePackage.Ident("Duration"), "(secs)") + g.P(" d += ", timePackage.Ident("Duration"), "(nanos) * ", timePackage.Ident("Nanosecond")) + g.P(" overflow = overflow || (secs < 0 && nanos < 0 && d > 0)") + g.P(" overflow = overflow || (secs > 0 && nanos > 0 && d < 0)") + g.P(" if overflow {") + g.P(" switch {") + g.P(" case secs < 0:") + g.P(" return ", timePackage.Ident("Duration"), "(", mathPackage.Ident("MinInt64"), ")") + g.P(" case secs > 0:") + g.P(" return ", timePackage.Ident("Duration"), "(", mathPackage.Ident("MaxInt64"), ")") + g.P(" }") + g.P(" }") + g.P(" return d") + g.P("}") + g.P() + + g.P("// IsValid reports whether the duration is valid.") + g.P("// It is equivalent to CheckValid == nil.") + g.P("func (x *Duration) IsValid() bool {") + g.P(" return x.check() == 0") + g.P("}") + g.P() + + g.P("// CheckValid returns an error if the duration is invalid.") + g.P("// In particular, it checks whether the value is within the range of") + g.P("// -10000 years to +10000 years inclusive.") + g.P("// An error is reported for a nil Duration.") + g.P("func (x *Duration) CheckValid() error {") + g.P(" switch x.check() {") + g.P(" case invalidNil:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil Duration\")") + g.P(" case invalidUnderflow:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) exceeds -10000 years\", x)") + g.P(" case invalidOverflow:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) exceeds +10000 years\", x)") + g.P(" case invalidNanosRange:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) has out-of-range nanos\", x)") + g.P(" case invalidNanosSign:") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) has seconds and nanos with different signs\", x)") + g.P(" default:") + g.P(" return nil") + g.P(" }") + g.P("}") + g.P() + + g.P("const (") + g.P(" _ = iota") + g.P(" invalidNil") + g.P(" invalidUnderflow") + g.P(" invalidOverflow") + g.P(" invalidNanosRange") + g.P(" invalidNanosSign") + g.P(")") + g.P() + + g.P("func (x *Duration) check() uint {") + g.P(" const absDuration = 315576000000 // 10000yr * 365.25day/yr * 24hr/day * 60min/hr * 60sec/min") + g.P(" secs := x.GetSeconds()") + g.P(" nanos := x.GetNanos()") + g.P(" switch {") + g.P(" case x == nil:") + g.P(" return invalidNil") + g.P(" case secs < -absDuration:") + g.P(" return invalidUnderflow") + g.P(" case secs > +absDuration:") + g.P(" return invalidOverflow") + g.P(" case nanos <= -1e9 || nanos >= +1e9:") + g.P(" return invalidNanosRange") + g.P(" case (secs > 0 && nanos < 0) || (secs < 0 && nanos > 0):") + g.P(" return invalidNanosSign") + g.P(" default:") + g.P(" return 0") + g.P(" }") + g.P("}") + g.P() + + case genid.Struct_message_fullname: + g.P("// NewStruct constructs a Struct from a general-purpose Go map.") + g.P("// The map keys must be valid UTF-8.") + g.P("// The map values are converted using NewValue.") + g.P("func NewStruct(v map[string]interface{}) (*Struct, error) {") + g.P(" x := &Struct{Fields: make(map[string]*Value, len(v))}") + g.P(" for k, v := range v {") + g.P(" if !", utf8Package.Ident("ValidString"), "(k) {") + g.P(" return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid UTF-8 in string: %q\", k)") + g.P(" }") + g.P(" var err error") + g.P(" x.Fields[k], err = NewValue(v)") + g.P(" if err != nil {") + g.P(" return nil, err") + g.P(" }") + g.P(" }") + g.P(" return x, nil") + g.P("}") + g.P() + + g.P("// AsMap converts x to a general-purpose Go map.") + g.P("// The map values are converted by calling Value.AsInterface.") + g.P("func (x *Struct) AsMap() map[string]interface{} {") + g.P(" vs := make(map[string]interface{})") + g.P(" for k, v := range x.GetFields() {") + g.P(" vs[k] = v.AsInterface()") + g.P(" }") + g.P(" return vs") + g.P("}") + g.P() + + g.P("func (x *Struct) MarshalJSON() ([]byte, error) {") + g.P(" return ", protojsonPackage.Ident("Marshal"), "(x)") + g.P("}") + g.P() + + g.P("func (x *Struct) UnmarshalJSON(b []byte) error {") + g.P(" return ", protojsonPackage.Ident("Unmarshal"), "(b, x)") + g.P("}") + g.P() + + case genid.ListValue_message_fullname: + g.P("// NewList constructs a ListValue from a general-purpose Go slice.") + g.P("// The slice elements are converted using NewValue.") + g.P("func NewList(v []interface{}) (*ListValue, error) {") + g.P(" x := &ListValue{Values: make([]*Value, len(v))}") + g.P(" for i, v := range v {") + g.P(" var err error") + g.P(" x.Values[i], err = NewValue(v)") + g.P(" if err != nil {") + g.P(" return nil, err") + g.P(" }") + g.P(" }") + g.P(" return x, nil") + g.P("}") + g.P() + + g.P("// AsSlice converts x to a general-purpose Go slice.") + g.P("// The slice elements are converted by calling Value.AsInterface.") + g.P("func (x *ListValue) AsSlice() []interface{} {") + g.P(" vs := make([]interface{}, len(x.GetValues()))") + g.P(" for i, v := range x.GetValues() {") + g.P(" vs[i] = v.AsInterface()") + g.P(" }") + g.P(" return vs") + g.P("}") + g.P() + + g.P("func (x *ListValue) MarshalJSON() ([]byte, error) {") + g.P(" return ", protojsonPackage.Ident("Marshal"), "(x)") + g.P("}") + g.P() + + g.P("func (x *ListValue) UnmarshalJSON(b []byte) error {") + g.P(" return ", protojsonPackage.Ident("Unmarshal"), "(b, x)") + g.P("}") + g.P() + + case genid.Value_message_fullname: + g.P("// NewValue constructs a Value from a general-purpose Go interface.") + g.P("//") + g.P("// ╔════════════════════════╤════════════════════════════════════════════╗") + g.P("// ║ Go type │ Conversion ║") + g.P("// ╠════════════════════════╪════════════════════════════════════════════╣") + g.P("// ║ nil │ stored as NullValue ║") + g.P("// ║ bool │ stored as BoolValue ║") + g.P("// ║ int, int32, int64 │ stored as NumberValue ║") + g.P("// ║ uint, uint32, uint64 │ stored as NumberValue ║") + g.P("// ║ float32, float64 │ stored as NumberValue ║") + g.P("// ║ string │ stored as StringValue; must be valid UTF-8 ║") + g.P("// ║ []byte │ stored as StringValue; base64-encoded ║") + g.P("// ║ map[string]interface{} │ stored as StructValue ║") + g.P("// ║ []interface{} │ stored as ListValue ║") + g.P("// ╚════════════════════════╧════════════════════════════════════════════╝") + g.P("//") + g.P("// When converting an int64 or uint64 to a NumberValue, numeric precision loss") + g.P("// is possible since they are stored as a float64.") + g.P("func NewValue(v interface{}) (*Value, error) {") + g.P(" switch v := v.(type) {") + g.P(" case nil:") + g.P(" return NewNullValue(), nil") + g.P(" case bool:") + g.P(" return NewBoolValue(v), nil") + g.P(" case int:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case int32:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case int64:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case uint:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case uint32:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case uint64:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case float32:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case float64:") + g.P(" return NewNumberValue(float64(v)), nil") + g.P(" case string:") + g.P(" if !", utf8Package.Ident("ValidString"), "(v) {") + g.P(" return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid UTF-8 in string: %q\", v)") + g.P(" }") + g.P(" return NewStringValue(v), nil") + g.P(" case []byte:") + g.P(" s := ", base64Package.Ident("StdEncoding"), ".EncodeToString(v)") + g.P(" return NewStringValue(s), nil") + g.P(" case map[string]interface{}:") + g.P(" v2, err := NewStruct(v)") + g.P(" if err != nil {") + g.P(" return nil, err") + g.P(" }") + g.P(" return NewStructValue(v2), nil") + g.P(" case []interface{}:") + g.P(" v2, err := NewList(v)") + g.P(" if err != nil {") + g.P(" return nil, err") + g.P(" }") + g.P(" return NewListValue(v2), nil") + g.P(" default:") + g.P(" return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid type: %T\", v)") + g.P(" }") + g.P("}") + g.P() + + g.P("// NewNullValue constructs a new null Value.") + g.P("func NewNullValue() *Value {") + g.P(" return &Value{Kind: &Value_NullValue{NullValue: NullValue_NULL_VALUE}}") + g.P("}") + g.P() + + g.P("// NewBoolValue constructs a new boolean Value.") + g.P("func NewBoolValue(v bool) *Value {") + g.P(" return &Value{Kind: &Value_BoolValue{BoolValue: v}}") + g.P("}") + g.P() + + g.P("// NewNumberValue constructs a new number Value.") + g.P("func NewNumberValue(v float64) *Value {") + g.P(" return &Value{Kind: &Value_NumberValue{NumberValue: v}}") + g.P("}") + g.P() + + g.P("// NewStringValue constructs a new string Value.") + g.P("func NewStringValue(v string) *Value {") + g.P(" return &Value{Kind: &Value_StringValue{StringValue: v}}") + g.P("}") + g.P() + + g.P("// NewStructValue constructs a new struct Value.") + g.P("func NewStructValue(v *Struct) *Value {") + g.P(" return &Value{Kind: &Value_StructValue{StructValue: v}}") + g.P("}") + g.P() + + g.P("// NewListValue constructs a new list Value.") + g.P("func NewListValue(v *ListValue) *Value {") + g.P(" return &Value{Kind: &Value_ListValue{ListValue: v}}") + g.P("}") + g.P() + + g.P("// AsInterface converts x to a general-purpose Go interface.") + g.P("//") + g.P("// Calling Value.MarshalJSON and \"encoding/json\".Marshal on this output produce") + g.P("// semantically equivalent JSON (assuming no errors occur).") + g.P("//") + g.P("// Floating-point values (i.e., \"NaN\", \"Infinity\", and \"-Infinity\") are") + g.P("// converted as strings to remain compatible with MarshalJSON.") + g.P("func (x *Value) AsInterface() interface{} {") + g.P(" switch v := x.GetKind().(type) {") + g.P(" case *Value_NumberValue:") + g.P(" if v != nil {") + g.P(" switch {") + g.P(" case ", mathPackage.Ident("IsNaN"), "(v.NumberValue):") + g.P(" return \"NaN\"") + g.P(" case ", mathPackage.Ident("IsInf"), "(v.NumberValue, +1):") + g.P(" return \"Infinity\"") + g.P(" case ", mathPackage.Ident("IsInf"), "(v.NumberValue, -1):") + g.P(" return \"-Infinity\"") + g.P(" default:") + g.P(" return v.NumberValue") + g.P(" }") + g.P(" }") + g.P(" case *Value_StringValue:") + g.P(" if v != nil {") + g.P(" return v.StringValue") + g.P(" }") + g.P(" case *Value_BoolValue:") + g.P(" if v != nil {") + g.P(" return v.BoolValue") + g.P(" }") + g.P(" case *Value_StructValue:") + g.P(" if v != nil {") + g.P(" return v.StructValue.AsMap()") + g.P(" }") + g.P(" case *Value_ListValue:") + g.P(" if v != nil {") + g.P(" return v.ListValue.AsSlice()") + g.P(" }") + g.P(" }") + g.P(" return nil") + g.P("}") + g.P() + + g.P("func (x *Value) MarshalJSON() ([]byte, error) {") + g.P(" return ", protojsonPackage.Ident("Marshal"), "(x)") + g.P("}") + g.P() + + g.P("func (x *Value) UnmarshalJSON(b []byte) error {") + g.P(" return ", protojsonPackage.Ident("Unmarshal"), "(b, x)") + g.P("}") + g.P() + + case genid.FieldMask_message_fullname: + g.P("// New constructs a field mask from a list of paths and verifies that") + g.P("// each one is valid according to the specified message type.") + g.P("func New(m ", protoPackage.Ident("Message"), ", paths ...string) (*FieldMask, error) {") + g.P(" x := new(FieldMask)") + g.P(" return x, x.Append(m, paths...)") + g.P("}") + g.P() + + g.P("// Union returns the union of all the paths in the input field masks.") + g.P("func Union(mx *FieldMask, my *FieldMask, ms ...*FieldMask) *FieldMask {") + g.P(" var out []string") + g.P(" out = append(out, mx.GetPaths()...)") + g.P(" out = append(out, my.GetPaths()...)") + g.P(" for _, m := range ms {") + g.P(" out = append(out, m.GetPaths()...)") + g.P(" }") + g.P(" return &FieldMask{Paths: normalizePaths(out)}") + g.P("}") + g.P() + + g.P("// Intersect returns the intersection of all the paths in the input field masks.") + g.P("func Intersect(mx *FieldMask, my *FieldMask, ms ...*FieldMask) *FieldMask {") + g.P(" var ss1, ss2 []string // reused buffers for performance") + g.P(" intersect := func(out, in []string) []string {") + g.P(" ss1 = normalizePaths(append(ss1[:0], in...))") + g.P(" ss2 = normalizePaths(append(ss2[:0], out...))") + g.P(" out = out[:0]") + g.P(" for i1, i2 := 0, 0; i1 < len(ss1) && i2 < len(ss2); {") + g.P(" switch s1, s2 := ss1[i1], ss2[i2]; {") + g.P(" case hasPathPrefix(s1, s2):") + g.P(" out = append(out, s1)") + g.P(" i1++") + g.P(" case hasPathPrefix(s2, s1):") + g.P(" out = append(out, s2)") + g.P(" i2++") + g.P(" case lessPath(s1, s2):") + g.P(" i1++") + g.P(" case lessPath(s2, s1):") + g.P(" i2++") + g.P(" }") + g.P(" }") + g.P(" return out") + g.P(" }") + g.P() + g.P(" out := Union(mx, my, ms...).GetPaths()") + g.P(" out = intersect(out, mx.GetPaths())") + g.P(" out = intersect(out, my.GetPaths())") + g.P(" for _, m := range ms {") + g.P(" out = intersect(out, m.GetPaths())") + g.P(" }") + g.P(" return &FieldMask{Paths: normalizePaths(out)}") + g.P("}") + g.P() + + g.P("// IsValid reports whether all the paths are syntactically valid and") + g.P("// refer to known fields in the specified message type.") + g.P("// It reports false for a nil FieldMask.") + g.P("func (x *FieldMask) IsValid(m ", protoPackage.Ident("Message"), ") bool {") + g.P(" paths := x.GetPaths()") + g.P(" return x != nil && numValidPaths(m, paths) == len(paths)") + g.P("}") + g.P() + + g.P("// Append appends a list of paths to the mask and verifies that each one") + g.P("// is valid according to the specified message type.") + g.P("// An invalid path is not appended and breaks insertion of subsequent paths.") + g.P("func (x *FieldMask) Append(m ", protoPackage.Ident("Message"), ", paths ...string) error {") + g.P(" numValid := numValidPaths(m, paths)") + g.P(" x.Paths = append(x.Paths, paths[:numValid]...)") + g.P(" paths = paths[numValid:]") + g.P(" if len(paths) > 0 {") + g.P(" name := m.ProtoReflect().Descriptor().FullName()") + g.P(" return ", protoimplPackage.Ident("X"), ".NewError(\"invalid path %q for message %q\", paths[0], name)") + g.P(" }") + g.P(" return nil") + g.P("}") + g.P() + + g.P("func numValidPaths(m ", protoPackage.Ident("Message"), ", paths []string) int {") + g.P(" md0 := m.ProtoReflect().Descriptor()") + g.P(" for i, path := range paths {") + g.P(" md := md0") + g.P(" if !rangeFields(path, func(field string) bool {") + g.P(" // Search the field within the message.") + g.P(" if md == nil {") + g.P(" return false // not within a message") + g.P(" }") + g.P(" fd := md.Fields().ByName(", protoreflectPackage.Ident("Name"), "(field))") + g.P(" // The real field name of a group is the message name.") + g.P(" if fd == nil {") + g.P(" gd := md.Fields().ByName(", protoreflectPackage.Ident("Name"), "(", stringsPackage.Ident("ToLower"), "(field)))") + g.P(" if gd != nil && gd.Kind() == ", protoreflectPackage.Ident("GroupKind"), " && string(gd.Message().Name()) == field {") + g.P(" fd = gd") + g.P(" }") + g.P(" } else if fd.Kind() == ", protoreflectPackage.Ident("GroupKind"), " && string(fd.Message().Name()) != field {") + g.P(" fd = nil") + g.P(" }") + g.P(" if fd == nil {") + g.P(" return false // message has does not have this field") + g.P(" }") + g.P() + g.P(" // Identify the next message to search within.") + g.P(" md = fd.Message() // may be nil") + g.P(" if fd.IsMap() {") + g.P(" md = fd.MapValue().Message() // may be nil") + g.P(" }") + g.P(" return true") + g.P(" }) {") + g.P(" return i") + g.P(" }") + g.P(" }") + g.P(" return len(paths)") + g.P("}") + g.P() + + g.P("// Normalize converts the mask to its canonical form where all paths are sorted") + g.P("// and redundant paths are removed.") + g.P("func (x *FieldMask) Normalize() {") + g.P(" x.Paths = normalizePaths(x.Paths)") + g.P("}") + g.P() + g.P("func normalizePaths(paths []string) []string {") + g.P(" ", sortPackage.Ident("Slice"), "(paths, func(i, j int) bool {") + g.P(" return lessPath(paths[i], paths[j])") + g.P(" })") + g.P() + g.P(" // Elide any path that is a prefix match on the previous.") + g.P(" out := paths[:0]") + g.P(" for _, path := range paths {") + g.P(" if len(out) > 0 && hasPathPrefix(path, out[len(out)-1]) {") + g.P(" continue") + g.P(" }") + g.P(" out = append(out, path)") + g.P(" }") + g.P(" return out") + g.P("}") + g.P() + + g.P("// hasPathPrefix is like strings.HasPrefix, but further checks for either") + g.P("// an exact matche or that the prefix is delimited by a dot.") + g.P("func hasPathPrefix(path, prefix string) bool {") + g.P(" return ", stringsPackage.Ident("HasPrefix"), "(path, prefix) && (len(path) == len(prefix) || path[len(prefix)] == '.')") + g.P("}") + g.P() + + g.P("// lessPath is a lexicographical comparison where dot is specially treated") + g.P("// as the smallest symbol.") + g.P("func lessPath(x, y string) bool {") + g.P(" for i := 0; i < len(x) && i < len(y); i++ {") + g.P(" if x[i] != y[i] {") + g.P(" return (x[i] - '.') < (y[i] - '.')") + g.P(" }") + g.P(" }") + g.P(" return len(x) < len(y)") + g.P("}") + g.P() + + g.P("// rangeFields is like strings.Split(path, \".\"), but avoids allocations by") + g.P("// iterating over each field in place and calling a iterator function.") + g.P("func rangeFields(path string, f func(field string) bool) bool {") + g.P(" for {") + g.P(" var field string") + g.P(" if i := ", stringsPackage.Ident("IndexByte"), "(path, '.'); i >= 0 {") + g.P(" field, path = path[:i], path[i:]") + g.P(" } else {") + g.P(" field, path = path, \"\"") + g.P(" }") + g.P() + g.P(" if !f(field) {") + g.P(" return false") + g.P(" }") + g.P() + g.P(" if len(path) == 0 {") + g.P(" return true") + g.P(" }") + g.P(" path = ", stringsPackage.Ident("TrimPrefix"), "(path, \".\")") + g.P(" }") + g.P("}") + g.P() + + case genid.BoolValue_message_fullname, + genid.Int32Value_message_fullname, + genid.Int64Value_message_fullname, + genid.UInt32Value_message_fullname, + genid.UInt64Value_message_fullname, + genid.FloatValue_message_fullname, + genid.DoubleValue_message_fullname, + genid.StringValue_message_fullname, + genid.BytesValue_message_fullname: + funcName := strings.TrimSuffix(m.GoIdent.GoName, "Value") + typeName := strings.ToLower(funcName) + switch typeName { + case "float": + typeName = "float32" + case "double": + typeName = "float64" + case "bytes": + typeName = "[]byte" + } + + g.P("// ", funcName, " stores v in a new ", m.GoIdent, " and returns a pointer to it.") + g.P("func ", funcName, "(v ", typeName, ") *", m.GoIdent, " {") + g.P(" return &", m.GoIdent, "{Value: v}") + g.P("}") + g.P() + } +} diff --git a/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go b/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go index b3f7a6ee1..3892d0583 100644 --- a/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go +++ b/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go @@ -30,7 +30,7 @@ import ( "strings" "google.golang.org/protobuf/encoding/prototext" - "google.golang.org/protobuf/internal/fieldnum" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protodesc" @@ -625,9 +625,9 @@ type Enum struct { func newEnum(gen *Plugin, f *File, parent *Message, desc protoreflect.EnumDescriptor) *Enum { var loc Location if parent != nil { - loc = parent.Location.appendPath(fieldnum.DescriptorProto_EnumType, int32(desc.Index())) + loc = parent.Location.appendPath(int32(genid.DescriptorProto_EnumType_field_number), int32(desc.Index())) } else { - loc = f.location(fieldnum.FileDescriptorProto_EnumType, int32(desc.Index())) + loc = f.location(int32(genid.FileDescriptorProto_EnumType_field_number), int32(desc.Index())) } enum := &Enum{ Desc: desc, @@ -664,7 +664,7 @@ func newEnumValue(gen *Plugin, f *File, message *Message, enum *Enum, desc proto parentIdent = message.GoIdent } name := parentIdent.GoName + "_" + string(desc.Name()) - loc := enum.Location.appendPath(fieldnum.EnumDescriptorProto_Value, int32(desc.Index())) + loc := enum.Location.appendPath(int32(genid.EnumDescriptorProto_Value_field_number), int32(desc.Index())) return &EnumValue{ Desc: desc, GoIdent: f.GoImportPath.Ident(name), @@ -694,9 +694,9 @@ type Message struct { func newMessage(gen *Plugin, f *File, parent *Message, desc protoreflect.MessageDescriptor) *Message { var loc Location if parent != nil { - loc = parent.Location.appendPath(fieldnum.DescriptorProto_NestedType, int32(desc.Index())) + loc = parent.Location.appendPath(int32(genid.DescriptorProto_NestedType_field_number), int32(desc.Index())) } else { - loc = f.location(fieldnum.FileDescriptorProto_MessageType, int32(desc.Index())) + loc = f.location(int32(genid.FileDescriptorProto_MessageType_field_number), int32(desc.Index())) } message := &Message{ Desc: desc, @@ -852,11 +852,11 @@ func newField(gen *Plugin, f *File, message *Message, desc protoreflect.FieldDes var loc Location switch { case desc.IsExtension() && message == nil: - loc = f.location(fieldnum.FileDescriptorProto_Extension, int32(desc.Index())) + loc = f.location(int32(genid.FileDescriptorProto_Extension_field_number), int32(desc.Index())) case desc.IsExtension() && message != nil: - loc = message.Location.appendPath(fieldnum.DescriptorProto_Extension, int32(desc.Index())) + loc = message.Location.appendPath(int32(genid.DescriptorProto_Extension_field_number), int32(desc.Index())) default: - loc = message.Location.appendPath(fieldnum.DescriptorProto_Field, int32(desc.Index())) + loc = message.Location.appendPath(int32(genid.DescriptorProto_Field_field_number), int32(desc.Index())) } camelCased := strs.GoCamelCase(string(desc.Name())) var parentPrefix string @@ -927,7 +927,7 @@ type Oneof struct { } func newOneof(gen *Plugin, f *File, message *Message, desc protoreflect.OneofDescriptor) *Oneof { - loc := message.Location.appendPath(fieldnum.DescriptorProto_OneofDecl, int32(desc.Index())) + loc := message.Location.appendPath(int32(genid.DescriptorProto_OneofDecl_field_number), int32(desc.Index())) camelCased := strs.GoCamelCase(string(desc.Name())) parentPrefix := message.GoIdent.GoName + "_" return &Oneof{ @@ -959,7 +959,7 @@ type Service struct { } func newService(gen *Plugin, f *File, desc protoreflect.ServiceDescriptor) *Service { - loc := f.location(fieldnum.FileDescriptorProto_Service, int32(desc.Index())) + loc := f.location(int32(genid.FileDescriptorProto_Service_field_number), int32(desc.Index())) service := &Service{ Desc: desc, GoName: strs.GoCamelCase(string(desc.Name())), @@ -988,7 +988,7 @@ type Method struct { } func newMethod(gen *Plugin, f *File, service *Service, desc protoreflect.MethodDescriptor) *Method { - loc := service.Location.appendPath(fieldnum.ServiceDescriptorProto_Method, int32(desc.Index())) + loc := service.Location.appendPath(int32(genid.ServiceDescriptorProto_Method_field_number), int32(desc.Index())) method := &Method{ Desc: desc, GoName: strs.GoCamelCase(string(desc.Name())), diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go index c2f8f28f2..cab95a427 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/decode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/decode.go @@ -12,8 +12,8 @@ import ( "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/text" "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/internal/fieldnum" "google.golang.org/protobuf/internal/flags" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/set" "google.golang.org/protobuf/internal/strs" @@ -108,7 +108,7 @@ func (d decoder) unmarshalMessage(m pref.Message, checkDelims bool) error { return errors.New("no support for proto1 MessageSets") } - if messageDesc.FullName() == "google.protobuf.Any" { + if messageDesc.FullName() == genid.Any_message_fullname { return d.unmarshalAny(m, checkDelims) } @@ -538,14 +538,13 @@ Loop: return d.unexpectedTokenError(tok) } - name := tok.IdentName() - switch name { - case "key": + switch name := pref.Name(tok.IdentName()); name { + case genid.MapEntry_Key_field_name: if !tok.HasSeparator() { return d.syntaxError(tok.Pos(), "missing field separator :") } if key.IsValid() { - return d.newError(tok.Pos(), `map entry "key" cannot be repeated`) + return d.newError(tok.Pos(), "map entry %q cannot be repeated", name) } val, err := d.unmarshalScalar(fd.MapKey()) if err != nil { @@ -553,14 +552,14 @@ Loop: } key = val.MapKey() - case "value": + case genid.MapEntry_Value_field_name: if kind := fd.MapValue().Kind(); (kind != pref.MessageKind) && (kind != pref.GroupKind) { if !tok.HasSeparator() { return d.syntaxError(tok.Pos(), "missing field separator :") } } if pval.IsValid() { - return d.newError(tok.Pos(), `map entry "value" cannot be repeated`) + return d.newError(tok.Pos(), "map entry %q cannot be repeated", name) } pval, err = unmarshalMapValue() if err != nil { @@ -597,13 +596,9 @@ Loop: func (d decoder) unmarshalAny(m pref.Message, checkDelims bool) error { var typeURL string var bValue []byte - - // hasFields tracks which valid fields have been seen in the loop below in - // order to flag an error if there are duplicates or conflicts. It may - // contain the strings "type_url", "value" and "expanded". The literal - // "expanded" is used to indicate that the expanded form has been - // encountered already. - hasFields := map[string]bool{} + var seenTypeUrl bool + var seenValue bool + var isExpanded bool if checkDelims { tok, err := d.Read() @@ -642,12 +637,12 @@ Loop: return d.syntaxError(tok.Pos(), "missing field separator :") } - switch tok.IdentName() { - case "type_url": - if hasFields["type_url"] { - return d.newError(tok.Pos(), "duplicate Any type_url field") + switch name := pref.Name(tok.IdentName()); name { + case genid.Any_TypeUrl_field_name: + if seenTypeUrl { + return d.newError(tok.Pos(), "duplicate %v field", genid.Any_TypeUrl_field_fullname) } - if hasFields["expanded"] { + if isExpanded { return d.newError(tok.Pos(), "conflict with [%s] field", typeURL) } tok, err := d.Read() @@ -657,15 +652,15 @@ Loop: var ok bool typeURL, ok = tok.String() if !ok { - return d.newError(tok.Pos(), "invalid Any type_url: %v", tok.RawString()) + return d.newError(tok.Pos(), "invalid %v field value: %v", genid.Any_TypeUrl_field_fullname, tok.RawString()) } - hasFields["type_url"] = true + seenTypeUrl = true - case "value": - if hasFields["value"] { - return d.newError(tok.Pos(), "duplicate Any value field") + case genid.Any_Value_field_name: + if seenValue { + return d.newError(tok.Pos(), "duplicate %v field", genid.Any_Value_field_fullname) } - if hasFields["expanded"] { + if isExpanded { return d.newError(tok.Pos(), "conflict with [%s] field", typeURL) } tok, err := d.Read() @@ -674,22 +669,22 @@ Loop: } s, ok := tok.String() if !ok { - return d.newError(tok.Pos(), "invalid Any value: %v", tok.RawString()) + return d.newError(tok.Pos(), "invalid %v field value: %v", genid.Any_Value_field_fullname, tok.RawString()) } bValue = []byte(s) - hasFields["value"] = true + seenValue = true default: if !d.opts.DiscardUnknown { - return d.newError(tok.Pos(), "invalid field name %q in google.protobuf.Any message", tok.RawString()) + return d.newError(tok.Pos(), "invalid field name %q in %v message", tok.RawString(), genid.Any_message_fullname) } } case text.TypeName: - if hasFields["expanded"] { + if isExpanded { return d.newError(tok.Pos(), "cannot have more than one type") } - if hasFields["type_url"] { + if seenTypeUrl { return d.newError(tok.Pos(), "conflict with type_url field") } typeURL = tok.TypeName() @@ -698,21 +693,21 @@ Loop: if err != nil { return err } - hasFields["expanded"] = true + isExpanded = true default: if !d.opts.DiscardUnknown { - return d.newError(tok.Pos(), "invalid field name %q in google.protobuf.Any message", tok.RawString()) + return d.newError(tok.Pos(), "invalid field name %q in %v message", tok.RawString(), genid.Any_message_fullname) } } } fds := m.Descriptor().Fields() if len(typeURL) > 0 { - m.Set(fds.ByNumber(fieldnum.Any_TypeUrl), pref.ValueOfString(typeURL)) + m.Set(fds.ByNumber(genid.Any_TypeUrl_field_number), pref.ValueOfString(typeURL)) } if len(bValue) > 0 { - m.Set(fds.ByNumber(fieldnum.Any_Value), pref.ValueOfBytes(bValue)) + m.Set(fds.ByNumber(genid.Any_Value_field_number), pref.ValueOfBytes(bValue)) } return nil } diff --git a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go index 41e5c773c..0877d71c5 100644 --- a/vendor/google.golang.org/protobuf/encoding/prototext/encode.go +++ b/vendor/google.golang.org/protobuf/encoding/prototext/encode.go @@ -14,8 +14,8 @@ import ( "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/encoding/text" "google.golang.org/protobuf/internal/errors" - "google.golang.org/protobuf/internal/fieldnum" "google.golang.org/protobuf/internal/flags" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/mapsort" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/strs" @@ -162,7 +162,7 @@ func (e encoder) marshalMessage(m pref.Message, inclDelims bool) error { } // Handle Any expansion. - if messageDesc.FullName() == "google.protobuf.Any" { + if messageDesc.FullName() == genid.Any_message_fullname { if e.marshalAny(m) { return nil } @@ -295,13 +295,13 @@ func (e encoder) marshalMap(name string, mmap pref.Map, fd pref.FieldDescriptor) e.StartMessage() defer e.EndMessage() - e.WriteName("key") + e.WriteName(string(genid.MapEntry_Key_field_name)) err = e.marshalSingular(key.Value(), fd.MapKey()) if err != nil { return false } - e.WriteName("value") + e.WriteName(string(genid.MapEntry_Value_field_name)) err = e.marshalSingular(val, fd.MapValue()) if err != nil { return false @@ -399,7 +399,7 @@ func (e encoder) marshalUnknown(b []byte) { func (e encoder) marshalAny(any pref.Message) bool { // Construct the embedded message. fds := any.Descriptor().Fields() - fdType := fds.ByNumber(fieldnum.Any_TypeUrl) + fdType := fds.ByNumber(genid.Any_TypeUrl_field_number) typeURL := any.Get(fdType).String() mt, err := e.opts.Resolver.FindMessageByURL(typeURL) if err != nil { @@ -408,7 +408,7 @@ func (e encoder) marshalAny(any pref.Message) bool { m := mt.New().Interface() // Unmarshal bytes into embedded message. - fdValue := fds.ByNumber(fieldnum.Any_Value) + fdValue := fds.ByNumber(genid.Any_Value_field_number) value := any.Get(fdValue) err = proto.UnmarshalOptions{ AllowPartial: true, diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/any_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/any_gen.go deleted file mode 100644 index 74c5fef24..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/any_gen.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.Any. -const ( - Any_TypeUrl = 1 // optional string - Any_Value = 2 // optional bytes -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/api_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/api_gen.go deleted file mode 100644 index 9a6b5f29b..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/api_gen.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.Api. -const ( - Api_Name = 1 // optional string - Api_Methods = 2 // repeated google.protobuf.Method - Api_Options = 3 // repeated google.protobuf.Option - Api_Version = 4 // optional string - Api_SourceContext = 5 // optional google.protobuf.SourceContext - Api_Mixins = 6 // repeated google.protobuf.Mixin - Api_Syntax = 7 // optional google.protobuf.Syntax -) - -// Field numbers for google.protobuf.Method. -const ( - Method_Name = 1 // optional string - Method_RequestTypeUrl = 2 // optional string - Method_RequestStreaming = 3 // optional bool - Method_ResponseTypeUrl = 4 // optional string - Method_ResponseStreaming = 5 // optional bool - Method_Options = 6 // repeated google.protobuf.Option - Method_Syntax = 7 // optional google.protobuf.Syntax -) - -// Field numbers for google.protobuf.Mixin. -const ( - Mixin_Name = 1 // optional string - Mixin_Root = 2 // optional string -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go deleted file mode 100644 index 6e37b59e9..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/descriptor_gen.go +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.FileDescriptorSet. -const ( - FileDescriptorSet_File = 1 // repeated google.protobuf.FileDescriptorProto -) - -// Field numbers for google.protobuf.FileDescriptorProto. -const ( - FileDescriptorProto_Name = 1 // optional string - FileDescriptorProto_Package = 2 // optional string - FileDescriptorProto_Dependency = 3 // repeated string - FileDescriptorProto_PublicDependency = 10 // repeated int32 - FileDescriptorProto_WeakDependency = 11 // repeated int32 - FileDescriptorProto_MessageType = 4 // repeated google.protobuf.DescriptorProto - FileDescriptorProto_EnumType = 5 // repeated google.protobuf.EnumDescriptorProto - FileDescriptorProto_Service = 6 // repeated google.protobuf.ServiceDescriptorProto - FileDescriptorProto_Extension = 7 // repeated google.protobuf.FieldDescriptorProto - FileDescriptorProto_Options = 8 // optional google.protobuf.FileOptions - FileDescriptorProto_SourceCodeInfo = 9 // optional google.protobuf.SourceCodeInfo - FileDescriptorProto_Syntax = 12 // optional string -) - -// Field numbers for google.protobuf.DescriptorProto. -const ( - DescriptorProto_Name = 1 // optional string - DescriptorProto_Field = 2 // repeated google.protobuf.FieldDescriptorProto - DescriptorProto_Extension = 6 // repeated google.protobuf.FieldDescriptorProto - DescriptorProto_NestedType = 3 // repeated google.protobuf.DescriptorProto - DescriptorProto_EnumType = 4 // repeated google.protobuf.EnumDescriptorProto - DescriptorProto_ExtensionRange = 5 // repeated google.protobuf.DescriptorProto.ExtensionRange - DescriptorProto_OneofDecl = 8 // repeated google.protobuf.OneofDescriptorProto - DescriptorProto_Options = 7 // optional google.protobuf.MessageOptions - DescriptorProto_ReservedRange = 9 // repeated google.protobuf.DescriptorProto.ReservedRange - DescriptorProto_ReservedName = 10 // repeated string -) - -// Field numbers for google.protobuf.DescriptorProto.ExtensionRange. -const ( - DescriptorProto_ExtensionRange_Start = 1 // optional int32 - DescriptorProto_ExtensionRange_End = 2 // optional int32 - DescriptorProto_ExtensionRange_Options = 3 // optional google.protobuf.ExtensionRangeOptions -) - -// Field numbers for google.protobuf.DescriptorProto.ReservedRange. -const ( - DescriptorProto_ReservedRange_Start = 1 // optional int32 - DescriptorProto_ReservedRange_End = 2 // optional int32 -) - -// Field numbers for google.protobuf.ExtensionRangeOptions. -const ( - ExtensionRangeOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.FieldDescriptorProto. -const ( - FieldDescriptorProto_Name = 1 // optional string - FieldDescriptorProto_Number = 3 // optional int32 - FieldDescriptorProto_Label = 4 // optional google.protobuf.FieldDescriptorProto.Label - FieldDescriptorProto_Type = 5 // optional google.protobuf.FieldDescriptorProto.Type - FieldDescriptorProto_TypeName = 6 // optional string - FieldDescriptorProto_Extendee = 2 // optional string - FieldDescriptorProto_DefaultValue = 7 // optional string - FieldDescriptorProto_OneofIndex = 9 // optional int32 - FieldDescriptorProto_JsonName = 10 // optional string - FieldDescriptorProto_Options = 8 // optional google.protobuf.FieldOptions - FieldDescriptorProto_Proto3Optional = 17 // optional bool -) - -// Field numbers for google.protobuf.OneofDescriptorProto. -const ( - OneofDescriptorProto_Name = 1 // optional string - OneofDescriptorProto_Options = 2 // optional google.protobuf.OneofOptions -) - -// Field numbers for google.protobuf.EnumDescriptorProto. -const ( - EnumDescriptorProto_Name = 1 // optional string - EnumDescriptorProto_Value = 2 // repeated google.protobuf.EnumValueDescriptorProto - EnumDescriptorProto_Options = 3 // optional google.protobuf.EnumOptions - EnumDescriptorProto_ReservedRange = 4 // repeated google.protobuf.EnumDescriptorProto.EnumReservedRange - EnumDescriptorProto_ReservedName = 5 // repeated string -) - -// Field numbers for google.protobuf.EnumDescriptorProto.EnumReservedRange. -const ( - EnumDescriptorProto_EnumReservedRange_Start = 1 // optional int32 - EnumDescriptorProto_EnumReservedRange_End = 2 // optional int32 -) - -// Field numbers for google.protobuf.EnumValueDescriptorProto. -const ( - EnumValueDescriptorProto_Name = 1 // optional string - EnumValueDescriptorProto_Number = 2 // optional int32 - EnumValueDescriptorProto_Options = 3 // optional google.protobuf.EnumValueOptions -) - -// Field numbers for google.protobuf.ServiceDescriptorProto. -const ( - ServiceDescriptorProto_Name = 1 // optional string - ServiceDescriptorProto_Method = 2 // repeated google.protobuf.MethodDescriptorProto - ServiceDescriptorProto_Options = 3 // optional google.protobuf.ServiceOptions -) - -// Field numbers for google.protobuf.MethodDescriptorProto. -const ( - MethodDescriptorProto_Name = 1 // optional string - MethodDescriptorProto_InputType = 2 // optional string - MethodDescriptorProto_OutputType = 3 // optional string - MethodDescriptorProto_Options = 4 // optional google.protobuf.MethodOptions - MethodDescriptorProto_ClientStreaming = 5 // optional bool - MethodDescriptorProto_ServerStreaming = 6 // optional bool -) - -// Field numbers for google.protobuf.FileOptions. -const ( - FileOptions_JavaPackage = 1 // optional string - FileOptions_JavaOuterClassname = 8 // optional string - FileOptions_JavaMultipleFiles = 10 // optional bool - FileOptions_JavaGenerateEqualsAndHash = 20 // optional bool - FileOptions_JavaStringCheckUtf8 = 27 // optional bool - FileOptions_OptimizeFor = 9 // optional google.protobuf.FileOptions.OptimizeMode - FileOptions_GoPackage = 11 // optional string - FileOptions_CcGenericServices = 16 // optional bool - FileOptions_JavaGenericServices = 17 // optional bool - FileOptions_PyGenericServices = 18 // optional bool - FileOptions_PhpGenericServices = 42 // optional bool - FileOptions_Deprecated = 23 // optional bool - FileOptions_CcEnableArenas = 31 // optional bool - FileOptions_ObjcClassPrefix = 36 // optional string - FileOptions_CsharpNamespace = 37 // optional string - FileOptions_SwiftPrefix = 39 // optional string - FileOptions_PhpClassPrefix = 40 // optional string - FileOptions_PhpNamespace = 41 // optional string - FileOptions_PhpMetadataNamespace = 44 // optional string - FileOptions_RubyPackage = 45 // optional string - FileOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.MessageOptions. -const ( - MessageOptions_MessageSetWireFormat = 1 // optional bool - MessageOptions_NoStandardDescriptorAccessor = 2 // optional bool - MessageOptions_Deprecated = 3 // optional bool - MessageOptions_MapEntry = 7 // optional bool - MessageOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.FieldOptions. -const ( - FieldOptions_Ctype = 1 // optional google.protobuf.FieldOptions.CType - FieldOptions_Packed = 2 // optional bool - FieldOptions_Jstype = 6 // optional google.protobuf.FieldOptions.JSType - FieldOptions_Lazy = 5 // optional bool - FieldOptions_Deprecated = 3 // optional bool - FieldOptions_Weak = 10 // optional bool - FieldOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.OneofOptions. -const ( - OneofOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.EnumOptions. -const ( - EnumOptions_AllowAlias = 2 // optional bool - EnumOptions_Deprecated = 3 // optional bool - EnumOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.EnumValueOptions. -const ( - EnumValueOptions_Deprecated = 1 // optional bool - EnumValueOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.ServiceOptions. -const ( - ServiceOptions_Deprecated = 33 // optional bool - ServiceOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.MethodOptions. -const ( - MethodOptions_Deprecated = 33 // optional bool - MethodOptions_IdempotencyLevel = 34 // optional google.protobuf.MethodOptions.IdempotencyLevel - MethodOptions_UninterpretedOption = 999 // repeated google.protobuf.UninterpretedOption -) - -// Field numbers for google.protobuf.UninterpretedOption. -const ( - UninterpretedOption_Name = 2 // repeated google.protobuf.UninterpretedOption.NamePart - UninterpretedOption_IdentifierValue = 3 // optional string - UninterpretedOption_PositiveIntValue = 4 // optional uint64 - UninterpretedOption_NegativeIntValue = 5 // optional int64 - UninterpretedOption_DoubleValue = 6 // optional double - UninterpretedOption_StringValue = 7 // optional bytes - UninterpretedOption_AggregateValue = 8 // optional string -) - -// Field numbers for google.protobuf.UninterpretedOption.NamePart. -const ( - UninterpretedOption_NamePart_NamePart = 1 // required string - UninterpretedOption_NamePart_IsExtension = 2 // required bool -) - -// Field numbers for google.protobuf.SourceCodeInfo. -const ( - SourceCodeInfo_Location = 1 // repeated google.protobuf.SourceCodeInfo.Location -) - -// Field numbers for google.protobuf.SourceCodeInfo.Location. -const ( - SourceCodeInfo_Location_Path = 1 // repeated int32 - SourceCodeInfo_Location_Span = 2 // repeated int32 - SourceCodeInfo_Location_LeadingComments = 3 // optional string - SourceCodeInfo_Location_TrailingComments = 4 // optional string - SourceCodeInfo_Location_LeadingDetachedComments = 6 // repeated string -) - -// Field numbers for google.protobuf.GeneratedCodeInfo. -const ( - GeneratedCodeInfo_Annotation = 1 // repeated google.protobuf.GeneratedCodeInfo.Annotation -) - -// Field numbers for google.protobuf.GeneratedCodeInfo.Annotation. -const ( - GeneratedCodeInfo_Annotation_Path = 1 // repeated int32 - GeneratedCodeInfo_Annotation_SourceFile = 2 // optional string - GeneratedCodeInfo_Annotation_Begin = 3 // optional int32 - GeneratedCodeInfo_Annotation_End = 4 // optional int32 -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/doc.go b/vendor/google.golang.org/protobuf/internal/fieldnum/doc.go deleted file mode 100644 index e59788599..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package fieldnum contains constants for field numbers of fields in messages -// declared in descriptor.proto and any of the well-known types. -package fieldnum diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/duration_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/duration_gen.go deleted file mode 100644 index 8816c7358..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/duration_gen.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.Duration. -const ( - Duration_Seconds = 1 // optional int64 - Duration_Nanos = 2 // optional int32 -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/empty_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/empty_gen.go deleted file mode 100644 index b5130a6dd..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/empty_gen.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.Empty. -const () diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/field_mask_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/field_mask_gen.go deleted file mode 100644 index 7e3bfa27b..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/field_mask_gen.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.FieldMask. -const ( - FieldMask_Paths = 1 // repeated string -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/source_context_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/source_context_gen.go deleted file mode 100644 index 241972b1f..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/source_context_gen.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.SourceContext. -const ( - SourceContext_FileName = 1 // optional string -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/struct_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/struct_gen.go deleted file mode 100644 index c460aab44..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/struct_gen.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.Struct. -const ( - Struct_Fields = 1 // repeated google.protobuf.Struct.FieldsEntry -) - -// Field numbers for google.protobuf.Struct.FieldsEntry. -const ( - Struct_FieldsEntry_Key = 1 // optional string - Struct_FieldsEntry_Value = 2 // optional google.protobuf.Value -) - -// Field numbers for google.protobuf.Value. -const ( - Value_NullValue = 1 // optional google.protobuf.NullValue - Value_NumberValue = 2 // optional double - Value_StringValue = 3 // optional string - Value_BoolValue = 4 // optional bool - Value_StructValue = 5 // optional google.protobuf.Struct - Value_ListValue = 6 // optional google.protobuf.ListValue -) - -// Field numbers for google.protobuf.ListValue. -const ( - ListValue_Values = 1 // repeated google.protobuf.Value -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/timestamp_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/timestamp_gen.go deleted file mode 100644 index b4346fba5..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/timestamp_gen.go +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.Timestamp. -const ( - Timestamp_Seconds = 1 // optional int64 - Timestamp_Nanos = 2 // optional int32 -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/type_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/type_gen.go deleted file mode 100644 index b392e9598..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/type_gen.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.Type. -const ( - Type_Name = 1 // optional string - Type_Fields = 2 // repeated google.protobuf.Field - Type_Oneofs = 3 // repeated string - Type_Options = 4 // repeated google.protobuf.Option - Type_SourceContext = 5 // optional google.protobuf.SourceContext - Type_Syntax = 6 // optional google.protobuf.Syntax -) - -// Field numbers for google.protobuf.Field. -const ( - Field_Kind = 1 // optional google.protobuf.Field.Kind - Field_Cardinality = 2 // optional google.protobuf.Field.Cardinality - Field_Number = 3 // optional int32 - Field_Name = 4 // optional string - Field_TypeUrl = 6 // optional string - Field_OneofIndex = 7 // optional int32 - Field_Packed = 8 // optional bool - Field_Options = 9 // repeated google.protobuf.Option - Field_JsonName = 10 // optional string - Field_DefaultValue = 11 // optional string -) - -// Field numbers for google.protobuf.Enum. -const ( - Enum_Name = 1 // optional string - Enum_Enumvalue = 2 // repeated google.protobuf.EnumValue - Enum_Options = 3 // repeated google.protobuf.Option - Enum_SourceContext = 4 // optional google.protobuf.SourceContext - Enum_Syntax = 5 // optional google.protobuf.Syntax -) - -// Field numbers for google.protobuf.EnumValue. -const ( - EnumValue_Name = 1 // optional string - EnumValue_Number = 2 // optional int32 - EnumValue_Options = 3 // repeated google.protobuf.Option -) - -// Field numbers for google.protobuf.Option. -const ( - Option_Name = 1 // optional string - Option_Value = 2 // optional google.protobuf.Any -) diff --git a/vendor/google.golang.org/protobuf/internal/fieldnum/wrappers_gen.go b/vendor/google.golang.org/protobuf/internal/fieldnum/wrappers_gen.go deleted file mode 100644 index 42f846a9f..000000000 --- a/vendor/google.golang.org/protobuf/internal/fieldnum/wrappers_gen.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Code generated by generate-protos. DO NOT EDIT. - -package fieldnum - -// Field numbers for google.protobuf.DoubleValue. -const ( - DoubleValue_Value = 1 // optional double -) - -// Field numbers for google.protobuf.FloatValue. -const ( - FloatValue_Value = 1 // optional float -) - -// Field numbers for google.protobuf.Int64Value. -const ( - Int64Value_Value = 1 // optional int64 -) - -// Field numbers for google.protobuf.UInt64Value. -const ( - UInt64Value_Value = 1 // optional uint64 -) - -// Field numbers for google.protobuf.Int32Value. -const ( - Int32Value_Value = 1 // optional int32 -) - -// Field numbers for google.protobuf.UInt32Value. -const ( - UInt32Value_Value = 1 // optional uint32 -) - -// Field numbers for google.protobuf.BoolValue. -const ( - BoolValue_Value = 1 // optional bool -) - -// Field numbers for google.protobuf.StringValue. -const ( - StringValue_Value = 1 // optional string -) - -// Field numbers for google.protobuf.BytesValue. -const ( - BytesValue_Value = 1 // optional bytes -) diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/build.go b/vendor/google.golang.org/protobuf/internal/filedesc/build.go index 462d384e9..d02d770c9 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/build.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/build.go @@ -7,7 +7,7 @@ package filedesc import ( "google.golang.org/protobuf/encoding/protowire" - "google.golang.org/protobuf/internal/fieldnum" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/reflect/protoreflect" pref "google.golang.org/protobuf/reflect/protoreflect" preg "google.golang.org/protobuf/reflect/protoregistry" @@ -126,24 +126,24 @@ func (db *Builder) unmarshalCounts(b []byte, isFile bool) { b = b[m:] if isFile { switch num { - case fieldnum.FileDescriptorProto_EnumType: + case genid.FileDescriptorProto_EnumType_field_number: db.NumEnums++ - case fieldnum.FileDescriptorProto_MessageType: + case genid.FileDescriptorProto_MessageType_field_number: db.unmarshalCounts(v, false) db.NumMessages++ - case fieldnum.FileDescriptorProto_Extension: + case genid.FileDescriptorProto_Extension_field_number: db.NumExtensions++ - case fieldnum.FileDescriptorProto_Service: + case genid.FileDescriptorProto_Service_field_number: db.NumServices++ } } else { switch num { - case fieldnum.DescriptorProto_EnumType: + case genid.DescriptorProto_EnumType_field_number: db.NumEnums++ - case fieldnum.DescriptorProto_NestedType: + case genid.DescriptorProto_NestedType_field_number: db.unmarshalCounts(v, false) db.NumMessages++ - case fieldnum.DescriptorProto_Extension: + case genid.DescriptorProto_Extension_field_number: db.NumExtensions++ } } diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go index 2540befd6..9385126fb 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc.go @@ -13,6 +13,7 @@ import ( "google.golang.org/protobuf/internal/descfmt" "google.golang.org/protobuf/internal/descopts" "google.golang.org/protobuf/internal/encoding/defval" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/internal/strs" pref "google.golang.org/protobuf/reflect/protoreflect" @@ -302,13 +303,13 @@ func (fd *Field) MapKey() pref.FieldDescriptor { if !fd.IsMap() { return nil } - return fd.Message().Fields().ByNumber(1) + return fd.Message().Fields().ByNumber(genid.MapEntry_Key_field_number) } func (fd *Field) MapValue() pref.FieldDescriptor { if !fd.IsMap() { return nil } - return fd.Message().Fields().ByNumber(2) + return fd.Message().Fields().ByNumber(genid.MapEntry_Value_field_number) } func (fd *Field) HasDefault() bool { return fd.L1.Default.has } func (fd *Field) Default() pref.Value { return fd.L1.Default.get(fd) } diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go index c0cddf86a..66e1fee52 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_init.go @@ -8,7 +8,7 @@ import ( "sync" "google.golang.org/protobuf/encoding/protowire" - "google.golang.org/protobuf/internal/fieldnum" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" pref "google.golang.org/protobuf/reflect/protoreflect" ) @@ -107,7 +107,7 @@ func (fd *File) unmarshalSeed(b []byte) { v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.FileDescriptorProto_Syntax: + case genid.FileDescriptorProto_Syntax_field_number: switch string(v) { case "proto2": fd.L1.Syntax = pref.Proto2 @@ -116,36 +116,36 @@ func (fd *File) unmarshalSeed(b []byte) { default: panic("invalid syntax") } - case fieldnum.FileDescriptorProto_Name: + case genid.FileDescriptorProto_Name_field_number: fd.L1.Path = sb.MakeString(v) - case fieldnum.FileDescriptorProto_Package: + case genid.FileDescriptorProto_Package_field_number: fd.L1.Package = pref.FullName(sb.MakeString(v)) - case fieldnum.FileDescriptorProto_EnumType: - if prevField != fieldnum.FileDescriptorProto_EnumType { + case genid.FileDescriptorProto_EnumType_field_number: + if prevField != genid.FileDescriptorProto_EnumType_field_number { if numEnums > 0 { panic("non-contiguous repeated field") } posEnums = len(b0) - len(b) - n - m } numEnums++ - case fieldnum.FileDescriptorProto_MessageType: - if prevField != fieldnum.FileDescriptorProto_MessageType { + case genid.FileDescriptorProto_MessageType_field_number: + if prevField != genid.FileDescriptorProto_MessageType_field_number { if numMessages > 0 { panic("non-contiguous repeated field") } posMessages = len(b0) - len(b) - n - m } numMessages++ - case fieldnum.FileDescriptorProto_Extension: - if prevField != fieldnum.FileDescriptorProto_Extension { + case genid.FileDescriptorProto_Extension_field_number: + if prevField != genid.FileDescriptorProto_Extension_field_number { if numExtensions > 0 { panic("non-contiguous repeated field") } posExtensions = len(b0) - len(b) - n - m } numExtensions++ - case fieldnum.FileDescriptorProto_Service: - if prevField != fieldnum.FileDescriptorProto_Service { + case genid.FileDescriptorProto_Service_field_number: + if prevField != genid.FileDescriptorProto_Service_field_number { if numServices > 0 { panic("non-contiguous repeated field") } @@ -233,9 +233,9 @@ func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Desc v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.EnumDescriptorProto_Name: + case genid.EnumDescriptorProto_Name_field_number: ed.L0.FullName = appendFullName(sb, pd.FullName(), v) - case fieldnum.EnumDescriptorProto_Value: + case genid.EnumDescriptorProto_Value_field_number: numValues++ } default: @@ -260,7 +260,7 @@ func (ed *Enum) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.Desc v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.EnumDescriptorProto_Value: + case genid.EnumDescriptorProto_Value_field_number: ed.L2.Values.List[i].unmarshalFull(v, sb, pf, ed, i) i++ } @@ -288,33 +288,33 @@ func (md *Message) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.D v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.DescriptorProto_Name: + case genid.DescriptorProto_Name_field_number: md.L0.FullName = appendFullName(sb, pd.FullName(), v) - case fieldnum.DescriptorProto_EnumType: - if prevField != fieldnum.DescriptorProto_EnumType { + case genid.DescriptorProto_EnumType_field_number: + if prevField != genid.DescriptorProto_EnumType_field_number { if numEnums > 0 { panic("non-contiguous repeated field") } posEnums = len(b0) - len(b) - n - m } numEnums++ - case fieldnum.DescriptorProto_NestedType: - if prevField != fieldnum.DescriptorProto_NestedType { + case genid.DescriptorProto_NestedType_field_number: + if prevField != genid.DescriptorProto_NestedType_field_number { if numMessages > 0 { panic("non-contiguous repeated field") } posMessages = len(b0) - len(b) - n - m } numMessages++ - case fieldnum.DescriptorProto_Extension: - if prevField != fieldnum.DescriptorProto_Extension { + case genid.DescriptorProto_Extension_field_number: + if prevField != genid.DescriptorProto_Extension_field_number { if numExtensions > 0 { panic("non-contiguous repeated field") } posExtensions = len(b0) - len(b) - n - m } numExtensions++ - case fieldnum.DescriptorProto_Options: + case genid.DescriptorProto_Options_field_number: md.unmarshalSeedOptions(v) } prevField = num @@ -375,9 +375,9 @@ func (md *Message) unmarshalSeedOptions(b []byte) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.MessageOptions_MapEntry: + case genid.MessageOptions_MapEntry_field_number: md.L1.IsMapEntry = protowire.DecodeBool(v) - case fieldnum.MessageOptions_MessageSetWireFormat: + case genid.MessageOptions_MessageSetWireFormat_field_number: md.L1.IsMessageSet = protowire.DecodeBool(v) } default: @@ -400,20 +400,20 @@ func (xd *Extension) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.FieldDescriptorProto_Number: + case genid.FieldDescriptorProto_Number_field_number: xd.L1.Number = pref.FieldNumber(v) - case fieldnum.FieldDescriptorProto_Label: + case genid.FieldDescriptorProto_Label_field_number: xd.L1.Cardinality = pref.Cardinality(v) - case fieldnum.FieldDescriptorProto_Type: + case genid.FieldDescriptorProto_Type_field_number: xd.L1.Kind = pref.Kind(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.FieldDescriptorProto_Name: + case genid.FieldDescriptorProto_Name_field_number: xd.L0.FullName = appendFullName(sb, pd.FullName(), v) - case fieldnum.FieldDescriptorProto_Extendee: + case genid.FieldDescriptorProto_Extendee_field_number: xd.L1.Extendee = PlaceholderMessage(makeFullName(sb, v)) } default: @@ -436,7 +436,7 @@ func (sd *Service) unmarshalSeed(b []byte, sb *strs.Builder, pf *File, pd pref.D v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.ServiceDescriptorProto_Name: + case genid.ServiceDescriptorProto_Name_field_number: sd.L0.FullName = appendFullName(sb, pd.FullName(), v) } default: diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go index bc215944a..e672233e7 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_lazy.go @@ -10,7 +10,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/descopts" - "google.golang.org/protobuf/internal/fieldnum" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/proto" pref "google.golang.org/protobuf/reflect/protoreflect" @@ -143,35 +143,35 @@ func (fd *File) unmarshalFull(b []byte) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.FileDescriptorProto_PublicDependency: + case genid.FileDescriptorProto_PublicDependency_field_number: fd.L2.Imports[v].IsPublic = true - case fieldnum.FileDescriptorProto_WeakDependency: + case genid.FileDescriptorProto_WeakDependency_field_number: fd.L2.Imports[v].IsWeak = true } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.FileDescriptorProto_Dependency: + case genid.FileDescriptorProto_Dependency_field_number: path := sb.MakeString(v) imp, _ := fd.builder.FileRegistry.FindFileByPath(path) if imp == nil { imp = PlaceholderFile(path) } fd.L2.Imports = append(fd.L2.Imports, pref.FileImport{FileDescriptor: imp}) - case fieldnum.FileDescriptorProto_EnumType: + case genid.FileDescriptorProto_EnumType_field_number: fd.L1.Enums.List[enumIdx].unmarshalFull(v, sb) enumIdx++ - case fieldnum.FileDescriptorProto_MessageType: + case genid.FileDescriptorProto_MessageType_field_number: fd.L1.Messages.List[messageIdx].unmarshalFull(v, sb) messageIdx++ - case fieldnum.FileDescriptorProto_Extension: + case genid.FileDescriptorProto_Extension_field_number: fd.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb) extensionIdx++ - case fieldnum.FileDescriptorProto_Service: + case genid.FileDescriptorProto_Service_field_number: fd.L1.Services.List[serviceIdx].unmarshalFull(v, sb) serviceIdx++ - case fieldnum.FileDescriptorProto_Options: + case genid.FileDescriptorProto_Options_field_number: rawOptions = appendOptions(rawOptions, v) } default: @@ -196,13 +196,13 @@ func (ed *Enum) unmarshalFull(b []byte, sb *strs.Builder) { v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.EnumDescriptorProto_Value: + case genid.EnumDescriptorProto_Value_field_number: rawValues = append(rawValues, v) - case fieldnum.EnumDescriptorProto_ReservedName: + case genid.EnumDescriptorProto_ReservedName_field_number: ed.L2.ReservedNames.List = append(ed.L2.ReservedNames.List, pref.Name(sb.MakeString(v))) - case fieldnum.EnumDescriptorProto_ReservedRange: + case genid.EnumDescriptorProto_ReservedRange_field_number: ed.L2.ReservedRanges.List = append(ed.L2.ReservedRanges.List, unmarshalEnumReservedRange(v)) - case fieldnum.EnumDescriptorProto_Options: + case genid.EnumDescriptorProto_Options_field_number: rawOptions = appendOptions(rawOptions, v) } default: @@ -228,9 +228,9 @@ func unmarshalEnumReservedRange(b []byte) (r [2]pref.EnumNumber) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.EnumDescriptorProto_EnumReservedRange_Start: + case genid.EnumDescriptorProto_EnumReservedRange_Start_field_number: r[0] = pref.EnumNumber(v) - case fieldnum.EnumDescriptorProto_EnumReservedRange_End: + case genid.EnumDescriptorProto_EnumReservedRange_End_field_number: r[1] = pref.EnumNumber(v) } default: @@ -255,17 +255,17 @@ func (vd *EnumValue) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.EnumValueDescriptorProto_Number: + case genid.EnumValueDescriptorProto_Number_field_number: vd.L1.Number = pref.EnumNumber(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.EnumValueDescriptorProto_Name: + case genid.EnumValueDescriptorProto_Name_field_number: // NOTE: Enum values are in the same scope as the enum parent. vd.L0.FullName = appendFullName(sb, pd.Parent().FullName(), v) - case fieldnum.EnumValueDescriptorProto_Options: + case genid.EnumValueDescriptorProto_Options_field_number: rawOptions = appendOptions(rawOptions, v) } default: @@ -289,29 +289,29 @@ func (md *Message) unmarshalFull(b []byte, sb *strs.Builder) { v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.DescriptorProto_Field: + case genid.DescriptorProto_Field_field_number: rawFields = append(rawFields, v) - case fieldnum.DescriptorProto_OneofDecl: + case genid.DescriptorProto_OneofDecl_field_number: rawOneofs = append(rawOneofs, v) - case fieldnum.DescriptorProto_ReservedName: + case genid.DescriptorProto_ReservedName_field_number: md.L2.ReservedNames.List = append(md.L2.ReservedNames.List, pref.Name(sb.MakeString(v))) - case fieldnum.DescriptorProto_ReservedRange: + case genid.DescriptorProto_ReservedRange_field_number: md.L2.ReservedRanges.List = append(md.L2.ReservedRanges.List, unmarshalMessageReservedRange(v)) - case fieldnum.DescriptorProto_ExtensionRange: + case genid.DescriptorProto_ExtensionRange_field_number: r, rawOptions := unmarshalMessageExtensionRange(v) opts := md.L0.ParentFile.builder.optionsUnmarshaler(&descopts.ExtensionRange, rawOptions) md.L2.ExtensionRanges.List = append(md.L2.ExtensionRanges.List, r) md.L2.ExtensionRangeOptions = append(md.L2.ExtensionRangeOptions, opts) - case fieldnum.DescriptorProto_EnumType: + case genid.DescriptorProto_EnumType_field_number: md.L1.Enums.List[enumIdx].unmarshalFull(v, sb) enumIdx++ - case fieldnum.DescriptorProto_NestedType: + case genid.DescriptorProto_NestedType_field_number: md.L1.Messages.List[messageIdx].unmarshalFull(v, sb) messageIdx++ - case fieldnum.DescriptorProto_Extension: + case genid.DescriptorProto_Extension_field_number: md.L1.Extensions.List[extensionIdx].unmarshalFull(v, sb) extensionIdx++ - case fieldnum.DescriptorProto_Options: + case genid.DescriptorProto_Options_field_number: md.unmarshalOptions(v) rawOptions = appendOptions(rawOptions, v) } @@ -347,9 +347,9 @@ func (md *Message) unmarshalOptions(b []byte) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.MessageOptions_MapEntry: + case genid.MessageOptions_MapEntry_field_number: md.L1.IsMapEntry = protowire.DecodeBool(v) - case fieldnum.MessageOptions_MessageSetWireFormat: + case genid.MessageOptions_MessageSetWireFormat_field_number: md.L1.IsMessageSet = protowire.DecodeBool(v) } default: @@ -368,9 +368,9 @@ func unmarshalMessageReservedRange(b []byte) (r [2]pref.FieldNumber) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.DescriptorProto_ReservedRange_Start: + case genid.DescriptorProto_ReservedRange_Start_field_number: r[0] = pref.FieldNumber(v) - case fieldnum.DescriptorProto_ReservedRange_End: + case genid.DescriptorProto_ReservedRange_End_field_number: r[1] = pref.FieldNumber(v) } default: @@ -390,16 +390,16 @@ func unmarshalMessageExtensionRange(b []byte) (r [2]pref.FieldNumber, rawOptions v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.DescriptorProto_ExtensionRange_Start: + case genid.DescriptorProto_ExtensionRange_Start_field_number: r[0] = pref.FieldNumber(v) - case fieldnum.DescriptorProto_ExtensionRange_End: + case genid.DescriptorProto_ExtensionRange_End_field_number: r[1] = pref.FieldNumber(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.DescriptorProto_ExtensionRange_Options: + case genid.DescriptorProto_ExtensionRange_Options_field_number: rawOptions = appendOptions(rawOptions, v) } default: @@ -425,13 +425,13 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.FieldDescriptorProto_Number: + case genid.FieldDescriptorProto_Number_field_number: fd.L1.Number = pref.FieldNumber(v) - case fieldnum.FieldDescriptorProto_Label: + case genid.FieldDescriptorProto_Label_field_number: fd.L1.Cardinality = pref.Cardinality(v) - case fieldnum.FieldDescriptorProto_Type: + case genid.FieldDescriptorProto_Type_field_number: fd.L1.Kind = pref.Kind(v) - case fieldnum.FieldDescriptorProto_OneofIndex: + case genid.FieldDescriptorProto_OneofIndex_field_number: // In Message.unmarshalFull, we allocate slices for both // the field and oneof descriptors before unmarshaling either // of them. This ensures pointers to slice elements are stable. @@ -441,22 +441,22 @@ func (fd *Field) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des panic("oneof type already set") } fd.L1.ContainingOneof = od - case fieldnum.FieldDescriptorProto_Proto3Optional: + case genid.FieldDescriptorProto_Proto3Optional_field_number: fd.L1.IsProto3Optional = protowire.DecodeBool(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.FieldDescriptorProto_Name: + case genid.FieldDescriptorProto_Name_field_number: fd.L0.FullName = appendFullName(sb, pd.FullName(), v) - case fieldnum.FieldDescriptorProto_JsonName: + case genid.FieldDescriptorProto_JsonName_field_number: fd.L1.JSONName.Init(sb.MakeString(v)) - case fieldnum.FieldDescriptorProto_DefaultValue: + case genid.FieldDescriptorProto_DefaultValue_field_number: fd.L1.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveMessages - case fieldnum.FieldDescriptorProto_TypeName: + case genid.FieldDescriptorProto_TypeName_field_number: rawTypeName = v - case fieldnum.FieldDescriptorProto_Options: + case genid.FieldDescriptorProto_Options_field_number: fd.unmarshalOptions(v) rawOptions = appendOptions(rawOptions, v) } @@ -488,10 +488,10 @@ func (fd *Field) unmarshalOptions(b []byte) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.FieldOptions_Packed: + case genid.FieldOptions_Packed_field_number: fd.L1.HasPacked = true fd.L1.IsPacked = protowire.DecodeBool(v) - case fieldnum.FieldOptions_Weak: + case genid.FieldOptions_Weak_field_number: fd.L1.IsWeak = protowire.DecodeBool(v) case FieldOptions_EnforceUTF8: fd.L1.HasEnforceUTF8 = true @@ -518,9 +518,9 @@ func (od *Oneof) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.Des v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.OneofDescriptorProto_Name: + case genid.OneofDescriptorProto_Name_field_number: od.L0.FullName = appendFullName(sb, pd.FullName(), v) - case fieldnum.OneofDescriptorProto_Options: + case genid.OneofDescriptorProto_Options_field_number: rawOptions = appendOptions(rawOptions, v) } default: @@ -543,20 +543,20 @@ func (xd *Extension) unmarshalFull(b []byte, sb *strs.Builder) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.FieldDescriptorProto_Proto3Optional: + case genid.FieldDescriptorProto_Proto3Optional_field_number: xd.L2.IsProto3Optional = protowire.DecodeBool(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.FieldDescriptorProto_JsonName: + case genid.FieldDescriptorProto_JsonName_field_number: xd.L2.JSONName.Init(sb.MakeString(v)) - case fieldnum.FieldDescriptorProto_DefaultValue: + case genid.FieldDescriptorProto_DefaultValue_field_number: xd.L2.Default.val = pref.ValueOfBytes(v) // temporarily store as bytes; later resolved in resolveExtensions - case fieldnum.FieldDescriptorProto_TypeName: + case genid.FieldDescriptorProto_TypeName_field_number: rawTypeName = v - case fieldnum.FieldDescriptorProto_Options: + case genid.FieldDescriptorProto_Options_field_number: xd.unmarshalOptions(v) rawOptions = appendOptions(rawOptions, v) } @@ -586,7 +586,7 @@ func (xd *Extension) unmarshalOptions(b []byte) { v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.FieldOptions_Packed: + case genid.FieldOptions_Packed_field_number: xd.L2.IsPacked = protowire.DecodeBool(v) } default: @@ -608,9 +608,9 @@ func (sd *Service) unmarshalFull(b []byte, sb *strs.Builder) { v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.ServiceDescriptorProto_Method: + case genid.ServiceDescriptorProto_Method_field_number: rawMethods = append(rawMethods, v) - case fieldnum.ServiceDescriptorProto_Options: + case genid.ServiceDescriptorProto_Options_field_number: rawOptions = appendOptions(rawOptions, v) } default: @@ -641,22 +641,22 @@ func (md *Method) unmarshalFull(b []byte, sb *strs.Builder, pf *File, pd pref.De v, m := protowire.ConsumeVarint(b) b = b[m:] switch num { - case fieldnum.MethodDescriptorProto_ClientStreaming: + case genid.MethodDescriptorProto_ClientStreaming_field_number: md.L1.IsStreamingClient = protowire.DecodeBool(v) - case fieldnum.MethodDescriptorProto_ServerStreaming: + case genid.MethodDescriptorProto_ServerStreaming_field_number: md.L1.IsStreamingServer = protowire.DecodeBool(v) } case protowire.BytesType: v, m := protowire.ConsumeBytes(b) b = b[m:] switch num { - case fieldnum.MethodDescriptorProto_Name: + case genid.MethodDescriptorProto_Name_field_number: md.L0.FullName = appendFullName(sb, pd.FullName(), v) - case fieldnum.MethodDescriptorProto_InputType: + case genid.MethodDescriptorProto_InputType_field_number: md.L1.Input = PlaceholderMessage(makeFullName(sb, v)) - case fieldnum.MethodDescriptorProto_OutputType: + case genid.MethodDescriptorProto_OutputType_field_number: md.L1.Output = PlaceholderMessage(makeFullName(sb, v)) - case fieldnum.MethodDescriptorProto_Options: + case genid.MethodDescriptorProto_Options_field_number: rawOptions = appendOptions(rawOptions, v) } default: diff --git a/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go index 1b7089b64..c876cd34d 100644 --- a/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go +++ b/vendor/google.golang.org/protobuf/internal/filedesc/desc_list.go @@ -6,7 +6,6 @@ package filedesc import ( "fmt" - "math" "sort" "sync" @@ -185,10 +184,7 @@ func (p *FieldRanges) CheckValid(isMessageSet bool) error { // Unlike the FieldNumber.IsValid method, it allows ranges that cover the // reserved number range. func isValidFieldNumber(n protoreflect.FieldNumber, isMessageSet bool) bool { - if isMessageSet { - return protowire.MinValidNumber <= n && n <= math.MaxInt32 - } - return protowire.MinValidNumber <= n && n <= protowire.MaxValidNumber + return protowire.MinValidNumber <= n && (n <= protowire.MaxValidNumber || isMessageSet) } // CheckOverlap reports an error if p and q overlap. diff --git a/vendor/google.golang.org/protobuf/internal/genid/any_gen.go b/vendor/google.golang.org/protobuf/internal/genid/any_gen.go new file mode 100644 index 000000000..e6f7d47ab --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/any_gen.go @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_any_proto = "google/protobuf/any.proto" + +// Names for google.protobuf.Any. +const ( + Any_message_name protoreflect.Name = "Any" + Any_message_fullname protoreflect.FullName = "google.protobuf.Any" +) + +// Field names for google.protobuf.Any. +const ( + Any_TypeUrl_field_name protoreflect.Name = "type_url" + Any_Value_field_name protoreflect.Name = "value" + + Any_TypeUrl_field_fullname protoreflect.FullName = "google.protobuf.Any.type_url" + Any_Value_field_fullname protoreflect.FullName = "google.protobuf.Any.value" +) + +// Field numbers for google.protobuf.Any. +const ( + Any_TypeUrl_field_number protoreflect.FieldNumber = 1 + Any_Value_field_number protoreflect.FieldNumber = 2 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/api_gen.go b/vendor/google.golang.org/protobuf/internal/genid/api_gen.go new file mode 100644 index 000000000..df8f91850 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/api_gen.go @@ -0,0 +1,106 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_api_proto = "google/protobuf/api.proto" + +// Names for google.protobuf.Api. +const ( + Api_message_name protoreflect.Name = "Api" + Api_message_fullname protoreflect.FullName = "google.protobuf.Api" +) + +// Field names for google.protobuf.Api. +const ( + Api_Name_field_name protoreflect.Name = "name" + Api_Methods_field_name protoreflect.Name = "methods" + Api_Options_field_name protoreflect.Name = "options" + Api_Version_field_name protoreflect.Name = "version" + Api_SourceContext_field_name protoreflect.Name = "source_context" + Api_Mixins_field_name protoreflect.Name = "mixins" + Api_Syntax_field_name protoreflect.Name = "syntax" + + Api_Name_field_fullname protoreflect.FullName = "google.protobuf.Api.name" + Api_Methods_field_fullname protoreflect.FullName = "google.protobuf.Api.methods" + Api_Options_field_fullname protoreflect.FullName = "google.protobuf.Api.options" + Api_Version_field_fullname protoreflect.FullName = "google.protobuf.Api.version" + Api_SourceContext_field_fullname protoreflect.FullName = "google.protobuf.Api.source_context" + Api_Mixins_field_fullname protoreflect.FullName = "google.protobuf.Api.mixins" + Api_Syntax_field_fullname protoreflect.FullName = "google.protobuf.Api.syntax" +) + +// Field numbers for google.protobuf.Api. +const ( + Api_Name_field_number protoreflect.FieldNumber = 1 + Api_Methods_field_number protoreflect.FieldNumber = 2 + Api_Options_field_number protoreflect.FieldNumber = 3 + Api_Version_field_number protoreflect.FieldNumber = 4 + Api_SourceContext_field_number protoreflect.FieldNumber = 5 + Api_Mixins_field_number protoreflect.FieldNumber = 6 + Api_Syntax_field_number protoreflect.FieldNumber = 7 +) + +// Names for google.protobuf.Method. +const ( + Method_message_name protoreflect.Name = "Method" + Method_message_fullname protoreflect.FullName = "google.protobuf.Method" +) + +// Field names for google.protobuf.Method. +const ( + Method_Name_field_name protoreflect.Name = "name" + Method_RequestTypeUrl_field_name protoreflect.Name = "request_type_url" + Method_RequestStreaming_field_name protoreflect.Name = "request_streaming" + Method_ResponseTypeUrl_field_name protoreflect.Name = "response_type_url" + Method_ResponseStreaming_field_name protoreflect.Name = "response_streaming" + Method_Options_field_name protoreflect.Name = "options" + Method_Syntax_field_name protoreflect.Name = "syntax" + + Method_Name_field_fullname protoreflect.FullName = "google.protobuf.Method.name" + Method_RequestTypeUrl_field_fullname protoreflect.FullName = "google.protobuf.Method.request_type_url" + Method_RequestStreaming_field_fullname protoreflect.FullName = "google.protobuf.Method.request_streaming" + Method_ResponseTypeUrl_field_fullname protoreflect.FullName = "google.protobuf.Method.response_type_url" + Method_ResponseStreaming_field_fullname protoreflect.FullName = "google.protobuf.Method.response_streaming" + Method_Options_field_fullname protoreflect.FullName = "google.protobuf.Method.options" + Method_Syntax_field_fullname protoreflect.FullName = "google.protobuf.Method.syntax" +) + +// Field numbers for google.protobuf.Method. +const ( + Method_Name_field_number protoreflect.FieldNumber = 1 + Method_RequestTypeUrl_field_number protoreflect.FieldNumber = 2 + Method_RequestStreaming_field_number protoreflect.FieldNumber = 3 + Method_ResponseTypeUrl_field_number protoreflect.FieldNumber = 4 + Method_ResponseStreaming_field_number protoreflect.FieldNumber = 5 + Method_Options_field_number protoreflect.FieldNumber = 6 + Method_Syntax_field_number protoreflect.FieldNumber = 7 +) + +// Names for google.protobuf.Mixin. +const ( + Mixin_message_name protoreflect.Name = "Mixin" + Mixin_message_fullname protoreflect.FullName = "google.protobuf.Mixin" +) + +// Field names for google.protobuf.Mixin. +const ( + Mixin_Name_field_name protoreflect.Name = "name" + Mixin_Root_field_name protoreflect.Name = "root" + + Mixin_Name_field_fullname protoreflect.FullName = "google.protobuf.Mixin.name" + Mixin_Root_field_fullname protoreflect.FullName = "google.protobuf.Mixin.root" +) + +// Field numbers for google.protobuf.Mixin. +const ( + Mixin_Name_field_number protoreflect.FieldNumber = 1 + Mixin_Root_field_number protoreflect.FieldNumber = 2 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go new file mode 100644 index 000000000..e3cdf1c20 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/descriptor_gen.go @@ -0,0 +1,829 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_descriptor_proto = "google/protobuf/descriptor.proto" + +// Names for google.protobuf.FileDescriptorSet. +const ( + FileDescriptorSet_message_name protoreflect.Name = "FileDescriptorSet" + FileDescriptorSet_message_fullname protoreflect.FullName = "google.protobuf.FileDescriptorSet" +) + +// Field names for google.protobuf.FileDescriptorSet. +const ( + FileDescriptorSet_File_field_name protoreflect.Name = "file" + + FileDescriptorSet_File_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorSet.file" +) + +// Field numbers for google.protobuf.FileDescriptorSet. +const ( + FileDescriptorSet_File_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.FileDescriptorProto. +const ( + FileDescriptorProto_message_name protoreflect.Name = "FileDescriptorProto" + FileDescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto" +) + +// Field names for google.protobuf.FileDescriptorProto. +const ( + FileDescriptorProto_Name_field_name protoreflect.Name = "name" + FileDescriptorProto_Package_field_name protoreflect.Name = "package" + FileDescriptorProto_Dependency_field_name protoreflect.Name = "dependency" + FileDescriptorProto_PublicDependency_field_name protoreflect.Name = "public_dependency" + FileDescriptorProto_WeakDependency_field_name protoreflect.Name = "weak_dependency" + FileDescriptorProto_MessageType_field_name protoreflect.Name = "message_type" + FileDescriptorProto_EnumType_field_name protoreflect.Name = "enum_type" + FileDescriptorProto_Service_field_name protoreflect.Name = "service" + FileDescriptorProto_Extension_field_name protoreflect.Name = "extension" + FileDescriptorProto_Options_field_name protoreflect.Name = "options" + FileDescriptorProto_SourceCodeInfo_field_name protoreflect.Name = "source_code_info" + FileDescriptorProto_Syntax_field_name protoreflect.Name = "syntax" + + FileDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.name" + FileDescriptorProto_Package_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.package" + FileDescriptorProto_Dependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.dependency" + FileDescriptorProto_PublicDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.public_dependency" + FileDescriptorProto_WeakDependency_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.weak_dependency" + FileDescriptorProto_MessageType_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.message_type" + FileDescriptorProto_EnumType_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.enum_type" + FileDescriptorProto_Service_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.service" + FileDescriptorProto_Extension_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.extension" + FileDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.options" + FileDescriptorProto_SourceCodeInfo_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.source_code_info" + FileDescriptorProto_Syntax_field_fullname protoreflect.FullName = "google.protobuf.FileDescriptorProto.syntax" +) + +// Field numbers for google.protobuf.FileDescriptorProto. +const ( + FileDescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + FileDescriptorProto_Package_field_number protoreflect.FieldNumber = 2 + FileDescriptorProto_Dependency_field_number protoreflect.FieldNumber = 3 + FileDescriptorProto_PublicDependency_field_number protoreflect.FieldNumber = 10 + FileDescriptorProto_WeakDependency_field_number protoreflect.FieldNumber = 11 + FileDescriptorProto_MessageType_field_number protoreflect.FieldNumber = 4 + FileDescriptorProto_EnumType_field_number protoreflect.FieldNumber = 5 + FileDescriptorProto_Service_field_number protoreflect.FieldNumber = 6 + FileDescriptorProto_Extension_field_number protoreflect.FieldNumber = 7 + FileDescriptorProto_Options_field_number protoreflect.FieldNumber = 8 + FileDescriptorProto_SourceCodeInfo_field_number protoreflect.FieldNumber = 9 + FileDescriptorProto_Syntax_field_number protoreflect.FieldNumber = 12 +) + +// Names for google.protobuf.DescriptorProto. +const ( + DescriptorProto_message_name protoreflect.Name = "DescriptorProto" + DescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.DescriptorProto" +) + +// Field names for google.protobuf.DescriptorProto. +const ( + DescriptorProto_Name_field_name protoreflect.Name = "name" + DescriptorProto_Field_field_name protoreflect.Name = "field" + DescriptorProto_Extension_field_name protoreflect.Name = "extension" + DescriptorProto_NestedType_field_name protoreflect.Name = "nested_type" + DescriptorProto_EnumType_field_name protoreflect.Name = "enum_type" + DescriptorProto_ExtensionRange_field_name protoreflect.Name = "extension_range" + DescriptorProto_OneofDecl_field_name protoreflect.Name = "oneof_decl" + DescriptorProto_Options_field_name protoreflect.Name = "options" + DescriptorProto_ReservedRange_field_name protoreflect.Name = "reserved_range" + DescriptorProto_ReservedName_field_name protoreflect.Name = "reserved_name" + + DescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.name" + DescriptorProto_Field_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.field" + DescriptorProto_Extension_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.extension" + DescriptorProto_NestedType_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.nested_type" + DescriptorProto_EnumType_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.enum_type" + DescriptorProto_ExtensionRange_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.extension_range" + DescriptorProto_OneofDecl_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.oneof_decl" + DescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.options" + DescriptorProto_ReservedRange_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_range" + DescriptorProto_ReservedName_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.reserved_name" +) + +// Field numbers for google.protobuf.DescriptorProto. +const ( + DescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + DescriptorProto_Field_field_number protoreflect.FieldNumber = 2 + DescriptorProto_Extension_field_number protoreflect.FieldNumber = 6 + DescriptorProto_NestedType_field_number protoreflect.FieldNumber = 3 + DescriptorProto_EnumType_field_number protoreflect.FieldNumber = 4 + DescriptorProto_ExtensionRange_field_number protoreflect.FieldNumber = 5 + DescriptorProto_OneofDecl_field_number protoreflect.FieldNumber = 8 + DescriptorProto_Options_field_number protoreflect.FieldNumber = 7 + DescriptorProto_ReservedRange_field_number protoreflect.FieldNumber = 9 + DescriptorProto_ReservedName_field_number protoreflect.FieldNumber = 10 +) + +// Names for google.protobuf.DescriptorProto.ExtensionRange. +const ( + DescriptorProto_ExtensionRange_message_name protoreflect.Name = "ExtensionRange" + DescriptorProto_ExtensionRange_message_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.ExtensionRange" +) + +// Field names for google.protobuf.DescriptorProto.ExtensionRange. +const ( + DescriptorProto_ExtensionRange_Start_field_name protoreflect.Name = "start" + DescriptorProto_ExtensionRange_End_field_name protoreflect.Name = "end" + DescriptorProto_ExtensionRange_Options_field_name protoreflect.Name = "options" + + DescriptorProto_ExtensionRange_Start_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.ExtensionRange.start" + DescriptorProto_ExtensionRange_End_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.ExtensionRange.end" + DescriptorProto_ExtensionRange_Options_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.ExtensionRange.options" +) + +// Field numbers for google.protobuf.DescriptorProto.ExtensionRange. +const ( + DescriptorProto_ExtensionRange_Start_field_number protoreflect.FieldNumber = 1 + DescriptorProto_ExtensionRange_End_field_number protoreflect.FieldNumber = 2 + DescriptorProto_ExtensionRange_Options_field_number protoreflect.FieldNumber = 3 +) + +// Names for google.protobuf.DescriptorProto.ReservedRange. +const ( + DescriptorProto_ReservedRange_message_name protoreflect.Name = "ReservedRange" + DescriptorProto_ReservedRange_message_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.ReservedRange" +) + +// Field names for google.protobuf.DescriptorProto.ReservedRange. +const ( + DescriptorProto_ReservedRange_Start_field_name protoreflect.Name = "start" + DescriptorProto_ReservedRange_End_field_name protoreflect.Name = "end" + + DescriptorProto_ReservedRange_Start_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.ReservedRange.start" + DescriptorProto_ReservedRange_End_field_fullname protoreflect.FullName = "google.protobuf.DescriptorProto.ReservedRange.end" +) + +// Field numbers for google.protobuf.DescriptorProto.ReservedRange. +const ( + DescriptorProto_ReservedRange_Start_field_number protoreflect.FieldNumber = 1 + DescriptorProto_ReservedRange_End_field_number protoreflect.FieldNumber = 2 +) + +// Names for google.protobuf.ExtensionRangeOptions. +const ( + ExtensionRangeOptions_message_name protoreflect.Name = "ExtensionRangeOptions" + ExtensionRangeOptions_message_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions" +) + +// Field names for google.protobuf.ExtensionRangeOptions. +const ( + ExtensionRangeOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + ExtensionRangeOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.ExtensionRangeOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.ExtensionRangeOptions. +const ( + ExtensionRangeOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Names for google.protobuf.FieldDescriptorProto. +const ( + FieldDescriptorProto_message_name protoreflect.Name = "FieldDescriptorProto" + FieldDescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto" +) + +// Field names for google.protobuf.FieldDescriptorProto. +const ( + FieldDescriptorProto_Name_field_name protoreflect.Name = "name" + FieldDescriptorProto_Number_field_name protoreflect.Name = "number" + FieldDescriptorProto_Label_field_name protoreflect.Name = "label" + FieldDescriptorProto_Type_field_name protoreflect.Name = "type" + FieldDescriptorProto_TypeName_field_name protoreflect.Name = "type_name" + FieldDescriptorProto_Extendee_field_name protoreflect.Name = "extendee" + FieldDescriptorProto_DefaultValue_field_name protoreflect.Name = "default_value" + FieldDescriptorProto_OneofIndex_field_name protoreflect.Name = "oneof_index" + FieldDescriptorProto_JsonName_field_name protoreflect.Name = "json_name" + FieldDescriptorProto_Options_field_name protoreflect.Name = "options" + FieldDescriptorProto_Proto3Optional_field_name protoreflect.Name = "proto3_optional" + + FieldDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.name" + FieldDescriptorProto_Number_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.number" + FieldDescriptorProto_Label_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.label" + FieldDescriptorProto_Type_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.type" + FieldDescriptorProto_TypeName_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.type_name" + FieldDescriptorProto_Extendee_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.extendee" + FieldDescriptorProto_DefaultValue_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.default_value" + FieldDescriptorProto_OneofIndex_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.oneof_index" + FieldDescriptorProto_JsonName_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.json_name" + FieldDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.options" + FieldDescriptorProto_Proto3Optional_field_fullname protoreflect.FullName = "google.protobuf.FieldDescriptorProto.proto3_optional" +) + +// Field numbers for google.protobuf.FieldDescriptorProto. +const ( + FieldDescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + FieldDescriptorProto_Number_field_number protoreflect.FieldNumber = 3 + FieldDescriptorProto_Label_field_number protoreflect.FieldNumber = 4 + FieldDescriptorProto_Type_field_number protoreflect.FieldNumber = 5 + FieldDescriptorProto_TypeName_field_number protoreflect.FieldNumber = 6 + FieldDescriptorProto_Extendee_field_number protoreflect.FieldNumber = 2 + FieldDescriptorProto_DefaultValue_field_number protoreflect.FieldNumber = 7 + FieldDescriptorProto_OneofIndex_field_number protoreflect.FieldNumber = 9 + FieldDescriptorProto_JsonName_field_number protoreflect.FieldNumber = 10 + FieldDescriptorProto_Options_field_number protoreflect.FieldNumber = 8 + FieldDescriptorProto_Proto3Optional_field_number protoreflect.FieldNumber = 17 +) + +// Full and short names for google.protobuf.FieldDescriptorProto.Type. +const ( + FieldDescriptorProto_Type_enum_fullname = "google.protobuf.FieldDescriptorProto.Type" + FieldDescriptorProto_Type_enum_name = "Type" +) + +// Full and short names for google.protobuf.FieldDescriptorProto.Label. +const ( + FieldDescriptorProto_Label_enum_fullname = "google.protobuf.FieldDescriptorProto.Label" + FieldDescriptorProto_Label_enum_name = "Label" +) + +// Names for google.protobuf.OneofDescriptorProto. +const ( + OneofDescriptorProto_message_name protoreflect.Name = "OneofDescriptorProto" + OneofDescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.OneofDescriptorProto" +) + +// Field names for google.protobuf.OneofDescriptorProto. +const ( + OneofDescriptorProto_Name_field_name protoreflect.Name = "name" + OneofDescriptorProto_Options_field_name protoreflect.Name = "options" + + OneofDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.OneofDescriptorProto.name" + OneofDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.OneofDescriptorProto.options" +) + +// Field numbers for google.protobuf.OneofDescriptorProto. +const ( + OneofDescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + OneofDescriptorProto_Options_field_number protoreflect.FieldNumber = 2 +) + +// Names for google.protobuf.EnumDescriptorProto. +const ( + EnumDescriptorProto_message_name protoreflect.Name = "EnumDescriptorProto" + EnumDescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto" +) + +// Field names for google.protobuf.EnumDescriptorProto. +const ( + EnumDescriptorProto_Name_field_name protoreflect.Name = "name" + EnumDescriptorProto_Value_field_name protoreflect.Name = "value" + EnumDescriptorProto_Options_field_name protoreflect.Name = "options" + EnumDescriptorProto_ReservedRange_field_name protoreflect.Name = "reserved_range" + EnumDescriptorProto_ReservedName_field_name protoreflect.Name = "reserved_name" + + EnumDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.name" + EnumDescriptorProto_Value_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.value" + EnumDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.options" + EnumDescriptorProto_ReservedRange_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_range" + EnumDescriptorProto_ReservedName_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.reserved_name" +) + +// Field numbers for google.protobuf.EnumDescriptorProto. +const ( + EnumDescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + EnumDescriptorProto_Value_field_number protoreflect.FieldNumber = 2 + EnumDescriptorProto_Options_field_number protoreflect.FieldNumber = 3 + EnumDescriptorProto_ReservedRange_field_number protoreflect.FieldNumber = 4 + EnumDescriptorProto_ReservedName_field_number protoreflect.FieldNumber = 5 +) + +// Names for google.protobuf.EnumDescriptorProto.EnumReservedRange. +const ( + EnumDescriptorProto_EnumReservedRange_message_name protoreflect.Name = "EnumReservedRange" + EnumDescriptorProto_EnumReservedRange_message_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.EnumReservedRange" +) + +// Field names for google.protobuf.EnumDescriptorProto.EnumReservedRange. +const ( + EnumDescriptorProto_EnumReservedRange_Start_field_name protoreflect.Name = "start" + EnumDescriptorProto_EnumReservedRange_End_field_name protoreflect.Name = "end" + + EnumDescriptorProto_EnumReservedRange_Start_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.EnumReservedRange.start" + EnumDescriptorProto_EnumReservedRange_End_field_fullname protoreflect.FullName = "google.protobuf.EnumDescriptorProto.EnumReservedRange.end" +) + +// Field numbers for google.protobuf.EnumDescriptorProto.EnumReservedRange. +const ( + EnumDescriptorProto_EnumReservedRange_Start_field_number protoreflect.FieldNumber = 1 + EnumDescriptorProto_EnumReservedRange_End_field_number protoreflect.FieldNumber = 2 +) + +// Names for google.protobuf.EnumValueDescriptorProto. +const ( + EnumValueDescriptorProto_message_name protoreflect.Name = "EnumValueDescriptorProto" + EnumValueDescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.EnumValueDescriptorProto" +) + +// Field names for google.protobuf.EnumValueDescriptorProto. +const ( + EnumValueDescriptorProto_Name_field_name protoreflect.Name = "name" + EnumValueDescriptorProto_Number_field_name protoreflect.Name = "number" + EnumValueDescriptorProto_Options_field_name protoreflect.Name = "options" + + EnumValueDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.EnumValueDescriptorProto.name" + EnumValueDescriptorProto_Number_field_fullname protoreflect.FullName = "google.protobuf.EnumValueDescriptorProto.number" + EnumValueDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.EnumValueDescriptorProto.options" +) + +// Field numbers for google.protobuf.EnumValueDescriptorProto. +const ( + EnumValueDescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + EnumValueDescriptorProto_Number_field_number protoreflect.FieldNumber = 2 + EnumValueDescriptorProto_Options_field_number protoreflect.FieldNumber = 3 +) + +// Names for google.protobuf.ServiceDescriptorProto. +const ( + ServiceDescriptorProto_message_name protoreflect.Name = "ServiceDescriptorProto" + ServiceDescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.ServiceDescriptorProto" +) + +// Field names for google.protobuf.ServiceDescriptorProto. +const ( + ServiceDescriptorProto_Name_field_name protoreflect.Name = "name" + ServiceDescriptorProto_Method_field_name protoreflect.Name = "method" + ServiceDescriptorProto_Options_field_name protoreflect.Name = "options" + + ServiceDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.ServiceDescriptorProto.name" + ServiceDescriptorProto_Method_field_fullname protoreflect.FullName = "google.protobuf.ServiceDescriptorProto.method" + ServiceDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.ServiceDescriptorProto.options" +) + +// Field numbers for google.protobuf.ServiceDescriptorProto. +const ( + ServiceDescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + ServiceDescriptorProto_Method_field_number protoreflect.FieldNumber = 2 + ServiceDescriptorProto_Options_field_number protoreflect.FieldNumber = 3 +) + +// Names for google.protobuf.MethodDescriptorProto. +const ( + MethodDescriptorProto_message_name protoreflect.Name = "MethodDescriptorProto" + MethodDescriptorProto_message_fullname protoreflect.FullName = "google.protobuf.MethodDescriptorProto" +) + +// Field names for google.protobuf.MethodDescriptorProto. +const ( + MethodDescriptorProto_Name_field_name protoreflect.Name = "name" + MethodDescriptorProto_InputType_field_name protoreflect.Name = "input_type" + MethodDescriptorProto_OutputType_field_name protoreflect.Name = "output_type" + MethodDescriptorProto_Options_field_name protoreflect.Name = "options" + MethodDescriptorProto_ClientStreaming_field_name protoreflect.Name = "client_streaming" + MethodDescriptorProto_ServerStreaming_field_name protoreflect.Name = "server_streaming" + + MethodDescriptorProto_Name_field_fullname protoreflect.FullName = "google.protobuf.MethodDescriptorProto.name" + MethodDescriptorProto_InputType_field_fullname protoreflect.FullName = "google.protobuf.MethodDescriptorProto.input_type" + MethodDescriptorProto_OutputType_field_fullname protoreflect.FullName = "google.protobuf.MethodDescriptorProto.output_type" + MethodDescriptorProto_Options_field_fullname protoreflect.FullName = "google.protobuf.MethodDescriptorProto.options" + MethodDescriptorProto_ClientStreaming_field_fullname protoreflect.FullName = "google.protobuf.MethodDescriptorProto.client_streaming" + MethodDescriptorProto_ServerStreaming_field_fullname protoreflect.FullName = "google.protobuf.MethodDescriptorProto.server_streaming" +) + +// Field numbers for google.protobuf.MethodDescriptorProto. +const ( + MethodDescriptorProto_Name_field_number protoreflect.FieldNumber = 1 + MethodDescriptorProto_InputType_field_number protoreflect.FieldNumber = 2 + MethodDescriptorProto_OutputType_field_number protoreflect.FieldNumber = 3 + MethodDescriptorProto_Options_field_number protoreflect.FieldNumber = 4 + MethodDescriptorProto_ClientStreaming_field_number protoreflect.FieldNumber = 5 + MethodDescriptorProto_ServerStreaming_field_number protoreflect.FieldNumber = 6 +) + +// Names for google.protobuf.FileOptions. +const ( + FileOptions_message_name protoreflect.Name = "FileOptions" + FileOptions_message_fullname protoreflect.FullName = "google.protobuf.FileOptions" +) + +// Field names for google.protobuf.FileOptions. +const ( + FileOptions_JavaPackage_field_name protoreflect.Name = "java_package" + FileOptions_JavaOuterClassname_field_name protoreflect.Name = "java_outer_classname" + FileOptions_JavaMultipleFiles_field_name protoreflect.Name = "java_multiple_files" + FileOptions_JavaGenerateEqualsAndHash_field_name protoreflect.Name = "java_generate_equals_and_hash" + FileOptions_JavaStringCheckUtf8_field_name protoreflect.Name = "java_string_check_utf8" + FileOptions_OptimizeFor_field_name protoreflect.Name = "optimize_for" + FileOptions_GoPackage_field_name protoreflect.Name = "go_package" + FileOptions_CcGenericServices_field_name protoreflect.Name = "cc_generic_services" + FileOptions_JavaGenericServices_field_name protoreflect.Name = "java_generic_services" + FileOptions_PyGenericServices_field_name protoreflect.Name = "py_generic_services" + FileOptions_PhpGenericServices_field_name protoreflect.Name = "php_generic_services" + FileOptions_Deprecated_field_name protoreflect.Name = "deprecated" + FileOptions_CcEnableArenas_field_name protoreflect.Name = "cc_enable_arenas" + FileOptions_ObjcClassPrefix_field_name protoreflect.Name = "objc_class_prefix" + FileOptions_CsharpNamespace_field_name protoreflect.Name = "csharp_namespace" + FileOptions_SwiftPrefix_field_name protoreflect.Name = "swift_prefix" + FileOptions_PhpClassPrefix_field_name protoreflect.Name = "php_class_prefix" + FileOptions_PhpNamespace_field_name protoreflect.Name = "php_namespace" + FileOptions_PhpMetadataNamespace_field_name protoreflect.Name = "php_metadata_namespace" + FileOptions_RubyPackage_field_name protoreflect.Name = "ruby_package" + FileOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + FileOptions_JavaPackage_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.java_package" + FileOptions_JavaOuterClassname_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.java_outer_classname" + FileOptions_JavaMultipleFiles_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.java_multiple_files" + FileOptions_JavaGenerateEqualsAndHash_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.java_generate_equals_and_hash" + FileOptions_JavaStringCheckUtf8_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.java_string_check_utf8" + FileOptions_OptimizeFor_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.optimize_for" + FileOptions_GoPackage_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.go_package" + FileOptions_CcGenericServices_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.cc_generic_services" + FileOptions_JavaGenericServices_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.java_generic_services" + FileOptions_PyGenericServices_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.py_generic_services" + FileOptions_PhpGenericServices_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.php_generic_services" + FileOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.deprecated" + FileOptions_CcEnableArenas_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.cc_enable_arenas" + FileOptions_ObjcClassPrefix_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.objc_class_prefix" + FileOptions_CsharpNamespace_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.csharp_namespace" + FileOptions_SwiftPrefix_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.swift_prefix" + FileOptions_PhpClassPrefix_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.php_class_prefix" + FileOptions_PhpNamespace_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.php_namespace" + FileOptions_PhpMetadataNamespace_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.php_metadata_namespace" + FileOptions_RubyPackage_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.ruby_package" + FileOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.FileOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.FileOptions. +const ( + FileOptions_JavaPackage_field_number protoreflect.FieldNumber = 1 + FileOptions_JavaOuterClassname_field_number protoreflect.FieldNumber = 8 + FileOptions_JavaMultipleFiles_field_number protoreflect.FieldNumber = 10 + FileOptions_JavaGenerateEqualsAndHash_field_number protoreflect.FieldNumber = 20 + FileOptions_JavaStringCheckUtf8_field_number protoreflect.FieldNumber = 27 + FileOptions_OptimizeFor_field_number protoreflect.FieldNumber = 9 + FileOptions_GoPackage_field_number protoreflect.FieldNumber = 11 + FileOptions_CcGenericServices_field_number protoreflect.FieldNumber = 16 + FileOptions_JavaGenericServices_field_number protoreflect.FieldNumber = 17 + FileOptions_PyGenericServices_field_number protoreflect.FieldNumber = 18 + FileOptions_PhpGenericServices_field_number protoreflect.FieldNumber = 42 + FileOptions_Deprecated_field_number protoreflect.FieldNumber = 23 + FileOptions_CcEnableArenas_field_number protoreflect.FieldNumber = 31 + FileOptions_ObjcClassPrefix_field_number protoreflect.FieldNumber = 36 + FileOptions_CsharpNamespace_field_number protoreflect.FieldNumber = 37 + FileOptions_SwiftPrefix_field_number protoreflect.FieldNumber = 39 + FileOptions_PhpClassPrefix_field_number protoreflect.FieldNumber = 40 + FileOptions_PhpNamespace_field_number protoreflect.FieldNumber = 41 + FileOptions_PhpMetadataNamespace_field_number protoreflect.FieldNumber = 44 + FileOptions_RubyPackage_field_number protoreflect.FieldNumber = 45 + FileOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Full and short names for google.protobuf.FileOptions.OptimizeMode. +const ( + FileOptions_OptimizeMode_enum_fullname = "google.protobuf.FileOptions.OptimizeMode" + FileOptions_OptimizeMode_enum_name = "OptimizeMode" +) + +// Names for google.protobuf.MessageOptions. +const ( + MessageOptions_message_name protoreflect.Name = "MessageOptions" + MessageOptions_message_fullname protoreflect.FullName = "google.protobuf.MessageOptions" +) + +// Field names for google.protobuf.MessageOptions. +const ( + MessageOptions_MessageSetWireFormat_field_name protoreflect.Name = "message_set_wire_format" + MessageOptions_NoStandardDescriptorAccessor_field_name protoreflect.Name = "no_standard_descriptor_accessor" + MessageOptions_Deprecated_field_name protoreflect.Name = "deprecated" + MessageOptions_MapEntry_field_name protoreflect.Name = "map_entry" + MessageOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + MessageOptions_MessageSetWireFormat_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.message_set_wire_format" + MessageOptions_NoStandardDescriptorAccessor_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.no_standard_descriptor_accessor" + MessageOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.deprecated" + MessageOptions_MapEntry_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.map_entry" + MessageOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.MessageOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.MessageOptions. +const ( + MessageOptions_MessageSetWireFormat_field_number protoreflect.FieldNumber = 1 + MessageOptions_NoStandardDescriptorAccessor_field_number protoreflect.FieldNumber = 2 + MessageOptions_Deprecated_field_number protoreflect.FieldNumber = 3 + MessageOptions_MapEntry_field_number protoreflect.FieldNumber = 7 + MessageOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Names for google.protobuf.FieldOptions. +const ( + FieldOptions_message_name protoreflect.Name = "FieldOptions" + FieldOptions_message_fullname protoreflect.FullName = "google.protobuf.FieldOptions" +) + +// Field names for google.protobuf.FieldOptions. +const ( + FieldOptions_Ctype_field_name protoreflect.Name = "ctype" + FieldOptions_Packed_field_name protoreflect.Name = "packed" + FieldOptions_Jstype_field_name protoreflect.Name = "jstype" + FieldOptions_Lazy_field_name protoreflect.Name = "lazy" + FieldOptions_Deprecated_field_name protoreflect.Name = "deprecated" + FieldOptions_Weak_field_name protoreflect.Name = "weak" + FieldOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + FieldOptions_Ctype_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.ctype" + FieldOptions_Packed_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.packed" + FieldOptions_Jstype_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.jstype" + FieldOptions_Lazy_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.lazy" + FieldOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.deprecated" + FieldOptions_Weak_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.weak" + FieldOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.FieldOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.FieldOptions. +const ( + FieldOptions_Ctype_field_number protoreflect.FieldNumber = 1 + FieldOptions_Packed_field_number protoreflect.FieldNumber = 2 + FieldOptions_Jstype_field_number protoreflect.FieldNumber = 6 + FieldOptions_Lazy_field_number protoreflect.FieldNumber = 5 + FieldOptions_Deprecated_field_number protoreflect.FieldNumber = 3 + FieldOptions_Weak_field_number protoreflect.FieldNumber = 10 + FieldOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Full and short names for google.protobuf.FieldOptions.CType. +const ( + FieldOptions_CType_enum_fullname = "google.protobuf.FieldOptions.CType" + FieldOptions_CType_enum_name = "CType" +) + +// Full and short names for google.protobuf.FieldOptions.JSType. +const ( + FieldOptions_JSType_enum_fullname = "google.protobuf.FieldOptions.JSType" + FieldOptions_JSType_enum_name = "JSType" +) + +// Names for google.protobuf.OneofOptions. +const ( + OneofOptions_message_name protoreflect.Name = "OneofOptions" + OneofOptions_message_fullname protoreflect.FullName = "google.protobuf.OneofOptions" +) + +// Field names for google.protobuf.OneofOptions. +const ( + OneofOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + OneofOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.OneofOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.OneofOptions. +const ( + OneofOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Names for google.protobuf.EnumOptions. +const ( + EnumOptions_message_name protoreflect.Name = "EnumOptions" + EnumOptions_message_fullname protoreflect.FullName = "google.protobuf.EnumOptions" +) + +// Field names for google.protobuf.EnumOptions. +const ( + EnumOptions_AllowAlias_field_name protoreflect.Name = "allow_alias" + EnumOptions_Deprecated_field_name protoreflect.Name = "deprecated" + EnumOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + EnumOptions_AllowAlias_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.allow_alias" + EnumOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.deprecated" + EnumOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.EnumOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.EnumOptions. +const ( + EnumOptions_AllowAlias_field_number protoreflect.FieldNumber = 2 + EnumOptions_Deprecated_field_number protoreflect.FieldNumber = 3 + EnumOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Names for google.protobuf.EnumValueOptions. +const ( + EnumValueOptions_message_name protoreflect.Name = "EnumValueOptions" + EnumValueOptions_message_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions" +) + +// Field names for google.protobuf.EnumValueOptions. +const ( + EnumValueOptions_Deprecated_field_name protoreflect.Name = "deprecated" + EnumValueOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + EnumValueOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions.deprecated" + EnumValueOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.EnumValueOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.EnumValueOptions. +const ( + EnumValueOptions_Deprecated_field_number protoreflect.FieldNumber = 1 + EnumValueOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Names for google.protobuf.ServiceOptions. +const ( + ServiceOptions_message_name protoreflect.Name = "ServiceOptions" + ServiceOptions_message_fullname protoreflect.FullName = "google.protobuf.ServiceOptions" +) + +// Field names for google.protobuf.ServiceOptions. +const ( + ServiceOptions_Deprecated_field_name protoreflect.Name = "deprecated" + ServiceOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + ServiceOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.ServiceOptions.deprecated" + ServiceOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.ServiceOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.ServiceOptions. +const ( + ServiceOptions_Deprecated_field_number protoreflect.FieldNumber = 33 + ServiceOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Names for google.protobuf.MethodOptions. +const ( + MethodOptions_message_name protoreflect.Name = "MethodOptions" + MethodOptions_message_fullname protoreflect.FullName = "google.protobuf.MethodOptions" +) + +// Field names for google.protobuf.MethodOptions. +const ( + MethodOptions_Deprecated_field_name protoreflect.Name = "deprecated" + MethodOptions_IdempotencyLevel_field_name protoreflect.Name = "idempotency_level" + MethodOptions_UninterpretedOption_field_name protoreflect.Name = "uninterpreted_option" + + MethodOptions_Deprecated_field_fullname protoreflect.FullName = "google.protobuf.MethodOptions.deprecated" + MethodOptions_IdempotencyLevel_field_fullname protoreflect.FullName = "google.protobuf.MethodOptions.idempotency_level" + MethodOptions_UninterpretedOption_field_fullname protoreflect.FullName = "google.protobuf.MethodOptions.uninterpreted_option" +) + +// Field numbers for google.protobuf.MethodOptions. +const ( + MethodOptions_Deprecated_field_number protoreflect.FieldNumber = 33 + MethodOptions_IdempotencyLevel_field_number protoreflect.FieldNumber = 34 + MethodOptions_UninterpretedOption_field_number protoreflect.FieldNumber = 999 +) + +// Full and short names for google.protobuf.MethodOptions.IdempotencyLevel. +const ( + MethodOptions_IdempotencyLevel_enum_fullname = "google.protobuf.MethodOptions.IdempotencyLevel" + MethodOptions_IdempotencyLevel_enum_name = "IdempotencyLevel" +) + +// Names for google.protobuf.UninterpretedOption. +const ( + UninterpretedOption_message_name protoreflect.Name = "UninterpretedOption" + UninterpretedOption_message_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption" +) + +// Field names for google.protobuf.UninterpretedOption. +const ( + UninterpretedOption_Name_field_name protoreflect.Name = "name" + UninterpretedOption_IdentifierValue_field_name protoreflect.Name = "identifier_value" + UninterpretedOption_PositiveIntValue_field_name protoreflect.Name = "positive_int_value" + UninterpretedOption_NegativeIntValue_field_name protoreflect.Name = "negative_int_value" + UninterpretedOption_DoubleValue_field_name protoreflect.Name = "double_value" + UninterpretedOption_StringValue_field_name protoreflect.Name = "string_value" + UninterpretedOption_AggregateValue_field_name protoreflect.Name = "aggregate_value" + + UninterpretedOption_Name_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.name" + UninterpretedOption_IdentifierValue_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.identifier_value" + UninterpretedOption_PositiveIntValue_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.positive_int_value" + UninterpretedOption_NegativeIntValue_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.negative_int_value" + UninterpretedOption_DoubleValue_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.double_value" + UninterpretedOption_StringValue_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.string_value" + UninterpretedOption_AggregateValue_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.aggregate_value" +) + +// Field numbers for google.protobuf.UninterpretedOption. +const ( + UninterpretedOption_Name_field_number protoreflect.FieldNumber = 2 + UninterpretedOption_IdentifierValue_field_number protoreflect.FieldNumber = 3 + UninterpretedOption_PositiveIntValue_field_number protoreflect.FieldNumber = 4 + UninterpretedOption_NegativeIntValue_field_number protoreflect.FieldNumber = 5 + UninterpretedOption_DoubleValue_field_number protoreflect.FieldNumber = 6 + UninterpretedOption_StringValue_field_number protoreflect.FieldNumber = 7 + UninterpretedOption_AggregateValue_field_number protoreflect.FieldNumber = 8 +) + +// Names for google.protobuf.UninterpretedOption.NamePart. +const ( + UninterpretedOption_NamePart_message_name protoreflect.Name = "NamePart" + UninterpretedOption_NamePart_message_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.NamePart" +) + +// Field names for google.protobuf.UninterpretedOption.NamePart. +const ( + UninterpretedOption_NamePart_NamePart_field_name protoreflect.Name = "name_part" + UninterpretedOption_NamePart_IsExtension_field_name protoreflect.Name = "is_extension" + + UninterpretedOption_NamePart_NamePart_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.NamePart.name_part" + UninterpretedOption_NamePart_IsExtension_field_fullname protoreflect.FullName = "google.protobuf.UninterpretedOption.NamePart.is_extension" +) + +// Field numbers for google.protobuf.UninterpretedOption.NamePart. +const ( + UninterpretedOption_NamePart_NamePart_field_number protoreflect.FieldNumber = 1 + UninterpretedOption_NamePart_IsExtension_field_number protoreflect.FieldNumber = 2 +) + +// Names for google.protobuf.SourceCodeInfo. +const ( + SourceCodeInfo_message_name protoreflect.Name = "SourceCodeInfo" + SourceCodeInfo_message_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo" +) + +// Field names for google.protobuf.SourceCodeInfo. +const ( + SourceCodeInfo_Location_field_name protoreflect.Name = "location" + + SourceCodeInfo_Location_field_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo.location" +) + +// Field numbers for google.protobuf.SourceCodeInfo. +const ( + SourceCodeInfo_Location_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.SourceCodeInfo.Location. +const ( + SourceCodeInfo_Location_message_name protoreflect.Name = "Location" + SourceCodeInfo_Location_message_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo.Location" +) + +// Field names for google.protobuf.SourceCodeInfo.Location. +const ( + SourceCodeInfo_Location_Path_field_name protoreflect.Name = "path" + SourceCodeInfo_Location_Span_field_name protoreflect.Name = "span" + SourceCodeInfo_Location_LeadingComments_field_name protoreflect.Name = "leading_comments" + SourceCodeInfo_Location_TrailingComments_field_name protoreflect.Name = "trailing_comments" + SourceCodeInfo_Location_LeadingDetachedComments_field_name protoreflect.Name = "leading_detached_comments" + + SourceCodeInfo_Location_Path_field_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo.Location.path" + SourceCodeInfo_Location_Span_field_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo.Location.span" + SourceCodeInfo_Location_LeadingComments_field_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo.Location.leading_comments" + SourceCodeInfo_Location_TrailingComments_field_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo.Location.trailing_comments" + SourceCodeInfo_Location_LeadingDetachedComments_field_fullname protoreflect.FullName = "google.protobuf.SourceCodeInfo.Location.leading_detached_comments" +) + +// Field numbers for google.protobuf.SourceCodeInfo.Location. +const ( + SourceCodeInfo_Location_Path_field_number protoreflect.FieldNumber = 1 + SourceCodeInfo_Location_Span_field_number protoreflect.FieldNumber = 2 + SourceCodeInfo_Location_LeadingComments_field_number protoreflect.FieldNumber = 3 + SourceCodeInfo_Location_TrailingComments_field_number protoreflect.FieldNumber = 4 + SourceCodeInfo_Location_LeadingDetachedComments_field_number protoreflect.FieldNumber = 6 +) + +// Names for google.protobuf.GeneratedCodeInfo. +const ( + GeneratedCodeInfo_message_name protoreflect.Name = "GeneratedCodeInfo" + GeneratedCodeInfo_message_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo" +) + +// Field names for google.protobuf.GeneratedCodeInfo. +const ( + GeneratedCodeInfo_Annotation_field_name protoreflect.Name = "annotation" + + GeneratedCodeInfo_Annotation_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.annotation" +) + +// Field numbers for google.protobuf.GeneratedCodeInfo. +const ( + GeneratedCodeInfo_Annotation_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.GeneratedCodeInfo.Annotation. +const ( + GeneratedCodeInfo_Annotation_message_name protoreflect.Name = "Annotation" + GeneratedCodeInfo_Annotation_message_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation" +) + +// Field names for google.protobuf.GeneratedCodeInfo.Annotation. +const ( + GeneratedCodeInfo_Annotation_Path_field_name protoreflect.Name = "path" + GeneratedCodeInfo_Annotation_SourceFile_field_name protoreflect.Name = "source_file" + GeneratedCodeInfo_Annotation_Begin_field_name protoreflect.Name = "begin" + GeneratedCodeInfo_Annotation_End_field_name protoreflect.Name = "end" + + GeneratedCodeInfo_Annotation_Path_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.path" + GeneratedCodeInfo_Annotation_SourceFile_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.source_file" + GeneratedCodeInfo_Annotation_Begin_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.begin" + GeneratedCodeInfo_Annotation_End_field_fullname protoreflect.FullName = "google.protobuf.GeneratedCodeInfo.Annotation.end" +) + +// Field numbers for google.protobuf.GeneratedCodeInfo.Annotation. +const ( + GeneratedCodeInfo_Annotation_Path_field_number protoreflect.FieldNumber = 1 + GeneratedCodeInfo_Annotation_SourceFile_field_number protoreflect.FieldNumber = 2 + GeneratedCodeInfo_Annotation_Begin_field_number protoreflect.FieldNumber = 3 + GeneratedCodeInfo_Annotation_End_field_number protoreflect.FieldNumber = 4 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/doc.go b/vendor/google.golang.org/protobuf/internal/genid/doc.go new file mode 100644 index 000000000..45ccd0121 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/doc.go @@ -0,0 +1,11 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package genid contains constants for declarations in descriptor.proto +// and the well-known types. +package genid + +import protoreflect "google.golang.org/protobuf/reflect/protoreflect" + +const GoogleProtobuf_package protoreflect.FullName = "google.protobuf" diff --git a/vendor/google.golang.org/protobuf/internal/genid/duration_gen.go b/vendor/google.golang.org/protobuf/internal/genid/duration_gen.go new file mode 100644 index 000000000..b070ef4fd --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/duration_gen.go @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_duration_proto = "google/protobuf/duration.proto" + +// Names for google.protobuf.Duration. +const ( + Duration_message_name protoreflect.Name = "Duration" + Duration_message_fullname protoreflect.FullName = "google.protobuf.Duration" +) + +// Field names for google.protobuf.Duration. +const ( + Duration_Seconds_field_name protoreflect.Name = "seconds" + Duration_Nanos_field_name protoreflect.Name = "nanos" + + Duration_Seconds_field_fullname protoreflect.FullName = "google.protobuf.Duration.seconds" + Duration_Nanos_field_fullname protoreflect.FullName = "google.protobuf.Duration.nanos" +) + +// Field numbers for google.protobuf.Duration. +const ( + Duration_Seconds_field_number protoreflect.FieldNumber = 1 + Duration_Nanos_field_number protoreflect.FieldNumber = 2 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/empty_gen.go b/vendor/google.golang.org/protobuf/internal/genid/empty_gen.go new file mode 100644 index 000000000..762abb34a --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/empty_gen.go @@ -0,0 +1,19 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_empty_proto = "google/protobuf/empty.proto" + +// Names for google.protobuf.Empty. +const ( + Empty_message_name protoreflect.Name = "Empty" + Empty_message_fullname protoreflect.FullName = "google.protobuf.Empty" +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go b/vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go new file mode 100644 index 000000000..70bed453f --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/field_mask_gen.go @@ -0,0 +1,31 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_field_mask_proto = "google/protobuf/field_mask.proto" + +// Names for google.protobuf.FieldMask. +const ( + FieldMask_message_name protoreflect.Name = "FieldMask" + FieldMask_message_fullname protoreflect.FullName = "google.protobuf.FieldMask" +) + +// Field names for google.protobuf.FieldMask. +const ( + FieldMask_Paths_field_name protoreflect.Name = "paths" + + FieldMask_Paths_field_fullname protoreflect.FullName = "google.protobuf.FieldMask.paths" +) + +// Field numbers for google.protobuf.FieldMask. +const ( + FieldMask_Paths_field_number protoreflect.FieldNumber = 1 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/goname.go b/vendor/google.golang.org/protobuf/internal/genid/goname.go new file mode 100644 index 000000000..693d2e9e1 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/goname.go @@ -0,0 +1,25 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package genid + +// Go names of implementation-specific struct fields in generated messages. +const ( + State_goname = "state" + + SizeCache_goname = "sizeCache" + SizeCacheA_goname = "XXX_sizecache" + + WeakFields_goname = "weakFields" + WeakFieldsA_goname = "XXX_weak" + + UnknownFields_goname = "unknownFields" + UnknownFieldsA_goname = "XXX_unrecognized" + + ExtensionFields_goname = "extensionFields" + ExtensionFieldsA_goname = "XXX_InternalExtensions" + ExtensionFieldsB_goname = "XXX_extensions" + + WeakFieldPrefix_goname = "XXX_weak_" +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/map_entry.go b/vendor/google.golang.org/protobuf/internal/genid/map_entry.go new file mode 100644 index 000000000..8f9ea02ff --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/map_entry.go @@ -0,0 +1,16 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package genid + +import protoreflect "google.golang.org/protobuf/reflect/protoreflect" + +// Generic field names and numbers for synthetic map entry messages. +const ( + MapEntry_Key_field_name protoreflect.Name = "key" + MapEntry_Value_field_name protoreflect.Name = "value" + + MapEntry_Key_field_number protoreflect.FieldNumber = 1 + MapEntry_Value_field_number protoreflect.FieldNumber = 2 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go b/vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go new file mode 100644 index 000000000..3e99ae16c --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/source_context_gen.go @@ -0,0 +1,31 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_source_context_proto = "google/protobuf/source_context.proto" + +// Names for google.protobuf.SourceContext. +const ( + SourceContext_message_name protoreflect.Name = "SourceContext" + SourceContext_message_fullname protoreflect.FullName = "google.protobuf.SourceContext" +) + +// Field names for google.protobuf.SourceContext. +const ( + SourceContext_FileName_field_name protoreflect.Name = "file_name" + + SourceContext_FileName_field_fullname protoreflect.FullName = "google.protobuf.SourceContext.file_name" +) + +// Field numbers for google.protobuf.SourceContext. +const ( + SourceContext_FileName_field_number protoreflect.FieldNumber = 1 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/struct_gen.go b/vendor/google.golang.org/protobuf/internal/genid/struct_gen.go new file mode 100644 index 000000000..1a38944b2 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/struct_gen.go @@ -0,0 +1,116 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_struct_proto = "google/protobuf/struct.proto" + +// Full and short names for google.protobuf.NullValue. +const ( + NullValue_enum_fullname = "google.protobuf.NullValue" + NullValue_enum_name = "NullValue" +) + +// Names for google.protobuf.Struct. +const ( + Struct_message_name protoreflect.Name = "Struct" + Struct_message_fullname protoreflect.FullName = "google.protobuf.Struct" +) + +// Field names for google.protobuf.Struct. +const ( + Struct_Fields_field_name protoreflect.Name = "fields" + + Struct_Fields_field_fullname protoreflect.FullName = "google.protobuf.Struct.fields" +) + +// Field numbers for google.protobuf.Struct. +const ( + Struct_Fields_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.Struct.FieldsEntry. +const ( + Struct_FieldsEntry_message_name protoreflect.Name = "FieldsEntry" + Struct_FieldsEntry_message_fullname protoreflect.FullName = "google.protobuf.Struct.FieldsEntry" +) + +// Field names for google.protobuf.Struct.FieldsEntry. +const ( + Struct_FieldsEntry_Key_field_name protoreflect.Name = "key" + Struct_FieldsEntry_Value_field_name protoreflect.Name = "value" + + Struct_FieldsEntry_Key_field_fullname protoreflect.FullName = "google.protobuf.Struct.FieldsEntry.key" + Struct_FieldsEntry_Value_field_fullname protoreflect.FullName = "google.protobuf.Struct.FieldsEntry.value" +) + +// Field numbers for google.protobuf.Struct.FieldsEntry. +const ( + Struct_FieldsEntry_Key_field_number protoreflect.FieldNumber = 1 + Struct_FieldsEntry_Value_field_number protoreflect.FieldNumber = 2 +) + +// Names for google.protobuf.Value. +const ( + Value_message_name protoreflect.Name = "Value" + Value_message_fullname protoreflect.FullName = "google.protobuf.Value" +) + +// Field names for google.protobuf.Value. +const ( + Value_NullValue_field_name protoreflect.Name = "null_value" + Value_NumberValue_field_name protoreflect.Name = "number_value" + Value_StringValue_field_name protoreflect.Name = "string_value" + Value_BoolValue_field_name protoreflect.Name = "bool_value" + Value_StructValue_field_name protoreflect.Name = "struct_value" + Value_ListValue_field_name protoreflect.Name = "list_value" + + Value_NullValue_field_fullname protoreflect.FullName = "google.protobuf.Value.null_value" + Value_NumberValue_field_fullname protoreflect.FullName = "google.protobuf.Value.number_value" + Value_StringValue_field_fullname protoreflect.FullName = "google.protobuf.Value.string_value" + Value_BoolValue_field_fullname protoreflect.FullName = "google.protobuf.Value.bool_value" + Value_StructValue_field_fullname protoreflect.FullName = "google.protobuf.Value.struct_value" + Value_ListValue_field_fullname protoreflect.FullName = "google.protobuf.Value.list_value" +) + +// Field numbers for google.protobuf.Value. +const ( + Value_NullValue_field_number protoreflect.FieldNumber = 1 + Value_NumberValue_field_number protoreflect.FieldNumber = 2 + Value_StringValue_field_number protoreflect.FieldNumber = 3 + Value_BoolValue_field_number protoreflect.FieldNumber = 4 + Value_StructValue_field_number protoreflect.FieldNumber = 5 + Value_ListValue_field_number protoreflect.FieldNumber = 6 +) + +// Oneof names for google.protobuf.Value. +const ( + Value_Kind_oneof_name protoreflect.Name = "kind" + + Value_Kind_oneof_fullname protoreflect.FullName = "google.protobuf.Value.kind" +) + +// Names for google.protobuf.ListValue. +const ( + ListValue_message_name protoreflect.Name = "ListValue" + ListValue_message_fullname protoreflect.FullName = "google.protobuf.ListValue" +) + +// Field names for google.protobuf.ListValue. +const ( + ListValue_Values_field_name protoreflect.Name = "values" + + ListValue_Values_field_fullname protoreflect.FullName = "google.protobuf.ListValue.values" +) + +// Field numbers for google.protobuf.ListValue. +const ( + ListValue_Values_field_number protoreflect.FieldNumber = 1 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go b/vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go new file mode 100644 index 000000000..f5cd5634c --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/timestamp_gen.go @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_timestamp_proto = "google/protobuf/timestamp.proto" + +// Names for google.protobuf.Timestamp. +const ( + Timestamp_message_name protoreflect.Name = "Timestamp" + Timestamp_message_fullname protoreflect.FullName = "google.protobuf.Timestamp" +) + +// Field names for google.protobuf.Timestamp. +const ( + Timestamp_Seconds_field_name protoreflect.Name = "seconds" + Timestamp_Nanos_field_name protoreflect.Name = "nanos" + + Timestamp_Seconds_field_fullname protoreflect.FullName = "google.protobuf.Timestamp.seconds" + Timestamp_Nanos_field_fullname protoreflect.FullName = "google.protobuf.Timestamp.nanos" +) + +// Field numbers for google.protobuf.Timestamp. +const ( + Timestamp_Seconds_field_number protoreflect.FieldNumber = 1 + Timestamp_Nanos_field_number protoreflect.FieldNumber = 2 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/type_gen.go b/vendor/google.golang.org/protobuf/internal/genid/type_gen.go new file mode 100644 index 000000000..3bc710138 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/type_gen.go @@ -0,0 +1,184 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_type_proto = "google/protobuf/type.proto" + +// Full and short names for google.protobuf.Syntax. +const ( + Syntax_enum_fullname = "google.protobuf.Syntax" + Syntax_enum_name = "Syntax" +) + +// Names for google.protobuf.Type. +const ( + Type_message_name protoreflect.Name = "Type" + Type_message_fullname protoreflect.FullName = "google.protobuf.Type" +) + +// Field names for google.protobuf.Type. +const ( + Type_Name_field_name protoreflect.Name = "name" + Type_Fields_field_name protoreflect.Name = "fields" + Type_Oneofs_field_name protoreflect.Name = "oneofs" + Type_Options_field_name protoreflect.Name = "options" + Type_SourceContext_field_name protoreflect.Name = "source_context" + Type_Syntax_field_name protoreflect.Name = "syntax" + + Type_Name_field_fullname protoreflect.FullName = "google.protobuf.Type.name" + Type_Fields_field_fullname protoreflect.FullName = "google.protobuf.Type.fields" + Type_Oneofs_field_fullname protoreflect.FullName = "google.protobuf.Type.oneofs" + Type_Options_field_fullname protoreflect.FullName = "google.protobuf.Type.options" + Type_SourceContext_field_fullname protoreflect.FullName = "google.protobuf.Type.source_context" + Type_Syntax_field_fullname protoreflect.FullName = "google.protobuf.Type.syntax" +) + +// Field numbers for google.protobuf.Type. +const ( + Type_Name_field_number protoreflect.FieldNumber = 1 + Type_Fields_field_number protoreflect.FieldNumber = 2 + Type_Oneofs_field_number protoreflect.FieldNumber = 3 + Type_Options_field_number protoreflect.FieldNumber = 4 + Type_SourceContext_field_number protoreflect.FieldNumber = 5 + Type_Syntax_field_number protoreflect.FieldNumber = 6 +) + +// Names for google.protobuf.Field. +const ( + Field_message_name protoreflect.Name = "Field" + Field_message_fullname protoreflect.FullName = "google.protobuf.Field" +) + +// Field names for google.protobuf.Field. +const ( + Field_Kind_field_name protoreflect.Name = "kind" + Field_Cardinality_field_name protoreflect.Name = "cardinality" + Field_Number_field_name protoreflect.Name = "number" + Field_Name_field_name protoreflect.Name = "name" + Field_TypeUrl_field_name protoreflect.Name = "type_url" + Field_OneofIndex_field_name protoreflect.Name = "oneof_index" + Field_Packed_field_name protoreflect.Name = "packed" + Field_Options_field_name protoreflect.Name = "options" + Field_JsonName_field_name protoreflect.Name = "json_name" + Field_DefaultValue_field_name protoreflect.Name = "default_value" + + Field_Kind_field_fullname protoreflect.FullName = "google.protobuf.Field.kind" + Field_Cardinality_field_fullname protoreflect.FullName = "google.protobuf.Field.cardinality" + Field_Number_field_fullname protoreflect.FullName = "google.protobuf.Field.number" + Field_Name_field_fullname protoreflect.FullName = "google.protobuf.Field.name" + Field_TypeUrl_field_fullname protoreflect.FullName = "google.protobuf.Field.type_url" + Field_OneofIndex_field_fullname protoreflect.FullName = "google.protobuf.Field.oneof_index" + Field_Packed_field_fullname protoreflect.FullName = "google.protobuf.Field.packed" + Field_Options_field_fullname protoreflect.FullName = "google.protobuf.Field.options" + Field_JsonName_field_fullname protoreflect.FullName = "google.protobuf.Field.json_name" + Field_DefaultValue_field_fullname protoreflect.FullName = "google.protobuf.Field.default_value" +) + +// Field numbers for google.protobuf.Field. +const ( + Field_Kind_field_number protoreflect.FieldNumber = 1 + Field_Cardinality_field_number protoreflect.FieldNumber = 2 + Field_Number_field_number protoreflect.FieldNumber = 3 + Field_Name_field_number protoreflect.FieldNumber = 4 + Field_TypeUrl_field_number protoreflect.FieldNumber = 6 + Field_OneofIndex_field_number protoreflect.FieldNumber = 7 + Field_Packed_field_number protoreflect.FieldNumber = 8 + Field_Options_field_number protoreflect.FieldNumber = 9 + Field_JsonName_field_number protoreflect.FieldNumber = 10 + Field_DefaultValue_field_number protoreflect.FieldNumber = 11 +) + +// Full and short names for google.protobuf.Field.Kind. +const ( + Field_Kind_enum_fullname = "google.protobuf.Field.Kind" + Field_Kind_enum_name = "Kind" +) + +// Full and short names for google.protobuf.Field.Cardinality. +const ( + Field_Cardinality_enum_fullname = "google.protobuf.Field.Cardinality" + Field_Cardinality_enum_name = "Cardinality" +) + +// Names for google.protobuf.Enum. +const ( + Enum_message_name protoreflect.Name = "Enum" + Enum_message_fullname protoreflect.FullName = "google.protobuf.Enum" +) + +// Field names for google.protobuf.Enum. +const ( + Enum_Name_field_name protoreflect.Name = "name" + Enum_Enumvalue_field_name protoreflect.Name = "enumvalue" + Enum_Options_field_name protoreflect.Name = "options" + Enum_SourceContext_field_name protoreflect.Name = "source_context" + Enum_Syntax_field_name protoreflect.Name = "syntax" + + Enum_Name_field_fullname protoreflect.FullName = "google.protobuf.Enum.name" + Enum_Enumvalue_field_fullname protoreflect.FullName = "google.protobuf.Enum.enumvalue" + Enum_Options_field_fullname protoreflect.FullName = "google.protobuf.Enum.options" + Enum_SourceContext_field_fullname protoreflect.FullName = "google.protobuf.Enum.source_context" + Enum_Syntax_field_fullname protoreflect.FullName = "google.protobuf.Enum.syntax" +) + +// Field numbers for google.protobuf.Enum. +const ( + Enum_Name_field_number protoreflect.FieldNumber = 1 + Enum_Enumvalue_field_number protoreflect.FieldNumber = 2 + Enum_Options_field_number protoreflect.FieldNumber = 3 + Enum_SourceContext_field_number protoreflect.FieldNumber = 4 + Enum_Syntax_field_number protoreflect.FieldNumber = 5 +) + +// Names for google.protobuf.EnumValue. +const ( + EnumValue_message_name protoreflect.Name = "EnumValue" + EnumValue_message_fullname protoreflect.FullName = "google.protobuf.EnumValue" +) + +// Field names for google.protobuf.EnumValue. +const ( + EnumValue_Name_field_name protoreflect.Name = "name" + EnumValue_Number_field_name protoreflect.Name = "number" + EnumValue_Options_field_name protoreflect.Name = "options" + + EnumValue_Name_field_fullname protoreflect.FullName = "google.protobuf.EnumValue.name" + EnumValue_Number_field_fullname protoreflect.FullName = "google.protobuf.EnumValue.number" + EnumValue_Options_field_fullname protoreflect.FullName = "google.protobuf.EnumValue.options" +) + +// Field numbers for google.protobuf.EnumValue. +const ( + EnumValue_Name_field_number protoreflect.FieldNumber = 1 + EnumValue_Number_field_number protoreflect.FieldNumber = 2 + EnumValue_Options_field_number protoreflect.FieldNumber = 3 +) + +// Names for google.protobuf.Option. +const ( + Option_message_name protoreflect.Name = "Option" + Option_message_fullname protoreflect.FullName = "google.protobuf.Option" +) + +// Field names for google.protobuf.Option. +const ( + Option_Name_field_name protoreflect.Name = "name" + Option_Value_field_name protoreflect.Name = "value" + + Option_Name_field_fullname protoreflect.FullName = "google.protobuf.Option.name" + Option_Value_field_fullname protoreflect.FullName = "google.protobuf.Option.value" +) + +// Field numbers for google.protobuf.Option. +const ( + Option_Name_field_number protoreflect.FieldNumber = 1 + Option_Value_field_number protoreflect.FieldNumber = 2 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/wrappers.go b/vendor/google.golang.org/protobuf/internal/genid/wrappers.go new file mode 100644 index 000000000..429384b85 --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/wrappers.go @@ -0,0 +1,13 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package genid + +import protoreflect "google.golang.org/protobuf/reflect/protoreflect" + +// Generic field name and number for messages in wrappers.proto. +const ( + WrapperValue_Value_field_name protoreflect.Name = "value" + WrapperValue_Value_field_number protoreflect.FieldNumber = 1 +) diff --git a/vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go b/vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go new file mode 100644 index 000000000..72527d2ab --- /dev/null +++ b/vendor/google.golang.org/protobuf/internal/genid/wrappers_gen.go @@ -0,0 +1,175 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Code generated by generate-protos. DO NOT EDIT. + +package genid + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" +) + +const File_google_protobuf_wrappers_proto = "google/protobuf/wrappers.proto" + +// Names for google.protobuf.DoubleValue. +const ( + DoubleValue_message_name protoreflect.Name = "DoubleValue" + DoubleValue_message_fullname protoreflect.FullName = "google.protobuf.DoubleValue" +) + +// Field names for google.protobuf.DoubleValue. +const ( + DoubleValue_Value_field_name protoreflect.Name = "value" + + DoubleValue_Value_field_fullname protoreflect.FullName = "google.protobuf.DoubleValue.value" +) + +// Field numbers for google.protobuf.DoubleValue. +const ( + DoubleValue_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.FloatValue. +const ( + FloatValue_message_name protoreflect.Name = "FloatValue" + FloatValue_message_fullname protoreflect.FullName = "google.protobuf.FloatValue" +) + +// Field names for google.protobuf.FloatValue. +const ( + FloatValue_Value_field_name protoreflect.Name = "value" + + FloatValue_Value_field_fullname protoreflect.FullName = "google.protobuf.FloatValue.value" +) + +// Field numbers for google.protobuf.FloatValue. +const ( + FloatValue_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.Int64Value. +const ( + Int64Value_message_name protoreflect.Name = "Int64Value" + Int64Value_message_fullname protoreflect.FullName = "google.protobuf.Int64Value" +) + +// Field names for google.protobuf.Int64Value. +const ( + Int64Value_Value_field_name protoreflect.Name = "value" + + Int64Value_Value_field_fullname protoreflect.FullName = "google.protobuf.Int64Value.value" +) + +// Field numbers for google.protobuf.Int64Value. +const ( + Int64Value_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.UInt64Value. +const ( + UInt64Value_message_name protoreflect.Name = "UInt64Value" + UInt64Value_message_fullname protoreflect.FullName = "google.protobuf.UInt64Value" +) + +// Field names for google.protobuf.UInt64Value. +const ( + UInt64Value_Value_field_name protoreflect.Name = "value" + + UInt64Value_Value_field_fullname protoreflect.FullName = "google.protobuf.UInt64Value.value" +) + +// Field numbers for google.protobuf.UInt64Value. +const ( + UInt64Value_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.Int32Value. +const ( + Int32Value_message_name protoreflect.Name = "Int32Value" + Int32Value_message_fullname protoreflect.FullName = "google.protobuf.Int32Value" +) + +// Field names for google.protobuf.Int32Value. +const ( + Int32Value_Value_field_name protoreflect.Name = "value" + + Int32Value_Value_field_fullname protoreflect.FullName = "google.protobuf.Int32Value.value" +) + +// Field numbers for google.protobuf.Int32Value. +const ( + Int32Value_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.UInt32Value. +const ( + UInt32Value_message_name protoreflect.Name = "UInt32Value" + UInt32Value_message_fullname protoreflect.FullName = "google.protobuf.UInt32Value" +) + +// Field names for google.protobuf.UInt32Value. +const ( + UInt32Value_Value_field_name protoreflect.Name = "value" + + UInt32Value_Value_field_fullname protoreflect.FullName = "google.protobuf.UInt32Value.value" +) + +// Field numbers for google.protobuf.UInt32Value. +const ( + UInt32Value_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.BoolValue. +const ( + BoolValue_message_name protoreflect.Name = "BoolValue" + BoolValue_message_fullname protoreflect.FullName = "google.protobuf.BoolValue" +) + +// Field names for google.protobuf.BoolValue. +const ( + BoolValue_Value_field_name protoreflect.Name = "value" + + BoolValue_Value_field_fullname protoreflect.FullName = "google.protobuf.BoolValue.value" +) + +// Field numbers for google.protobuf.BoolValue. +const ( + BoolValue_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.StringValue. +const ( + StringValue_message_name protoreflect.Name = "StringValue" + StringValue_message_fullname protoreflect.FullName = "google.protobuf.StringValue" +) + +// Field names for google.protobuf.StringValue. +const ( + StringValue_Value_field_name protoreflect.Name = "value" + + StringValue_Value_field_fullname protoreflect.FullName = "google.protobuf.StringValue.value" +) + +// Field numbers for google.protobuf.StringValue. +const ( + StringValue_Value_field_number protoreflect.FieldNumber = 1 +) + +// Names for google.protobuf.BytesValue. +const ( + BytesValue_message_name protoreflect.Name = "BytesValue" + BytesValue_message_fullname protoreflect.FullName = "google.protobuf.BytesValue" +) + +// Field names for google.protobuf.BytesValue. +const ( + BytesValue_Value_field_name protoreflect.Name = "value" + + BytesValue_Value_field_fullname protoreflect.FullName = "google.protobuf.BytesValue.value" +) + +// Field numbers for google.protobuf.BytesValue. +const ( + BytesValue_Value_field_number protoreflect.FieldNumber = 1 +) diff --git a/vendor/google.golang.org/protobuf/internal/genname/name.go b/vendor/google.golang.org/protobuf/internal/genname/name.go deleted file mode 100644 index f45509fbd..000000000 --- a/vendor/google.golang.org/protobuf/internal/genname/name.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package genname contains constants for generated names. -package genname - -const ( - State = "state" - - SizeCache = "sizeCache" - SizeCacheA = "XXX_sizecache" - - WeakFields = "weakFields" - WeakFieldsA = "XXX_weak" - - UnknownFields = "unknownFields" - UnknownFieldsA = "XXX_unrecognized" - - ExtensionFields = "extensionFields" - ExtensionFieldsA = "XXX_InternalExtensions" - ExtensionFieldsB = "XXX_extensions" - - WeakFieldPrefix = "XXX_weak_" -) diff --git a/vendor/google.golang.org/protobuf/internal/impl/api_export.go b/vendor/google.golang.org/protobuf/internal/impl/api_export.go index 4d22c9604..b5974528d 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/api_export.go +++ b/vendor/google.golang.org/protobuf/internal/impl/api_export.go @@ -10,6 +10,7 @@ import ( "strconv" "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/proto" pref "google.golang.org/protobuf/reflect/protoreflect" piface "google.golang.org/protobuf/runtime/protoiface" @@ -19,6 +20,12 @@ import ( // functions that we do not want to appear in godoc. type Export struct{} +// NewError formats a string according to the format specifier and arguments and +// returns an error that has a "proto" prefix. +func (Export) NewError(f string, x ...interface{}) error { + return errors.New(f, x...) +} + // enum is any enum type generated by protoc-gen-go // and must be a named int32 type. type enum = interface{} diff --git a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go index 35a67c25b..44885a761 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/codec_map.go +++ b/vendor/google.golang.org/protobuf/internal/impl/codec_map.go @@ -10,6 +10,7 @@ import ( "sort" "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/internal/genid" pref "google.golang.org/protobuf/reflect/protoreflect" ) @@ -134,7 +135,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo b = b[n:] err := errUnknown switch num { - case 1: + case genid.MapEntry_Key_field_number: var v pref.Value var o unmarshalOutput v, o, err = mapi.keyFuncs.unmarshal(b, key, num, wtyp, opts) @@ -143,7 +144,7 @@ func consumeMap(b []byte, mapv reflect.Value, wtyp protowire.Type, mapi *mapInfo } key = v n = o.n - case 2: + case genid.MapEntry_Value_field_number: var v pref.Value var o unmarshalOutput v, o, err = mapi.valFuncs.unmarshal(b, val, num, wtyp, opts) diff --git a/vendor/google.golang.org/protobuf/internal/impl/message.go b/vendor/google.golang.org/protobuf/internal/impl/message.go index 7dd994bd9..c026a9818 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/message.go +++ b/vendor/google.golang.org/protobuf/internal/impl/message.go @@ -12,7 +12,7 @@ import ( "sync" "sync/atomic" - "google.golang.org/protobuf/internal/genname" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/reflect/protoreflect" pref "google.golang.org/protobuf/reflect/protoreflect" ) @@ -148,19 +148,19 @@ func (mi *MessageInfo) makeStructInfo(t reflect.Type) structInfo { fieldLoop: for i := 0; i < t.NumField(); i++ { switch f := t.Field(i); f.Name { - case genname.SizeCache, genname.SizeCacheA: + case genid.SizeCache_goname, genid.SizeCacheA_goname: if f.Type == sizecacheType { si.sizecacheOffset = offsetOf(f, mi.Exporter) } - case genname.WeakFields, genname.WeakFieldsA: + case genid.WeakFields_goname, genid.WeakFieldsA_goname: if f.Type == weakFieldsType { si.weakOffset = offsetOf(f, mi.Exporter) } - case genname.UnknownFields, genname.UnknownFieldsA: + case genid.UnknownFields_goname, genid.UnknownFieldsA_goname: if f.Type == unknownFieldsType { si.unknownOffset = offsetOf(f, mi.Exporter) } - case genname.ExtensionFields, genname.ExtensionFieldsA, genname.ExtensionFieldsB: + case genid.ExtensionFields_goname, genid.ExtensionFieldsA_goname, genid.ExtensionFieldsB_goname: if f.Type == extensionFieldsType { si.extensionOffset = offsetOf(f, mi.Exporter) } diff --git a/vendor/google.golang.org/protobuf/internal/impl/validate.go b/vendor/google.golang.org/protobuf/internal/impl/validate.go index 57de9cc85..08cfb6054 100644 --- a/vendor/google.golang.org/protobuf/internal/impl/validate.go +++ b/vendor/google.golang.org/protobuf/internal/impl/validate.go @@ -14,6 +14,7 @@ import ( "google.golang.org/protobuf/encoding/protowire" "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/flags" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" pref "google.golang.org/protobuf/reflect/protoreflect" preg "google.golang.org/protobuf/reflect/protoregistry" @@ -282,9 +283,9 @@ State: switch { case st.typ == validationTypeMap: switch num { - case 1: + case genid.MapEntry_Key_field_number: vi.typ = st.keyType - case 2: + case genid.MapEntry_Value_field_number: vi.typ = st.valType vi.mi = st.mi vi.requiredBit = 1 diff --git a/vendor/google.golang.org/protobuf/internal/version/version.go b/vendor/google.golang.org/protobuf/internal/version/version.go index 6b3001c66..72cf770b4 100644 --- a/vendor/google.golang.org/protobuf/internal/version/version.go +++ b/vendor/google.golang.org/protobuf/internal/version/version.go @@ -52,7 +52,7 @@ import ( // 10. Send out the CL for review and submit it. const ( Major = 1 - Minor = 24 + Minor = 25 Patch = 0 PreRelease = "" ) diff --git a/vendor/google.golang.org/protobuf/proto/decode.go b/vendor/google.golang.org/protobuf/proto/decode.go index 4974b16d5..42fc5195e 100644 --- a/vendor/google.golang.org/protobuf/proto/decode.go +++ b/vendor/google.golang.org/protobuf/proto/decode.go @@ -9,6 +9,7 @@ import ( "google.golang.org/protobuf/internal/encoding/messageset" "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/flags" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/pragma" "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/reflect/protoregistry" @@ -220,13 +221,13 @@ func (o UnmarshalOptions) unmarshalMap(b []byte, wtyp protowire.Type, mapv proto b = b[n:] err = errUnknown switch num { - case 1: + case genid.MapEntry_Key_field_number: key, n, err = o.unmarshalScalar(b, wtyp, keyField) if err != nil { break } haveKey = true - case 2: + case genid.MapEntry_Value_field_number: var v protoreflect.Value v, n, err = o.unmarshalScalar(b, wtyp, valField) if err != nil { diff --git a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go index cf9641ab9..2d5fa9936 100644 --- a/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go +++ b/vendor/google.golang.org/protobuf/reflect/protodesc/desc_validate.go @@ -12,6 +12,7 @@ import ( "google.golang.org/protobuf/internal/errors" "google.golang.org/protobuf/internal/filedesc" "google.golang.org/protobuf/internal/flags" + "google.golang.org/protobuf/internal/genid" "google.golang.org/protobuf/internal/strs" "google.golang.org/protobuf/reflect/protoreflect" @@ -348,9 +349,9 @@ func checkValidMap(fd protoreflect.FieldDescriptor) error { kf := md.Fields().Get(0) vf := md.Fields().Get(1) switch { - case kf.Name() != "key" || kf.Number() != 1 || kf.Cardinality() != protoreflect.Optional || kf.ContainingOneof() != nil || kf.HasDefault(): + case kf.Name() != genid.MapEntry_Key_field_name || kf.Number() != genid.MapEntry_Key_field_number || kf.Cardinality() != protoreflect.Optional || kf.ContainingOneof() != nil || kf.HasDefault(): return errors.New("invalid key field") - case vf.Name() != "value" || vf.Number() != 2 || vf.Cardinality() != protoreflect.Optional || vf.ContainingOneof() != nil || vf.HasDefault(): + case vf.Name() != genid.MapEntry_Value_field_name || vf.Number() != genid.MapEntry_Value_field_number || vf.Cardinality() != protoreflect.Optional || vf.ContainingOneof() != nil || vf.HasDefault(): return errors.New("invalid value field") } switch kf.Kind() { diff --git a/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go index b669a4e76..dd85915bd 100644 --- a/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go +++ b/vendor/google.golang.org/protobuf/reflect/protoreflect/proto.go @@ -128,7 +128,6 @@ package protoreflect import ( "fmt" - "regexp" "strings" "google.golang.org/protobuf/encoding/protowire" @@ -408,19 +407,14 @@ type EnumRanges interface { doNotImplement } -var ( - regexName = regexp.MustCompile(`^[_a-zA-Z][_a-zA-Z0-9]*$`) - regexFullName = regexp.MustCompile(`^[_a-zA-Z][_a-zA-Z0-9]*(\.[_a-zA-Z][_a-zA-Z0-9]*)*$`) -) - // Name is the short name for a proto declaration. This is not the name // as used in Go source code, which might not be identical to the proto name. type Name string // e.g., "Kind" -// IsValid reports whether n is a syntactically valid name. +// IsValid reports whether s is a syntactically valid name. // An empty name is invalid. -func (n Name) IsValid() bool { - return regexName.MatchString(string(n)) +func (s Name) IsValid() bool { + return consumeIdent(string(s)) == len(s) } // Names represent a list of names. @@ -443,10 +437,42 @@ type Names interface { // This should not have any leading or trailing dots. type FullName string // e.g., "google.protobuf.Field.Kind" -// IsValid reports whether n is a syntactically valid full name. +// IsValid reports whether s is a syntactically valid full name. // An empty full name is invalid. -func (n FullName) IsValid() bool { - return regexFullName.MatchString(string(n)) +func (s FullName) IsValid() bool { + i := consumeIdent(string(s)) + if i < 0 { + return false + } + for len(s) > i { + if s[i] != '.' { + return false + } + i++ + n := consumeIdent(string(s[i:])) + if n < 0 { + return false + } + i += n + } + return true +} + +func consumeIdent(s string) (i int) { + if len(s) == 0 || !isLetter(s[i]) { + return -1 + } + i++ + for len(s) > i && isLetterDigit(s[i]) { + i++ + } + return i +} +func isLetter(c byte) bool { + return c == '_' || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') +} +func isLetterDigit(c byte) bool { + return isLetter(c) || ('0' <= c && c <= '9') } // Name returns the short name, which is the last identifier segment. diff --git a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go index 5f9498e4e..82a473e26 100644 --- a/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/anypb/any.pb.go @@ -31,12 +31,100 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/any.proto +// Package anypb contains generated types for google/protobuf/any.proto. +// +// The Any message is a dynamic representation of any other message value. +// It is functionally a tuple of the full name of the remote message type and +// the serialized bytes of the remote message value. +// +// +// Constructing an Any +// +// An Any message containing another message value is constructed using New: +// +// any, err := anypb.New(m) +// if err != nil { +// ... // handle error +// } +// ... // make use of any +// +// +// Unmarshaling an Any +// +// With a populated Any message, the underlying message can be serialized into +// a remote concrete message value in a few ways. +// +// If the exact concrete type is known, then a new (or pre-existing) instance +// of that message can be passed to the UnmarshalTo method: +// +// m := new(foopb.MyMessage) +// if err := any.UnmarshalTo(m); err != nil { +// ... // handle error +// } +// ... // make use of m +// +// If the exact concrete type is not known, then the UnmarshalNew method can be +// used to unmarshal the contents into a new instance of the remote message type: +// +// m, err := any.UnmarshalNew() +// if err != nil { +// ... // handle error +// } +// ... // make use of m +// +// UnmarshalNew uses the global type registry to resolve the message type and +// construct a new instance of that message to unmarshal into. In order for a +// message type to appear in the global registry, the Go type representing that +// protobuf message type must be linked into the Go binary. For messages +// generated by protoc-gen-go, this is achieved through an import of the +// generated Go package representing a .proto file. +// +// A common pattern with UnmarshalNew is to use a type switch with the resulting +// proto.Message value: +// +// switch m := m.(type) { +// case *foopb.MyMessage: +// ... // make use of m as a *foopb.MyMessage +// case *barpb.OtherMessage: +// ... // make use of m as a *barpb.OtherMessage +// case *bazpb.SomeMessage: +// ... // make use of m as a *bazpb.SomeMessage +// } +// +// This pattern ensures that the generated packages containing the message types +// listed in the case clauses are linked into the Go binary and therefore also +// registered in the global registry. +// +// +// Type checking an Any +// +// In order to type check whether an Any message represents some other message, +// then use the MessageIs method: +// +// if any.MessageIs((*foopb.MyMessage)(nil)) { +// ... // make use of any, knowing that it contains a foopb.MyMessage +// } +// +// The MessageIs method can also be used with an allocated instance of the target +// message type if the intention is to unmarshal into it if the type matches: +// +// m := new(foopb.MyMessage) +// if any.MessageIs(m) { +// if err := any.UnmarshalTo(m); err != nil { +// ... // handle error +// } +// ... // make use of m +// } +// package anypb import ( + proto "google.golang.org/protobuf/proto" protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoregistry "google.golang.org/protobuf/reflect/protoregistry" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" + strings "strings" sync "sync" ) @@ -158,6 +246,125 @@ type Any struct { Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` } +// New marshals src into a new Any instance. +func New(src proto.Message) (*Any, error) { + dst := new(Any) + if err := dst.MarshalFrom(src); err != nil { + return nil, err + } + return dst, nil +} + +// MarshalFrom marshals src into dst as the underlying message +// using the provided marshal options. +// +// If no options are specified, call dst.MarshalFrom instead. +func MarshalFrom(dst *Any, src proto.Message, opts proto.MarshalOptions) error { + const urlPrefix = "type.googleapis.com/" + if src == nil { + return protoimpl.X.NewError("invalid nil source message") + } + b, err := opts.Marshal(src) + if err != nil { + return err + } + dst.TypeUrl = urlPrefix + string(src.ProtoReflect().Descriptor().FullName()) + dst.Value = b + return nil +} + +// UnmarshalTo unmarshals the underlying message from src into dst +// using the provided unmarshal options. +// It reports an error if dst is not of the right message type. +// +// If no options are specified, call src.UnmarshalTo instead. +func UnmarshalTo(src *Any, dst proto.Message, opts proto.UnmarshalOptions) error { + if src == nil { + return protoimpl.X.NewError("invalid nil source message") + } + if !src.MessageIs(dst) { + got := dst.ProtoReflect().Descriptor().FullName() + want := src.MessageName() + return protoimpl.X.NewError("mismatched message type: got %q, want %q", got, want) + } + return opts.Unmarshal(src.GetValue(), dst) +} + +// UnmarshalNew unmarshals the underlying message from src into dst, +// which is newly created message using a type resolved from the type URL. +// The message type is resolved according to opt.Resolver, +// which should implement protoregistry.MessageTypeResolver. +// It reports an error if the underlying message type could not be resolved. +// +// If no options are specified, call src.UnmarshalNew instead. +func UnmarshalNew(src *Any, opts proto.UnmarshalOptions) (dst proto.Message, err error) { + if src.GetTypeUrl() == "" { + return nil, protoimpl.X.NewError("invalid empty type URL") + } + if opts.Resolver == nil { + opts.Resolver = protoregistry.GlobalTypes + } + r, ok := opts.Resolver.(protoregistry.MessageTypeResolver) + if !ok { + return nil, protoregistry.NotFound + } + mt, err := r.FindMessageByURL(src.GetTypeUrl()) + if err != nil { + if err == protoregistry.NotFound { + return nil, err + } + return nil, protoimpl.X.NewError("could not resolve %q: %v", src.GetTypeUrl(), err) + } + dst = mt.New().Interface() + return dst, opts.Unmarshal(src.GetValue(), dst) +} + +// MessageIs reports whether the underlying message is of the same type as m. +func (x *Any) MessageIs(m proto.Message) bool { + if m == nil { + return false + } + url := x.GetTypeUrl() + name := string(m.ProtoReflect().Descriptor().FullName()) + if !strings.HasSuffix(url, name) { + return false + } + return len(url) == len(name) || url[len(url)-len(name)-1] == '/' +} + +// MessageName reports the full name of the underlying message, +// returning an empty string if invalid. +func (x *Any) MessageName() protoreflect.FullName { + url := x.GetTypeUrl() + name := protoreflect.FullName(url) + if i := strings.LastIndexByte(url, '/'); i >= 0 { + name = name[i+len("/"):] + } + if !name.IsValid() { + return "" + } + return name +} + +// MarshalFrom marshals m into x as the underlying message. +func (x *Any) MarshalFrom(m proto.Message) error { + return MarshalFrom(x, m, proto.MarshalOptions{}) +} + +// UnmarshalTo unmarshals the contents of the underlying message of x into m. +// It resets m before performing the unmarshal operation. +// It reports an error if m is not of the right message type. +func (x *Any) UnmarshalTo(m proto.Message) error { + return UnmarshalTo(x, m, proto.UnmarshalOptions{}) +} + +// UnmarshalNew unmarshals the contents of the underlying message of x into +// a newly allocated message of the specified type. +// It reports an error if the underlying message type could not be resolved. +func (x *Any) UnmarshalNew() (proto.Message, error) { + return UnmarshalNew(x, proto.UnmarshalOptions{}) +} + func (x *Any) Reset() { *x = Any{} if protoimpl.UnsafeEnabled { diff --git a/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go b/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go index 3997c604f..f7a110994 100644 --- a/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/durationpb/duration.pb.go @@ -31,13 +31,58 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/duration.proto +// Package durationpb contains generated types for google/protobuf/duration.proto. +// +// The Duration message represents a signed span of time. +// +// +// Conversion to a Go Duration +// +// The AsDuration method can be used to convert a Duration message to a +// standard Go time.Duration value: +// +// d := dur.AsDuration() +// ... // make use of d as a time.Duration +// +// Converting to a time.Duration is a common operation so that the extensive +// set of time-based operations provided by the time package can be leveraged. +// See https://golang.org/pkg/time for more information. +// +// The AsDuration method performs the conversion on a best-effort basis. +// Durations with denormal values (e.g., nanoseconds beyond -99999999 and +// +99999999, inclusive; or seconds and nanoseconds with opposite signs) +// are normalized during the conversion to a time.Duration. To manually check for +// invalid Duration per the documented limitations in duration.proto, +// additionally call the CheckValid method: +// +// if err := dur.CheckValid(); err != nil { +// ... // handle error +// } +// +// Note that the documented limitations in duration.proto does not protect a +// Duration from overflowing the representable range of a time.Duration in Go. +// The AsDuration method uses saturation arithmetic such that an overflow clamps +// the resulting value to the closest representable value (e.g., math.MaxInt64 +// for positive overflow and math.MinInt64 for negative overflow). +// +// +// Conversion from a Go Duration +// +// The durationpb.New function can be used to construct a Duration message +// from a standard Go time.Duration value: +// +// dur := durationpb.New(d) +// ... // make use of d as a *durationpb.Duration +// package durationpb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + math "math" reflect "reflect" sync "sync" + time "time" ) // A Duration represents a signed, fixed-length span of time represented @@ -118,6 +163,91 @@ type Duration struct { Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` } +// New constructs a new Duration from the provided time.Duration. +func New(d time.Duration) *Duration { + nanos := d.Nanoseconds() + secs := nanos / 1e9 + nanos -= secs * 1e9 + return &Duration{Seconds: int64(secs), Nanos: int32(nanos)} +} + +// AsDuration converts x to a time.Duration, +// returning the closest duration value in the event of overflow. +func (x *Duration) AsDuration() time.Duration { + secs := x.GetSeconds() + nanos := x.GetNanos() + d := time.Duration(secs) * time.Second + overflow := d/time.Second != time.Duration(secs) + d += time.Duration(nanos) * time.Nanosecond + overflow = overflow || (secs < 0 && nanos < 0 && d > 0) + overflow = overflow || (secs > 0 && nanos > 0 && d < 0) + if overflow { + switch { + case secs < 0: + return time.Duration(math.MinInt64) + case secs > 0: + return time.Duration(math.MaxInt64) + } + } + return d +} + +// IsValid reports whether the duration is valid. +// It is equivalent to CheckValid == nil. +func (x *Duration) IsValid() bool { + return x.check() == 0 +} + +// CheckValid returns an error if the duration is invalid. +// In particular, it checks whether the value is within the range of +// -10000 years to +10000 years inclusive. +// An error is reported for a nil Duration. +func (x *Duration) CheckValid() error { + switch x.check() { + case invalidNil: + return protoimpl.X.NewError("invalid nil Duration") + case invalidUnderflow: + return protoimpl.X.NewError("duration (%v) exceeds -10000 years", x) + case invalidOverflow: + return protoimpl.X.NewError("duration (%v) exceeds +10000 years", x) + case invalidNanosRange: + return protoimpl.X.NewError("duration (%v) has out-of-range nanos", x) + case invalidNanosSign: + return protoimpl.X.NewError("duration (%v) has seconds and nanos with different signs", x) + default: + return nil + } +} + +const ( + _ = iota + invalidNil + invalidUnderflow + invalidOverflow + invalidNanosRange + invalidNanosSign +) + +func (x *Duration) check() uint { + const absDuration = 315576000000 // 10000yr * 365.25day/yr * 24hr/day * 60min/hr * 60sec/min + secs := x.GetSeconds() + nanos := x.GetNanos() + switch { + case x == nil: + return invalidNil + case secs < -absDuration: + return invalidUnderflow + case secs > +absDuration: + return invalidOverflow + case nanos <= -1e9 || nanos >= +1e9: + return invalidNanosRange + case (secs > 0 && nanos < 0) || (secs < 0 && nanos > 0): + return invalidNanosSign + default: + return 0 + } +} + func (x *Duration) Reset() { *x = Duration{} if protoimpl.UnsafeEnabled { diff --git a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go index 6fe6d42f1..c25e4bd7d 100644 --- a/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go +++ b/vendor/google.golang.org/protobuf/types/known/timestamppb/timestamp.pb.go @@ -31,6 +31,48 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: google/protobuf/timestamp.proto +// Package timestamppb contains generated types for google/protobuf/timestamp.proto. +// +// The Timestamp message represents a timestamp, +// an instant in time since the Unix epoch (January 1st, 1970). +// +// +// Conversion to a Go Time +// +// The AsTime method can be used to convert a Timestamp message to a +// standard Go time.Time value in UTC: +// +// t := ts.AsTime() +// ... // make use of t as a time.Time +// +// Converting to a time.Time is a common operation so that the extensive +// set of time-based operations provided by the time package can be leveraged. +// See https://golang.org/pkg/time for more information. +// +// The AsTime method performs the conversion on a best-effort basis. Timestamps +// with denormal values (e.g., nanoseconds beyond 0 and 99999999, inclusive) +// are normalized during the conversion to a time.Time. To manually check for +// invalid Timestamps per the documented limitations in timestamp.proto, +// additionally call the CheckValid method: +// +// if err := ts.CheckValid(); err != nil { +// ... // handle error +// } +// +// +// Conversion from a Go Time +// +// The timestamppb.New function can be used to construct a Timestamp message +// from a standard Go time.Time value: +// +// ts := timestamppb.New(t) +// ... // make use of ts as a *timestamppb.Timestamp +// +// In order to construct a Timestamp representing the current time, use Now: +// +// ts := timestamppb.Now() +// ... // make use of ts as a *timestamppb.Timestamp +// package timestamppb import ( @@ -38,6 +80,7 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" + time "time" ) // A Timestamp represents a point in time independent of any time zone or local @@ -140,6 +183,73 @@ type Timestamp struct { Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` } +// Now constructs a new Timestamp from the current time. +func Now() *Timestamp { + return New(time.Now()) +} + +// New constructs a new Timestamp from the provided time.Time. +func New(t time.Time) *Timestamp { + return &Timestamp{Seconds: int64(t.Unix()), Nanos: int32(t.Nanosecond())} +} + +// AsTime converts x to a time.Time. +func (x *Timestamp) AsTime() time.Time { + return time.Unix(int64(x.GetSeconds()), int64(x.GetNanos())).UTC() +} + +// IsValid reports whether the timestamp is valid. +// It is equivalent to CheckValid == nil. +func (x *Timestamp) IsValid() bool { + return x.check() == 0 +} + +// CheckValid returns an error if the timestamp is invalid. +// In particular, it checks whether the value represents a date that is +// in the range of 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. +// An error is reported for a nil Timestamp. +func (x *Timestamp) CheckValid() error { + switch x.check() { + case invalidNil: + return protoimpl.X.NewError("invalid nil Timestamp") + case invalidUnderflow: + return protoimpl.X.NewError("timestamp (%v) before 0001-01-01", x) + case invalidOverflow: + return protoimpl.X.NewError("timestamp (%v) after 9999-12-31", x) + case invalidNanos: + return protoimpl.X.NewError("timestamp (%v) has out-of-range nanos", x) + default: + return nil + } +} + +const ( + _ = iota + invalidNil + invalidUnderflow + invalidOverflow + invalidNanos +) + +func (x *Timestamp) check() uint { + const minTimestamp = -62135596800 // Seconds between 1970-01-01T00:00:00Z and 0001-01-01T00:00:00Z, inclusive + const maxTimestamp = +253402300799 // Seconds between 1970-01-01T00:00:00Z and 9999-12-31T23:59:59Z, inclusive + secs := x.GetSeconds() + nanos := x.GetNanos() + switch { + case x == nil: + return invalidNil + case secs < minTimestamp: + return invalidUnderflow + case secs > maxTimestamp: + return invalidOverflow + case nanos < 0 || nanos >= 1e9: + return invalidNanos + default: + return 0 + } +} + func (x *Timestamp) Reset() { *x = Timestamp{} if protoimpl.UnsafeEnabled { diff --git a/vendor/honnef.co/go/tools/LICENSE b/vendor/honnef.co/go/tools/LICENSE deleted file mode 100644 index dfd031454..000000000 --- a/vendor/honnef.co/go/tools/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2016 Dominik Honnef - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY b/vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY deleted file mode 100644 index 623d85e85..000000000 --- a/vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY +++ /dev/null @@ -1,284 +0,0 @@ -Staticcheck and its related tools make use of third party projects, -either by reusing their code, or by statically linking them into -resulting binaries. These projects are: - -* The Go Programming Language - https://golang.org/ - - Copyright (c) 2009 The Go Authors. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -* github.com/BurntSushi/toml - https://github.com/BurntSushi/toml - - The MIT License (MIT) - - Copyright (c) 2013 TOML authors - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - -* github.com/google/renameio - https://github.com/google/renameio - - Copyright 2018 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -* github.com/kisielk/gotool - https://github.com/kisielk/gotool - - Copyright (c) 2013 Kamil Kisiel - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - All the files in this distribution are covered under either the MIT - license (see the file LICENSE) except some files mentioned below. - - match.go, match_test.go: - - Copyright (c) 2009 The Go Authors. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -* github.com/rogpeppe/go-internal - https://github.com/rogpeppe/go-internal - - Copyright (c) 2018 The Go Authors. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -* golang.org/x/mod/module - https://github.com/golang/mod - - Copyright (c) 2009 The Go Authors. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -* golang.org/x/tools/go/analysis - https://github.com/golang/tools - - Copyright (c) 2009 The Go Authors. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of Google Inc. nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -* gogrep - https://github.com/mvdan/gogrep - - Copyright (c) 2017, Daniel Martí. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -* gosmith - https://github.com/dvyukov/gosmith - - Copyright (c) 2014 Dmitry Vyukov. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - * The name of Dmitry Vyukov may be used to endorse or promote - products derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/honnef.co/go/tools/arg/arg.go b/vendor/honnef.co/go/tools/arg/arg.go deleted file mode 100644 index 1e7f30db4..000000000 --- a/vendor/honnef.co/go/tools/arg/arg.go +++ /dev/null @@ -1,48 +0,0 @@ -package arg - -var args = map[string]int{ - "(*encoding/json.Decoder).Decode.v": 0, - "(*encoding/json.Encoder).Encode.v": 0, - "(*encoding/xml.Decoder).Decode.v": 0, - "(*encoding/xml.Encoder).Encode.v": 0, - "(*sync.Pool).Put.x": 0, - "(*text/template.Template).Parse.text": 0, - "(io.Seeker).Seek.offset": 0, - "(time.Time).Sub.u": 0, - "append.elems": 1, - "append.slice": 0, - "bytes.Equal.a": 0, - "bytes.Equal.b": 1, - "encoding/binary.Write.data": 2, - "errors.New.text": 0, - "fmt.Fprintf.format": 1, - "fmt.Printf.format": 0, - "fmt.Sprintf.a[0]": 1, - "fmt.Sprintf.format": 0, - "json.Marshal.v": 0, - "json.Unmarshal.v": 1, - "len.v": 0, - "make.size[0]": 1, - "make.size[1]": 2, - "make.t": 0, - "net/url.Parse.rawurl": 0, - "os.OpenFile.flag": 1, - "os/exec.Command.name": 0, - "os/signal.Notify.c": 0, - "regexp.Compile.expr": 0, - "runtime.SetFinalizer.finalizer": 1, - "runtime.SetFinalizer.obj": 0, - "sort.Sort.data": 0, - "time.Parse.layout": 0, - "time.Sleep.d": 0, - "xml.Marshal.v": 0, - "xml.Unmarshal.v": 1, -} - -func Arg(name string) int { - n, ok := args[name] - if !ok { - panic("unknown argument " + name) - } - return n -} diff --git a/vendor/honnef.co/go/tools/cmd/staticcheck/README.md b/vendor/honnef.co/go/tools/cmd/staticcheck/README.md deleted file mode 100644 index 4d14577fd..000000000 --- a/vendor/honnef.co/go/tools/cmd/staticcheck/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# staticcheck - -_staticcheck_ offers extensive analysis of Go code, covering a myriad -of categories. It will detect bugs, suggest code simplifications, -point out dead code, and more. - -## Installation - -See [the main README](https://github.com/dominikh/go-tools#installation) for installation instructions. - -## Documentation - -Detailed documentation can be found on -[staticcheck.io](https://staticcheck.io/docs/). - diff --git a/vendor/honnef.co/go/tools/cmd/staticcheck/staticcheck.go b/vendor/honnef.co/go/tools/cmd/staticcheck/staticcheck.go deleted file mode 100644 index 4f504dc39..000000000 --- a/vendor/honnef.co/go/tools/cmd/staticcheck/staticcheck.go +++ /dev/null @@ -1,44 +0,0 @@ -// staticcheck analyses Go code and makes it better. -package main // import "honnef.co/go/tools/cmd/staticcheck" - -import ( - "log" - "os" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/lint" - "honnef.co/go/tools/lint/lintutil" - "honnef.co/go/tools/simple" - "honnef.co/go/tools/staticcheck" - "honnef.co/go/tools/stylecheck" - "honnef.co/go/tools/unused" -) - -func main() { - fs := lintutil.FlagSet("staticcheck") - wholeProgram := fs.Bool("unused.whole-program", false, "Run unused in whole program mode") - debug := fs.String("debug.unused-graph", "", "Write unused's object graph to `file`") - fs.Parse(os.Args[1:]) - - var cs []*analysis.Analyzer - for _, v := range simple.Analyzers { - cs = append(cs, v) - } - for _, v := range staticcheck.Analyzers { - cs = append(cs, v) - } - for _, v := range stylecheck.Analyzers { - cs = append(cs, v) - } - - u := unused.NewChecker(*wholeProgram) - if *debug != "" { - f, err := os.OpenFile(*debug, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) - if err != nil { - log.Fatal(err) - } - u.Debug = f - } - cums := []lint.CumulativeChecker{u} - lintutil.ProcessFlagSet(cs, cums, fs) -} diff --git a/vendor/honnef.co/go/tools/code/code.go b/vendor/honnef.co/go/tools/code/code.go deleted file mode 100644 index 6f4df8b9a..000000000 --- a/vendor/honnef.co/go/tools/code/code.go +++ /dev/null @@ -1,481 +0,0 @@ -// Package code answers structural and type questions about Go code. -package code - -import ( - "flag" - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" - "strings" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/analysis/passes/inspect" - "golang.org/x/tools/go/ast/astutil" - "golang.org/x/tools/go/ast/inspector" - "honnef.co/go/tools/facts" - "honnef.co/go/tools/go/types/typeutil" - "honnef.co/go/tools/ir" - "honnef.co/go/tools/lint" -) - -type Positioner interface { - Pos() token.Pos -} - -func CallName(call *ir.CallCommon) string { - if call.IsInvoke() { - return "" - } - switch v := call.Value.(type) { - case *ir.Function: - fn, ok := v.Object().(*types.Func) - if !ok { - return "" - } - return lint.FuncName(fn) - case *ir.Builtin: - return v.Name() - } - return "" -} - -func IsCallTo(call *ir.CallCommon, name string) bool { return CallName(call) == name } - -func IsCallToAny(call *ir.CallCommon, names ...string) bool { - q := CallName(call) - for _, name := range names { - if q == name { - return true - } - } - return false -} - -func IsType(T types.Type, name string) bool { return types.TypeString(T, nil) == name } - -func FilterDebug(instr []ir.Instruction) []ir.Instruction { - var out []ir.Instruction - for _, ins := range instr { - if _, ok := ins.(*ir.DebugRef); !ok { - out = append(out, ins) - } - } - return out -} - -func IsExample(fn *ir.Function) bool { - if !strings.HasPrefix(fn.Name(), "Example") { - return false - } - f := fn.Prog.Fset.File(fn.Pos()) - if f == nil { - return false - } - return strings.HasSuffix(f.Name(), "_test.go") -} - -func IsPointerLike(T types.Type) bool { - switch T := T.Underlying().(type) { - case *types.Interface, *types.Chan, *types.Map, *types.Signature, *types.Pointer: - return true - case *types.Basic: - return T.Kind() == types.UnsafePointer - } - return false -} - -func IsIdent(expr ast.Expr, ident string) bool { - id, ok := expr.(*ast.Ident) - return ok && id.Name == ident -} - -// isBlank returns whether id is the blank identifier "_". -// If id == nil, the answer is false. -func IsBlank(id ast.Expr) bool { - ident, _ := id.(*ast.Ident) - return ident != nil && ident.Name == "_" -} - -func IsIntLiteral(expr ast.Expr, literal string) bool { - lit, ok := expr.(*ast.BasicLit) - return ok && lit.Kind == token.INT && lit.Value == literal -} - -// Deprecated: use IsIntLiteral instead -func IsZero(expr ast.Expr) bool { - return IsIntLiteral(expr, "0") -} - -func IsOfType(pass *analysis.Pass, expr ast.Expr, name string) bool { - return IsType(pass.TypesInfo.TypeOf(expr), name) -} - -func IsInTest(pass *analysis.Pass, node Positioner) bool { - // FIXME(dh): this doesn't work for global variables with - // initializers - f := pass.Fset.File(node.Pos()) - return f != nil && strings.HasSuffix(f.Name(), "_test.go") -} - -// IsMain reports whether the package being processed is a package -// main. -func IsMain(pass *analysis.Pass) bool { - return pass.Pkg.Name() == "main" -} - -// IsMainLike reports whether the package being processed is a -// main-like package. A main-like package is a package that is -// package main, or that is intended to be used by a tool framework -// such as cobra to implement a command. -// -// Note that this function errs on the side of false positives; it may -// return true for packages that aren't main-like. IsMainLike is -// intended for analyses that wish to suppress diagnostics for -// main-like packages to avoid false positives. -func IsMainLike(pass *analysis.Pass) bool { - if pass.Pkg.Name() == "main" { - return true - } - for _, imp := range pass.Pkg.Imports() { - if imp.Path() == "github.com/spf13/cobra" { - return true - } - } - return false -} - -func SelectorName(pass *analysis.Pass, expr *ast.SelectorExpr) string { - info := pass.TypesInfo - sel := info.Selections[expr] - if sel == nil { - if x, ok := expr.X.(*ast.Ident); ok { - pkg, ok := info.ObjectOf(x).(*types.PkgName) - if !ok { - // This shouldn't happen - return fmt.Sprintf("%s.%s", x.Name, expr.Sel.Name) - } - return fmt.Sprintf("%s.%s", pkg.Imported().Path(), expr.Sel.Name) - } - panic(fmt.Sprintf("unsupported selector: %v", expr)) - } - return fmt.Sprintf("(%s).%s", sel.Recv(), sel.Obj().Name()) -} - -func IsNil(pass *analysis.Pass, expr ast.Expr) bool { - return pass.TypesInfo.Types[expr].IsNil() -} - -func BoolConst(pass *analysis.Pass, expr ast.Expr) bool { - val := pass.TypesInfo.ObjectOf(expr.(*ast.Ident)).(*types.Const).Val() - return constant.BoolVal(val) -} - -func IsBoolConst(pass *analysis.Pass, expr ast.Expr) bool { - // We explicitly don't support typed bools because more often than - // not, custom bool types are used as binary enums and the - // explicit comparison is desired. - - ident, ok := expr.(*ast.Ident) - if !ok { - return false - } - obj := pass.TypesInfo.ObjectOf(ident) - c, ok := obj.(*types.Const) - if !ok { - return false - } - basic, ok := c.Type().(*types.Basic) - if !ok { - return false - } - if basic.Kind() != types.UntypedBool && basic.Kind() != types.Bool { - return false - } - return true -} - -func ExprToInt(pass *analysis.Pass, expr ast.Expr) (int64, bool) { - tv := pass.TypesInfo.Types[expr] - if tv.Value == nil { - return 0, false - } - if tv.Value.Kind() != constant.Int { - return 0, false - } - return constant.Int64Val(tv.Value) -} - -func ExprToString(pass *analysis.Pass, expr ast.Expr) (string, bool) { - val := pass.TypesInfo.Types[expr].Value - if val == nil { - return "", false - } - if val.Kind() != constant.String { - return "", false - } - return constant.StringVal(val), true -} - -// Dereference returns a pointer's element type; otherwise it returns -// T. -func Dereference(T types.Type) types.Type { - if p, ok := T.Underlying().(*types.Pointer); ok { - return p.Elem() - } - return T -} - -// DereferenceR returns a pointer's element type; otherwise it returns -// T. If the element type is itself a pointer, DereferenceR will be -// applied recursively. -func DereferenceR(T types.Type) types.Type { - if p, ok := T.Underlying().(*types.Pointer); ok { - return DereferenceR(p.Elem()) - } - return T -} - -func CallNameAST(pass *analysis.Pass, call *ast.CallExpr) string { - switch fun := astutil.Unparen(call.Fun).(type) { - case *ast.SelectorExpr: - fn, ok := pass.TypesInfo.ObjectOf(fun.Sel).(*types.Func) - if !ok { - return "" - } - return lint.FuncName(fn) - case *ast.Ident: - obj := pass.TypesInfo.ObjectOf(fun) - switch obj := obj.(type) { - case *types.Func: - return lint.FuncName(obj) - case *types.Builtin: - return obj.Name() - default: - return "" - } - default: - return "" - } -} - -func IsCallToAST(pass *analysis.Pass, node ast.Node, name string) bool { - call, ok := node.(*ast.CallExpr) - if !ok { - return false - } - return CallNameAST(pass, call) == name -} - -func IsCallToAnyAST(pass *analysis.Pass, node ast.Node, names ...string) bool { - call, ok := node.(*ast.CallExpr) - if !ok { - return false - } - q := CallNameAST(pass, call) - for _, name := range names { - if q == name { - return true - } - } - return false -} - -func Preamble(f *ast.File) string { - cutoff := f.Package - if f.Doc != nil { - cutoff = f.Doc.Pos() - } - var out []string - for _, cmt := range f.Comments { - if cmt.Pos() >= cutoff { - break - } - out = append(out, cmt.Text()) - } - return strings.Join(out, "\n") -} - -func GroupSpecs(fset *token.FileSet, specs []ast.Spec) [][]ast.Spec { - if len(specs) == 0 { - return nil - } - groups := make([][]ast.Spec, 1) - groups[0] = append(groups[0], specs[0]) - - for _, spec := range specs[1:] { - g := groups[len(groups)-1] - if fset.PositionFor(spec.Pos(), false).Line-1 != - fset.PositionFor(g[len(g)-1].End(), false).Line { - - groups = append(groups, nil) - } - - groups[len(groups)-1] = append(groups[len(groups)-1], spec) - } - - return groups -} - -func IsObject(obj types.Object, name string) bool { - var path string - if pkg := obj.Pkg(); pkg != nil { - path = pkg.Path() + "." - } - return path+obj.Name() == name -} - -type Field struct { - Var *types.Var - Tag string - Path []int -} - -// FlattenFields recursively flattens T and embedded structs, -// returning a list of fields. If multiple fields with the same name -// exist, all will be returned. -func FlattenFields(T *types.Struct) []Field { - return flattenFields(T, nil, nil) -} - -func flattenFields(T *types.Struct, path []int, seen map[types.Type]bool) []Field { - if seen == nil { - seen = map[types.Type]bool{} - } - if seen[T] { - return nil - } - seen[T] = true - var out []Field - for i := 0; i < T.NumFields(); i++ { - field := T.Field(i) - tag := T.Tag(i) - np := append(path[:len(path):len(path)], i) - if field.Anonymous() { - if s, ok := Dereference(field.Type()).Underlying().(*types.Struct); ok { - out = append(out, flattenFields(s, np, seen)...) - } - } else { - out = append(out, Field{field, tag, np}) - } - } - return out -} - -func File(pass *analysis.Pass, node Positioner) *ast.File { - m := pass.ResultOf[facts.TokenFile].(map[*token.File]*ast.File) - return m[pass.Fset.File(node.Pos())] -} - -// IsGenerated reports whether pos is in a generated file, It ignores -// //line directives. -func IsGenerated(pass *analysis.Pass, pos token.Pos) bool { - _, ok := Generator(pass, pos) - return ok -} - -// Generator returns the generator that generated the file containing -// pos. It ignores //line directives. -func Generator(pass *analysis.Pass, pos token.Pos) (facts.Generator, bool) { - file := pass.Fset.PositionFor(pos, false).Filename - m := pass.ResultOf[facts.Generated].(map[string]facts.Generator) - g, ok := m[file] - return g, ok -} - -// MayHaveSideEffects reports whether expr may have side effects. If -// the purity argument is nil, this function implements a purely -// syntactic check, meaning that any function call may have side -// effects, regardless of the called function's body. Otherwise, -// purity will be consulted to determine the purity of function calls. -func MayHaveSideEffects(pass *analysis.Pass, expr ast.Expr, purity facts.PurityResult) bool { - switch expr := expr.(type) { - case *ast.BadExpr: - return true - case *ast.Ellipsis: - return MayHaveSideEffects(pass, expr.Elt, purity) - case *ast.FuncLit: - // the literal itself cannot have side ffects, only calling it - // might, which is handled by CallExpr. - return false - case *ast.ArrayType, *ast.StructType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.ChanType: - // types cannot have side effects - return false - case *ast.BasicLit: - return false - case *ast.BinaryExpr: - return MayHaveSideEffects(pass, expr.X, purity) || MayHaveSideEffects(pass, expr.Y, purity) - case *ast.CallExpr: - if purity == nil { - return true - } - switch obj := typeutil.Callee(pass.TypesInfo, expr).(type) { - case *types.Func: - if _, ok := purity[obj]; !ok { - return true - } - case *types.Builtin: - switch obj.Name() { - case "len", "cap": - default: - return true - } - default: - return true - } - for _, arg := range expr.Args { - if MayHaveSideEffects(pass, arg, purity) { - return true - } - } - return false - case *ast.CompositeLit: - if MayHaveSideEffects(pass, expr.Type, purity) { - return true - } - for _, elt := range expr.Elts { - if MayHaveSideEffects(pass, elt, purity) { - return true - } - } - return false - case *ast.Ident: - return false - case *ast.IndexExpr: - return MayHaveSideEffects(pass, expr.X, purity) || MayHaveSideEffects(pass, expr.Index, purity) - case *ast.KeyValueExpr: - return MayHaveSideEffects(pass, expr.Key, purity) || MayHaveSideEffects(pass, expr.Value, purity) - case *ast.SelectorExpr: - return MayHaveSideEffects(pass, expr.X, purity) - case *ast.SliceExpr: - return MayHaveSideEffects(pass, expr.X, purity) || - MayHaveSideEffects(pass, expr.Low, purity) || - MayHaveSideEffects(pass, expr.High, purity) || - MayHaveSideEffects(pass, expr.Max, purity) - case *ast.StarExpr: - return MayHaveSideEffects(pass, expr.X, purity) - case *ast.TypeAssertExpr: - return MayHaveSideEffects(pass, expr.X, purity) - case *ast.UnaryExpr: - if MayHaveSideEffects(pass, expr.X, purity) { - return true - } - return expr.Op == token.ARROW - case *ast.ParenExpr: - return MayHaveSideEffects(pass, expr.X, purity) - case nil: - return false - default: - panic(fmt.Sprintf("internal error: unhandled type %T", expr)) - } -} - -func IsGoVersion(pass *analysis.Pass, minor int) bool { - version := pass.Analyzer.Flags.Lookup("go").Value.(flag.Getter).Get().(int) - return version >= minor -} - -func Preorder(pass *analysis.Pass, fn func(ast.Node), types ...ast.Node) { - pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder(types, fn) -} diff --git a/vendor/honnef.co/go/tools/config/config.go b/vendor/honnef.co/go/tools/config/config.go deleted file mode 100644 index 55115371b..000000000 --- a/vendor/honnef.co/go/tools/config/config.go +++ /dev/null @@ -1,245 +0,0 @@ -package config - -import ( - "bytes" - "fmt" - "go/ast" - "go/token" - "os" - "path/filepath" - "reflect" - "strings" - - "github.com/BurntSushi/toml" - "golang.org/x/tools/go/analysis" -) - -// Dir looks at a list of absolute file names, which should make up a -// single package, and returns the path of the directory that may -// contain a staticcheck.conf file. It returns the empty string if no -// such directory could be determined, for example because all files -// were located in Go's build cache. -func Dir(files []string) string { - if len(files) == 0 { - return "" - } - cache, err := os.UserCacheDir() - if err != nil { - cache = "" - } - var path string - for _, p := range files { - // FIXME(dh): using strings.HasPrefix isn't technically - // correct, but it should be good enough for now. - if cache != "" && strings.HasPrefix(p, cache) { - // File in the build cache of the standard Go build system - continue - } - path = p - break - } - - if path == "" { - // The package only consists of generated files. - return "" - } - - dir := filepath.Dir(path) - return dir -} - -func dirAST(files []*ast.File, fset *token.FileSet) string { - names := make([]string, len(files)) - for i, f := range files { - names[i] = fset.PositionFor(f.Pos(), true).Filename - } - return Dir(names) -} - -var Analyzer = &analysis.Analyzer{ - Name: "config", - Doc: "loads configuration for the current package tree", - Run: func(pass *analysis.Pass) (interface{}, error) { - dir := dirAST(pass.Files, pass.Fset) - if dir == "" { - cfg := DefaultConfig - return &cfg, nil - } - cfg, err := Load(dir) - if err != nil { - return nil, fmt.Errorf("error loading staticcheck.conf: %s", err) - } - return &cfg, nil - }, - RunDespiteErrors: true, - ResultType: reflect.TypeOf((*Config)(nil)), -} - -func For(pass *analysis.Pass) *Config { - return pass.ResultOf[Analyzer].(*Config) -} - -func mergeLists(a, b []string) []string { - out := make([]string, 0, len(a)+len(b)) - for _, el := range b { - if el == "inherit" { - out = append(out, a...) - } else { - out = append(out, el) - } - } - - return out -} - -func normalizeList(list []string) []string { - if len(list) > 1 { - nlist := make([]string, 0, len(list)) - nlist = append(nlist, list[0]) - for i, el := range list[1:] { - if el != list[i] { - nlist = append(nlist, el) - } - } - list = nlist - } - - for _, el := range list { - if el == "inherit" { - // This should never happen, because the default config - // should not use "inherit" - panic(`unresolved "inherit"`) - } - } - - return list -} - -func (cfg Config) Merge(ocfg Config) Config { - if ocfg.Checks != nil { - cfg.Checks = mergeLists(cfg.Checks, ocfg.Checks) - } - if ocfg.Initialisms != nil { - cfg.Initialisms = mergeLists(cfg.Initialisms, ocfg.Initialisms) - } - if ocfg.DotImportWhitelist != nil { - cfg.DotImportWhitelist = mergeLists(cfg.DotImportWhitelist, ocfg.DotImportWhitelist) - } - if ocfg.HTTPStatusCodeWhitelist != nil { - cfg.HTTPStatusCodeWhitelist = mergeLists(cfg.HTTPStatusCodeWhitelist, ocfg.HTTPStatusCodeWhitelist) - } - return cfg -} - -type Config struct { - // TODO(dh): this implementation makes it impossible for external - // clients to add their own checkers with configuration. At the - // moment, we don't really care about that; we don't encourage - // that people use this package. In the future, we may. The - // obvious solution would be using map[string]interface{}, but - // that's obviously subpar. - - Checks []string `toml:"checks"` - Initialisms []string `toml:"initialisms"` - DotImportWhitelist []string `toml:"dot_import_whitelist"` - HTTPStatusCodeWhitelist []string `toml:"http_status_code_whitelist"` -} - -func (c Config) String() string { - buf := &bytes.Buffer{} - - fmt.Fprintf(buf, "Checks: %#v\n", c.Checks) - fmt.Fprintf(buf, "Initialisms: %#v\n", c.Initialisms) - fmt.Fprintf(buf, "DotImportWhitelist: %#v\n", c.DotImportWhitelist) - fmt.Fprintf(buf, "HTTPStatusCodeWhitelist: %#v", c.HTTPStatusCodeWhitelist) - - return buf.String() -} - -var DefaultConfig = Config{ - Checks: []string{"all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022"}, - Initialisms: []string{ - "ACL", "API", "ASCII", "CPU", "CSS", "DNS", - "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", - "IP", "JSON", "QPS", "RAM", "RPC", "SLA", - "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", - "UDP", "UI", "GID", "UID", "UUID", "URI", - "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", - "XSS", "SIP", "RTP", "AMQP", "DB", "TS", - }, - DotImportWhitelist: []string{}, - HTTPStatusCodeWhitelist: []string{"200", "400", "404", "500"}, -} - -const ConfigName = "staticcheck.conf" - -func parseConfigs(dir string) ([]Config, error) { - var out []Config - - // TODO(dh): consider stopping at the GOPATH/module boundary - for dir != "" { - f, err := os.Open(filepath.Join(dir, ConfigName)) - if os.IsNotExist(err) { - ndir := filepath.Dir(dir) - if ndir == dir { - break - } - dir = ndir - continue - } - if err != nil { - return nil, err - } - var cfg Config - _, err = toml.DecodeReader(f, &cfg) - f.Close() - if err != nil { - return nil, err - } - out = append(out, cfg) - ndir := filepath.Dir(dir) - if ndir == dir { - break - } - dir = ndir - } - out = append(out, DefaultConfig) - if len(out) < 2 { - return out, nil - } - for i := 0; i < len(out)/2; i++ { - out[i], out[len(out)-1-i] = out[len(out)-1-i], out[i] - } - return out, nil -} - -func mergeConfigs(confs []Config) Config { - if len(confs) == 0 { - // This shouldn't happen because we always have at least a - // default config. - panic("trying to merge zero configs") - } - if len(confs) == 1 { - return confs[0] - } - conf := confs[0] - for _, oconf := range confs[1:] { - conf = conf.Merge(oconf) - } - return conf -} - -func Load(dir string) (Config, error) { - confs, err := parseConfigs(dir) - if err != nil { - return Config{}, err - } - conf := mergeConfigs(confs) - - conf.Checks = normalizeList(conf.Checks) - conf.Initialisms = normalizeList(conf.Initialisms) - conf.DotImportWhitelist = normalizeList(conf.DotImportWhitelist) - conf.HTTPStatusCodeWhitelist = normalizeList(conf.HTTPStatusCodeWhitelist) - - return conf, nil -} diff --git a/vendor/honnef.co/go/tools/config/example.conf b/vendor/honnef.co/go/tools/config/example.conf deleted file mode 100644 index a715a24d4..000000000 --- a/vendor/honnef.co/go/tools/config/example.conf +++ /dev/null @@ -1,10 +0,0 @@ -checks = ["all", "-ST1003", "-ST1014"] -initialisms = ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", - "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", - "IP", "JSON", "QPS", "RAM", "RPC", "SLA", - "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", - "UDP", "UI", "GID", "UID", "UUID", "URI", - "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", - "XSS", "SIP", "RTP"] -dot_import_whitelist = [] -http_status_code_whitelist = ["200", "400", "404", "500"] diff --git a/vendor/honnef.co/go/tools/deprecated/stdlib.go b/vendor/honnef.co/go/tools/deprecated/stdlib.go deleted file mode 100644 index cabb8500a..000000000 --- a/vendor/honnef.co/go/tools/deprecated/stdlib.go +++ /dev/null @@ -1,119 +0,0 @@ -package deprecated - -type Deprecation struct { - DeprecatedSince int - AlternativeAvailableSince int -} - -var Stdlib = map[string]Deprecation{ - // FIXME(dh): AllowBinary isn't being detected as deprecated - // because the comment has a newline right after "Deprecated:" - "go/build.AllowBinary": {7, 7}, - "(archive/zip.FileHeader).CompressedSize": {1, 1}, - "(archive/zip.FileHeader).UncompressedSize": {1, 1}, - "(archive/zip.FileHeader).ModifiedTime": {10, 10}, - "(archive/zip.FileHeader).ModifiedDate": {10, 10}, - "(*archive/zip.FileHeader).ModTime": {10, 10}, - "(*archive/zip.FileHeader).SetModTime": {10, 10}, - "(go/doc.Package).Bugs": {1, 1}, - "os.SEEK_SET": {7, 7}, - "os.SEEK_CUR": {7, 7}, - "os.SEEK_END": {7, 7}, - "(net.Dialer).Cancel": {7, 7}, - "runtime.CPUProfile": {9, 0}, - "compress/flate.ReadError": {6, 6}, - "compress/flate.WriteError": {6, 6}, - "path/filepath.HasPrefix": {0, 0}, - "(net/http.Transport).Dial": {7, 7}, - "(*net/http.Transport).CancelRequest": {6, 5}, - "net/http.ErrWriteAfterFlush": {7, 0}, - "net/http.ErrHeaderTooLong": {8, 0}, - "net/http.ErrShortBody": {8, 0}, - "net/http.ErrMissingContentLength": {8, 0}, - "net/http/httputil.ErrPersistEOF": {0, 0}, - "net/http/httputil.ErrClosed": {0, 0}, - "net/http/httputil.ErrPipeline": {0, 0}, - "net/http/httputil.ServerConn": {0, 0}, - "net/http/httputil.NewServerConn": {0, 0}, - "net/http/httputil.ClientConn": {0, 0}, - "net/http/httputil.NewClientConn": {0, 0}, - "net/http/httputil.NewProxyClientConn": {0, 0}, - "(net/http.Request).Cancel": {7, 7}, - "(text/template/parse.PipeNode).Line": {1, 1}, - "(text/template/parse.ActionNode).Line": {1, 1}, - "(text/template/parse.BranchNode).Line": {1, 1}, - "(text/template/parse.TemplateNode).Line": {1, 1}, - "database/sql/driver.ColumnConverter": {9, 9}, - "database/sql/driver.Execer": {8, 8}, - "database/sql/driver.Queryer": {8, 8}, - "(database/sql/driver.Conn).Begin": {8, 8}, - "(database/sql/driver.Stmt).Exec": {8, 8}, - "(database/sql/driver.Stmt).Query": {8, 8}, - "syscall.StringByteSlice": {1, 1}, - "syscall.StringBytePtr": {1, 1}, - "syscall.StringSlicePtr": {1, 1}, - "syscall.StringToUTF16": {1, 1}, - "syscall.StringToUTF16Ptr": {1, 1}, - "(*regexp.Regexp).Copy": {12, 12}, - "(archive/tar.Header).Xattrs": {10, 10}, - "archive/tar.TypeRegA": {11, 1}, - "go/types.NewInterface": {11, 11}, - "(*go/types.Interface).Embedded": {11, 11}, - "go/importer.For": {12, 12}, - "encoding/json.InvalidUTF8Error": {2, 2}, - "encoding/json.UnmarshalFieldError": {2, 2}, - "encoding/csv.ErrTrailingComma": {2, 2}, - "(encoding/csv.Reader).TrailingComma": {2, 2}, - "(net.Dialer).DualStack": {12, 12}, - "net/http.ErrUnexpectedTrailer": {12, 12}, - "net/http.CloseNotifier": {11, 7}, - "net/http.ProtocolError": {8, 8}, - "(crypto/x509.CertificateRequest).Attributes": {5, 3}, - // This function has no alternative, but also no purpose. - "(*crypto/rc4.Cipher).Reset": {12, 0}, - "(net/http/httptest.ResponseRecorder).HeaderMap": {11, 7}, - "image.ZP": {13, 0}, - "image.ZR": {13, 0}, - "(*debug/gosym.LineTable).LineToPC": {2, 2}, - "(*debug/gosym.LineTable).PCToLine": {2, 2}, - "crypto/tls.VersionSSL30": {13, 0}, - "(crypto/tls.Config).NameToCertificate": {14, 14}, - "(*crypto/tls.Config).BuildNameToCertificate": {14, 14}, - "image/jpeg.Reader": {4, 0}, - - // All of these have been deprecated in favour of external libraries - "syscall.AttachLsf": {7, 0}, - "syscall.DetachLsf": {7, 0}, - "syscall.LsfSocket": {7, 0}, - "syscall.SetLsfPromisc": {7, 0}, - "syscall.LsfJump": {7, 0}, - "syscall.LsfStmt": {7, 0}, - "syscall.BpfStmt": {7, 0}, - "syscall.BpfJump": {7, 0}, - "syscall.BpfBuflen": {7, 0}, - "syscall.SetBpfBuflen": {7, 0}, - "syscall.BpfDatalink": {7, 0}, - "syscall.SetBpfDatalink": {7, 0}, - "syscall.SetBpfPromisc": {7, 0}, - "syscall.FlushBpf": {7, 0}, - "syscall.BpfInterface": {7, 0}, - "syscall.SetBpfInterface": {7, 0}, - "syscall.BpfTimeout": {7, 0}, - "syscall.SetBpfTimeout": {7, 0}, - "syscall.BpfStats": {7, 0}, - "syscall.SetBpfImmediate": {7, 0}, - "syscall.SetBpf": {7, 0}, - "syscall.CheckBpfVersion": {7, 0}, - "syscall.BpfHeadercmpl": {7, 0}, - "syscall.SetBpfHeadercmpl": {7, 0}, - "syscall.RouteRIB": {8, 0}, - "syscall.RoutingMessage": {8, 0}, - "syscall.RouteMessage": {8, 0}, - "syscall.InterfaceMessage": {8, 0}, - "syscall.InterfaceAddrMessage": {8, 0}, - "syscall.ParseRoutingMessage": {8, 0}, - "syscall.ParseRoutingSockaddr": {8, 0}, - "syscall.InterfaceAnnounceMessage": {7, 0}, - "syscall.InterfaceMulticastAddrMessage": {7, 0}, - "syscall.FormatMessage": {5, 0}, -} diff --git a/vendor/honnef.co/go/tools/edit/edit.go b/vendor/honnef.co/go/tools/edit/edit.go deleted file mode 100644 index f4cfba234..000000000 --- a/vendor/honnef.co/go/tools/edit/edit.go +++ /dev/null @@ -1,67 +0,0 @@ -package edit - -import ( - "bytes" - "go/ast" - "go/format" - "go/token" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/pattern" -) - -type Ranger interface { - Pos() token.Pos - End() token.Pos -} - -type Range [2]token.Pos - -func (r Range) Pos() token.Pos { return r[0] } -func (r Range) End() token.Pos { return r[1] } - -func ReplaceWithString(fset *token.FileSet, old Ranger, new string) analysis.TextEdit { - return analysis.TextEdit{ - Pos: old.Pos(), - End: old.End(), - NewText: []byte(new), - } -} - -func ReplaceWithNode(fset *token.FileSet, old Ranger, new ast.Node) analysis.TextEdit { - buf := &bytes.Buffer{} - if err := format.Node(buf, fset, new); err != nil { - panic("internal error: " + err.Error()) - } - return analysis.TextEdit{ - Pos: old.Pos(), - End: old.End(), - NewText: buf.Bytes(), - } -} - -func ReplaceWithPattern(pass *analysis.Pass, after pattern.Pattern, state pattern.State, node Ranger) analysis.TextEdit { - r := pattern.NodeToAST(after.Root, state) - buf := &bytes.Buffer{} - format.Node(buf, pass.Fset, r) - return analysis.TextEdit{ - Pos: node.Pos(), - End: node.End(), - NewText: buf.Bytes(), - } -} - -func Delete(old Ranger) analysis.TextEdit { - return analysis.TextEdit{ - Pos: old.Pos(), - End: old.End(), - NewText: nil, - } -} - -func Fix(msg string, edits ...analysis.TextEdit) analysis.SuggestedFix { - return analysis.SuggestedFix{ - Message: msg, - TextEdits: edits, - } -} diff --git a/vendor/honnef.co/go/tools/facts/deprecated.go b/vendor/honnef.co/go/tools/facts/deprecated.go deleted file mode 100644 index 8587b0e0e..000000000 --- a/vendor/honnef.co/go/tools/facts/deprecated.go +++ /dev/null @@ -1,144 +0,0 @@ -package facts - -import ( - "go/ast" - "go/token" - "go/types" - "reflect" - "strings" - - "golang.org/x/tools/go/analysis" -) - -type IsDeprecated struct{ Msg string } - -func (*IsDeprecated) AFact() {} -func (d *IsDeprecated) String() string { return "Deprecated: " + d.Msg } - -type DeprecatedResult struct { - Objects map[types.Object]*IsDeprecated - Packages map[*types.Package]*IsDeprecated -} - -var Deprecated = &analysis.Analyzer{ - Name: "fact_deprecated", - Doc: "Mark deprecated objects", - Run: deprecated, - FactTypes: []analysis.Fact{(*IsDeprecated)(nil)}, - ResultType: reflect.TypeOf(DeprecatedResult{}), -} - -func deprecated(pass *analysis.Pass) (interface{}, error) { - var names []*ast.Ident - - extractDeprecatedMessage := func(docs []*ast.CommentGroup) string { - for _, doc := range docs { - if doc == nil { - continue - } - parts := strings.Split(doc.Text(), "\n\n") - last := parts[len(parts)-1] - if !strings.HasPrefix(last, "Deprecated: ") { - continue - } - alt := last[len("Deprecated: "):] - alt = strings.Replace(alt, "\n", " ", -1) - return alt - } - return "" - } - doDocs := func(names []*ast.Ident, docs []*ast.CommentGroup) { - alt := extractDeprecatedMessage(docs) - if alt == "" { - return - } - - for _, name := range names { - obj := pass.TypesInfo.ObjectOf(name) - pass.ExportObjectFact(obj, &IsDeprecated{alt}) - } - } - - var docs []*ast.CommentGroup - for _, f := range pass.Files { - docs = append(docs, f.Doc) - } - if alt := extractDeprecatedMessage(docs); alt != "" { - // Don't mark package syscall as deprecated, even though - // it is. A lot of people still use it for simple - // constants like SIGKILL, and I am not comfortable - // telling them to use x/sys for that. - if pass.Pkg.Path() != "syscall" { - pass.ExportPackageFact(&IsDeprecated{alt}) - } - } - - docs = docs[:0] - for _, f := range pass.Files { - fn := func(node ast.Node) bool { - if node == nil { - return true - } - var ret bool - switch node := node.(type) { - case *ast.GenDecl: - switch node.Tok { - case token.TYPE, token.CONST, token.VAR: - docs = append(docs, node.Doc) - return true - default: - return false - } - case *ast.FuncDecl: - docs = append(docs, node.Doc) - names = []*ast.Ident{node.Name} - ret = false - case *ast.TypeSpec: - docs = append(docs, node.Doc) - names = []*ast.Ident{node.Name} - ret = true - case *ast.ValueSpec: - docs = append(docs, node.Doc) - names = node.Names - ret = false - case *ast.File: - return true - case *ast.StructType: - for _, field := range node.Fields.List { - doDocs(field.Names, []*ast.CommentGroup{field.Doc}) - } - return false - case *ast.InterfaceType: - for _, field := range node.Methods.List { - doDocs(field.Names, []*ast.CommentGroup{field.Doc}) - } - return false - default: - return false - } - if len(names) == 0 || len(docs) == 0 { - return ret - } - doDocs(names, docs) - - docs = docs[:0] - names = nil - return ret - } - ast.Inspect(f, fn) - } - - out := DeprecatedResult{ - Objects: map[types.Object]*IsDeprecated{}, - Packages: map[*types.Package]*IsDeprecated{}, - } - - for _, fact := range pass.AllObjectFacts() { - out.Objects[fact.Object] = fact.Fact.(*IsDeprecated) - } - for _, fact := range pass.AllPackageFacts() { - out.Packages[fact.Package] = fact.Fact.(*IsDeprecated) - } - - return out, nil -} diff --git a/vendor/honnef.co/go/tools/facts/generated.go b/vendor/honnef.co/go/tools/facts/generated.go deleted file mode 100644 index 18cbb49bd..000000000 --- a/vendor/honnef.co/go/tools/facts/generated.go +++ /dev/null @@ -1,93 +0,0 @@ -package facts - -import ( - "bufio" - "bytes" - "io" - "os" - "reflect" - "strings" - - "golang.org/x/tools/go/analysis" -) - -type Generator int - -// A list of known generators we can detect -const ( - Unknown Generator = iota - Goyacc - Cgo - Stringer - ProtocGenGo -) - -var ( - // used by cgo before Go 1.11 - oldCgo = []byte("// Created by cgo - DO NOT EDIT") - prefix = []byte("// Code generated ") - suffix = []byte(" DO NOT EDIT.") - nl = []byte("\n") - crnl = []byte("\r\n") -) - -func isGenerated(path string) (Generator, bool) { - f, err := os.Open(path) - if err != nil { - return 0, false - } - defer f.Close() - br := bufio.NewReader(f) - for { - s, err := br.ReadBytes('\n') - if err != nil && err != io.EOF { - return 0, false - } - s = bytes.TrimSuffix(s, crnl) - s = bytes.TrimSuffix(s, nl) - if bytes.HasPrefix(s, prefix) && bytes.HasSuffix(s, suffix) { - text := string(s[len(prefix) : len(s)-len(suffix)]) - switch text { - case "by goyacc.": - return Goyacc, true - case "by cmd/cgo;": - return Cgo, true - case "by protoc-gen-go.": - return ProtocGenGo, true - } - if strings.HasPrefix(text, `by "stringer `) { - return Stringer, true - } - if strings.HasPrefix(text, `by goyacc `) { - return Goyacc, true - } - - return Unknown, true - } - if bytes.Equal(s, oldCgo) { - return Cgo, true - } - if err == io.EOF { - break - } - } - return 0, false -} - -var Generated = &analysis.Analyzer{ - Name: "isgenerated", - Doc: "annotate file names that have been code generated", - Run: func(pass *analysis.Pass) (interface{}, error) { - m := map[string]Generator{} - for _, f := range pass.Files { - path := pass.Fset.PositionFor(f.Pos(), false).Filename - g, ok := isGenerated(path) - if ok { - m[path] = g - } - } - return m, nil - }, - RunDespiteErrors: true, - ResultType: reflect.TypeOf(map[string]Generator{}), -} diff --git a/vendor/honnef.co/go/tools/facts/purity.go b/vendor/honnef.co/go/tools/facts/purity.go deleted file mode 100644 index 099ee23e3..000000000 --- a/vendor/honnef.co/go/tools/facts/purity.go +++ /dev/null @@ -1,177 +0,0 @@ -package facts - -import ( - "go/types" - "reflect" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/functions" - "honnef.co/go/tools/internal/passes/buildir" - "honnef.co/go/tools/ir" -) - -type IsPure struct{} - -func (*IsPure) AFact() {} -func (d *IsPure) String() string { return "is pure" } - -type PurityResult map[*types.Func]*IsPure - -var Purity = &analysis.Analyzer{ - Name: "fact_purity", - Doc: "Mark pure functions", - Run: purity, - Requires: []*analysis.Analyzer{buildir.Analyzer}, - FactTypes: []analysis.Fact{(*IsPure)(nil)}, - ResultType: reflect.TypeOf(PurityResult{}), -} - -var pureStdlib = map[string]struct{}{ - "errors.New": {}, - "fmt.Errorf": {}, - "fmt.Sprintf": {}, - "fmt.Sprint": {}, - "sort.Reverse": {}, - "strings.Map": {}, - "strings.Repeat": {}, - "strings.Replace": {}, - "strings.Title": {}, - "strings.ToLower": {}, - "strings.ToLowerSpecial": {}, - "strings.ToTitle": {}, - "strings.ToTitleSpecial": {}, - "strings.ToUpper": {}, - "strings.ToUpperSpecial": {}, - "strings.Trim": {}, - "strings.TrimFunc": {}, - "strings.TrimLeft": {}, - "strings.TrimLeftFunc": {}, - "strings.TrimPrefix": {}, - "strings.TrimRight": {}, - "strings.TrimRightFunc": {}, - "strings.TrimSpace": {}, - "strings.TrimSuffix": {}, - "(*net/http.Request).WithContext": {}, -} - -func purity(pass *analysis.Pass) (interface{}, error) { - seen := map[*ir.Function]struct{}{} - irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg - var check func(fn *ir.Function) (ret bool) - check = func(fn *ir.Function) (ret bool) { - if fn.Object() == nil { - // TODO(dh): support closures - return false - } - if pass.ImportObjectFact(fn.Object(), new(IsPure)) { - return true - } - if fn.Pkg != irpkg { - // Function is in another package but wasn't marked as - // pure, ergo it isn't pure - return false - } - // Break recursion - if _, ok := seen[fn]; ok { - return false - } - - seen[fn] = struct{}{} - defer func() { - if ret { - pass.ExportObjectFact(fn.Object(), &IsPure{}) - } - }() - - if functions.IsStub(fn) { - return false - } - - if _, ok := pureStdlib[fn.Object().(*types.Func).FullName()]; ok { - return true - } - - if fn.Signature.Results().Len() == 0 { - // A function with no return values is empty or is doing some - // work we cannot see (for example because of build tags); - // don't consider it pure. - return false - } - - for _, param := range fn.Params { - // TODO(dh): this may not be strictly correct. pure code - // can, to an extent, operate on non-basic types. - if _, ok := param.Type().Underlying().(*types.Basic); !ok { - return false - } - } - - // Don't consider external functions pure. - if fn.Blocks == nil { - return false - } - checkCall := func(common *ir.CallCommon) bool { - if common.IsInvoke() { - return false - } - builtin, ok := common.Value.(*ir.Builtin) - if !ok { - if common.StaticCallee() != fn { - if common.StaticCallee() == nil { - return false - } - if !check(common.StaticCallee()) { - return false - } - } - } else { - switch builtin.Name() { - case "len", "cap": - default: - return false - } - } - return true - } - for _, b := range fn.Blocks { - for _, ins := range b.Instrs { - switch ins := ins.(type) { - case *ir.Call: - if !checkCall(ins.Common()) { - return false - } - case *ir.Defer: - if !checkCall(&ins.Call) { - return false - } - case *ir.Select: - return false - case *ir.Send: - return false - case *ir.Go: - return false - case *ir.Panic: - return false - case *ir.Store: - return false - case *ir.FieldAddr: - return false - case *ir.Alloc: - return false - case *ir.Load: - return false - } - } - } - return true - } - for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs { - check(fn) - } - - out := PurityResult{} - for _, fact := range pass.AllObjectFacts() { - out[fact.Object.(*types.Func)] = fact.Fact.(*IsPure) - } - return out, nil -} diff --git a/vendor/honnef.co/go/tools/facts/token.go b/vendor/honnef.co/go/tools/facts/token.go deleted file mode 100644 index 26e76ff73..000000000 --- a/vendor/honnef.co/go/tools/facts/token.go +++ /dev/null @@ -1,24 +0,0 @@ -package facts - -import ( - "go/ast" - "go/token" - "reflect" - - "golang.org/x/tools/go/analysis" -) - -var TokenFile = &analysis.Analyzer{ - Name: "tokenfileanalyzer", - Doc: "creates a mapping of *token.File to *ast.File", - Run: func(pass *analysis.Pass) (interface{}, error) { - m := map[*token.File]*ast.File{} - for _, af := range pass.Files { - tf := pass.Fset.File(af.Pos()) - m[tf] = af - } - return m, nil - }, - RunDespiteErrors: true, - ResultType: reflect.TypeOf(map[*token.File]*ast.File{}), -} diff --git a/vendor/honnef.co/go/tools/functions/loops.go b/vendor/honnef.co/go/tools/functions/loops.go deleted file mode 100644 index a8af70100..000000000 --- a/vendor/honnef.co/go/tools/functions/loops.go +++ /dev/null @@ -1,54 +0,0 @@ -package functions - -import "honnef.co/go/tools/ir" - -type Loop struct{ *ir.BlockSet } - -func FindLoops(fn *ir.Function) []Loop { - if fn.Blocks == nil { - return nil - } - tree := fn.DomPreorder() - var sets []Loop - for _, h := range tree { - for _, n := range h.Preds { - if !h.Dominates(n) { - continue - } - // n is a back-edge to h - // h is the loop header - if n == h { - set := Loop{ir.NewBlockSet(len(fn.Blocks))} - set.Add(n) - sets = append(sets, set) - continue - } - set := Loop{ir.NewBlockSet(len(fn.Blocks))} - set.Add(h) - set.Add(n) - for _, b := range allPredsBut(n, h, nil) { - set.Add(b) - } - sets = append(sets, set) - } - } - return sets -} - -func allPredsBut(b, but *ir.BasicBlock, list []*ir.BasicBlock) []*ir.BasicBlock { -outer: - for _, pred := range b.Preds { - if pred == but { - continue - } - for _, p := range list { - // TODO improve big-o complexity of this function - if pred == p { - continue outer - } - } - list = append(list, pred) - list = allPredsBut(pred, but, list) - } - return list -} diff --git a/vendor/honnef.co/go/tools/functions/stub.go b/vendor/honnef.co/go/tools/functions/stub.go deleted file mode 100644 index 4d5de10b8..000000000 --- a/vendor/honnef.co/go/tools/functions/stub.go +++ /dev/null @@ -1,32 +0,0 @@ -package functions - -import ( - "honnef.co/go/tools/ir" -) - -// IsStub reports whether a function is a stub. A function is -// considered a stub if it has no instructions or if all it does is -// return a constant value. -func IsStub(fn *ir.Function) bool { - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.Const: - // const naturally has no side-effects - case *ir.Panic: - // panic is a stub if it only uses constants - case *ir.Return: - // return is a stub if it only uses constants - case *ir.DebugRef: - case *ir.Jump: - // if there are no disallowed instructions, then we're - // only jumping to the exit block (or possibly - // somewhere else that's stubby?) - default: - // all other instructions are assumed to do actual work - return false - } - } - } - return true -} diff --git a/vendor/honnef.co/go/tools/functions/terminates.go b/vendor/honnef.co/go/tools/functions/terminates.go deleted file mode 100644 index c4984673f..000000000 --- a/vendor/honnef.co/go/tools/functions/terminates.go +++ /dev/null @@ -1,70 +0,0 @@ -package functions - -import ( - "go/types" - - "honnef.co/go/tools/ir" -) - -// Terminates reports whether fn is supposed to return, that is if it -// has at least one theoretic path that returns from the function. -// Explicit panics do not count as terminating. -func Terminates(fn *ir.Function) bool { - if fn.Blocks == nil { - // assuming that a function terminates is the conservative - // choice - return true - } - - for _, block := range fn.Blocks { - if _, ok := block.Control().(*ir.Return); ok { - if len(block.Preds) == 0 { - return true - } - for _, pred := range block.Preds { - switch ctrl := pred.Control().(type) { - case *ir.Panic: - // explicit panics do not count as terminating - case *ir.If: - // Check if we got here by receiving from a closed - // time.Tick channel – this cannot happen at - // runtime and thus doesn't constitute termination - iff := ctrl - if !ok { - return true - } - ex, ok := iff.Cond.(*ir.Extract) - if !ok { - return true - } - if ex.Index != 1 { - return true - } - recv, ok := ex.Tuple.(*ir.Recv) - if !ok { - return true - } - call, ok := recv.Chan.(*ir.Call) - if !ok { - return true - } - fn, ok := call.Common().Value.(*ir.Function) - if !ok { - return true - } - fn2, ok := fn.Object().(*types.Func) - if !ok { - return true - } - if fn2.FullName() != "time.Tick" { - return true - } - default: - // we've reached the exit block - return true - } - } - } - } - return false -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/callee.go b/vendor/honnef.co/go/tools/go/types/typeutil/callee.go deleted file mode 100644 index 38f596daf..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/callee.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeutil - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/ast/astutil" -) - -// Callee returns the named target of a function call, if any: -// a function, method, builtin, or variable. -func Callee(info *types.Info, call *ast.CallExpr) types.Object { - var obj types.Object - switch fun := astutil.Unparen(call.Fun).(type) { - case *ast.Ident: - obj = info.Uses[fun] // type, var, builtin, or declared func - case *ast.SelectorExpr: - if sel, ok := info.Selections[fun]; ok { - obj = sel.Obj() // method or field - } else { - obj = info.Uses[fun.Sel] // qualified identifier? - } - } - if _, ok := obj.(*types.TypeName); ok { - return nil // T(x) is a conversion, not a call - } - return obj -} - -// StaticCallee returns the target (function or method) of a static -// function call, if any. It returns nil for calls to builtins. -func StaticCallee(info *types.Info, call *ast.CallExpr) *types.Func { - if f, ok := Callee(info, call).(*types.Func); ok && !interfaceMethod(f) { - return f - } - return nil -} - -func interfaceMethod(f *types.Func) bool { - recv := f.Type().(*types.Signature).Recv() - return recv != nil && types.IsInterface(recv.Type()) -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/identical.go b/vendor/honnef.co/go/tools/go/types/typeutil/identical.go deleted file mode 100644 index c0ca441c3..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/identical.go +++ /dev/null @@ -1,75 +0,0 @@ -package typeutil - -import ( - "go/types" -) - -// Identical reports whether x and y are identical types. -// Unlike types.Identical, receivers of Signature types are not ignored. -// Unlike types.Identical, interfaces are compared via pointer equality (except for the empty interface, which gets deduplicated). -// Unlike types.Identical, structs are compared via pointer equality. -func Identical(x, y types.Type) (ret bool) { - if !types.Identical(x, y) { - return false - } - - switch x := x.(type) { - case *types.Struct: - y, ok := y.(*types.Struct) - if !ok { - // should be impossible - return true - } - return x == y - case *types.Interface: - // The issue with interfaces, typeutil.Map and types.Identical - // - // types.Identical, when comparing two interfaces, only looks at the set - // of all methods, not differentiating between implicit (embedded) and - // explicit methods. - // - // When we see the following two types, in source order - // - // type I1 interface { foo() } - // type I2 interface { I1 } - // - // then we will first correctly process I1 and its underlying type. When - // we get to I2, we will see that its underlying type is identical to - // that of I1 and not process it again. This, however, means that we will - // not record the fact that I2 embeds I1. If only I2 is reachable via the - // graph root, then I1 will not be considered used. - // - // We choose to be lazy and compare interfaces by their - // pointers. This will obviously miss identical interfaces, - // but this only has a runtime cost, it doesn't affect - // correctness. - y, ok := y.(*types.Interface) - if !ok { - // should be impossible - return true - } - if x.NumEmbeddeds() == 0 && - y.NumEmbeddeds() == 0 && - x.NumMethods() == 0 && - y.NumMethods() == 0 { - // all truly empty interfaces are the same - return true - } - return x == y - case *types.Signature: - y, ok := y.(*types.Signature) - if !ok { - // should be impossible - return true - } - if x.Recv() == y.Recv() { - return true - } - if x.Recv() == nil || y.Recv() == nil { - return false - } - return Identical(x.Recv().Type(), y.Recv().Type()) - default: - return true - } -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/imports.go b/vendor/honnef.co/go/tools/go/types/typeutil/imports.go deleted file mode 100644 index 9c441dba9..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/imports.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeutil - -import "go/types" - -// Dependencies returns all dependencies of the specified packages. -// -// Dependent packages appear in topological order: if package P imports -// package Q, Q appears earlier than P in the result. -// The algorithm follows import statements in the order they -// appear in the source code, so the result is a total order. -// -func Dependencies(pkgs ...*types.Package) []*types.Package { - var result []*types.Package - seen := make(map[*types.Package]bool) - var visit func(pkgs []*types.Package) - visit = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !seen[p] { - seen[p] = true - visit(p.Imports()) - result = append(result, p) - } - } - } - visit(pkgs) - return result -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/map.go b/vendor/honnef.co/go/tools/go/types/typeutil/map.go deleted file mode 100644 index f929353cc..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/map.go +++ /dev/null @@ -1,319 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package typeutil defines various utilities for types, such as Map, -// a mapping from types.Type to interface{} values. -package typeutil - -import ( - "bytes" - "fmt" - "go/types" - "reflect" -) - -// Map is a hash-table-based mapping from types (types.Type) to -// arbitrary interface{} values. The concrete types that implement -// the Type interface are pointers. Since they are not canonicalized, -// == cannot be used to check for equivalence, and thus we cannot -// simply use a Go map. -// -// Just as with map[K]V, a nil *Map is a valid empty map. -// -// Not thread-safe. -// -// This fork handles Signatures correctly, respecting method -// receivers. Furthermore, it doesn't deduplicate interfaces or -// structs. Interfaces aren't deduplicated as not to conflate implicit -// and explicit methods. Structs aren't deduplicated because we track -// fields of each type separately. -// -type Map struct { - hasher Hasher // shared by many Maps - table map[uint32][]entry // maps hash to bucket; entry.key==nil means unused - length int // number of map entries -} - -// entry is an entry (key/value association) in a hash bucket. -type entry struct { - key types.Type - value interface{} -} - -// SetHasher sets the hasher used by Map. -// -// All Hashers are functionally equivalent but contain internal state -// used to cache the results of hashing previously seen types. -// -// A single Hasher created by MakeHasher() may be shared among many -// Maps. This is recommended if the instances have many keys in -// common, as it will amortize the cost of hash computation. -// -// A Hasher may grow without bound as new types are seen. Even when a -// type is deleted from the map, the Hasher never shrinks, since other -// types in the map may reference the deleted type indirectly. -// -// Hashers are not thread-safe, and read-only operations such as -// Map.Lookup require updates to the hasher, so a full Mutex lock (not a -// read-lock) is require around all Map operations if a shared -// hasher is accessed from multiple threads. -// -// If SetHasher is not called, the Map will create a private hasher at -// the first call to Insert. -// -func (m *Map) SetHasher(hasher Hasher) { - m.hasher = hasher -} - -// Delete removes the entry with the given key, if any. -// It returns true if the entry was found. -// -func (m *Map) Delete(key types.Type) bool { - if m != nil && m.table != nil { - hash := m.hasher.Hash(key) - bucket := m.table[hash] - for i, e := range bucket { - if e.key != nil && Identical(key, e.key) { - // We can't compact the bucket as it - // would disturb iterators. - bucket[i] = entry{} - m.length-- - return true - } - } - } - return false -} - -// At returns the map entry for the given key. -// The result is nil if the entry is not present. -// -func (m *Map) At(key types.Type) interface{} { - if m != nil && m.table != nil { - for _, e := range m.table[m.hasher.Hash(key)] { - if e.key != nil && Identical(key, e.key) { - return e.value - } - } - } - return nil -} - -// Set sets the map entry for key to val, -// and returns the previous entry, if any. -func (m *Map) Set(key types.Type, value interface{}) (prev interface{}) { - if m.table != nil { - hash := m.hasher.Hash(key) - bucket := m.table[hash] - var hole *entry - for i, e := range bucket { - if e.key == nil { - hole = &bucket[i] - } else if Identical(key, e.key) { - prev = e.value - bucket[i].value = value - return - } - } - - if hole != nil { - *hole = entry{key, value} // overwrite deleted entry - } else { - m.table[hash] = append(bucket, entry{key, value}) - } - } else { - if m.hasher.memo == nil { - m.hasher = MakeHasher() - } - hash := m.hasher.Hash(key) - m.table = map[uint32][]entry{hash: {entry{key, value}}} - } - - m.length++ - return -} - -// Len returns the number of map entries. -func (m *Map) Len() int { - if m != nil { - return m.length - } - return 0 -} - -// Iterate calls function f on each entry in the map in unspecified order. -// -// If f should mutate the map, Iterate provides the same guarantees as -// Go maps: if f deletes a map entry that Iterate has not yet reached, -// f will not be invoked for it, but if f inserts a map entry that -// Iterate has not yet reached, whether or not f will be invoked for -// it is unspecified. -// -func (m *Map) Iterate(f func(key types.Type, value interface{})) { - if m != nil { - for _, bucket := range m.table { - for _, e := range bucket { - if e.key != nil { - f(e.key, e.value) - } - } - } - } -} - -// Keys returns a new slice containing the set of map keys. -// The order is unspecified. -func (m *Map) Keys() []types.Type { - keys := make([]types.Type, 0, m.Len()) - m.Iterate(func(key types.Type, _ interface{}) { - keys = append(keys, key) - }) - return keys -} - -func (m *Map) toString(values bool) string { - if m == nil { - return "{}" - } - var buf bytes.Buffer - fmt.Fprint(&buf, "{") - sep := "" - m.Iterate(func(key types.Type, value interface{}) { - fmt.Fprint(&buf, sep) - sep = ", " - fmt.Fprint(&buf, key) - if values { - fmt.Fprintf(&buf, ": %q", value) - } - }) - fmt.Fprint(&buf, "}") - return buf.String() -} - -// String returns a string representation of the map's entries. -// Values are printed using fmt.Sprintf("%v", v). -// Order is unspecified. -// -func (m *Map) String() string { - return m.toString(true) -} - -// KeysString returns a string representation of the map's key set. -// Order is unspecified. -// -func (m *Map) KeysString() string { - return m.toString(false) -} - -//////////////////////////////////////////////////////////////////////// -// Hasher - -// A Hasher maps each type to its hash value. -// For efficiency, a hasher uses memoization; thus its memory -// footprint grows monotonically over time. -// Hashers are not thread-safe. -// Hashers have reference semantics. -// Call MakeHasher to create a Hasher. -type Hasher struct { - memo map[types.Type]uint32 -} - -// MakeHasher returns a new Hasher instance. -func MakeHasher() Hasher { - return Hasher{make(map[types.Type]uint32)} -} - -// Hash computes a hash value for the given type t such that -// Identical(t, t') => Hash(t) == Hash(t'). -func (h Hasher) Hash(t types.Type) uint32 { - hash, ok := h.memo[t] - if !ok { - hash = h.hashFor(t) - h.memo[t] = hash - } - return hash -} - -// hashString computes the Fowler–Noll–Vo hash of s. -func hashString(s string) uint32 { - var h uint32 - for i := 0; i < len(s); i++ { - h ^= uint32(s[i]) - h *= 16777619 - } - return h -} - -// hashFor computes the hash of t. -func (h Hasher) hashFor(t types.Type) uint32 { - // See Identical for rationale. - switch t := t.(type) { - case *types.Basic: - return uint32(t.Kind()) - - case *types.Array: - return 9043 + 2*uint32(t.Len()) + 3*h.Hash(t.Elem()) - - case *types.Slice: - return 9049 + 2*h.Hash(t.Elem()) - - case *types.Struct: - var hash uint32 = 9059 - for i, n := 0, t.NumFields(); i < n; i++ { - f := t.Field(i) - if f.Anonymous() { - hash += 8861 - } - hash += hashString(t.Tag(i)) - hash += hashString(f.Name()) // (ignore f.Pkg) - hash += h.Hash(f.Type()) - } - return hash - - case *types.Pointer: - return 9067 + 2*h.Hash(t.Elem()) - - case *types.Signature: - var hash uint32 = 9091 - if t.Variadic() { - hash *= 8863 - } - return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results()) - - case *types.Interface: - var hash uint32 = 9103 - for i, n := 0, t.NumMethods(); i < n; i++ { - // See go/types.identicalMethods for rationale. - // Method order is not significant. - // Ignore m.Pkg(). - m := t.Method(i) - hash += 3*hashString(m.Name()) + 5*h.Hash(m.Type()) - } - return hash - - case *types.Map: - return 9109 + 2*h.Hash(t.Key()) + 3*h.Hash(t.Elem()) - - case *types.Chan: - return 9127 + 2*uint32(t.Dir()) + 3*h.Hash(t.Elem()) - - case *types.Named: - // Not safe with a copying GC; objects may move. - return uint32(reflect.ValueOf(t.Obj()).Pointer()) - - case *types.Tuple: - return h.hashTuple(t) - } - panic(t) -} - -func (h Hasher) hashTuple(tuple *types.Tuple) uint32 { - // See go/types.identicalTypes for rationale. - n := tuple.Len() - var hash uint32 = 9137 + 2*uint32(n) - for i := 0; i < n; i++ { - hash += 3 * h.Hash(tuple.At(i).Type()) - } - return hash -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/methodsetcache.go b/vendor/honnef.co/go/tools/go/types/typeutil/methodsetcache.go deleted file mode 100644 index 32084610f..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/methodsetcache.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements a cache of method sets. - -package typeutil - -import ( - "go/types" - "sync" -) - -// A MethodSetCache records the method set of each type T for which -// MethodSet(T) is called so that repeat queries are fast. -// The zero value is a ready-to-use cache instance. -type MethodSetCache struct { - mu sync.Mutex - named map[*types.Named]struct{ value, pointer *types.MethodSet } // method sets for named N and *N - others map[types.Type]*types.MethodSet // all other types -} - -// MethodSet returns the method set of type T. It is thread-safe. -// -// If cache is nil, this function is equivalent to types.NewMethodSet(T). -// Utility functions can thus expose an optional *MethodSetCache -// parameter to clients that care about performance. -// -func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet { - if cache == nil { - return types.NewMethodSet(T) - } - cache.mu.Lock() - defer cache.mu.Unlock() - - switch T := T.(type) { - case *types.Named: - return cache.lookupNamed(T).value - - case *types.Pointer: - if N, ok := T.Elem().(*types.Named); ok { - return cache.lookupNamed(N).pointer - } - } - - // all other types - // (The map uses pointer equivalence, not type identity.) - mset := cache.others[T] - if mset == nil { - mset = types.NewMethodSet(T) - if cache.others == nil { - cache.others = make(map[types.Type]*types.MethodSet) - } - cache.others[T] = mset - } - return mset -} - -func (cache *MethodSetCache) lookupNamed(named *types.Named) struct{ value, pointer *types.MethodSet } { - if cache.named == nil { - cache.named = make(map[*types.Named]struct{ value, pointer *types.MethodSet }) - } - // Avoid recomputing mset(*T) for each distinct Pointer - // instance whose underlying type is a named type. - msets, ok := cache.named[named] - if !ok { - msets.value = types.NewMethodSet(named) - msets.pointer = types.NewMethodSet(types.NewPointer(named)) - cache.named[named] = msets - } - return msets -} diff --git a/vendor/honnef.co/go/tools/go/types/typeutil/ui.go b/vendor/honnef.co/go/tools/go/types/typeutil/ui.go deleted file mode 100644 index 9849c24ce..000000000 --- a/vendor/honnef.co/go/tools/go/types/typeutil/ui.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2014 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package typeutil - -// This file defines utilities for user interfaces that display types. - -import "go/types" - -// IntuitiveMethodSet returns the intuitive method set of a type T, -// which is the set of methods you can call on an addressable value of -// that type. -// -// The result always contains MethodSet(T), and is exactly MethodSet(T) -// for interface types and for pointer-to-concrete types. -// For all other concrete types T, the result additionally -// contains each method belonging to *T if there is no identically -// named method on T itself. -// -// This corresponds to user intuition about method sets; -// this function is intended only for user interfaces. -// -// The order of the result is as for types.MethodSet(T). -// -func IntuitiveMethodSet(T types.Type, msets *MethodSetCache) []*types.Selection { - isPointerToConcrete := func(T types.Type) bool { - ptr, ok := T.(*types.Pointer) - return ok && !types.IsInterface(ptr.Elem()) - } - - var result []*types.Selection - mset := msets.MethodSet(T) - if types.IsInterface(T) || isPointerToConcrete(T) { - for i, n := 0, mset.Len(); i < n; i++ { - result = append(result, mset.At(i)) - } - } else { - // T is some other concrete type. - // Report methods of T and *T, preferring those of T. - pmset := msets.MethodSet(types.NewPointer(T)) - for i, n := 0, pmset.Len(); i < n; i++ { - meth := pmset.At(i) - if m := mset.Lookup(meth.Obj().Pkg(), meth.Obj().Name()); m != nil { - meth = m - } - result = append(result, meth) - } - - } - return result -} diff --git a/vendor/honnef.co/go/tools/internal/cache/cache.go b/vendor/honnef.co/go/tools/internal/cache/cache.go deleted file mode 100644 index 6b41811cf..000000000 --- a/vendor/honnef.co/go/tools/internal/cache/cache.go +++ /dev/null @@ -1,496 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package cache implements a build artifact cache. -// -// This package is a slightly modified fork of Go's -// cmd/go/internal/cache package. -package cache - -import ( - "bytes" - "crypto/sha256" - "encoding/hex" - "errors" - "fmt" - "io" - "io/ioutil" - "os" - "path/filepath" - "strconv" - "strings" - "time" - - "honnef.co/go/tools/internal/renameio" -) - -// An ActionID is a cache action key, the hash of a complete description of a -// repeatable computation (command line, environment variables, -// input file contents, executable contents). -type ActionID [HashSize]byte - -// An OutputID is a cache output key, the hash of an output of a computation. -type OutputID [HashSize]byte - -// A Cache is a package cache, backed by a file system directory tree. -type Cache struct { - dir string - now func() time.Time -} - -// Open opens and returns the cache in the given directory. -// -// It is safe for multiple processes on a single machine to use the -// same cache directory in a local file system simultaneously. -// They will coordinate using operating system file locks and may -// duplicate effort but will not corrupt the cache. -// -// However, it is NOT safe for multiple processes on different machines -// to share a cache directory (for example, if the directory were stored -// in a network file system). File locking is notoriously unreliable in -// network file systems and may not suffice to protect the cache. -// -func Open(dir string) (*Cache, error) { - info, err := os.Stat(dir) - if err != nil { - return nil, err - } - if !info.IsDir() { - return nil, &os.PathError{Op: "open", Path: dir, Err: fmt.Errorf("not a directory")} - } - for i := 0; i < 256; i++ { - name := filepath.Join(dir, fmt.Sprintf("%02x", i)) - if err := os.MkdirAll(name, 0777); err != nil { - return nil, err - } - } - c := &Cache{ - dir: dir, - now: time.Now, - } - return c, nil -} - -// fileName returns the name of the file corresponding to the given id. -func (c *Cache) fileName(id [HashSize]byte, key string) string { - return filepath.Join(c.dir, fmt.Sprintf("%02x", id[0]), fmt.Sprintf("%x", id)+"-"+key) -} - -var errMissing = errors.New("cache entry not found") - -const ( - // action entry file is "v1 \n" - hexSize = HashSize * 2 - entrySize = 2 + 1 + hexSize + 1 + hexSize + 1 + 20 + 1 + 20 + 1 -) - -// verify controls whether to run the cache in verify mode. -// In verify mode, the cache always returns errMissing from Get -// but then double-checks in Put that the data being written -// exactly matches any existing entry. This provides an easy -// way to detect program behavior that would have been different -// had the cache entry been returned from Get. -// -// verify is enabled by setting the environment variable -// GODEBUG=gocacheverify=1. -var verify = false - -// DebugTest is set when GODEBUG=gocachetest=1 is in the environment. -var DebugTest = false - -func init() { initEnv() } - -func initEnv() { - verify = false - debugHash = false - debug := strings.Split(os.Getenv("GODEBUG"), ",") - for _, f := range debug { - if f == "gocacheverify=1" { - verify = true - } - if f == "gocachehash=1" { - debugHash = true - } - if f == "gocachetest=1" { - DebugTest = true - } - } -} - -// Get looks up the action ID in the cache, -// returning the corresponding output ID and file size, if any. -// Note that finding an output ID does not guarantee that the -// saved file for that output ID is still available. -func (c *Cache) Get(id ActionID) (Entry, error) { - if verify { - return Entry{}, errMissing - } - return c.get(id) -} - -type Entry struct { - OutputID OutputID - Size int64 - Time time.Time -} - -// get is Get but does not respect verify mode, so that Put can use it. -func (c *Cache) get(id ActionID) (Entry, error) { - missing := func() (Entry, error) { - return Entry{}, errMissing - } - f, err := os.Open(c.fileName(id, "a")) - if err != nil { - return missing() - } - defer f.Close() - entry := make([]byte, entrySize+1) // +1 to detect whether f is too long - if n, err := io.ReadFull(f, entry); n != entrySize || err != io.ErrUnexpectedEOF { - return missing() - } - if entry[0] != 'v' || entry[1] != '1' || entry[2] != ' ' || entry[3+hexSize] != ' ' || entry[3+hexSize+1+hexSize] != ' ' || entry[3+hexSize+1+hexSize+1+20] != ' ' || entry[entrySize-1] != '\n' { - return missing() - } - eid, entry := entry[3:3+hexSize], entry[3+hexSize:] - eout, entry := entry[1:1+hexSize], entry[1+hexSize:] - esize, entry := entry[1:1+20], entry[1+20:] - //lint:ignore SA4006 See https://github.com/dominikh/go-tools/issues/465 - etime, entry := entry[1:1+20], entry[1+20:] - var buf [HashSize]byte - if _, err := hex.Decode(buf[:], eid); err != nil || buf != id { - return missing() - } - if _, err := hex.Decode(buf[:], eout); err != nil { - return missing() - } - i := 0 - for i < len(esize) && esize[i] == ' ' { - i++ - } - size, err := strconv.ParseInt(string(esize[i:]), 10, 64) - if err != nil || size < 0 { - return missing() - } - i = 0 - for i < len(etime) && etime[i] == ' ' { - i++ - } - tm, err := strconv.ParseInt(string(etime[i:]), 10, 64) - if err != nil || tm < 0 { - return missing() - } - - c.used(c.fileName(id, "a")) - - return Entry{buf, size, time.Unix(0, tm)}, nil -} - -// GetFile looks up the action ID in the cache and returns -// the name of the corresponding data file. -func (c *Cache) GetFile(id ActionID) (file string, entry Entry, err error) { - entry, err = c.Get(id) - if err != nil { - return "", Entry{}, err - } - file = c.OutputFile(entry.OutputID) - info, err := os.Stat(file) - if err != nil || info.Size() != entry.Size { - return "", Entry{}, errMissing - } - return file, entry, nil -} - -// GetBytes looks up the action ID in the cache and returns -// the corresponding output bytes. -// GetBytes should only be used for data that can be expected to fit in memory. -func (c *Cache) GetBytes(id ActionID) ([]byte, Entry, error) { - entry, err := c.Get(id) - if err != nil { - return nil, entry, err - } - data, _ := ioutil.ReadFile(c.OutputFile(entry.OutputID)) - if sha256.Sum256(data) != entry.OutputID { - return nil, entry, errMissing - } - return data, entry, nil -} - -// OutputFile returns the name of the cache file storing output with the given OutputID. -func (c *Cache) OutputFile(out OutputID) string { - file := c.fileName(out, "d") - c.used(file) - return file -} - -// Time constants for cache expiration. -// -// We set the mtime on a cache file on each use, but at most one per mtimeInterval (1 hour), -// to avoid causing many unnecessary inode updates. The mtimes therefore -// roughly reflect "time of last use" but may in fact be older by at most an hour. -// -// We scan the cache for entries to delete at most once per trimInterval (1 day). -// -// When we do scan the cache, we delete entries that have not been used for -// at least trimLimit (5 days). Statistics gathered from a month of usage by -// Go developers found that essentially all reuse of cached entries happened -// within 5 days of the previous reuse. See golang.org/issue/22990. -const ( - mtimeInterval = 1 * time.Hour - trimInterval = 24 * time.Hour - trimLimit = 5 * 24 * time.Hour -) - -// used makes a best-effort attempt to update mtime on file, -// so that mtime reflects cache access time. -// -// Because the reflection only needs to be approximate, -// and to reduce the amount of disk activity caused by using -// cache entries, used only updates the mtime if the current -// mtime is more than an hour old. This heuristic eliminates -// nearly all of the mtime updates that would otherwise happen, -// while still keeping the mtimes useful for cache trimming. -func (c *Cache) used(file string) { - info, err := os.Stat(file) - if err == nil && c.now().Sub(info.ModTime()) < mtimeInterval { - return - } - os.Chtimes(file, c.now(), c.now()) -} - -// Trim removes old cache entries that are likely not to be reused. -func (c *Cache) Trim() { - now := c.now() - - // We maintain in dir/trim.txt the time of the last completed cache trim. - // If the cache has been trimmed recently enough, do nothing. - // This is the common case. - data, _ := renameio.ReadFile(filepath.Join(c.dir, "trim.txt")) - t, err := strconv.ParseInt(strings.TrimSpace(string(data)), 10, 64) - if err == nil && now.Sub(time.Unix(t, 0)) < trimInterval { - return - } - - // Trim each of the 256 subdirectories. - // We subtract an additional mtimeInterval - // to account for the imprecision of our "last used" mtimes. - cutoff := now.Add(-trimLimit - mtimeInterval) - for i := 0; i < 256; i++ { - subdir := filepath.Join(c.dir, fmt.Sprintf("%02x", i)) - c.trimSubdir(subdir, cutoff) - } - - // Ignore errors from here: if we don't write the complete timestamp, the - // cache will appear older than it is, and we'll trim it again next time. - renameio.WriteFile(filepath.Join(c.dir, "trim.txt"), []byte(fmt.Sprintf("%d", now.Unix())), 0666) -} - -// trimSubdir trims a single cache subdirectory. -func (c *Cache) trimSubdir(subdir string, cutoff time.Time) { - // Read all directory entries from subdir before removing - // any files, in case removing files invalidates the file offset - // in the directory scan. Also, ignore error from f.Readdirnames, - // because we don't care about reporting the error and we still - // want to process any entries found before the error. - f, err := os.Open(subdir) - if err != nil { - return - } - names, _ := f.Readdirnames(-1) - f.Close() - - for _, name := range names { - // Remove only cache entries (xxxx-a and xxxx-d). - if !strings.HasSuffix(name, "-a") && !strings.HasSuffix(name, "-d") { - continue - } - entry := filepath.Join(subdir, name) - info, err := os.Stat(entry) - if err == nil && info.ModTime().Before(cutoff) { - os.Remove(entry) - } - } -} - -// putIndexEntry adds an entry to the cache recording that executing the action -// with the given id produces an output with the given output id (hash) and size. -func (c *Cache) putIndexEntry(id ActionID, out OutputID, size int64, allowVerify bool) error { - // Note: We expect that for one reason or another it may happen - // that repeating an action produces a different output hash - // (for example, if the output contains a time stamp or temp dir name). - // While not ideal, this is also not a correctness problem, so we - // don't make a big deal about it. In particular, we leave the action - // cache entries writable specifically so that they can be overwritten. - // - // Setting GODEBUG=gocacheverify=1 does make a big deal: - // in verify mode we are double-checking that the cache entries - // are entirely reproducible. As just noted, this may be unrealistic - // in some cases but the check is also useful for shaking out real bugs. - entry := fmt.Sprintf("v1 %x %x %20d %20d\n", id, out, size, time.Now().UnixNano()) - - if verify && allowVerify { - old, err := c.get(id) - if err == nil && (old.OutputID != out || old.Size != size) { - // panic to show stack trace, so we can see what code is generating this cache entry. - msg := fmt.Sprintf("go: internal cache error: cache verify failed: id=%x changed:<<<\n%s\n>>>\nold: %x %d\nnew: %x %d", id, reverseHash(id), out, size, old.OutputID, old.Size) - panic(msg) - } - } - file := c.fileName(id, "a") - - // Copy file to cache directory. - mode := os.O_WRONLY | os.O_CREATE - f, err := os.OpenFile(file, mode, 0666) - if err != nil { - return err - } - _, err = f.WriteString(entry) - if err == nil { - // Truncate the file only *after* writing it. - // (This should be a no-op, but truncate just in case of previous corruption.) - // - // This differs from ioutil.WriteFile, which truncates to 0 *before* writing - // via os.O_TRUNC. Truncating only after writing ensures that a second write - // of the same content to the same file is idempotent, and does not — even - // temporarily! — undo the effect of the first write. - err = f.Truncate(int64(len(entry))) - } - if closeErr := f.Close(); err == nil { - err = closeErr - } - if err != nil { - // TODO(bcmills): This Remove potentially races with another go command writing to file. - // Can we eliminate it? - os.Remove(file) - return err - } - os.Chtimes(file, c.now(), c.now()) // mainly for tests - - return nil -} - -// Put stores the given output in the cache as the output for the action ID. -// It may read file twice. The content of file must not change between the two passes. -func (c *Cache) Put(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - return c.put(id, file, true) -} - -// PutNoVerify is like Put but disables the verify check -// when GODEBUG=goverifycache=1 is set. -// It is meant for data that is OK to cache but that we expect to vary slightly from run to run, -// like test output containing times and the like. -func (c *Cache) PutNoVerify(id ActionID, file io.ReadSeeker) (OutputID, int64, error) { - return c.put(id, file, false) -} - -func (c *Cache) put(id ActionID, file io.ReadSeeker, allowVerify bool) (OutputID, int64, error) { - // Compute output ID. - h := sha256.New() - if _, err := file.Seek(0, 0); err != nil { - return OutputID{}, 0, err - } - size, err := io.Copy(h, file) - if err != nil { - return OutputID{}, 0, err - } - var out OutputID - h.Sum(out[:0]) - - // Copy to cached output file (if not already present). - if err := c.copyFile(file, out, size); err != nil { - return out, size, err - } - - // Add to cache index. - return out, size, c.putIndexEntry(id, out, size, allowVerify) -} - -// PutBytes stores the given bytes in the cache as the output for the action ID. -func (c *Cache) PutBytes(id ActionID, data []byte) error { - _, _, err := c.Put(id, bytes.NewReader(data)) - return err -} - -// copyFile copies file into the cache, expecting it to have the given -// output ID and size, if that file is not present already. -func (c *Cache) copyFile(file io.ReadSeeker, out OutputID, size int64) error { - name := c.fileName(out, "d") - info, err := os.Stat(name) - if err == nil && info.Size() == size { - // Check hash. - if f, err := os.Open(name); err == nil { - h := sha256.New() - io.Copy(h, f) - f.Close() - var out2 OutputID - h.Sum(out2[:0]) - if out == out2 { - return nil - } - } - // Hash did not match. Fall through and rewrite file. - } - - // Copy file to cache directory. - mode := os.O_RDWR | os.O_CREATE - if err == nil && info.Size() > size { // shouldn't happen but fix in case - mode |= os.O_TRUNC - } - f, err := os.OpenFile(name, mode, 0666) - if err != nil { - return err - } - defer f.Close() - if size == 0 { - // File now exists with correct size. - // Only one possible zero-length file, so contents are OK too. - // Early return here makes sure there's a "last byte" for code below. - return nil - } - - // From here on, if any of the I/O writing the file fails, - // we make a best-effort attempt to truncate the file f - // before returning, to avoid leaving bad bytes in the file. - - // Copy file to f, but also into h to double-check hash. - if _, err := file.Seek(0, 0); err != nil { - f.Truncate(0) - return err - } - h := sha256.New() - w := io.MultiWriter(f, h) - if _, err := io.CopyN(w, file, size-1); err != nil { - f.Truncate(0) - return err - } - // Check last byte before writing it; writing it will make the size match - // what other processes expect to find and might cause them to start - // using the file. - buf := make([]byte, 1) - if _, err := file.Read(buf); err != nil { - f.Truncate(0) - return err - } - h.Write(buf) - sum := h.Sum(nil) - if !bytes.Equal(sum, out[:]) { - f.Truncate(0) - return fmt.Errorf("file content changed underfoot") - } - - // Commit cache file entry. - if _, err := f.Write(buf); err != nil { - f.Truncate(0) - return err - } - if err := f.Close(); err != nil { - // Data might not have been written, - // but file may look like it is the right size. - // To be extra careful, remove cached file. - os.Remove(name) - return err - } - os.Chtimes(name, c.now(), c.now()) // mainly for tests - - return nil -} diff --git a/vendor/honnef.co/go/tools/internal/cache/default.go b/vendor/honnef.co/go/tools/internal/cache/default.go deleted file mode 100644 index 3034f76a5..000000000 --- a/vendor/honnef.co/go/tools/internal/cache/default.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cache - -import ( - "fmt" - "io/ioutil" - "log" - "os" - "path/filepath" - "sync" -) - -// Default returns the default cache to use. -func Default() (*Cache, error) { - defaultOnce.Do(initDefaultCache) - return defaultCache, defaultDirErr -} - -var ( - defaultOnce sync.Once - defaultCache *Cache -) - -// cacheREADME is a message stored in a README in the cache directory. -// Because the cache lives outside the normal Go trees, we leave the -// README as a courtesy to explain where it came from. -const cacheREADME = `This directory holds cached build artifacts from staticcheck. -` - -// initDefaultCache does the work of finding the default cache -// the first time Default is called. -func initDefaultCache() { - dir := DefaultDir() - if err := os.MkdirAll(dir, 0777); err != nil { - log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - if _, err := os.Stat(filepath.Join(dir, "README")); err != nil { - // Best effort. - ioutil.WriteFile(filepath.Join(dir, "README"), []byte(cacheREADME), 0666) - } - - c, err := Open(dir) - if err != nil { - log.Fatalf("failed to initialize build cache at %s: %s\n", dir, err) - } - defaultCache = c -} - -var ( - defaultDirOnce sync.Once - defaultDir string - defaultDirErr error -) - -// DefaultDir returns the effective STATICCHECK_CACHE setting. -func DefaultDir() string { - // Save the result of the first call to DefaultDir for later use in - // initDefaultCache. cmd/go/main.go explicitly sets GOCACHE so that - // subprocesses will inherit it, but that means initDefaultCache can't - // otherwise distinguish between an explicit "off" and a UserCacheDir error. - - defaultDirOnce.Do(func() { - defaultDir = os.Getenv("STATICCHECK_CACHE") - if filepath.IsAbs(defaultDir) { - return - } - if defaultDir != "" { - defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not an absolute path") - return - } - - // Compute default location. - dir, err := os.UserCacheDir() - if err != nil { - defaultDirErr = fmt.Errorf("STATICCHECK_CACHE is not defined and %v", err) - return - } - defaultDir = filepath.Join(dir, "staticcheck") - }) - - return defaultDir -} diff --git a/vendor/honnef.co/go/tools/internal/cache/hash.go b/vendor/honnef.co/go/tools/internal/cache/hash.go deleted file mode 100644 index a53543ec5..000000000 --- a/vendor/honnef.co/go/tools/internal/cache/hash.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package cache - -import ( - "bytes" - "crypto/sha256" - "fmt" - "hash" - "io" - "os" - "sync" -) - -var debugHash = false // set when GODEBUG=gocachehash=1 - -// HashSize is the number of bytes in a hash. -const HashSize = 32 - -// A Hash provides access to the canonical hash function used to index the cache. -// The current implementation uses salted SHA256, but clients must not assume this. -type Hash struct { - h hash.Hash - name string // for debugging - buf *bytes.Buffer // for verify -} - -// hashSalt is a salt string added to the beginning of every hash -// created by NewHash. Using the Staticcheck version makes sure that different -// versions of the command do not address the same cache -// entries, so that a bug in one version does not affect the execution -// of other versions. This salt will result in additional ActionID files -// in the cache, but not additional copies of the large output files, -// which are still addressed by unsalted SHA256. -var hashSalt []byte - -func SetSalt(b []byte) { - hashSalt = b -} - -// Subkey returns an action ID corresponding to mixing a parent -// action ID with a string description of the subkey. -func Subkey(parent ActionID, desc string) ActionID { - h := sha256.New() - h.Write([]byte("subkey:")) - h.Write(parent[:]) - h.Write([]byte(desc)) - var out ActionID - h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH subkey %x %q = %x\n", parent, desc, out) - } - if verify { - hashDebug.Lock() - hashDebug.m[out] = fmt.Sprintf("subkey %x %q", parent, desc) - hashDebug.Unlock() - } - return out -} - -// NewHash returns a new Hash. -// The caller is expected to Write data to it and then call Sum. -func NewHash(name string) *Hash { - h := &Hash{h: sha256.New(), name: name} - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]\n", h.name) - } - h.Write(hashSalt) - if verify { - h.buf = new(bytes.Buffer) - } - return h -} - -// Write writes data to the running hash. -func (h *Hash) Write(b []byte) (int, error) { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]: %q\n", h.name, b) - } - if h.buf != nil { - h.buf.Write(b) - } - return h.h.Write(b) -} - -// Sum returns the hash of the data written previously. -func (h *Hash) Sum() [HashSize]byte { - var out [HashSize]byte - h.h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH[%s]: %x\n", h.name, out) - } - if h.buf != nil { - hashDebug.Lock() - if hashDebug.m == nil { - hashDebug.m = make(map[[HashSize]byte]string) - } - hashDebug.m[out] = h.buf.String() - hashDebug.Unlock() - } - return out -} - -// In GODEBUG=gocacheverify=1 mode, -// hashDebug holds the input to every computed hash ID, -// so that we can work backward from the ID involved in a -// cache entry mismatch to a description of what should be there. -var hashDebug struct { - sync.Mutex - m map[[HashSize]byte]string -} - -// reverseHash returns the input used to compute the hash id. -func reverseHash(id [HashSize]byte) string { - hashDebug.Lock() - s := hashDebug.m[id] - hashDebug.Unlock() - return s -} - -var hashFileCache struct { - sync.Mutex - m map[string][HashSize]byte -} - -// FileHash returns the hash of the named file. -// It caches repeated lookups for a given file, -// and the cache entry for a file can be initialized -// using SetFileHash. -// The hash used by FileHash is not the same as -// the hash used by NewHash. -func FileHash(file string) ([HashSize]byte, error) { - hashFileCache.Lock() - out, ok := hashFileCache.m[file] - hashFileCache.Unlock() - - if ok { - return out, nil - } - - h := sha256.New() - f, err := os.Open(file) - if err != nil { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) - } - return [HashSize]byte{}, err - } - _, err = io.Copy(h, f) - f.Close() - if err != nil { - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %v\n", file, err) - } - return [HashSize]byte{}, err - } - h.Sum(out[:0]) - if debugHash { - fmt.Fprintf(os.Stderr, "HASH %s: %x\n", file, out) - } - - SetFileHash(file, out) - return out, nil -} - -// SetFileHash sets the hash returned by FileHash for file. -func SetFileHash(file string, sum [HashSize]byte) { - hashFileCache.Lock() - if hashFileCache.m == nil { - hashFileCache.m = make(map[string][HashSize]byte) - } - hashFileCache.m[file] = sum - hashFileCache.Unlock() -} diff --git a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go b/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go deleted file mode 100644 index 394697702..000000000 --- a/vendor/honnef.co/go/tools/internal/passes/buildir/buildir.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package buildir defines an Analyzer that constructs the IR -// of an error-free package and returns the set of all -// functions within it. It does not report any diagnostics itself but -// may be used as an input to other analyzers. -// -// THIS INTERFACE IS EXPERIMENTAL AND MAY BE SUBJECT TO INCOMPATIBLE CHANGE. -package buildir - -import ( - "go/ast" - "go/types" - "reflect" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/ir" -) - -type willExit struct{} -type willUnwind struct{} - -func (*willExit) AFact() {} -func (*willUnwind) AFact() {} - -var Analyzer = &analysis.Analyzer{ - Name: "buildir", - Doc: "build IR for later passes", - Run: run, - ResultType: reflect.TypeOf(new(IR)), - FactTypes: []analysis.Fact{new(willExit), new(willUnwind)}, -} - -// IR provides intermediate representation for all the -// non-blank source functions in the current package. -type IR struct { - Pkg *ir.Package - SrcFuncs []*ir.Function -} - -func run(pass *analysis.Pass) (interface{}, error) { - // Plundered from ssautil.BuildPackage. - - // We must create a new Program for each Package because the - // analysis API provides no place to hang a Program shared by - // all Packages. Consequently, IR Packages and Functions do not - // have a canonical representation across an analysis session of - // multiple packages. This is unlikely to be a problem in - // practice because the analysis API essentially forces all - // packages to be analysed independently, so any given call to - // Analysis.Run on a package will see only IR objects belonging - // to a single Program. - - mode := ir.GlobalDebug - - prog := ir.NewProgram(pass.Fset, mode) - - // Create IR packages for all imports. - // Order is not significant. - created := make(map[*types.Package]bool) - var createAll func(pkgs []*types.Package) - createAll = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !created[p] { - created[p] = true - irpkg := prog.CreatePackage(p, nil, nil, true) - for _, fn := range irpkg.Functions { - if ast.IsExported(fn.Name()) { - var exit willExit - var unwind willUnwind - if pass.ImportObjectFact(fn.Object(), &exit) { - fn.WillExit = true - } - if pass.ImportObjectFact(fn.Object(), &unwind) { - fn.WillUnwind = true - } - } - } - createAll(p.Imports()) - } - } - } - createAll(pass.Pkg.Imports()) - - // Create and build the primary package. - irpkg := prog.CreatePackage(pass.Pkg, pass.Files, pass.TypesInfo, false) - irpkg.Build() - - // Compute list of source functions, including literals, - // in source order. - var addAnons func(f *ir.Function) - funcs := make([]*ir.Function, len(irpkg.Functions)) - copy(funcs, irpkg.Functions) - addAnons = func(f *ir.Function) { - for _, anon := range f.AnonFuncs { - funcs = append(funcs, anon) - addAnons(anon) - } - } - for _, fn := range irpkg.Functions { - addAnons(fn) - if fn.WillExit { - pass.ExportObjectFact(fn.Object(), new(willExit)) - } - if fn.WillUnwind { - pass.ExportObjectFact(fn.Object(), new(willUnwind)) - } - } - - return &IR{Pkg: irpkg, SrcFuncs: funcs}, nil -} diff --git a/vendor/honnef.co/go/tools/internal/renameio/renameio.go b/vendor/honnef.co/go/tools/internal/renameio/renameio.go deleted file mode 100644 index a279d1a1e..000000000 --- a/vendor/honnef.co/go/tools/internal/renameio/renameio.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package renameio writes files atomically by renaming temporary files. -package renameio - -import ( - "bytes" - "io" - "math/rand" - "os" - "path/filepath" - "strconv" - - "honnef.co/go/tools/internal/robustio" -) - -const patternSuffix = ".tmp" - -// Pattern returns a glob pattern that matches the unrenamed temporary files -// created when writing to filename. -func Pattern(filename string) string { - return filepath.Join(filepath.Dir(filename), filepath.Base(filename)+patternSuffix) -} - -// WriteFile is like ioutil.WriteFile, but first writes data to an arbitrary -// file in the same directory as filename, then renames it atomically to the -// final name. -// -// That ensures that the final location, if it exists, is always a complete file. -func WriteFile(filename string, data []byte, perm os.FileMode) (err error) { - return WriteToFile(filename, bytes.NewReader(data), perm) -} - -// WriteToFile is a variant of WriteFile that accepts the data as an io.Reader -// instead of a slice. -func WriteToFile(filename string, data io.Reader, perm os.FileMode) (err error) { - f, err := tempFile(filepath.Dir(filename), filepath.Base(filename), perm) - if err != nil { - return err - } - defer func() { - // Only call os.Remove on f.Name() if we failed to rename it: otherwise, - // some other process may have created a new file with the same name after - // that. - if err != nil { - f.Close() - os.Remove(f.Name()) - } - }() - - if _, err := io.Copy(f, data); err != nil { - return err - } - // Sync the file before renaming it: otherwise, after a crash the reader may - // observe a 0-length file instead of the actual contents. - // See https://golang.org/issue/22397#issuecomment-380831736. - if err := f.Sync(); err != nil { - return err - } - if err := f.Close(); err != nil { - return err - } - - return robustio.Rename(f.Name(), filename) -} - -// tempFile creates a new temporary file with given permission bits. -func tempFile(dir, prefix string, perm os.FileMode) (f *os.File, err error) { - for i := 0; i < 10000; i++ { - name := filepath.Join(dir, prefix+strconv.Itoa(rand.Intn(1000000000))+patternSuffix) - f, err = os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, perm) - if os.IsExist(err) { - continue - } - break - } - return -} - -// ReadFile is like ioutil.ReadFile, but on Windows retries spurious errors that -// may occur if the file is concurrently replaced. -// -// Errors are classified heuristically and retries are bounded, so even this -// function may occasionally return a spurious error on Windows. -// If so, the error will likely wrap one of: -// - syscall.ERROR_ACCESS_DENIED -// - syscall.ERROR_FILE_NOT_FOUND -// - internal/syscall/windows.ERROR_SHARING_VIOLATION -func ReadFile(filename string) ([]byte, error) { - return robustio.ReadFile(filename) -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio.go b/vendor/honnef.co/go/tools/internal/robustio/robustio.go deleted file mode 100644 index 76e47ad1f..000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package robustio wraps I/O functions that are prone to failure on Windows, -// transparently retrying errors up to an arbitrary timeout. -// -// Errors are classified heuristically and retries are bounded, so the functions -// in this package do not completely eliminate spurious errors. However, they do -// significantly reduce the rate of failure in practice. -// -// If so, the error will likely wrap one of: -// The functions in this package do not completely eliminate spurious errors, -// but substantially reduce their rate of occurrence in practice. -package robustio - -// Rename is like os.Rename, but on Windows retries errors that may occur if the -// file is concurrently read or overwritten. -// -// (See golang.org/issue/31247 and golang.org/issue/32188.) -func Rename(oldpath, newpath string) error { - return rename(oldpath, newpath) -} - -// ReadFile is like ioutil.ReadFile, but on Windows retries errors that may -// occur if the file is concurrently replaced. -// -// (See golang.org/issue/31247 and golang.org/issue/32188.) -func ReadFile(filename string) ([]byte, error) { - return readFile(filename) -} - -// RemoveAll is like os.RemoveAll, but on Windows retries errors that may occur -// if an executable file in the directory has recently been executed. -// -// (See golang.org/issue/19491.) -func RemoveAll(path string) error { - return removeAll(path) -} - -// IsEphemeralError reports whether err is one of the errors that the functions -// in this package attempt to mitigate. -// -// Errors considered ephemeral include: -// - syscall.ERROR_ACCESS_DENIED -// - syscall.ERROR_FILE_NOT_FOUND -// - internal/syscall/windows.ERROR_SHARING_VIOLATION -// -// This set may be expanded in the future; programs must not rely on the -// non-ephemerality of any given error. -func IsEphemeralError(err error) bool { - return isEphemeralError(err) -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go deleted file mode 100644 index 1ac0d10d7..000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_darwin.go +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package robustio - -import ( - "os" - "syscall" -) - -const errFileNotFound = syscall.ENOENT - -// isEphemeralError returns true if err may be resolved by waiting. -func isEphemeralError(err error) bool { - switch werr := err.(type) { - case *os.PathError: - err = werr.Err - case *os.LinkError: - err = werr.Err - case *os.SyscallError: - err = werr.Err - - } - if errno, ok := err.(syscall.Errno); ok { - return errno == errFileNotFound - } - return false -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go deleted file mode 100644 index e0bf5b9b3..000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_flaky.go +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows darwin - -package robustio - -import ( - "io/ioutil" - "math/rand" - "os" - "syscall" - "time" -) - -const arbitraryTimeout = 500 * time.Millisecond - -const ERROR_SHARING_VIOLATION = 32 - -// retry retries ephemeral errors from f up to an arbitrary timeout -// to work around filesystem flakiness on Windows and Darwin. -func retry(f func() (err error, mayRetry bool)) error { - var ( - bestErr error - lowestErrno syscall.Errno - start time.Time - nextSleep time.Duration = 1 * time.Millisecond - ) - for { - err, mayRetry := f() - if err == nil || !mayRetry { - return err - } - - if errno, ok := err.(syscall.Errno); ok && (lowestErrno == 0 || errno < lowestErrno) { - bestErr = err - lowestErrno = errno - } else if bestErr == nil { - bestErr = err - } - - if start.IsZero() { - start = time.Now() - } else if d := time.Since(start) + nextSleep; d >= arbitraryTimeout { - break - } - time.Sleep(nextSleep) - nextSleep += time.Duration(rand.Int63n(int64(nextSleep))) - } - - return bestErr -} - -// rename is like os.Rename, but retries ephemeral errors. -// -// On windows it wraps os.Rename, which (as of 2019-06-04) uses MoveFileEx with -// MOVEFILE_REPLACE_EXISTING. -// -// Windows also provides a different system call, ReplaceFile, -// that provides similar semantics, but perhaps preserves more metadata. (The -// documentation on the differences between the two is very sparse.) -// -// Empirical error rates with MoveFileEx are lower under modest concurrency, so -// for now we're sticking with what the os package already provides. -func rename(oldpath, newpath string) (err error) { - return retry(func() (err error, mayRetry bool) { - err = os.Rename(oldpath, newpath) - return err, isEphemeralError(err) - }) -} - -// readFile is like ioutil.ReadFile, but retries ephemeral errors. -func readFile(filename string) ([]byte, error) { - var b []byte - err := retry(func() (err error, mayRetry bool) { - b, err = ioutil.ReadFile(filename) - - // Unlike in rename, we do not retry errFileNotFound here: it can occur - // as a spurious error, but the file may also genuinely not exist, so the - // increase in robustness is probably not worth the extra latency. - - return err, isEphemeralError(err) && err != errFileNotFound - }) - return b, err -} - -func removeAll(path string) error { - return retry(func() (err error, mayRetry bool) { - err = os.RemoveAll(path) - return err, isEphemeralError(err) - }) -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go deleted file mode 100644 index a2428856f..000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_other.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//+build !windows,!darwin - -package robustio - -import ( - "io/ioutil" - "os" -) - -func rename(oldpath, newpath string) error { - return os.Rename(oldpath, newpath) -} - -func readFile(filename string) ([]byte, error) { - return ioutil.ReadFile(filename) -} - -func removeAll(path string) error { - return os.RemoveAll(path) -} - -func isEphemeralError(err error) bool { - return false -} diff --git a/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go b/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go deleted file mode 100644 index a35237d44..000000000 --- a/vendor/honnef.co/go/tools/internal/robustio/robustio_windows.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package robustio - -import ( - "os" - "syscall" -) - -const errFileNotFound = syscall.ERROR_FILE_NOT_FOUND - -// isEphemeralError returns true if err may be resolved by waiting. -func isEphemeralError(err error) bool { - switch werr := err.(type) { - case *os.PathError: - err = werr.Err - case *os.LinkError: - err = werr.Err - case *os.SyscallError: - err = werr.Err - } - if errno, ok := err.(syscall.Errno); ok { - switch errno { - case syscall.ERROR_ACCESS_DENIED, - syscall.ERROR_FILE_NOT_FOUND, - ERROR_SHARING_VIOLATION: - return true - } - } - return false -} diff --git a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go b/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go deleted file mode 100644 index e9abf0d89..000000000 --- a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go +++ /dev/null @@ -1,71 +0,0 @@ -package sharedcheck - -import ( - "go/ast" - "go/types" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/code" - "honnef.co/go/tools/internal/passes/buildir" - "honnef.co/go/tools/ir" - . "honnef.co/go/tools/lint/lintdsl" -) - -func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) { - for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs { - cb := func(node ast.Node) bool { - rng, ok := node.(*ast.RangeStmt) - if !ok || !code.IsBlank(rng.Key) { - return true - } - - v, _ := fn.ValueForExpr(rng.X) - - // Check that we're converting from string to []rune - val, _ := v.(*ir.Convert) - if val == nil { - return true - } - Tsrc, ok := val.X.Type().(*types.Basic) - if !ok || Tsrc.Kind() != types.String { - return true - } - Tdst, ok := val.Type().(*types.Slice) - if !ok { - return true - } - TdstElem, ok := Tdst.Elem().(*types.Basic) - if !ok || TdstElem.Kind() != types.Int32 { - return true - } - - // Check that the result of the conversion is only used to - // range over - refs := val.Referrers() - if refs == nil { - return true - } - - // Expect two refs: one for obtaining the length of the slice, - // one for accessing the elements - if len(code.FilterDebug(*refs)) != 2 { - // TODO(dh): right now, we check that only one place - // refers to our slice. This will miss cases such as - // ranging over the slice twice. Ideally, we'd ensure that - // the slice is only used for ranging over (without - // accessing the key), but that is harder to do because in - // IR form, ranging over a slice looks like an ordinary - // loop with index increments and slice accesses. We'd - // have to look at the associated AST node to check that - // it's a range statement. - return true - } - - pass.Reportf(rng.Pos(), "should range over string, not []rune(string)") - - return true - } - Inspect(fn.Source(), cb) - } - return nil, nil -} diff --git a/vendor/honnef.co/go/tools/ir/LICENSE b/vendor/honnef.co/go/tools/ir/LICENSE deleted file mode 100644 index aee48041e..000000000 --- a/vendor/honnef.co/go/tools/ir/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. -Copyright (c) 2016 Dominik Honnef. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/honnef.co/go/tools/ir/blockopt.go b/vendor/honnef.co/go/tools/ir/blockopt.go deleted file mode 100644 index d7a0e3567..000000000 --- a/vendor/honnef.co/go/tools/ir/blockopt.go +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// Simple block optimizations to simplify the control flow graph. - -// TODO(adonovan): opt: instead of creating several "unreachable" blocks -// per function in the Builder, reuse a single one (e.g. at Blocks[1]) -// to reduce garbage. - -import ( - "fmt" - "os" -) - -// If true, perform sanity checking and show progress at each -// successive iteration of optimizeBlocks. Very verbose. -const debugBlockOpt = false - -// markReachable sets Index=-1 for all blocks reachable from b. -func markReachable(b *BasicBlock) { - b.gaps = -1 - for _, succ := range b.Succs { - if succ.gaps == 0 { - markReachable(succ) - } - } -} - -// deleteUnreachableBlocks marks all reachable blocks of f and -// eliminates (nils) all others, including possibly cyclic subgraphs. -// -func deleteUnreachableBlocks(f *Function) { - const white, black = 0, -1 - // We borrow b.gaps temporarily as the mark bit. - for _, b := range f.Blocks { - b.gaps = white - } - markReachable(f.Blocks[0]) - // In SSI form, we need the exit to be reachable for correct - // post-dominance information. In original form, however, we - // cannot unconditionally mark it reachable because we won't - // be adding fake edges, and this breaks the calculation of - // dominance information. - markReachable(f.Exit) - for i, b := range f.Blocks { - if b.gaps == white { - for _, c := range b.Succs { - if c.gaps == black { - c.removePred(b) // delete white->black edge - } - } - if debugBlockOpt { - fmt.Fprintln(os.Stderr, "unreachable", b) - } - f.Blocks[i] = nil // delete b - } - } - f.removeNilBlocks() -} - -// jumpThreading attempts to apply simple jump-threading to block b, -// in which a->b->c become a->c if b is just a Jump. -// The result is true if the optimization was applied. -// -func jumpThreading(f *Function, b *BasicBlock) bool { - if b.Index == 0 { - return false // don't apply to entry block - } - if b.Instrs == nil { - return false - } - for _, pred := range b.Preds { - switch pred.Control().(type) { - case *ConstantSwitch: - // don't optimize away the head blocks of switch statements - return false - } - } - if _, ok := b.Instrs[0].(*Jump); !ok { - return false // not just a jump - } - c := b.Succs[0] - if c == b { - return false // don't apply to degenerate jump-to-self. - } - if c.hasPhi() { - return false // not sound without more effort - } - for j, a := range b.Preds { - a.replaceSucc(b, c) - - // If a now has two edges to c, replace its degenerate If by Jump. - if len(a.Succs) == 2 && a.Succs[0] == c && a.Succs[1] == c { - jump := new(Jump) - jump.setBlock(a) - a.Instrs[len(a.Instrs)-1] = jump - a.Succs = a.Succs[:1] - c.removePred(b) - } else { - if j == 0 { - c.replacePred(b, a) - } else { - c.Preds = append(c.Preds, a) - } - } - - if debugBlockOpt { - fmt.Fprintln(os.Stderr, "jumpThreading", a, b, c) - } - } - f.Blocks[b.Index] = nil // delete b - return true -} - -// fuseBlocks attempts to apply the block fusion optimization to block -// a, in which a->b becomes ab if len(a.Succs)==len(b.Preds)==1. -// The result is true if the optimization was applied. -// -func fuseBlocks(f *Function, a *BasicBlock) bool { - if len(a.Succs) != 1 { - return false - } - if a.Succs[0] == f.Exit { - return false - } - b := a.Succs[0] - if len(b.Preds) != 1 { - return false - } - if _, ok := a.Instrs[len(a.Instrs)-1].(*Panic); ok { - // panics aren't simple jumps, they have side effects. - return false - } - - // Degenerate &&/|| ops may result in a straight-line CFG - // containing φ-nodes. (Ideally we'd replace such them with - // their sole operand but that requires Referrers, built later.) - if b.hasPhi() { - return false // not sound without further effort - } - - // Eliminate jump at end of A, then copy all of B across. - a.Instrs = append(a.Instrs[:len(a.Instrs)-1], b.Instrs...) - for _, instr := range b.Instrs { - instr.setBlock(a) - } - - // A inherits B's successors - a.Succs = append(a.succs2[:0], b.Succs...) - - // Fix up Preds links of all successors of B. - for _, c := range b.Succs { - c.replacePred(b, a) - } - - if debugBlockOpt { - fmt.Fprintln(os.Stderr, "fuseBlocks", a, b) - } - - f.Blocks[b.Index] = nil // delete b - return true -} - -// optimizeBlocks() performs some simple block optimizations on a -// completed function: dead block elimination, block fusion, jump -// threading. -// -func optimizeBlocks(f *Function) { - if debugBlockOpt { - f.WriteTo(os.Stderr) - mustSanityCheck(f, nil) - } - - deleteUnreachableBlocks(f) - - // Loop until no further progress. - changed := true - for changed { - changed = false - - if debugBlockOpt { - f.WriteTo(os.Stderr) - mustSanityCheck(f, nil) - } - - for _, b := range f.Blocks { - // f.Blocks will temporarily contain nils to indicate - // deleted blocks; we remove them at the end. - if b == nil { - continue - } - - // Fuse blocks. b->c becomes bc. - if fuseBlocks(f, b) { - changed = true - } - - // a->b->c becomes a->c if b contains only a Jump. - if jumpThreading(f, b) { - changed = true - continue // (b was disconnected) - } - } - } - f.removeNilBlocks() -} diff --git a/vendor/honnef.co/go/tools/ir/builder.go b/vendor/honnef.co/go/tools/ir/builder.go deleted file mode 100644 index fdf4cb1a9..000000000 --- a/vendor/honnef.co/go/tools/ir/builder.go +++ /dev/null @@ -1,2474 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file implements the BUILD phase of IR construction. -// -// IR construction has two phases, CREATE and BUILD. In the CREATE phase -// (create.go), all packages are constructed and type-checked and -// definitions of all package members are created, method-sets are -// computed, and wrapper methods are synthesized. -// ir.Packages are created in arbitrary order. -// -// In the BUILD phase (builder.go), the builder traverses the AST of -// each Go source function and generates IR instructions for the -// function body. Initializer expressions for package-level variables -// are emitted to the package's init() function in the order specified -// by go/types.Info.InitOrder, then code for each function in the -// package is generated in lexical order. -// -// The builder's and Program's indices (maps) are populated and -// mutated during the CREATE phase, but during the BUILD phase they -// remain constant. The sole exception is Prog.methodSets and its -// related maps, which are protected by a dedicated mutex. - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" - "os" -) - -type opaqueType struct { - types.Type - name string -} - -func (t *opaqueType) String() string { return t.name } - -var ( - varOk = newVar("ok", tBool) - varIndex = newVar("index", tInt) - - // Type constants. - tBool = types.Typ[types.Bool] - tByte = types.Typ[types.Byte] - tInt = types.Typ[types.Int] - tInvalid = types.Typ[types.Invalid] - tString = types.Typ[types.String] - tUntypedNil = types.Typ[types.UntypedNil] - tRangeIter = &opaqueType{nil, "iter"} // the type of all "range" iterators - tEface = types.NewInterfaceType(nil, nil).Complete() -) - -// builder holds state associated with the package currently being built. -// Its methods contain all the logic for AST-to-IR conversion. -type builder struct { - printFunc string - - blocksets [5]BlockSet -} - -// cond emits to fn code to evaluate boolean condition e and jump -// to t or f depending on its value, performing various simplifications. -// -// Postcondition: fn.currentBlock is nil. -// -func (b *builder) cond(fn *Function, e ast.Expr, t, f *BasicBlock) *If { - switch e := e.(type) { - case *ast.ParenExpr: - return b.cond(fn, e.X, t, f) - - case *ast.BinaryExpr: - switch e.Op { - case token.LAND: - ltrue := fn.newBasicBlock("cond.true") - b.cond(fn, e.X, ltrue, f) - fn.currentBlock = ltrue - return b.cond(fn, e.Y, t, f) - - case token.LOR: - lfalse := fn.newBasicBlock("cond.false") - b.cond(fn, e.X, t, lfalse) - fn.currentBlock = lfalse - return b.cond(fn, e.Y, t, f) - } - - case *ast.UnaryExpr: - if e.Op == token.NOT { - return b.cond(fn, e.X, f, t) - } - } - - // A traditional compiler would simplify "if false" (etc) here - // but we do not, for better fidelity to the source code. - // - // The value of a constant condition may be platform-specific, - // and may cause blocks that are reachable in some configuration - // to be hidden from subsequent analyses such as bug-finding tools. - return emitIf(fn, b.expr(fn, e), t, f, e) -} - -// logicalBinop emits code to fn to evaluate e, a &&- or -// ||-expression whose reified boolean value is wanted. -// The value is returned. -// -func (b *builder) logicalBinop(fn *Function, e *ast.BinaryExpr) Value { - rhs := fn.newBasicBlock("binop.rhs") - done := fn.newBasicBlock("binop.done") - - // T(e) = T(e.X) = T(e.Y) after untyped constants have been - // eliminated. - // TODO(adonovan): not true; MyBool==MyBool yields UntypedBool. - t := fn.Pkg.typeOf(e) - - var short Value // value of the short-circuit path - switch e.Op { - case token.LAND: - b.cond(fn, e.X, rhs, done) - short = emitConst(fn, NewConst(constant.MakeBool(false), t)) - - case token.LOR: - b.cond(fn, e.X, done, rhs) - short = emitConst(fn, NewConst(constant.MakeBool(true), t)) - } - - // Is rhs unreachable? - if rhs.Preds == nil { - // Simplify false&&y to false, true||y to true. - fn.currentBlock = done - return short - } - - // Is done unreachable? - if done.Preds == nil { - // Simplify true&&y (or false||y) to y. - fn.currentBlock = rhs - return b.expr(fn, e.Y) - } - - // All edges from e.X to done carry the short-circuit value. - var edges []Value - for range done.Preds { - edges = append(edges, short) - } - - // The edge from e.Y to done carries the value of e.Y. - fn.currentBlock = rhs - edges = append(edges, b.expr(fn, e.Y)) - emitJump(fn, done, e) - fn.currentBlock = done - - phi := &Phi{Edges: edges} - phi.typ = t - return done.emit(phi, e) -} - -// exprN lowers a multi-result expression e to IR form, emitting code -// to fn and returning a single Value whose type is a *types.Tuple. -// The caller must access the components via Extract. -// -// Multi-result expressions include CallExprs in a multi-value -// assignment or return statement, and "value,ok" uses of -// TypeAssertExpr, IndexExpr (when X is a map), and Recv. -// -func (b *builder) exprN(fn *Function, e ast.Expr) Value { - typ := fn.Pkg.typeOf(e).(*types.Tuple) - switch e := e.(type) { - case *ast.ParenExpr: - return b.exprN(fn, e.X) - - case *ast.CallExpr: - // Currently, no built-in function nor type conversion - // has multiple results, so we can avoid some of the - // cases for single-valued CallExpr. - var c Call - b.setCall(fn, e, &c.Call) - c.typ = typ - return fn.emit(&c, e) - - case *ast.IndexExpr: - mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map) - lookup := &MapLookup{ - X: b.expr(fn, e.X), - Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key(), e), - CommaOk: true, - } - lookup.setType(typ) - return fn.emit(lookup, e) - - case *ast.TypeAssertExpr: - return emitTypeTest(fn, b.expr(fn, e.X), typ.At(0).Type(), e) - - case *ast.UnaryExpr: // must be receive <- - return emitRecv(fn, b.expr(fn, e.X), true, typ, e) - } - panic(fmt.Sprintf("exprN(%T) in %s", e, fn)) -} - -// builtin emits to fn IR instructions to implement a call to the -// built-in function obj with the specified arguments -// and return type. It returns the value defined by the result. -// -// The result is nil if no special handling was required; in this case -// the caller should treat this like an ordinary library function -// call. -// -func (b *builder) builtin(fn *Function, obj *types.Builtin, args []ast.Expr, typ types.Type, source ast.Node) Value { - switch obj.Name() { - case "make": - switch typ.Underlying().(type) { - case *types.Slice: - n := b.expr(fn, args[1]) - m := n - if len(args) == 3 { - m = b.expr(fn, args[2]) - } - if m, ok := m.(*Const); ok { - // treat make([]T, n, m) as new([m]T)[:n] - cap := m.Int64() - at := types.NewArray(typ.Underlying().(*types.Slice).Elem(), cap) - alloc := emitNew(fn, at, source) - v := &Slice{ - X: alloc, - High: n, - } - v.setType(typ) - return fn.emit(v, source) - } - v := &MakeSlice{ - Len: n, - Cap: m, - } - v.setType(typ) - return fn.emit(v, source) - - case *types.Map: - var res Value - if len(args) == 2 { - res = b.expr(fn, args[1]) - } - v := &MakeMap{Reserve: res} - v.setType(typ) - return fn.emit(v, source) - - case *types.Chan: - var sz Value = emitConst(fn, intConst(0)) - if len(args) == 2 { - sz = b.expr(fn, args[1]) - } - v := &MakeChan{Size: sz} - v.setType(typ) - return fn.emit(v, source) - } - - case "new": - alloc := emitNew(fn, deref(typ), source) - return alloc - - case "len", "cap": - // Special case: len or cap of an array or *array is - // based on the type, not the value which may be nil. - // We must still evaluate the value, though. (If it - // was side-effect free, the whole call would have - // been constant-folded.) - t := deref(fn.Pkg.typeOf(args[0])).Underlying() - if at, ok := t.(*types.Array); ok { - b.expr(fn, args[0]) // for effects only - return emitConst(fn, intConst(at.Len())) - } - // Otherwise treat as normal. - - case "panic": - fn.emit(&Panic{ - X: emitConv(fn, b.expr(fn, args[0]), tEface, source), - }, source) - addEdge(fn.currentBlock, fn.Exit) - fn.currentBlock = fn.newBasicBlock("unreachable") - return emitConst(fn, NewConst(constant.MakeBool(true), tBool)) // any non-nil Value will do - } - return nil // treat all others as a regular function call -} - -// addr lowers a single-result addressable expression e to IR form, -// emitting code to fn and returning the location (an lvalue) defined -// by the expression. -// -// If escaping is true, addr marks the base variable of the -// addressable expression e as being a potentially escaping pointer -// value. For example, in this code: -// -// a := A{ -// b: [1]B{B{c: 1}} -// } -// return &a.b[0].c -// -// the application of & causes a.b[0].c to have its address taken, -// which means that ultimately the local variable a must be -// heap-allocated. This is a simple but very conservative escape -// analysis. -// -// Operations forming potentially escaping pointers include: -// - &x, including when implicit in method call or composite literals. -// - a[:] iff a is an array (not *array) -// - references to variables in lexically enclosing functions. -// -func (b *builder) addr(fn *Function, e ast.Expr, escaping bool) lvalue { - switch e := e.(type) { - case *ast.Ident: - if isBlankIdent(e) { - return blank{} - } - obj := fn.Pkg.objectOf(e) - v := fn.Prog.packageLevelValue(obj) // var (address) - if v == nil { - v = fn.lookup(obj, escaping) - } - return &address{addr: v, expr: e} - - case *ast.CompositeLit: - t := deref(fn.Pkg.typeOf(e)) - var v *Alloc - if escaping { - v = emitNew(fn, t, e) - } else { - v = fn.addLocal(t, e) - } - var sb storebuf - b.compLit(fn, v, e, true, &sb) - sb.emit(fn) - return &address{addr: v, expr: e} - - case *ast.ParenExpr: - return b.addr(fn, e.X, escaping) - - case *ast.SelectorExpr: - sel, ok := fn.Pkg.info.Selections[e] - if !ok { - // qualified identifier - return b.addr(fn, e.Sel, escaping) - } - if sel.Kind() != types.FieldVal { - panic(sel) - } - wantAddr := true - v := b.receiver(fn, e.X, wantAddr, escaping, sel, e) - last := len(sel.Index()) - 1 - return &address{ - addr: emitFieldSelection(fn, v, sel.Index()[last], true, e.Sel), - expr: e.Sel, - } - - case *ast.IndexExpr: - var x Value - var et types.Type - switch t := fn.Pkg.typeOf(e.X).Underlying().(type) { - case *types.Array: - x = b.addr(fn, e.X, escaping).address(fn) - et = types.NewPointer(t.Elem()) - case *types.Pointer: // *array - x = b.expr(fn, e.X) - et = types.NewPointer(t.Elem().Underlying().(*types.Array).Elem()) - case *types.Slice: - x = b.expr(fn, e.X) - et = types.NewPointer(t.Elem()) - case *types.Map: - return &element{ - m: b.expr(fn, e.X), - k: emitConv(fn, b.expr(fn, e.Index), t.Key(), e.Index), - t: t.Elem(), - } - default: - panic("unexpected container type in IndexExpr: " + t.String()) - } - v := &IndexAddr{ - X: x, - Index: emitConv(fn, b.expr(fn, e.Index), tInt, e.Index), - } - v.setType(et) - return &address{addr: fn.emit(v, e), expr: e} - - case *ast.StarExpr: - return &address{addr: b.expr(fn, e.X), expr: e} - } - - panic(fmt.Sprintf("unexpected address expression: %T", e)) -} - -type store struct { - lhs lvalue - rhs Value - source ast.Node -} - -type storebuf struct{ stores []store } - -func (sb *storebuf) store(lhs lvalue, rhs Value, source ast.Node) { - sb.stores = append(sb.stores, store{lhs, rhs, source}) -} - -func (sb *storebuf) emit(fn *Function) { - for _, s := range sb.stores { - s.lhs.store(fn, s.rhs, s.source) - } -} - -// assign emits to fn code to initialize the lvalue loc with the value -// of expression e. If isZero is true, assign assumes that loc holds -// the zero value for its type. -// -// This is equivalent to loc.store(fn, b.expr(fn, e)), but may generate -// better code in some cases, e.g., for composite literals in an -// addressable location. -// -// If sb is not nil, assign generates code to evaluate expression e, but -// not to update loc. Instead, the necessary stores are appended to the -// storebuf sb so that they can be executed later. This allows correct -// in-place update of existing variables when the RHS is a composite -// literal that may reference parts of the LHS. -// -func (b *builder) assign(fn *Function, loc lvalue, e ast.Expr, isZero bool, sb *storebuf, source ast.Node) { - // Can we initialize it in place? - if e, ok := unparen(e).(*ast.CompositeLit); ok { - // A CompositeLit never evaluates to a pointer, - // so if the type of the location is a pointer, - // an &-operation is implied. - if _, ok := loc.(blank); !ok { // avoid calling blank.typ() - if isPointer(loc.typ()) { - ptr := b.addr(fn, e, true).address(fn) - // copy address - if sb != nil { - sb.store(loc, ptr, source) - } else { - loc.store(fn, ptr, source) - } - return - } - } - - if _, ok := loc.(*address); ok { - if isInterface(loc.typ()) { - // e.g. var x interface{} = T{...} - // Can't in-place initialize an interface value. - // Fall back to copying. - } else { - // x = T{...} or x := T{...} - addr := loc.address(fn) - if sb != nil { - b.compLit(fn, addr, e, isZero, sb) - } else { - var sb storebuf - b.compLit(fn, addr, e, isZero, &sb) - sb.emit(fn) - } - - // Subtle: emit debug ref for aggregate types only; - // slice and map are handled by store ops in compLit. - switch loc.typ().Underlying().(type) { - case *types.Struct, *types.Array: - emitDebugRef(fn, e, addr, true) - } - - return - } - } - } - - // simple case: just copy - rhs := b.expr(fn, e) - if sb != nil { - sb.store(loc, rhs, source) - } else { - loc.store(fn, rhs, source) - } -} - -// expr lowers a single-result expression e to IR form, emitting code -// to fn and returning the Value defined by the expression. -// -func (b *builder) expr(fn *Function, e ast.Expr) Value { - e = unparen(e) - - tv := fn.Pkg.info.Types[e] - - // Is expression a constant? - if tv.Value != nil { - return emitConst(fn, NewConst(tv.Value, tv.Type)) - } - - var v Value - if tv.Addressable() { - // Prefer pointer arithmetic ({Index,Field}Addr) followed - // by Load over subelement extraction (e.g. Index, Field), - // to avoid large copies. - v = b.addr(fn, e, false).load(fn, e) - } else { - v = b.expr0(fn, e, tv) - } - if fn.debugInfo() { - emitDebugRef(fn, e, v, false) - } - return v -} - -func (b *builder) expr0(fn *Function, e ast.Expr, tv types.TypeAndValue) Value { - switch e := e.(type) { - case *ast.BasicLit: - panic("non-constant BasicLit") // unreachable - - case *ast.FuncLit: - fn2 := &Function{ - name: fmt.Sprintf("%s$%d", fn.Name(), 1+len(fn.AnonFuncs)), - Signature: fn.Pkg.typeOf(e.Type).Underlying().(*types.Signature), - parent: fn, - Pkg: fn.Pkg, - Prog: fn.Prog, - functionBody: new(functionBody), - } - fn2.source = e - fn.AnonFuncs = append(fn.AnonFuncs, fn2) - fn2.initHTML(b.printFunc) - b.buildFunction(fn2) - if fn2.FreeVars == nil { - return fn2 - } - v := &MakeClosure{Fn: fn2} - v.setType(tv.Type) - for _, fv := range fn2.FreeVars { - v.Bindings = append(v.Bindings, fv.outer) - fv.outer = nil - } - return fn.emit(v, e) - - case *ast.TypeAssertExpr: // single-result form only - return emitTypeAssert(fn, b.expr(fn, e.X), tv.Type, e) - - case *ast.CallExpr: - if fn.Pkg.info.Types[e.Fun].IsType() { - // Explicit type conversion, e.g. string(x) or big.Int(x) - x := b.expr(fn, e.Args[0]) - y := emitConv(fn, x, tv.Type, e) - return y - } - // Call to "intrinsic" built-ins, e.g. new, make, panic. - if id, ok := unparen(e.Fun).(*ast.Ident); ok { - if obj, ok := fn.Pkg.info.Uses[id].(*types.Builtin); ok { - if v := b.builtin(fn, obj, e.Args, tv.Type, e); v != nil { - return v - } - } - } - // Regular function call. - var v Call - b.setCall(fn, e, &v.Call) - v.setType(tv.Type) - return fn.emit(&v, e) - - case *ast.UnaryExpr: - switch e.Op { - case token.AND: // &X --- potentially escaping. - addr := b.addr(fn, e.X, true) - if _, ok := unparen(e.X).(*ast.StarExpr); ok { - // &*p must panic if p is nil (http://golang.org/s/go12nil). - // For simplicity, we'll just (suboptimally) rely - // on the side effects of a load. - // TODO(adonovan): emit dedicated nilcheck. - addr.load(fn, e) - } - return addr.address(fn) - case token.ADD: - return b.expr(fn, e.X) - case token.NOT, token.SUB, token.XOR: // ! <- - ^ - v := &UnOp{ - Op: e.Op, - X: b.expr(fn, e.X), - } - v.setType(tv.Type) - return fn.emit(v, e) - case token.ARROW: - return emitRecv(fn, b.expr(fn, e.X), false, tv.Type, e) - default: - panic(e.Op) - } - - case *ast.BinaryExpr: - switch e.Op { - case token.LAND, token.LOR: - return b.logicalBinop(fn, e) - case token.SHL, token.SHR: - fallthrough - case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT: - return emitArith(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), tv.Type, e) - - case token.EQL, token.NEQ, token.GTR, token.LSS, token.LEQ, token.GEQ: - cmp := emitCompare(fn, e.Op, b.expr(fn, e.X), b.expr(fn, e.Y), e) - // The type of x==y may be UntypedBool. - return emitConv(fn, cmp, types.Default(tv.Type), e) - default: - panic("illegal op in BinaryExpr: " + e.Op.String()) - } - - case *ast.SliceExpr: - var low, high, max Value - var x Value - switch fn.Pkg.typeOf(e.X).Underlying().(type) { - case *types.Array: - // Potentially escaping. - x = b.addr(fn, e.X, true).address(fn) - case *types.Basic, *types.Slice, *types.Pointer: // *array - x = b.expr(fn, e.X) - default: - panic("unreachable") - } - if e.High != nil { - high = b.expr(fn, e.High) - } - if e.Low != nil { - low = b.expr(fn, e.Low) - } - if e.Slice3 { - max = b.expr(fn, e.Max) - } - v := &Slice{ - X: x, - Low: low, - High: high, - Max: max, - } - v.setType(tv.Type) - return fn.emit(v, e) - - case *ast.Ident: - obj := fn.Pkg.info.Uses[e] - // Universal built-in or nil? - switch obj := obj.(type) { - case *types.Builtin: - return &Builtin{name: obj.Name(), sig: tv.Type.(*types.Signature)} - case *types.Nil: - return emitConst(fn, nilConst(tv.Type)) - } - // Package-level func or var? - if v := fn.Prog.packageLevelValue(obj); v != nil { - if _, ok := obj.(*types.Var); ok { - return emitLoad(fn, v, e) // var (address) - } - return v // (func) - } - // Local var. - return emitLoad(fn, fn.lookup(obj, false), e) // var (address) - - case *ast.SelectorExpr: - sel, ok := fn.Pkg.info.Selections[e] - if !ok { - // qualified identifier - return b.expr(fn, e.Sel) - } - switch sel.Kind() { - case types.MethodExpr: - // (*T).f or T.f, the method f from the method-set of type T. - // The result is a "thunk". - return emitConv(fn, makeThunk(fn.Prog, sel), tv.Type, e) - - case types.MethodVal: - // e.f where e is an expression and f is a method. - // The result is a "bound". - obj := sel.Obj().(*types.Func) - rt := recvType(obj) - wantAddr := isPointer(rt) - escaping := true - v := b.receiver(fn, e.X, wantAddr, escaping, sel, e) - if isInterface(rt) { - // If v has interface type I, - // we must emit a check that v is non-nil. - // We use: typeassert v.(I). - emitTypeAssert(fn, v, rt, e) - } - c := &MakeClosure{ - Fn: makeBound(fn.Prog, obj), - Bindings: []Value{v}, - } - c.source = e.Sel - c.setType(tv.Type) - return fn.emit(c, e) - - case types.FieldVal: - indices := sel.Index() - last := len(indices) - 1 - v := b.expr(fn, e.X) - v = emitImplicitSelections(fn, v, indices[:last], e) - v = emitFieldSelection(fn, v, indices[last], false, e.Sel) - return v - } - - panic("unexpected expression-relative selector") - - case *ast.IndexExpr: - switch t := fn.Pkg.typeOf(e.X).Underlying().(type) { - case *types.Array: - // Non-addressable array (in a register). - v := &Index{ - X: b.expr(fn, e.X), - Index: emitConv(fn, b.expr(fn, e.Index), tInt, e.Index), - } - v.setType(t.Elem()) - return fn.emit(v, e) - - case *types.Map: - // Maps are not addressable. - mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map) - v := &MapLookup{ - X: b.expr(fn, e.X), - Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key(), e.Index), - } - v.setType(mapt.Elem()) - return fn.emit(v, e) - - case *types.Basic: // => string - // Strings are not addressable. - v := &StringLookup{ - X: b.expr(fn, e.X), - Index: b.expr(fn, e.Index), - } - v.setType(tByte) - return fn.emit(v, e) - - case *types.Slice, *types.Pointer: // *array - // Addressable slice/array; use IndexAddr and Load. - return b.addr(fn, e, false).load(fn, e) - - default: - panic("unexpected container type in IndexExpr: " + t.String()) - } - - case *ast.CompositeLit, *ast.StarExpr: - // Addressable types (lvalues) - return b.addr(fn, e, false).load(fn, e) - } - - panic(fmt.Sprintf("unexpected expr: %T", e)) -} - -// stmtList emits to fn code for all statements in list. -func (b *builder) stmtList(fn *Function, list []ast.Stmt) { - for _, s := range list { - b.stmt(fn, s) - } -} - -// receiver emits to fn code for expression e in the "receiver" -// position of selection e.f (where f may be a field or a method) and -// returns the effective receiver after applying the implicit field -// selections of sel. -// -// wantAddr requests that the result is an an address. If -// !sel.Indirect(), this may require that e be built in addr() mode; it -// must thus be addressable. -// -// escaping is defined as per builder.addr(). -// -func (b *builder) receiver(fn *Function, e ast.Expr, wantAddr, escaping bool, sel *types.Selection, source ast.Node) Value { - var v Value - if wantAddr && !sel.Indirect() && !isPointer(fn.Pkg.typeOf(e)) { - v = b.addr(fn, e, escaping).address(fn) - } else { - v = b.expr(fn, e) - } - - last := len(sel.Index()) - 1 - v = emitImplicitSelections(fn, v, sel.Index()[:last], source) - if !wantAddr && isPointer(v.Type()) { - v = emitLoad(fn, v, e) - } - return v -} - -// setCallFunc populates the function parts of a CallCommon structure -// (Func, Method, Recv, Args[0]) based on the kind of invocation -// occurring in e. -// -func (b *builder) setCallFunc(fn *Function, e *ast.CallExpr, c *CallCommon) { - // Is this a method call? - if selector, ok := unparen(e.Fun).(*ast.SelectorExpr); ok { - sel, ok := fn.Pkg.info.Selections[selector] - if ok && sel.Kind() == types.MethodVal { - obj := sel.Obj().(*types.Func) - recv := recvType(obj) - wantAddr := isPointer(recv) - escaping := true - v := b.receiver(fn, selector.X, wantAddr, escaping, sel, selector) - if isInterface(recv) { - // Invoke-mode call. - c.Value = v - c.Method = obj - } else { - // "Call"-mode call. - c.Value = fn.Prog.declaredFunc(obj) - c.Args = append(c.Args, v) - } - return - } - - // sel.Kind()==MethodExpr indicates T.f() or (*T).f(): - // a statically dispatched call to the method f in the - // method-set of T or *T. T may be an interface. - // - // e.Fun would evaluate to a concrete method, interface - // wrapper function, or promotion wrapper. - // - // For now, we evaluate it in the usual way. - // - // TODO(adonovan): opt: inline expr() here, to make the - // call static and to avoid generation of wrappers. - // It's somewhat tricky as it may consume the first - // actual parameter if the call is "invoke" mode. - // - // Examples: - // type T struct{}; func (T) f() {} // "call" mode - // type T interface { f() } // "invoke" mode - // - // type S struct{ T } - // - // var s S - // S.f(s) - // (*S).f(&s) - // - // Suggested approach: - // - consume the first actual parameter expression - // and build it with b.expr(). - // - apply implicit field selections. - // - use MethodVal logic to populate fields of c. - } - - // Evaluate the function operand in the usual way. - c.Value = b.expr(fn, e.Fun) -} - -// emitCallArgs emits to f code for the actual parameters of call e to -// a (possibly built-in) function of effective type sig. -// The argument values are appended to args, which is then returned. -// -func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallExpr, args []Value) []Value { - // f(x, y, z...): pass slice z straight through. - if e.Ellipsis != 0 { - for i, arg := range e.Args { - v := emitConv(fn, b.expr(fn, arg), sig.Params().At(i).Type(), arg) - args = append(args, v) - } - return args - } - - offset := len(args) // 1 if call has receiver, 0 otherwise - - // Evaluate actual parameter expressions. - // - // If this is a chained call of the form f(g()) where g has - // multiple return values (MRV), they are flattened out into - // args; a suffix of them may end up in a varargs slice. - for _, arg := range e.Args { - v := b.expr(fn, arg) - if ttuple, ok := v.Type().(*types.Tuple); ok { // MRV chain - for i, n := 0, ttuple.Len(); i < n; i++ { - args = append(args, emitExtract(fn, v, i, arg)) - } - } else { - args = append(args, v) - } - } - - // Actual->formal assignability conversions for normal parameters. - np := sig.Params().Len() // number of normal parameters - if sig.Variadic() { - np-- - } - for i := 0; i < np; i++ { - args[offset+i] = emitConv(fn, args[offset+i], sig.Params().At(i).Type(), args[offset+i].Source()) - } - - // Actual->formal assignability conversions for variadic parameter, - // and construction of slice. - if sig.Variadic() { - varargs := args[offset+np:] - st := sig.Params().At(np).Type().(*types.Slice) - vt := st.Elem() - if len(varargs) == 0 { - args = append(args, emitConst(fn, nilConst(st))) - } else { - // Replace a suffix of args with a slice containing it. - at := types.NewArray(vt, int64(len(varargs))) - a := emitNew(fn, at, e) - a.source = e - for i, arg := range varargs { - iaddr := &IndexAddr{ - X: a, - Index: emitConst(fn, intConst(int64(i))), - } - iaddr.setType(types.NewPointer(vt)) - fn.emit(iaddr, e) - emitStore(fn, iaddr, arg, arg.Source()) - } - s := &Slice{X: a} - s.setType(st) - args[offset+np] = fn.emit(s, args[offset+np].Source()) - args = args[:offset+np+1] - } - } - return args -} - -// setCall emits to fn code to evaluate all the parameters of a function -// call e, and populates *c with those values. -// -func (b *builder) setCall(fn *Function, e *ast.CallExpr, c *CallCommon) { - // First deal with the f(...) part and optional receiver. - b.setCallFunc(fn, e, c) - - // Then append the other actual parameters. - sig, _ := fn.Pkg.typeOf(e.Fun).Underlying().(*types.Signature) - if sig == nil { - panic(fmt.Sprintf("no signature for call of %s", e.Fun)) - } - c.Args = b.emitCallArgs(fn, sig, e, c.Args) -} - -// assignOp emits to fn code to perform loc = val. -func (b *builder) assignOp(fn *Function, loc lvalue, val Value, op token.Token, source ast.Node) { - oldv := loc.load(fn, source) - loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, val, oldv.Type(), source), loc.typ(), source), source) -} - -// localValueSpec emits to fn code to define all of the vars in the -// function-local ValueSpec, spec. -// -func (b *builder) localValueSpec(fn *Function, spec *ast.ValueSpec) { - switch { - case len(spec.Values) == len(spec.Names): - // e.g. var x, y = 0, 1 - // 1:1 assignment - for i, id := range spec.Names { - if !isBlankIdent(id) { - fn.addLocalForIdent(id) - } - lval := b.addr(fn, id, false) // non-escaping - b.assign(fn, lval, spec.Values[i], true, nil, spec) - } - - case len(spec.Values) == 0: - // e.g. var x, y int - // Locals are implicitly zero-initialized. - for _, id := range spec.Names { - if !isBlankIdent(id) { - lhs := fn.addLocalForIdent(id) - if fn.debugInfo() { - emitDebugRef(fn, id, lhs, true) - } - } - } - - default: - // e.g. var x, y = pos() - tuple := b.exprN(fn, spec.Values[0]) - for i, id := range spec.Names { - if !isBlankIdent(id) { - fn.addLocalForIdent(id) - lhs := b.addr(fn, id, false) // non-escaping - lhs.store(fn, emitExtract(fn, tuple, i, id), id) - } - } - } -} - -// assignStmt emits code to fn for a parallel assignment of rhss to lhss. -// isDef is true if this is a short variable declaration (:=). -// -// Note the similarity with localValueSpec. -// -func (b *builder) assignStmt(fn *Function, lhss, rhss []ast.Expr, isDef bool, source ast.Node) { - // Side effects of all LHSs and RHSs must occur in left-to-right order. - lvals := make([]lvalue, len(lhss)) - isZero := make([]bool, len(lhss)) - for i, lhs := range lhss { - var lval lvalue = blank{} - if !isBlankIdent(lhs) { - if isDef { - if obj := fn.Pkg.info.Defs[lhs.(*ast.Ident)]; obj != nil { - fn.addNamedLocal(obj, lhs) - isZero[i] = true - } - } - lval = b.addr(fn, lhs, false) // non-escaping - } - lvals[i] = lval - } - if len(lhss) == len(rhss) { - // Simple assignment: x = f() (!isDef) - // Parallel assignment: x, y = f(), g() (!isDef) - // or short var decl: x, y := f(), g() (isDef) - // - // In all cases, the RHSs may refer to the LHSs, - // so we need a storebuf. - var sb storebuf - for i := range rhss { - b.assign(fn, lvals[i], rhss[i], isZero[i], &sb, source) - } - sb.emit(fn) - } else { - // e.g. x, y = pos() - tuple := b.exprN(fn, rhss[0]) - emitDebugRef(fn, rhss[0], tuple, false) - for i, lval := range lvals { - lval.store(fn, emitExtract(fn, tuple, i, source), source) - } - } -} - -// arrayLen returns the length of the array whose composite literal elements are elts. -func (b *builder) arrayLen(fn *Function, elts []ast.Expr) int64 { - var max int64 = -1 - var i int64 = -1 - for _, e := range elts { - if kv, ok := e.(*ast.KeyValueExpr); ok { - i = b.expr(fn, kv.Key).(*Const).Int64() - } else { - i++ - } - if i > max { - max = i - } - } - return max + 1 -} - -// compLit emits to fn code to initialize a composite literal e at -// address addr with type typ. -// -// Nested composite literals are recursively initialized in place -// where possible. If isZero is true, compLit assumes that addr -// holds the zero value for typ. -// -// Because the elements of a composite literal may refer to the -// variables being updated, as in the second line below, -// x := T{a: 1} -// x = T{a: x.a} -// all the reads must occur before all the writes. Thus all stores to -// loc are emitted to the storebuf sb for later execution. -// -// A CompositeLit may have pointer type only in the recursive (nested) -// case when the type name is implicit. e.g. in []*T{{}}, the inner -// literal has type *T behaves like &T{}. -// In that case, addr must hold a T, not a *T. -// -func (b *builder) compLit(fn *Function, addr Value, e *ast.CompositeLit, isZero bool, sb *storebuf) { - typ := deref(fn.Pkg.typeOf(e)) - switch t := typ.Underlying().(type) { - case *types.Struct: - if !isZero && len(e.Elts) != t.NumFields() { - // memclear - sb.store(&address{addr, nil}, zeroValue(fn, deref(addr.Type()), e), e) - isZero = true - } - for i, e := range e.Elts { - fieldIndex := i - if kv, ok := e.(*ast.KeyValueExpr); ok { - fname := kv.Key.(*ast.Ident).Name - for i, n := 0, t.NumFields(); i < n; i++ { - sf := t.Field(i) - if sf.Name() == fname { - fieldIndex = i - e = kv.Value - break - } - } - } - sf := t.Field(fieldIndex) - faddr := &FieldAddr{ - X: addr, - Field: fieldIndex, - } - faddr.setType(types.NewPointer(sf.Type())) - fn.emit(faddr, e) - b.assign(fn, &address{addr: faddr, expr: e}, e, isZero, sb, e) - } - - case *types.Array, *types.Slice: - var at *types.Array - var array Value - switch t := t.(type) { - case *types.Slice: - at = types.NewArray(t.Elem(), b.arrayLen(fn, e.Elts)) - alloc := emitNew(fn, at, e) - array = alloc - case *types.Array: - at = t - array = addr - - if !isZero && int64(len(e.Elts)) != at.Len() { - // memclear - sb.store(&address{array, nil}, zeroValue(fn, deref(array.Type()), e), e) - } - } - - var idx *Const - for _, e := range e.Elts { - if kv, ok := e.(*ast.KeyValueExpr); ok { - idx = b.expr(fn, kv.Key).(*Const) - e = kv.Value - } else { - var idxval int64 - if idx != nil { - idxval = idx.Int64() + 1 - } - idx = emitConst(fn, intConst(idxval)) - } - iaddr := &IndexAddr{ - X: array, - Index: idx, - } - iaddr.setType(types.NewPointer(at.Elem())) - fn.emit(iaddr, e) - if t != at { // slice - // backing array is unaliased => storebuf not needed. - b.assign(fn, &address{addr: iaddr, expr: e}, e, true, nil, e) - } else { - b.assign(fn, &address{addr: iaddr, expr: e}, e, true, sb, e) - } - } - - if t != at { // slice - s := &Slice{X: array} - s.setType(typ) - sb.store(&address{addr: addr, expr: e}, fn.emit(s, e), e) - } - - case *types.Map: - m := &MakeMap{Reserve: emitConst(fn, intConst(int64(len(e.Elts))))} - m.setType(typ) - fn.emit(m, e) - for _, e := range e.Elts { - e := e.(*ast.KeyValueExpr) - - // If a key expression in a map literal is itself a - // composite literal, the type may be omitted. - // For example: - // map[*struct{}]bool{{}: true} - // An &-operation may be implied: - // map[*struct{}]bool{&struct{}{}: true} - var key Value - if _, ok := unparen(e.Key).(*ast.CompositeLit); ok && isPointer(t.Key()) { - // A CompositeLit never evaluates to a pointer, - // so if the type of the location is a pointer, - // an &-operation is implied. - key = b.addr(fn, e.Key, true).address(fn) - } else { - key = b.expr(fn, e.Key) - } - - loc := element{ - m: m, - k: emitConv(fn, key, t.Key(), e), - t: t.Elem(), - } - - // We call assign() only because it takes care - // of any &-operation required in the recursive - // case, e.g., - // map[int]*struct{}{0: {}} implies &struct{}{}. - // In-place update is of course impossible, - // and no storebuf is needed. - b.assign(fn, &loc, e.Value, true, nil, e) - } - sb.store(&address{addr: addr, expr: e}, m, e) - - default: - panic("unexpected CompositeLit type: " + t.String()) - } -} - -func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) { - if s.Tag == nil { - b.switchStmtDynamic(fn, s, label) - return - } - dynamic := false - for _, iclause := range s.Body.List { - clause := iclause.(*ast.CaseClause) - for _, cond := range clause.List { - if fn.Pkg.info.Types[unparen(cond)].Value == nil { - dynamic = true - break - } - } - } - - if dynamic { - b.switchStmtDynamic(fn, s, label) - return - } - - if s.Init != nil { - b.stmt(fn, s.Init) - } - - entry := fn.currentBlock - tag := b.expr(fn, s.Tag) - - heads := make([]*BasicBlock, 0, len(s.Body.List)) - bodies := make([]*BasicBlock, len(s.Body.List)) - conds := make([]Value, 0, len(s.Body.List)) - - hasDefault := false - done := fn.newBasicBlock(fmt.Sprintf("switch.done")) - if label != nil { - label._break = done - } - for i, stmt := range s.Body.List { - body := fn.newBasicBlock(fmt.Sprintf("switch.body.%d", i)) - bodies[i] = body - cas := stmt.(*ast.CaseClause) - if cas.List == nil { - // default branch - hasDefault = true - head := fn.newBasicBlock(fmt.Sprintf("switch.head.%d", i)) - conds = append(conds, nil) - heads = append(heads, head) - fn.currentBlock = head - emitJump(fn, body, cas) - } - for j, cond := range stmt.(*ast.CaseClause).List { - fn.currentBlock = entry - head := fn.newBasicBlock(fmt.Sprintf("switch.head.%d.%d", i, j)) - conds = append(conds, b.expr(fn, cond)) - heads = append(heads, head) - fn.currentBlock = head - emitJump(fn, body, cond) - } - } - - for i, stmt := range s.Body.List { - clause := stmt.(*ast.CaseClause) - body := bodies[i] - fn.currentBlock = body - fallthru := done - if i+1 < len(bodies) { - fallthru = bodies[i+1] - } - fn.targets = &targets{ - tail: fn.targets, - _break: done, - _fallthrough: fallthru, - } - b.stmtList(fn, clause.Body) - fn.targets = fn.targets.tail - emitJump(fn, done, stmt) - } - - if !hasDefault { - head := fn.newBasicBlock(fmt.Sprintf("switch.head.implicit-default")) - body := fn.newBasicBlock("switch.body.implicit-default") - fn.currentBlock = head - emitJump(fn, body, s) - fn.currentBlock = body - emitJump(fn, done, s) - heads = append(heads, head) - conds = append(conds, nil) - } - - if len(heads) != len(conds) { - panic(fmt.Sprintf("internal error: %d heads for %d conds", len(heads), len(conds))) - } - for _, head := range heads { - addEdge(entry, head) - } - fn.currentBlock = entry - entry.emit(&ConstantSwitch{ - Tag: tag, - Conds: conds, - }, s) - fn.currentBlock = done -} - -// switchStmt emits to fn code for the switch statement s, optionally -// labelled by label. -// -func (b *builder) switchStmtDynamic(fn *Function, s *ast.SwitchStmt, label *lblock) { - // We treat SwitchStmt like a sequential if-else chain. - // Multiway dispatch can be recovered later by irutil.Switches() - // to those cases that are free of side effects. - if s.Init != nil { - b.stmt(fn, s.Init) - } - kTrue := emitConst(fn, NewConst(constant.MakeBool(true), tBool)) - - var tagv Value = kTrue - var tagSource ast.Node = s - if s.Tag != nil { - tagv = b.expr(fn, s.Tag) - tagSource = s.Tag - } - // lifting only considers loads and stores, but we want different - // sigma nodes for the different comparisons. use a temporary and - // load it in every branch. - tag := fn.addLocal(tagv.Type(), tagSource) - emitStore(fn, tag, tagv, tagSource) - - done := fn.newBasicBlock("switch.done") - if label != nil { - label._break = done - } - // We pull the default case (if present) down to the end. - // But each fallthrough label must point to the next - // body block in source order, so we preallocate a - // body block (fallthru) for the next case. - // Unfortunately this makes for a confusing block order. - var dfltBody *[]ast.Stmt - var dfltFallthrough *BasicBlock - var fallthru, dfltBlock *BasicBlock - ncases := len(s.Body.List) - for i, clause := range s.Body.List { - body := fallthru - if body == nil { - body = fn.newBasicBlock("switch.body") // first case only - } - - // Preallocate body block for the next case. - fallthru = done - if i+1 < ncases { - fallthru = fn.newBasicBlock("switch.body") - } - - cc := clause.(*ast.CaseClause) - if cc.List == nil { - // Default case. - dfltBody = &cc.Body - dfltFallthrough = fallthru - dfltBlock = body - continue - } - - var nextCond *BasicBlock - for _, cond := range cc.List { - nextCond = fn.newBasicBlock("switch.next") - if tagv == kTrue { - // emit a proper if/else chain instead of a comparison - // of a value against true. - // - // NOTE(dh): adonovan had a todo saying "don't forget - // conversions though". As far as I can tell, there - // aren't any conversions that we need to take care of - // here. `case bool(a) && bool(b)` as well as `case - // bool(a && b)` are being taken care of by b.cond, - // and `case a` where a is not of type bool is - // invalid. - b.cond(fn, cond, body, nextCond) - } else { - cond := emitCompare(fn, token.EQL, emitLoad(fn, tag, cond), b.expr(fn, cond), cond) - emitIf(fn, cond, body, nextCond, cond.Source()) - } - - fn.currentBlock = nextCond - } - fn.currentBlock = body - fn.targets = &targets{ - tail: fn.targets, - _break: done, - _fallthrough: fallthru, - } - b.stmtList(fn, cc.Body) - fn.targets = fn.targets.tail - emitJump(fn, done, s) - fn.currentBlock = nextCond - } - if dfltBlock != nil { - // The lack of a Source for the jump doesn't matter, block - // fusing will get rid of the jump later. - - emitJump(fn, dfltBlock, s) - fn.currentBlock = dfltBlock - fn.targets = &targets{ - tail: fn.targets, - _break: done, - _fallthrough: dfltFallthrough, - } - b.stmtList(fn, *dfltBody) - fn.targets = fn.targets.tail - } - emitJump(fn, done, s) - fn.currentBlock = done -} - -func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) { - if s.Init != nil { - b.stmt(fn, s.Init) - } - - var tag Value - switch e := s.Assign.(type) { - case *ast.ExprStmt: // x.(type) - tag = b.expr(fn, unparen(e.X).(*ast.TypeAssertExpr).X) - case *ast.AssignStmt: // y := x.(type) - tag = b.expr(fn, unparen(e.Rhs[0]).(*ast.TypeAssertExpr).X) - default: - panic("unreachable") - } - tagPtr := fn.addLocal(tag.Type(), tag.Source()) - emitStore(fn, tagPtr, tag, tag.Source()) - - // +1 in case there's no explicit default case - heads := make([]*BasicBlock, 0, len(s.Body.List)+1) - - entry := fn.currentBlock - done := fn.newBasicBlock("done") - if label != nil { - label._break = done - } - - // set up type switch and constant switch, populate their conditions - tswtch := &TypeSwitch{ - Tag: emitLoad(fn, tagPtr, tag.Source()), - Conds: make([]types.Type, 0, len(s.Body.List)+1), - } - cswtch := &ConstantSwitch{ - Conds: make([]Value, 0, len(s.Body.List)+1), - } - - rets := make([]types.Type, 0, len(s.Body.List)+1) - index := 0 - var default_ *ast.CaseClause - for _, clause := range s.Body.List { - cc := clause.(*ast.CaseClause) - if obj := fn.Pkg.info.Implicits[cc]; obj != nil { - fn.addNamedLocal(obj, cc) - } - if cc.List == nil { - // default case - default_ = cc - } else { - for _, expr := range cc.List { - tswtch.Conds = append(tswtch.Conds, fn.Pkg.typeOf(expr)) - cswtch.Conds = append(cswtch.Conds, emitConst(fn, intConst(int64(index)))) - index++ - } - if len(cc.List) == 1 { - rets = append(rets, fn.Pkg.typeOf(cc.List[0])) - } else { - for range cc.List { - rets = append(rets, tag.Type()) - } - } - } - } - - // default branch - rets = append(rets, tag.Type()) - - var vars []*types.Var - vars = append(vars, varIndex) - for _, typ := range rets { - vars = append(vars, anonVar(typ)) - } - tswtch.setType(types.NewTuple(vars...)) - // default branch - fn.currentBlock = entry - fn.emit(tswtch, s) - cswtch.Conds = append(cswtch.Conds, emitConst(fn, intConst(int64(-1)))) - // in theory we should add a local and stores/loads for tswtch, to - // generate sigma nodes in the branches. however, there isn't any - // useful information we could possibly attach to it. - cswtch.Tag = emitExtract(fn, tswtch, 0, s) - fn.emit(cswtch, s) - - // build heads and bodies - index = 0 - for _, clause := range s.Body.List { - cc := clause.(*ast.CaseClause) - if cc.List == nil { - continue - } - - body := fn.newBasicBlock("typeswitch.body") - for _, expr := range cc.List { - head := fn.newBasicBlock("typeswitch.head") - heads = append(heads, head) - fn.currentBlock = head - - if obj := fn.Pkg.info.Implicits[cc]; obj != nil { - // In a switch y := x.(type), each case clause - // implicitly declares a distinct object y. - // In a single-type case, y has that type. - // In multi-type cases, 'case nil' and default, - // y has the same type as the interface operand. - - l := fn.objects[obj] - if rets[index] == tUntypedNil { - emitStore(fn, l, emitConst(fn, nilConst(tswtch.Tag.Type())), s.Assign) - } else { - x := emitExtract(fn, tswtch, index+1, s.Assign) - emitStore(fn, l, x, nil) - } - } - - emitJump(fn, body, expr) - index++ - } - fn.currentBlock = body - fn.targets = &targets{ - tail: fn.targets, - _break: done, - } - b.stmtList(fn, cc.Body) - fn.targets = fn.targets.tail - emitJump(fn, done, clause) - } - - if default_ == nil { - // implicit default - heads = append(heads, done) - } else { - body := fn.newBasicBlock("typeswitch.default") - heads = append(heads, body) - fn.currentBlock = body - fn.targets = &targets{ - tail: fn.targets, - _break: done, - } - if obj := fn.Pkg.info.Implicits[default_]; obj != nil { - l := fn.objects[obj] - x := emitExtract(fn, tswtch, index+1, s.Assign) - emitStore(fn, l, x, s) - } - b.stmtList(fn, default_.Body) - fn.targets = fn.targets.tail - emitJump(fn, done, s) - } - - fn.currentBlock = entry - for _, head := range heads { - addEdge(entry, head) - } - fn.currentBlock = done -} - -// selectStmt emits to fn code for the select statement s, optionally -// labelled by label. -// -func (b *builder) selectStmt(fn *Function, s *ast.SelectStmt, label *lblock) (noreturn bool) { - if len(s.Body.List) == 0 { - instr := &Select{Blocking: true} - instr.setType(types.NewTuple(varIndex, varOk)) - fn.emit(instr, s) - fn.emit(new(Unreachable), s) - addEdge(fn.currentBlock, fn.Exit) - return true - } - - // A blocking select of a single case degenerates to a - // simple send or receive. - // TODO(adonovan): opt: is this optimization worth its weight? - if len(s.Body.List) == 1 { - clause := s.Body.List[0].(*ast.CommClause) - if clause.Comm != nil { - b.stmt(fn, clause.Comm) - done := fn.newBasicBlock("select.done") - if label != nil { - label._break = done - } - fn.targets = &targets{ - tail: fn.targets, - _break: done, - } - b.stmtList(fn, clause.Body) - fn.targets = fn.targets.tail - emitJump(fn, done, clause) - fn.currentBlock = done - return false - } - } - - // First evaluate all channels in all cases, and find - // the directions of each state. - var states []*SelectState - blocking := true - debugInfo := fn.debugInfo() - for _, clause := range s.Body.List { - var st *SelectState - switch comm := clause.(*ast.CommClause).Comm.(type) { - case nil: // default case - blocking = false - continue - - case *ast.SendStmt: // ch<- i - ch := b.expr(fn, comm.Chan) - st = &SelectState{ - Dir: types.SendOnly, - Chan: ch, - Send: emitConv(fn, b.expr(fn, comm.Value), - ch.Type().Underlying().(*types.Chan).Elem(), comm), - Pos: comm.Arrow, - } - if debugInfo { - st.DebugNode = comm - } - - case *ast.AssignStmt: // x := <-ch - recv := unparen(comm.Rhs[0]).(*ast.UnaryExpr) - st = &SelectState{ - Dir: types.RecvOnly, - Chan: b.expr(fn, recv.X), - Pos: recv.OpPos, - } - if debugInfo { - st.DebugNode = recv - } - - case *ast.ExprStmt: // <-ch - recv := unparen(comm.X).(*ast.UnaryExpr) - st = &SelectState{ - Dir: types.RecvOnly, - Chan: b.expr(fn, recv.X), - Pos: recv.OpPos, - } - if debugInfo { - st.DebugNode = recv - } - } - states = append(states, st) - } - - // We dispatch on the (fair) result of Select using a - // switch on the returned index. - sel := &Select{ - States: states, - Blocking: blocking, - } - sel.source = s - var vars []*types.Var - vars = append(vars, varIndex, varOk) - for _, st := range states { - if st.Dir == types.RecvOnly { - tElem := st.Chan.Type().Underlying().(*types.Chan).Elem() - vars = append(vars, anonVar(tElem)) - } - } - sel.setType(types.NewTuple(vars...)) - fn.emit(sel, s) - idx := emitExtract(fn, sel, 0, s) - - done := fn.newBasicBlock("select.done") - if label != nil { - label._break = done - } - - entry := fn.currentBlock - swtch := &ConstantSwitch{ - Tag: idx, - // one condition per case - Conds: make([]Value, 0, len(s.Body.List)+1), - } - // note that we don't need heads; a select case can only have a single condition - var bodies []*BasicBlock - - state := 0 - r := 2 // index in 'sel' tuple of value; increments if st.Dir==RECV - for _, cc := range s.Body.List { - clause := cc.(*ast.CommClause) - if clause.Comm == nil { - body := fn.newBasicBlock("select.default") - fn.currentBlock = body - bodies = append(bodies, body) - fn.targets = &targets{ - tail: fn.targets, - _break: done, - } - b.stmtList(fn, clause.Body) - emitJump(fn, done, s) - fn.targets = fn.targets.tail - swtch.Conds = append(swtch.Conds, emitConst(fn, intConst(-1))) - continue - } - swtch.Conds = append(swtch.Conds, emitConst(fn, intConst(int64(state)))) - body := fn.newBasicBlock("select.body") - fn.currentBlock = body - bodies = append(bodies, body) - fn.targets = &targets{ - tail: fn.targets, - _break: done, - } - switch comm := clause.Comm.(type) { - case *ast.ExprStmt: // <-ch - if debugInfo { - v := emitExtract(fn, sel, r, comm) - emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false) - } - r++ - - case *ast.AssignStmt: // x := <-states[state].Chan - if comm.Tok == token.DEFINE { - fn.addLocalForIdent(comm.Lhs[0].(*ast.Ident)) - } - x := b.addr(fn, comm.Lhs[0], false) // non-escaping - v := emitExtract(fn, sel, r, comm) - if debugInfo { - emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false) - } - x.store(fn, v, comm) - - if len(comm.Lhs) == 2 { // x, ok := ... - if comm.Tok == token.DEFINE { - fn.addLocalForIdent(comm.Lhs[1].(*ast.Ident)) - } - ok := b.addr(fn, comm.Lhs[1], false) // non-escaping - ok.store(fn, emitExtract(fn, sel, 1, comm), comm) - } - r++ - } - b.stmtList(fn, clause.Body) - fn.targets = fn.targets.tail - emitJump(fn, done, s) - state++ - } - fn.currentBlock = entry - fn.emit(swtch, s) - for _, body := range bodies { - addEdge(entry, body) - } - fn.currentBlock = done - return false -} - -// forStmt emits to fn code for the for statement s, optionally -// labelled by label. -// -func (b *builder) forStmt(fn *Function, s *ast.ForStmt, label *lblock) { - // ...init... - // jump loop - // loop: - // if cond goto body else done - // body: - // ...body... - // jump post - // post: (target of continue) - // ...post... - // jump loop - // done: (target of break) - if s.Init != nil { - b.stmt(fn, s.Init) - } - body := fn.newBasicBlock("for.body") - done := fn.newBasicBlock("for.done") // target of 'break' - loop := body // target of back-edge - if s.Cond != nil { - loop = fn.newBasicBlock("for.loop") - } - cont := loop // target of 'continue' - if s.Post != nil { - cont = fn.newBasicBlock("for.post") - } - if label != nil { - label._break = done - label._continue = cont - } - emitJump(fn, loop, s) - fn.currentBlock = loop - if loop != body { - b.cond(fn, s.Cond, body, done) - fn.currentBlock = body - } - fn.targets = &targets{ - tail: fn.targets, - _break: done, - _continue: cont, - } - b.stmt(fn, s.Body) - fn.targets = fn.targets.tail - emitJump(fn, cont, s) - - if s.Post != nil { - fn.currentBlock = cont - b.stmt(fn, s.Post) - emitJump(fn, loop, s) // back-edge - } - fn.currentBlock = done -} - -// rangeIndexed emits to fn the header for an integer-indexed loop -// over array, *array or slice value x. -// The v result is defined only if tv is non-nil. -// forPos is the position of the "for" token. -// -func (b *builder) rangeIndexed(fn *Function, x Value, tv types.Type, source ast.Node) (k, v Value, loop, done *BasicBlock) { - // - // length = len(x) - // index = -1 - // loop: (target of continue) - // index++ - // if index < length goto body else done - // body: - // k = index - // v = x[index] - // ...body... - // jump loop - // done: (target of break) - - // Determine number of iterations. - var length Value - if arr, ok := deref(x.Type()).Underlying().(*types.Array); ok { - // For array or *array, the number of iterations is - // known statically thanks to the type. We avoid a - // data dependence upon x, permitting later dead-code - // elimination if x is pure, static unrolling, etc. - // Ranging over a nil *array may have >0 iterations. - // We still generate code for x, in case it has effects. - length = emitConst(fn, intConst(arr.Len())) - } else { - // length = len(x). - var c Call - c.Call.Value = makeLen(x.Type()) - c.Call.Args = []Value{x} - c.setType(tInt) - length = fn.emit(&c, source) - } - - index := fn.addLocal(tInt, source) - emitStore(fn, index, emitConst(fn, intConst(-1)), source) - - loop = fn.newBasicBlock("rangeindex.loop") - emitJump(fn, loop, source) - fn.currentBlock = loop - - incr := &BinOp{ - Op: token.ADD, - X: emitLoad(fn, index, source), - Y: emitConst(fn, intConst(1)), - } - incr.setType(tInt) - emitStore(fn, index, fn.emit(incr, source), source) - - body := fn.newBasicBlock("rangeindex.body") - done = fn.newBasicBlock("rangeindex.done") - emitIf(fn, emitCompare(fn, token.LSS, incr, length, source), body, done, source) - fn.currentBlock = body - - k = emitLoad(fn, index, source) - if tv != nil { - switch t := x.Type().Underlying().(type) { - case *types.Array: - instr := &Index{ - X: x, - Index: k, - } - instr.setType(t.Elem()) - v = fn.emit(instr, source) - - case *types.Pointer: // *array - instr := &IndexAddr{ - X: x, - Index: k, - } - instr.setType(types.NewPointer(t.Elem().Underlying().(*types.Array).Elem())) - v = emitLoad(fn, fn.emit(instr, source), source) - - case *types.Slice: - instr := &IndexAddr{ - X: x, - Index: k, - } - instr.setType(types.NewPointer(t.Elem())) - v = emitLoad(fn, fn.emit(instr, source), source) - - default: - panic("rangeIndexed x:" + t.String()) - } - } - return -} - -// rangeIter emits to fn the header for a loop using -// Range/Next/Extract to iterate over map or string value x. -// tk and tv are the types of the key/value results k and v, or nil -// if the respective component is not wanted. -// -func (b *builder) rangeIter(fn *Function, x Value, tk, tv types.Type, source ast.Node) (k, v Value, loop, done *BasicBlock) { - // - // it = range x - // loop: (target of continue) - // okv = next it (ok, key, value) - // ok = extract okv #0 - // if ok goto body else done - // body: - // k = extract okv #1 - // v = extract okv #2 - // ...body... - // jump loop - // done: (target of break) - // - - if tk == nil { - tk = tInvalid - } - if tv == nil { - tv = tInvalid - } - - rng := &Range{X: x} - rng.setType(tRangeIter) - it := fn.emit(rng, source) - - loop = fn.newBasicBlock("rangeiter.loop") - emitJump(fn, loop, source) - fn.currentBlock = loop - - _, isString := x.Type().Underlying().(*types.Basic) - - okv := &Next{ - Iter: it, - IsString: isString, - } - okv.setType(types.NewTuple( - varOk, - newVar("k", tk), - newVar("v", tv), - )) - fn.emit(okv, source) - - body := fn.newBasicBlock("rangeiter.body") - done = fn.newBasicBlock("rangeiter.done") - emitIf(fn, emitExtract(fn, okv, 0, source), body, done, source) - fn.currentBlock = body - - if tk != tInvalid { - k = emitExtract(fn, okv, 1, source) - } - if tv != tInvalid { - v = emitExtract(fn, okv, 2, source) - } - return -} - -// rangeChan emits to fn the header for a loop that receives from -// channel x until it fails. -// tk is the channel's element type, or nil if the k result is -// not wanted -// pos is the position of the '=' or ':=' token. -// -func (b *builder) rangeChan(fn *Function, x Value, tk types.Type, source ast.Node) (k Value, loop, done *BasicBlock) { - // - // loop: (target of continue) - // ko = <-x (key, ok) - // ok = extract ko #1 - // if ok goto body else done - // body: - // k = extract ko #0 - // ... - // goto loop - // done: (target of break) - - loop = fn.newBasicBlock("rangechan.loop") - emitJump(fn, loop, source) - fn.currentBlock = loop - retv := emitRecv(fn, x, true, types.NewTuple(newVar("k", x.Type().Underlying().(*types.Chan).Elem()), varOk), source) - body := fn.newBasicBlock("rangechan.body") - done = fn.newBasicBlock("rangechan.done") - emitIf(fn, emitExtract(fn, retv, 1, source), body, done, source) - fn.currentBlock = body - if tk != nil { - k = emitExtract(fn, retv, 0, source) - } - return -} - -// rangeStmt emits to fn code for the range statement s, optionally -// labelled by label. -// -func (b *builder) rangeStmt(fn *Function, s *ast.RangeStmt, label *lblock, source ast.Node) { - var tk, tv types.Type - if s.Key != nil && !isBlankIdent(s.Key) { - tk = fn.Pkg.typeOf(s.Key) - } - if s.Value != nil && !isBlankIdent(s.Value) { - tv = fn.Pkg.typeOf(s.Value) - } - - // If iteration variables are defined (:=), this - // occurs once outside the loop. - // - // Unlike a short variable declaration, a RangeStmt - // using := never redeclares an existing variable; it - // always creates a new one. - if s.Tok == token.DEFINE { - if tk != nil { - fn.addLocalForIdent(s.Key.(*ast.Ident)) - } - if tv != nil { - fn.addLocalForIdent(s.Value.(*ast.Ident)) - } - } - - x := b.expr(fn, s.X) - - var k, v Value - var loop, done *BasicBlock - switch rt := x.Type().Underlying().(type) { - case *types.Slice, *types.Array, *types.Pointer: // *array - k, v, loop, done = b.rangeIndexed(fn, x, tv, source) - - case *types.Chan: - k, loop, done = b.rangeChan(fn, x, tk, source) - - case *types.Map, *types.Basic: // string - k, v, loop, done = b.rangeIter(fn, x, tk, tv, source) - - default: - panic("Cannot range over: " + rt.String()) - } - - // Evaluate both LHS expressions before we update either. - var kl, vl lvalue - if tk != nil { - kl = b.addr(fn, s.Key, false) // non-escaping - } - if tv != nil { - vl = b.addr(fn, s.Value, false) // non-escaping - } - if tk != nil { - kl.store(fn, k, s) - } - if tv != nil { - vl.store(fn, v, s) - } - - if label != nil { - label._break = done - label._continue = loop - } - - fn.targets = &targets{ - tail: fn.targets, - _break: done, - _continue: loop, - } - b.stmt(fn, s.Body) - fn.targets = fn.targets.tail - emitJump(fn, loop, source) // back-edge - fn.currentBlock = done -} - -// stmt lowers statement s to IR form, emitting code to fn. -func (b *builder) stmt(fn *Function, _s ast.Stmt) { - // The label of the current statement. If non-nil, its _goto - // target is always set; its _break and _continue are set only - // within the body of switch/typeswitch/select/for/range. - // It is effectively an additional default-nil parameter of stmt(). - var label *lblock -start: - switch s := _s.(type) { - case *ast.EmptyStmt: - // ignore. (Usually removed by gofmt.) - - case *ast.DeclStmt: // Con, Var or Typ - d := s.Decl.(*ast.GenDecl) - if d.Tok == token.VAR { - for _, spec := range d.Specs { - if vs, ok := spec.(*ast.ValueSpec); ok { - b.localValueSpec(fn, vs) - } - } - } - - case *ast.LabeledStmt: - label = fn.labelledBlock(s.Label) - emitJump(fn, label._goto, s) - fn.currentBlock = label._goto - _s = s.Stmt - goto start // effectively: tailcall stmt(fn, s.Stmt, label) - - case *ast.ExprStmt: - b.expr(fn, s.X) - - case *ast.SendStmt: - instr := &Send{ - Chan: b.expr(fn, s.Chan), - X: emitConv(fn, b.expr(fn, s.Value), - fn.Pkg.typeOf(s.Chan).Underlying().(*types.Chan).Elem(), s), - } - fn.emit(instr, s) - - case *ast.IncDecStmt: - op := token.ADD - if s.Tok == token.DEC { - op = token.SUB - } - loc := b.addr(fn, s.X, false) - b.assignOp(fn, loc, emitConst(fn, NewConst(constant.MakeInt64(1), loc.typ())), op, s) - - case *ast.AssignStmt: - switch s.Tok { - case token.ASSIGN, token.DEFINE: - b.assignStmt(fn, s.Lhs, s.Rhs, s.Tok == token.DEFINE, _s) - - default: // +=, etc. - op := s.Tok + token.ADD - token.ADD_ASSIGN - b.assignOp(fn, b.addr(fn, s.Lhs[0], false), b.expr(fn, s.Rhs[0]), op, s) - } - - case *ast.GoStmt: - // The "intrinsics" new/make/len/cap are forbidden here. - // panic is treated like an ordinary function call. - v := Go{} - b.setCall(fn, s.Call, &v.Call) - fn.emit(&v, s) - - case *ast.DeferStmt: - // The "intrinsics" new/make/len/cap are forbidden here. - // panic is treated like an ordinary function call. - v := Defer{} - b.setCall(fn, s.Call, &v.Call) - fn.hasDefer = true - fn.emit(&v, s) - - case *ast.ReturnStmt: - // TODO(dh): we could emit tigher position information by - // using the ith returned expression - - var results []Value - if len(s.Results) == 1 && fn.Signature.Results().Len() > 1 { - // Return of one expression in a multi-valued function. - tuple := b.exprN(fn, s.Results[0]) - ttuple := tuple.Type().(*types.Tuple) - for i, n := 0, ttuple.Len(); i < n; i++ { - results = append(results, - emitConv(fn, emitExtract(fn, tuple, i, s), - fn.Signature.Results().At(i).Type(), s)) - } - } else { - // 1:1 return, or no-arg return in non-void function. - for i, r := range s.Results { - v := emitConv(fn, b.expr(fn, r), fn.Signature.Results().At(i).Type(), s) - results = append(results, v) - } - } - - ret := fn.results() - for i, r := range results { - emitStore(fn, ret[i], r, s) - } - - emitJump(fn, fn.Exit, s) - fn.currentBlock = fn.newBasicBlock("unreachable") - - case *ast.BranchStmt: - var block *BasicBlock - switch s.Tok { - case token.BREAK: - if s.Label != nil { - block = fn.labelledBlock(s.Label)._break - } else { - for t := fn.targets; t != nil && block == nil; t = t.tail { - block = t._break - } - } - - case token.CONTINUE: - if s.Label != nil { - block = fn.labelledBlock(s.Label)._continue - } else { - for t := fn.targets; t != nil && block == nil; t = t.tail { - block = t._continue - } - } - - case token.FALLTHROUGH: - for t := fn.targets; t != nil && block == nil; t = t.tail { - block = t._fallthrough - } - - case token.GOTO: - block = fn.labelledBlock(s.Label)._goto - } - j := emitJump(fn, block, s) - j.Comment = s.Tok.String() - fn.currentBlock = fn.newBasicBlock("unreachable") - - case *ast.BlockStmt: - b.stmtList(fn, s.List) - - case *ast.IfStmt: - if s.Init != nil { - b.stmt(fn, s.Init) - } - then := fn.newBasicBlock("if.then") - done := fn.newBasicBlock("if.done") - els := done - if s.Else != nil { - els = fn.newBasicBlock("if.else") - } - instr := b.cond(fn, s.Cond, then, els) - instr.source = s - fn.currentBlock = then - b.stmt(fn, s.Body) - emitJump(fn, done, s) - - if s.Else != nil { - fn.currentBlock = els - b.stmt(fn, s.Else) - emitJump(fn, done, s) - } - - fn.currentBlock = done - - case *ast.SwitchStmt: - b.switchStmt(fn, s, label) - - case *ast.TypeSwitchStmt: - b.typeSwitchStmt(fn, s, label) - - case *ast.SelectStmt: - if b.selectStmt(fn, s, label) { - // the select has no cases, it blocks forever - fn.currentBlock = fn.newBasicBlock("unreachable") - } - - case *ast.ForStmt: - b.forStmt(fn, s, label) - - case *ast.RangeStmt: - b.rangeStmt(fn, s, label, s) - - default: - panic(fmt.Sprintf("unexpected statement kind: %T", s)) - } -} - -// buildFunction builds IR code for the body of function fn. Idempotent. -func (b *builder) buildFunction(fn *Function) { - if fn.Blocks != nil { - return // building already started - } - - var recvField *ast.FieldList - var body *ast.BlockStmt - var functype *ast.FuncType - switch n := fn.source.(type) { - case nil: - return // not a Go source function. (Synthetic, or from object file.) - case *ast.FuncDecl: - functype = n.Type - recvField = n.Recv - body = n.Body - case *ast.FuncLit: - functype = n.Type - body = n.Body - default: - panic(n) - } - - if fn.Package().Pkg.Path() == "syscall" && fn.Name() == "Exit" { - // syscall.Exit is a stub and the way os.Exit terminates the - // process. Note that there are other functions in the runtime - // that also terminate or unwind that we cannot analyze. - // However, they aren't stubs, so buildExits ends up getting - // called on them, so that's where we handle those special - // cases. - fn.WillExit = true - } - - if body == nil { - // External function. - if fn.Params == nil { - // This condition ensures we add a non-empty - // params list once only, but we may attempt - // the degenerate empty case repeatedly. - // TODO(adonovan): opt: don't do that. - - // We set Function.Params even though there is no body - // code to reference them. This simplifies clients. - if recv := fn.Signature.Recv(); recv != nil { - // XXX synthesize an ast.Node - fn.addParamObj(recv, nil) - } - params := fn.Signature.Params() - for i, n := 0, params.Len(); i < n; i++ { - // XXX synthesize an ast.Node - fn.addParamObj(params.At(i), nil) - } - } - return - } - if fn.Prog.mode&LogSource != 0 { - defer logStack("build function %s @ %s", fn, fn.Prog.Fset.Position(fn.Pos()))() - } - fn.blocksets = b.blocksets - fn.startBody() - fn.createSyntacticParams(recvField, functype) - fn.exitBlock() - b.stmt(fn, body) - if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb.Preds != nil) { - // Control fell off the end of the function's body block. - // - // Block optimizations eliminate the current block, if - // unreachable. It is a builder invariant that - // if this no-arg return is ill-typed for - // fn.Signature.Results, this block must be - // unreachable. The sanity checker checks this. - // fn.emit(new(RunDefers)) - // fn.emit(new(Return)) - emitJump(fn, fn.Exit, nil) - } - optimizeBlocks(fn) - buildFakeExits(fn) - b.buildExits(fn) - b.addUnreachables(fn) - fn.finishBody() - b.blocksets = fn.blocksets - fn.functionBody = nil -} - -// buildFuncDecl builds IR code for the function or method declared -// by decl in package pkg. -// -func (b *builder) buildFuncDecl(pkg *Package, decl *ast.FuncDecl) { - id := decl.Name - if isBlankIdent(id) { - return // discard - } - fn := pkg.values[pkg.info.Defs[id]].(*Function) - if decl.Recv == nil && id.Name == "init" { - var v Call - v.Call.Value = fn - v.setType(types.NewTuple()) - pkg.init.emit(&v, decl) - } - fn.source = decl - b.buildFunction(fn) -} - -// Build calls Package.Build for each package in prog. -// -// Build is intended for whole-program analysis; a typical compiler -// need only build a single package. -// -// Build is idempotent and thread-safe. -// -func (prog *Program) Build() { - for _, p := range prog.packages { - p.Build() - } -} - -// Build builds IR code for all functions and vars in package p. -// -// Precondition: CreatePackage must have been called for all of p's -// direct imports (and hence its direct imports must have been -// error-free). -// -// Build is idempotent and thread-safe. -// -func (p *Package) Build() { p.buildOnce.Do(p.build) } - -func (p *Package) build() { - if p.info == nil { - return // synthetic package, e.g. "testmain" - } - - // Ensure we have runtime type info for all exported members. - // TODO(adonovan): ideally belongs in memberFromObject, but - // that would require package creation in topological order. - for name, mem := range p.Members { - if ast.IsExported(name) { - p.Prog.needMethodsOf(mem.Type()) - } - } - if p.Prog.mode&LogSource != 0 { - defer logStack("build %s", p)() - } - init := p.init - init.startBody() - init.exitBlock() - - var done *BasicBlock - - // Make init() skip if package is already initialized. - initguard := p.Var("init$guard") - doinit := init.newBasicBlock("init.start") - done = init.Exit - emitIf(init, emitLoad(init, initguard, nil), done, doinit, nil) - init.currentBlock = doinit - emitStore(init, initguard, emitConst(init, NewConst(constant.MakeBool(true), tBool)), nil) - - // Call the init() function of each package we import. - for _, pkg := range p.Pkg.Imports() { - prereq := p.Prog.packages[pkg] - if prereq == nil { - panic(fmt.Sprintf("Package(%q).Build(): unsatisfied import: Program.CreatePackage(%q) was not called", p.Pkg.Path(), pkg.Path())) - } - var v Call - v.Call.Value = prereq.init - v.setType(types.NewTuple()) - init.emit(&v, nil) - } - - b := builder{ - printFunc: p.printFunc, - } - - // Initialize package-level vars in correct order. - for _, varinit := range p.info.InitOrder { - if init.Prog.mode&LogSource != 0 { - fmt.Fprintf(os.Stderr, "build global initializer %v @ %s\n", - varinit.Lhs, p.Prog.Fset.Position(varinit.Rhs.Pos())) - } - if len(varinit.Lhs) == 1 { - // 1:1 initialization: var x, y = a(), b() - var lval lvalue - if v := varinit.Lhs[0]; v.Name() != "_" { - lval = &address{addr: p.values[v].(*Global)} - } else { - lval = blank{} - } - // TODO(dh): do emit position information - b.assign(init, lval, varinit.Rhs, true, nil, nil) - } else { - // n:1 initialization: var x, y := f() - tuple := b.exprN(init, varinit.Rhs) - for i, v := range varinit.Lhs { - if v.Name() == "_" { - continue - } - emitStore(init, p.values[v].(*Global), emitExtract(init, tuple, i, nil), nil) - } - } - } - - // Build all package-level functions, init functions - // and methods, including unreachable/blank ones. - // We build them in source order, but it's not significant. - for _, file := range p.files { - for _, decl := range file.Decls { - if decl, ok := decl.(*ast.FuncDecl); ok { - b.buildFuncDecl(p, decl) - } - } - } - - // Finish up init(). - emitJump(init, done, nil) - init.finishBody() - - p.info = nil // We no longer need ASTs or go/types deductions. - - if p.Prog.mode&SanityCheckFunctions != 0 { - sanityCheckPackage(p) - } -} - -// Like ObjectOf, but panics instead of returning nil. -// Only valid during p's create and build phases. -func (p *Package) objectOf(id *ast.Ident) types.Object { - if o := p.info.ObjectOf(id); o != nil { - return o - } - panic(fmt.Sprintf("no types.Object for ast.Ident %s @ %s", - id.Name, p.Prog.Fset.Position(id.Pos()))) -} - -// Like TypeOf, but panics instead of returning nil. -// Only valid during p's create and build phases. -func (p *Package) typeOf(e ast.Expr) types.Type { - if T := p.info.TypeOf(e); T != nil { - return T - } - panic(fmt.Sprintf("no type for %T @ %s", - e, p.Prog.Fset.Position(e.Pos()))) -} diff --git a/vendor/honnef.co/go/tools/ir/const.go b/vendor/honnef.co/go/tools/ir/const.go deleted file mode 100644 index 7cdf006e8..000000000 --- a/vendor/honnef.co/go/tools/ir/const.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines the Const SSA value type. - -import ( - "fmt" - "go/constant" - "go/types" - "strconv" -) - -// NewConst returns a new constant of the specified value and type. -// val must be valid according to the specification of Const.Value. -// -func NewConst(val constant.Value, typ types.Type) *Const { - return &Const{ - register: register{ - typ: typ, - }, - Value: val, - } -} - -// intConst returns an 'int' constant that evaluates to i. -// (i is an int64 in case the host is narrower than the target.) -func intConst(i int64) *Const { - return NewConst(constant.MakeInt64(i), tInt) -} - -// nilConst returns a nil constant of the specified type, which may -// be any reference type, including interfaces. -// -func nilConst(typ types.Type) *Const { - return NewConst(nil, typ) -} - -// stringConst returns a 'string' constant that evaluates to s. -func stringConst(s string) *Const { - return NewConst(constant.MakeString(s), tString) -} - -// zeroConst returns a new "zero" constant of the specified type, -// which must not be an array or struct type: the zero values of -// aggregates are well-defined but cannot be represented by Const. -// -func zeroConst(t types.Type) *Const { - switch t := t.(type) { - case *types.Basic: - switch { - case t.Info()&types.IsBoolean != 0: - return NewConst(constant.MakeBool(false), t) - case t.Info()&types.IsNumeric != 0: - return NewConst(constant.MakeInt64(0), t) - case t.Info()&types.IsString != 0: - return NewConst(constant.MakeString(""), t) - case t.Kind() == types.UnsafePointer: - fallthrough - case t.Kind() == types.UntypedNil: - return nilConst(t) - default: - panic(fmt.Sprint("zeroConst for unexpected type:", t)) - } - case *types.Pointer, *types.Slice, *types.Interface, *types.Chan, *types.Map, *types.Signature: - return nilConst(t) - case *types.Named: - return NewConst(zeroConst(t.Underlying()).Value, t) - case *types.Array, *types.Struct, *types.Tuple: - panic(fmt.Sprint("zeroConst applied to aggregate:", t)) - } - panic(fmt.Sprint("zeroConst: unexpected ", t)) -} - -func (c *Const) RelString(from *types.Package) string { - var p string - if c.Value == nil { - p = "nil" - } else if c.Value.Kind() == constant.String { - v := constant.StringVal(c.Value) - const max = 20 - // TODO(adonovan): don't cut a rune in half. - if len(v) > max { - v = v[:max-3] + "..." // abbreviate - } - p = strconv.Quote(v) - } else { - p = c.Value.String() - } - return fmt.Sprintf("Const <%s> {%s}", relType(c.Type(), from), p) -} - -func (c *Const) String() string { - return c.RelString(c.Parent().pkg()) -} - -// IsNil returns true if this constant represents a typed or untyped nil value. -func (c *Const) IsNil() bool { - return c.Value == nil -} - -// Int64 returns the numeric value of this constant truncated to fit -// a signed 64-bit integer. -// -func (c *Const) Int64() int64 { - switch x := constant.ToInt(c.Value); x.Kind() { - case constant.Int: - if i, ok := constant.Int64Val(x); ok { - return i - } - return 0 - case constant.Float: - f, _ := constant.Float64Val(x) - return int64(f) - } - panic(fmt.Sprintf("unexpected constant value: %T", c.Value)) -} - -// Uint64 returns the numeric value of this constant truncated to fit -// an unsigned 64-bit integer. -// -func (c *Const) Uint64() uint64 { - switch x := constant.ToInt(c.Value); x.Kind() { - case constant.Int: - if u, ok := constant.Uint64Val(x); ok { - return u - } - return 0 - case constant.Float: - f, _ := constant.Float64Val(x) - return uint64(f) - } - panic(fmt.Sprintf("unexpected constant value: %T", c.Value)) -} - -// Float64 returns the numeric value of this constant truncated to fit -// a float64. -// -func (c *Const) Float64() float64 { - f, _ := constant.Float64Val(c.Value) - return f -} - -// Complex128 returns the complex value of this constant truncated to -// fit a complex128. -// -func (c *Const) Complex128() complex128 { - re, _ := constant.Float64Val(constant.Real(c.Value)) - im, _ := constant.Float64Val(constant.Imag(c.Value)) - return complex(re, im) -} diff --git a/vendor/honnef.co/go/tools/ir/create.go b/vendor/honnef.co/go/tools/ir/create.go deleted file mode 100644 index ff81a244b..000000000 --- a/vendor/honnef.co/go/tools/ir/create.go +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file implements the CREATE phase of IR construction. -// See builder.go for explanation. - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "os" - "sync" - - "golang.org/x/tools/go/types/typeutil" -) - -// NewProgram returns a new IR Program. -// -// mode controls diagnostics and checking during IR construction. -// -func NewProgram(fset *token.FileSet, mode BuilderMode) *Program { - prog := &Program{ - Fset: fset, - imported: make(map[string]*Package), - packages: make(map[*types.Package]*Package), - thunks: make(map[selectionKey]*Function), - bounds: make(map[*types.Func]*Function), - mode: mode, - } - - h := typeutil.MakeHasher() // protected by methodsMu, in effect - prog.methodSets.SetHasher(h) - prog.canon.SetHasher(h) - - return prog -} - -// memberFromObject populates package pkg with a member for the -// typechecker object obj. -// -// For objects from Go source code, syntax is the associated syntax -// tree (for funcs and vars only); it will be used during the build -// phase. -// -func memberFromObject(pkg *Package, obj types.Object, syntax ast.Node) { - name := obj.Name() - switch obj := obj.(type) { - case *types.Builtin: - if pkg.Pkg != types.Unsafe { - panic("unexpected builtin object: " + obj.String()) - } - - case *types.TypeName: - pkg.Members[name] = &Type{ - object: obj, - pkg: pkg, - } - - case *types.Const: - c := &NamedConst{ - object: obj, - Value: NewConst(obj.Val(), obj.Type()), - pkg: pkg, - } - pkg.values[obj] = c.Value - pkg.Members[name] = c - - case *types.Var: - g := &Global{ - Pkg: pkg, - name: name, - object: obj, - typ: types.NewPointer(obj.Type()), // address - } - pkg.values[obj] = g - pkg.Members[name] = g - - case *types.Func: - sig := obj.Type().(*types.Signature) - if sig.Recv() == nil && name == "init" { - pkg.ninit++ - name = fmt.Sprintf("init#%d", pkg.ninit) - } - fn := &Function{ - name: name, - object: obj, - Signature: sig, - Pkg: pkg, - Prog: pkg.Prog, - } - - fn.source = syntax - fn.initHTML(pkg.printFunc) - if syntax == nil { - fn.Synthetic = "loaded from gc object file" - } else { - fn.functionBody = new(functionBody) - } - - pkg.values[obj] = fn - pkg.Functions = append(pkg.Functions, fn) - if sig.Recv() == nil { - pkg.Members[name] = fn // package-level function - } - - default: // (incl. *types.Package) - panic("unexpected Object type: " + obj.String()) - } -} - -// membersFromDecl populates package pkg with members for each -// typechecker object (var, func, const or type) associated with the -// specified decl. -// -func membersFromDecl(pkg *Package, decl ast.Decl) { - switch decl := decl.(type) { - case *ast.GenDecl: // import, const, type or var - switch decl.Tok { - case token.CONST: - for _, spec := range decl.Specs { - for _, id := range spec.(*ast.ValueSpec).Names { - if !isBlankIdent(id) { - memberFromObject(pkg, pkg.info.Defs[id], nil) - } - } - } - - case token.VAR: - for _, spec := range decl.Specs { - for _, id := range spec.(*ast.ValueSpec).Names { - if !isBlankIdent(id) { - memberFromObject(pkg, pkg.info.Defs[id], spec) - } - } - } - - case token.TYPE: - for _, spec := range decl.Specs { - id := spec.(*ast.TypeSpec).Name - if !isBlankIdent(id) { - memberFromObject(pkg, pkg.info.Defs[id], nil) - } - } - } - - case *ast.FuncDecl: - id := decl.Name - if !isBlankIdent(id) { - memberFromObject(pkg, pkg.info.Defs[id], decl) - } - } -} - -// CreatePackage constructs and returns an IR Package from the -// specified type-checked, error-free file ASTs, and populates its -// Members mapping. -// -// importable determines whether this package should be returned by a -// subsequent call to ImportedPackage(pkg.Path()). -// -// The real work of building IR form for each function is not done -// until a subsequent call to Package.Build(). -// -func (prog *Program) CreatePackage(pkg *types.Package, files []*ast.File, info *types.Info, importable bool) *Package { - p := &Package{ - Prog: prog, - Members: make(map[string]Member), - values: make(map[types.Object]Value), - Pkg: pkg, - info: info, // transient (CREATE and BUILD phases) - files: files, // transient (CREATE and BUILD phases) - printFunc: prog.PrintFunc, - } - - // Add init() function. - p.init = &Function{ - name: "init", - Signature: new(types.Signature), - Synthetic: "package initializer", - Pkg: p, - Prog: prog, - functionBody: new(functionBody), - } - p.init.initHTML(prog.PrintFunc) - p.Members[p.init.name] = p.init - p.Functions = append(p.Functions, p.init) - - // CREATE phase. - // Allocate all package members: vars, funcs, consts and types. - if len(files) > 0 { - // Go source package. - for _, file := range files { - for _, decl := range file.Decls { - membersFromDecl(p, decl) - } - } - } else { - // GC-compiled binary package (or "unsafe") - // No code. - // No position information. - scope := p.Pkg.Scope() - for _, name := range scope.Names() { - obj := scope.Lookup(name) - memberFromObject(p, obj, nil) - if obj, ok := obj.(*types.TypeName); ok { - if named, ok := obj.Type().(*types.Named); ok { - for i, n := 0, named.NumMethods(); i < n; i++ { - memberFromObject(p, named.Method(i), nil) - } - } - } - } - } - - // Add initializer guard variable. - initguard := &Global{ - Pkg: p, - name: "init$guard", - typ: types.NewPointer(tBool), - } - p.Members[initguard.Name()] = initguard - - if prog.mode&GlobalDebug != 0 { - p.SetDebugMode(true) - } - - if prog.mode&PrintPackages != 0 { - printMu.Lock() - p.WriteTo(os.Stdout) - printMu.Unlock() - } - - if importable { - prog.imported[p.Pkg.Path()] = p - } - prog.packages[p.Pkg] = p - - return p -} - -// printMu serializes printing of Packages/Functions to stdout. -var printMu sync.Mutex - -// AllPackages returns a new slice containing all packages in the -// program prog in unspecified order. -// -func (prog *Program) AllPackages() []*Package { - pkgs := make([]*Package, 0, len(prog.packages)) - for _, pkg := range prog.packages { - pkgs = append(pkgs, pkg) - } - return pkgs -} - -// ImportedPackage returns the importable Package whose PkgPath -// is path, or nil if no such Package has been created. -// -// A parameter to CreatePackage determines whether a package should be -// considered importable. For example, no import declaration can resolve -// to the ad-hoc main package created by 'go build foo.go'. -// -// TODO(adonovan): rethink this function and the "importable" concept; -// most packages are importable. This function assumes that all -// types.Package.Path values are unique within the ir.Program, which is -// false---yet this function remains very convenient. -// Clients should use (*Program).Package instead where possible. -// IR doesn't really need a string-keyed map of packages. -// -func (prog *Program) ImportedPackage(path string) *Package { - return prog.imported[path] -} diff --git a/vendor/honnef.co/go/tools/ir/doc.go b/vendor/honnef.co/go/tools/ir/doc.go deleted file mode 100644 index a5f42e4f4..000000000 --- a/vendor/honnef.co/go/tools/ir/doc.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ir defines a representation of the elements of Go programs -// (packages, types, functions, variables and constants) using a -// static single-information (SSI) form intermediate representation -// (IR) for the bodies of functions. -// -// THIS INTERFACE IS EXPERIMENTAL AND IS LIKELY TO CHANGE. -// -// For an introduction to SSA form, upon which SSI builds, see -// http://en.wikipedia.org/wiki/Static_single_assignment_form. -// This page provides a broader reading list: -// http://www.dcs.gla.ac.uk/~jsinger/ssa.html. -// -// For an introduction to SSI form, see The static single information -// form by C. Scott Ananian. -// -// The level of abstraction of the IR form is intentionally close to -// the source language to facilitate construction of source analysis -// tools. It is not intended for machine code generation. -// -// The simplest way to create the IR of a package is -// to load typed syntax trees using golang.org/x/tools/go/packages, then -// invoke the irutil.Packages helper function. See ExampleLoadPackages -// and ExampleWholeProgram for examples. -// The resulting ir.Program contains all the packages and their -// members, but IR code is not created for function bodies until a -// subsequent call to (*Package).Build or (*Program).Build. -// -// The builder initially builds a naive IR form in which all local -// variables are addresses of stack locations with explicit loads and -// stores. Registerisation of eligible locals and φ-node insertion -// using dominance and dataflow are then performed as a second pass -// called "lifting" to improve the accuracy and performance of -// subsequent analyses; this pass can be skipped by setting the -// NaiveForm builder flag. -// -// The primary interfaces of this package are: -// -// - Member: a named member of a Go package. -// - Value: an expression that yields a value. -// - Instruction: a statement that consumes values and performs computation. -// - Node: a Value or Instruction (emphasizing its membership in the IR value graph) -// -// A computation that yields a result implements both the Value and -// Instruction interfaces. The following table shows for each -// concrete type which of these interfaces it implements. -// -// Value? Instruction? Member? -// *Alloc ✔ ✔ -// *BinOp ✔ ✔ -// *BlankStore ✔ -// *Builtin ✔ -// *Call ✔ ✔ -// *ChangeInterface ✔ ✔ -// *ChangeType ✔ ✔ -// *Const ✔ ✔ -// *Convert ✔ ✔ -// *DebugRef ✔ -// *Defer ✔ ✔ -// *Extract ✔ ✔ -// *Field ✔ ✔ -// *FieldAddr ✔ ✔ -// *FreeVar ✔ -// *Function ✔ ✔ (func) -// *Global ✔ ✔ (var) -// *Go ✔ ✔ -// *If ✔ -// *Index ✔ ✔ -// *IndexAddr ✔ ✔ -// *Jump ✔ -// *Load ✔ ✔ -// *MakeChan ✔ ✔ -// *MakeClosure ✔ ✔ -// *MakeInterface ✔ ✔ -// *MakeMap ✔ ✔ -// *MakeSlice ✔ ✔ -// *MapLookup ✔ ✔ -// *MapUpdate ✔ ✔ -// *NamedConst ✔ (const) -// *Next ✔ ✔ -// *Panic ✔ -// *Parameter ✔ ✔ -// *Phi ✔ ✔ -// *Range ✔ ✔ -// *Recv ✔ ✔ -// *Return ✔ -// *RunDefers ✔ -// *Select ✔ ✔ -// *Send ✔ ✔ -// *Sigma ✔ ✔ -// *Slice ✔ ✔ -// *Store ✔ ✔ -// *StringLookup ✔ ✔ -// *Type ✔ (type) -// *TypeAssert ✔ ✔ -// *UnOp ✔ ✔ -// *Unreachable ✔ -// -// Other key types in this package include: Program, Package, Function -// and BasicBlock. -// -// The program representation constructed by this package is fully -// resolved internally, i.e. it does not rely on the names of Values, -// Packages, Functions, Types or BasicBlocks for the correct -// interpretation of the program. Only the identities of objects and -// the topology of the IR and type graphs are semantically -// significant. (There is one exception: Ids, used to identify field -// and method names, contain strings.) Avoidance of name-based -// operations simplifies the implementation of subsequent passes and -// can make them very efficient. Many objects are nonetheless named -// to aid in debugging, but it is not essential that the names be -// either accurate or unambiguous. The public API exposes a number of -// name-based maps for client convenience. -// -// The ir/irutil package provides various utilities that depend only -// on the public API of this package. -// -// TODO(adonovan): Consider the exceptional control-flow implications -// of defer and recover(). -// -// TODO(adonovan): write a how-to document for all the various cases -// of trying to determine corresponding elements across the four -// domains of source locations, ast.Nodes, types.Objects, -// ir.Values/Instructions. -// -package ir // import "honnef.co/go/tools/ir" diff --git a/vendor/honnef.co/go/tools/ir/dom.go b/vendor/honnef.co/go/tools/ir/dom.go deleted file mode 100644 index 08c147df9..000000000 --- a/vendor/honnef.co/go/tools/ir/dom.go +++ /dev/null @@ -1,461 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines algorithms related to dominance. - -// Dominator tree construction ---------------------------------------- -// -// We use the algorithm described in Lengauer & Tarjan. 1979. A fast -// algorithm for finding dominators in a flowgraph. -// http://doi.acm.org/10.1145/357062.357071 -// -// We also apply the optimizations to SLT described in Georgiadis et -// al, Finding Dominators in Practice, JGAA 2006, -// http://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf -// to avoid the need for buckets of size > 1. - -import ( - "bytes" - "fmt" - "io" - "math/big" - "os" - "sort" -) - -// Idom returns the block that immediately dominates b: -// its parent in the dominator tree, if any. -// The entry node (b.Index==0) does not have a parent. -// -func (b *BasicBlock) Idom() *BasicBlock { return b.dom.idom } - -// Dominees returns the list of blocks that b immediately dominates: -// its children in the dominator tree. -// -func (b *BasicBlock) Dominees() []*BasicBlock { return b.dom.children } - -// Dominates reports whether b dominates c. -func (b *BasicBlock) Dominates(c *BasicBlock) bool { - return b.dom.pre <= c.dom.pre && c.dom.post <= b.dom.post -} - -type byDomPreorder []*BasicBlock - -func (a byDomPreorder) Len() int { return len(a) } -func (a byDomPreorder) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byDomPreorder) Less(i, j int) bool { return a[i].dom.pre < a[j].dom.pre } - -// DomPreorder returns a new slice containing the blocks of f in -// dominator tree preorder. -// -func (f *Function) DomPreorder() []*BasicBlock { - n := len(f.Blocks) - order := make(byDomPreorder, n) - copy(order, f.Blocks) - sort.Sort(order) - return order -} - -// domInfo contains a BasicBlock's dominance information. -type domInfo struct { - idom *BasicBlock // immediate dominator (parent in domtree) - children []*BasicBlock // nodes immediately dominated by this one - pre, post int32 // pre- and post-order numbering within domtree -} - -// buildDomTree computes the dominator tree of f using the LT algorithm. -// Precondition: all blocks are reachable (e.g. optimizeBlocks has been run). -// -func buildDomTree(fn *Function) { - // The step numbers refer to the original LT paper; the - // reordering is due to Georgiadis. - - // Clear any previous domInfo. - for _, b := range fn.Blocks { - b.dom = domInfo{} - } - - idoms := make([]*BasicBlock, len(fn.Blocks)) - - order := make([]*BasicBlock, 0, len(fn.Blocks)) - seen := fn.blockset(0) - var dfs func(b *BasicBlock) - dfs = func(b *BasicBlock) { - if !seen.Add(b) { - return - } - for _, succ := range b.Succs { - dfs(succ) - } - if fn.fakeExits.Has(b) { - dfs(fn.Exit) - } - order = append(order, b) - b.post = len(order) - 1 - } - dfs(fn.Blocks[0]) - - for i := 0; i < len(order)/2; i++ { - o := len(order) - i - 1 - order[i], order[o] = order[o], order[i] - } - - idoms[fn.Blocks[0].Index] = fn.Blocks[0] - changed := true - for changed { - changed = false - // iterate over all nodes in reverse postorder, except for the - // entry node - for _, b := range order[1:] { - var newIdom *BasicBlock - do := func(p *BasicBlock) { - if idoms[p.Index] == nil { - return - } - if newIdom == nil { - newIdom = p - } else { - finger1 := p - finger2 := newIdom - for finger1 != finger2 { - for finger1.post < finger2.post { - finger1 = idoms[finger1.Index] - } - for finger2.post < finger1.post { - finger2 = idoms[finger2.Index] - } - } - newIdom = finger1 - } - } - for _, p := range b.Preds { - do(p) - } - if b == fn.Exit { - for _, p := range fn.Blocks { - if fn.fakeExits.Has(p) { - do(p) - } - } - } - - if idoms[b.Index] != newIdom { - idoms[b.Index] = newIdom - changed = true - } - } - } - - for i, b := range idoms { - fn.Blocks[i].dom.idom = b - if b == nil { - // malformed CFG - continue - } - if i == b.Index { - continue - } - b.dom.children = append(b.dom.children, fn.Blocks[i]) - } - - numberDomTree(fn.Blocks[0], 0, 0) - - // printDomTreeDot(os.Stderr, fn) // debugging - // printDomTreeText(os.Stderr, root, 0) // debugging - - if fn.Prog.mode&SanityCheckFunctions != 0 { - sanityCheckDomTree(fn) - } -} - -// buildPostDomTree is like buildDomTree, but builds the post-dominator tree instead. -func buildPostDomTree(fn *Function) { - // The step numbers refer to the original LT paper; the - // reordering is due to Georgiadis. - - // Clear any previous domInfo. - for _, b := range fn.Blocks { - b.pdom = domInfo{} - } - - idoms := make([]*BasicBlock, len(fn.Blocks)) - - order := make([]*BasicBlock, 0, len(fn.Blocks)) - seen := fn.blockset(0) - var dfs func(b *BasicBlock) - dfs = func(b *BasicBlock) { - if !seen.Add(b) { - return - } - for _, pred := range b.Preds { - dfs(pred) - } - if b == fn.Exit { - for _, p := range fn.Blocks { - if fn.fakeExits.Has(p) { - dfs(p) - } - } - } - order = append(order, b) - b.post = len(order) - 1 - } - dfs(fn.Exit) - - for i := 0; i < len(order)/2; i++ { - o := len(order) - i - 1 - order[i], order[o] = order[o], order[i] - } - - idoms[fn.Exit.Index] = fn.Exit - changed := true - for changed { - changed = false - // iterate over all nodes in reverse postorder, except for the - // exit node - for _, b := range order[1:] { - var newIdom *BasicBlock - do := func(p *BasicBlock) { - if idoms[p.Index] == nil { - return - } - if newIdom == nil { - newIdom = p - } else { - finger1 := p - finger2 := newIdom - for finger1 != finger2 { - for finger1.post < finger2.post { - finger1 = idoms[finger1.Index] - } - for finger2.post < finger1.post { - finger2 = idoms[finger2.Index] - } - } - newIdom = finger1 - } - } - for _, p := range b.Succs { - do(p) - } - if fn.fakeExits.Has(b) { - do(fn.Exit) - } - - if idoms[b.Index] != newIdom { - idoms[b.Index] = newIdom - changed = true - } - } - } - - for i, b := range idoms { - fn.Blocks[i].pdom.idom = b - if b == nil { - // malformed CFG - continue - } - if i == b.Index { - continue - } - b.pdom.children = append(b.pdom.children, fn.Blocks[i]) - } - - numberPostDomTree(fn.Exit, 0, 0) - - // printPostDomTreeDot(os.Stderr, fn) // debugging - // printPostDomTreeText(os.Stderr, fn.Exit, 0) // debugging - - if fn.Prog.mode&SanityCheckFunctions != 0 { // XXX - sanityCheckDomTree(fn) // XXX - } -} - -// numberDomTree sets the pre- and post-order numbers of a depth-first -// traversal of the dominator tree rooted at v. These are used to -// answer dominance queries in constant time. -// -func numberDomTree(v *BasicBlock, pre, post int32) (int32, int32) { - v.dom.pre = pre - pre++ - for _, child := range v.dom.children { - pre, post = numberDomTree(child, pre, post) - } - v.dom.post = post - post++ - return pre, post -} - -// numberPostDomTree sets the pre- and post-order numbers of a depth-first -// traversal of the post-dominator tree rooted at v. These are used to -// answer post-dominance queries in constant time. -// -func numberPostDomTree(v *BasicBlock, pre, post int32) (int32, int32) { - v.pdom.pre = pre - pre++ - for _, child := range v.pdom.children { - pre, post = numberPostDomTree(child, pre, post) - } - v.pdom.post = post - post++ - return pre, post -} - -// Testing utilities ---------------------------------------- - -// sanityCheckDomTree checks the correctness of the dominator tree -// computed by the LT algorithm by comparing against the dominance -// relation computed by a naive Kildall-style forward dataflow -// analysis (Algorithm 10.16 from the "Dragon" book). -// -func sanityCheckDomTree(f *Function) { - n := len(f.Blocks) - - // D[i] is the set of blocks that dominate f.Blocks[i], - // represented as a bit-set of block indices. - D := make([]big.Int, n) - - one := big.NewInt(1) - - // all is the set of all blocks; constant. - var all big.Int - all.Set(one).Lsh(&all, uint(n)).Sub(&all, one) - - // Initialization. - for i := range f.Blocks { - if i == 0 { - // A root is dominated only by itself. - D[i].SetBit(&D[0], 0, 1) - } else { - // All other blocks are (initially) dominated - // by every block. - D[i].Set(&all) - } - } - - // Iteration until fixed point. - for changed := true; changed; { - changed = false - for i, b := range f.Blocks { - if i == 0 { - continue - } - // Compute intersection across predecessors. - var x big.Int - x.Set(&all) - for _, pred := range b.Preds { - x.And(&x, &D[pred.Index]) - } - if b == f.Exit { - for _, p := range f.Blocks { - if f.fakeExits.Has(p) { - x.And(&x, &D[p.Index]) - } - } - } - x.SetBit(&x, i, 1) // a block always dominates itself. - if D[i].Cmp(&x) != 0 { - D[i].Set(&x) - changed = true - } - } - } - - // Check the entire relation. O(n^2). - ok := true - for i := 0; i < n; i++ { - for j := 0; j < n; j++ { - b, c := f.Blocks[i], f.Blocks[j] - actual := b.Dominates(c) - expected := D[j].Bit(i) == 1 - if actual != expected { - fmt.Fprintf(os.Stderr, "dominates(%s, %s)==%t, want %t\n", b, c, actual, expected) - ok = false - } - } - } - - preorder := f.DomPreorder() - for _, b := range f.Blocks { - if got := preorder[b.dom.pre]; got != b { - fmt.Fprintf(os.Stderr, "preorder[%d]==%s, want %s\n", b.dom.pre, got, b) - ok = false - } - } - - if !ok { - panic("sanityCheckDomTree failed for " + f.String()) - } - -} - -// Printing functions ---------------------------------------- - -// printDomTree prints the dominator tree as text, using indentation. -//lint:ignore U1000 used during debugging -func printDomTreeText(buf *bytes.Buffer, v *BasicBlock, indent int) { - fmt.Fprintf(buf, "%*s%s\n", 4*indent, "", v) - for _, child := range v.dom.children { - printDomTreeText(buf, child, indent+1) - } -} - -// printDomTreeDot prints the dominator tree of f in AT&T GraphViz -// (.dot) format. -//lint:ignore U1000 used during debugging -func printDomTreeDot(buf io.Writer, f *Function) { - fmt.Fprintln(buf, "//", f) - fmt.Fprintln(buf, "digraph domtree {") - for i, b := range f.Blocks { - v := b.dom - fmt.Fprintf(buf, "\tn%d [label=\"%s (%d, %d)\",shape=\"rectangle\"];\n", v.pre, b, v.pre, v.post) - // TODO(adonovan): improve appearance of edges - // belonging to both dominator tree and CFG. - - // Dominator tree edge. - if i != 0 { - fmt.Fprintf(buf, "\tn%d -> n%d [style=\"solid\",weight=100];\n", v.idom.dom.pre, v.pre) - } - // CFG edges. - for _, pred := range b.Preds { - fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0];\n", pred.dom.pre, v.pre) - } - } - fmt.Fprintln(buf, "}") -} - -// printDomTree prints the dominator tree as text, using indentation. -//lint:ignore U1000 used during debugging -func printPostDomTreeText(buf io.Writer, v *BasicBlock, indent int) { - fmt.Fprintf(buf, "%*s%s\n", 4*indent, "", v) - for _, child := range v.pdom.children { - printPostDomTreeText(buf, child, indent+1) - } -} - -// printDomTreeDot prints the dominator tree of f in AT&T GraphViz -// (.dot) format. -//lint:ignore U1000 used during debugging -func printPostDomTreeDot(buf io.Writer, f *Function) { - fmt.Fprintln(buf, "//", f) - fmt.Fprintln(buf, "digraph pdomtree {") - for _, b := range f.Blocks { - v := b.pdom - fmt.Fprintf(buf, "\tn%d [label=\"%s (%d, %d)\",shape=\"rectangle\"];\n", v.pre, b, v.pre, v.post) - // TODO(adonovan): improve appearance of edges - // belonging to both dominator tree and CFG. - - // Dominator tree edge. - if b != f.Exit { - fmt.Fprintf(buf, "\tn%d -> n%d [style=\"solid\",weight=100];\n", v.idom.pdom.pre, v.pre) - } - // CFG edges. - for _, pred := range b.Preds { - fmt.Fprintf(buf, "\tn%d -> n%d [style=\"dotted\",weight=0];\n", pred.pdom.pre, v.pre) - } - } - fmt.Fprintln(buf, "}") -} diff --git a/vendor/honnef.co/go/tools/ir/emit.go b/vendor/honnef.co/go/tools/ir/emit.go deleted file mode 100644 index 5fa137af9..000000000 --- a/vendor/honnef.co/go/tools/ir/emit.go +++ /dev/null @@ -1,450 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// Helpers for emitting IR instructions. - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" -) - -// emitNew emits to f a new (heap Alloc) instruction allocating an -// object of type typ. pos is the optional source location. -// -func emitNew(f *Function, typ types.Type, source ast.Node) *Alloc { - v := &Alloc{Heap: true} - v.setType(types.NewPointer(typ)) - f.emit(v, source) - return v -} - -// emitLoad emits to f an instruction to load the address addr into a -// new temporary, and returns the value so defined. -// -func emitLoad(f *Function, addr Value, source ast.Node) *Load { - v := &Load{X: addr} - v.setType(deref(addr.Type())) - f.emit(v, source) - return v -} - -func emitRecv(f *Function, ch Value, commaOk bool, typ types.Type, source ast.Node) Value { - recv := &Recv{ - Chan: ch, - CommaOk: commaOk, - } - recv.setType(typ) - return f.emit(recv, source) -} - -// emitDebugRef emits to f a DebugRef pseudo-instruction associating -// expression e with value v. -// -func emitDebugRef(f *Function, e ast.Expr, v Value, isAddr bool) { - if !f.debugInfo() { - return // debugging not enabled - } - if v == nil || e == nil { - panic("nil") - } - var obj types.Object - e = unparen(e) - if id, ok := e.(*ast.Ident); ok { - if isBlankIdent(id) { - return - } - obj = f.Pkg.objectOf(id) - switch obj.(type) { - case *types.Nil, *types.Const, *types.Builtin: - return - } - } - f.emit(&DebugRef{ - X: v, - Expr: e, - IsAddr: isAddr, - object: obj, - }, nil) -} - -// emitArith emits to f code to compute the binary operation op(x, y) -// where op is an eager shift, logical or arithmetic operation. -// (Use emitCompare() for comparisons and Builder.logicalBinop() for -// non-eager operations.) -// -func emitArith(f *Function, op token.Token, x, y Value, t types.Type, source ast.Node) Value { - switch op { - case token.SHL, token.SHR: - x = emitConv(f, x, t, source) - // y may be signed or an 'untyped' constant. - // TODO(adonovan): whence signed values? - if b, ok := y.Type().Underlying().(*types.Basic); ok && b.Info()&types.IsUnsigned == 0 { - y = emitConv(f, y, types.Typ[types.Uint64], source) - } - - case token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.AND_NOT: - x = emitConv(f, x, t, source) - y = emitConv(f, y, t, source) - - default: - panic("illegal op in emitArith: " + op.String()) - - } - v := &BinOp{ - Op: op, - X: x, - Y: y, - } - v.setType(t) - return f.emit(v, source) -} - -// emitCompare emits to f code compute the boolean result of -// comparison comparison 'x op y'. -// -func emitCompare(f *Function, op token.Token, x, y Value, source ast.Node) Value { - xt := x.Type().Underlying() - yt := y.Type().Underlying() - - // Special case to optimise a tagless SwitchStmt so that - // these are equivalent - // switch { case e: ...} - // switch true { case e: ... } - // if e==true { ... } - // even in the case when e's type is an interface. - // TODO(adonovan): opt: generalise to x==true, false!=y, etc. - if x, ok := x.(*Const); ok && op == token.EQL && x.Value != nil && x.Value.Kind() == constant.Bool && constant.BoolVal(x.Value) { - if yt, ok := yt.(*types.Basic); ok && yt.Info()&types.IsBoolean != 0 { - return y - } - } - - if types.Identical(xt, yt) { - // no conversion necessary - } else if _, ok := xt.(*types.Interface); ok { - y = emitConv(f, y, x.Type(), source) - } else if _, ok := yt.(*types.Interface); ok { - x = emitConv(f, x, y.Type(), source) - } else if _, ok := x.(*Const); ok { - x = emitConv(f, x, y.Type(), source) - } else if _, ok := y.(*Const); ok { - y = emitConv(f, y, x.Type(), source) - //lint:ignore SA9003 no-op - } else { - // other cases, e.g. channels. No-op. - } - - v := &BinOp{ - Op: op, - X: x, - Y: y, - } - v.setType(tBool) - return f.emit(v, source) -} - -// isValuePreserving returns true if a conversion from ut_src to -// ut_dst is value-preserving, i.e. just a change of type. -// Precondition: neither argument is a named type. -// -func isValuePreserving(ut_src, ut_dst types.Type) bool { - // Identical underlying types? - if structTypesIdentical(ut_dst, ut_src) { - return true - } - - switch ut_dst.(type) { - case *types.Chan: - // Conversion between channel types? - _, ok := ut_src.(*types.Chan) - return ok - - case *types.Pointer: - // Conversion between pointers with identical base types? - _, ok := ut_src.(*types.Pointer) - return ok - } - return false -} - -// emitConv emits to f code to convert Value val to exactly type typ, -// and returns the converted value. Implicit conversions are required -// by language assignability rules in assignments, parameter passing, -// etc. Conversions cannot fail dynamically. -// -func emitConv(f *Function, val Value, typ types.Type, source ast.Node) Value { - t_src := val.Type() - - // Identical types? Conversion is a no-op. - if types.Identical(t_src, typ) { - return val - } - - ut_dst := typ.Underlying() - ut_src := t_src.Underlying() - - // Just a change of type, but not value or representation? - if isValuePreserving(ut_src, ut_dst) { - c := &ChangeType{X: val} - c.setType(typ) - return f.emit(c, source) - } - - // Conversion to, or construction of a value of, an interface type? - if _, ok := ut_dst.(*types.Interface); ok { - // Assignment from one interface type to another? - if _, ok := ut_src.(*types.Interface); ok { - c := &ChangeInterface{X: val} - c.setType(typ) - return f.emit(c, source) - } - - // Untyped nil constant? Return interface-typed nil constant. - if ut_src == tUntypedNil { - return emitConst(f, nilConst(typ)) - } - - // Convert (non-nil) "untyped" literals to their default type. - if t, ok := ut_src.(*types.Basic); ok && t.Info()&types.IsUntyped != 0 { - val = emitConv(f, val, types.Default(ut_src), source) - } - - f.Pkg.Prog.needMethodsOf(val.Type()) - mi := &MakeInterface{X: val} - mi.setType(typ) - return f.emit(mi, source) - } - - // Conversion of a compile-time constant value? - if c, ok := val.(*Const); ok { - if _, ok := ut_dst.(*types.Basic); ok || c.IsNil() { - // Conversion of a compile-time constant to - // another constant type results in a new - // constant of the destination type and - // (initially) the same abstract value. - // We don't truncate the value yet. - return emitConst(f, NewConst(c.Value, typ)) - } - - // We're converting from constant to non-constant type, - // e.g. string -> []byte/[]rune. - } - - // A representation-changing conversion? - // At least one of {ut_src,ut_dst} must be *Basic. - // (The other may be []byte or []rune.) - _, ok1 := ut_src.(*types.Basic) - _, ok2 := ut_dst.(*types.Basic) - if ok1 || ok2 { - c := &Convert{X: val} - c.setType(typ) - return f.emit(c, source) - } - - panic(fmt.Sprintf("in %s: cannot convert %s (%s) to %s", f, val, val.Type(), typ)) -} - -// emitStore emits to f an instruction to store value val at location -// addr, applying implicit conversions as required by assignability rules. -// -func emitStore(f *Function, addr, val Value, source ast.Node) *Store { - s := &Store{ - Addr: addr, - Val: emitConv(f, val, deref(addr.Type()), source), - } - // make sure we call getMem after the call to emitConv, which may - // itself update the memory state - f.emit(s, source) - return s -} - -// emitJump emits to f a jump to target, and updates the control-flow graph. -// Postcondition: f.currentBlock is nil. -// -func emitJump(f *Function, target *BasicBlock, source ast.Node) *Jump { - b := f.currentBlock - j := new(Jump) - b.emit(j, source) - addEdge(b, target) - f.currentBlock = nil - return j -} - -// emitIf emits to f a conditional jump to tblock or fblock based on -// cond, and updates the control-flow graph. -// Postcondition: f.currentBlock is nil. -// -func emitIf(f *Function, cond Value, tblock, fblock *BasicBlock, source ast.Node) *If { - b := f.currentBlock - stmt := &If{Cond: cond} - b.emit(stmt, source) - addEdge(b, tblock) - addEdge(b, fblock) - f.currentBlock = nil - return stmt -} - -// emitExtract emits to f an instruction to extract the index'th -// component of tuple. It returns the extracted value. -// -func emitExtract(f *Function, tuple Value, index int, source ast.Node) Value { - e := &Extract{Tuple: tuple, Index: index} - e.setType(tuple.Type().(*types.Tuple).At(index).Type()) - return f.emit(e, source) -} - -// emitTypeAssert emits to f a type assertion value := x.(t) and -// returns the value. x.Type() must be an interface. -// -func emitTypeAssert(f *Function, x Value, t types.Type, source ast.Node) Value { - a := &TypeAssert{X: x, AssertedType: t} - a.setType(t) - return f.emit(a, source) -} - -// emitTypeTest emits to f a type test value,ok := x.(t) and returns -// a (value, ok) tuple. x.Type() must be an interface. -// -func emitTypeTest(f *Function, x Value, t types.Type, source ast.Node) Value { - a := &TypeAssert{ - X: x, - AssertedType: t, - CommaOk: true, - } - a.setType(types.NewTuple( - newVar("value", t), - varOk, - )) - return f.emit(a, source) -} - -// emitTailCall emits to f a function call in tail position. The -// caller is responsible for all fields of 'call' except its type. -// Intended for wrapper methods. -// Precondition: f does/will not use deferred procedure calls. -// Postcondition: f.currentBlock is nil. -// -func emitTailCall(f *Function, call *Call, source ast.Node) { - tresults := f.Signature.Results() - nr := tresults.Len() - if nr == 1 { - call.typ = tresults.At(0).Type() - } else { - call.typ = tresults - } - tuple := f.emit(call, source) - var ret Return - switch nr { - case 0: - // no-op - case 1: - ret.Results = []Value{tuple} - default: - for i := 0; i < nr; i++ { - v := emitExtract(f, tuple, i, source) - // TODO(adonovan): in principle, this is required: - // v = emitConv(f, o.Type, f.Signature.Results[i].Type) - // but in practice emitTailCall is only used when - // the types exactly match. - ret.Results = append(ret.Results, v) - } - } - - f.Exit = f.newBasicBlock("exit") - emitJump(f, f.Exit, source) - f.currentBlock = f.Exit - f.emit(&ret, source) - f.currentBlock = nil -} - -// emitImplicitSelections emits to f code to apply the sequence of -// implicit field selections specified by indices to base value v, and -// returns the selected value. -// -// If v is the address of a struct, the result will be the address of -// a field; if it is the value of a struct, the result will be the -// value of a field. -// -func emitImplicitSelections(f *Function, v Value, indices []int, source ast.Node) Value { - for _, index := range indices { - fld := deref(v.Type()).Underlying().(*types.Struct).Field(index) - - if isPointer(v.Type()) { - instr := &FieldAddr{ - X: v, - Field: index, - } - instr.setType(types.NewPointer(fld.Type())) - v = f.emit(instr, source) - // Load the field's value iff indirectly embedded. - if isPointer(fld.Type()) { - v = emitLoad(f, v, source) - } - } else { - instr := &Field{ - X: v, - Field: index, - } - instr.setType(fld.Type()) - v = f.emit(instr, source) - } - } - return v -} - -// emitFieldSelection emits to f code to select the index'th field of v. -// -// If wantAddr, the input must be a pointer-to-struct and the result -// will be the field's address; otherwise the result will be the -// field's value. -// Ident id is used for position and debug info. -// -func emitFieldSelection(f *Function, v Value, index int, wantAddr bool, id *ast.Ident) Value { - fld := deref(v.Type()).Underlying().(*types.Struct).Field(index) - if isPointer(v.Type()) { - instr := &FieldAddr{ - X: v, - Field: index, - } - instr.setSource(id) - instr.setType(types.NewPointer(fld.Type())) - v = f.emit(instr, id) - // Load the field's value iff we don't want its address. - if !wantAddr { - v = emitLoad(f, v, id) - } - } else { - instr := &Field{ - X: v, - Field: index, - } - instr.setSource(id) - instr.setType(fld.Type()) - v = f.emit(instr, id) - } - emitDebugRef(f, id, v, wantAddr) - return v -} - -// zeroValue emits to f code to produce a zero value of type t, -// and returns it. -// -func zeroValue(f *Function, t types.Type, source ast.Node) Value { - switch t.Underlying().(type) { - case *types.Struct, *types.Array: - return emitLoad(f, f.addLocal(t, source), source) - default: - return emitConst(f, zeroConst(t)) - } -} - -func emitConst(f *Function, c *Const) *Const { - f.consts = append(f.consts, c) - return c -} diff --git a/vendor/honnef.co/go/tools/ir/exits.go b/vendor/honnef.co/go/tools/ir/exits.go deleted file mode 100644 index 10cda7bb6..000000000 --- a/vendor/honnef.co/go/tools/ir/exits.go +++ /dev/null @@ -1,271 +0,0 @@ -package ir - -import ( - "go/types" -) - -func (b *builder) buildExits(fn *Function) { - if obj := fn.Object(); obj != nil { - switch obj.Pkg().Path() { - case "runtime": - switch obj.Name() { - case "exit": - fn.WillExit = true - return - case "throw": - fn.WillExit = true - return - case "Goexit": - fn.WillUnwind = true - return - } - case "github.com/sirupsen/logrus": - switch obj.(*types.Func).FullName() { - case "(*github.com/sirupsen/logrus.Logger).Exit": - // Technically, this method does not unconditionally exit - // the process. It dynamically calls a function stored in - // the logger. If the function is nil, it defaults to - // os.Exit. - // - // The main intent of this method is to terminate the - // process, and that's what the vast majority of people - // will use it for. We'll happily accept some false - // negatives to avoid a lot of false positives. - fn.WillExit = true - return - case "(*github.com/sirupsen/logrus.Logger).Panic", - "(*github.com/sirupsen/logrus.Logger).Panicf", - "(*github.com/sirupsen/logrus.Logger).Panicln": - - // These methods will always panic, but that's not - // statically known from the code alone, because they - // take a detour through the generic Log methods. - fn.WillUnwind = true - return - case "(*github.com/sirupsen/logrus.Entry).Panicf", - "(*github.com/sirupsen/logrus.Entry).Panicln": - - // Entry.Panic has an explicit panic, but Panicf and - // Panicln do not, relying fully on the generic Log - // method. - fn.WillUnwind = true - return - case "(*github.com/sirupsen/logrus.Logger).Log", - "(*github.com/sirupsen/logrus.Logger).Logf", - "(*github.com/sirupsen/logrus.Logger).Logln": - // TODO(dh): we cannot handle these case. Whether they - // exit or unwind depends on the level, which is set - // via the first argument. We don't currently support - // call-site-specific exit information. - } - } - } - - buildDomTree(fn) - - isRecoverCall := func(instr Instruction) bool { - if instr, ok := instr.(*Call); ok { - if builtin, ok := instr.Call.Value.(*Builtin); ok { - if builtin.Name() == "recover" { - return true - } - } - } - return false - } - - // All panics branch to the exit block, which means that if every - // possible path through the function panics, then all - // predecessors of the exit block must panic. - willPanic := true - for _, pred := range fn.Exit.Preds { - if _, ok := pred.Control().(*Panic); !ok { - willPanic = false - } - } - if willPanic { - recovers := false - recoverLoop: - for _, u := range fn.Blocks { - for _, instr := range u.Instrs { - if instr, ok := instr.(*Defer); ok { - call := instr.Call.StaticCallee() - if call == nil { - // not a static call, so we can't be sure the - // deferred call isn't calling recover - recovers = true - break recoverLoop - } - if len(call.Blocks) == 0 { - // external function, we don't know what's - // happening inside it - // - // TODO(dh): this includes functions from - // imported packages, due to how go/analysis - // works. We could introduce another fact, - // like we've done for exiting and unwinding, - // but it doesn't seem worth it. Virtually all - // uses of recover will be in closures. - recovers = true - break recoverLoop - } - for _, y := range call.Blocks { - for _, instr2 := range y.Instrs { - if isRecoverCall(instr2) { - recovers = true - break recoverLoop - } - } - } - } - } - } - if !recovers { - fn.WillUnwind = true - return - } - } - - // TODO(dh): don't check that any specific call dominates the exit - // block. instead, check that all calls combined cover every - // possible path through the function. - exits := NewBlockSet(len(fn.Blocks)) - unwinds := NewBlockSet(len(fn.Blocks)) - for _, u := range fn.Blocks { - for _, instr := range u.Instrs { - if instr, ok := instr.(CallInstruction); ok { - switch instr.(type) { - case *Defer, *Call: - default: - continue - } - if instr.Common().IsInvoke() { - // give up - return - } - var call *Function - switch instr.Common().Value.(type) { - case *Function, *MakeClosure: - call = instr.Common().StaticCallee() - case *Builtin: - // the only builtins that affect control flow are - // panic and recover, and we've already handled - // those - continue - default: - // dynamic dispatch - return - } - // buildFunction is idempotent. if we're part of a - // (mutually) recursive call chain, then buildFunction - // will immediately return, and fn.WillExit will be false. - if call.Package() == fn.Package() { - b.buildFunction(call) - } - dom := u.Dominates(fn.Exit) - if call.WillExit { - if dom { - fn.WillExit = true - return - } - exits.Add(u) - } else if call.WillUnwind { - if dom { - fn.WillUnwind = true - return - } - unwinds.Add(u) - } - } - } - } - - // depth-first search trying to find a path to the exit block that - // doesn't cross any of the blacklisted blocks - seen := NewBlockSet(len(fn.Blocks)) - var findPath func(root *BasicBlock, bl *BlockSet) bool - findPath = func(root *BasicBlock, bl *BlockSet) bool { - if root == fn.Exit { - return true - } - if seen.Has(root) { - return false - } - if bl.Has(root) { - return false - } - seen.Add(root) - for _, succ := range root.Succs { - if findPath(succ, bl) { - return true - } - } - return false - } - - if exits.Num() > 0 { - if !findPath(fn.Blocks[0], exits) { - fn.WillExit = true - return - } - } - if unwinds.Num() > 0 { - seen.Clear() - if !findPath(fn.Blocks[0], unwinds) { - fn.WillUnwind = true - return - } - } -} - -func (b *builder) addUnreachables(fn *Function) { - for _, bb := range fn.Blocks { - for i, instr := range bb.Instrs { - if instr, ok := instr.(*Call); ok { - var call *Function - switch v := instr.Common().Value.(type) { - case *Function: - call = v - case *MakeClosure: - call = v.Fn.(*Function) - } - if call == nil { - continue - } - if call.Package() == fn.Package() { - // make sure we have information on all functions in this package - b.buildFunction(call) - } - if call.WillExit { - // This call will cause the process to terminate. - // Remove remaining instructions in the block and - // replace any control flow with Unreachable. - for _, succ := range bb.Succs { - succ.removePred(bb) - } - bb.Succs = bb.Succs[:0] - - bb.Instrs = bb.Instrs[:i+1] - bb.emit(new(Unreachable), instr.Source()) - addEdge(bb, fn.Exit) - break - } else if call.WillUnwind { - // This call will cause the goroutine to terminate - // and defers to run (i.e. a panic or - // runtime.Goexit). Remove remaining instructions - // in the block and replace any control flow with - // an unconditional jump to the exit block. - for _, succ := range bb.Succs { - succ.removePred(bb) - } - bb.Succs = bb.Succs[:0] - - bb.Instrs = bb.Instrs[:i+1] - bb.emit(new(Jump), instr.Source()) - addEdge(bb, fn.Exit) - break - } - } - } - } -} diff --git a/vendor/honnef.co/go/tools/ir/func.go b/vendor/honnef.co/go/tools/ir/func.go deleted file mode 100644 index 386d82b67..000000000 --- a/vendor/honnef.co/go/tools/ir/func.go +++ /dev/null @@ -1,961 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file implements the Function and BasicBlock types. - -import ( - "bytes" - "fmt" - "go/ast" - "go/constant" - "go/format" - "go/token" - "go/types" - "io" - "os" - "strings" -) - -// addEdge adds a control-flow graph edge from from to to. -func addEdge(from, to *BasicBlock) { - from.Succs = append(from.Succs, to) - to.Preds = append(to.Preds, from) -} - -// Control returns the last instruction in the block. -func (b *BasicBlock) Control() Instruction { - if len(b.Instrs) == 0 { - return nil - } - return b.Instrs[len(b.Instrs)-1] -} - -// SIgmaFor returns the sigma node for v coming from pred. -func (b *BasicBlock) SigmaFor(v Value, pred *BasicBlock) *Sigma { - for _, instr := range b.Instrs { - sigma, ok := instr.(*Sigma) - if !ok { - // no more sigmas - return nil - } - if sigma.From == pred && sigma.X == v { - return sigma - } - } - return nil -} - -// Parent returns the function that contains block b. -func (b *BasicBlock) Parent() *Function { return b.parent } - -// String returns a human-readable label of this block. -// It is not guaranteed unique within the function. -// -func (b *BasicBlock) String() string { - return fmt.Sprintf("%d", b.Index) -} - -// emit appends an instruction to the current basic block. -// If the instruction defines a Value, it is returned. -// -func (b *BasicBlock) emit(i Instruction, source ast.Node) Value { - i.setSource(source) - i.setBlock(b) - b.Instrs = append(b.Instrs, i) - v, _ := i.(Value) - return v -} - -// predIndex returns the i such that b.Preds[i] == c or panics if -// there is none. -func (b *BasicBlock) predIndex(c *BasicBlock) int { - for i, pred := range b.Preds { - if pred == c { - return i - } - } - panic(fmt.Sprintf("no edge %s -> %s", c, b)) -} - -// succIndex returns the i such that b.Succs[i] == c or -1 if there is none. -func (b *BasicBlock) succIndex(c *BasicBlock) int { - for i, succ := range b.Succs { - if succ == c { - return i - } - } - return -1 -} - -// hasPhi returns true if b.Instrs contains φ-nodes. -func (b *BasicBlock) hasPhi() bool { - _, ok := b.Instrs[0].(*Phi) - return ok -} - -func (b *BasicBlock) Phis() []Instruction { - return b.phis() -} - -// phis returns the prefix of b.Instrs containing all the block's φ-nodes. -func (b *BasicBlock) phis() []Instruction { - for i, instr := range b.Instrs { - if _, ok := instr.(*Phi); !ok { - return b.Instrs[:i] - } - } - return nil // unreachable in well-formed blocks -} - -// replacePred replaces all occurrences of p in b's predecessor list with q. -// Ordinarily there should be at most one. -// -func (b *BasicBlock) replacePred(p, q *BasicBlock) { - for i, pred := range b.Preds { - if pred == p { - b.Preds[i] = q - } - } -} - -// replaceSucc replaces all occurrences of p in b's successor list with q. -// Ordinarily there should be at most one. -// -func (b *BasicBlock) replaceSucc(p, q *BasicBlock) { - for i, succ := range b.Succs { - if succ == p { - b.Succs[i] = q - } - } -} - -// removePred removes all occurrences of p in b's -// predecessor list and φ-nodes. -// Ordinarily there should be at most one. -// -func (b *BasicBlock) removePred(p *BasicBlock) { - phis := b.phis() - - // We must preserve edge order for φ-nodes. - j := 0 - for i, pred := range b.Preds { - if pred != p { - b.Preds[j] = b.Preds[i] - // Strike out φ-edge too. - for _, instr := range phis { - phi := instr.(*Phi) - phi.Edges[j] = phi.Edges[i] - } - j++ - } - } - // Nil out b.Preds[j:] and φ-edges[j:] to aid GC. - for i := j; i < len(b.Preds); i++ { - b.Preds[i] = nil - for _, instr := range phis { - instr.(*Phi).Edges[i] = nil - } - } - b.Preds = b.Preds[:j] - for _, instr := range phis { - phi := instr.(*Phi) - phi.Edges = phi.Edges[:j] - } -} - -// Destinations associated with unlabelled for/switch/select stmts. -// We push/pop one of these as we enter/leave each construct and for -// each BranchStmt we scan for the innermost target of the right type. -// -type targets struct { - tail *targets // rest of stack - _break *BasicBlock - _continue *BasicBlock - _fallthrough *BasicBlock -} - -// Destinations associated with a labelled block. -// We populate these as labels are encountered in forward gotos or -// labelled statements. -// -type lblock struct { - _goto *BasicBlock - _break *BasicBlock - _continue *BasicBlock -} - -// labelledBlock returns the branch target associated with the -// specified label, creating it if needed. -// -func (f *Function) labelledBlock(label *ast.Ident) *lblock { - lb := f.lblocks[label.Obj] - if lb == nil { - lb = &lblock{_goto: f.newBasicBlock(label.Name)} - if f.lblocks == nil { - f.lblocks = make(map[*ast.Object]*lblock) - } - f.lblocks[label.Obj] = lb - } - return lb -} - -// addParam adds a (non-escaping) parameter to f.Params of the -// specified name, type and source position. -// -func (f *Function) addParam(name string, typ types.Type, source ast.Node) *Parameter { - var b *BasicBlock - if len(f.Blocks) > 0 { - b = f.Blocks[0] - } - v := &Parameter{ - name: name, - } - v.setBlock(b) - v.setType(typ) - v.setSource(source) - f.Params = append(f.Params, v) - if b != nil { - // There may be no blocks if this function has no body. We - // still create params, but aren't interested in the - // instruction. - f.Blocks[0].Instrs = append(f.Blocks[0].Instrs, v) - } - return v -} - -func (f *Function) addParamObj(obj types.Object, source ast.Node) *Parameter { - name := obj.Name() - if name == "" { - name = fmt.Sprintf("arg%d", len(f.Params)) - } - param := f.addParam(name, obj.Type(), source) - param.object = obj - return param -} - -// addSpilledParam declares a parameter that is pre-spilled to the -// stack; the function body will load/store the spilled location. -// Subsequent lifting will eliminate spills where possible. -// -func (f *Function) addSpilledParam(obj types.Object, source ast.Node) { - param := f.addParamObj(obj, source) - spill := &Alloc{} - spill.setType(types.NewPointer(obj.Type())) - spill.source = source - f.objects[obj] = spill - f.Locals = append(f.Locals, spill) - f.emit(spill, source) - emitStore(f, spill, param, source) - // f.emit(&Store{Addr: spill, Val: param}) -} - -// startBody initializes the function prior to generating IR code for its body. -// Precondition: f.Type() already set. -// -func (f *Function) startBody() { - entry := f.newBasicBlock("entry") - f.currentBlock = entry - f.objects = make(map[types.Object]Value) // needed for some synthetics, e.g. init -} - -func (f *Function) blockset(i int) *BlockSet { - bs := &f.blocksets[i] - if len(bs.values) != len(f.Blocks) { - if cap(bs.values) >= len(f.Blocks) { - bs.values = bs.values[:len(f.Blocks)] - bs.Clear() - } else { - bs.values = make([]bool, len(f.Blocks)) - } - } else { - bs.Clear() - } - return bs -} - -func (f *Function) exitBlock() { - old := f.currentBlock - - f.Exit = f.newBasicBlock("exit") - f.currentBlock = f.Exit - - ret := f.results() - results := make([]Value, len(ret)) - // Run function calls deferred in this - // function when explicitly returning from it. - f.emit(new(RunDefers), nil) - for i, r := range ret { - results[i] = emitLoad(f, r, nil) - } - - f.emit(&Return{Results: results}, nil) - f.currentBlock = old -} - -// createSyntacticParams populates f.Params and generates code (spills -// and named result locals) for all the parameters declared in the -// syntax. In addition it populates the f.objects mapping. -// -// Preconditions: -// f.startBody() was called. -// Postcondition: -// len(f.Params) == len(f.Signature.Params) + (f.Signature.Recv() ? 1 : 0) -// -func (f *Function) createSyntacticParams(recv *ast.FieldList, functype *ast.FuncType) { - // Receiver (at most one inner iteration). - if recv != nil { - for _, field := range recv.List { - for _, n := range field.Names { - f.addSpilledParam(f.Pkg.info.Defs[n], n) - } - // Anonymous receiver? No need to spill. - if field.Names == nil { - f.addParamObj(f.Signature.Recv(), field) - } - } - } - - // Parameters. - if functype.Params != nil { - n := len(f.Params) // 1 if has recv, 0 otherwise - for _, field := range functype.Params.List { - for _, n := range field.Names { - f.addSpilledParam(f.Pkg.info.Defs[n], n) - } - // Anonymous parameter? No need to spill. - if field.Names == nil { - f.addParamObj(f.Signature.Params().At(len(f.Params)-n), field) - } - } - } - - // Named results. - if functype.Results != nil { - for _, field := range functype.Results.List { - // Implicit "var" decl of locals for named results. - for _, n := range field.Names { - f.namedResults = append(f.namedResults, f.addLocalForIdent(n)) - } - } - - if len(f.namedResults) == 0 { - sig := f.Signature.Results() - for i := 0; i < sig.Len(); i++ { - // XXX position information - v := f.addLocal(sig.At(i).Type(), nil) - f.implicitResults = append(f.implicitResults, v) - } - } - } -} - -func numberNodes(f *Function) { - var base ID - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if instr == nil { - continue - } - base++ - instr.setID(base) - } - } -} - -// buildReferrers populates the def/use information in all non-nil -// Value.Referrers slice. -// Precondition: all such slices are initially empty. -func buildReferrers(f *Function) { - var rands []*Value - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - rands = instr.Operands(rands[:0]) // recycle storage - for _, rand := range rands { - if r := *rand; r != nil { - if ref := r.Referrers(); ref != nil { - *ref = append(*ref, instr) - } - } - } - } - } -} - -func (f *Function) emitConsts() { - if len(f.Blocks) == 0 { - f.consts = nil - return - } - - // TODO(dh): our deduplication only works on booleans and - // integers. other constants are represented as pointers to - // things. - if len(f.consts) == 0 { - return - } else if len(f.consts) <= 32 { - f.emitConstsFew() - } else { - f.emitConstsMany() - } -} - -func (f *Function) emitConstsFew() { - dedup := make([]*Const, 0, 32) - for _, c := range f.consts { - if len(*c.Referrers()) == 0 { - continue - } - found := false - for _, d := range dedup { - if c.typ == d.typ && c.Value == d.Value { - replaceAll(c, d) - found = true - break - } - } - if !found { - dedup = append(dedup, c) - } - } - - instrs := make([]Instruction, len(f.Blocks[0].Instrs)+len(dedup)) - for i, c := range dedup { - instrs[i] = c - c.setBlock(f.Blocks[0]) - } - copy(instrs[len(dedup):], f.Blocks[0].Instrs) - f.Blocks[0].Instrs = instrs - f.consts = nil -} - -func (f *Function) emitConstsMany() { - type constKey struct { - typ types.Type - value constant.Value - } - - m := make(map[constKey]Value, len(f.consts)) - areNil := 0 - for i, c := range f.consts { - if len(*c.Referrers()) == 0 { - f.consts[i] = nil - areNil++ - continue - } - - k := constKey{ - typ: c.typ, - value: c.Value, - } - if dup, ok := m[k]; !ok { - m[k] = c - } else { - f.consts[i] = nil - areNil++ - replaceAll(c, dup) - } - } - - instrs := make([]Instruction, len(f.Blocks[0].Instrs)+len(f.consts)-areNil) - i := 0 - for _, c := range f.consts { - if c != nil { - instrs[i] = c - c.setBlock(f.Blocks[0]) - i++ - } - } - copy(instrs[i:], f.Blocks[0].Instrs) - f.Blocks[0].Instrs = instrs - f.consts = nil -} - -// buildFakeExits ensures that every block in the function is -// reachable in reverse from the Exit block. This is required to build -// a full post-dominator tree, and to ensure the exit block's -// inclusion in the dominator tree. -func buildFakeExits(fn *Function) { - // Find back-edges via forward DFS - fn.fakeExits = BlockSet{values: make([]bool, len(fn.Blocks))} - seen := fn.blockset(0) - backEdges := fn.blockset(1) - - var dfs func(b *BasicBlock) - dfs = func(b *BasicBlock) { - if !seen.Add(b) { - backEdges.Add(b) - return - } - for _, pred := range b.Succs { - dfs(pred) - } - } - dfs(fn.Blocks[0]) -buildLoop: - for { - seen := fn.blockset(2) - var dfs func(b *BasicBlock) - dfs = func(b *BasicBlock) { - if !seen.Add(b) { - return - } - for _, pred := range b.Preds { - dfs(pred) - } - if b == fn.Exit { - for _, b := range fn.Blocks { - if fn.fakeExits.Has(b) { - dfs(b) - } - } - } - } - dfs(fn.Exit) - - for _, b := range fn.Blocks { - if !seen.Has(b) && backEdges.Has(b) { - // Block b is not reachable from the exit block. Add a - // fake jump from b to exit, then try again. Note that we - // only add one fake edge at a time, as it may make - // multiple blocks reachable. - // - // We only consider those blocks that have back edges. - // Any unreachable block that doesn't have a back edge - // must flow into a loop, which by definition has a - // back edge. Thus, by looking for loops, we should - // need fewer fake edges overall. - fn.fakeExits.Add(b) - continue buildLoop - } - } - - break - } -} - -// finishBody() finalizes the function after IR code generation of its body. -func (f *Function) finishBody() { - f.objects = nil - f.currentBlock = nil - f.lblocks = nil - - // Remove from f.Locals any Allocs that escape to the heap. - j := 0 - for _, l := range f.Locals { - if !l.Heap { - f.Locals[j] = l - j++ - } - } - // Nil out f.Locals[j:] to aid GC. - for i := j; i < len(f.Locals); i++ { - f.Locals[i] = nil - } - f.Locals = f.Locals[:j] - - optimizeBlocks(f) - buildReferrers(f) - buildDomTree(f) - buildPostDomTree(f) - - if f.Prog.mode&NaiveForm == 0 { - lift(f) - } - - // emit constants after lifting, because lifting may produce new constants. - f.emitConsts() - - f.namedResults = nil // (used by lifting) - f.implicitResults = nil - - numberNodes(f) - - defer f.wr.Close() - f.wr.WriteFunc("start", "start", f) - - if f.Prog.mode&PrintFunctions != 0 { - printMu.Lock() - f.WriteTo(os.Stdout) - printMu.Unlock() - } - - if f.Prog.mode&SanityCheckFunctions != 0 { - mustSanityCheck(f, nil) - } -} - -func isUselessPhi(phi *Phi) (Value, bool) { - var v0 Value - for _, e := range phi.Edges { - if e == phi { - continue - } - if v0 == nil { - v0 = e - } - if v0 != e { - if v0, ok := v0.(*Const); ok { - if e, ok := e.(*Const); ok { - if v0.typ == e.typ && v0.Value == e.Value { - continue - } - } - } - return nil, false - } - } - return v0, true -} - -func (f *Function) RemoveNilBlocks() { - f.removeNilBlocks() -} - -// removeNilBlocks eliminates nils from f.Blocks and updates each -// BasicBlock.Index. Use this after any pass that may delete blocks. -// -func (f *Function) removeNilBlocks() { - j := 0 - for _, b := range f.Blocks { - if b != nil { - b.Index = j - f.Blocks[j] = b - j++ - } - } - // Nil out f.Blocks[j:] to aid GC. - for i := j; i < len(f.Blocks); i++ { - f.Blocks[i] = nil - } - f.Blocks = f.Blocks[:j] -} - -// SetDebugMode sets the debug mode for package pkg. If true, all its -// functions will include full debug info. This greatly increases the -// size of the instruction stream, and causes Functions to depend upon -// the ASTs, potentially keeping them live in memory for longer. -// -func (pkg *Package) SetDebugMode(debug bool) { - // TODO(adonovan): do we want ast.File granularity? - pkg.debug = debug -} - -// debugInfo reports whether debug info is wanted for this function. -func (f *Function) debugInfo() bool { - return f.Pkg != nil && f.Pkg.debug -} - -// addNamedLocal creates a local variable, adds it to function f and -// returns it. Its name and type are taken from obj. Subsequent -// calls to f.lookup(obj) will return the same local. -// -func (f *Function) addNamedLocal(obj types.Object, source ast.Node) *Alloc { - l := f.addLocal(obj.Type(), source) - f.objects[obj] = l - return l -} - -func (f *Function) addLocalForIdent(id *ast.Ident) *Alloc { - return f.addNamedLocal(f.Pkg.info.Defs[id], id) -} - -// addLocal creates an anonymous local variable of type typ, adds it -// to function f and returns it. pos is the optional source location. -// -func (f *Function) addLocal(typ types.Type, source ast.Node) *Alloc { - v := &Alloc{} - v.setType(types.NewPointer(typ)) - f.Locals = append(f.Locals, v) - f.emit(v, source) - return v -} - -// lookup returns the address of the named variable identified by obj -// that is local to function f or one of its enclosing functions. -// If escaping, the reference comes from a potentially escaping pointer -// expression and the referent must be heap-allocated. -// -func (f *Function) lookup(obj types.Object, escaping bool) Value { - if v, ok := f.objects[obj]; ok { - if alloc, ok := v.(*Alloc); ok && escaping { - alloc.Heap = true - } - return v // function-local var (address) - } - - // Definition must be in an enclosing function; - // plumb it through intervening closures. - if f.parent == nil { - panic("no ir.Value for " + obj.String()) - } - outer := f.parent.lookup(obj, true) // escaping - v := &FreeVar{ - name: obj.Name(), - typ: outer.Type(), - outer: outer, - parent: f, - } - f.objects[obj] = v - f.FreeVars = append(f.FreeVars, v) - return v -} - -// emit emits the specified instruction to function f. -func (f *Function) emit(instr Instruction, source ast.Node) Value { - return f.currentBlock.emit(instr, source) -} - -// RelString returns the full name of this function, qualified by -// package name, receiver type, etc. -// -// The specific formatting rules are not guaranteed and may change. -// -// Examples: -// "math.IsNaN" // a package-level function -// "(*bytes.Buffer).Bytes" // a declared method or a wrapper -// "(*bytes.Buffer).Bytes$thunk" // thunk (func wrapping method; receiver is param 0) -// "(*bytes.Buffer).Bytes$bound" // bound (func wrapping method; receiver supplied by closure) -// "main.main$1" // an anonymous function in main -// "main.init#1" // a declared init function -// "main.init" // the synthesized package initializer -// -// When these functions are referred to from within the same package -// (i.e. from == f.Pkg.Object), they are rendered without the package path. -// For example: "IsNaN", "(*Buffer).Bytes", etc. -// -// All non-synthetic functions have distinct package-qualified names. -// (But two methods may have the same name "(T).f" if one is a synthetic -// wrapper promoting a non-exported method "f" from another package; in -// that case, the strings are equal but the identifiers "f" are distinct.) -// -func (f *Function) RelString(from *types.Package) string { - // Anonymous? - if f.parent != nil { - // An anonymous function's Name() looks like "parentName$1", - // but its String() should include the type/package/etc. - parent := f.parent.RelString(from) - for i, anon := range f.parent.AnonFuncs { - if anon == f { - return fmt.Sprintf("%s$%d", parent, 1+i) - } - } - - return f.name // should never happen - } - - // Method (declared or wrapper)? - if recv := f.Signature.Recv(); recv != nil { - return f.relMethod(from, recv.Type()) - } - - // Thunk? - if f.method != nil { - return f.relMethod(from, f.method.Recv()) - } - - // Bound? - if len(f.FreeVars) == 1 && strings.HasSuffix(f.name, "$bound") { - return f.relMethod(from, f.FreeVars[0].Type()) - } - - // Package-level function? - // Prefix with package name for cross-package references only. - if p := f.pkg(); p != nil && p != from { - return fmt.Sprintf("%s.%s", p.Path(), f.name) - } - - // Unknown. - return f.name -} - -func (f *Function) relMethod(from *types.Package, recv types.Type) string { - return fmt.Sprintf("(%s).%s", relType(recv, from), f.name) -} - -// writeSignature writes to buf the signature sig in declaration syntax. -func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *types.Signature, params []*Parameter) { - buf.WriteString("func ") - if recv := sig.Recv(); recv != nil { - buf.WriteString("(") - if n := params[0].Name(); n != "" { - buf.WriteString(n) - buf.WriteString(" ") - } - types.WriteType(buf, params[0].Type(), types.RelativeTo(from)) - buf.WriteString(") ") - } - buf.WriteString(name) - types.WriteSignature(buf, sig, types.RelativeTo(from)) -} - -func (f *Function) pkg() *types.Package { - if f.Pkg != nil { - return f.Pkg.Pkg - } - return nil -} - -var _ io.WriterTo = (*Function)(nil) // *Function implements io.Writer - -func (f *Function) WriteTo(w io.Writer) (int64, error) { - var buf bytes.Buffer - WriteFunction(&buf, f) - n, err := w.Write(buf.Bytes()) - return int64(n), err -} - -// WriteFunction writes to buf a human-readable "disassembly" of f. -func WriteFunction(buf *bytes.Buffer, f *Function) { - fmt.Fprintf(buf, "# Name: %s\n", f.String()) - if f.Pkg != nil { - fmt.Fprintf(buf, "# Package: %s\n", f.Pkg.Pkg.Path()) - } - if syn := f.Synthetic; syn != "" { - fmt.Fprintln(buf, "# Synthetic:", syn) - } - if pos := f.Pos(); pos.IsValid() { - fmt.Fprintf(buf, "# Location: %s\n", f.Prog.Fset.Position(pos)) - } - - if f.parent != nil { - fmt.Fprintf(buf, "# Parent: %s\n", f.parent.Name()) - } - - from := f.pkg() - - if f.FreeVars != nil { - buf.WriteString("# Free variables:\n") - for i, fv := range f.FreeVars { - fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, fv.Name(), relType(fv.Type(), from)) - } - } - - if len(f.Locals) > 0 { - buf.WriteString("# Locals:\n") - for i, l := range f.Locals { - fmt.Fprintf(buf, "# % 3d:\t%s %s\n", i, l.Name(), relType(deref(l.Type()), from)) - } - } - writeSignature(buf, from, f.Name(), f.Signature, f.Params) - buf.WriteString(":\n") - - if f.Blocks == nil { - buf.WriteString("\t(external)\n") - } - - for _, b := range f.Blocks { - if b == nil { - // Corrupt CFG. - fmt.Fprintf(buf, ".nil:\n") - continue - } - fmt.Fprintf(buf, "b%d:", b.Index) - if len(b.Preds) > 0 { - fmt.Fprint(buf, " ←") - for _, pred := range b.Preds { - fmt.Fprintf(buf, " b%d", pred.Index) - } - } - if b.Comment != "" { - fmt.Fprintf(buf, " # %s", b.Comment) - } - buf.WriteByte('\n') - - if false { // CFG debugging - fmt.Fprintf(buf, "\t# CFG: %s --> %s --> %s\n", b.Preds, b, b.Succs) - } - - buf2 := &bytes.Buffer{} - for _, instr := range b.Instrs { - buf.WriteString("\t") - switch v := instr.(type) { - case Value: - // Left-align the instruction. - if name := v.Name(); name != "" { - fmt.Fprintf(buf, "%s = ", name) - } - buf.WriteString(instr.String()) - case nil: - // Be robust against bad transforms. - buf.WriteString("") - default: - buf.WriteString(instr.String()) - } - buf.WriteString("\n") - - if f.Prog.mode&PrintSource != 0 { - if s := instr.Source(); s != nil { - buf2.Reset() - format.Node(buf2, f.Prog.Fset, s) - for { - line, err := buf2.ReadString('\n') - if len(line) == 0 { - break - } - buf.WriteString("\t\t> ") - buf.WriteString(line) - if line[len(line)-1] != '\n' { - buf.WriteString("\n") - } - if err != nil { - break - } - } - } - } - } - buf.WriteString("\n") - } -} - -// newBasicBlock adds to f a new basic block and returns it. It does -// not automatically become the current block for subsequent calls to emit. -// comment is an optional string for more readable debugging output. -// -func (f *Function) newBasicBlock(comment string) *BasicBlock { - b := &BasicBlock{ - Index: len(f.Blocks), - Comment: comment, - parent: f, - } - b.Succs = b.succs2[:0] - f.Blocks = append(f.Blocks, b) - return b -} - -// NewFunction returns a new synthetic Function instance belonging to -// prog, with its name and signature fields set as specified. -// -// The caller is responsible for initializing the remaining fields of -// the function object, e.g. Pkg, Params, Blocks. -// -// It is practically impossible for clients to construct well-formed -// IR functions/packages/programs directly, so we assume this is the -// job of the Builder alone. NewFunction exists to provide clients a -// little flexibility. For example, analysis tools may wish to -// construct fake Functions for the root of the callgraph, a fake -// "reflect" package, etc. -// -// TODO(adonovan): think harder about the API here. -// -func (prog *Program) NewFunction(name string, sig *types.Signature, provenance string) *Function { - return &Function{Prog: prog, name: name, Signature: sig, Synthetic: provenance} -} - -//lint:ignore U1000 we may make use of this for functions loaded from export data -type extentNode [2]token.Pos - -func (n extentNode) Pos() token.Pos { return n[0] } -func (n extentNode) End() token.Pos { return n[1] } - -func (f *Function) initHTML(name string) { - if name == "" { - return - } - if rel := f.RelString(nil); rel == name { - f.wr = NewHTMLWriter("ir.html", rel, "") - } -} diff --git a/vendor/honnef.co/go/tools/ir/html.go b/vendor/honnef.co/go/tools/ir/html.go deleted file mode 100644 index c18375333..000000000 --- a/vendor/honnef.co/go/tools/ir/html.go +++ /dev/null @@ -1,1124 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Copyright 2019 Dominik Honnef. All rights reserved. - -package ir - -import ( - "bytes" - "fmt" - "go/types" - "html" - "io" - "log" - "os" - "os/exec" - "path/filepath" - "reflect" - "sort" - "strings" -) - -func live(f *Function) []bool { - max := 0 - var ops []*Value - - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if int(instr.ID()) > max { - max = int(instr.ID()) - } - } - } - - out := make([]bool, max+1) - var q []Node - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - switch instr.(type) { - case *BlankStore, *Call, *ConstantSwitch, *Defer, *Go, *If, *Jump, *MapUpdate, *Next, *Panic, *Recv, *Return, *RunDefers, *Send, *Store, *Unreachable: - out[instr.ID()] = true - q = append(q, instr) - } - } - } - - for len(q) > 0 { - v := q[len(q)-1] - q = q[:len(q)-1] - for _, op := range v.Operands(ops) { - if *op == nil { - continue - } - if !out[(*op).ID()] { - out[(*op).ID()] = true - q = append(q, *op) - } - } - } - - return out -} - -type funcPrinter interface { - startBlock(b *BasicBlock, reachable bool) - endBlock(b *BasicBlock) - value(v Node, live bool) - startDepCycle() - endDepCycle() - named(n string, vals []Value) -} - -func namedValues(f *Function) map[types.Object][]Value { - names := map[types.Object][]Value{} - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if instr, ok := instr.(*DebugRef); ok { - if obj := instr.object; obj != nil { - names[obj] = append(names[obj], instr.X) - } - } - } - } - // XXX deduplicate values - return names -} - -func fprintFunc(p funcPrinter, f *Function) { - // XXX does our IR form preserve unreachable blocks? - // reachable, live := findlive(f) - - l := live(f) - for _, b := range f.Blocks { - // XXX - // p.startBlock(b, reachable[b.Index]) - p.startBlock(b, true) - - end := len(b.Instrs) - 1 - if end < 0 { - end = 0 - } - for _, v := range b.Instrs[:end] { - if _, ok := v.(*DebugRef); !ok { - p.value(v, l[v.ID()]) - } - } - p.endBlock(b) - } - - names := namedValues(f) - keys := make([]types.Object, 0, len(names)) - for key := range names { - keys = append(keys, key) - } - sort.Slice(keys, func(i, j int) bool { - return keys[i].Pos() < keys[j].Pos() - }) - for _, key := range keys { - p.named(key.Name(), names[key]) - } -} - -func opName(v Node) string { - switch v := v.(type) { - case *Call: - if v.Common().IsInvoke() { - return "Invoke" - } - return "Call" - case *Alloc: - if v.Heap { - return "HeapAlloc" - } - return "StackAlloc" - case *Select: - if v.Blocking { - return "SelectBlocking" - } - return "SelectNonBlocking" - default: - return reflect.ValueOf(v).Type().Elem().Name() - } -} - -type HTMLWriter struct { - w io.WriteCloser - path string - dot *dotWriter -} - -func NewHTMLWriter(path string, funcname, cfgMask string) *HTMLWriter { - out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) - if err != nil { - log.Fatalf("%v", err) - } - pwd, err := os.Getwd() - if err != nil { - log.Fatalf("%v", err) - } - html := HTMLWriter{w: out, path: filepath.Join(pwd, path)} - html.dot = newDotWriter() - html.start(funcname) - return &html -} - -func (w *HTMLWriter) start(name string) { - if w == nil { - return - } - w.WriteString("") - w.WriteString(` - - - - - -`) - w.WriteString("") - w.WriteString("

") - w.WriteString(html.EscapeString(name)) - w.WriteString("

") - w.WriteString(` -help -
- -

-Click on a value or block to toggle highlighting of that value/block -and its uses. (Values and blocks are highlighted by ID, and IDs of -dead items may be reused, so not all highlights necessarily correspond -to the clicked item.) -

- -

-Faded out values and blocks are dead code that has not been eliminated. -

- -

-Values printed in italics have a dependency cycle. -

- -

-CFG: Dashed edge is for unlikely branches. Blue color is for backward edges. -Edge with a dot means that this edge follows the order in which blocks were laidout. -

- -
-`) - w.WriteString("") - w.WriteString("") -} - -func (w *HTMLWriter) Close() { - if w == nil { - return - } - io.WriteString(w.w, "") - io.WriteString(w.w, "
") - io.WriteString(w.w, "") - io.WriteString(w.w, "") - w.w.Close() - fmt.Printf("dumped IR to %v\n", w.path) -} - -// WriteFunc writes f in a column headed by title. -// phase is used for collapsing columns and should be unique across the table. -func (w *HTMLWriter) WriteFunc(phase, title string, f *Function) { - if w == nil { - return - } - w.WriteColumn(phase, title, "", funcHTML(f, phase, w.dot)) -} - -// WriteColumn writes raw HTML in a column headed by title. -// It is intended for pre- and post-compilation log output. -func (w *HTMLWriter) WriteColumn(phase, title, class, html string) { - if w == nil { - return - } - id := strings.Replace(phase, " ", "-", -1) - // collapsed column - w.Printf("
%v
", id, phase) - - if class == "" { - w.Printf("", id) - } else { - w.Printf("", id, class) - } - w.WriteString("

" + title + "

") - w.WriteString(html) - w.WriteString("") -} - -func (w *HTMLWriter) Printf(msg string, v ...interface{}) { - if _, err := fmt.Fprintf(w.w, msg, v...); err != nil { - log.Fatalf("%v", err) - } -} - -func (w *HTMLWriter) WriteString(s string) { - if _, err := io.WriteString(w.w, s); err != nil { - log.Fatalf("%v", err) - } -} - -func valueHTML(v Node) string { - if v == nil { - return "<nil>" - } - // TODO: Using the value ID as the class ignores the fact - // that value IDs get recycled and that some values - // are transmuted into other values. - class := fmt.Sprintf("t%d", v.ID()) - var label string - switch v := v.(type) { - case *Function: - label = v.RelString(nil) - case *Builtin: - label = v.Name() - default: - label = class - } - return fmt.Sprintf("%s", class, label) -} - -func valueLongHTML(v Node) string { - // TODO: Any intra-value formatting? - // I'm wary of adding too much visual noise, - // but a little bit might be valuable. - // We already have visual noise in the form of punctuation - // maybe we could replace some of that with formatting. - s := fmt.Sprintf("", v.ID()) - - linenumber := "(?)" - if v.Pos().IsValid() { - line := v.Parent().Prog.Fset.Position(v.Pos()).Line - linenumber = fmt.Sprintf("(%d)", line, line) - } - - s += fmt.Sprintf("%s %s = %s", valueHTML(v), linenumber, opName(v)) - - if v, ok := v.(Value); ok { - s += " <" + html.EscapeString(v.Type().String()) + ">" - } - - switch v := v.(type) { - case *Parameter: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.name)) - case *BinOp: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())) - case *UnOp: - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Op.String())) - case *Extract: - name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name() - s += fmt.Sprintf(" [%d] (%s)", v.Index, name) - case *Field: - st := v.X.Type().Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - s += fmt.Sprintf(" [%d] (%s)", v.Field, name) - case *FieldAddr: - st := deref(v.X.Type()).Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - - s += fmt.Sprintf(" [%d] (%s)", v.Field, name) - case *Recv: - s += fmt.Sprintf(" {%t}", v.CommaOk) - case *Call: - if v.Common().IsInvoke() { - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Common().Method.FullName())) - } - case *Const: - if v.Value == nil { - s += " {<nil>}" - } else { - s += fmt.Sprintf(" {%s}", html.EscapeString(v.Value.String())) - } - case *Sigma: - s += fmt.Sprintf(" [#%s]", v.From) - } - for _, a := range v.Operands(nil) { - s += fmt.Sprintf(" %s", valueHTML(*a)) - } - - // OPT(dh): we're calling namedValues many times on the same function. - allNames := namedValues(v.Parent()) - var names []string - for name, values := range allNames { - for _, value := range values { - if v == value { - names = append(names, name.Name()) - break - } - } - } - if len(names) != 0 { - s += " (" + strings.Join(names, ", ") + ")" - } - - s += "" - return s -} - -func blockHTML(b *BasicBlock) string { - // TODO: Using the value ID as the class ignores the fact - // that value IDs get recycled and that some values - // are transmuted into other values. - s := html.EscapeString(b.String()) - return fmt.Sprintf("%s", s, s) -} - -func blockLongHTML(b *BasicBlock) string { - var kind string - var term Instruction - if len(b.Instrs) > 0 { - term = b.Control() - kind = opName(term) - } - // TODO: improve this for HTML? - s := fmt.Sprintf("%s", b.Index, kind) - - if term != nil { - ops := term.Operands(nil) - if len(ops) > 0 { - var ss []string - for _, op := range ops { - ss = append(ss, valueHTML(*op)) - } - s += " " + strings.Join(ss, ", ") - } - } - if len(b.Succs) > 0 { - s += " →" // right arrow - for _, c := range b.Succs { - s += " " + blockHTML(c) - } - } - return s -} - -func funcHTML(f *Function, phase string, dot *dotWriter) string { - buf := new(bytes.Buffer) - if dot != nil { - dot.writeFuncSVG(buf, phase, f) - } - fmt.Fprint(buf, "") - p := htmlFuncPrinter{w: buf} - fprintFunc(p, f) - - // fprintFunc(&buf, f) // TODO: HTML, not text,
for line breaks, etc. - fmt.Fprint(buf, "
") - return buf.String() -} - -type htmlFuncPrinter struct { - w io.Writer -} - -func (p htmlFuncPrinter) startBlock(b *BasicBlock, reachable bool) { - var dead string - if !reachable { - dead = "dead-block" - } - fmt.Fprintf(p.w, "
    ", b, dead) - fmt.Fprintf(p.w, "
  • %s:", blockHTML(b)) - if len(b.Preds) > 0 { - io.WriteString(p.w, " ←") // left arrow - for _, pred := range b.Preds { - fmt.Fprintf(p.w, " %s", blockHTML(pred)) - } - } - if len(b.Instrs) > 0 { - io.WriteString(p.w, ``) - } - io.WriteString(p.w, "
  • ") - if len(b.Instrs) > 0 { // start list of values - io.WriteString(p.w, "
  • ") - io.WriteString(p.w, "
      ") - } -} - -func (p htmlFuncPrinter) endBlock(b *BasicBlock) { - if len(b.Instrs) > 0 { // end list of values - io.WriteString(p.w, "
    ") - io.WriteString(p.w, "
  • ") - } - io.WriteString(p.w, "
  • ") - fmt.Fprint(p.w, blockLongHTML(b)) - io.WriteString(p.w, "
  • ") - io.WriteString(p.w, "
") -} - -func (p htmlFuncPrinter) value(v Node, live bool) { - var dead string - if !live { - dead = "dead-value" - } - fmt.Fprintf(p.w, "
  • ", dead) - fmt.Fprint(p.w, valueLongHTML(v)) - io.WriteString(p.w, "
  • ") -} - -func (p htmlFuncPrinter) startDepCycle() { - fmt.Fprintln(p.w, "") -} - -func (p htmlFuncPrinter) endDepCycle() { - fmt.Fprintln(p.w, "") -} - -func (p htmlFuncPrinter) named(n string, vals []Value) { - fmt.Fprintf(p.w, "
  • name %s: ", n) - for _, val := range vals { - fmt.Fprintf(p.w, "%s ", valueHTML(val)) - } - fmt.Fprintf(p.w, "
  • ") -} - -type dotWriter struct { - path string - broken bool -} - -// newDotWriter returns non-nil value when mask is valid. -// dotWriter will generate SVGs only for the phases specified in the mask. -// mask can contain following patterns and combinations of them: -// * - all of them; -// x-y - x through y, inclusive; -// x,y - x and y, but not the passes between. -func newDotWriter() *dotWriter { - path, err := exec.LookPath("dot") - if err != nil { - fmt.Println(err) - return nil - } - return &dotWriter{path: path} -} - -func (d *dotWriter) writeFuncSVG(w io.Writer, phase string, f *Function) { - if d.broken { - return - } - cmd := exec.Command(d.path, "-Tsvg") - pipe, err := cmd.StdinPipe() - if err != nil { - d.broken = true - fmt.Println(err) - return - } - buf := new(bytes.Buffer) - cmd.Stdout = buf - bufErr := new(bytes.Buffer) - cmd.Stderr = bufErr - err = cmd.Start() - if err != nil { - d.broken = true - fmt.Println(err) - return - } - fmt.Fprint(pipe, `digraph "" { margin=0; size="4,40"; ranksep=.2; `) - id := strings.Replace(phase, " ", "-", -1) - fmt.Fprintf(pipe, `id="g_graph_%s";`, id) - fmt.Fprintf(pipe, `node [style=filled,fillcolor=white,fontsize=16,fontname="Menlo,Times,serif",margin="0.01,0.03"];`) - fmt.Fprintf(pipe, `edge [fontsize=16,fontname="Menlo,Times,serif"];`) - for _, b := range f.Blocks { - layout := "" - fmt.Fprintf(pipe, `%v [label="%v%s\n%v",id="graph_node_%v_%v"];`, b, b, layout, b.Control().String(), id, b) - } - indexOf := make([]int, len(f.Blocks)) - for i, b := range f.Blocks { - indexOf[b.Index] = i - } - - // XXX - /* - ponums := make([]int32, len(f.Blocks)) - _ = postorderWithNumbering(f, ponums) - isBackEdge := func(from, to int) bool { - return ponums[from] <= ponums[to] - } - */ - isBackEdge := func(from, to int) bool { return false } - - for _, b := range f.Blocks { - for i, s := range b.Succs { - style := "solid" - color := "black" - arrow := "vee" - if isBackEdge(b.Index, s.Index) { - color = "blue" - } - fmt.Fprintf(pipe, `%v -> %v [label=" %d ",style="%s",color="%s",arrowhead="%s"];`, b, s, i, style, color, arrow) - } - } - fmt.Fprint(pipe, "}") - pipe.Close() - err = cmd.Wait() - if err != nil { - d.broken = true - fmt.Printf("dot: %v\n%v\n", err, bufErr.String()) - return - } - - svgID := "svg_graph_" + id - fmt.Fprintf(w, `
    `, svgID, svgID) - // For now, an awful hack: edit the html as it passes through - // our fingers, finding ' 0 { - fset = initial[0].Fset - } - - prog := ir.NewProgram(fset, mode) - if opts != nil { - prog.PrintFunc = opts.PrintFunc - } - - isInitial := make(map[*packages.Package]bool, len(initial)) - for _, p := range initial { - isInitial[p] = true - } - - irmap := make(map[*packages.Package]*ir.Package) - packages.Visit(initial, nil, func(p *packages.Package) { - if p.Types != nil && !p.IllTyped { - var files []*ast.File - if deps || isInitial[p] { - files = p.Syntax - } - irmap[p] = prog.CreatePackage(p.Types, files, p.TypesInfo, true) - } - }) - - var irpkgs []*ir.Package - for _, p := range initial { - irpkgs = append(irpkgs, irmap[p]) // may be nil - } - return prog, irpkgs -} - -// CreateProgram returns a new program in IR form, given a program -// loaded from source. An IR package is created for each transitively -// error-free package of lprog. -// -// Code for bodies of functions is not built until Build is called -// on the result. -// -// The mode parameter controls diagnostics and checking during IR construction. -// -// Deprecated: use golang.org/x/tools/go/packages and the Packages -// function instead; see ir.ExampleLoadPackages. -// -func CreateProgram(lprog *loader.Program, mode ir.BuilderMode) *ir.Program { - prog := ir.NewProgram(lprog.Fset, mode) - - for _, info := range lprog.AllPackages { - if info.TransitivelyErrorFree { - prog.CreatePackage(info.Pkg, info.Files, &info.Info, info.Importable) - } - } - - return prog -} - -// BuildPackage builds an IR program with IR for a single package. -// -// It populates pkg by type-checking the specified file ASTs. All -// dependencies are loaded using the importer specified by tc, which -// typically loads compiler export data; IR code cannot be built for -// those packages. BuildPackage then constructs an ir.Program with all -// dependency packages created, and builds and returns the IR package -// corresponding to pkg. -// -// The caller must have set pkg.Path() to the import path. -// -// The operation fails if there were any type-checking or import errors. -// -// See ../ir/example_test.go for an example. -// -func BuildPackage(tc *types.Config, fset *token.FileSet, pkg *types.Package, files []*ast.File, mode ir.BuilderMode) (*ir.Package, *types.Info, error) { - if fset == nil { - panic("no token.FileSet") - } - if pkg.Path() == "" { - panic("package has no import path") - } - - info := &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - } - if err := types.NewChecker(tc, fset, pkg, info).Files(files); err != nil { - return nil, nil, err - } - - prog := ir.NewProgram(fset, mode) - - // Create IR packages for all imports. - // Order is not significant. - created := make(map[*types.Package]bool) - var createAll func(pkgs []*types.Package) - createAll = func(pkgs []*types.Package) { - for _, p := range pkgs { - if !created[p] { - created[p] = true - prog.CreatePackage(p, nil, nil, true) - createAll(p.Imports()) - } - } - } - createAll(pkg.Imports()) - - // Create and build the primary package. - irpkg := prog.CreatePackage(pkg, files, info, false) - irpkg.Build() - return irpkg, info, nil -} diff --git a/vendor/honnef.co/go/tools/ir/irutil/switch.go b/vendor/honnef.co/go/tools/ir/irutil/switch.go deleted file mode 100644 index f44cbca9e..000000000 --- a/vendor/honnef.co/go/tools/ir/irutil/switch.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package irutil - -// This file implements discovery of switch and type-switch constructs -// from low-level control flow. -// -// Many techniques exist for compiling a high-level switch with -// constant cases to efficient machine code. The optimal choice will -// depend on the data type, the specific case values, the code in the -// body of each case, and the hardware. -// Some examples: -// - a lookup table (for a switch that maps constants to constants) -// - a computed goto -// - a binary tree -// - a perfect hash -// - a two-level switch (to partition constant strings by their first byte). - -import ( - "bytes" - "fmt" - "go/token" - "go/types" - - "honnef.co/go/tools/ir" -) - -// A ConstCase represents a single constant comparison. -// It is part of a Switch. -type ConstCase struct { - Block *ir.BasicBlock // block performing the comparison - Body *ir.BasicBlock // body of the case - Value *ir.Const // case comparand -} - -// A TypeCase represents a single type assertion. -// It is part of a Switch. -type TypeCase struct { - Block *ir.BasicBlock // block performing the type assert - Body *ir.BasicBlock // body of the case - Type types.Type // case type - Binding ir.Value // value bound by this case -} - -// A Switch is a logical high-level control flow operation -// (a multiway branch) discovered by analysis of a CFG containing -// only if/else chains. It is not part of the ir.Instruction set. -// -// One of ConstCases and TypeCases has length >= 2; -// the other is nil. -// -// In a value switch, the list of cases may contain duplicate constants. -// A type switch may contain duplicate types, or types assignable -// to an interface type also in the list. -// TODO(adonovan): eliminate such duplicates. -// -type Switch struct { - Start *ir.BasicBlock // block containing start of if/else chain - X ir.Value // the switch operand - ConstCases []ConstCase // ordered list of constant comparisons - TypeCases []TypeCase // ordered list of type assertions - Default *ir.BasicBlock // successor if all comparisons fail -} - -func (sw *Switch) String() string { - // We represent each block by the String() of its - // first Instruction, e.g. "print(42:int)". - var buf bytes.Buffer - if sw.ConstCases != nil { - fmt.Fprintf(&buf, "switch %s {\n", sw.X.Name()) - for _, c := range sw.ConstCases { - fmt.Fprintf(&buf, "case %s: %s\n", c.Value.Name(), c.Body.Instrs[0]) - } - } else { - fmt.Fprintf(&buf, "switch %s.(type) {\n", sw.X.Name()) - for _, c := range sw.TypeCases { - fmt.Fprintf(&buf, "case %s %s: %s\n", - c.Binding.Name(), c.Type, c.Body.Instrs[0]) - } - } - if sw.Default != nil { - fmt.Fprintf(&buf, "default: %s\n", sw.Default.Instrs[0]) - } - fmt.Fprintf(&buf, "}") - return buf.String() -} - -// Switches examines the control-flow graph of fn and returns the -// set of inferred value and type switches. A value switch tests an -// ir.Value for equality against two or more compile-time constant -// values. Switches involving link-time constants (addresses) are -// ignored. A type switch type-asserts an ir.Value against two or -// more types. -// -// The switches are returned in dominance order. -// -// The resulting switches do not necessarily correspond to uses of the -// 'switch' keyword in the source: for example, a single source-level -// switch statement with non-constant cases may result in zero, one or -// many Switches, one per plural sequence of constant cases. -// Switches may even be inferred from if/else- or goto-based control flow. -// (In general, the control flow constructs of the source program -// cannot be faithfully reproduced from the IR.) -// -func Switches(fn *ir.Function) []Switch { - // Traverse the CFG in dominance order, so we don't - // enter an if/else-chain in the middle. - var switches []Switch - seen := make(map[*ir.BasicBlock]bool) // TODO(adonovan): opt: use ir.blockSet - for _, b := range fn.DomPreorder() { - if x, k := isComparisonBlock(b); x != nil { - // Block b starts a switch. - sw := Switch{Start: b, X: x} - valueSwitch(&sw, k, seen) - if len(sw.ConstCases) > 1 { - switches = append(switches, sw) - } - } - - if y, x, T := isTypeAssertBlock(b); y != nil { - // Block b starts a type switch. - sw := Switch{Start: b, X: x} - typeSwitch(&sw, y, T, seen) - if len(sw.TypeCases) > 1 { - switches = append(switches, sw) - } - } - } - return switches -} - -func isSameX(x1 ir.Value, x2 ir.Value) bool { - if x1 == x2 { - return true - } - if x2, ok := x2.(*ir.Sigma); ok { - return isSameX(x1, x2.X) - } - return false -} - -func valueSwitch(sw *Switch, k *ir.Const, seen map[*ir.BasicBlock]bool) { - b := sw.Start - x := sw.X - for isSameX(sw.X, x) { - if seen[b] { - break - } - seen[b] = true - - sw.ConstCases = append(sw.ConstCases, ConstCase{ - Block: b, - Body: b.Succs[0], - Value: k, - }) - b = b.Succs[1] - n := 0 - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.If, *ir.BinOp: - n++ - case *ir.Sigma, *ir.Phi, *ir.DebugRef: - default: - n += 1000 - } - } - if n != 2 { - // Block b contains not just 'if x == k' and σ/ϕ nodes, - // so it may have side effects that - // make it unsafe to elide. - break - } - if len(b.Preds) != 1 { - // Block b has multiple predecessors, - // so it cannot be treated as a case. - break - } - x, k = isComparisonBlock(b) - } - sw.Default = b -} - -func typeSwitch(sw *Switch, y ir.Value, T types.Type, seen map[*ir.BasicBlock]bool) { - b := sw.Start - x := sw.X - for isSameX(sw.X, x) { - if seen[b] { - break - } - seen[b] = true - - sw.TypeCases = append(sw.TypeCases, TypeCase{ - Block: b, - Body: b.Succs[0], - Type: T, - Binding: y, - }) - b = b.Succs[1] - n := 0 - for _, instr := range b.Instrs { - switch instr.(type) { - case *ir.TypeAssert, *ir.Extract, *ir.If: - n++ - case *ir.Sigma, *ir.Phi: - default: - n += 1000 - } - } - if n != 4 { - // Block b contains not just - // {TypeAssert; Extract #0; Extract #1; If} - // so it may have side effects that - // make it unsafe to elide. - break - } - if len(b.Preds) != 1 { - // Block b has multiple predecessors, - // so it cannot be treated as a case. - break - } - y, x, T = isTypeAssertBlock(b) - } - sw.Default = b -} - -// isComparisonBlock returns the operands (v, k) if a block ends with -// a comparison v==k, where k is a compile-time constant. -// -func isComparisonBlock(b *ir.BasicBlock) (v ir.Value, k *ir.Const) { - if n := len(b.Instrs); n >= 2 { - if i, ok := b.Instrs[n-1].(*ir.If); ok { - if binop, ok := i.Cond.(*ir.BinOp); ok && binop.Block() == b && binop.Op == token.EQL { - if k, ok := binop.Y.(*ir.Const); ok { - return binop.X, k - } - if k, ok := binop.X.(*ir.Const); ok { - return binop.Y, k - } - } - } - } - return -} - -// isTypeAssertBlock returns the operands (y, x, T) if a block ends with -// a type assertion "if y, ok := x.(T); ok {". -// -func isTypeAssertBlock(b *ir.BasicBlock) (y, x ir.Value, T types.Type) { - if n := len(b.Instrs); n >= 4 { - if i, ok := b.Instrs[n-1].(*ir.If); ok { - if ext1, ok := i.Cond.(*ir.Extract); ok && ext1.Block() == b && ext1.Index == 1 { - if ta, ok := ext1.Tuple.(*ir.TypeAssert); ok && ta.Block() == b { - // hack: relies upon instruction ordering. - if ext0, ok := b.Instrs[n-3].(*ir.Extract); ok { - return ext0, ta.X, ta.AssertedType - } - } - } - } - } - return -} diff --git a/vendor/honnef.co/go/tools/ir/irutil/util.go b/vendor/honnef.co/go/tools/ir/irutil/util.go deleted file mode 100644 index 04b25f5f9..000000000 --- a/vendor/honnef.co/go/tools/ir/irutil/util.go +++ /dev/null @@ -1,70 +0,0 @@ -package irutil - -import ( - "honnef.co/go/tools/ir" -) - -func Reachable(from, to *ir.BasicBlock) bool { - if from == to { - return true - } - if from.Dominates(to) { - return true - } - - found := false - Walk(from, func(b *ir.BasicBlock) bool { - if b == to { - found = true - return false - } - return true - }) - return found -} - -func Walk(b *ir.BasicBlock, fn func(*ir.BasicBlock) bool) { - seen := map[*ir.BasicBlock]bool{} - wl := []*ir.BasicBlock{b} - for len(wl) > 0 { - b := wl[len(wl)-1] - wl = wl[:len(wl)-1] - if seen[b] { - continue - } - seen[b] = true - if !fn(b) { - continue - } - wl = append(wl, b.Succs...) - } -} - -func Vararg(x *ir.Slice) ([]ir.Value, bool) { - var out []ir.Value - slice, ok := x.X.(*ir.Alloc) - if !ok { - return nil, false - } - for _, ref := range *slice.Referrers() { - if ref == x { - continue - } - if ref.Block() != x.Block() { - return nil, false - } - idx, ok := ref.(*ir.IndexAddr) - if !ok { - return nil, false - } - if len(*idx.Referrers()) != 1 { - return nil, false - } - store, ok := (*idx.Referrers())[0].(*ir.Store) - if !ok { - return nil, false - } - out = append(out, store.Val) - } - return out, true -} diff --git a/vendor/honnef.co/go/tools/ir/irutil/visit.go b/vendor/honnef.co/go/tools/ir/irutil/visit.go deleted file mode 100644 index 657c9cde7..000000000 --- a/vendor/honnef.co/go/tools/ir/irutil/visit.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package irutil // import "honnef.co/go/tools/ir/irutil" - -import "honnef.co/go/tools/ir" - -// This file defines utilities for visiting the IR of -// a Program. -// -// TODO(adonovan): test coverage. - -// AllFunctions finds and returns the set of functions potentially -// needed by program prog, as determined by a simple linker-style -// reachability algorithm starting from the members and method-sets of -// each package. The result may include anonymous functions and -// synthetic wrappers. -// -// Precondition: all packages are built. -// -func AllFunctions(prog *ir.Program) map[*ir.Function]bool { - visit := visitor{ - prog: prog, - seen: make(map[*ir.Function]bool), - } - visit.program() - return visit.seen -} - -type visitor struct { - prog *ir.Program - seen map[*ir.Function]bool -} - -func (visit *visitor) program() { - for _, pkg := range visit.prog.AllPackages() { - for _, mem := range pkg.Members { - if fn, ok := mem.(*ir.Function); ok { - visit.function(fn) - } - } - } - for _, T := range visit.prog.RuntimeTypes() { - mset := visit.prog.MethodSets.MethodSet(T) - for i, n := 0, mset.Len(); i < n; i++ { - visit.function(visit.prog.MethodValue(mset.At(i))) - } - } -} - -func (visit *visitor) function(fn *ir.Function) { - if !visit.seen[fn] { - visit.seen[fn] = true - var buf [10]*ir.Value // avoid alloc in common case - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - for _, op := range instr.Operands(buf[:0]) { - if fn, ok := (*op).(*ir.Function); ok { - visit.function(fn) - } - } - } - } - } -} - -// MainPackages returns the subset of the specified packages -// named "main" that define a main function. -// The result may include synthetic "testmain" packages. -func MainPackages(pkgs []*ir.Package) []*ir.Package { - var mains []*ir.Package - for _, pkg := range pkgs { - if pkg.Pkg.Name() == "main" && pkg.Func("main") != nil { - mains = append(mains, pkg) - } - } - return mains -} diff --git a/vendor/honnef.co/go/tools/ir/lift.go b/vendor/honnef.co/go/tools/ir/lift.go deleted file mode 100644 index 71d5c8cb0..000000000 --- a/vendor/honnef.co/go/tools/ir/lift.go +++ /dev/null @@ -1,1063 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines the lifting pass which tries to "lift" Alloc -// cells (new/local variables) into SSA registers, replacing loads -// with the dominating stored value, eliminating loads and stores, and -// inserting φ- and σ-nodes as needed. - -// Cited papers and resources: -// -// Ron Cytron et al. 1991. Efficiently computing SSA form... -// http://doi.acm.org/10.1145/115372.115320 -// -// Cooper, Harvey, Kennedy. 2001. A Simple, Fast Dominance Algorithm. -// Software Practice and Experience 2001, 4:1-10. -// http://www.hipersoft.rice.edu/grads/publications/dom14.pdf -// -// Daniel Berlin, llvmdev mailing list, 2012. -// http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046638.html -// (Be sure to expand the whole thread.) -// -// C. Scott Ananian. 1997. The static single information form. -// -// Jeremy Singer. 2006. Static program analysis based on virtual register renaming. - -// TODO(adonovan): opt: there are many optimizations worth evaluating, and -// the conventional wisdom for SSA construction is that a simple -// algorithm well engineered often beats those of better asymptotic -// complexity on all but the most egregious inputs. -// -// Danny Berlin suggests that the Cooper et al. algorithm for -// computing the dominance frontier is superior to Cytron et al. -// Furthermore he recommends that rather than computing the DF for the -// whole function then renaming all alloc cells, it may be cheaper to -// compute the DF for each alloc cell separately and throw it away. -// -// Consider exploiting liveness information to avoid creating dead -// φ-nodes which we then immediately remove. -// -// Also see many other "TODO: opt" suggestions in the code. - -import ( - "fmt" - "go/types" - "os" -) - -// If true, show diagnostic information at each step of lifting. -// Very verbose. -const debugLifting = false - -// domFrontier maps each block to the set of blocks in its dominance -// frontier. The outer slice is conceptually a map keyed by -// Block.Index. The inner slice is conceptually a set, possibly -// containing duplicates. -// -// TODO(adonovan): opt: measure impact of dups; consider a packed bit -// representation, e.g. big.Int, and bitwise parallel operations for -// the union step in the Children loop. -// -// domFrontier's methods mutate the slice's elements but not its -// length, so their receivers needn't be pointers. -// -type domFrontier [][]*BasicBlock - -func (df domFrontier) add(u, v *BasicBlock) { - df[u.Index] = append(df[u.Index], v) -} - -// build builds the dominance frontier df for the dominator tree of -// fn, using the algorithm found in A Simple, Fast Dominance -// Algorithm, Figure 5. -// -// TODO(adonovan): opt: consider Berlin approach, computing pruned SSA -// by pruning the entire IDF computation, rather than merely pruning -// the DF -> IDF step. -func (df domFrontier) build(fn *Function) { - for _, b := range fn.Blocks { - if len(b.Preds) >= 2 { - for _, p := range b.Preds { - runner := p - for runner != b.dom.idom { - df.add(runner, b) - runner = runner.dom.idom - } - } - } - } -} - -func buildDomFrontier(fn *Function) domFrontier { - df := make(domFrontier, len(fn.Blocks)) - df.build(fn) - return df -} - -type postDomFrontier [][]*BasicBlock - -func (rdf postDomFrontier) add(u, v *BasicBlock) { - rdf[u.Index] = append(rdf[u.Index], v) -} - -func (rdf postDomFrontier) build(fn *Function) { - for _, b := range fn.Blocks { - if len(b.Succs) >= 2 { - for _, s := range b.Succs { - runner := s - for runner != b.pdom.idom { - rdf.add(runner, b) - runner = runner.pdom.idom - } - } - } - } -} - -func buildPostDomFrontier(fn *Function) postDomFrontier { - rdf := make(postDomFrontier, len(fn.Blocks)) - rdf.build(fn) - return rdf -} - -func removeInstr(refs []Instruction, instr Instruction) []Instruction { - i := 0 - for _, ref := range refs { - if ref == instr { - continue - } - refs[i] = ref - i++ - } - for j := i; j != len(refs); j++ { - refs[j] = nil // aid GC - } - return refs[:i] -} - -func clearInstrs(instrs []Instruction) { - for i := range instrs { - instrs[i] = nil - } -} - -// lift replaces local and new Allocs accessed only with -// load/store by IR registers, inserting φ- and σ-nodes where necessary. -// The result is a program in pruned SSI form. -// -// Preconditions: -// - fn has no dead blocks (blockopt has run). -// - Def/use info (Operands and Referrers) is up-to-date. -// - The dominator tree is up-to-date. -// -func lift(fn *Function) { - // TODO(adonovan): opt: lots of little optimizations may be - // worthwhile here, especially if they cause us to avoid - // buildDomFrontier. For example: - // - // - Alloc never loaded? Eliminate. - // - Alloc never stored? Replace all loads with a zero constant. - // - Alloc stored once? Replace loads with dominating store; - // don't forget that an Alloc is itself an effective store - // of zero. - // - Alloc used only within a single block? - // Use degenerate algorithm avoiding φ-nodes. - // - Consider synergy with scalar replacement of aggregates (SRA). - // e.g. *(&x.f) where x is an Alloc. - // Perhaps we'd get better results if we generated this as x.f - // i.e. Field(x, .f) instead of Load(FieldIndex(x, .f)). - // Unclear. - // - // But we will start with the simplest correct code. - var df domFrontier - var rdf postDomFrontier - var closure *closure - var newPhis newPhiMap - var newSigmas newSigmaMap - - // During this pass we will replace some BasicBlock.Instrs - // (allocs, loads and stores) with nil, keeping a count in - // BasicBlock.gaps. At the end we will reset Instrs to the - // concatenation of all non-dead newPhis and non-nil Instrs - // for the block, reusing the original array if space permits. - - // While we're here, we also eliminate 'rundefers' - // instructions in functions that contain no 'defer' - // instructions. - usesDefer := false - - // Determine which allocs we can lift and number them densely. - // The renaming phase uses this numbering for compact maps. - numAllocs := 0 - for _, b := range fn.Blocks { - b.gaps = 0 - b.rundefers = 0 - for _, instr := range b.Instrs { - switch instr := instr.(type) { - case *Alloc: - if !liftable(instr) { - instr.index = -1 - continue - } - index := -1 - if numAllocs == 0 { - df = buildDomFrontier(fn) - rdf = buildPostDomFrontier(fn) - if len(fn.Blocks) > 2 { - closure = transitiveClosure(fn) - } - newPhis = make(newPhiMap, len(fn.Blocks)) - newSigmas = make(newSigmaMap, len(fn.Blocks)) - - if debugLifting { - title := false - for i, blocks := range df { - if blocks != nil { - if !title { - fmt.Fprintf(os.Stderr, "Dominance frontier of %s:\n", fn) - title = true - } - fmt.Fprintf(os.Stderr, "\t%s: %s\n", fn.Blocks[i], blocks) - } - } - } - } - liftAlloc(closure, df, rdf, instr, newPhis, newSigmas) - index = numAllocs - numAllocs++ - instr.index = index - case *Defer: - usesDefer = true - case *RunDefers: - b.rundefers++ - } - } - } - - if numAllocs > 0 { - // renaming maps an alloc (keyed by index) to its replacement - // value. Initially the renaming contains nil, signifying the - // zero constant of the appropriate type; we construct the - // Const lazily at most once on each path through the domtree. - // TODO(adonovan): opt: cache per-function not per subtree. - renaming := make([]Value, numAllocs) - - // Renaming. - rename(fn.Blocks[0], renaming, newPhis, newSigmas) - - simplifyPhis(newPhis) - - // Eliminate dead φ- and σ-nodes. - markLiveNodes(fn.Blocks, newPhis, newSigmas) - } - - // Prepend remaining live φ-nodes to each block and possibly kill rundefers. - for _, b := range fn.Blocks { - var head []Instruction - if numAllocs > 0 { - nps := newPhis[b.Index] - head = make([]Instruction, 0, len(nps)) - for _, pred := range b.Preds { - nss := newSigmas[pred.Index] - idx := pred.succIndex(b) - for _, newSigma := range nss { - if sigma := newSigma.sigmas[idx]; sigma != nil && sigma.live { - head = append(head, sigma) - - // we didn't populate referrers before, as most - // sigma nodes will be killed - if refs := sigma.X.Referrers(); refs != nil { - *refs = append(*refs, sigma) - } - } else if sigma != nil { - sigma.block = nil - } - } - } - for _, np := range nps { - if np.phi.live { - head = append(head, np.phi) - } else { - for _, edge := range np.phi.Edges { - if refs := edge.Referrers(); refs != nil { - *refs = removeInstr(*refs, np.phi) - } - } - np.phi.block = nil - } - } - } - - rundefersToKill := b.rundefers - if usesDefer { - rundefersToKill = 0 - } - - j := len(head) - if j+b.gaps+rundefersToKill == 0 { - continue // fast path: no new phis or gaps - } - - // We could do straight copies instead of element-wise copies - // when both b.gaps and rundefersToKill are zero. However, - // that seems to only be the case ~1% of the time, which - // doesn't seem worth the extra branch. - - // Remove dead instructions, add phis and sigmas - ns := len(b.Instrs) + j - b.gaps - rundefersToKill - if ns <= cap(b.Instrs) { - // b.Instrs has enough capacity to store all instructions - - // OPT(dh): check cap vs the actually required space; if - // there is a big enough difference, it may be worth - // allocating a new slice, to avoid pinning memory. - dst := b.Instrs[:cap(b.Instrs)] - i := len(dst) - 1 - for n := len(b.Instrs) - 1; n >= 0; n-- { - instr := dst[n] - if instr == nil { - continue - } - if !usesDefer { - if _, ok := instr.(*RunDefers); ok { - continue - } - } - dst[i] = instr - i-- - } - off := i + 1 - len(head) - // aid GC - clearInstrs(dst[:off]) - dst = dst[off:] - copy(dst, head) - b.Instrs = dst - } else { - // not enough space, so allocate a new slice and copy - // over. - dst := make([]Instruction, ns) - copy(dst, head) - - for _, instr := range b.Instrs { - if instr == nil { - continue - } - if !usesDefer { - if _, ok := instr.(*RunDefers); ok { - continue - } - } - dst[j] = instr - j++ - } - b.Instrs = dst - } - } - - // Remove any fn.Locals that were lifted. - j := 0 - for _, l := range fn.Locals { - if l.index < 0 { - fn.Locals[j] = l - j++ - } - } - // Nil out fn.Locals[j:] to aid GC. - for i := j; i < len(fn.Locals); i++ { - fn.Locals[i] = nil - } - fn.Locals = fn.Locals[:j] -} - -func hasDirectReferrer(instr Instruction) bool { - for _, instr := range *instr.Referrers() { - switch instr.(type) { - case *Phi, *Sigma: - // ignore - default: - return true - } - } - return false -} - -func markLiveNodes(blocks []*BasicBlock, newPhis newPhiMap, newSigmas newSigmaMap) { - // Phi and sigma nodes are considered live if a non-phi, non-sigma - // node uses them. Once we find a node that is live, we mark all - // of its operands as used, too. - for _, npList := range newPhis { - for _, np := range npList { - phi := np.phi - if !phi.live && hasDirectReferrer(phi) { - markLivePhi(phi) - } - } - } - for _, npList := range newSigmas { - for _, np := range npList { - for _, sigma := range np.sigmas { - if sigma != nil && !sigma.live && hasDirectReferrer(sigma) { - markLiveSigma(sigma) - } - } - } - } - // Existing φ-nodes due to && and || operators - // are all considered live (see Go issue 19622). - for _, b := range blocks { - for _, phi := range b.phis() { - markLivePhi(phi.(*Phi)) - } - } -} - -func markLivePhi(phi *Phi) { - phi.live = true - for _, rand := range phi.Edges { - switch rand := rand.(type) { - case *Phi: - if !rand.live { - markLivePhi(rand) - } - case *Sigma: - if !rand.live { - markLiveSigma(rand) - } - } - } -} - -func markLiveSigma(sigma *Sigma) { - sigma.live = true - switch rand := sigma.X.(type) { - case *Phi: - if !rand.live { - markLivePhi(rand) - } - case *Sigma: - if !rand.live { - markLiveSigma(rand) - } - } -} - -// simplifyPhis replaces trivial phis with non-phi alternatives. Phi -// nodes where all edges are identical, or consist of only the phi -// itself and one other value, may be replaced with the value. -func simplifyPhis(newPhis newPhiMap) { - // find all phis that are trivial and can be replaced with a - // non-phi value. run until we reach a fixpoint, because replacing - // a phi may make other phis trivial. - for changed := true; changed; { - changed = false - for _, npList := range newPhis { - for _, np := range npList { - if np.phi.live { - // we're reusing 'live' to mean 'dead' in the context of simplifyPhis - continue - } - if r, ok := isUselessPhi(np.phi); ok { - // useless phi, replace its uses with the - // replacement value. the dead phi pass will clean - // up the phi afterwards. - replaceAll(np.phi, r) - np.phi.live = true - changed = true - } - } - } - } - - for _, npList := range newPhis { - for _, np := range npList { - np.phi.live = false - } - } -} - -type BlockSet struct { - idx int - values []bool - count int -} - -func NewBlockSet(size int) *BlockSet { - return &BlockSet{values: make([]bool, size)} -} - -func (s *BlockSet) Set(s2 *BlockSet) { - copy(s.values, s2.values) - s.count = 0 - for _, v := range s.values { - if v { - s.count++ - } - } -} - -func (s *BlockSet) Num() int { - return s.count -} - -func (s *BlockSet) Has(b *BasicBlock) bool { - if b.Index >= len(s.values) { - return false - } - return s.values[b.Index] -} - -// add adds b to the set and returns true if the set changed. -func (s *BlockSet) Add(b *BasicBlock) bool { - if s.values[b.Index] { - return false - } - s.count++ - s.values[b.Index] = true - s.idx = b.Index - - return true -} - -func (s *BlockSet) Clear() { - for j := range s.values { - s.values[j] = false - } - s.count = 0 -} - -// take removes an arbitrary element from a set s and -// returns its index, or returns -1 if empty. -func (s *BlockSet) Take() int { - // [i, end] - for i := s.idx; i < len(s.values); i++ { - if s.values[i] { - s.values[i] = false - s.idx = i - s.count-- - return i - } - } - - // [start, i) - for i := 0; i < s.idx; i++ { - if s.values[i] { - s.values[i] = false - s.idx = i - s.count-- - return i - } - } - - return -1 -} - -type closure struct { - span []uint32 - reachables []interval -} - -type interval uint32 - -const ( - flagMask = 1 << 31 - numBits = 20 - lengthBits = 32 - numBits - 1 - lengthMask = (1<>numBits - } else { - // large interval - i++ - start = uint32(inv & numMask) - end = uint32(r[i]) - } - if idx >= start && idx <= end { - return true - } - } - return false -} - -func (c closure) reachable(id int) []interval { - return c.reachables[c.span[id]:c.span[id+1]] -} - -func (c closure) walk(current *BasicBlock, b *BasicBlock, visited []bool) { - visited[b.Index] = true - for _, succ := range b.Succs { - if visited[succ.Index] { - continue - } - visited[succ.Index] = true - c.walk(current, succ, visited) - } -} - -func transitiveClosure(fn *Function) *closure { - reachable := make([]bool, len(fn.Blocks)) - c := &closure{} - c.span = make([]uint32, len(fn.Blocks)+1) - - addInterval := func(start, end uint32) { - if l := end - start; l <= 1<= 0 { // store of zero to Alloc cell - // Replace dominated loads by the zero value. - renaming[instr.index] = nil - if debugLifting { - fmt.Fprintf(os.Stderr, "\tkill alloc %s\n", instr) - } - // Delete the Alloc. - u.Instrs[i] = nil - u.gaps++ - } - - case *Store: - if alloc, ok := instr.Addr.(*Alloc); ok && alloc.index >= 0 { // store to Alloc cell - // Replace dominated loads by the stored value. - renaming[alloc.index] = instr.Val - if debugLifting { - fmt.Fprintf(os.Stderr, "\tkill store %s; new value: %s\n", - instr, instr.Val.Name()) - } - if refs := instr.Addr.Referrers(); refs != nil { - *refs = removeInstr(*refs, instr) - } - if refs := instr.Val.Referrers(); refs != nil { - *refs = removeInstr(*refs, instr) - } - // Delete the Store. - u.Instrs[i] = nil - u.gaps++ - } - - case *Load: - if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // load of Alloc cell - // In theory, we wouldn't be able to replace loads - // directly, because a loaded value could be used in - // different branches, in which case it should be - // replaced with different sigma nodes. But we can't - // simply defer replacement, either, because then - // later stores might incorrectly affect this load. - // - // To avoid doing renaming on _all_ values (instead of - // just loads and stores like we're doing), we make - // sure during code generation that each load is only - // used in one block. For example, in constant switch - // statements, where the tag is only evaluated once, - // we store it in a temporary and load it for each - // comparison, so that we have individual loads to - // replace. - newval := renamed(u.Parent(), renaming, alloc) - if debugLifting { - fmt.Fprintf(os.Stderr, "\tupdate load %s = %s with %s\n", - instr.Name(), instr, newval) - } - replaceAll(instr, newval) - u.Instrs[i] = nil - u.gaps++ - } - - case *DebugRef: - if x, ok := instr.X.(*Alloc); ok && x.index >= 0 { - if instr.IsAddr { - instr.X = renamed(u.Parent(), renaming, x) - instr.IsAddr = false - - // Add DebugRef to instr.X's referrers. - if refs := instr.X.Referrers(); refs != nil { - *refs = append(*refs, instr) - } - } else { - // A source expression denotes the address - // of an Alloc that was optimized away. - instr.X = nil - - // Delete the DebugRef. - u.Instrs[i] = nil - u.gaps++ - } - } - } - } - - // update all outgoing sigma nodes with the dominating store - for _, sigmas := range newSigmas[u.Index] { - for _, sigma := range sigmas.sigmas { - if sigma == nil { - continue - } - sigma.X = renamed(u.Parent(), renaming, sigmas.alloc) - } - } - - // For each φ-node in a CFG successor, rename the edge. - for succi, v := range u.Succs { - phis := newPhis[v.Index] - if len(phis) == 0 { - continue - } - i := v.predIndex(u) - for _, np := range phis { - phi := np.phi - alloc := np.alloc - // if there's a sigma node, use it, else use the dominating value - var newval Value - for _, sigmas := range newSigmas[u.Index] { - if sigmas.alloc == alloc && sigmas.sigmas[succi] != nil { - newval = sigmas.sigmas[succi] - break - } - } - if newval == nil { - newval = renamed(u.Parent(), renaming, alloc) - } - if debugLifting { - fmt.Fprintf(os.Stderr, "\tsetphi %s edge %s -> %s (#%d) (alloc=%s) := %s\n", - phi.Name(), u, v, i, alloc.Name(), newval.Name()) - } - phi.Edges[i] = newval - if prefs := newval.Referrers(); prefs != nil { - *prefs = append(*prefs, phi) - } - } - } - - // Continue depth-first recursion over domtree, pushing a - // fresh copy of the renaming map for each subtree. - r := make([]Value, len(renaming)) - for _, v := range u.dom.children { - // XXX add debugging - copy(r, renaming) - - // on entry to a block, the incoming sigma nodes become the new values for their alloc - if idx := u.succIndex(v); idx != -1 { - for _, sigma := range newSigmas[u.Index] { - if sigma.sigmas[idx] != nil { - r[sigma.alloc.index] = sigma.sigmas[idx] - } - } - } - rename(v, r, newPhis, newSigmas) - } - -} diff --git a/vendor/honnef.co/go/tools/ir/lvalue.go b/vendor/honnef.co/go/tools/ir/lvalue.go deleted file mode 100644 index f676a1f7a..000000000 --- a/vendor/honnef.co/go/tools/ir/lvalue.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// lvalues are the union of addressable expressions and map-index -// expressions. - -import ( - "go/ast" - "go/types" -) - -// An lvalue represents an assignable location that may appear on the -// left-hand side of an assignment. This is a generalization of a -// pointer to permit updates to elements of maps. -// -type lvalue interface { - store(fn *Function, v Value, source ast.Node) // stores v into the location - load(fn *Function, source ast.Node) Value // loads the contents of the location - address(fn *Function) Value // address of the location - typ() types.Type // returns the type of the location -} - -// An address is an lvalue represented by a true pointer. -type address struct { - addr Value - expr ast.Expr // source syntax of the value (not address) [debug mode] -} - -func (a *address) load(fn *Function, source ast.Node) Value { - return emitLoad(fn, a.addr, source) -} - -func (a *address) store(fn *Function, v Value, source ast.Node) { - store := emitStore(fn, a.addr, v, source) - if a.expr != nil { - // store.Val is v, converted for assignability. - emitDebugRef(fn, a.expr, store.Val, false) - } -} - -func (a *address) address(fn *Function) Value { - if a.expr != nil { - emitDebugRef(fn, a.expr, a.addr, true) - } - return a.addr -} - -func (a *address) typ() types.Type { - return deref(a.addr.Type()) -} - -// An element is an lvalue represented by m[k], the location of an -// element of a map. These locations are not addressable -// since pointers cannot be formed from them, but they do support -// load() and store(). -// -type element struct { - m, k Value // map - t types.Type // map element type -} - -func (e *element) load(fn *Function, source ast.Node) Value { - l := &MapLookup{ - X: e.m, - Index: e.k, - } - l.setType(e.t) - return fn.emit(l, source) -} - -func (e *element) store(fn *Function, v Value, source ast.Node) { - up := &MapUpdate{ - Map: e.m, - Key: e.k, - Value: emitConv(fn, v, e.t, source), - } - fn.emit(up, source) -} - -func (e *element) address(fn *Function) Value { - panic("map elements are not addressable") -} - -func (e *element) typ() types.Type { - return e.t -} - -// A blank is a dummy variable whose name is "_". -// It is not reified: loads are illegal and stores are ignored. -// -type blank struct{} - -func (bl blank) load(fn *Function, source ast.Node) Value { - panic("blank.load is illegal") -} - -func (bl blank) store(fn *Function, v Value, source ast.Node) { - s := &BlankStore{ - Val: v, - } - fn.emit(s, source) -} - -func (bl blank) address(fn *Function) Value { - panic("blank var is not addressable") -} - -func (bl blank) typ() types.Type { - // This should be the type of the blank Ident; the typechecker - // doesn't provide this yet, but fortunately, we don't need it - // yet either. - panic("blank.typ is unimplemented") -} diff --git a/vendor/honnef.co/go/tools/ir/methods.go b/vendor/honnef.co/go/tools/ir/methods.go deleted file mode 100644 index 517f448b8..000000000 --- a/vendor/honnef.co/go/tools/ir/methods.go +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines utilities for population of method sets. - -import ( - "fmt" - "go/types" -) - -// MethodValue returns the Function implementing method sel, building -// wrapper methods on demand. It returns nil if sel denotes an -// abstract (interface) method. -// -// Precondition: sel.Kind() == MethodVal. -// -// Thread-safe. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -// -func (prog *Program) MethodValue(sel *types.Selection) *Function { - if sel.Kind() != types.MethodVal { - panic(fmt.Sprintf("MethodValue(%s) kind != MethodVal", sel)) - } - T := sel.Recv() - if isInterface(T) { - return nil // abstract method - } - if prog.mode&LogSource != 0 { - defer logStack("MethodValue %s %v", T, sel)() - } - - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - return prog.addMethod(prog.createMethodSet(T), sel) -} - -// LookupMethod returns the implementation of the method of type T -// identified by (pkg, name). It returns nil if the method exists but -// is abstract, and panics if T has no such method. -// -func (prog *Program) LookupMethod(T types.Type, pkg *types.Package, name string) *Function { - sel := prog.MethodSets.MethodSet(T).Lookup(pkg, name) - if sel == nil { - panic(fmt.Sprintf("%s has no method %s", T, types.Id(pkg, name))) - } - return prog.MethodValue(sel) -} - -// methodSet contains the (concrete) methods of a non-interface type. -type methodSet struct { - mapping map[string]*Function // populated lazily - complete bool // mapping contains all methods -} - -// Precondition: !isInterface(T). -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func (prog *Program) createMethodSet(T types.Type) *methodSet { - mset, ok := prog.methodSets.At(T).(*methodSet) - if !ok { - mset = &methodSet{mapping: make(map[string]*Function)} - prog.methodSets.Set(T, mset) - } - return mset -} - -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -func (prog *Program) addMethod(mset *methodSet, sel *types.Selection) *Function { - if sel.Kind() == types.MethodExpr { - panic(sel) - } - id := sel.Obj().Id() - fn := mset.mapping[id] - if fn == nil { - obj := sel.Obj().(*types.Func) - - needsPromotion := len(sel.Index()) > 1 - needsIndirection := !isPointer(recvType(obj)) && isPointer(sel.Recv()) - if needsPromotion || needsIndirection { - fn = makeWrapper(prog, sel) - } else { - fn = prog.declaredFunc(obj) - } - if fn.Signature.Recv() == nil { - panic(fn) // missing receiver - } - mset.mapping[id] = fn - } - return fn -} - -// RuntimeTypes returns a new unordered slice containing all -// concrete types in the program for which a complete (non-empty) -// method set is required at run-time. -// -// Thread-safe. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -// -func (prog *Program) RuntimeTypes() []types.Type { - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - var res []types.Type - prog.methodSets.Iterate(func(T types.Type, v interface{}) { - if v.(*methodSet).complete { - res = append(res, T) - } - }) - return res -} - -// declaredFunc returns the concrete function/method denoted by obj. -// Panic ensues if there is none. -// -func (prog *Program) declaredFunc(obj *types.Func) *Function { - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Function) - } - panic("no concrete method: " + obj.String()) -} - -// needMethodsOf ensures that runtime type information (including the -// complete method set) is available for the specified type T and all -// its subcomponents. -// -// needMethodsOf must be called for at least every type that is an -// operand of some MakeInterface instruction, and for the type of -// every exported package member. -// -// Precondition: T is not a method signature (*Signature with Recv()!=nil). -// -// Thread-safe. (Called via emitConv from multiple builder goroutines.) -// -// TODO(adonovan): make this faster. It accounts for 20% of SSA build time. -// -// EXCLUSIVE_LOCKS_ACQUIRED(prog.methodsMu) -// -func (prog *Program) needMethodsOf(T types.Type) { - prog.methodsMu.Lock() - prog.needMethods(T, false) - prog.methodsMu.Unlock() -} - -// Precondition: T is not a method signature (*Signature with Recv()!=nil). -// Recursive case: skip => don't create methods for T. -// -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -// -func (prog *Program) needMethods(T types.Type, skip bool) { - // Each package maintains its own set of types it has visited. - if prevSkip, ok := prog.runtimeTypes.At(T).(bool); ok { - // needMethods(T) was previously called - if !prevSkip || skip { - return // already seen, with same or false 'skip' value - } - } - prog.runtimeTypes.Set(T, skip) - - tmset := prog.MethodSets.MethodSet(T) - - if !skip && !isInterface(T) && tmset.Len() > 0 { - // Create methods of T. - mset := prog.createMethodSet(T) - if !mset.complete { - mset.complete = true - n := tmset.Len() - for i := 0; i < n; i++ { - prog.addMethod(mset, tmset.At(i)) - } - } - } - - // Recursion over signatures of each method. - for i := 0; i < tmset.Len(); i++ { - sig := tmset.At(i).Type().(*types.Signature) - prog.needMethods(sig.Params(), false) - prog.needMethods(sig.Results(), false) - } - - switch t := T.(type) { - case *types.Basic: - // nop - - case *types.Interface: - // nop---handled by recursion over method set. - - case *types.Pointer: - prog.needMethods(t.Elem(), false) - - case *types.Slice: - prog.needMethods(t.Elem(), false) - - case *types.Chan: - prog.needMethods(t.Elem(), false) - - case *types.Map: - prog.needMethods(t.Key(), false) - prog.needMethods(t.Elem(), false) - - case *types.Signature: - if t.Recv() != nil { - panic(fmt.Sprintf("Signature %s has Recv %s", t, t.Recv())) - } - prog.needMethods(t.Params(), false) - prog.needMethods(t.Results(), false) - - case *types.Named: - // A pointer-to-named type can be derived from a named - // type via reflection. It may have methods too. - prog.needMethods(types.NewPointer(T), false) - - // Consider 'type T struct{S}' where S has methods. - // Reflection provides no way to get from T to struct{S}, - // only to S, so the method set of struct{S} is unwanted, - // so set 'skip' flag during recursion. - prog.needMethods(t.Underlying(), true) - - case *types.Array: - prog.needMethods(t.Elem(), false) - - case *types.Struct: - for i, n := 0, t.NumFields(); i < n; i++ { - prog.needMethods(t.Field(i).Type(), false) - } - - case *types.Tuple: - for i, n := 0, t.Len(); i < n; i++ { - prog.needMethods(t.At(i).Type(), false) - } - - default: - panic(T) - } -} diff --git a/vendor/honnef.co/go/tools/ir/mode.go b/vendor/honnef.co/go/tools/ir/mode.go deleted file mode 100644 index da548fdbb..000000000 --- a/vendor/honnef.co/go/tools/ir/mode.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines the BuilderMode type and its command-line flag. - -import ( - "bytes" - "fmt" -) - -// BuilderMode is a bitmask of options for diagnostics and checking. -// -// *BuilderMode satisfies the flag.Value interface. Example: -// -// var mode = ir.BuilderMode(0) -// func init() { flag.Var(&mode, "build", ir.BuilderModeDoc) } -// -type BuilderMode uint - -const ( - PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout - PrintFunctions // Print function IR code to stdout - PrintSource // Print source code when printing function IR - LogSource // Log source locations as IR builder progresses - SanityCheckFunctions // Perform sanity checking of function bodies - NaiveForm // Build naïve IR form: don't replace local loads/stores with registers - GlobalDebug // Enable debug info for all packages -) - -const BuilderModeDoc = `Options controlling the IR builder. -The value is a sequence of zero or more of these letters: -C perform sanity [C]hecking of the IR form. -D include [D]ebug info for every function. -P print [P]ackage inventory. -F print [F]unction IR code. -A print [A]ST nodes responsible for IR instructions -S log [S]ource locations as IR builder progresses. -N build [N]aive IR form: don't replace local loads/stores with registers. -` - -func (m BuilderMode) String() string { - var buf bytes.Buffer - if m&GlobalDebug != 0 { - buf.WriteByte('D') - } - if m&PrintPackages != 0 { - buf.WriteByte('P') - } - if m&PrintFunctions != 0 { - buf.WriteByte('F') - } - if m&PrintSource != 0 { - buf.WriteByte('A') - } - if m&LogSource != 0 { - buf.WriteByte('S') - } - if m&SanityCheckFunctions != 0 { - buf.WriteByte('C') - } - if m&NaiveForm != 0 { - buf.WriteByte('N') - } - return buf.String() -} - -// Set parses the flag characters in s and updates *m. -func (m *BuilderMode) Set(s string) error { - var mode BuilderMode - for _, c := range s { - switch c { - case 'D': - mode |= GlobalDebug - case 'P': - mode |= PrintPackages - case 'F': - mode |= PrintFunctions - case 'A': - mode |= PrintSource - case 'S': - mode |= LogSource - case 'C': - mode |= SanityCheckFunctions - case 'N': - mode |= NaiveForm - default: - return fmt.Errorf("unknown BuilderMode option: %q", c) - } - } - *m = mode - return nil -} - -// Get returns m. -func (m BuilderMode) Get() interface{} { return m } diff --git a/vendor/honnef.co/go/tools/ir/print.go b/vendor/honnef.co/go/tools/ir/print.go deleted file mode 100644 index c16c08efa..000000000 --- a/vendor/honnef.co/go/tools/ir/print.go +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file implements the String() methods for all Value and -// Instruction types. - -import ( - "bytes" - "fmt" - "go/types" - "io" - "reflect" - "sort" - - "golang.org/x/tools/go/types/typeutil" -) - -// relName returns the name of v relative to i. -// In most cases, this is identical to v.Name(), but references to -// Functions (including methods) and Globals use RelString and -// all types are displayed with relType, so that only cross-package -// references are package-qualified. -// -func relName(v Value, i Instruction) string { - if v == nil { - return "" - } - var from *types.Package - if i != nil { - from = i.Parent().pkg() - } - switch v := v.(type) { - case Member: // *Function or *Global - return v.RelString(from) - } - return v.Name() -} - -func relType(t types.Type, from *types.Package) string { - return types.TypeString(t, types.RelativeTo(from)) -} - -func relString(m Member, from *types.Package) string { - // NB: not all globals have an Object (e.g. init$guard), - // so use Package().Object not Object.Package(). - if pkg := m.Package().Pkg; pkg != nil && pkg != from { - return fmt.Sprintf("%s.%s", pkg.Path(), m.Name()) - } - return m.Name() -} - -// Value.String() -// -// This method is provided only for debugging. -// It never appears in disassembly, which uses Value.Name(). - -func (v *Parameter) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Parameter <%s> {%s}", relType(v.Type(), from), v.name) -} - -func (v *FreeVar) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("FreeVar <%s> %s", relType(v.Type(), from), v.Name()) -} - -func (v *Builtin) String() string { - return fmt.Sprintf("Builtin %s", v.Name()) -} - -// Instruction.String() - -func (v *Alloc) String() string { - from := v.Parent().pkg() - storage := "Stack" - if v.Heap { - storage = "Heap" - } - return fmt.Sprintf("%sAlloc <%s>", storage, relType(v.Type(), from)) -} - -func (v *Sigma) String() string { - from := v.Parent().pkg() - s := fmt.Sprintf("Sigma <%s> [b%d] %s", relType(v.Type(), from), v.From.Index, v.X.Name()) - return s -} - -func (v *Phi) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "Phi <%s>", v.Type()) - for i, edge := range v.Edges { - b.WriteString(" ") - // Be robust against malformed CFG. - if v.block == nil { - b.WriteString("??") - continue - } - block := -1 - if i < len(v.block.Preds) { - block = v.block.Preds[i].Index - } - fmt.Fprintf(&b, "%d:", block) - edgeVal := "" // be robust - if edge != nil { - edgeVal = relName(edge, v) - } - b.WriteString(edgeVal) - } - return b.String() -} - -func printCall(v *CallCommon, prefix string, instr Instruction) string { - var b bytes.Buffer - if !v.IsInvoke() { - if value, ok := instr.(Value); ok { - fmt.Fprintf(&b, "%s <%s> %s", prefix, relType(value.Type(), instr.Parent().pkg()), relName(v.Value, instr)) - } else { - fmt.Fprintf(&b, "%s %s", prefix, relName(v.Value, instr)) - } - } else { - if value, ok := instr.(Value); ok { - fmt.Fprintf(&b, "%sInvoke <%s> %s.%s", prefix, relType(value.Type(), instr.Parent().pkg()), relName(v.Value, instr), v.Method.Name()) - } else { - fmt.Fprintf(&b, "%sInvoke %s.%s", prefix, relName(v.Value, instr), v.Method.Name()) - } - } - for _, arg := range v.Args { - b.WriteString(" ") - b.WriteString(relName(arg, instr)) - } - return b.String() -} - -func (c *CallCommon) String() string { - return printCall(c, "", nil) -} - -func (v *Call) String() string { - return printCall(&v.Call, "Call", v) -} - -func (v *BinOp) String() string { - return fmt.Sprintf("BinOp <%s> {%s} %s %s", relType(v.Type(), v.Parent().pkg()), v.Op.String(), relName(v.X, v), relName(v.Y, v)) -} - -func (v *UnOp) String() string { - return fmt.Sprintf("UnOp <%s> {%s} %s", relType(v.Type(), v.Parent().pkg()), v.Op.String(), relName(v.X, v)) -} - -func (v *Load) String() string { - return fmt.Sprintf("Load <%s> %s", relType(v.Type(), v.Parent().pkg()), relName(v.X, v)) -} - -func printConv(prefix string, v, x Value) string { - from := v.Parent().pkg() - return fmt.Sprintf("%s <%s> %s", - prefix, - relType(v.Type(), from), - relName(x, v.(Instruction))) -} - -func (v *ChangeType) String() string { return printConv("ChangeType", v, v.X) } -func (v *Convert) String() string { return printConv("Convert", v, v.X) } -func (v *ChangeInterface) String() string { return printConv("ChangeInterface", v, v.X) } -func (v *MakeInterface) String() string { return printConv("MakeInterface", v, v.X) } - -func (v *MakeClosure) String() string { - from := v.Parent().pkg() - var b bytes.Buffer - fmt.Fprintf(&b, "MakeClosure <%s> %s", relType(v.Type(), from), relName(v.Fn, v)) - if v.Bindings != nil { - for _, c := range v.Bindings { - b.WriteString(" ") - b.WriteString(relName(c, v)) - } - } - return b.String() -} - -func (v *MakeSlice) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MakeSlice <%s> %s %s", - relType(v.Type(), from), - relName(v.Len, v), - relName(v.Cap, v)) -} - -func (v *Slice) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Slice <%s> %s %s %s %s", - relType(v.Type(), from), relName(v.X, v), relName(v.Low, v), relName(v.High, v), relName(v.Max, v)) -} - -func (v *MakeMap) String() string { - res := "" - if v.Reserve != nil { - res = relName(v.Reserve, v) - } - from := v.Parent().pkg() - return fmt.Sprintf("MakeMap <%s> %s", relType(v.Type(), from), res) -} - -func (v *MakeChan) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MakeChan <%s> %s", relType(v.Type(), from), relName(v.Size, v)) -} - -func (v *FieldAddr) String() string { - from := v.Parent().pkg() - st := deref(v.X.Type()).Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - return fmt.Sprintf("FieldAddr <%s> [%d] (%s) %s", relType(v.Type(), from), v.Field, name, relName(v.X, v)) -} - -func (v *Field) String() string { - st := v.X.Type().Underlying().(*types.Struct) - // Be robust against a bad index. - name := "?" - if 0 <= v.Field && v.Field < st.NumFields() { - name = st.Field(v.Field).Name() - } - from := v.Parent().pkg() - return fmt.Sprintf("Field <%s> [%d] (%s) %s", relType(v.Type(), from), v.Field, name, relName(v.X, v)) -} - -func (v *IndexAddr) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("IndexAddr <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *Index) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Index <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *MapLookup) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("MapLookup <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *StringLookup) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("StringLookup <%s> %s %s", relType(v.Type(), from), relName(v.X, v), relName(v.Index, v)) -} - -func (v *Range) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Range <%s> %s", relType(v.Type(), from), relName(v.X, v)) -} - -func (v *Next) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("Next <%s> %s", relType(v.Type(), from), relName(v.Iter, v)) -} - -func (v *TypeAssert) String() string { - from := v.Parent().pkg() - return fmt.Sprintf("TypeAssert <%s> %s", relType(v.Type(), from), relName(v.X, v)) -} - -func (v *Extract) String() string { - from := v.Parent().pkg() - name := v.Tuple.Type().(*types.Tuple).At(v.Index).Name() - return fmt.Sprintf("Extract <%s> [%d] (%s) %s", relType(v.Type(), from), v.Index, name, relName(v.Tuple, v)) -} - -func (s *Jump) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - str := fmt.Sprintf("Jump → b%d", block) - if s.Comment != "" { - str = fmt.Sprintf("%s # %s", str, s.Comment) - } - return str -} - -func (s *Unreachable) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - return fmt.Sprintf("Unreachable → b%d", block) -} - -func (s *If) String() string { - // Be robust against malformed CFG. - tblock, fblock := -1, -1 - if s.block != nil && len(s.block.Succs) == 2 { - tblock = s.block.Succs[0].Index - fblock = s.block.Succs[1].Index - } - return fmt.Sprintf("If %s → b%d b%d", relName(s.Cond, s), tblock, fblock) -} - -func (s *ConstantSwitch) String() string { - var b bytes.Buffer - fmt.Fprintf(&b, "ConstantSwitch %s", relName(s.Tag, s)) - for _, cond := range s.Conds { - fmt.Fprintf(&b, " %s", relName(cond, s)) - } - fmt.Fprint(&b, " →") - for _, succ := range s.block.Succs { - fmt.Fprintf(&b, " b%d", succ.Index) - } - return b.String() -} - -func (s *TypeSwitch) String() string { - from := s.Parent().pkg() - var b bytes.Buffer - fmt.Fprintf(&b, "TypeSwitch <%s> %s", relType(s.typ, from), relName(s.Tag, s)) - for _, cond := range s.Conds { - fmt.Fprintf(&b, " %q", relType(cond, s.block.parent.pkg())) - } - return b.String() -} - -func (s *Go) String() string { - return printCall(&s.Call, "Go", s) -} - -func (s *Panic) String() string { - // Be robust against malformed CFG. - block := -1 - if s.block != nil && len(s.block.Succs) == 1 { - block = s.block.Succs[0].Index - } - return fmt.Sprintf("Panic %s → b%d", relName(s.X, s), block) -} - -func (s *Return) String() string { - var b bytes.Buffer - b.WriteString("Return") - for _, r := range s.Results { - b.WriteString(" ") - b.WriteString(relName(r, s)) - } - return b.String() -} - -func (*RunDefers) String() string { - return "RunDefers" -} - -func (s *Send) String() string { - return fmt.Sprintf("Send %s %s", relName(s.Chan, s), relName(s.X, s)) -} - -func (recv *Recv) String() string { - from := recv.Parent().pkg() - return fmt.Sprintf("Recv <%s> %s", relType(recv.Type(), from), relName(recv.Chan, recv)) -} - -func (s *Defer) String() string { - return printCall(&s.Call, "Defer", s) -} - -func (s *Select) String() string { - var b bytes.Buffer - for i, st := range s.States { - if i > 0 { - b.WriteString(", ") - } - if st.Dir == types.RecvOnly { - b.WriteString("<-") - b.WriteString(relName(st.Chan, s)) - } else { - b.WriteString(relName(st.Chan, s)) - b.WriteString("<-") - b.WriteString(relName(st.Send, s)) - } - } - non := "" - if !s.Blocking { - non = "Non" - } - from := s.Parent().pkg() - return fmt.Sprintf("Select%sBlocking <%s> [%s]", non, relType(s.Type(), from), b.String()) -} - -func (s *Store) String() string { - return fmt.Sprintf("Store {%s} %s %s", - s.Val.Type(), relName(s.Addr, s), relName(s.Val, s)) -} - -func (s *BlankStore) String() string { - return fmt.Sprintf("BlankStore %s", relName(s.Val, s)) -} - -func (s *MapUpdate) String() string { - return fmt.Sprintf("MapUpdate %s %s %s", relName(s.Map, s), relName(s.Key, s), relName(s.Value, s)) -} - -func (s *DebugRef) String() string { - p := s.Parent().Prog.Fset.Position(s.Pos()) - var descr interface{} - if s.object != nil { - descr = s.object // e.g. "var x int" - } else { - descr = reflect.TypeOf(s.Expr) // e.g. "*ast.CallExpr" - } - var addr string - if s.IsAddr { - addr = "address of " - } - return fmt.Sprintf("; %s%s @ %d:%d is %s", addr, descr, p.Line, p.Column, s.X.Name()) -} - -func (p *Package) String() string { - return "package " + p.Pkg.Path() -} - -var _ io.WriterTo = (*Package)(nil) // *Package implements io.Writer - -func (p *Package) WriteTo(w io.Writer) (int64, error) { - var buf bytes.Buffer - WritePackage(&buf, p) - n, err := w.Write(buf.Bytes()) - return int64(n), err -} - -// WritePackage writes to buf a human-readable summary of p. -func WritePackage(buf *bytes.Buffer, p *Package) { - fmt.Fprintf(buf, "%s:\n", p) - - var names []string - maxname := 0 - for name := range p.Members { - if l := len(name); l > maxname { - maxname = l - } - names = append(names, name) - } - - from := p.Pkg - sort.Strings(names) - for _, name := range names { - switch mem := p.Members[name].(type) { - case *NamedConst: - fmt.Fprintf(buf, " const %-*s %s = %s\n", - maxname, name, mem.Name(), mem.Value.RelString(from)) - - case *Function: - fmt.Fprintf(buf, " func %-*s %s\n", - maxname, name, relType(mem.Type(), from)) - - case *Type: - fmt.Fprintf(buf, " type %-*s %s\n", - maxname, name, relType(mem.Type().Underlying(), from)) - for _, meth := range typeutil.IntuitiveMethodSet(mem.Type(), &p.Prog.MethodSets) { - fmt.Fprintf(buf, " %s\n", types.SelectionString(meth, types.RelativeTo(from))) - } - - case *Global: - fmt.Fprintf(buf, " var %-*s %s\n", - maxname, name, relType(mem.Type().(*types.Pointer).Elem(), from)) - } - } - - fmt.Fprintf(buf, "\n") -} diff --git a/vendor/honnef.co/go/tools/ir/sanity.go b/vendor/honnef.co/go/tools/ir/sanity.go deleted file mode 100644 index ff9edbc64..000000000 --- a/vendor/honnef.co/go/tools/ir/sanity.go +++ /dev/null @@ -1,555 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// An optional pass for sanity-checking invariants of the IR representation. -// Currently it checks CFG invariants but little at the instruction level. - -import ( - "fmt" - "go/types" - "io" - "os" - "strings" -) - -type sanity struct { - reporter io.Writer - fn *Function - block *BasicBlock - instrs map[Instruction]struct{} - insane bool -} - -// sanityCheck performs integrity checking of the IR representation -// of the function fn and returns true if it was valid. Diagnostics -// are written to reporter if non-nil, os.Stderr otherwise. Some -// diagnostics are only warnings and do not imply a negative result. -// -// Sanity-checking is intended to facilitate the debugging of code -// transformation passes. -// -func sanityCheck(fn *Function, reporter io.Writer) bool { - if reporter == nil { - reporter = os.Stderr - } - return (&sanity{reporter: reporter}).checkFunction(fn) -} - -// mustSanityCheck is like sanityCheck but panics instead of returning -// a negative result. -// -func mustSanityCheck(fn *Function, reporter io.Writer) { - if !sanityCheck(fn, reporter) { - fn.WriteTo(os.Stderr) - panic("SanityCheck failed") - } -} - -func (s *sanity) diagnostic(prefix, format string, args ...interface{}) { - fmt.Fprintf(s.reporter, "%s: function %s", prefix, s.fn) - if s.block != nil { - fmt.Fprintf(s.reporter, ", block %s", s.block) - } - io.WriteString(s.reporter, ": ") - fmt.Fprintf(s.reporter, format, args...) - io.WriteString(s.reporter, "\n") -} - -func (s *sanity) errorf(format string, args ...interface{}) { - s.insane = true - s.diagnostic("Error", format, args...) -} - -func (s *sanity) warnf(format string, args ...interface{}) { - s.diagnostic("Warning", format, args...) -} - -// findDuplicate returns an arbitrary basic block that appeared more -// than once in blocks, or nil if all were unique. -func findDuplicate(blocks []*BasicBlock) *BasicBlock { - if len(blocks) < 2 { - return nil - } - if blocks[0] == blocks[1] { - return blocks[0] - } - // Slow path: - m := make(map[*BasicBlock]bool) - for _, b := range blocks { - if m[b] { - return b - } - m[b] = true - } - return nil -} - -func (s *sanity) checkInstr(idx int, instr Instruction) { - switch instr := instr.(type) { - case *If, *Jump, *Return, *Panic, *Unreachable, *ConstantSwitch: - s.errorf("control flow instruction not at end of block") - case *Sigma: - if idx > 0 { - prev := s.block.Instrs[idx-1] - if _, ok := prev.(*Sigma); !ok { - s.errorf("Sigma instruction follows a non-Sigma: %T", prev) - } - } - case *Phi: - if idx == 0 { - // It suffices to apply this check to just the first phi node. - if dup := findDuplicate(s.block.Preds); dup != nil { - s.errorf("phi node in block with duplicate predecessor %s", dup) - } - } else { - prev := s.block.Instrs[idx-1] - switch prev.(type) { - case *Phi, *Sigma: - default: - s.errorf("Phi instruction follows a non-Phi, non-Sigma: %T", prev) - } - } - if ne, np := len(instr.Edges), len(s.block.Preds); ne != np { - s.errorf("phi node has %d edges but %d predecessors", ne, np) - - } else { - for i, e := range instr.Edges { - if e == nil { - s.errorf("phi node '%v' has no value for edge #%d from %s", instr, i, s.block.Preds[i]) - } - } - } - - case *Alloc: - if !instr.Heap { - found := false - for _, l := range s.fn.Locals { - if l == instr { - found = true - break - } - } - if !found { - s.errorf("local alloc %s = %s does not appear in Function.Locals", instr.Name(), instr) - } - } - - case *BinOp: - case *Call: - case *ChangeInterface: - case *ChangeType: - case *Convert: - if _, ok := instr.X.Type().Underlying().(*types.Basic); !ok { - if _, ok := instr.Type().Underlying().(*types.Basic); !ok { - s.errorf("convert %s -> %s: at least one type must be basic", instr.X.Type(), instr.Type()) - } - } - - case *Defer: - case *Extract: - case *Field: - case *FieldAddr: - case *Go: - case *Index: - case *IndexAddr: - case *MapLookup: - case *StringLookup: - case *MakeChan: - case *MakeClosure: - numFree := len(instr.Fn.(*Function).FreeVars) - numBind := len(instr.Bindings) - if numFree != numBind { - s.errorf("MakeClosure has %d Bindings for function %s with %d free vars", - numBind, instr.Fn, numFree) - - } - if recv := instr.Type().(*types.Signature).Recv(); recv != nil { - s.errorf("MakeClosure's type includes receiver %s", recv.Type()) - } - - case *MakeInterface: - case *MakeMap: - case *MakeSlice: - case *MapUpdate: - case *Next: - case *Range: - case *RunDefers: - case *Select: - case *Send: - case *Slice: - case *Store: - case *TypeAssert: - case *UnOp: - case *DebugRef: - case *BlankStore: - case *Load: - case *Parameter: - case *Const: - case *Recv: - case *TypeSwitch: - default: - panic(fmt.Sprintf("Unknown instruction type: %T", instr)) - } - - if call, ok := instr.(CallInstruction); ok { - if call.Common().Signature() == nil { - s.errorf("nil signature: %s", call) - } - } - - // Check that value-defining instructions have valid types - // and a valid referrer list. - if v, ok := instr.(Value); ok { - t := v.Type() - if t == nil { - s.errorf("no type: %s = %s", v.Name(), v) - } else if t == tRangeIter { - // not a proper type; ignore. - } else if b, ok := t.Underlying().(*types.Basic); ok && b.Info()&types.IsUntyped != 0 { - if _, ok := v.(*Const); !ok { - s.errorf("instruction has 'untyped' result: %s = %s : %s", v.Name(), v, t) - } - } - s.checkReferrerList(v) - } - - // Untyped constants are legal as instruction Operands(), - // for example: - // _ = "foo"[0] - // or: - // if wordsize==64 {...} - - // All other non-Instruction Values can be found via their - // enclosing Function or Package. -} - -func (s *sanity) checkFinalInstr(instr Instruction) { - switch instr := instr.(type) { - case *If: - if nsuccs := len(s.block.Succs); nsuccs != 2 { - s.errorf("If-terminated block has %d successors; expected 2", nsuccs) - return - } - if s.block.Succs[0] == s.block.Succs[1] { - s.errorf("If-instruction has same True, False target blocks: %s", s.block.Succs[0]) - return - } - - case *Jump: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Jump-terminated block has %d successors; expected 1", nsuccs) - return - } - - case *Return: - if nsuccs := len(s.block.Succs); nsuccs != 0 { - s.errorf("Return-terminated block has %d successors; expected none", nsuccs) - return - } - if na, nf := len(instr.Results), s.fn.Signature.Results().Len(); nf != na { - s.errorf("%d-ary return in %d-ary function", na, nf) - } - - case *Panic: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Panic-terminated block has %d successors; expected one", nsuccs) - return - } - - case *Unreachable: - if nsuccs := len(s.block.Succs); nsuccs != 1 { - s.errorf("Unreachable-terminated block has %d successors; expected one", nsuccs) - return - } - - case *ConstantSwitch: - - default: - s.errorf("non-control flow instruction at end of block") - } -} - -func (s *sanity) checkBlock(b *BasicBlock, index int) { - s.block = b - - if b.Index != index { - s.errorf("block has incorrect Index %d", b.Index) - } - if b.parent != s.fn { - s.errorf("block has incorrect parent %s", b.parent) - } - - // Check all blocks are reachable. - // (The entry block is always implicitly reachable, the exit block may be unreachable.) - if index > 1 && len(b.Preds) == 0 { - s.warnf("unreachable block") - if b.Instrs == nil { - // Since this block is about to be pruned, - // tolerating transient problems in it - // simplifies other optimizations. - return - } - } - - // Check predecessor and successor relations are dual, - // and that all blocks in CFG belong to same function. - for _, a := range b.Preds { - found := false - for _, bb := range a.Succs { - if bb == b { - found = true - break - } - } - if !found { - s.errorf("expected successor edge in predecessor %s; found only: %s", a, a.Succs) - } - if a.parent != s.fn { - s.errorf("predecessor %s belongs to different function %s", a, a.parent) - } - } - for _, c := range b.Succs { - found := false - for _, bb := range c.Preds { - if bb == b { - found = true - break - } - } - if !found { - s.errorf("expected predecessor edge in successor %s; found only: %s", c, c.Preds) - } - if c.parent != s.fn { - s.errorf("successor %s belongs to different function %s", c, c.parent) - } - } - - // Check each instruction is sane. - n := len(b.Instrs) - if n == 0 { - s.errorf("basic block contains no instructions") - } - var rands [10]*Value // reuse storage - for j, instr := range b.Instrs { - if instr == nil { - s.errorf("nil instruction at index %d", j) - continue - } - if b2 := instr.Block(); b2 == nil { - s.errorf("nil Block() for instruction at index %d", j) - continue - } else if b2 != b { - s.errorf("wrong Block() (%s) for instruction at index %d ", b2, j) - continue - } - if j < n-1 { - s.checkInstr(j, instr) - } else { - s.checkFinalInstr(instr) - } - - // Check Instruction.Operands. - operands: - for i, op := range instr.Operands(rands[:0]) { - if op == nil { - s.errorf("nil operand pointer %d of %s", i, instr) - continue - } - val := *op - if val == nil { - continue // a nil operand is ok - } - - // Check that "untyped" types only appear on constant operands. - if _, ok := (*op).(*Const); !ok { - if basic, ok := (*op).Type().(*types.Basic); ok { - if basic.Info()&types.IsUntyped != 0 { - s.errorf("operand #%d of %s is untyped: %s", i, instr, basic) - } - } - } - - // Check that Operands that are also Instructions belong to same function. - // TODO(adonovan): also check their block dominates block b. - if val, ok := val.(Instruction); ok { - if val.Block() == nil { - s.errorf("operand %d of %s is an instruction (%s) that belongs to no block", i, instr, val) - } else if val.Parent() != s.fn { - s.errorf("operand %d of %s is an instruction (%s) from function %s", i, instr, val, val.Parent()) - } - } - - // Check that each function-local operand of - // instr refers back to instr. (NB: quadratic) - switch val := val.(type) { - case *Const, *Global, *Builtin: - continue // not local - case *Function: - if val.parent == nil { - continue // only anon functions are local - } - } - - // TODO(adonovan): check val.Parent() != nil <=> val.Referrers() is defined. - - if refs := val.Referrers(); refs != nil { - for _, ref := range *refs { - if ref == instr { - continue operands - } - } - s.errorf("operand %d of %s (%s) does not refer to us", i, instr, val) - } else { - s.errorf("operand %d of %s (%s) has no referrers", i, instr, val) - } - } - } -} - -func (s *sanity) checkReferrerList(v Value) { - refs := v.Referrers() - if refs == nil { - s.errorf("%s has missing referrer list", v.Name()) - return - } - for i, ref := range *refs { - if _, ok := s.instrs[ref]; !ok { - if val, ok := ref.(Value); ok { - s.errorf("%s.Referrers()[%d] = %s = %s is not an instruction belonging to this function", v.Name(), i, val.Name(), val) - } else { - s.errorf("%s.Referrers()[%d] = %s is not an instruction belonging to this function", v.Name(), i, ref) - } - } - } -} - -func (s *sanity) checkFunction(fn *Function) bool { - // TODO(adonovan): check Function invariants: - // - check params match signature - // - check transient fields are nil - // - warn if any fn.Locals do not appear among block instructions. - s.fn = fn - if fn.Prog == nil { - s.errorf("nil Prog") - } - - _ = fn.String() // must not crash - _ = fn.RelString(fn.pkg()) // must not crash - - // All functions have a package, except delegates (which are - // shared across packages, or duplicated as weak symbols in a - // separate-compilation model), and error.Error. - if fn.Pkg == nil { - if strings.HasPrefix(fn.Synthetic, "wrapper ") || - strings.HasPrefix(fn.Synthetic, "bound ") || - strings.HasPrefix(fn.Synthetic, "thunk ") || - strings.HasSuffix(fn.name, "Error") { - // ok - } else { - s.errorf("nil Pkg") - } - } - if src, syn := fn.Synthetic == "", fn.source != nil; src != syn { - s.errorf("got fromSource=%t, hasSyntax=%t; want same values", src, syn) - } - for i, l := range fn.Locals { - if l.Parent() != fn { - s.errorf("Local %s at index %d has wrong parent", l.Name(), i) - } - if l.Heap { - s.errorf("Local %s at index %d has Heap flag set", l.Name(), i) - } - } - // Build the set of valid referrers. - s.instrs = make(map[Instruction]struct{}) - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - s.instrs[instr] = struct{}{} - } - } - for i, p := range fn.Params { - if p.Parent() != fn { - s.errorf("Param %s at index %d has wrong parent", p.Name(), i) - } - // Check common suffix of Signature and Params match type. - if sig := fn.Signature; sig != nil { - j := i - len(fn.Params) + sig.Params().Len() // index within sig.Params - if j < 0 { - continue - } - if !types.Identical(p.Type(), sig.Params().At(j).Type()) { - s.errorf("Param %s at index %d has wrong type (%s, versus %s in Signature)", p.Name(), i, p.Type(), sig.Params().At(j).Type()) - - } - } - - s.checkReferrerList(p) - } - for i, fv := range fn.FreeVars { - if fv.Parent() != fn { - s.errorf("FreeVar %s at index %d has wrong parent", fv.Name(), i) - } - s.checkReferrerList(fv) - } - - if fn.Blocks != nil && len(fn.Blocks) == 0 { - // Function _had_ blocks (so it's not external) but - // they were "optimized" away, even the entry block. - s.errorf("Blocks slice is non-nil but empty") - } - for i, b := range fn.Blocks { - if b == nil { - s.warnf("nil *BasicBlock at f.Blocks[%d]", i) - continue - } - s.checkBlock(b, i) - } - - s.block = nil - for i, anon := range fn.AnonFuncs { - if anon.Parent() != fn { - s.errorf("AnonFuncs[%d]=%s but %s.Parent()=%s", i, anon, anon, anon.Parent()) - } - } - s.fn = nil - return !s.insane -} - -// sanityCheckPackage checks invariants of packages upon creation. -// It does not require that the package is built. -// Unlike sanityCheck (for functions), it just panics at the first error. -func sanityCheckPackage(pkg *Package) { - if pkg.Pkg == nil { - panic(fmt.Sprintf("Package %s has no Object", pkg)) - } - _ = pkg.String() // must not crash - - for name, mem := range pkg.Members { - if name != mem.Name() { - panic(fmt.Sprintf("%s: %T.Name() = %s, want %s", - pkg.Pkg.Path(), mem, mem.Name(), name)) - } - obj := mem.Object() - if obj == nil { - // This check is sound because fields - // {Global,Function}.object have type - // types.Object. (If they were declared as - // *types.{Var,Func}, we'd have a non-empty - // interface containing a nil pointer.) - - continue // not all members have typechecker objects - } - if obj.Name() != name { - if obj.Name() == "init" && strings.HasPrefix(mem.Name(), "init#") { - // Ok. The name of a declared init function varies between - // its types.Func ("init") and its ir.Function ("init#%d"). - } else { - panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s", - pkg.Pkg.Path(), mem, obj.Name(), name)) - } - } - } -} diff --git a/vendor/honnef.co/go/tools/ir/source.go b/vendor/honnef.co/go/tools/ir/source.go deleted file mode 100644 index 93d1ccbd2..000000000 --- a/vendor/honnef.co/go/tools/ir/source.go +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines utilities for working with source positions -// or source-level named entities ("objects"). - -// TODO(adonovan): test that {Value,Instruction}.Pos() positions match -// the originating syntax, as specified. - -import ( - "go/ast" - "go/token" - "go/types" -) - -// EnclosingFunction returns the function that contains the syntax -// node denoted by path. -// -// Syntax associated with package-level variable specifications is -// enclosed by the package's init() function. -// -// Returns nil if not found; reasons might include: -// - the node is not enclosed by any function. -// - the node is within an anonymous function (FuncLit) and -// its IR function has not been created yet -// (pkg.Build() has not yet been called). -// -func EnclosingFunction(pkg *Package, path []ast.Node) *Function { - // Start with package-level function... - fn := findEnclosingPackageLevelFunction(pkg, path) - if fn == nil { - return nil // not in any function - } - - // ...then walk down the nested anonymous functions. - n := len(path) -outer: - for i := range path { - if lit, ok := path[n-1-i].(*ast.FuncLit); ok { - for _, anon := range fn.AnonFuncs { - if anon.Pos() == lit.Type.Func { - fn = anon - continue outer - } - } - // IR function not found: - // - package not yet built, or maybe - // - builder skipped FuncLit in dead block - // (in principle; but currently the Builder - // generates even dead FuncLits). - return nil - } - } - return fn -} - -// HasEnclosingFunction returns true if the AST node denoted by path -// is contained within the declaration of some function or -// package-level variable. -// -// Unlike EnclosingFunction, the behaviour of this function does not -// depend on whether IR code for pkg has been built, so it can be -// used to quickly reject check inputs that will cause -// EnclosingFunction to fail, prior to IR building. -// -func HasEnclosingFunction(pkg *Package, path []ast.Node) bool { - return findEnclosingPackageLevelFunction(pkg, path) != nil -} - -// findEnclosingPackageLevelFunction returns the Function -// corresponding to the package-level function enclosing path. -// -func findEnclosingPackageLevelFunction(pkg *Package, path []ast.Node) *Function { - if n := len(path); n >= 2 { // [... {Gen,Func}Decl File] - switch decl := path[n-2].(type) { - case *ast.GenDecl: - if decl.Tok == token.VAR && n >= 3 { - // Package-level 'var' initializer. - return pkg.init - } - - case *ast.FuncDecl: - // Declared function/method. - fn := findNamedFunc(pkg, decl.Pos()) - if fn == nil && decl.Recv == nil && decl.Name.Name == "init" { - // Hack: return non-nil when IR is not yet - // built so that HasEnclosingFunction works. - return pkg.init - } - return fn - } - } - return nil // not in any function -} - -// findNamedFunc returns the named function whose FuncDecl.Ident is at -// position pos. -// -func findNamedFunc(pkg *Package, pos token.Pos) *Function { - for _, fn := range pkg.Functions { - if fn.Pos() == pos { - return fn - } - } - return nil -} - -// ValueForExpr returns the IR Value that corresponds to non-constant -// expression e. -// -// It returns nil if no value was found, e.g. -// - the expression is not lexically contained within f; -// - f was not built with debug information; or -// - e is a constant expression. (For efficiency, no debug -// information is stored for constants. Use -// go/types.Info.Types[e].Value instead.) -// - e is a reference to nil or a built-in function. -// - the value was optimised away. -// -// If e is an addressable expression used in an lvalue context, -// value is the address denoted by e, and isAddr is true. -// -// The types of e (or &e, if isAddr) and the result are equal -// (modulo "untyped" bools resulting from comparisons). -// -// (Tip: to find the ir.Value given a source position, use -// astutil.PathEnclosingInterval to locate the ast.Node, then -// EnclosingFunction to locate the Function, then ValueForExpr to find -// the ir.Value.) -// -func (f *Function) ValueForExpr(e ast.Expr) (value Value, isAddr bool) { - if f.debugInfo() { // (opt) - e = unparen(e) - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if ref, ok := instr.(*DebugRef); ok { - if ref.Expr == e { - return ref.X, ref.IsAddr - } - } - } - } - } - return -} - -// --- Lookup functions for source-level named entities (types.Objects) --- - -// Package returns the IR Package corresponding to the specified -// type-checker package object. -// It returns nil if no such IR package has been created. -// -func (prog *Program) Package(obj *types.Package) *Package { - return prog.packages[obj] -} - -// packageLevelValue returns the package-level value corresponding to -// the specified named object, which may be a package-level const -// (*Const), var (*Global) or func (*Function) of some package in -// prog. It returns nil if the object is not found. -// -func (prog *Program) packageLevelValue(obj types.Object) Value { - if pkg, ok := prog.packages[obj.Pkg()]; ok { - return pkg.values[obj] - } - return nil -} - -// FuncValue returns the concrete Function denoted by the source-level -// named function obj, or nil if obj denotes an interface method. -// -// TODO(adonovan): check the invariant that obj.Type() matches the -// result's Signature, both in the params/results and in the receiver. -// -func (prog *Program) FuncValue(obj *types.Func) *Function { - fn, _ := prog.packageLevelValue(obj).(*Function) - return fn -} - -// ConstValue returns the IR Value denoted by the source-level named -// constant obj. -// -func (prog *Program) ConstValue(obj *types.Const) *Const { - // TODO(adonovan): opt: share (don't reallocate) - // Consts for const objects and constant ast.Exprs. - - // Universal constant? {true,false,nil} - if obj.Parent() == types.Universe { - return NewConst(obj.Val(), obj.Type()) - } - // Package-level named constant? - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Const) - } - return NewConst(obj.Val(), obj.Type()) -} - -// VarValue returns the IR Value that corresponds to a specific -// identifier denoting the source-level named variable obj. -// -// VarValue returns nil if a local variable was not found, perhaps -// because its package was not built, the debug information was not -// requested during IR construction, or the value was optimized away. -// -// ref is the path to an ast.Ident (e.g. from PathEnclosingInterval), -// and that ident must resolve to obj. -// -// pkg is the package enclosing the reference. (A reference to a var -// always occurs within a function, so we need to know where to find it.) -// -// If the identifier is a field selector and its base expression is -// non-addressable, then VarValue returns the value of that field. -// For example: -// func f() struct {x int} -// f().x // VarValue(x) returns a *Field instruction of type int -// -// All other identifiers denote addressable locations (variables). -// For them, VarValue may return either the variable's address or its -// value, even when the expression is evaluated only for its value; the -// situation is reported by isAddr, the second component of the result. -// -// If !isAddr, the returned value is the one associated with the -// specific identifier. For example, -// var x int // VarValue(x) returns Const 0 here -// x = 1 // VarValue(x) returns Const 1 here -// -// It is not specified whether the value or the address is returned in -// any particular case, as it may depend upon optimizations performed -// during IR code generation, such as registerization, constant -// folding, avoidance of materialization of subexpressions, etc. -// -func (prog *Program) VarValue(obj *types.Var, pkg *Package, ref []ast.Node) (value Value, isAddr bool) { - // All references to a var are local to some function, possibly init. - fn := EnclosingFunction(pkg, ref) - if fn == nil { - return // e.g. def of struct field; IR not built? - } - - id := ref[0].(*ast.Ident) - - // Defining ident of a parameter? - if id.Pos() == obj.Pos() { - for _, param := range fn.Params { - if param.Object() == obj { - return param, false - } - } - } - - // Other ident? - for _, b := range fn.Blocks { - for _, instr := range b.Instrs { - if dr, ok := instr.(*DebugRef); ok { - if dr.Pos() == id.Pos() { - return dr.X, dr.IsAddr - } - } - } - } - - // Defining ident of package-level var? - if v := prog.packageLevelValue(obj); v != nil { - return v.(*Global), true - } - - return // e.g. debug info not requested, or var optimized away -} diff --git a/vendor/honnef.co/go/tools/ir/ssa.go b/vendor/honnef.co/go/tools/ir/ssa.go deleted file mode 100644 index 49693045f..000000000 --- a/vendor/honnef.co/go/tools/ir/ssa.go +++ /dev/null @@ -1,1856 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This package defines a high-level intermediate representation for -// Go programs using static single-information (SSI) form. - -import ( - "fmt" - "go/ast" - "go/constant" - "go/token" - "go/types" - "sync" - - "golang.org/x/tools/go/types/typeutil" -) - -type ID int - -// A Program is a partial or complete Go program converted to IR form. -type Program struct { - Fset *token.FileSet // position information for the files of this Program - PrintFunc string // create ir.html for function specified in PrintFunc - imported map[string]*Package // all importable Packages, keyed by import path - packages map[*types.Package]*Package // all loaded Packages, keyed by object - mode BuilderMode // set of mode bits for IR construction - MethodSets typeutil.MethodSetCache // cache of type-checker's method-sets - - methodsMu sync.Mutex // guards the following maps: - methodSets typeutil.Map // maps type to its concrete methodSet - runtimeTypes typeutil.Map // types for which rtypes are needed - canon typeutil.Map // type canonicalization map - bounds map[*types.Func]*Function // bounds for curried x.Method closures - thunks map[selectionKey]*Function // thunks for T.Method expressions -} - -// A Package is a single analyzed Go package containing Members for -// all package-level functions, variables, constants and types it -// declares. These may be accessed directly via Members, or via the -// type-specific accessor methods Func, Type, Var and Const. -// -// Members also contains entries for "init" (the synthetic package -// initializer) and "init#%d", the nth declared init function, -// and unspecified other things too. -// -type Package struct { - Prog *Program // the owning program - Pkg *types.Package // the corresponding go/types.Package - Members map[string]Member // all package members keyed by name (incl. init and init#%d) - Functions []*Function // all functions, excluding anonymous ones - values map[types.Object]Value // package members (incl. types and methods), keyed by object - init *Function // Func("init"); the package's init function - debug bool // include full debug info in this package - printFunc string // which function to print in HTML form - - // The following fields are set transiently, then cleared - // after building. - buildOnce sync.Once // ensures package building occurs once - ninit int32 // number of init functions - info *types.Info // package type information - files []*ast.File // package ASTs -} - -// A Member is a member of a Go package, implemented by *NamedConst, -// *Global, *Function, or *Type; they are created by package-level -// const, var, func and type declarations respectively. -// -type Member interface { - Name() string // declared name of the package member - String() string // package-qualified name of the package member - RelString(*types.Package) string // like String, but relative refs are unqualified - Object() types.Object // typechecker's object for this member, if any - Type() types.Type // type of the package member - Token() token.Token // token.{VAR,FUNC,CONST,TYPE} - Package() *Package // the containing package -} - -// A Type is a Member of a Package representing a package-level named type. -type Type struct { - object *types.TypeName - pkg *Package -} - -// A NamedConst is a Member of a Package representing a package-level -// named constant. -// -// Pos() returns the position of the declaring ast.ValueSpec.Names[*] -// identifier. -// -// NB: a NamedConst is not a Value; it contains a constant Value, which -// it augments with the name and position of its 'const' declaration. -// -type NamedConst struct { - object *types.Const - Value *Const - pkg *Package -} - -// A Value is an IR value that can be referenced by an instruction. -type Value interface { - setID(ID) - - // Name returns the name of this value, and determines how - // this Value appears when used as an operand of an - // Instruction. - // - // This is the same as the source name for Parameters, - // Builtins, Functions, FreeVars, Globals. - // For constants, it is a representation of the constant's value - // and type. For all other Values this is the name of the - // virtual register defined by the instruction. - // - // The name of an IR Value is not semantically significant, - // and may not even be unique within a function. - Name() string - - // ID returns the ID of this value. IDs are unique within a single - // function and are densely numbered, but may contain gaps. - // Values and other Instructions share the same ID space. - // Globally, values are identified by their addresses. However, - // IDs exist to facilitate efficient storage of mappings between - // values and data when analysing functions. - // - // NB: IDs are allocated late in the IR construction process and - // are not available to early stages of said process. - ID() ID - - // If this value is an Instruction, String returns its - // disassembled form; otherwise it returns unspecified - // human-readable information about the Value, such as its - // kind, name and type. - String() string - - // Type returns the type of this value. Many instructions - // (e.g. IndexAddr) change their behaviour depending on the - // types of their operands. - Type() types.Type - - // Parent returns the function to which this Value belongs. - // It returns nil for named Functions, Builtin and Global. - Parent() *Function - - // Referrers returns the list of instructions that have this - // value as one of their operands; it may contain duplicates - // if an instruction has a repeated operand. - // - // Referrers actually returns a pointer through which the - // caller may perform mutations to the object's state. - // - // Referrers is currently only defined if Parent()!=nil, - // i.e. for the function-local values FreeVar, Parameter, - // Functions (iff anonymous) and all value-defining instructions. - // It returns nil for named Functions, Builtin and Global. - // - // Instruction.Operands contains the inverse of this relation. - Referrers() *[]Instruction - - Operands(rands []*Value) []*Value // nil for non-Instructions - - // Source returns the AST node responsible for creating this - // value. A single AST node may be responsible for more than one - // value, and not all values have an associated AST node. - // - // Do not use this method to find a Value given an ast.Expr; use - // ValueForExpr instead. - Source() ast.Node - - // Pos returns Source().Pos() if Source is not nil, else it - // returns token.NoPos. - Pos() token.Pos -} - -// An Instruction is an IR instruction that computes a new Value or -// has some effect. -// -// An Instruction that defines a value (e.g. BinOp) also implements -// the Value interface; an Instruction that only has an effect (e.g. Store) -// does not. -// -type Instruction interface { - setSource(ast.Node) - setID(ID) - - // String returns the disassembled form of this value. - // - // Examples of Instructions that are Values: - // "BinOp {+} t1 t2" (BinOp) - // "Call len t1" (Call) - // Note that the name of the Value is not printed. - // - // Examples of Instructions that are not Values: - // "Return t1" (Return) - // "Store {int} t2 t1" (Store) - // - // (The separation of Value.Name() from Value.String() is useful - // for some analyses which distinguish the operation from the - // value it defines, e.g., 'y = local int' is both an allocation - // of memory 'local int' and a definition of a pointer y.) - String() string - - // ID returns the ID of this instruction. IDs are unique within a single - // function and are densely numbered, but may contain gaps. - // Globally, instructions are identified by their addresses. However, - // IDs exist to facilitate efficient storage of mappings between - // instructions and data when analysing functions. - // - // NB: IDs are allocated late in the IR construction process and - // are not available to early stages of said process. - ID() ID - - // Parent returns the function to which this instruction - // belongs. - Parent() *Function - - // Block returns the basic block to which this instruction - // belongs. - Block() *BasicBlock - - // setBlock sets the basic block to which this instruction belongs. - setBlock(*BasicBlock) - - // Operands returns the operands of this instruction: the - // set of Values it references. - // - // Specifically, it appends their addresses to rands, a - // user-provided slice, and returns the resulting slice, - // permitting avoidance of memory allocation. - // - // The operands are appended in undefined order, but the order - // is consistent for a given Instruction; the addresses are - // always non-nil but may point to a nil Value. Clients may - // store through the pointers, e.g. to effect a value - // renaming. - // - // Value.Referrers is a subset of the inverse of this - // relation. (Referrers are not tracked for all types of - // Values.) - Operands(rands []*Value) []*Value - - Referrers() *[]Instruction // nil for non-Values - - // Source returns the AST node responsible for creating this - // instruction. A single AST node may be responsible for more than - // one instruction, and not all instructions have an associated - // AST node. - Source() ast.Node - - // Pos returns Source().Pos() if Source is not nil, else it - // returns token.NoPos. - Pos() token.Pos -} - -// A Node is a node in the IR value graph. Every concrete type that -// implements Node is also either a Value, an Instruction, or both. -// -// Node contains the methods common to Value and Instruction, plus the -// Operands and Referrers methods generalized to return nil for -// non-Instructions and non-Values, respectively. -// -// Node is provided to simplify IR graph algorithms. Clients should -// use the more specific and informative Value or Instruction -// interfaces where appropriate. -// -type Node interface { - setID(ID) - - // Common methods: - ID() ID - String() string - Source() ast.Node - Pos() token.Pos - Parent() *Function - - // Partial methods: - Operands(rands []*Value) []*Value // nil for non-Instructions - Referrers() *[]Instruction // nil for non-Values -} - -// Function represents the parameters, results, and code of a function -// or method. -// -// If Blocks is nil, this indicates an external function for which no -// Go source code is available. In this case, FreeVars and Locals -// are nil too. Clients performing whole-program analysis must -// handle external functions specially. -// -// Blocks contains the function's control-flow graph (CFG). -// Blocks[0] is the function entry point; block order is not otherwise -// semantically significant, though it may affect the readability of -// the disassembly. -// To iterate over the blocks in dominance order, use DomPreorder(). -// -// A nested function (Parent()!=nil) that refers to one or more -// lexically enclosing local variables ("free variables") has FreeVars. -// Such functions cannot be called directly but require a -// value created by MakeClosure which, via its Bindings, supplies -// values for these parameters. -// -// If the function is a method (Signature.Recv() != nil) then the first -// element of Params is the receiver parameter. -// -// A Go package may declare many functions called "init". -// For each one, Object().Name() returns "init" but Name() returns -// "init#1", etc, in declaration order. -// -// Pos() returns the declaring ast.FuncLit.Type.Func or the position -// of the ast.FuncDecl.Name, if the function was explicit in the -// source. Synthetic wrappers, for which Synthetic != "", may share -// the same position as the function they wrap. -// Syntax.Pos() always returns the position of the declaring "func" token. -// -// Type() returns the function's Signature. -// -type Function struct { - node - - name string - object types.Object // a declared *types.Func or one of its wrappers - method *types.Selection // info about provenance of synthetic methods - Signature *types.Signature - - Synthetic string // provenance of synthetic function; "" for true source functions - parent *Function // enclosing function if anon; nil if global - Pkg *Package // enclosing package; nil for shared funcs (wrappers and error.Error) - Prog *Program // enclosing program - Params []*Parameter // function parameters; for methods, includes receiver - FreeVars []*FreeVar // free variables whose values must be supplied by closure - Locals []*Alloc // local variables of this function - Blocks []*BasicBlock // basic blocks of the function; nil => external - Exit *BasicBlock // The function's exit block - AnonFuncs []*Function // anonymous functions directly beneath this one - referrers []Instruction // referring instructions (iff Parent() != nil) - WillExit bool // Calling this function will always terminate the process - WillUnwind bool // Calling this function will always unwind (it will call runtime.Goexit or panic) - - *functionBody -} - -type functionBody struct { - // The following fields are set transiently during building, - // then cleared. - currentBlock *BasicBlock // where to emit code - objects map[types.Object]Value // addresses of local variables - namedResults []*Alloc // tuple of named results - implicitResults []*Alloc // tuple of results - targets *targets // linked stack of branch targets - lblocks map[*ast.Object]*lblock // labelled blocks - consts []*Const - wr *HTMLWriter - fakeExits BlockSet - blocksets [5]BlockSet - hasDefer bool -} - -func (fn *Function) results() []*Alloc { - if len(fn.namedResults) > 0 { - return fn.namedResults - } - return fn.implicitResults -} - -// BasicBlock represents an IR basic block. -// -// The final element of Instrs is always an explicit transfer of -// control (If, Jump, Return, Panic, or Unreachable). -// -// A block may contain no Instructions only if it is unreachable, -// i.e., Preds is nil. Empty blocks are typically pruned. -// -// BasicBlocks and their Preds/Succs relation form a (possibly cyclic) -// graph independent of the IR Value graph: the control-flow graph or -// CFG. It is illegal for multiple edges to exist between the same -// pair of blocks. -// -// Each BasicBlock is also a node in the dominator tree of the CFG. -// The tree may be navigated using Idom()/Dominees() and queried using -// Dominates(). -// -// The order of Preds and Succs is significant (to Phi and If -// instructions, respectively). -// -type BasicBlock struct { - Index int // index of this block within Parent().Blocks - Comment string // optional label; no semantic significance - parent *Function // parent function - Instrs []Instruction // instructions in order - Preds, Succs []*BasicBlock // predecessors and successors - succs2 [2]*BasicBlock // initial space for Succs - dom domInfo // dominator tree info - pdom domInfo // post-dominator tree info - post int - gaps int // number of nil Instrs (transient) - rundefers int // number of rundefers (transient) -} - -// Pure values ---------------------------------------- - -// A FreeVar represents a free variable of the function to which it -// belongs. -// -// FreeVars are used to implement anonymous functions, whose free -// variables are lexically captured in a closure formed by -// MakeClosure. The value of such a free var is an Alloc or another -// FreeVar and is considered a potentially escaping heap address, with -// pointer type. -// -// FreeVars are also used to implement bound method closures. Such a -// free var represents the receiver value and may be of any type that -// has concrete methods. -// -// Pos() returns the position of the value that was captured, which -// belongs to an enclosing function. -// -type FreeVar struct { - node - - name string - typ types.Type - parent *Function - referrers []Instruction - - // Transiently needed during building. - outer Value // the Value captured from the enclosing context. -} - -// A Parameter represents an input parameter of a function. -// -type Parameter struct { - register - - name string - object types.Object // a *types.Var; nil for non-source locals -} - -// A Const represents the value of a constant expression. -// -// The underlying type of a constant may be any boolean, numeric, or -// string type. In addition, a Const may represent the nil value of -// any reference type---interface, map, channel, pointer, slice, or -// function---but not "untyped nil". -// -// All source-level constant expressions are represented by a Const -// of the same type and value. -// -// Value holds the exact value of the constant, independent of its -// Type(), using the same representation as package go/constant uses for -// constants, or nil for a typed nil value. -// -// Pos() returns token.NoPos. -// -// Example printed form: -// Const {42} -// Const {"test"} -// Const {(3 + 4i)} -// -type Const struct { - register - - Value constant.Value -} - -// A Global is a named Value holding the address of a package-level -// variable. -// -// Pos() returns the position of the ast.ValueSpec.Names[*] -// identifier. -// -type Global struct { - node - - name string - object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard - typ types.Type - - Pkg *Package -} - -// A Builtin represents a specific use of a built-in function, e.g. len. -// -// Builtins are immutable values. Builtins do not have addresses. -// Builtins can only appear in CallCommon.Func. -// -// Name() indicates the function: one of the built-in functions from the -// Go spec (excluding "make" and "new") or one of these ir-defined -// intrinsics: -// -// // wrapnilchk returns ptr if non-nil, panics otherwise. -// // (For use in indirection wrappers.) -// func ir:wrapnilchk(ptr *T, recvType, methodName string) *T -// -// Object() returns a *types.Builtin for built-ins defined by the spec, -// nil for others. -// -// Type() returns a *types.Signature representing the effective -// signature of the built-in for this call. -// -type Builtin struct { - node - - name string - sig *types.Signature -} - -// Value-defining instructions ---------------------------------------- - -// The Alloc instruction reserves space for a variable of the given type, -// zero-initializes it, and yields its address. -// -// Alloc values are always addresses, and have pointer types, so the -// type of the allocated variable is actually -// Type().Underlying().(*types.Pointer).Elem(). -// -// If Heap is false, Alloc allocates space in the function's -// activation record (frame); we refer to an Alloc(Heap=false) as a -// "stack" alloc. Each stack Alloc returns the same address each time -// it is executed within the same activation; the space is -// re-initialized to zero. -// -// If Heap is true, Alloc allocates space in the heap; we -// refer to an Alloc(Heap=true) as a "heap" alloc. Each heap Alloc -// returns a different address each time it is executed. -// -// When Alloc is applied to a channel, map or slice type, it returns -// the address of an uninitialized (nil) reference of that kind; store -// the result of MakeSlice, MakeMap or MakeChan in that location to -// instantiate these types. -// -// Pos() returns the ast.CompositeLit.Lbrace for a composite literal, -// or the ast.CallExpr.Rparen for a call to new() or for a call that -// allocates a varargs slice. -// -// Example printed form: -// t1 = StackAlloc <*int> -// t2 = HeapAlloc <*int> (new) -// -type Alloc struct { - register - Heap bool - index int // dense numbering; for lifting -} - -var _ Instruction = (*Sigma)(nil) -var _ Value = (*Sigma)(nil) - -// The Sigma instruction represents an SSI σ-node, which splits values -// at branches in the control flow. -// -// Conceptually, σ-nodes exist at the end of blocks that branch and -// constitute parallel assignments to one value per destination block. -// However, such a representation would be awkward to work with, so -// instead we place σ-nodes at the beginning of branch targets. The -// From field denotes to which incoming edge the node applies. -// -// Within a block, all σ-nodes must appear before all non-σ nodes. -// -// Example printed form: -// t2 = Sigma [#0] t1 (x) -// -type Sigma struct { - register - From *BasicBlock - X Value - - live bool // used during lifting -} - -// The Phi instruction represents an SSA φ-node, which combines values -// that differ across incoming control-flow edges and yields a new -// value. Within a block, all φ-nodes must appear before all non-φ, non-σ -// nodes. -// -// Pos() returns the position of the && or || for short-circuit -// control-flow joins, or that of the *Alloc for φ-nodes inserted -// during SSA renaming. -// -// Example printed form: -// t3 = Phi 2:t1 4:t2 (x) -// -type Phi struct { - register - Edges []Value // Edges[i] is value for Block().Preds[i] - - live bool // used during lifting -} - -// The Call instruction represents a function or method call. -// -// The Call instruction yields the function result if there is exactly -// one. Otherwise it returns a tuple, the components of which are -// accessed via Extract. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.CallExpr.Lparen, if explicit in the source. -// -// Example printed form: -// t3 = Call <()> println t1 t2 -// t4 = Call <()> foo$1 -// t6 = Invoke t5.String -// -type Call struct { - register - Call CallCommon -} - -// The BinOp instruction yields the result of binary operation X Op Y. -// -// Pos() returns the ast.BinaryExpr.OpPos, if explicit in the source. -// -// Example printed form: -// t3 = BinOp {+} t2 t1 -// -type BinOp struct { - register - // One of: - // ADD SUB MUL QUO REM + - * / % - // AND OR XOR SHL SHR AND_NOT & | ^ << >> &^ - // EQL NEQ LSS LEQ GTR GEQ == != < <= < >= - Op token.Token - X, Y Value -} - -// The UnOp instruction yields the result of Op X. -// XOR is bitwise complement. -// SUB is negation. -// NOT is logical negation. -// -// -// Example printed form: -// t2 = UnOp {^} t1 -// -type UnOp struct { - register - Op token.Token // One of: NOT SUB XOR ! - ^ - X Value -} - -// The Load instruction loads a value from a memory address. -// -// For implicit memory loads, Pos() returns the position of the -// most closely associated source-level construct; the details are not -// specified. -// -// Example printed form: -// t2 = Load t1 -// -type Load struct { - register - X Value -} - -// The ChangeType instruction applies to X a value-preserving type -// change to Type(). -// -// Type changes are permitted: -// - between a named type and its underlying type. -// - between two named types of the same underlying type. -// - between (possibly named) pointers to identical base types. -// - from a bidirectional channel to a read- or write-channel, -// optionally adding/removing a name. -// -// This operation cannot fail dynamically. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// t2 = ChangeType <*T> t1 -// -type ChangeType struct { - register - X Value -} - -// The Convert instruction yields the conversion of value X to type -// Type(). One or both of those types is basic (but possibly named). -// -// A conversion may change the value and representation of its operand. -// Conversions are permitted: -// - between real numeric types. -// - between complex numeric types. -// - between string and []byte or []rune. -// - between pointers and unsafe.Pointer. -// - between unsafe.Pointer and uintptr. -// - from (Unicode) integer to (UTF-8) string. -// A conversion may imply a type name change also. -// -// This operation cannot fail dynamically. -// -// Conversions of untyped string/number/bool constants to a specific -// representation are eliminated during IR construction. -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// t2 = Convert <[]byte> t1 -// -type Convert struct { - register - X Value -} - -// ChangeInterface constructs a value of one interface type from a -// value of another interface type known to be assignable to it. -// This operation cannot fail. -// -// Pos() returns the ast.CallExpr.Lparen if the instruction arose from -// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the -// instruction arose from an explicit e.(T) operation; or token.NoPos -// otherwise. -// -// Example printed form: -// t2 = ChangeInterface t1 -// -type ChangeInterface struct { - register - X Value -} - -// MakeInterface constructs an instance of an interface type from a -// value of a concrete type. -// -// Use Program.MethodSets.MethodSet(X.Type()) to find the method-set -// of X, and Program.MethodValue(m) to find the implementation of a method. -// -// To construct the zero value of an interface type T, use: -// NewConst(constant.MakeNil(), T, pos) -// -// Pos() returns the ast.CallExpr.Lparen, if the instruction arose -// from an explicit conversion in the source. -// -// Example printed form: -// t2 = MakeInterface t1 -// -type MakeInterface struct { - register - X Value -} - -// The MakeClosure instruction yields a closure value whose code is -// Fn and whose free variables' values are supplied by Bindings. -// -// Type() returns a (possibly named) *types.Signature. -// -// Pos() returns the ast.FuncLit.Type.Func for a function literal -// closure or the ast.SelectorExpr.Sel for a bound method closure. -// -// Example printed form: -// t1 = MakeClosure foo$1 t1 t2 -// t5 = MakeClosure (T).foo$bound t4 -// -type MakeClosure struct { - register - Fn Value // always a *Function - Bindings []Value // values for each free variable in Fn.FreeVars -} - -// The MakeMap instruction creates a new hash-table-based map object -// and yields a value of kind map. -// -// Type() returns a (possibly named) *types.Map. -// -// Pos() returns the ast.CallExpr.Lparen, if created by make(map), or -// the ast.CompositeLit.Lbrack if created by a literal. -// -// Example printed form: -// t1 = MakeMap -// t2 = MakeMap t1 -// -type MakeMap struct { - register - Reserve Value // initial space reservation; nil => default -} - -// The MakeChan instruction creates a new channel object and yields a -// value of kind chan. -// -// Type() returns a (possibly named) *types.Chan. -// -// Pos() returns the ast.CallExpr.Lparen for the make(chan) that -// created it. -// -// Example printed form: -// t3 = MakeChan t1 -// t4 = MakeChan t2 -// -type MakeChan struct { - register - Size Value // int; size of buffer; zero => synchronous. -} - -// The MakeSlice instruction yields a slice of length Len backed by a -// newly allocated array of length Cap. -// -// Both Len and Cap must be non-nil Values of integer type. -// -// (Alloc(types.Array) followed by Slice will not suffice because -// Alloc can only create arrays of constant length.) -// -// Type() returns a (possibly named) *types.Slice. -// -// Pos() returns the ast.CallExpr.Lparen for the make([]T) that -// created it. -// -// Example printed form: -// t3 = MakeSlice <[]string> t1 t2 -// t4 = MakeSlice t1 t2 -// -type MakeSlice struct { - register - Len Value - Cap Value -} - -// The Slice instruction yields a slice of an existing string, slice -// or *array X between optional integer bounds Low and High. -// -// Dynamically, this instruction panics if X evaluates to a nil *array -// pointer. -// -// Type() returns string if the type of X was string, otherwise a -// *types.Slice with the same element type as X. -// -// Pos() returns the ast.SliceExpr.Lbrack if created by a x[:] slice -// operation, the ast.CompositeLit.Lbrace if created by a literal, or -// NoPos if not explicit in the source (e.g. a variadic argument slice). -// -// Example printed form: -// t4 = Slice <[]int> t3 t2 t1 -// -type Slice struct { - register - X Value // slice, string, or *array - Low, High, Max Value // each may be nil -} - -// The FieldAddr instruction yields the address of Field of *struct X. -// -// The field is identified by its index within the field list of the -// struct type of X. -// -// Dynamically, this instruction panics if X evaluates to a nil -// pointer. -// -// Type() returns a (possibly named) *types.Pointer. -// -// Pos() returns the position of the ast.SelectorExpr.Sel for the -// field, if explicit in the source. -// -// Example printed form: -// t2 = FieldAddr <*int> [0] (X) t1 -// -type FieldAddr struct { - register - X Value // *struct - Field int // field is X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct).Field(Field) -} - -// The Field instruction yields the Field of struct X. -// -// The field is identified by its index within the field list of the -// struct type of X; by using numeric indices we avoid ambiguity of -// package-local identifiers and permit compact representations. -// -// Pos() returns the position of the ast.SelectorExpr.Sel for the -// field, if explicit in the source. -// -// Example printed form: -// t2 = FieldAddr [0] (X) t1 -// -type Field struct { - register - X Value // struct - Field int // index into X.Type().(*types.Struct).Fields -} - -// The IndexAddr instruction yields the address of the element at -// index Index of collection X. Index is an integer expression. -// -// The elements of maps and strings are not addressable; use StringLookup, MapLookup or -// MapUpdate instead. -// -// Dynamically, this instruction panics if X evaluates to a nil *array -// pointer. -// -// Type() returns a (possibly named) *types.Pointer. -// -// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if -// explicit in the source. -// -// Example printed form: -// t3 = IndexAddr <*int> t2 t1 -// -type IndexAddr struct { - register - X Value // slice or *array, - Index Value // numeric index -} - -// The Index instruction yields element Index of array X. -// -// Pos() returns the ast.IndexExpr.Lbrack for the index operation, if -// explicit in the source. -// -// Example printed form: -// t3 = Index t2 t1 -// -type Index struct { - register - X Value // array - Index Value // integer index -} - -// The MapLookup instruction yields element Index of collection X, a map. -// -// If CommaOk, the result is a 2-tuple of the value above and a -// boolean indicating the result of a map membership test for the key. -// The components of the tuple are accessed using Extract. -// -// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. -// -// Example printed form: -// t4 = MapLookup t3 t1 -// t6 = MapLookup <(string, bool)> t3 t2 -// -type MapLookup struct { - register - X Value // map - Index Value // key-typed index - CommaOk bool // return a value,ok pair -} - -// The StringLookup instruction yields element Index of collection X, a string. -// Index is an integer expression. -// -// Pos() returns the ast.IndexExpr.Lbrack, if explicit in the source. -// -// Example printed form: -// t3 = StringLookup t2 t1 -// -type StringLookup struct { - register - X Value // string - Index Value // numeric index -} - -// SelectState is a helper for Select. -// It represents one goal state and its corresponding communication. -// -type SelectState struct { - Dir types.ChanDir // direction of case (SendOnly or RecvOnly) - Chan Value // channel to use (for send or receive) - Send Value // value to send (for send) - Pos token.Pos // position of token.ARROW - DebugNode ast.Node // ast.SendStmt or ast.UnaryExpr(<-) [debug mode] -} - -// The Select instruction tests whether (or blocks until) one -// of the specified sent or received states is entered. -// -// Let n be the number of States for which Dir==RECV and Tᵢ (0 ≤ i < n) -// be the element type of each such state's Chan. -// Select returns an n+2-tuple -// (index int, recvOk bool, r₀ T₀, ... rₙ-1 Tₙ-1) -// The tuple's components, described below, must be accessed via the -// Extract instruction. -// -// If Blocking, select waits until exactly one state holds, i.e. a -// channel becomes ready for the designated operation of sending or -// receiving; select chooses one among the ready states -// pseudorandomly, performs the send or receive operation, and sets -// 'index' to the index of the chosen channel. -// -// If !Blocking, select doesn't block if no states hold; instead it -// returns immediately with index equal to -1. -// -// If the chosen channel was used for a receive, the rᵢ component is -// set to the received value, where i is the index of that state among -// all n receive states; otherwise rᵢ has the zero value of type Tᵢ. -// Note that the receive index i is not the same as the state -// index index. -// -// The second component of the triple, recvOk, is a boolean whose value -// is true iff the selected operation was a receive and the receive -// successfully yielded a value. -// -// Pos() returns the ast.SelectStmt.Select. -// -// Example printed form: -// t6 = SelectNonBlocking <(index int, ok bool, int)> [<-t4, t5<-t1] -// t11 = SelectBlocking <(index int, ok bool)> [] -// -type Select struct { - register - States []*SelectState - Blocking bool -} - -// The Range instruction yields an iterator over the domain and range -// of X, which must be a string or map. -// -// Elements are accessed via Next. -// -// Type() returns an opaque and degenerate "rangeIter" type. -// -// Pos() returns the ast.RangeStmt.For. -// -// Example printed form: -// t2 = Range t1 -// -type Range struct { - register - X Value // string or map -} - -// The Next instruction reads and advances the (map or string) -// iterator Iter and returns a 3-tuple value (ok, k, v). If the -// iterator is not exhausted, ok is true and k and v are the next -// elements of the domain and range, respectively. Otherwise ok is -// false and k and v are undefined. -// -// Components of the tuple are accessed using Extract. -// -// The IsString field distinguishes iterators over strings from those -// over maps, as the Type() alone is insufficient: consider -// map[int]rune. -// -// Type() returns a *types.Tuple for the triple (ok, k, v). -// The types of k and/or v may be types.Invalid. -// -// Example printed form: -// t5 = Next <(ok bool, k int, v rune)> t2 -// t5 = Next <(ok bool, k invalid type, v invalid type)> t2 -// -type Next struct { - register - Iter Value - IsString bool // true => string iterator; false => map iterator. -} - -// The TypeAssert instruction tests whether interface value X has type -// AssertedType. -// -// If !CommaOk, on success it returns v, the result of the conversion -// (defined below); on failure it panics. -// -// If CommaOk: on success it returns a pair (v, true) where v is the -// result of the conversion; on failure it returns (z, false) where z -// is AssertedType's zero value. The components of the pair must be -// accessed using the Extract instruction. -// -// If AssertedType is a concrete type, TypeAssert checks whether the -// dynamic type in interface X is equal to it, and if so, the result -// of the conversion is a copy of the value in the interface. -// -// If AssertedType is an interface, TypeAssert checks whether the -// dynamic type of the interface is assignable to it, and if so, the -// result of the conversion is a copy of the interface value X. -// If AssertedType is a superinterface of X.Type(), the operation will -// fail iff the operand is nil. (Contrast with ChangeInterface, which -// performs no nil-check.) -// -// Type() reflects the actual type of the result, possibly a -// 2-types.Tuple; AssertedType is the asserted type. -// -// Pos() returns the ast.CallExpr.Lparen if the instruction arose from -// an explicit T(e) conversion; the ast.TypeAssertExpr.Lparen if the -// instruction arose from an explicit e.(T) operation; or the -// ast.CaseClause.Case if the instruction arose from a case of a -// type-switch statement. -// -// Example printed form: -// t2 = TypeAssert t1 -// t4 = TypeAssert <(value fmt.Stringer, ok bool)> t1 -// -type TypeAssert struct { - register - X Value - AssertedType types.Type - CommaOk bool -} - -// The Extract instruction yields component Index of Tuple. -// -// This is used to access the results of instructions with multiple -// return values, such as Call, TypeAssert, Next, Recv, -// MapLookup and others. -// -// Example printed form: -// t7 = Extract [1] (ok) t4 -// -type Extract struct { - register - Tuple Value - Index int -} - -// Instructions executed for effect. They do not yield a value. -------------------- - -// The Jump instruction transfers control to the sole successor of its -// owning block. -// -// A Jump must be the last instruction of its containing BasicBlock. -// -// Pos() returns NoPos. -// -// Example printed form: -// Jump → b1 -// -type Jump struct { - anInstruction - Comment string -} - -// The Unreachable pseudo-instruction signals that execution cannot -// continue after the preceding function call because it terminates -// the process. -// -// The instruction acts as a control instruction, jumping to the exit -// block. However, this jump will never execute. -// -// An Unreachable instruction must be the last instruction of its -// containing BasicBlock. -// -// Example printed form: -// Unreachable → b1 -// -type Unreachable struct { - anInstruction -} - -// The If instruction transfers control to one of the two successors -// of its owning block, depending on the boolean Cond: the first if -// true, the second if false. -// -// An If instruction must be the last instruction of its containing -// BasicBlock. -// -// Pos() returns the *ast.IfStmt, if explicit in the source. -// -// Example printed form: -// If t2 → b1 b2 -// -type If struct { - anInstruction - Cond Value -} - -type ConstantSwitch struct { - anInstruction - Tag Value - // Constant branch conditions. A nil Value denotes the (implicit - // or explicit) default branch. - Conds []Value -} - -type TypeSwitch struct { - register - Tag Value - Conds []types.Type -} - -// The Return instruction returns values and control back to the calling -// function. -// -// len(Results) is always equal to the number of results in the -// function's signature. -// -// If len(Results) > 1, Return returns a tuple value with the specified -// components which the caller must access using Extract instructions. -// -// There is no instruction to return a ready-made tuple like those -// returned by a "value,ok"-mode TypeAssert, MapLookup or Recv or -// a tail-call to a function with multiple result parameters. -// -// Return must be the last instruction of its containing BasicBlock. -// Such a block has no successors. -// -// Pos() returns the ast.ReturnStmt.Return, if explicit in the source. -// -// Example printed form: -// Return -// Return t1 t2 -// -type Return struct { - anInstruction - Results []Value -} - -// The RunDefers instruction pops and invokes the entire stack of -// procedure calls pushed by Defer instructions in this function. -// -// It is legal to encounter multiple 'rundefers' instructions in a -// single control-flow path through a function; this is useful in -// the combined init() function, for example. -// -// Pos() returns NoPos. -// -// Example printed form: -// RunDefers -// -type RunDefers struct { - anInstruction -} - -// The Panic instruction initiates a panic with value X. -// -// A Panic instruction must be the last instruction of its containing -// BasicBlock, which must have one successor, the exit block. -// -// NB: 'go panic(x)' and 'defer panic(x)' do not use this instruction; -// they are treated as calls to a built-in function. -// -// Pos() returns the ast.CallExpr.Lparen if this panic was explicit -// in the source. -// -// Example printed form: -// Panic t1 -// -type Panic struct { - anInstruction - X Value // an interface{} -} - -// The Go instruction creates a new goroutine and calls the specified -// function within it. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.GoStmt.Go. -// -// Example printed form: -// Go println t1 -// Go t3 -// GoInvoke t4.Bar t2 -// -type Go struct { - anInstruction - Call CallCommon -} - -// The Defer instruction pushes the specified call onto a stack of -// functions to be called by a RunDefers instruction or by a panic. -// -// See CallCommon for generic function call documentation. -// -// Pos() returns the ast.DeferStmt.Defer. -// -// Example printed form: -// Defer println t1 -// Defer t3 -// DeferInvoke t4.Bar t2 -// -type Defer struct { - anInstruction - Call CallCommon -} - -// The Send instruction sends X on channel Chan. -// -// Pos() returns the ast.SendStmt.Arrow, if explicit in the source. -// -// Example printed form: -// Send t2 t1 -// -type Send struct { - anInstruction - Chan, X Value -} - -// The Recv instruction receives from channel Chan. -// -// If CommaOk, the result is a 2-tuple of the value above -// and a boolean indicating the success of the receive. The -// components of the tuple are accessed using Extract. -// -// Pos() returns the ast.UnaryExpr.OpPos, if explicit in the source. -// For receive operations implicit in ranging over a channel, -// Pos() returns the ast.RangeStmt.For. -// -// Example printed form: -// t2 = Recv t1 -// t3 = Recv <(int, bool)> t1 -type Recv struct { - register - Chan Value - CommaOk bool -} - -// The Store instruction stores Val at address Addr. -// Stores can be of arbitrary types. -// -// Pos() returns the position of the source-level construct most closely -// associated with the memory store operation. -// Since implicit memory stores are numerous and varied and depend upon -// implementation choices, the details are not specified. -// -// Example printed form: -// Store {int} t2 t1 -// -type Store struct { - anInstruction - Addr Value - Val Value -} - -// The BlankStore instruction is emitted for assignments to the blank -// identifier. -// -// BlankStore is a pseudo-instruction: it has no dynamic effect. -// -// Pos() returns NoPos. -// -// Example printed form: -// BlankStore t1 -// -type BlankStore struct { - anInstruction - Val Value -} - -// The MapUpdate instruction updates the association of Map[Key] to -// Value. -// -// Pos() returns the ast.KeyValueExpr.Colon or ast.IndexExpr.Lbrack, -// if explicit in the source. -// -// Example printed form: -// MapUpdate t3 t1 t2 -// -type MapUpdate struct { - anInstruction - Map Value - Key Value - Value Value -} - -// A DebugRef instruction maps a source-level expression Expr to the -// IR value X that represents the value (!IsAddr) or address (IsAddr) -// of that expression. -// -// DebugRef is a pseudo-instruction: it has no dynamic effect. -// -// Pos() returns Expr.Pos(), the start position of the source-level -// expression. This is not the same as the "designated" token as -// documented at Value.Pos(). e.g. CallExpr.Pos() does not return the -// position of the ("designated") Lparen token. -// -// DebugRefs are generated only for functions built with debugging -// enabled; see Package.SetDebugMode() and the GlobalDebug builder -// mode flag. -// -// DebugRefs are not emitted for ast.Idents referring to constants or -// predeclared identifiers, since they are trivial and numerous. -// Nor are they emitted for ast.ParenExprs. -// -// (By representing these as instructions, rather than out-of-band, -// consistency is maintained during transformation passes by the -// ordinary SSA renaming machinery.) -// -// Example printed form: -// ; *ast.CallExpr @ 102:9 is t5 -// ; var x float64 @ 109:72 is x -// ; address of *ast.CompositeLit @ 216:10 is t0 -// -type DebugRef struct { - anInstruction - Expr ast.Expr // the referring expression (never *ast.ParenExpr) - object types.Object // the identity of the source var/func - IsAddr bool // Expr is addressable and X is the address it denotes - X Value // the value or address of Expr -} - -// Embeddable mix-ins and helpers for common parts of other structs. ----------- - -// register is a mix-in embedded by all IR values that are also -// instructions, i.e. virtual registers, and provides a uniform -// implementation of most of the Value interface: Value.Name() is a -// numbered register (e.g. "t0"); the other methods are field accessors. -// -// Temporary names are automatically assigned to each register on -// completion of building a function in IR form. -// -type register struct { - anInstruction - typ types.Type // type of virtual register - referrers []Instruction -} - -type node struct { - source ast.Node - id ID -} - -func (n *node) setID(id ID) { n.id = id } -func (n node) ID() ID { return n.id } - -func (n *node) setSource(source ast.Node) { n.source = source } -func (n *node) Source() ast.Node { return n.source } - -func (n *node) Pos() token.Pos { - if n.source != nil { - return n.source.Pos() - } - return token.NoPos -} - -// anInstruction is a mix-in embedded by all Instructions. -// It provides the implementations of the Block and setBlock methods. -type anInstruction struct { - node - block *BasicBlock // the basic block of this instruction -} - -// CallCommon is contained by Go, Defer and Call to hold the -// common parts of a function or method call. -// -// Each CallCommon exists in one of two modes, function call and -// interface method invocation, or "call" and "invoke" for short. -// -// 1. "call" mode: when Method is nil (!IsInvoke), a CallCommon -// represents an ordinary function call of the value in Value, -// which may be a *Builtin, a *Function or any other value of kind -// 'func'. -// -// Value may be one of: -// (a) a *Function, indicating a statically dispatched call -// to a package-level function, an anonymous function, or -// a method of a named type. -// (b) a *MakeClosure, indicating an immediately applied -// function literal with free variables. -// (c) a *Builtin, indicating a statically dispatched call -// to a built-in function. -// (d) any other value, indicating a dynamically dispatched -// function call. -// StaticCallee returns the identity of the callee in cases -// (a) and (b), nil otherwise. -// -// Args contains the arguments to the call. If Value is a method, -// Args[0] contains the receiver parameter. -// -// Example printed form: -// t3 = Call <()> println t1 t2 -// Go t3 -// Defer t3 -// -// 2. "invoke" mode: when Method is non-nil (IsInvoke), a CallCommon -// represents a dynamically dispatched call to an interface method. -// In this mode, Value is the interface value and Method is the -// interface's abstract method. Note: an abstract method may be -// shared by multiple interfaces due to embedding; Value.Type() -// provides the specific interface used for this call. -// -// Value is implicitly supplied to the concrete method implementation -// as the receiver parameter; in other words, Args[0] holds not the -// receiver but the first true argument. -// -// Example printed form: -// t6 = Invoke t5.String -// GoInvoke t4.Bar t2 -// DeferInvoke t4.Bar t2 -// -// For all calls to variadic functions (Signature().Variadic()), -// the last element of Args is a slice. -// -type CallCommon struct { - Value Value // receiver (invoke mode) or func value (call mode) - Method *types.Func // abstract method (invoke mode) - Args []Value // actual parameters (in static method call, includes receiver) - Results Value -} - -// IsInvoke returns true if this call has "invoke" (not "call") mode. -func (c *CallCommon) IsInvoke() bool { - return c.Method != nil -} - -// Signature returns the signature of the called function. -// -// For an "invoke"-mode call, the signature of the interface method is -// returned. -// -// In either "call" or "invoke" mode, if the callee is a method, its -// receiver is represented by sig.Recv, not sig.Params().At(0). -// -func (c *CallCommon) Signature() *types.Signature { - if c.Method != nil { - return c.Method.Type().(*types.Signature) - } - return c.Value.Type().Underlying().(*types.Signature) -} - -// StaticCallee returns the callee if this is a trivially static -// "call"-mode call to a function. -func (c *CallCommon) StaticCallee() *Function { - switch fn := c.Value.(type) { - case *Function: - return fn - case *MakeClosure: - return fn.Fn.(*Function) - } - return nil -} - -// Description returns a description of the mode of this call suitable -// for a user interface, e.g., "static method call". -func (c *CallCommon) Description() string { - switch fn := c.Value.(type) { - case *Builtin: - return "built-in function call" - case *MakeClosure: - return "static function closure call" - case *Function: - if fn.Signature.Recv() != nil { - return "static method call" - } - return "static function call" - } - if c.IsInvoke() { - return "dynamic method call" // ("invoke" mode) - } - return "dynamic function call" -} - -// The CallInstruction interface, implemented by *Go, *Defer and *Call, -// exposes the common parts of function-calling instructions, -// yet provides a way back to the Value defined by *Call alone. -// -type CallInstruction interface { - Instruction - Common() *CallCommon // returns the common parts of the call - Value() *Call -} - -func (s *Call) Common() *CallCommon { return &s.Call } -func (s *Defer) Common() *CallCommon { return &s.Call } -func (s *Go) Common() *CallCommon { return &s.Call } - -func (s *Call) Value() *Call { return s } -func (s *Defer) Value() *Call { return nil } -func (s *Go) Value() *Call { return nil } - -func (v *Builtin) Type() types.Type { return v.sig } -func (v *Builtin) Name() string { return v.name } -func (*Builtin) Referrers() *[]Instruction { return nil } -func (v *Builtin) Pos() token.Pos { return token.NoPos } -func (v *Builtin) Object() types.Object { return types.Universe.Lookup(v.name) } -func (v *Builtin) Parent() *Function { return nil } - -func (v *FreeVar) Type() types.Type { return v.typ } -func (v *FreeVar) Name() string { return v.name } -func (v *FreeVar) Referrers() *[]Instruction { return &v.referrers } -func (v *FreeVar) Parent() *Function { return v.parent } - -func (v *Global) Type() types.Type { return v.typ } -func (v *Global) Name() string { return v.name } -func (v *Global) Parent() *Function { return nil } -func (v *Global) Referrers() *[]Instruction { return nil } -func (v *Global) Token() token.Token { return token.VAR } -func (v *Global) Object() types.Object { return v.object } -func (v *Global) String() string { return v.RelString(nil) } -func (v *Global) Package() *Package { return v.Pkg } -func (v *Global) RelString(from *types.Package) string { return relString(v, from) } - -func (v *Function) Name() string { return v.name } -func (v *Function) Type() types.Type { return v.Signature } -func (v *Function) Token() token.Token { return token.FUNC } -func (v *Function) Object() types.Object { return v.object } -func (v *Function) String() string { return v.RelString(nil) } -func (v *Function) Package() *Package { return v.Pkg } -func (v *Function) Parent() *Function { return v.parent } -func (v *Function) Referrers() *[]Instruction { - if v.parent != nil { - return &v.referrers - } - return nil -} - -func (v *Parameter) Object() types.Object { return v.object } - -func (v *Alloc) Type() types.Type { return v.typ } -func (v *Alloc) Referrers() *[]Instruction { return &v.referrers } - -func (v *register) Type() types.Type { return v.typ } -func (v *register) setType(typ types.Type) { v.typ = typ } -func (v *register) Name() string { return fmt.Sprintf("t%d", v.id) } -func (v *register) Referrers() *[]Instruction { return &v.referrers } - -func (v *anInstruction) Parent() *Function { return v.block.parent } -func (v *anInstruction) Block() *BasicBlock { return v.block } -func (v *anInstruction) setBlock(block *BasicBlock) { v.block = block } -func (v *anInstruction) Referrers() *[]Instruction { return nil } - -func (t *Type) Name() string { return t.object.Name() } -func (t *Type) Pos() token.Pos { return t.object.Pos() } -func (t *Type) Type() types.Type { return t.object.Type() } -func (t *Type) Token() token.Token { return token.TYPE } -func (t *Type) Object() types.Object { return t.object } -func (t *Type) String() string { return t.RelString(nil) } -func (t *Type) Package() *Package { return t.pkg } -func (t *Type) RelString(from *types.Package) string { return relString(t, from) } - -func (c *NamedConst) Name() string { return c.object.Name() } -func (c *NamedConst) Pos() token.Pos { return c.object.Pos() } -func (c *NamedConst) String() string { return c.RelString(nil) } -func (c *NamedConst) Type() types.Type { return c.object.Type() } -func (c *NamedConst) Token() token.Token { return token.CONST } -func (c *NamedConst) Object() types.Object { return c.object } -func (c *NamedConst) Package() *Package { return c.pkg } -func (c *NamedConst) RelString(from *types.Package) string { return relString(c, from) } - -// Func returns the package-level function of the specified name, -// or nil if not found. -// -func (p *Package) Func(name string) (f *Function) { - f, _ = p.Members[name].(*Function) - return -} - -// Var returns the package-level variable of the specified name, -// or nil if not found. -// -func (p *Package) Var(name string) (g *Global) { - g, _ = p.Members[name].(*Global) - return -} - -// Const returns the package-level constant of the specified name, -// or nil if not found. -// -func (p *Package) Const(name string) (c *NamedConst) { - c, _ = p.Members[name].(*NamedConst) - return -} - -// Type returns the package-level type of the specified name, -// or nil if not found. -// -func (p *Package) Type(name string) (t *Type) { - t, _ = p.Members[name].(*Type) - return -} - -func (s *DebugRef) Pos() token.Pos { return s.Expr.Pos() } - -// Operands. - -func (v *Alloc) Operands(rands []*Value) []*Value { - return rands -} - -func (v *BinOp) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Y) -} - -func (c *CallCommon) Operands(rands []*Value) []*Value { - rands = append(rands, &c.Value) - for i := range c.Args { - rands = append(rands, &c.Args[i]) - } - return rands -} - -func (s *Go) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (s *Call) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (s *Defer) Operands(rands []*Value) []*Value { - return s.Call.Operands(rands) -} - -func (v *ChangeInterface) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *ChangeType) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Convert) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *DebugRef) Operands(rands []*Value) []*Value { - return append(rands, &s.X) -} - -func (v *Extract) Operands(rands []*Value) []*Value { - return append(rands, &v.Tuple) -} - -func (v *Field) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *FieldAddr) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *If) Operands(rands []*Value) []*Value { - return append(rands, &s.Cond) -} - -func (s *ConstantSwitch) Operands(rands []*Value) []*Value { - rands = append(rands, &s.Tag) - for i := range s.Conds { - rands = append(rands, &s.Conds[i]) - } - return rands -} - -func (s *TypeSwitch) Operands(rands []*Value) []*Value { - rands = append(rands, &s.Tag) - return rands -} - -func (v *Index) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *IndexAddr) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (*Jump) Operands(rands []*Value) []*Value { - return rands -} - -func (*Unreachable) Operands(rands []*Value) []*Value { - return rands -} - -func (v *MapLookup) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *StringLookup) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Index) -} - -func (v *MakeChan) Operands(rands []*Value) []*Value { - return append(rands, &v.Size) -} - -func (v *MakeClosure) Operands(rands []*Value) []*Value { - rands = append(rands, &v.Fn) - for i := range v.Bindings { - rands = append(rands, &v.Bindings[i]) - } - return rands -} - -func (v *MakeInterface) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *MakeMap) Operands(rands []*Value) []*Value { - return append(rands, &v.Reserve) -} - -func (v *MakeSlice) Operands(rands []*Value) []*Value { - return append(rands, &v.Len, &v.Cap) -} - -func (v *MapUpdate) Operands(rands []*Value) []*Value { - return append(rands, &v.Map, &v.Key, &v.Value) -} - -func (v *Next) Operands(rands []*Value) []*Value { - return append(rands, &v.Iter) -} - -func (s *Panic) Operands(rands []*Value) []*Value { - return append(rands, &s.X) -} - -func (v *Sigma) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Phi) Operands(rands []*Value) []*Value { - for i := range v.Edges { - rands = append(rands, &v.Edges[i]) - } - return rands -} - -func (v *Range) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (s *Return) Operands(rands []*Value) []*Value { - for i := range s.Results { - rands = append(rands, &s.Results[i]) - } - return rands -} - -func (*RunDefers) Operands(rands []*Value) []*Value { - return rands -} - -func (v *Select) Operands(rands []*Value) []*Value { - for i := range v.States { - rands = append(rands, &v.States[i].Chan, &v.States[i].Send) - } - return rands -} - -func (s *Send) Operands(rands []*Value) []*Value { - return append(rands, &s.Chan, &s.X) -} - -func (recv *Recv) Operands(rands []*Value) []*Value { - return append(rands, &recv.Chan) -} - -func (v *Slice) Operands(rands []*Value) []*Value { - return append(rands, &v.X, &v.Low, &v.High, &v.Max) -} - -func (s *Store) Operands(rands []*Value) []*Value { - return append(rands, &s.Addr, &s.Val) -} - -func (s *BlankStore) Operands(rands []*Value) []*Value { - return append(rands, &s.Val) -} - -func (v *TypeAssert) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *UnOp) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -func (v *Load) Operands(rands []*Value) []*Value { - return append(rands, &v.X) -} - -// Non-Instruction Values: -func (v *Builtin) Operands(rands []*Value) []*Value { return rands } -func (v *FreeVar) Operands(rands []*Value) []*Value { return rands } -func (v *Const) Operands(rands []*Value) []*Value { return rands } -func (v *Function) Operands(rands []*Value) []*Value { return rands } -func (v *Global) Operands(rands []*Value) []*Value { return rands } -func (v *Parameter) Operands(rands []*Value) []*Value { return rands } diff --git a/vendor/honnef.co/go/tools/ir/staticcheck.conf b/vendor/honnef.co/go/tools/ir/staticcheck.conf deleted file mode 100644 index d7b38bc35..000000000 --- a/vendor/honnef.co/go/tools/ir/staticcheck.conf +++ /dev/null @@ -1,3 +0,0 @@ -# ssa/... is mostly imported from upstream and we don't want to -# deviate from it too much, hence disabling SA1019 -checks = ["inherit", "-SA1019"] diff --git a/vendor/honnef.co/go/tools/ir/util.go b/vendor/honnef.co/go/tools/ir/util.go deleted file mode 100644 index df0f8bf97..000000000 --- a/vendor/honnef.co/go/tools/ir/util.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines a number of miscellaneous utility functions. - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "io" - "os" - - "golang.org/x/tools/go/ast/astutil" -) - -//// AST utilities - -func unparen(e ast.Expr) ast.Expr { return astutil.Unparen(e) } - -// isBlankIdent returns true iff e is an Ident with name "_". -// They have no associated types.Object, and thus no type. -// -func isBlankIdent(e ast.Expr) bool { - id, ok := e.(*ast.Ident) - return ok && id.Name == "_" -} - -//// Type utilities. Some of these belong in go/types. - -// isPointer returns true for types whose underlying type is a pointer. -func isPointer(typ types.Type) bool { - _, ok := typ.Underlying().(*types.Pointer) - return ok -} - -func isInterface(T types.Type) bool { return types.IsInterface(T) } - -// deref returns a pointer's element type; otherwise it returns typ. -func deref(typ types.Type) types.Type { - if p, ok := typ.Underlying().(*types.Pointer); ok { - return p.Elem() - } - return typ -} - -// recvType returns the receiver type of method obj. -func recvType(obj *types.Func) types.Type { - return obj.Type().(*types.Signature).Recv().Type() -} - -// logStack prints the formatted "start" message to stderr and -// returns a closure that prints the corresponding "end" message. -// Call using 'defer logStack(...)()' to show builder stack on panic. -// Don't forget trailing parens! -// -func logStack(format string, args ...interface{}) func() { - msg := fmt.Sprintf(format, args...) - io.WriteString(os.Stderr, msg) - io.WriteString(os.Stderr, "\n") - return func() { - io.WriteString(os.Stderr, msg) - io.WriteString(os.Stderr, " end\n") - } -} - -// newVar creates a 'var' for use in a types.Tuple. -func newVar(name string, typ types.Type) *types.Var { - return types.NewParam(token.NoPos, nil, name, typ) -} - -// anonVar creates an anonymous 'var' for use in a types.Tuple. -func anonVar(typ types.Type) *types.Var { - return newVar("", typ) -} - -var lenResults = types.NewTuple(anonVar(tInt)) - -// makeLen returns the len builtin specialized to type func(T)int. -func makeLen(T types.Type) *Builtin { - lenParams := types.NewTuple(anonVar(T)) - return &Builtin{ - name: "len", - sig: types.NewSignature(nil, lenParams, lenResults, false), - } -} diff --git a/vendor/honnef.co/go/tools/ir/wrappers.go b/vendor/honnef.co/go/tools/ir/wrappers.go deleted file mode 100644 index 7dd334748..000000000 --- a/vendor/honnef.co/go/tools/ir/wrappers.go +++ /dev/null @@ -1,292 +0,0 @@ -// Copyright 2013 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package ir - -// This file defines synthesis of Functions that delegate to declared -// methods; they come in three kinds: -// -// (1) wrappers: methods that wrap declared methods, performing -// implicit pointer indirections and embedded field selections. -// -// (2) thunks: funcs that wrap declared methods. Like wrappers, -// thunks perform indirections and field selections. The thunk's -// first parameter is used as the receiver for the method call. -// -// (3) bounds: funcs that wrap declared methods. The bound's sole -// free variable, supplied by a closure, is used as the receiver -// for the method call. No indirections or field selections are -// performed since they can be done before the call. - -import ( - "fmt" - - "go/types" -) - -// -- wrappers ----------------------------------------------------------- - -// makeWrapper returns a synthetic method that delegates to the -// declared method denoted by meth.Obj(), first performing any -// necessary pointer indirections or field selections implied by meth. -// -// The resulting method's receiver type is meth.Recv(). -// -// This function is versatile but quite subtle! Consider the -// following axes of variation when making changes: -// - optional receiver indirection -// - optional implicit field selections -// - meth.Obj() may denote a concrete or an interface method -// - the result may be a thunk or a wrapper. -// -// EXCLUSIVE_LOCKS_REQUIRED(prog.methodsMu) -// -func makeWrapper(prog *Program, sel *types.Selection) *Function { - obj := sel.Obj().(*types.Func) // the declared function - sig := sel.Type().(*types.Signature) // type of this wrapper - - var recv *types.Var // wrapper's receiver or thunk's params[0] - name := obj.Name() - var description string - var start int // first regular param - if sel.Kind() == types.MethodExpr { - name += "$thunk" - description = "thunk" - recv = sig.Params().At(0) - start = 1 - } else { - description = "wrapper" - recv = sig.Recv() - } - - description = fmt.Sprintf("%s for %s", description, sel.Obj()) - if prog.mode&LogSource != 0 { - defer logStack("make %s to (%s)", description, recv.Type())() - } - fn := &Function{ - name: name, - method: sel, - object: obj, - Signature: sig, - Synthetic: description, - Prog: prog, - functionBody: new(functionBody), - } - fn.initHTML(prog.PrintFunc) - fn.startBody() - fn.addSpilledParam(recv, nil) - createParams(fn, start) - - indices := sel.Index() - - var v Value = fn.Locals[0] // spilled receiver - if isPointer(sel.Recv()) { - v = emitLoad(fn, v, nil) - - // For simple indirection wrappers, perform an informative nil-check: - // "value method (T).f called using nil *T pointer" - if len(indices) == 1 && !isPointer(recvType(obj)) { - var c Call - c.Call.Value = &Builtin{ - name: "ir:wrapnilchk", - sig: types.NewSignature(nil, - types.NewTuple(anonVar(sel.Recv()), anonVar(tString), anonVar(tString)), - types.NewTuple(anonVar(sel.Recv())), false), - } - c.Call.Args = []Value{ - v, - emitConst(fn, stringConst(deref(sel.Recv()).String())), - emitConst(fn, stringConst(sel.Obj().Name())), - } - c.setType(v.Type()) - v = fn.emit(&c, nil) - } - } - - // Invariant: v is a pointer, either - // value of *A receiver param, or - // address of A spilled receiver. - - // We use pointer arithmetic (FieldAddr possibly followed by - // Load) in preference to value extraction (Field possibly - // preceded by Load). - - v = emitImplicitSelections(fn, v, indices[:len(indices)-1], nil) - - // Invariant: v is a pointer, either - // value of implicit *C field, or - // address of implicit C field. - - var c Call - if r := recvType(obj); !isInterface(r) { // concrete method - if !isPointer(r) { - v = emitLoad(fn, v, nil) - } - c.Call.Value = prog.declaredFunc(obj) - c.Call.Args = append(c.Call.Args, v) - } else { - c.Call.Method = obj - c.Call.Value = emitLoad(fn, v, nil) - } - for _, arg := range fn.Params[1:] { - c.Call.Args = append(c.Call.Args, arg) - } - emitTailCall(fn, &c, nil) - fn.finishBody() - return fn -} - -// createParams creates parameters for wrapper method fn based on its -// Signature.Params, which do not include the receiver. -// start is the index of the first regular parameter to use. -// -func createParams(fn *Function, start int) { - tparams := fn.Signature.Params() - for i, n := start, tparams.Len(); i < n; i++ { - fn.addParamObj(tparams.At(i), nil) - } -} - -// -- bounds ----------------------------------------------------------- - -// makeBound returns a bound method wrapper (or "bound"), a synthetic -// function that delegates to a concrete or interface method denoted -// by obj. The resulting function has no receiver, but has one free -// variable which will be used as the method's receiver in the -// tail-call. -// -// Use MakeClosure with such a wrapper to construct a bound method -// closure. e.g.: -// -// type T int or: type T interface { meth() } -// func (t T) meth() -// var t T -// f := t.meth -// f() // calls t.meth() -// -// f is a closure of a synthetic wrapper defined as if by: -// -// f := func() { return t.meth() } -// -// Unlike makeWrapper, makeBound need perform no indirection or field -// selections because that can be done before the closure is -// constructed. -// -// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu) -// -func makeBound(prog *Program, obj *types.Func) *Function { - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - fn, ok := prog.bounds[obj] - if !ok { - description := fmt.Sprintf("bound method wrapper for %s", obj) - if prog.mode&LogSource != 0 { - defer logStack("%s", description)() - } - fn = &Function{ - name: obj.Name() + "$bound", - object: obj, - Signature: changeRecv(obj.Type().(*types.Signature), nil), // drop receiver - Synthetic: description, - Prog: prog, - functionBody: new(functionBody), - } - fn.initHTML(prog.PrintFunc) - - fv := &FreeVar{name: "recv", typ: recvType(obj), parent: fn} - fn.FreeVars = []*FreeVar{fv} - fn.startBody() - createParams(fn, 0) - var c Call - - if !isInterface(recvType(obj)) { // concrete - c.Call.Value = prog.declaredFunc(obj) - c.Call.Args = []Value{fv} - } else { - c.Call.Value = fv - c.Call.Method = obj - } - for _, arg := range fn.Params { - c.Call.Args = append(c.Call.Args, arg) - } - emitTailCall(fn, &c, nil) - fn.finishBody() - - prog.bounds[obj] = fn - } - return fn -} - -// -- thunks ----------------------------------------------------------- - -// makeThunk returns a thunk, a synthetic function that delegates to a -// concrete or interface method denoted by sel.Obj(). The resulting -// function has no receiver, but has an additional (first) regular -// parameter. -// -// Precondition: sel.Kind() == types.MethodExpr. -// -// type T int or: type T interface { meth() } -// func (t T) meth() -// f := T.meth -// var t T -// f(t) // calls t.meth() -// -// f is a synthetic wrapper defined as if by: -// -// f := func(t T) { return t.meth() } -// -// TODO(adonovan): opt: currently the stub is created even when used -// directly in a function call: C.f(i, 0). This is less efficient -// than inlining the stub. -// -// EXCLUSIVE_LOCKS_ACQUIRED(meth.Prog.methodsMu) -// -func makeThunk(prog *Program, sel *types.Selection) *Function { - if sel.Kind() != types.MethodExpr { - panic(sel) - } - - key := selectionKey{ - kind: sel.Kind(), - recv: sel.Recv(), - obj: sel.Obj(), - index: fmt.Sprint(sel.Index()), - indirect: sel.Indirect(), - } - - prog.methodsMu.Lock() - defer prog.methodsMu.Unlock() - - // Canonicalize key.recv to avoid constructing duplicate thunks. - canonRecv, ok := prog.canon.At(key.recv).(types.Type) - if !ok { - canonRecv = key.recv - prog.canon.Set(key.recv, canonRecv) - } - key.recv = canonRecv - - fn, ok := prog.thunks[key] - if !ok { - fn = makeWrapper(prog, sel) - if fn.Signature.Recv() != nil { - panic(fn) // unexpected receiver - } - prog.thunks[key] = fn - } - return fn -} - -func changeRecv(s *types.Signature, recv *types.Var) *types.Signature { - return types.NewSignature(recv, s.Params(), s.Results(), s.Variadic()) -} - -// selectionKey is like types.Selection but a usable map key. -type selectionKey struct { - kind types.SelectionKind - recv types.Type // canonicalized via Program.canon - obj types.Object - index string - indirect bool -} diff --git a/vendor/honnef.co/go/tools/ir/write.go b/vendor/honnef.co/go/tools/ir/write.go deleted file mode 100644 index b936bc985..000000000 --- a/vendor/honnef.co/go/tools/ir/write.go +++ /dev/null @@ -1,5 +0,0 @@ -package ir - -func NewJump(parent *BasicBlock) *Jump { - return &Jump{anInstruction{block: parent}, ""} -} diff --git a/vendor/honnef.co/go/tools/lint/LICENSE b/vendor/honnef.co/go/tools/lint/LICENSE deleted file mode 100644 index 796130a12..000000000 --- a/vendor/honnef.co/go/tools/lint/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Copyright (c) 2013 The Go Authors. All rights reserved. -Copyright (c) 2016 Dominik Honnef. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/honnef.co/go/tools/lint/lint.go b/vendor/honnef.co/go/tools/lint/lint.go deleted file mode 100644 index 1a70e0c29..000000000 --- a/vendor/honnef.co/go/tools/lint/lint.go +++ /dev/null @@ -1,539 +0,0 @@ -// Package lint provides the foundation for tools like staticcheck -package lint // import "honnef.co/go/tools/lint" - -import ( - "bytes" - "encoding/gob" - "fmt" - "go/scanner" - "go/token" - "go/types" - "path/filepath" - "sort" - "strings" - "sync" - "sync/atomic" - "unicode" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - "honnef.co/go/tools/config" - "honnef.co/go/tools/internal/cache" -) - -type Documentation struct { - Title string - Text string - Since string - NonDefault bool - Options []string -} - -func (doc *Documentation) String() string { - b := &strings.Builder{} - fmt.Fprintf(b, "%s\n\n", doc.Title) - if doc.Text != "" { - fmt.Fprintf(b, "%s\n\n", doc.Text) - } - fmt.Fprint(b, "Available since\n ") - if doc.Since == "" { - fmt.Fprint(b, "unreleased") - } else { - fmt.Fprintf(b, "%s", doc.Since) - } - if doc.NonDefault { - fmt.Fprint(b, ", non-default") - } - fmt.Fprint(b, "\n") - if len(doc.Options) > 0 { - fmt.Fprintf(b, "\nOptions\n") - for _, opt := range doc.Options { - fmt.Fprintf(b, " %s", opt) - } - fmt.Fprint(b, "\n") - } - return b.String() -} - -type Ignore interface { - Match(p Problem) bool -} - -type LineIgnore struct { - File string - Line int - Checks []string - Matched bool - Pos token.Position -} - -func (li *LineIgnore) Match(p Problem) bool { - pos := p.Pos - if pos.Filename != li.File || pos.Line != li.Line { - return false - } - for _, c := range li.Checks { - if m, _ := filepath.Match(c, p.Check); m { - li.Matched = true - return true - } - } - return false -} - -func (li *LineIgnore) String() string { - matched := "not matched" - if li.Matched { - matched = "matched" - } - return fmt.Sprintf("%s:%d %s (%s)", li.File, li.Line, strings.Join(li.Checks, ", "), matched) -} - -type FileIgnore struct { - File string - Checks []string -} - -func (fi *FileIgnore) Match(p Problem) bool { - if p.Pos.Filename != fi.File { - return false - } - for _, c := range fi.Checks { - if m, _ := filepath.Match(c, p.Check); m { - return true - } - } - return false -} - -type Severity uint8 - -const ( - Error Severity = iota - Warning - Ignored -) - -// Problem represents a problem in some source code. -type Problem struct { - Pos token.Position - End token.Position - Message string - Check string - Severity Severity - Related []Related -} - -type Related struct { - Pos token.Position - End token.Position - Message string -} - -func (p Problem) Equal(o Problem) bool { - return p.Pos == o.Pos && - p.End == o.End && - p.Message == o.Message && - p.Check == o.Check && - p.Severity == o.Severity -} - -func (p *Problem) String() string { - return fmt.Sprintf("%s (%s)", p.Message, p.Check) -} - -// A Linter lints Go source code. -type Linter struct { - Checkers []*analysis.Analyzer - CumulativeCheckers []CumulativeChecker - GoVersion int - Config config.Config - Stats Stats - RepeatAnalyzers uint -} - -type CumulativeChecker interface { - Analyzer() *analysis.Analyzer - Result() []types.Object - ProblemObject(*token.FileSet, types.Object) Problem -} - -func (l *Linter) Lint(cfg *packages.Config, patterns []string) ([]Problem, error) { - var allAnalyzers []*analysis.Analyzer - allAnalyzers = append(allAnalyzers, l.Checkers...) - for _, cum := range l.CumulativeCheckers { - allAnalyzers = append(allAnalyzers, cum.Analyzer()) - } - - // The -checks command line flag overrules all configuration - // files, which means that for `-checks="foo"`, no check other - // than foo can ever be reported to the user. Make use of this - // fact to cull the list of analyses we need to run. - - // replace "inherit" with "all", as we don't want to base the - // list of all checks on the default configuration, which - // disables certain checks. - checks := make([]string, len(l.Config.Checks)) - copy(checks, l.Config.Checks) - for i, c := range checks { - if c == "inherit" { - checks[i] = "all" - } - } - - allowed := FilterChecks(allAnalyzers, checks) - var allowedAnalyzers []*analysis.Analyzer - for _, c := range l.Checkers { - if allowed[c.Name] { - allowedAnalyzers = append(allowedAnalyzers, c) - } - } - hasCumulative := false - for _, cum := range l.CumulativeCheckers { - a := cum.Analyzer() - if allowed[a.Name] { - hasCumulative = true - allowedAnalyzers = append(allowedAnalyzers, a) - } - } - - r, err := NewRunner(&l.Stats) - if err != nil { - return nil, err - } - r.goVersion = l.GoVersion - r.repeatAnalyzers = l.RepeatAnalyzers - - pkgs, err := r.Run(cfg, patterns, allowedAnalyzers, hasCumulative) - if err != nil { - return nil, err - } - - tpkgToPkg := map[*types.Package]*Package{} - for _, pkg := range pkgs { - tpkgToPkg[pkg.Types] = pkg - - for _, e := range pkg.errs { - switch e := e.(type) { - case types.Error: - p := Problem{ - Pos: e.Fset.PositionFor(e.Pos, false), - Message: e.Msg, - Severity: Error, - Check: "compile", - } - pkg.problems = append(pkg.problems, p) - case packages.Error: - msg := e.Msg - if len(msg) != 0 && msg[0] == '\n' { - // TODO(dh): See https://github.com/golang/go/issues/32363 - msg = msg[1:] - } - - var pos token.Position - if e.Pos == "" { - // Under certain conditions (malformed package - // declarations, multiple packages in the same - // directory), go list emits an error on stderr - // instead of JSON. Those errors do not have - // associated position information in - // go/packages.Error, even though the output on - // stderr may contain it. - if p, n, err := parsePos(msg); err == nil { - if abs, err := filepath.Abs(p.Filename); err == nil { - p.Filename = abs - } - pos = p - msg = msg[n+2:] - } - } else { - var err error - pos, _, err = parsePos(e.Pos) - if err != nil { - panic(fmt.Sprintf("internal error: %s", e)) - } - } - p := Problem{ - Pos: pos, - Message: msg, - Severity: Error, - Check: "compile", - } - pkg.problems = append(pkg.problems, p) - case scanner.ErrorList: - for _, e := range e { - p := Problem{ - Pos: e.Pos, - Message: e.Msg, - Severity: Error, - Check: "compile", - } - pkg.problems = append(pkg.problems, p) - } - case error: - p := Problem{ - Pos: token.Position{}, - Message: e.Error(), - Severity: Error, - Check: "compile", - } - pkg.problems = append(pkg.problems, p) - } - } - } - - atomic.StoreUint32(&r.stats.State, StateCumulative) - for _, cum := range l.CumulativeCheckers { - for _, res := range cum.Result() { - pkg := tpkgToPkg[res.Pkg()] - if pkg == nil { - panic(fmt.Sprintf("analyzer %s flagged object %s in package %s, a package that we aren't tracking", cum.Analyzer(), res, res.Pkg())) - } - allowedChecks := FilterChecks(allowedAnalyzers, pkg.cfg.Merge(l.Config).Checks) - if allowedChecks[cum.Analyzer().Name] { - pos := DisplayPosition(pkg.Fset, res.Pos()) - // FIXME(dh): why are we ignoring generated files - // here? Surely this is specific to 'unused', not all - // cumulative checkers - if _, ok := pkg.gen[pos.Filename]; ok { - continue - } - p := cum.ProblemObject(pkg.Fset, res) - pkg.problems = append(pkg.problems, p) - } - } - } - - for _, pkg := range pkgs { - if !pkg.fromSource { - // Don't cache packages that we loaded from the cache - continue - } - cpkg := cachedPackage{ - Problems: pkg.problems, - Ignores: pkg.ignores, - Config: pkg.cfg, - } - buf := &bytes.Buffer{} - if err := gob.NewEncoder(buf).Encode(cpkg); err != nil { - return nil, err - } - id := cache.Subkey(pkg.actionID, "data "+r.problemsCacheKey) - if err := r.cache.PutBytes(id, buf.Bytes()); err != nil { - return nil, err - } - } - - var problems []Problem - // Deduplicate line ignores. When U1000 processes a package and - // its test variant, it will only emit a single problem for an - // unused object, not two problems. We will, however, have two - // line ignores, one per package. Without deduplication, one line - // ignore will be marked as matched, while the other one won't, - // subsequently reporting a "this linter directive didn't match - // anything" error. - ignores := map[token.Position]Ignore{} - for _, pkg := range pkgs { - for _, ig := range pkg.ignores { - if lig, ok := ig.(*LineIgnore); ok { - ig = ignores[lig.Pos] - if ig == nil { - ignores[lig.Pos] = lig - ig = lig - } - } - for i := range pkg.problems { - p := &pkg.problems[i] - if ig.Match(*p) { - p.Severity = Ignored - } - } - } - - if pkg.cfg == nil { - // The package failed to load, otherwise we would have a - // valid config. Pass through all errors. - problems = append(problems, pkg.problems...) - } else { - for _, p := range pkg.problems { - allowedChecks := FilterChecks(allowedAnalyzers, pkg.cfg.Merge(l.Config).Checks) - allowedChecks["compile"] = true - if allowedChecks[p.Check] { - problems = append(problems, p) - } - } - } - - for _, ig := range pkg.ignores { - ig, ok := ig.(*LineIgnore) - if !ok { - continue - } - ig = ignores[ig.Pos].(*LineIgnore) - if ig.Matched { - continue - } - - couldveMatched := false - allowedChecks := FilterChecks(allowedAnalyzers, pkg.cfg.Merge(l.Config).Checks) - for _, c := range ig.Checks { - if !allowedChecks[c] { - continue - } - couldveMatched = true - break - } - - if !couldveMatched { - // The ignored checks were disabled for the containing package. - // Don't flag the ignore for not having matched. - continue - } - p := Problem{ - Pos: ig.Pos, - Message: "this linter directive didn't match anything; should it be removed?", - Check: "", - } - problems = append(problems, p) - } - } - - if len(problems) == 0 { - return nil, nil - } - - sort.Slice(problems, func(i, j int) bool { - pi := problems[i].Pos - pj := problems[j].Pos - - if pi.Filename != pj.Filename { - return pi.Filename < pj.Filename - } - if pi.Line != pj.Line { - return pi.Line < pj.Line - } - if pi.Column != pj.Column { - return pi.Column < pj.Column - } - - return problems[i].Message < problems[j].Message - }) - - var out []Problem - out = append(out, problems[0]) - for i, p := range problems[1:] { - // We may encounter duplicate problems because one file - // can be part of many packages. - if !problems[i].Equal(p) { - out = append(out, p) - } - } - return out, nil -} - -func FilterChecks(allChecks []*analysis.Analyzer, checks []string) map[string]bool { - // OPT(dh): this entire computation could be cached per package - allowedChecks := map[string]bool{} - - for _, check := range checks { - b := true - if len(check) > 1 && check[0] == '-' { - b = false - check = check[1:] - } - if check == "*" || check == "all" { - // Match all - for _, c := range allChecks { - allowedChecks[c.Name] = b - } - } else if strings.HasSuffix(check, "*") { - // Glob - prefix := check[:len(check)-1] - isCat := strings.IndexFunc(prefix, func(r rune) bool { return unicode.IsNumber(r) }) == -1 - - for _, c := range allChecks { - idx := strings.IndexFunc(c.Name, func(r rune) bool { return unicode.IsNumber(r) }) - if isCat { - // Glob is S*, which should match S1000 but not SA1000 - cat := c.Name[:idx] - if prefix == cat { - allowedChecks[c.Name] = b - } - } else { - // Glob is S1* - if strings.HasPrefix(c.Name, prefix) { - allowedChecks[c.Name] = b - } - } - } - } else { - // Literal check name - allowedChecks[check] = b - } - } - return allowedChecks -} - -func DisplayPosition(fset *token.FileSet, p token.Pos) token.Position { - if p == token.NoPos { - return token.Position{} - } - - // Only use the adjusted position if it points to another Go file. - // This means we'll point to the original file for cgo files, but - // we won't point to a YACC grammar file. - pos := fset.PositionFor(p, false) - adjPos := fset.PositionFor(p, true) - - if filepath.Ext(adjPos.Filename) == ".go" { - return adjPos - } - return pos -} - -var bufferPool = &sync.Pool{ - New: func() interface{} { - buf := bytes.NewBuffer(nil) - buf.Grow(64) - return buf - }, -} - -func FuncName(f *types.Func) string { - buf := bufferPool.Get().(*bytes.Buffer) - buf.Reset() - if f.Type() != nil { - sig := f.Type().(*types.Signature) - if recv := sig.Recv(); recv != nil { - buf.WriteByte('(') - if _, ok := recv.Type().(*types.Interface); ok { - // gcimporter creates abstract methods of - // named interfaces using the interface type - // (not the named type) as the receiver. - // Don't print it in full. - buf.WriteString("interface") - } else { - types.WriteType(buf, recv.Type(), nil) - } - buf.WriteByte(')') - buf.WriteByte('.') - } else if f.Pkg() != nil { - writePackage(buf, f.Pkg()) - } - } - buf.WriteString(f.Name()) - s := buf.String() - bufferPool.Put(buf) - return s -} - -func writePackage(buf *bytes.Buffer, pkg *types.Package) { - if pkg == nil { - return - } - s := pkg.Path() - if s != "" { - buf.WriteString(s) - buf.WriteByte('.') - } -} diff --git a/vendor/honnef.co/go/tools/lint/lintdsl/lintdsl.go b/vendor/honnef.co/go/tools/lint/lintdsl/lintdsl.go deleted file mode 100644 index 4408aff25..000000000 --- a/vendor/honnef.co/go/tools/lint/lintdsl/lintdsl.go +++ /dev/null @@ -1,58 +0,0 @@ -// Package lintdsl provides helpers for implementing static analysis -// checks. Dot-importing this package is encouraged. -package lintdsl - -import ( - "bytes" - "fmt" - "go/ast" - "go/format" - - "golang.org/x/tools/go/analysis" - "honnef.co/go/tools/pattern" -) - -func Inspect(node ast.Node, fn func(node ast.Node) bool) { - if node == nil { - return - } - ast.Inspect(node, fn) -} - -func Match(pass *analysis.Pass, q pattern.Pattern, node ast.Node) (*pattern.Matcher, bool) { - // Note that we ignore q.Relevant – callers of Match usually use - // AST inspectors that already filter on nodes we're interested - // in. - m := &pattern.Matcher{TypesInfo: pass.TypesInfo} - ok := m.Match(q.Root, node) - return m, ok -} - -func MatchAndEdit(pass *analysis.Pass, before, after pattern.Pattern, node ast.Node) (*pattern.Matcher, []analysis.TextEdit, bool) { - m, ok := Match(pass, before, node) - if !ok { - return m, nil, false - } - r := pattern.NodeToAST(after.Root, m.State) - buf := &bytes.Buffer{} - format.Node(buf, pass.Fset, r) - edit := []analysis.TextEdit{{ - Pos: node.Pos(), - End: node.End(), - NewText: buf.Bytes(), - }} - return m, edit, true -} - -func Selector(x, sel string) *ast.SelectorExpr { - return &ast.SelectorExpr{ - X: &ast.Ident{Name: x}, - Sel: &ast.Ident{Name: sel}, - } -} - -// ExhaustiveTypeSwitch panics when called. It can be used to ensure -// that type switches are exhaustive. -func ExhaustiveTypeSwitch(v interface{}) { - panic(fmt.Sprintf("internal error: unhandled case %T", v)) -} diff --git a/vendor/honnef.co/go/tools/lint/lintutil/format/format.go b/vendor/honnef.co/go/tools/lint/lintutil/format/format.go deleted file mode 100644 index b28f8885b..000000000 --- a/vendor/honnef.co/go/tools/lint/lintutil/format/format.go +++ /dev/null @@ -1,162 +0,0 @@ -// Package format provides formatters for linter problems. -package format - -import ( - "encoding/json" - "fmt" - "go/token" - "io" - "os" - "path/filepath" - "text/tabwriter" - - "honnef.co/go/tools/lint" -) - -func shortPath(path string) string { - cwd, err := os.Getwd() - if err != nil { - return path - } - if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) { - return rel - } - return path -} - -func relativePositionString(pos token.Position) string { - s := shortPath(pos.Filename) - if pos.IsValid() { - if s != "" { - s += ":" - } - s += fmt.Sprintf("%d:%d", pos.Line, pos.Column) - } - if s == "" { - s = "-" - } - return s -} - -type Statter interface { - Stats(total, errors, warnings, ignored int) -} - -type Formatter interface { - Format(p lint.Problem) -} - -type Text struct { - W io.Writer -} - -func (o Text) Format(p lint.Problem) { - fmt.Fprintf(o.W, "%s: %s\n", relativePositionString(p.Pos), p.String()) - for _, r := range p.Related { - fmt.Fprintf(o.W, "\t%s: %s\n", relativePositionString(r.Pos), r.Message) - } -} - -type JSON struct { - W io.Writer -} - -func severity(s lint.Severity) string { - switch s { - case lint.Error: - return "error" - case lint.Warning: - return "warning" - case lint.Ignored: - return "ignored" - } - return "" -} - -func (o JSON) Format(p lint.Problem) { - type location struct { - File string `json:"file"` - Line int `json:"line"` - Column int `json:"column"` - } - type related struct { - Location location `json:"location"` - End location `json:"end"` - Message string `json:"message"` - } - jp := struct { - Code string `json:"code"` - Severity string `json:"severity,omitempty"` - Location location `json:"location"` - End location `json:"end"` - Message string `json:"message"` - Related []related `json:"related,omitempty"` - }{ - Code: p.Check, - Severity: severity(p.Severity), - Location: location{ - File: p.Pos.Filename, - Line: p.Pos.Line, - Column: p.Pos.Column, - }, - End: location{ - File: p.End.Filename, - Line: p.End.Line, - Column: p.End.Column, - }, - Message: p.Message, - } - for _, r := range p.Related { - jp.Related = append(jp.Related, related{ - Location: location{ - File: r.Pos.Filename, - Line: r.Pos.Line, - Column: r.Pos.Column, - }, - End: location{ - File: r.End.Filename, - Line: r.End.Line, - Column: r.End.Column, - }, - Message: r.Message, - }) - } - _ = json.NewEncoder(o.W).Encode(jp) -} - -type Stylish struct { - W io.Writer - - prevFile string - tw *tabwriter.Writer -} - -func (o *Stylish) Format(p lint.Problem) { - pos := p.Pos - if pos.Filename == "" { - pos.Filename = "-" - } - - if pos.Filename != o.prevFile { - if o.prevFile != "" { - o.tw.Flush() - fmt.Fprintln(o.W) - } - fmt.Fprintln(o.W, pos.Filename) - o.prevFile = pos.Filename - o.tw = tabwriter.NewWriter(o.W, 0, 4, 2, ' ', 0) - } - fmt.Fprintf(o.tw, " (%d, %d)\t%s\t%s\n", pos.Line, pos.Column, p.Check, p.Message) - for _, r := range p.Related { - fmt.Fprintf(o.tw, " (%d, %d)\t\t %s\n", r.Pos.Line, r.Pos.Column, r.Message) - } -} - -func (o *Stylish) Stats(total, errors, warnings, ignored int) { - if o.tw != nil { - o.tw.Flush() - fmt.Fprintln(o.W) - } - fmt.Fprintf(o.W, " ✖ %d problems (%d errors, %d warnings, %d ignored)\n", - total, errors, warnings, ignored) -} diff --git a/vendor/honnef.co/go/tools/lint/lintutil/stats.go b/vendor/honnef.co/go/tools/lint/lintutil/stats.go deleted file mode 100644 index ba8caf0af..000000000 --- a/vendor/honnef.co/go/tools/lint/lintutil/stats.go +++ /dev/null @@ -1,7 +0,0 @@ -// +build !aix,!android,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris - -package lintutil - -import "os" - -var infoSignals = []os.Signal{} diff --git a/vendor/honnef.co/go/tools/lint/lintutil/stats_bsd.go b/vendor/honnef.co/go/tools/lint/lintutil/stats_bsd.go deleted file mode 100644 index 3a62ede03..000000000 --- a/vendor/honnef.co/go/tools/lint/lintutil/stats_bsd.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build darwin dragonfly freebsd netbsd openbsd - -package lintutil - -import ( - "os" - "syscall" -) - -var infoSignals = []os.Signal{syscall.SIGINFO} diff --git a/vendor/honnef.co/go/tools/lint/lintutil/stats_posix.go b/vendor/honnef.co/go/tools/lint/lintutil/stats_posix.go deleted file mode 100644 index 53f21c666..000000000 --- a/vendor/honnef.co/go/tools/lint/lintutil/stats_posix.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build aix android linux solaris - -package lintutil - -import ( - "os" - "syscall" -) - -var infoSignals = []os.Signal{syscall.SIGUSR1} diff --git a/vendor/honnef.co/go/tools/lint/lintutil/util.go b/vendor/honnef.co/go/tools/lint/lintutil/util.go deleted file mode 100644 index 7c3dbdec1..000000000 --- a/vendor/honnef.co/go/tools/lint/lintutil/util.go +++ /dev/null @@ -1,444 +0,0 @@ -// Copyright (c) 2013 The Go Authors. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file or at -// https://developers.google.com/open-source/licenses/bsd. - -// Package lintutil provides helpers for writing linter command lines. -package lintutil // import "honnef.co/go/tools/lint/lintutil" - -import ( - "crypto/sha256" - "errors" - "flag" - "fmt" - "go/build" - "go/token" - "io" - "log" - "os" - "os/signal" - "regexp" - "runtime" - "runtime/pprof" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" - - "honnef.co/go/tools/config" - "honnef.co/go/tools/internal/cache" - "honnef.co/go/tools/lint" - "honnef.co/go/tools/lint/lintutil/format" - "honnef.co/go/tools/version" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/buildutil" - "golang.org/x/tools/go/packages" -) - -func NewVersionFlag() flag.Getter { - tags := build.Default.ReleaseTags - v := tags[len(tags)-1][2:] - version := new(VersionFlag) - if err := version.Set(v); err != nil { - panic(fmt.Sprintf("internal error: %s", err)) - } - return version -} - -type VersionFlag int - -func (v *VersionFlag) String() string { - return fmt.Sprintf("1.%d", *v) - -} - -func (v *VersionFlag) Set(s string) error { - if len(s) < 3 { - return errors.New("invalid Go version") - } - if s[0] != '1' { - return errors.New("invalid Go version") - } - if s[1] != '.' { - return errors.New("invalid Go version") - } - i, err := strconv.Atoi(s[2:]) - *v = VersionFlag(i) - return err -} - -func (v *VersionFlag) Get() interface{} { - return int(*v) -} - -func usage(name string, flags *flag.FlagSet) func() { - return func() { - fmt.Fprintf(os.Stderr, "Usage of %s:\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] # runs on package in current directory\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] packages\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] directory\n", name) - fmt.Fprintf(os.Stderr, "\t%s [flags] files... # must be a single package\n", name) - fmt.Fprintf(os.Stderr, "Flags:\n") - flags.PrintDefaults() - } -} - -type list []string - -func (list *list) String() string { - return `"` + strings.Join(*list, ",") + `"` -} - -func (list *list) Set(s string) error { - if s == "" { - *list = nil - return nil - } - - *list = strings.Split(s, ",") - return nil -} - -func FlagSet(name string) *flag.FlagSet { - flags := flag.NewFlagSet("", flag.ExitOnError) - flags.Usage = usage(name, flags) - flags.String("tags", "", "List of `build tags`") - flags.Bool("tests", true, "Include tests") - flags.Bool("version", false, "Print version and exit") - flags.Bool("show-ignored", false, "Don't filter ignored problems") - flags.String("f", "text", "Output `format` (valid choices are 'stylish', 'text' and 'json')") - flags.String("explain", "", "Print description of `check`") - - flags.String("debug.cpuprofile", "", "Write CPU profile to `file`") - flags.String("debug.memprofile", "", "Write memory profile to `file`") - flags.Bool("debug.version", false, "Print detailed version information about this program") - flags.Bool("debug.no-compile-errors", false, "Don't print compile errors") - flags.String("debug.measure-analyzers", "", "Write analysis measurements to `file`. `file` will be opened for appending if it already exists.") - flags.Uint("debug.repeat-analyzers", 0, "Run analyzers `num` times") - - checks := list{"inherit"} - fail := list{"all"} - flags.Var(&checks, "checks", "Comma-separated list of `checks` to enable.") - flags.Var(&fail, "fail", "Comma-separated list of `checks` that can cause a non-zero exit status.") - - tags := build.Default.ReleaseTags - v := tags[len(tags)-1][2:] - version := new(VersionFlag) - if err := version.Set(v); err != nil { - panic(fmt.Sprintf("internal error: %s", err)) - } - - flags.Var(version, "go", "Target Go `version` in the format '1.x'") - return flags -} - -func findCheck(cs []*analysis.Analyzer, check string) (*analysis.Analyzer, bool) { - for _, c := range cs { - if c.Name == check { - return c, true - } - } - return nil, false -} - -func ProcessFlagSet(cs []*analysis.Analyzer, cums []lint.CumulativeChecker, fs *flag.FlagSet) { - tags := fs.Lookup("tags").Value.(flag.Getter).Get().(string) - tests := fs.Lookup("tests").Value.(flag.Getter).Get().(bool) - goVersion := fs.Lookup("go").Value.(flag.Getter).Get().(int) - formatter := fs.Lookup("f").Value.(flag.Getter).Get().(string) - printVersion := fs.Lookup("version").Value.(flag.Getter).Get().(bool) - showIgnored := fs.Lookup("show-ignored").Value.(flag.Getter).Get().(bool) - explain := fs.Lookup("explain").Value.(flag.Getter).Get().(string) - - cpuProfile := fs.Lookup("debug.cpuprofile").Value.(flag.Getter).Get().(string) - memProfile := fs.Lookup("debug.memprofile").Value.(flag.Getter).Get().(string) - debugVersion := fs.Lookup("debug.version").Value.(flag.Getter).Get().(bool) - debugNoCompile := fs.Lookup("debug.no-compile-errors").Value.(flag.Getter).Get().(bool) - debugRepeat := fs.Lookup("debug.repeat-analyzers").Value.(flag.Getter).Get().(uint) - - var measureAnalyzers func(analysis *analysis.Analyzer, pkg *lint.Package, d time.Duration) - if path := fs.Lookup("debug.measure-analyzers").Value.(flag.Getter).Get().(string); path != "" { - f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600) - if err != nil { - log.Fatal(err) - } - - mu := &sync.Mutex{} - measureAnalyzers = func(analysis *analysis.Analyzer, pkg *lint.Package, d time.Duration) { - mu.Lock() - defer mu.Unlock() - if _, err := fmt.Fprintf(f, "%s\t%s\t%d\n", analysis.Name, pkg.ID, d.Nanoseconds()); err != nil { - log.Println("error writing analysis measurements:", err) - } - } - } - - cfg := config.Config{} - cfg.Checks = *fs.Lookup("checks").Value.(*list) - - exit := func(code int) { - if cpuProfile != "" { - pprof.StopCPUProfile() - } - if memProfile != "" { - f, err := os.Create(memProfile) - if err != nil { - panic(err) - } - runtime.GC() - pprof.WriteHeapProfile(f) - } - os.Exit(code) - } - if cpuProfile != "" { - f, err := os.Create(cpuProfile) - if err != nil { - log.Fatal(err) - } - pprof.StartCPUProfile(f) - } - - if debugVersion { - version.Verbose() - exit(0) - } - - if printVersion { - version.Print() - exit(0) - } - - // Validate that the tags argument is well-formed. go/packages - // doesn't detect malformed build flags and returns unhelpful - // errors. - tf := buildutil.TagsFlag{} - if err := tf.Set(tags); err != nil { - fmt.Fprintln(os.Stderr, fmt.Errorf("invalid value %q for flag -tags: %s", tags, err)) - exit(1) - } - - if explain != "" { - var haystack []*analysis.Analyzer - haystack = append(haystack, cs...) - for _, cum := range cums { - haystack = append(haystack, cum.Analyzer()) - } - check, ok := findCheck(haystack, explain) - if !ok { - fmt.Fprintln(os.Stderr, "Couldn't find check", explain) - exit(1) - } - if check.Doc == "" { - fmt.Fprintln(os.Stderr, explain, "has no documentation") - exit(1) - } - fmt.Println(check.Doc) - exit(0) - } - - ps, err := Lint(cs, cums, fs.Args(), &Options{ - Tags: tags, - LintTests: tests, - GoVersion: goVersion, - Config: cfg, - PrintAnalyzerMeasurement: measureAnalyzers, - RepeatAnalyzers: debugRepeat, - }) - if err != nil { - fmt.Fprintln(os.Stderr, err) - exit(1) - } - - var f format.Formatter - switch formatter { - case "text": - f = format.Text{W: os.Stdout} - case "stylish": - f = &format.Stylish{W: os.Stdout} - case "json": - f = format.JSON{W: os.Stdout} - default: - fmt.Fprintf(os.Stderr, "unsupported output format %q\n", formatter) - exit(2) - } - - var ( - total int - errors int - warnings int - ignored int - ) - - fail := *fs.Lookup("fail").Value.(*list) - analyzers := make([]*analysis.Analyzer, len(cs), len(cs)+len(cums)) - copy(analyzers, cs) - for _, cum := range cums { - analyzers = append(analyzers, cum.Analyzer()) - } - shouldExit := lint.FilterChecks(analyzers, fail) - shouldExit["compile"] = true - - total = len(ps) - for _, p := range ps { - if p.Check == "compile" && debugNoCompile { - continue - } - if p.Severity == lint.Ignored && !showIgnored { - ignored++ - continue - } - if shouldExit[p.Check] { - errors++ - } else { - p.Severity = lint.Warning - warnings++ - } - f.Format(p) - } - if f, ok := f.(format.Statter); ok { - f.Stats(total, errors, warnings, ignored) - } - if errors > 0 { - exit(1) - } - exit(0) -} - -type Options struct { - Config config.Config - - Tags string - LintTests bool - GoVersion int - PrintAnalyzerMeasurement func(analysis *analysis.Analyzer, pkg *lint.Package, d time.Duration) - RepeatAnalyzers uint -} - -func computeSalt() ([]byte, error) { - if version.Version != "devel" { - return []byte(version.Version), nil - } - p, err := os.Executable() - if err != nil { - return nil, err - } - f, err := os.Open(p) - if err != nil { - return nil, err - } - defer f.Close() - h := sha256.New() - if _, err := io.Copy(h, f); err != nil { - return nil, err - } - return h.Sum(nil), nil -} - -func Lint(cs []*analysis.Analyzer, cums []lint.CumulativeChecker, paths []string, opt *Options) ([]lint.Problem, error) { - salt, err := computeSalt() - if err != nil { - return nil, fmt.Errorf("could not compute salt for cache: %s", err) - } - cache.SetSalt(salt) - - if opt == nil { - opt = &Options{} - } - - l := &lint.Linter{ - Checkers: cs, - CumulativeCheckers: cums, - GoVersion: opt.GoVersion, - Config: opt.Config, - RepeatAnalyzers: opt.RepeatAnalyzers, - } - l.Stats.PrintAnalyzerMeasurement = opt.PrintAnalyzerMeasurement - cfg := &packages.Config{} - if opt.LintTests { - cfg.Tests = true - } - if opt.Tags != "" { - cfg.BuildFlags = append(cfg.BuildFlags, "-tags", opt.Tags) - } - - printStats := func() { - // Individual stats are read atomically, but overall there - // is no synchronisation. For printing rough progress - // information, this doesn't matter. - switch atomic.LoadUint32(&l.Stats.State) { - case lint.StateInitializing: - fmt.Fprintln(os.Stderr, "Status: initializing") - case lint.StateGraph: - fmt.Fprintln(os.Stderr, "Status: loading package graph") - case lint.StateProcessing: - fmt.Fprintf(os.Stderr, "Packages: %d/%d initial, %d/%d total; Workers: %d/%d; Problems: %d\n", - atomic.LoadUint32(&l.Stats.ProcessedInitialPackages), - atomic.LoadUint32(&l.Stats.InitialPackages), - atomic.LoadUint32(&l.Stats.ProcessedPackages), - atomic.LoadUint32(&l.Stats.TotalPackages), - atomic.LoadUint32(&l.Stats.ActiveWorkers), - atomic.LoadUint32(&l.Stats.TotalWorkers), - atomic.LoadUint32(&l.Stats.Problems), - ) - case lint.StateCumulative: - fmt.Fprintln(os.Stderr, "Status: processing cumulative checkers") - } - } - if len(infoSignals) > 0 { - ch := make(chan os.Signal, 1) - signal.Notify(ch, infoSignals...) - defer signal.Stop(ch) - go func() { - for range ch { - printStats() - } - }() - } - - ps, err := l.Lint(cfg, paths) - return ps, err -} - -var posRe = regexp.MustCompile(`^(.+?):(\d+)(?::(\d+)?)?$`) - -func parsePos(pos string) token.Position { - if pos == "-" || pos == "" { - return token.Position{} - } - parts := posRe.FindStringSubmatch(pos) - if parts == nil { - panic(fmt.Sprintf("internal error: malformed position %q", pos)) - } - file := parts[1] - line, _ := strconv.Atoi(parts[2]) - col, _ := strconv.Atoi(parts[3]) - return token.Position{ - Filename: file, - Line: line, - Column: col, - } -} - -func InitializeAnalyzers(docs map[string]*lint.Documentation, analyzers map[string]*analysis.Analyzer) map[string]*analysis.Analyzer { - out := make(map[string]*analysis.Analyzer, len(analyzers)) - for k, v := range analyzers { - vc := *v - out[k] = &vc - - vc.Name = k - doc, ok := docs[k] - if !ok { - panic(fmt.Sprintf("missing documentation for check %s", k)) - } - vc.Doc = doc.String() - if vc.Flags.Usage == nil { - fs := flag.NewFlagSet("", flag.PanicOnError) - fs.Var(NewVersionFlag(), "go", "Target Go version") - vc.Flags = *fs - } - } - return out -} diff --git a/vendor/honnef.co/go/tools/lint/runner.go b/vendor/honnef.co/go/tools/lint/runner.go deleted file mode 100644 index 74106ced8..000000000 --- a/vendor/honnef.co/go/tools/lint/runner.go +++ /dev/null @@ -1,1114 +0,0 @@ -package lint - -/* -Package loading - -Conceptually, package loading in the runner can be imagined as a -graph-shaped work list. We iteratively pop off leaf nodes (packages -that have no unloaded dependencies) and load data from export data, -our cache, or source. - -Specifically, non-initial packages are loaded from export data and the -fact cache if possible, otherwise from source. Initial packages are -loaded from export data, the fact cache and the (problems, ignores, -config) cache if possible, otherwise from source. - -The appeal of this approach is that it is both simple to implement and -easily parallelizable. Each leaf node can be processed independently, -and new leaf nodes appear as their dependencies are being processed. - -The downside of this approach, however, is that we're doing more work -than necessary. Imagine an initial package A, which has the following -dependency chain: A->B->C->D – in the current implementation, we will -load all 4 packages. However, if package A can be loaded fully from -cached information, then none of its dependencies are necessary, and -we could avoid loading them. - - -Parallelism - -Runner implements parallel processing of packages by spawning one -goroutine per package in the dependency graph, without any semaphores. -Each goroutine initially waits on the completion of all of its -dependencies, thus establishing correct order of processing. Once all -dependencies finish processing, the goroutine will load the package -from export data or source – this loading is guarded by a semaphore, -sized according to the number of CPU cores. This way, we only have as -many packages occupying memory and CPU resources as there are actual -cores to process them. - -This combination of unbounded goroutines but bounded package loading -means that if we have many parallel, independent subgraphs, they will -all execute in parallel, while not wasting resources for long linear -chains or trying to process more subgraphs in parallel than the system -can handle. - - -Caching - -We make use of several caches. These caches are Go's export data, our -facts cache, and our (problems, ignores, config) cache. - -Initial packages will either be loaded from a combination of all three -caches, or from source. Non-initial packages will either be loaded -from a combination of export data and facts cache, or from source. - -The facts cache is separate from the (problems, ignores, config) cache -because when we process non-initial packages, we generate facts, but -we discard problems and ignores. - -The facts cache is keyed by (package, analyzer), whereas the -(problems, ignores, config) cache is keyed by (package, list of -analyzes). The difference between the two exists because there are -only a handful of analyses that produce facts, but hundreds of -analyses that don't. Creating one cache entry per fact-generating -analysis is feasible, creating one cache entry per normal analysis has -significant performance and storage overheads. - -The downside of keying by the list of analyzes is, naturally, that a -change in list of analyzes changes the cache key. `staticcheck -checks -A` and `staticcheck -checks A,B` will therefore need their own cache -entries and not reuse each other's work. This problem does not affect -the facts cache. - -*/ - -import ( - "bytes" - "encoding/gob" - "encoding/hex" - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" - "regexp" - "runtime" - "sort" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" - - "golang.org/x/tools/go/analysis" - "golang.org/x/tools/go/packages" - "golang.org/x/tools/go/types/objectpath" - "honnef.co/go/tools/config" - "honnef.co/go/tools/facts" - "honnef.co/go/tools/internal/cache" - "honnef.co/go/tools/loader" -) - -func init() { - gob.Register(&FileIgnore{}) - gob.Register(&LineIgnore{}) -} - -// If enabled, abuse of the go/analysis API will lead to panics -const sanityCheck = true - -// OPT(dh): for a dependency tree A->B->C->D, if we have cached data -// for B, there should be no need to load C and D individually. Go's -// export data for B contains all the data we need on types, and our -// fact cache could store the union of B, C and D in B. -// -// This may change unused's behavior, however, as it may observe fewer -// interfaces from transitive dependencies. - -// OPT(dh): every single package will have the same value for -// canClearTypes. We could move the Package.decUse method to runner to -// eliminate this field. This is probably not worth it, though. There -// are only thousands of packages, so the field only takes up -// kilobytes of memory. - -// OPT(dh): do we really need the Package.gen field? it's based -// trivially on pkg.results and merely caches the result of a type -// assertion. How often do we actually use the field? - -type Package struct { - // dependents is initially set to 1 plus the number of packages - // that directly import this package. It is atomically decreased - // by 1 every time a dependent has been processed or when the - // package itself has been processed. Once the value reaches zero, - // the package is no longer needed. - dependents uint64 - - *packages.Package - Imports []*Package - initial bool - // fromSource is set to true for packages that have been loaded - // from source. This is the case for initial packages, packages - // with missing export data, and packages with no cached facts. - fromSource bool - // hash stores the package hash, as computed by packageHash - hash string - actionID cache.ActionID - done chan struct{} - - resultsMu sync.Mutex - // results maps analyzer IDs to analyzer results. it is - // implemented as a deduplicating concurrent cache. - results []*result - - cfg *config.Config - // gen maps file names to the code generator that created them - gen map[string]facts.Generator - problems []Problem - ignores []Ignore - errs []error - - // these slices are indexed by analysis - facts []map[types.Object][]analysis.Fact - pkgFacts [][]analysis.Fact - - // canClearTypes is set to true if we can discard type - // information after the package and its dependents have been - // processed. This is the case when no cumulative checkers are - // being run. - canClearTypes bool -} - -type cachedPackage struct { - Problems []Problem - Ignores []Ignore - Config *config.Config -} - -func (pkg *Package) decUse() { - ret := atomic.AddUint64(&pkg.dependents, ^uint64(0)) - if ret == 0 { - // nobody depends on this package anymore - if pkg.canClearTypes { - pkg.Types = nil - } - pkg.facts = nil - pkg.pkgFacts = nil - - for _, imp := range pkg.Imports { - imp.decUse() - } - } -} - -type result struct { - v interface{} - err error - ready chan struct{} -} - -type Runner struct { - cache *cache.Cache - goVersion int - stats *Stats - repeatAnalyzers uint - - analyzerIDs analyzerIDs - problemsCacheKey string - - // limits parallelism of loading packages - loadSem chan struct{} -} - -type analyzerIDs struct { - m map[*analysis.Analyzer]int -} - -func (ids analyzerIDs) get(a *analysis.Analyzer) int { - id, ok := ids.m[a] - if !ok { - panic(fmt.Sprintf("no analyzer ID for %s", a.Name)) - } - return id -} - -type Fact struct { - Path string - Fact analysis.Fact -} - -type analysisAction struct { - analyzer *analysis.Analyzer - analyzerID int - pkg *Package - newPackageFacts []analysis.Fact - problems []Problem - - pkgFacts map[*types.Package][]analysis.Fact -} - -func (ac *analysisAction) String() string { - return fmt.Sprintf("%s @ %s", ac.analyzer, ac.pkg) -} - -func (ac *analysisAction) allObjectFacts() []analysis.ObjectFact { - out := make([]analysis.ObjectFact, 0, len(ac.pkg.facts[ac.analyzerID])) - for obj, facts := range ac.pkg.facts[ac.analyzerID] { - for _, fact := range facts { - out = append(out, analysis.ObjectFact{ - Object: obj, - Fact: fact, - }) - } - } - return out -} - -func (ac *analysisAction) allPackageFacts() []analysis.PackageFact { - out := make([]analysis.PackageFact, 0, len(ac.pkgFacts)) - for pkg, facts := range ac.pkgFacts { - for _, fact := range facts { - out = append(out, analysis.PackageFact{ - Package: pkg, - Fact: fact, - }) - } - } - return out -} - -func (ac *analysisAction) importObjectFact(obj types.Object, fact analysis.Fact) bool { - if sanityCheck && len(ac.analyzer.FactTypes) == 0 { - panic("analysis doesn't export any facts") - } - for _, f := range ac.pkg.facts[ac.analyzerID][obj] { - if reflect.TypeOf(f) == reflect.TypeOf(fact) { - reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem()) - return true - } - } - return false -} - -func (ac *analysisAction) importPackageFact(pkg *types.Package, fact analysis.Fact) bool { - if sanityCheck && len(ac.analyzer.FactTypes) == 0 { - panic("analysis doesn't export any facts") - } - for _, f := range ac.pkgFacts[pkg] { - if reflect.TypeOf(f) == reflect.TypeOf(fact) { - reflect.ValueOf(fact).Elem().Set(reflect.ValueOf(f).Elem()) - return true - } - } - return false -} - -func (ac *analysisAction) exportObjectFact(obj types.Object, fact analysis.Fact) { - if sanityCheck && len(ac.analyzer.FactTypes) == 0 { - panic("analysis doesn't export any facts") - } - ac.pkg.facts[ac.analyzerID][obj] = append(ac.pkg.facts[ac.analyzerID][obj], fact) -} - -func (ac *analysisAction) exportPackageFact(fact analysis.Fact) { - if sanityCheck && len(ac.analyzer.FactTypes) == 0 { - panic("analysis doesn't export any facts") - } - ac.pkgFacts[ac.pkg.Types] = append(ac.pkgFacts[ac.pkg.Types], fact) - ac.newPackageFacts = append(ac.newPackageFacts, fact) -} - -func (ac *analysisAction) report(pass *analysis.Pass, d analysis.Diagnostic) { - p := Problem{ - Pos: DisplayPosition(pass.Fset, d.Pos), - End: DisplayPosition(pass.Fset, d.End), - Message: d.Message, - Check: pass.Analyzer.Name, - } - for _, r := range d.Related { - p.Related = append(p.Related, Related{ - Pos: DisplayPosition(pass.Fset, r.Pos), - End: DisplayPosition(pass.Fset, r.End), - Message: r.Message, - }) - } - ac.problems = append(ac.problems, p) -} - -func (r *Runner) runAnalysis(ac *analysisAction) (ret interface{}, err error) { - ac.pkg.resultsMu.Lock() - res := ac.pkg.results[r.analyzerIDs.get(ac.analyzer)] - if res != nil { - ac.pkg.resultsMu.Unlock() - <-res.ready - return res.v, res.err - } else { - res = &result{ - ready: make(chan struct{}), - } - ac.pkg.results[r.analyzerIDs.get(ac.analyzer)] = res - ac.pkg.resultsMu.Unlock() - - defer func() { - res.v = ret - res.err = err - close(res.ready) - }() - - pass := new(analysis.Pass) - *pass = analysis.Pass{ - Analyzer: ac.analyzer, - Fset: ac.pkg.Fset, - Files: ac.pkg.Syntax, - // type information may be nil or may be populated. if it is - // nil, it will get populated later. - Pkg: ac.pkg.Types, - TypesInfo: ac.pkg.TypesInfo, - TypesSizes: ac.pkg.TypesSizes, - ResultOf: map[*analysis.Analyzer]interface{}{}, - ImportObjectFact: ac.importObjectFact, - ImportPackageFact: ac.importPackageFact, - ExportObjectFact: ac.exportObjectFact, - ExportPackageFact: ac.exportPackageFact, - Report: func(d analysis.Diagnostic) { - ac.report(pass, d) - }, - AllObjectFacts: ac.allObjectFacts, - AllPackageFacts: ac.allPackageFacts, - } - - if !ac.pkg.initial { - // Don't report problems in dependencies - pass.Report = func(analysis.Diagnostic) {} - } - return r.runAnalysisUser(pass, ac) - } -} - -func (r *Runner) loadCachedPackage(pkg *Package, analyzers []*analysis.Analyzer) (cachedPackage, bool) { - // OPT(dh): we can cache this computation, it'll be the same for all packages - id := cache.Subkey(pkg.actionID, "data "+r.problemsCacheKey) - - b, _, err := r.cache.GetBytes(id) - if err != nil { - return cachedPackage{}, false - } - var cpkg cachedPackage - if err := gob.NewDecoder(bytes.NewReader(b)).Decode(&cpkg); err != nil { - return cachedPackage{}, false - } - return cpkg, true -} - -func (r *Runner) loadCachedFacts(a *analysis.Analyzer, pkg *Package) ([]Fact, bool) { - if len(a.FactTypes) == 0 { - return nil, true - } - - var facts []Fact - // Look in the cache for facts - aID := passActionID(pkg, a) - aID = cache.Subkey(aID, "facts") - b, _, err := r.cache.GetBytes(aID) - if err != nil { - // No cached facts, analyse this package like a user-provided one, but ignore diagnostics - return nil, false - } - - if err := gob.NewDecoder(bytes.NewReader(b)).Decode(&facts); err != nil { - // Cached facts are broken, analyse this package like a user-provided one, but ignore diagnostics - return nil, false - } - return facts, true -} - -type dependencyError struct { - dep string - err error -} - -func (err dependencyError) nested() dependencyError { - if o, ok := err.err.(dependencyError); ok { - return o.nested() - } - return err -} - -func (err dependencyError) Error() string { - if o, ok := err.err.(dependencyError); ok { - return o.Error() - } - return fmt.Sprintf("error running dependency %s: %s", err.dep, err.err) -} - -func (r *Runner) makeAnalysisAction(a *analysis.Analyzer, pkg *Package) *analysisAction { - aid := r.analyzerIDs.get(a) - ac := &analysisAction{ - analyzer: a, - analyzerID: aid, - pkg: pkg, - } - - if len(a.FactTypes) == 0 { - return ac - } - - // Merge all package facts of dependencies - ac.pkgFacts = map[*types.Package][]analysis.Fact{} - seen := map[*Package]struct{}{} - var dfs func(*Package) - dfs = func(pkg *Package) { - if _, ok := seen[pkg]; ok { - return - } - seen[pkg] = struct{}{} - s := pkg.pkgFacts[aid] - ac.pkgFacts[pkg.Types] = s[0:len(s):len(s)] - for _, imp := range pkg.Imports { - dfs(imp) - } - } - dfs(pkg) - - return ac -} - -// analyzes that we always want to run, even if they're not being run -// explicitly or as dependencies. these are necessary for the inner -// workings of the runner. -var injectedAnalyses = []*analysis.Analyzer{facts.Generated, config.Analyzer} - -func (r *Runner) runAnalysisUser(pass *analysis.Pass, ac *analysisAction) (interface{}, error) { - if !ac.pkg.fromSource { - panic(fmt.Sprintf("internal error: %s was not loaded from source", ac.pkg)) - } - - // User-provided package, analyse it - // First analyze it with dependencies - for _, req := range ac.analyzer.Requires { - acReq := r.makeAnalysisAction(req, ac.pkg) - ret, err := r.runAnalysis(acReq) - if err != nil { - // We couldn't run a dependency, no point in going on - return nil, dependencyError{req.Name, err} - } - - pass.ResultOf[req] = ret - } - - // Then with this analyzer - var ret interface{} - for i := uint(0); i < r.repeatAnalyzers+1; i++ { - var err error - t := time.Now() - ret, err = ac.analyzer.Run(pass) - r.stats.MeasureAnalyzer(ac.analyzer, ac.pkg, time.Since(t)) - if err != nil { - return nil, err - } - } - - if len(ac.analyzer.FactTypes) > 0 { - // Merge new facts into the package and persist them. - var facts []Fact - for _, fact := range ac.newPackageFacts { - id := r.analyzerIDs.get(ac.analyzer) - ac.pkg.pkgFacts[id] = append(ac.pkg.pkgFacts[id], fact) - facts = append(facts, Fact{"", fact}) - } - for obj, afacts := range ac.pkg.facts[ac.analyzerID] { - if obj.Pkg() != ac.pkg.Package.Types { - continue - } - path, err := objectpath.For(obj) - if err != nil { - continue - } - for _, fact := range afacts { - facts = append(facts, Fact{string(path), fact}) - } - } - - if err := r.cacheData(facts, ac.pkg, ac.analyzer, "facts"); err != nil { - return nil, err - } - } - - return ret, nil -} - -func (r *Runner) cacheData(v interface{}, pkg *Package, a *analysis.Analyzer, subkey string) error { - buf := &bytes.Buffer{} - if err := gob.NewEncoder(buf).Encode(v); err != nil { - return err - } - aID := passActionID(pkg, a) - aID = cache.Subkey(aID, subkey) - if err := r.cache.PutBytes(aID, buf.Bytes()); err != nil { - return err - } - return nil -} - -func NewRunner(stats *Stats) (*Runner, error) { - cache, err := cache.Default() - if err != nil { - return nil, err - } - - return &Runner{ - cache: cache, - stats: stats, - }, nil -} - -// Run loads packages corresponding to patterns and analyses them with -// analyzers. It returns the loaded packages, which contain reported -// diagnostics as well as extracted ignore directives. -// -// Note that diagnostics have not been filtered at this point yet, to -// accommodate cumulative analyzes that require additional steps to -// produce diagnostics. -func (r *Runner) Run(cfg *packages.Config, patterns []string, analyzers []*analysis.Analyzer, hasCumulative bool) ([]*Package, error) { - checkerNames := make([]string, len(analyzers)) - for i, a := range analyzers { - checkerNames[i] = a.Name - } - sort.Strings(checkerNames) - r.problemsCacheKey = strings.Join(checkerNames, " ") - - var allAnalyzers []*analysis.Analyzer - r.analyzerIDs = analyzerIDs{m: map[*analysis.Analyzer]int{}} - id := 0 - seen := map[*analysis.Analyzer]struct{}{} - var dfs func(a *analysis.Analyzer) - dfs = func(a *analysis.Analyzer) { - if _, ok := seen[a]; ok { - return - } - seen[a] = struct{}{} - allAnalyzers = append(allAnalyzers, a) - r.analyzerIDs.m[a] = id - id++ - for _, f := range a.FactTypes { - gob.Register(f) - } - for _, req := range a.Requires { - dfs(req) - } - } - for _, a := range analyzers { - if v := a.Flags.Lookup("go"); v != nil { - v.Value.Set(fmt.Sprintf("1.%d", r.goVersion)) - } - dfs(a) - } - for _, a := range injectedAnalyses { - dfs(a) - } - // Run all analyzers on all packages (subject to further - // restrictions enforced later). This guarantees that if analyzer - // A1 depends on A2, and A2 has facts, that A2 will run on the - // dependencies of user-provided packages, even though A1 won't. - analyzers = allAnalyzers - - var dcfg packages.Config - if cfg != nil { - dcfg = *cfg - } - - atomic.StoreUint32(&r.stats.State, StateGraph) - initialPkgs, err := loader.Graph(dcfg, patterns...) - if err != nil { - return nil, err - } - defer r.cache.Trim() - - var allPkgs []*Package - m := map[*packages.Package]*Package{} - packages.Visit(initialPkgs, nil, func(l *packages.Package) { - m[l] = &Package{ - Package: l, - results: make([]*result, len(r.analyzerIDs.m)), - facts: make([]map[types.Object][]analysis.Fact, len(r.analyzerIDs.m)), - pkgFacts: make([][]analysis.Fact, len(r.analyzerIDs.m)), - done: make(chan struct{}), - // every package needs itself - dependents: 1, - canClearTypes: !hasCumulative, - } - allPkgs = append(allPkgs, m[l]) - for i := range m[l].facts { - m[l].facts[i] = map[types.Object][]analysis.Fact{} - } - for _, err := range l.Errors { - m[l].errs = append(m[l].errs, err) - } - for _, v := range l.Imports { - m[v].dependents++ - m[l].Imports = append(m[l].Imports, m[v]) - } - - m[l].hash, err = r.packageHash(m[l]) - m[l].actionID = packageActionID(m[l]) - if err != nil { - m[l].errs = append(m[l].errs, err) - } - }) - - pkgs := make([]*Package, len(initialPkgs)) - for i, l := range initialPkgs { - pkgs[i] = m[l] - pkgs[i].initial = true - } - - atomic.StoreUint32(&r.stats.InitialPackages, uint32(len(initialPkgs))) - atomic.StoreUint32(&r.stats.TotalPackages, uint32(len(allPkgs))) - atomic.StoreUint32(&r.stats.State, StateProcessing) - - var wg sync.WaitGroup - wg.Add(len(allPkgs)) - r.loadSem = make(chan struct{}, runtime.GOMAXPROCS(-1)) - atomic.StoreUint32(&r.stats.TotalWorkers, uint32(cap(r.loadSem))) - for _, pkg := range allPkgs { - pkg := pkg - go func() { - r.processPkg(pkg, analyzers) - - if pkg.initial { - atomic.AddUint32(&r.stats.ProcessedInitialPackages, 1) - } - atomic.AddUint32(&r.stats.Problems, uint32(len(pkg.problems))) - wg.Done() - }() - } - wg.Wait() - - return pkgs, nil -} - -var posRe = regexp.MustCompile(`^(.+?):(\d+)(?::(\d+)?)?`) - -func parsePos(pos string) (token.Position, int, error) { - if pos == "-" || pos == "" { - return token.Position{}, 0, nil - } - parts := posRe.FindStringSubmatch(pos) - if parts == nil { - return token.Position{}, 0, fmt.Errorf("malformed position %q", pos) - } - file := parts[1] - line, _ := strconv.Atoi(parts[2]) - col, _ := strconv.Atoi(parts[3]) - return token.Position{ - Filename: file, - Line: line, - Column: col, - }, len(parts[0]), nil -} - -// loadPkg loads a Go package. It may be loaded from a combination of -// caches, or from source. -func (r *Runner) loadPkg(pkg *Package, analyzers []*analysis.Analyzer) error { - if pkg.Types != nil { - panic(fmt.Sprintf("internal error: %s has already been loaded", pkg.Package)) - } - - if pkg.initial { - // Try to load cached package - cpkg, ok := r.loadCachedPackage(pkg, analyzers) - if ok { - pkg.problems = cpkg.Problems - pkg.ignores = cpkg.Ignores - pkg.cfg = cpkg.Config - } else { - pkg.fromSource = true - return loader.LoadFromSource(pkg.Package) - } - } - - // At this point we're either working with a non-initial package, - // or we managed to load cached problems for the package. We still - // need export data and facts. - - // OPT(dh): we don't need type information for this package if no - // other package depends on it. this may be the case for initial - // packages. - - // Load package from export data - if err := loader.LoadFromExport(pkg.Package); err != nil { - // We asked Go to give us up to date export data, yet - // we can't load it. There must be something wrong. - // - // Attempt loading from source. This should fail (because - // otherwise there would be export data); we just want to - // get the compile errors. If loading from source succeeds - // we discard the result, anyway. Otherwise we'll fail - // when trying to reload from export data later. - // - // FIXME(dh): we no longer reload from export data, so - // theoretically we should be able to continue - pkg.fromSource = true - if err := loader.LoadFromSource(pkg.Package); err != nil { - return err - } - // Make sure this package can't be imported successfully - pkg.Package.Errors = append(pkg.Package.Errors, packages.Error{ - Pos: "-", - Msg: fmt.Sprintf("could not load export data: %s", err), - Kind: packages.ParseError, - }) - return fmt.Errorf("could not load export data: %s", err) - } - - failed := false - seen := make([]bool, len(r.analyzerIDs.m)) - var dfs func(*analysis.Analyzer) - dfs = func(a *analysis.Analyzer) { - if seen[r.analyzerIDs.get(a)] { - return - } - seen[r.analyzerIDs.get(a)] = true - - if len(a.FactTypes) > 0 { - facts, ok := r.loadCachedFacts(a, pkg) - if !ok { - failed = true - return - } - - for _, f := range facts { - if f.Path == "" { - // This is a package fact - pkg.pkgFacts[r.analyzerIDs.get(a)] = append(pkg.pkgFacts[r.analyzerIDs.get(a)], f.Fact) - continue - } - obj, err := objectpath.Object(pkg.Types, objectpath.Path(f.Path)) - if err != nil { - // Be lenient about these errors. For example, when - // analysing io/ioutil from source, we may get a fact - // for methods on the devNull type, and objectpath - // will happily create a path for them. However, when - // we later load io/ioutil from export data, the path - // no longer resolves. - // - // If an exported type embeds the unexported type, - // then (part of) the unexported type will become part - // of the type information and our path will resolve - // again. - continue - } - pkg.facts[r.analyzerIDs.get(a)][obj] = append(pkg.facts[r.analyzerIDs.get(a)][obj], f.Fact) - } - } - - for _, req := range a.Requires { - dfs(req) - } - } - for _, a := range analyzers { - dfs(a) - } - - if !failed { - return nil - } - - // We failed to load some cached facts - pkg.fromSource = true - // XXX we added facts to the maps, we need to get rid of those - return loader.LoadFromSource(pkg.Package) -} - -type analysisError struct { - analyzer *analysis.Analyzer - pkg *Package - err error -} - -func (err analysisError) Error() string { - return fmt.Sprintf("error running analyzer %s on %s: %s", err.analyzer, err.pkg, err.err) -} - -// processPkg processes a package. This involves loading the package, -// either from export data or from source. For packages loaded from -// source, the provides analyzers will be run on the package. -func (r *Runner) processPkg(pkg *Package, analyzers []*analysis.Analyzer) { - defer func() { - // Clear information we no longer need. Make sure to do this - // when returning from processPkg so that we clear - // dependencies, not just initial packages. - pkg.TypesInfo = nil - pkg.Syntax = nil - pkg.results = nil - - atomic.AddUint32(&r.stats.ProcessedPackages, 1) - pkg.decUse() - close(pkg.done) - }() - - // Ensure all packages have the generated map and config. This is - // required by internals of the runner. Analyses that themselves - // make use of either have an explicit dependency so that other - // runners work correctly, too. - analyzers = append(analyzers[0:len(analyzers):len(analyzers)], injectedAnalyses...) - - if len(pkg.errs) != 0 { - return - } - - for _, imp := range pkg.Imports { - <-imp.done - if len(imp.errs) > 0 { - if imp.initial { - // Don't print the error of the dependency since it's - // an initial package and we're already printing the - // error. - pkg.errs = append(pkg.errs, fmt.Errorf("could not analyze dependency %s of %s", imp, pkg)) - } else { - var s string - for _, err := range imp.errs { - s += "\n\t" + err.Error() - } - pkg.errs = append(pkg.errs, fmt.Errorf("could not analyze dependency %s of %s: %s", imp, pkg, s)) - } - return - } - } - if pkg.PkgPath == "unsafe" { - pkg.Types = types.Unsafe - return - } - - r.loadSem <- struct{}{} - atomic.AddUint32(&r.stats.ActiveWorkers, 1) - defer func() { - <-r.loadSem - atomic.AddUint32(&r.stats.ActiveWorkers, ^uint32(0)) - }() - if err := r.loadPkg(pkg, analyzers); err != nil { - pkg.errs = append(pkg.errs, err) - return - } - - // A package's object facts is the union of all of its dependencies. - for _, imp := range pkg.Imports { - for ai, m := range imp.facts { - for obj, facts := range m { - pkg.facts[ai][obj] = facts[0:len(facts):len(facts)] - } - } - } - - if !pkg.fromSource { - // Nothing left to do for the package. - return - } - - // Run analyses on initial packages and those missing facts - var wg sync.WaitGroup - wg.Add(len(analyzers)) - errs := make([]error, len(analyzers)) - var acs []*analysisAction - for i, a := range analyzers { - i := i - a := a - ac := r.makeAnalysisAction(a, pkg) - acs = append(acs, ac) - go func() { - defer wg.Done() - // Only initial packages and packages with missing - // facts will have been loaded from source. - if pkg.initial || len(a.FactTypes) > 0 { - if _, err := r.runAnalysis(ac); err != nil { - errs[i] = analysisError{a, pkg, err} - return - } - } - }() - } - wg.Wait() - - depErrors := map[dependencyError]int{} - for _, err := range errs { - if err == nil { - continue - } - switch err := err.(type) { - case analysisError: - switch err := err.err.(type) { - case dependencyError: - depErrors[err.nested()]++ - default: - pkg.errs = append(pkg.errs, err) - } - default: - pkg.errs = append(pkg.errs, err) - } - } - for err, count := range depErrors { - pkg.errs = append(pkg.errs, - fmt.Errorf("could not run %s@%s, preventing %d analyzers from running: %s", err.dep, pkg, count, err.err)) - } - - // We can't process ignores at this point because `unused` needs - // to see more than one package to make its decision. - // - // OPT(dh): can't we guard this block of code by pkg.initial? - ignores, problems := parseDirectives(pkg.Package) - pkg.ignores = append(pkg.ignores, ignores...) - pkg.problems = append(pkg.problems, problems...) - for _, ac := range acs { - pkg.problems = append(pkg.problems, ac.problems...) - } - - if pkg.initial { - // Only initial packages have these analyzers run, and only - // initial packages need these. - if pkg.results[r.analyzerIDs.get(config.Analyzer)].v != nil { - pkg.cfg = pkg.results[r.analyzerIDs.get(config.Analyzer)].v.(*config.Config) - } - pkg.gen = pkg.results[r.analyzerIDs.get(facts.Generated)].v.(map[string]facts.Generator) - } - - // In a previous version of the code, we would throw away all type - // information and reload it from export data. That was - // nonsensical. The *types.Package doesn't keep any information - // live that export data wouldn't also. We only need to discard - // the AST and the TypesInfo maps; that happens after we return - // from processPkg. -} - -func parseDirective(s string) (cmd string, args []string) { - if !strings.HasPrefix(s, "//lint:") { - return "", nil - } - s = strings.TrimPrefix(s, "//lint:") - fields := strings.Split(s, " ") - return fields[0], fields[1:] -} - -// parseDirectives extracts all linter directives from the source -// files of the package. Malformed directives are returned as problems. -func parseDirectives(pkg *packages.Package) ([]Ignore, []Problem) { - var ignores []Ignore - var problems []Problem - - for _, f := range pkg.Syntax { - found := false - commentLoop: - for _, cg := range f.Comments { - for _, c := range cg.List { - if strings.Contains(c.Text, "//lint:") { - found = true - break commentLoop - } - } - } - if !found { - continue - } - cm := ast.NewCommentMap(pkg.Fset, f, f.Comments) - for node, cgs := range cm { - for _, cg := range cgs { - for _, c := range cg.List { - if !strings.HasPrefix(c.Text, "//lint:") { - continue - } - cmd, args := parseDirective(c.Text) - switch cmd { - case "ignore", "file-ignore": - if len(args) < 2 { - p := Problem{ - Pos: DisplayPosition(pkg.Fset, c.Pos()), - Message: "malformed linter directive; missing the required reason field?", - Severity: Error, - Check: "compile", - } - problems = append(problems, p) - continue - } - default: - // unknown directive, ignore - continue - } - checks := strings.Split(args[0], ",") - pos := DisplayPosition(pkg.Fset, node.Pos()) - var ig Ignore - switch cmd { - case "ignore": - ig = &LineIgnore{ - File: pos.Filename, - Line: pos.Line, - Checks: checks, - Pos: DisplayPosition(pkg.Fset, c.Pos()), - } - case "file-ignore": - ig = &FileIgnore{ - File: pos.Filename, - Checks: checks, - } - } - ignores = append(ignores, ig) - } - } - } - } - - return ignores, problems -} - -// packageHash computes a package's hash. The hash is based on all Go -// files that make up the package, as well as the hashes of imported -// packages. -func (r *Runner) packageHash(pkg *Package) (string, error) { - key := cache.NewHash("package hash") - fmt.Fprintf(key, "pkgpath %s\n", pkg.PkgPath) - fmt.Fprintf(key, "go %d\n", r.goVersion) - for _, f := range pkg.CompiledGoFiles { - h, err := cache.FileHash(f) - if err != nil { - return "", err - } - fmt.Fprintf(key, "file %s %x\n", f, h) - } - - // Actually load the configuration to calculate its hash. This - // will take into consideration inheritance of configuration - // files, as well as the default configuration. - // - // OPT(dh): doing this means we'll load the config twice: once for - // computing the hash, and once when analyzing the package from - // source. - cdir := config.Dir(pkg.GoFiles) - if cdir == "" { - fmt.Fprintf(key, "file %s %x\n", config.ConfigName, [cache.HashSize]byte{}) - } else { - cfg, err := config.Load(cdir) - if err != nil { - return "", err - } - h := cache.NewHash(config.ConfigName) - if _, err := h.Write([]byte(cfg.String())); err != nil { - return "", err - } - fmt.Fprintf(key, "file %s %x\n", config.ConfigName, h.Sum()) - } - - imps := make([]*Package, len(pkg.Imports)) - copy(imps, pkg.Imports) - sort.Slice(imps, func(i, j int) bool { - return imps[i].PkgPath < imps[j].PkgPath - }) - for _, dep := range imps { - if dep.PkgPath == "unsafe" { - continue - } - - fmt.Fprintf(key, "import %s %s\n", dep.PkgPath, dep.hash) - } - h := key.Sum() - return hex.EncodeToString(h[:]), nil -} - -func packageActionID(pkg *Package) cache.ActionID { - key := cache.NewHash("package ID") - fmt.Fprintf(key, "pkgpath %s\n", pkg.PkgPath) - fmt.Fprintf(key, "pkghash %s\n", pkg.hash) - return key.Sum() -} - -// passActionID computes an ActionID for an analysis pass. -func passActionID(pkg *Package, analyzer *analysis.Analyzer) cache.ActionID { - return cache.Subkey(pkg.actionID, fmt.Sprintf("analyzer %s", analyzer.Name)) -} diff --git a/vendor/honnef.co/go/tools/lint/stats.go b/vendor/honnef.co/go/tools/lint/stats.go deleted file mode 100644 index 85eb97844..000000000 --- a/vendor/honnef.co/go/tools/lint/stats.go +++ /dev/null @@ -1,38 +0,0 @@ -package lint - -import ( - "time" - - "golang.org/x/tools/go/analysis" -) - -const ( - StateInitializing = 0 - StateGraph = 1 - StateProcessing = 2 - StateCumulative = 3 -) - -type Stats struct { - State uint32 - - InitialPackages uint32 - TotalPackages uint32 - ProcessedPackages uint32 - ProcessedInitialPackages uint32 - Problems uint32 - ActiveWorkers uint32 - TotalWorkers uint32 - PrintAnalyzerMeasurement func(*analysis.Analyzer, *Package, time.Duration) -} - -type AnalysisMeasurementKey struct { - Analysis string - Pkg string -} - -func (s *Stats) MeasureAnalyzer(analysis *analysis.Analyzer, pkg *Package, d time.Duration) { - if s.PrintAnalyzerMeasurement != nil { - s.PrintAnalyzerMeasurement(analysis, pkg, d) - } -} diff --git a/vendor/honnef.co/go/tools/loader/loader.go b/vendor/honnef.co/go/tools/loader/loader.go deleted file mode 100644 index a14f274d2..000000000 --- a/vendor/honnef.co/go/tools/loader/loader.go +++ /dev/null @@ -1,210 +0,0 @@ -package loader - -import ( - "errors" - "fmt" - "go/ast" - "go/parser" - "go/scanner" - "go/token" - "go/types" - "log" - "os" - - "golang.org/x/tools/go/gcexportdata" - "golang.org/x/tools/go/packages" -) - -// Graph resolves patterns and returns packages with all the -// information required to later load type information, and optionally -// syntax trees. -// -// The provided config can set any setting with the exception of Mode. -func Graph(cfg packages.Config, patterns ...string) ([]*packages.Package, error) { - cfg.Mode = packages.NeedName | packages.NeedImports | packages.NeedDeps | packages.NeedExportsFile | packages.NeedFiles | packages.NeedCompiledGoFiles | packages.NeedTypesSizes - pkgs, err := packages.Load(&cfg, patterns...) - if err != nil { - return nil, err - } - fset := token.NewFileSet() - packages.Visit(pkgs, nil, func(pkg *packages.Package) { - pkg.Fset = fset - }) - - n := 0 - for _, pkg := range pkgs { - if len(pkg.CompiledGoFiles) == 0 && len(pkg.Errors) == 0 && pkg.PkgPath != "unsafe" { - // If a package consists only of test files, then - // go/packages incorrectly(?) returns an empty package for - // the non-test variant. Get rid of those packages. See - // #646. - // - // Do not, however, skip packages that have errors. Those, - // too, may have no files, but we want to print the - // errors. - continue - } - pkgs[n] = pkg - n++ - } - return pkgs[:n], nil -} - -// LoadFromExport loads a package from export data. All of its -// dependencies must have been loaded already. -func LoadFromExport(pkg *packages.Package) error { - pkg.IllTyped = true - for path, pkg := range pkg.Imports { - if pkg.Types == nil { - return fmt.Errorf("dependency %q hasn't been loaded yet", path) - } - } - if pkg.ExportFile == "" { - return fmt.Errorf("no export data for %q", pkg.ID) - } - f, err := os.Open(pkg.ExportFile) - if err != nil { - return err - } - defer f.Close() - - r, err := gcexportdata.NewReader(f) - if err != nil { - return err - } - - view := make(map[string]*types.Package) // view seen by gcexportdata - seen := make(map[*packages.Package]bool) // all visited packages - var visit func(pkgs map[string]*packages.Package) - visit = func(pkgs map[string]*packages.Package) { - for _, pkg := range pkgs { - if !seen[pkg] { - seen[pkg] = true - view[pkg.PkgPath] = pkg.Types - visit(pkg.Imports) - } - } - } - visit(pkg.Imports) - tpkg, err := gcexportdata.Read(r, pkg.Fset, view, pkg.PkgPath) - if err != nil { - return err - } - pkg.Types = tpkg - pkg.IllTyped = false - return nil -} - -// LoadFromSource loads a package from source. All of its dependencies -// must have been loaded already. -func LoadFromSource(pkg *packages.Package) error { - pkg.IllTyped = true - pkg.Types = types.NewPackage(pkg.PkgPath, pkg.Name) - - // OPT(dh): many packages have few files, much fewer than there - // are CPU cores. Additionally, parsing each individual file is - // very fast. A naive parallel implementation of this loop won't - // be faster, and tends to be slower due to extra scheduling, - // bookkeeping and potentially false sharing of cache lines. - pkg.Syntax = make([]*ast.File, len(pkg.CompiledGoFiles)) - for i, file := range pkg.CompiledGoFiles { - f, err := parser.ParseFile(pkg.Fset, file, nil, parser.ParseComments) - if err != nil { - pkg.Errors = append(pkg.Errors, convertError(err)...) - return err - } - pkg.Syntax[i] = f - } - pkg.TypesInfo = &types.Info{ - Types: make(map[ast.Expr]types.TypeAndValue), - Defs: make(map[*ast.Ident]types.Object), - Uses: make(map[*ast.Ident]types.Object), - Implicits: make(map[ast.Node]types.Object), - Scopes: make(map[ast.Node]*types.Scope), - Selections: make(map[*ast.SelectorExpr]*types.Selection), - } - - importer := func(path string) (*types.Package, error) { - if path == "unsafe" { - return types.Unsafe, nil - } - if path == "C" { - // go/packages doesn't tell us that cgo preprocessing - // failed. When we subsequently try to parse the package, - // we'll encounter the raw C import. - return nil, errors.New("cgo preprocessing failed") - } - imp := pkg.Imports[path] - if imp == nil { - return nil, nil - } - if len(imp.Errors) > 0 { - return nil, imp.Errors[0] - } - return imp.Types, nil - } - tc := &types.Config{ - Importer: importerFunc(importer), - Error: func(err error) { - pkg.Errors = append(pkg.Errors, convertError(err)...) - }, - } - err := types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax) - if err != nil { - return err - } - pkg.IllTyped = false - return nil -} - -func convertError(err error) []packages.Error { - var errs []packages.Error - // taken from go/packages - switch err := err.(type) { - case packages.Error: - // from driver - errs = append(errs, err) - - case *os.PathError: - // from parser - errs = append(errs, packages.Error{ - Pos: err.Path + ":1", - Msg: err.Err.Error(), - Kind: packages.ParseError, - }) - - case scanner.ErrorList: - // from parser - for _, err := range err { - errs = append(errs, packages.Error{ - Pos: err.Pos.String(), - Msg: err.Msg, - Kind: packages.ParseError, - }) - } - - case types.Error: - // from type checker - errs = append(errs, packages.Error{ - Pos: err.Fset.Position(err.Pos).String(), - Msg: err.Msg, - Kind: packages.TypeError, - }) - - default: - // unexpected impoverished error from parser? - errs = append(errs, packages.Error{ - Pos: "-", - Msg: err.Error(), - Kind: packages.UnknownError, - }) - - // If you see this error message, please file a bug. - log.Printf("internal error: error %q (%T) without position", err, err) - } - return errs -} - -type importerFunc func(path string) (*types.Package, error) - -func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) } diff --git a/vendor/honnef.co/go/tools/pattern/convert.go b/vendor/honnef.co/go/tools/pattern/convert.go deleted file mode 100644 index dfcd1560d..000000000 --- a/vendor/honnef.co/go/tools/pattern/convert.go +++ /dev/null @@ -1,242 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" -) - -var astTypes = map[string]reflect.Type{ - "Ellipsis": reflect.TypeOf(ast.Ellipsis{}), - "RangeStmt": reflect.TypeOf(ast.RangeStmt{}), - "AssignStmt": reflect.TypeOf(ast.AssignStmt{}), - "IndexExpr": reflect.TypeOf(ast.IndexExpr{}), - "Ident": reflect.TypeOf(ast.Ident{}), - "ValueSpec": reflect.TypeOf(ast.ValueSpec{}), - "GenDecl": reflect.TypeOf(ast.GenDecl{}), - "BinaryExpr": reflect.TypeOf(ast.BinaryExpr{}), - "ForStmt": reflect.TypeOf(ast.ForStmt{}), - "ArrayType": reflect.TypeOf(ast.ArrayType{}), - "DeferStmt": reflect.TypeOf(ast.DeferStmt{}), - "MapType": reflect.TypeOf(ast.MapType{}), - "ReturnStmt": reflect.TypeOf(ast.ReturnStmt{}), - "SliceExpr": reflect.TypeOf(ast.SliceExpr{}), - "StarExpr": reflect.TypeOf(ast.StarExpr{}), - "UnaryExpr": reflect.TypeOf(ast.UnaryExpr{}), - "SendStmt": reflect.TypeOf(ast.SendStmt{}), - "SelectStmt": reflect.TypeOf(ast.SelectStmt{}), - "ImportSpec": reflect.TypeOf(ast.ImportSpec{}), - "IfStmt": reflect.TypeOf(ast.IfStmt{}), - "GoStmt": reflect.TypeOf(ast.GoStmt{}), - "Field": reflect.TypeOf(ast.Field{}), - "SelectorExpr": reflect.TypeOf(ast.SelectorExpr{}), - "StructType": reflect.TypeOf(ast.StructType{}), - "KeyValueExpr": reflect.TypeOf(ast.KeyValueExpr{}), - "FuncType": reflect.TypeOf(ast.FuncType{}), - "FuncLit": reflect.TypeOf(ast.FuncLit{}), - "FuncDecl": reflect.TypeOf(ast.FuncDecl{}), - "ChanType": reflect.TypeOf(ast.ChanType{}), - "CallExpr": reflect.TypeOf(ast.CallExpr{}), - "CaseClause": reflect.TypeOf(ast.CaseClause{}), - "CommClause": reflect.TypeOf(ast.CommClause{}), - "CompositeLit": reflect.TypeOf(ast.CompositeLit{}), - "EmptyStmt": reflect.TypeOf(ast.EmptyStmt{}), - "SwitchStmt": reflect.TypeOf(ast.SwitchStmt{}), - "TypeSwitchStmt": reflect.TypeOf(ast.TypeSwitchStmt{}), - "TypeAssertExpr": reflect.TypeOf(ast.TypeAssertExpr{}), - "TypeSpec": reflect.TypeOf(ast.TypeSpec{}), - "InterfaceType": reflect.TypeOf(ast.InterfaceType{}), - "BranchStmt": reflect.TypeOf(ast.BranchStmt{}), - "IncDecStmt": reflect.TypeOf(ast.IncDecStmt{}), - "BasicLit": reflect.TypeOf(ast.BasicLit{}), -} - -func ASTToNode(node interface{}) Node { - switch node := node.(type) { - case *ast.File: - panic("cannot convert *ast.File to Node") - case nil: - return Nil{} - case string: - return String(node) - case token.Token: - return Token(node) - case *ast.ExprStmt: - return ASTToNode(node.X) - case *ast.BlockStmt: - if node == nil { - return Nil{} - } - return ASTToNode(node.List) - case *ast.FieldList: - if node == nil { - return Nil{} - } - return ASTToNode(node.List) - case *ast.BasicLit: - if node == nil { - return Nil{} - } - case *ast.ParenExpr: - return ASTToNode(node.X) - } - - if node, ok := node.(ast.Node); ok { - name := reflect.TypeOf(node).Elem().Name() - T, ok := structNodes[name] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - - if reflect.ValueOf(node).IsNil() { - return Nil{} - } - v := reflect.ValueOf(node).Elem() - objs := make([]Node, T.NumField()) - for i := 0; i < T.NumField(); i++ { - f := v.FieldByName(T.Field(i).Name) - objs[i] = ASTToNode(f.Interface()) - } - - n, err := populateNode(name, objs, false) - if err != nil { - panic(fmt.Sprintf("internal error: %s", err)) - } - return n - } - - s := reflect.ValueOf(node) - if s.Kind() == reflect.Slice { - if s.Len() == 0 { - return List{} - } - if s.Len() == 1 { - return ASTToNode(s.Index(0).Interface()) - } - - tail := List{} - for i := s.Len() - 1; i >= 0; i-- { - head := ASTToNode(s.Index(i).Interface()) - l := List{ - Head: head, - Tail: tail, - } - tail = l - } - return tail - } - - panic(fmt.Sprintf("internal error: unhandled type %T", node)) -} - -func NodeToAST(node Node, state State) interface{} { - switch node := node.(type) { - case Binding: - v, ok := state[node.Name] - if !ok { - // really we want to return an error here - panic("XXX") - } - switch v := v.(type) { - case types.Object: - return &ast.Ident{Name: v.Name()} - default: - return v - } - case Builtin, Any, Object, Function, Not, Or: - panic("XXX") - case List: - if (node == List{}) { - return []ast.Node{} - } - x := []ast.Node{NodeToAST(node.Head, state).(ast.Node)} - x = append(x, NodeToAST(node.Tail, state).([]ast.Node)...) - return x - case Token: - return token.Token(node) - case String: - return string(node) - case Nil: - return nil - } - - name := reflect.TypeOf(node).Name() - T, ok := astTypes[name] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - v := reflect.ValueOf(node) - out := reflect.New(T) - for i := 0; i < T.NumField(); i++ { - fNode := v.FieldByName(T.Field(i).Name) - if (fNode == reflect.Value{}) { - continue - } - fAST := out.Elem().FieldByName(T.Field(i).Name) - switch fAST.Type().Kind() { - case reflect.Slice: - c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state)) - if c.Kind() != reflect.Slice { - // it's a single node in the pattern, we have to wrap - // it in a slice - slice := reflect.MakeSlice(fAST.Type(), 1, 1) - slice.Index(0).Set(c) - c = slice - } - switch fAST.Interface().(type) { - case []ast.Node: - switch cc := c.Interface().(type) { - case []ast.Node: - fAST.Set(c) - case []ast.Expr: - var slice []ast.Node - for _, el := range cc { - slice = append(slice, el) - } - fAST.Set(reflect.ValueOf(slice)) - default: - panic("XXX") - } - case []ast.Expr: - switch cc := c.Interface().(type) { - case []ast.Node: - var slice []ast.Expr - for _, el := range cc { - slice = append(slice, el.(ast.Expr)) - } - fAST.Set(reflect.ValueOf(slice)) - case []ast.Expr: - fAST.Set(c) - default: - panic("XXX") - } - default: - panic("XXX") - } - case reflect.Int: - c := reflect.ValueOf(NodeToAST(fNode.Interface().(Node), state)) - switch c.Kind() { - case reflect.String: - tok, ok := tokensByString[c.Interface().(string)] - if !ok { - // really we want to return an error here - panic("XXX") - } - fAST.SetInt(int64(tok)) - case reflect.Int: - fAST.Set(c) - default: - panic(fmt.Sprintf("internal error: unexpected kind %s", c.Kind())) - } - default: - r := NodeToAST(fNode.Interface().(Node), state) - if r != nil { - fAST.Set(reflect.ValueOf(r)) - } - } - } - - return out.Interface().(ast.Node) -} diff --git a/vendor/honnef.co/go/tools/pattern/doc.go b/vendor/honnef.co/go/tools/pattern/doc.go deleted file mode 100644 index 05d86c251..000000000 --- a/vendor/honnef.co/go/tools/pattern/doc.go +++ /dev/null @@ -1,273 +0,0 @@ -/* -Package pattern implements a simple language for pattern matching Go ASTs. - -Design decisions and trade-offs - -The language is designed specifically for the task of filtering ASTs -to simplify the implementation of analyses in staticcheck. -It is also intended to be trivial to parse and execute. - -To that end, we make certain decisions that make the language more -suited to its task, while making certain queries infeasible. - -Furthermore, it is fully expected that the majority of analyses will still require ordinary Go code -to further process the filtered AST, to make use of type information and to enforce complex invariants. -It is not our goal to design a scripting language for writing entire checks in. - -The language - -At its core, patterns are a representation of Go ASTs, allowing for the use of placeholders to enable pattern matching. -Their syntax is inspired by LISP and Haskell, but unlike LISP, the core unit of patterns isn't the list, but the node. -There is a fixed set of nodes, identified by name, and with the exception of the Or node, all nodes have a fixed number of arguments. -In addition to nodes, there are atoms, which represent basic units such as strings or the nil value. - -Pattern matching is implemented via bindings, represented by the Binding node. -A Binding can match nodes and associate them with names, to later recall the nodes. -This allows for expressing "this node must be equal to that node" constraints. - -To simplify writing and reading patterns, a small amount of additional syntax exists on top of nodes and atoms. -This additional syntax doesn't add any new features of its own, it simply provides shortcuts to creating nodes and atoms. - -To show an example of a pattern, first consider this snippet of Go code: - - if x := fn(); x != nil { - for _, v := range x { - println(v, x) - } - } - -The corresponding AST expressed as an idiomatic pattern would look as follows: - - (IfStmt - (AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") [])) - (BinaryExpr (Ident "x") "!=" (Ident "nil")) - (RangeStmt - (Ident "_") (Ident "v") ":=" (Ident "x") - (CallExpr (Ident "println") [(Ident "v") (Ident "x")])) - nil) - -Two things are worth noting about this representation. -First, the [el1 el2 ...] syntax is a short-hand for creating lists. -It is a short-hand for el1:el2:[], which itself is a short-hand for (List el1 (List el2 (List nil nil)). -Second, note the absence of a lot of lists in places that normally accept lists. -For example, assignment assigns a number of right-hands to a number of left-hands, yet our AssignStmt is lacking any form of list. -This is due to the fact that a single node can match a list of exactly one element. -Thus, the two following forms have identical matching behavior: - - (AssignStmt (Ident "x") ":=" (CallExpr (Ident "fn") [])) - (AssignStmt [(Ident "x")] ":=" [(CallExpr (Ident "fn") [])]) - -This section serves as an overview of the language's syntax. -More in-depth explanations of the matching behavior as well as an exhaustive list of node types follows in the coming sections. - -Pattern matching - -TODO write about pattern matching - -- inspired by haskell syntax, but much, much simpler and naive - -Node types - -The language contains two kinds of nodes: those that map to nodes in the AST, and those that implement additional logic. - -Nodes that map directly to AST nodes are named identically to the types in the go/ast package. -What follows is an exhaustive list of these nodes: - - (ArrayType len elt) - (AssignStmt lhs tok rhs) - (BasicLit kind value) - (BinaryExpr x op y) - (BranchStmt tok label) - (CallExpr fun args) - (CaseClause list body) - (ChanType dir value) - (CommClause comm body) - (CompositeLit type elts) - (DeferStmt call) - (Ellipsis elt) - (EmptyStmt) - (Field names type tag) - (ForStmt init cond post body) - (FuncDecl recv name type body) - (FuncLit type body) - (FuncType params results) - (GenDecl specs) - (GoStmt call) - (Ident name) - (IfStmt init cond body else) - (ImportSpec name path) - (IncDecStmt x tok) - (IndexExpr x index) - (InterfaceType methods) - (KeyValueExpr key value) - (MapType key value) - (RangeStmt key value tok x body) - (ReturnStmt results) - (SelectStmt body) - (SelectorExpr x sel) - (SendStmt chan value) - (SliceExpr x low high max) - (StarExpr x) - (StructType fields) - (SwitchStmt init tag body) - (TypeAssertExpr) - (TypeSpec name type) - (TypeSwitchStmt init assign body) - (UnaryExpr op x) - (ValueSpec names type values) - -Additionally, there are the String, Token and nil atoms. -Strings are double-quoted string literals, as in (Ident "someName"). -Tokens are also represented as double-quoted string literals, but are converted to token.Token values in contexts that require tokens, -such as in (BinaryExpr x "<" y), where "<" is transparently converted to token.LSS during matching. -The keyword 'nil' denotes the nil value, which represents the absence of any value. - -We also defines the (List head tail) node, which is used to represent sequences of elements as a singly linked list. -The head is a single element, and the tail is the remainder of the list. -For example, - - (List "foo" (List "bar" (List "baz" (List nil nil)))) - -represents a list of three elements, "foo", "bar" and "baz". There is dedicated syntax for writing lists, which looks as follows: - - ["foo" "bar" "baz"] - -This syntax is itself syntactic sugar for the following form: - - "foo":"bar":"baz":[] - -This form is of particular interest for pattern matching, as it allows matching on the head and tail. For example, - - "foo":"bar":_ - -would match any list with at least two elements, where the first two elements are "foo" and "bar". This is equivalent to writing - - (List "foo" (List "bar" _)) - -Note that it is not possible to match from the end of the list. -That is, there is no way to express a query such as "a list of any length where the last element is foo". - -Note that unlike in LISP, nil and empty lists are distinct from one another. -In patterns, with respect to lists, nil is akin to Go's untyped nil. -It will match a nil ast.Node, but it will not match a nil []ast.Expr. Nil will, however, match pointers to named types such as *ast.Ident. -Similarly, lists are akin to Go's -slices. An empty list will match both a nil and an empty []ast.Expr, but it will not match a nil ast.Node. - -Due to the difference between nil and empty lists, an empty list is represented as (List nil nil), i.e. a list with no head or tail. -Similarly, a list of one element is represented as (List el (List nil nil)). Unlike in LISP, it cannot be represented by (List el nil). - -Finally, there are nodes that implement special logic or matching behavior. - -(Any) matches any value. The underscore (_) maps to this node, making the following two forms equivalent: - - (Ident _) - (Ident (Any)) - -(Builtin name) matches a built-in identifier or function by name. -This is a type-aware variant of (Ident name). -Instead of only comparing the name, it resolves the object behind the name and makes sure it's a pre-declared identifier. - -For example, in the following piece of code - - func fn() { - println(true) - true := false - println(true) - } - -the pattern - - (Builtin "true") - -will match exactly once, on the first use of 'true' in the function. -Subsequent occurrences of 'true' no longer refer to the pre-declared identifier. - -(Object name) matches an identifier by name, but yields the -types.Object it refers to. - -(Function name) matches ast.Idents and ast.SelectorExprs that refer to a function with a given fully qualified name. -For example, "net/url.PathEscape" matches the PathEscape function in the net/url package, -and "(net/url.EscapeError).Error" refers to the Error method on the net/url.EscapeError type, -either on an instance of the type, or on the type itself. - -For example, the following patterns match the following lines of code: - - (CallExpr (Function "fmt.Println") _) // pattern 1 - (CallExpr (Function "(net/url.EscapeError).Error") _) // pattern 2 - - fmt.Println("hello, world") // matches pattern 1 - var x url.EscapeError - x.Error() // matches pattern 2 - (url.EscapeError).Error(x) // also matches pattern 2 - -(Binding name node) creates or uses a binding. -Bindings work like variable assignments, allowing referring to already matched nodes. -As an example, bindings are necessary to match self-assignment of the form "x = x", -since we need to express that the right-hand side is identical to the left-hand side. - -If a binding's node is not nil, the matcher will attempt to match a node according to the pattern. -If a binding's node is nil, the binding will either recall an existing value, or match the Any node. -It is an error to provide a non-nil node to a binding that has already been bound. - -Referring back to the earlier example, the following pattern will match self-assignment of idents: - - (AssignStmt (Binding "lhs" (Ident _)) "=" (Binding "lhs" nil)) - -Because bindings are a crucial component of pattern matching, there is special syntax for creating and recalling bindings. -Lower-case names refer to bindings. If standing on its own, the name "foo" will be equivalent to (Binding "foo" nil). -If a name is followed by an at-sign (@) then it will create a binding for the node that follows. -Together, this allows us to rewrite the earlier example as follows: - - (AssignStmt lhs@(Ident _) "=" lhs) - -(Or nodes...) is a variadic node that tries matching each node until one succeeds. For example, the following pattern matches all idents of name "foo" or "bar": - - (Ident (Or "foo" "bar")) - -We could also have written - - (Or (Ident "foo") (Ident "bar")) - -and achieved the same result. We can also mix different kinds of nodes: - - (Or (Ident "foo") (CallExpr (Ident "bar") _)) - -When using bindings inside of nodes used inside Or, all or none of the bindings will be bound. -That is, partially matched nodes that ultimately failed to match will not produce any bindings observable outside of the matching attempt. -We can thus write - - (Or (Ident name) (CallExpr name)) - -and 'name' will either be a String if the first option matched, or an Ident or SelectorExpr if the second option matched. - -(Not node) - -The Not node negates a match. For example, (Not (Ident _)) will match all nodes that aren't identifiers. - -ChanDir(0) - -Automatic unnesting of AST nodes - -The Go AST has several types of nodes that wrap other nodes. -To simplify matching, we automatically unwrap some of these nodes. - -These nodes are ExprStmt (for using expressions in a statement context), -ParenExpr (for parenthesized expressions), -DeclStmt (for declarations in a statement context), -and LabeledStmt (for labeled statements). - -Thus, the query - - (FuncLit _ [(CallExpr _ _)] - -will match a function literal containing a single function call, -even though in the actual Go AST, the CallExpr is nested inside an ExprStmt, -as function bodies are made up of sequences of statements. - -On the flip-side, there is no way to specifically match these wrapper nodes. -For example, there is no way of searching for unnecessary parentheses, like in the following piece of Go code: - - ((x)) += 2 - -*/ -package pattern diff --git a/vendor/honnef.co/go/tools/pattern/fuzz.go b/vendor/honnef.co/go/tools/pattern/fuzz.go deleted file mode 100644 index 52e7df974..000000000 --- a/vendor/honnef.co/go/tools/pattern/fuzz.go +++ /dev/null @@ -1,50 +0,0 @@ -// +build gofuzz - -package pattern - -import ( - "go/ast" - goparser "go/parser" - "go/token" - "os" - "path/filepath" - "strings" -) - -var files []*ast.File - -func init() { - fset := token.NewFileSet() - filepath.Walk("/usr/lib/go/src", func(path string, info os.FileInfo, err error) error { - if err != nil { - // XXX error handling - panic(err) - } - if !strings.HasSuffix(path, ".go") { - return nil - } - f, err := goparser.ParseFile(fset, path, nil, 0) - if err != nil { - return nil - } - files = append(files, f) - return nil - }) -} - -func Fuzz(data []byte) int { - p := &Parser{} - pat, err := p.Parse(string(data)) - if err != nil { - if strings.Contains(err.Error(), "internal error") { - panic(err) - } - return 0 - } - _ = pat.Root.String() - - for _, f := range files { - Match(pat.Root, f) - } - return 1 -} diff --git a/vendor/honnef.co/go/tools/pattern/lexer.go b/vendor/honnef.co/go/tools/pattern/lexer.go deleted file mode 100644 index fb72e392b..000000000 --- a/vendor/honnef.co/go/tools/pattern/lexer.go +++ /dev/null @@ -1,221 +0,0 @@ -package pattern - -import ( - "fmt" - "go/token" - "unicode" - "unicode/utf8" -) - -type lexer struct { - f *token.File - - input string - start int - pos int - width int - items chan item -} - -type itemType int - -const eof = -1 - -const ( - itemError itemType = iota - itemLeftParen - itemRightParen - itemLeftBracket - itemRightBracket - itemTypeName - itemVariable - itemAt - itemColon - itemBlank - itemString - itemEOF -) - -func (typ itemType) String() string { - switch typ { - case itemError: - return "ERROR" - case itemLeftParen: - return "(" - case itemRightParen: - return ")" - case itemLeftBracket: - return "[" - case itemRightBracket: - return "]" - case itemTypeName: - return "TYPE" - case itemVariable: - return "VAR" - case itemAt: - return "@" - case itemColon: - return ":" - case itemBlank: - return "_" - case itemString: - return "STRING" - case itemEOF: - return "EOF" - default: - return fmt.Sprintf("itemType(%d)", typ) - } -} - -type item struct { - typ itemType - val string - pos int -} - -type stateFn func(*lexer) stateFn - -func (l *lexer) run() { - for state := lexStart; state != nil; { - state = state(l) - } - close(l.items) -} - -func (l *lexer) emitValue(t itemType, value string) { - l.items <- item{t, value, l.start} - l.start = l.pos -} - -func (l *lexer) emit(t itemType) { - l.items <- item{t, l.input[l.start:l.pos], l.start} - l.start = l.pos -} - -func lexStart(l *lexer) stateFn { - switch r := l.next(); { - case r == eof: - l.emit(itemEOF) - return nil - case unicode.IsSpace(r): - l.ignore() - case r == '(': - l.emit(itemLeftParen) - case r == ')': - l.emit(itemRightParen) - case r == '[': - l.emit(itemLeftBracket) - case r == ']': - l.emit(itemRightBracket) - case r == '@': - l.emit(itemAt) - case r == ':': - l.emit(itemColon) - case r == '_': - l.emit(itemBlank) - case r == '"': - l.backup() - return lexString - case unicode.IsUpper(r): - l.backup() - return lexType - case unicode.IsLower(r): - l.backup() - return lexVariable - default: - return l.errorf("unexpected character %c", r) - } - return lexStart -} - -func (l *lexer) next() (r rune) { - if l.pos >= len(l.input) { - l.width = 0 - return eof - } - r, l.width = utf8.DecodeRuneInString(l.input[l.pos:]) - - if r == '\n' { - l.f.AddLine(l.pos) - } - - l.pos += l.width - - return r -} - -func (l *lexer) ignore() { - l.start = l.pos -} - -func (l *lexer) backup() { - l.pos -= l.width -} - -func (l *lexer) errorf(format string, args ...interface{}) stateFn { - // TODO(dh): emit position information in errors - l.items <- item{ - itemError, - fmt.Sprintf(format, args...), - l.start, - } - return nil -} - -func isAlphaNumeric(r rune) bool { - return r >= '0' && r <= '9' || - r >= 'a' && r <= 'z' || - r >= 'A' && r <= 'Z' -} - -func lexString(l *lexer) stateFn { - l.next() // skip quote - escape := false - - var runes []rune - for { - switch r := l.next(); r { - case eof: - return l.errorf("unterminated string") - case '"': - if !escape { - l.emitValue(itemString, string(runes)) - return lexStart - } else { - runes = append(runes, '"') - escape = false - } - case '\\': - if escape { - runes = append(runes, '\\') - escape = false - } else { - escape = true - } - default: - runes = append(runes, r) - } - } -} - -func lexType(l *lexer) stateFn { - l.next() - for { - if !isAlphaNumeric(l.next()) { - l.backup() - l.emit(itemTypeName) - return lexStart - } - } -} - -func lexVariable(l *lexer) stateFn { - l.next() - for { - if !isAlphaNumeric(l.next()) { - l.backup() - l.emit(itemVariable) - return lexStart - } - } -} diff --git a/vendor/honnef.co/go/tools/pattern/match.go b/vendor/honnef.co/go/tools/pattern/match.go deleted file mode 100644 index ff039baa7..000000000 --- a/vendor/honnef.co/go/tools/pattern/match.go +++ /dev/null @@ -1,513 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "go/types" - "reflect" - - "honnef.co/go/tools/lint" -) - -var tokensByString = map[string]Token{ - "INT": Token(token.INT), - "FLOAT": Token(token.FLOAT), - "IMAG": Token(token.IMAG), - "CHAR": Token(token.CHAR), - "STRING": Token(token.STRING), - "+": Token(token.ADD), - "-": Token(token.SUB), - "*": Token(token.MUL), - "/": Token(token.QUO), - "%": Token(token.REM), - "&": Token(token.AND), - "|": Token(token.OR), - "^": Token(token.XOR), - "<<": Token(token.SHL), - ">>": Token(token.SHR), - "&^": Token(token.AND_NOT), - "+=": Token(token.ADD_ASSIGN), - "-=": Token(token.SUB_ASSIGN), - "*=": Token(token.MUL_ASSIGN), - "/=": Token(token.QUO_ASSIGN), - "%=": Token(token.REM_ASSIGN), - "&=": Token(token.AND_ASSIGN), - "|=": Token(token.OR_ASSIGN), - "^=": Token(token.XOR_ASSIGN), - "<<=": Token(token.SHL_ASSIGN), - ">>=": Token(token.SHR_ASSIGN), - "&^=": Token(token.AND_NOT_ASSIGN), - "&&": Token(token.LAND), - "||": Token(token.LOR), - "<-": Token(token.ARROW), - "++": Token(token.INC), - "--": Token(token.DEC), - "==": Token(token.EQL), - "<": Token(token.LSS), - ">": Token(token.GTR), - "=": Token(token.ASSIGN), - "!": Token(token.NOT), - "!=": Token(token.NEQ), - "<=": Token(token.LEQ), - ">=": Token(token.GEQ), - ":=": Token(token.DEFINE), - "...": Token(token.ELLIPSIS), - "IMPORT": Token(token.IMPORT), - "VAR": Token(token.VAR), - "TYPE": Token(token.TYPE), - "CONST": Token(token.CONST), -} - -func maybeToken(node Node) (Node, bool) { - if node, ok := node.(String); ok { - if tok, ok := tokensByString[string(node)]; ok { - return tok, true - } - return node, false - } - return node, false -} - -func isNil(v interface{}) bool { - if v == nil { - return true - } - if _, ok := v.(Nil); ok { - return true - } - return false -} - -type matcher interface { - Match(*Matcher, interface{}) (interface{}, bool) -} - -type State = map[string]interface{} - -type Matcher struct { - TypesInfo *types.Info - State State -} - -func (m *Matcher) fork() *Matcher { - state := make(State, len(m.State)) - for k, v := range m.State { - state[k] = v - } - return &Matcher{ - TypesInfo: m.TypesInfo, - State: state, - } -} - -func (m *Matcher) merge(mc *Matcher) { - m.State = mc.State -} - -func (m *Matcher) Match(a Node, b ast.Node) bool { - m.State = State{} - _, ok := match(m, a, b) - return ok -} - -func Match(a Node, b ast.Node) (*Matcher, bool) { - m := &Matcher{} - ret := m.Match(a, b) - return m, ret -} - -// Match two items, which may be (Node, AST) or (AST, AST) -func match(m *Matcher, l, r interface{}) (interface{}, bool) { - if _, ok := r.(Node); ok { - panic("Node mustn't be on right side of match") - } - - switch l := l.(type) { - case *ast.ParenExpr: - return match(m, l.X, r) - case *ast.ExprStmt: - return match(m, l.X, r) - case *ast.DeclStmt: - return match(m, l.Decl, r) - case *ast.LabeledStmt: - return match(m, l.Stmt, r) - case *ast.BlockStmt: - return match(m, l.List, r) - case *ast.FieldList: - return match(m, l.List, r) - } - - switch r := r.(type) { - case *ast.ParenExpr: - return match(m, l, r.X) - case *ast.ExprStmt: - return match(m, l, r.X) - case *ast.DeclStmt: - return match(m, l, r.Decl) - case *ast.LabeledStmt: - return match(m, l, r.Stmt) - case *ast.BlockStmt: - if r == nil { - return match(m, l, nil) - } - return match(m, l, r.List) - case *ast.FieldList: - if r == nil { - return match(m, l, nil) - } - return match(m, l, r.List) - case *ast.BasicLit: - if r == nil { - return match(m, l, nil) - } - } - - if l, ok := l.(matcher); ok { - return l.Match(m, r) - } - - if l, ok := l.(Node); ok { - // Matching of pattern with concrete value - return matchNodeAST(m, l, r) - } - - if l == nil || r == nil { - return nil, l == r - } - - { - ln, ok1 := l.(ast.Node) - rn, ok2 := r.(ast.Node) - if ok1 && ok2 { - return matchAST(m, ln, rn) - } - } - - { - obj, ok := l.(types.Object) - if ok { - switch r := r.(type) { - case *ast.Ident: - return obj, obj == m.TypesInfo.ObjectOf(r) - case *ast.SelectorExpr: - return obj, obj == m.TypesInfo.ObjectOf(r.Sel) - default: - return obj, false - } - } - } - - { - ln, ok1 := l.([]ast.Expr) - rn, ok2 := r.([]ast.Expr) - if ok1 || ok2 { - if ok1 && !ok2 { - rn = []ast.Expr{r.(ast.Expr)} - } else if !ok1 && ok2 { - ln = []ast.Expr{l.(ast.Expr)} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - { - ln, ok1 := l.([]ast.Stmt) - rn, ok2 := r.([]ast.Stmt) - if ok1 || ok2 { - if ok1 && !ok2 { - rn = []ast.Stmt{r.(ast.Stmt)} - } else if !ok1 && ok2 { - ln = []ast.Stmt{l.(ast.Stmt)} - } - - if len(ln) != len(rn) { - return nil, false - } - for i, ll := range ln { - if _, ok := match(m, ll, rn[i]); !ok { - return nil, false - } - } - return r, true - } - } - - panic(fmt.Sprintf("unsupported comparison: %T and %T", l, r)) -} - -// Match a Node with an AST node -func matchNodeAST(m *Matcher, a Node, b interface{}) (interface{}, bool) { - switch b := b.(type) { - case []ast.Stmt: - // 'a' is not a List or we'd be using its Match - // implementation. - - if len(b) != 1 { - return nil, false - } - return match(m, a, b[0]) - case []ast.Expr: - // 'a' is not a List or we'd be using its Match - // implementation. - - if len(b) != 1 { - return nil, false - } - return match(m, a, b[0]) - case ast.Node: - ra := reflect.ValueOf(a) - rb := reflect.ValueOf(b).Elem() - - if ra.Type().Name() != rb.Type().Name() { - return nil, false - } - - for i := 0; i < ra.NumField(); i++ { - af := ra.Field(i) - fieldName := ra.Type().Field(i).Name - bf := rb.FieldByName(fieldName) - if (bf == reflect.Value{}) { - panic(fmt.Sprintf("internal error: could not find field %s in type %t when comparing with %T", fieldName, b, a)) - } - ai := af.Interface() - bi := bf.Interface() - if ai == nil { - return b, bi == nil - } - if _, ok := match(m, ai.(Node), bi); !ok { - return b, false - } - } - return b, true - case nil: - return nil, a == Nil{} - default: - panic(fmt.Sprintf("unhandled type %T", b)) - } -} - -// Match two AST nodes -func matchAST(m *Matcher, a, b ast.Node) (interface{}, bool) { - ra := reflect.ValueOf(a) - rb := reflect.ValueOf(b) - - if ra.Type() != rb.Type() { - return nil, false - } - if ra.IsNil() || rb.IsNil() { - return rb, ra.IsNil() == rb.IsNil() - } - - ra = ra.Elem() - rb = rb.Elem() - for i := 0; i < ra.NumField(); i++ { - af := ra.Field(i) - bf := rb.Field(i) - if af.Type() == rtTokPos || af.Type() == rtObject || af.Type() == rtCommentGroup { - continue - } - - switch af.Kind() { - case reflect.Slice: - if af.Len() != bf.Len() { - return nil, false - } - for j := 0; j < af.Len(); j++ { - if _, ok := match(m, af.Index(j).Interface().(ast.Node), bf.Index(j).Interface().(ast.Node)); !ok { - return nil, false - } - } - case reflect.String: - if af.String() != bf.String() { - return nil, false - } - case reflect.Int: - if af.Int() != bf.Int() { - return nil, false - } - case reflect.Bool: - if af.Bool() != bf.Bool() { - return nil, false - } - case reflect.Ptr, reflect.Interface: - if _, ok := match(m, af.Interface(), bf.Interface()); !ok { - return nil, false - } - default: - panic(fmt.Sprintf("internal error: unhandled kind %s (%T)", af.Kind(), af.Interface())) - } - } - return b, true -} - -func (b Binding) Match(m *Matcher, node interface{}) (interface{}, bool) { - if isNil(b.Node) { - v, ok := m.State[b.Name] - if ok { - // Recall value - return match(m, v, node) - } - // Matching anything - b.Node = Any{} - } - - // Store value - if _, ok := m.State[b.Name]; ok { - panic(fmt.Sprintf("binding already created: %s", b.Name)) - } - new, ret := match(m, b.Node, node) - if ret { - m.State[b.Name] = new - } - return new, ret -} - -func (Any) Match(m *Matcher, node interface{}) (interface{}, bool) { - return node, true -} - -func (l List) Match(m *Matcher, node interface{}) (interface{}, bool) { - v := reflect.ValueOf(node) - if v.Kind() == reflect.Slice { - if isNil(l.Head) { - return node, v.Len() == 0 - } - if v.Len() == 0 { - return nil, false - } - // OPT(dh): don't check the entire tail if head didn't match - _, ok1 := match(m, l.Head, v.Index(0).Interface()) - _, ok2 := match(m, l.Tail, v.Slice(1, v.Len()).Interface()) - return node, ok1 && ok2 - } - // Our empty list does not equal an untyped Go nil. This way, we can - // tell apart an if with no else and an if with an empty else. - return nil, false -} - -func (s String) Match(m *Matcher, node interface{}) (interface{}, bool) { - switch o := node.(type) { - case token.Token: - if tok, ok := maybeToken(s); ok { - return match(m, tok, node) - } - return nil, false - case string: - return o, string(s) == o - default: - return nil, false - } -} - -func (tok Token) Match(m *Matcher, node interface{}) (interface{}, bool) { - o, ok := node.(token.Token) - if !ok { - return nil, false - } - return o, token.Token(tok) == o -} - -func (Nil) Match(m *Matcher, node interface{}) (interface{}, bool) { - return nil, isNil(node) -} - -func (builtin Builtin) Match(m *Matcher, node interface{}) (interface{}, bool) { - ident, ok := node.(*ast.Ident) - if !ok { - return nil, false - } - obj := m.TypesInfo.ObjectOf(ident) - if obj != types.Universe.Lookup(ident.Name) { - return nil, false - } - return match(m, builtin.Name, ident.Name) -} - -func (obj Object) Match(m *Matcher, node interface{}) (interface{}, bool) { - ident, ok := node.(*ast.Ident) - if !ok { - return nil, false - } - - id := m.TypesInfo.ObjectOf(ident) - _, ok = match(m, obj.Name, ident.Name) - return id, ok -} - -func (fn Function) Match(m *Matcher, node interface{}) (interface{}, bool) { - var name string - var obj types.Object - switch node := node.(type) { - case *ast.Ident: - obj = m.TypesInfo.ObjectOf(node) - switch obj := obj.(type) { - case *types.Func: - name = lint.FuncName(obj) - case *types.Builtin: - name = obj.Name() - default: - return nil, false - } - case *ast.SelectorExpr: - var ok bool - obj, ok = m.TypesInfo.ObjectOf(node.Sel).(*types.Func) - if !ok { - return nil, false - } - name = lint.FuncName(obj.(*types.Func)) - default: - return nil, false - } - _, ok := match(m, fn.Name, name) - return obj, ok -} - -func (or Or) Match(m *Matcher, node interface{}) (interface{}, bool) { - for _, opt := range or.Nodes { - mc := m.fork() - if ret, ok := match(mc, opt, node); ok { - m.merge(mc) - return ret, true - } - } - return nil, false -} - -func (not Not) Match(m *Matcher, node interface{}) (interface{}, bool) { - _, ok := match(m, not.Node, node) - if ok { - return nil, false - } - return node, true -} - -var ( - // Types of fields in go/ast structs that we want to skip - rtTokPos = reflect.TypeOf(token.Pos(0)) - rtObject = reflect.TypeOf((*ast.Object)(nil)) - rtCommentGroup = reflect.TypeOf((*ast.CommentGroup)(nil)) -) - -var ( - _ matcher = Binding{} - _ matcher = Any{} - _ matcher = List{} - _ matcher = String("") - _ matcher = Token(0) - _ matcher = Nil{} - _ matcher = Builtin{} - _ matcher = Object{} - _ matcher = Function{} - _ matcher = Or{} - _ matcher = Not{} -) diff --git a/vendor/honnef.co/go/tools/pattern/parser.go b/vendor/honnef.co/go/tools/pattern/parser.go deleted file mode 100644 index 009238b86..000000000 --- a/vendor/honnef.co/go/tools/pattern/parser.go +++ /dev/null @@ -1,455 +0,0 @@ -package pattern - -import ( - "fmt" - "go/ast" - "go/token" - "reflect" -) - -type Pattern struct { - Root Node - // Relevant contains instances of ast.Node that could potentially - // initiate a successful match of the pattern. - Relevant []reflect.Type -} - -func MustParse(s string) Pattern { - p := &Parser{AllowTypeInfo: true} - pat, err := p.Parse(s) - if err != nil { - panic(err) - } - return pat -} - -func roots(node Node) []reflect.Type { - switch node := node.(type) { - case Or: - var out []reflect.Type - for _, el := range node.Nodes { - out = append(out, roots(el)...) - } - return out - case Not: - return roots(node.Node) - case Binding: - return roots(node.Node) - case Nil, nil: - // this branch is reached via bindings - return allTypes - default: - Ts, ok := nodeToASTTypes[reflect.TypeOf(node)] - if !ok { - panic(fmt.Sprintf("internal error: unhandled type %T", node)) - } - return Ts - } -} - -var allTypes = []reflect.Type{ - reflect.TypeOf((*ast.RangeStmt)(nil)), - reflect.TypeOf((*ast.AssignStmt)(nil)), - reflect.TypeOf((*ast.IndexExpr)(nil)), - reflect.TypeOf((*ast.Ident)(nil)), - reflect.TypeOf((*ast.ValueSpec)(nil)), - reflect.TypeOf((*ast.GenDecl)(nil)), - reflect.TypeOf((*ast.BinaryExpr)(nil)), - reflect.TypeOf((*ast.ForStmt)(nil)), - reflect.TypeOf((*ast.ArrayType)(nil)), - reflect.TypeOf((*ast.DeferStmt)(nil)), - reflect.TypeOf((*ast.MapType)(nil)), - reflect.TypeOf((*ast.ReturnStmt)(nil)), - reflect.TypeOf((*ast.SliceExpr)(nil)), - reflect.TypeOf((*ast.StarExpr)(nil)), - reflect.TypeOf((*ast.UnaryExpr)(nil)), - reflect.TypeOf((*ast.SendStmt)(nil)), - reflect.TypeOf((*ast.SelectStmt)(nil)), - reflect.TypeOf((*ast.ImportSpec)(nil)), - reflect.TypeOf((*ast.IfStmt)(nil)), - reflect.TypeOf((*ast.GoStmt)(nil)), - reflect.TypeOf((*ast.Field)(nil)), - reflect.TypeOf((*ast.SelectorExpr)(nil)), - reflect.TypeOf((*ast.StructType)(nil)), - reflect.TypeOf((*ast.KeyValueExpr)(nil)), - reflect.TypeOf((*ast.FuncType)(nil)), - reflect.TypeOf((*ast.FuncLit)(nil)), - reflect.TypeOf((*ast.FuncDecl)(nil)), - reflect.TypeOf((*ast.ChanType)(nil)), - reflect.TypeOf((*ast.CallExpr)(nil)), - reflect.TypeOf((*ast.CaseClause)(nil)), - reflect.TypeOf((*ast.CommClause)(nil)), - reflect.TypeOf((*ast.CompositeLit)(nil)), - reflect.TypeOf((*ast.EmptyStmt)(nil)), - reflect.TypeOf((*ast.SwitchStmt)(nil)), - reflect.TypeOf((*ast.TypeSwitchStmt)(nil)), - reflect.TypeOf((*ast.TypeAssertExpr)(nil)), - reflect.TypeOf((*ast.TypeSpec)(nil)), - reflect.TypeOf((*ast.InterfaceType)(nil)), - reflect.TypeOf((*ast.BranchStmt)(nil)), - reflect.TypeOf((*ast.IncDecStmt)(nil)), - reflect.TypeOf((*ast.BasicLit)(nil)), -} - -var nodeToASTTypes = map[reflect.Type][]reflect.Type{ - reflect.TypeOf(String("")): nil, - reflect.TypeOf(Token(0)): nil, - reflect.TypeOf(List{}): {reflect.TypeOf((*ast.BlockStmt)(nil)), reflect.TypeOf((*ast.FieldList)(nil))}, - reflect.TypeOf(Builtin{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(Object{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(Function{}): {reflect.TypeOf((*ast.Ident)(nil)), reflect.TypeOf((*ast.SelectorExpr)(nil))}, - reflect.TypeOf(Any{}): allTypes, - reflect.TypeOf(RangeStmt{}): {reflect.TypeOf((*ast.RangeStmt)(nil))}, - reflect.TypeOf(AssignStmt{}): {reflect.TypeOf((*ast.AssignStmt)(nil))}, - reflect.TypeOf(IndexExpr{}): {reflect.TypeOf((*ast.IndexExpr)(nil))}, - reflect.TypeOf(Ident{}): {reflect.TypeOf((*ast.Ident)(nil))}, - reflect.TypeOf(ValueSpec{}): {reflect.TypeOf((*ast.ValueSpec)(nil))}, - reflect.TypeOf(GenDecl{}): {reflect.TypeOf((*ast.GenDecl)(nil))}, - reflect.TypeOf(BinaryExpr{}): {reflect.TypeOf((*ast.BinaryExpr)(nil))}, - reflect.TypeOf(ForStmt{}): {reflect.TypeOf((*ast.ForStmt)(nil))}, - reflect.TypeOf(ArrayType{}): {reflect.TypeOf((*ast.ArrayType)(nil))}, - reflect.TypeOf(DeferStmt{}): {reflect.TypeOf((*ast.DeferStmt)(nil))}, - reflect.TypeOf(MapType{}): {reflect.TypeOf((*ast.MapType)(nil))}, - reflect.TypeOf(ReturnStmt{}): {reflect.TypeOf((*ast.ReturnStmt)(nil))}, - reflect.TypeOf(SliceExpr{}): {reflect.TypeOf((*ast.SliceExpr)(nil))}, - reflect.TypeOf(StarExpr{}): {reflect.TypeOf((*ast.StarExpr)(nil))}, - reflect.TypeOf(UnaryExpr{}): {reflect.TypeOf((*ast.UnaryExpr)(nil))}, - reflect.TypeOf(SendStmt{}): {reflect.TypeOf((*ast.SendStmt)(nil))}, - reflect.TypeOf(SelectStmt{}): {reflect.TypeOf((*ast.SelectStmt)(nil))}, - reflect.TypeOf(ImportSpec{}): {reflect.TypeOf((*ast.ImportSpec)(nil))}, - reflect.TypeOf(IfStmt{}): {reflect.TypeOf((*ast.IfStmt)(nil))}, - reflect.TypeOf(GoStmt{}): {reflect.TypeOf((*ast.GoStmt)(nil))}, - reflect.TypeOf(Field{}): {reflect.TypeOf((*ast.Field)(nil))}, - reflect.TypeOf(SelectorExpr{}): {reflect.TypeOf((*ast.SelectorExpr)(nil))}, - reflect.TypeOf(StructType{}): {reflect.TypeOf((*ast.StructType)(nil))}, - reflect.TypeOf(KeyValueExpr{}): {reflect.TypeOf((*ast.KeyValueExpr)(nil))}, - reflect.TypeOf(FuncType{}): {reflect.TypeOf((*ast.FuncType)(nil))}, - reflect.TypeOf(FuncLit{}): {reflect.TypeOf((*ast.FuncLit)(nil))}, - reflect.TypeOf(FuncDecl{}): {reflect.TypeOf((*ast.FuncDecl)(nil))}, - reflect.TypeOf(ChanType{}): {reflect.TypeOf((*ast.ChanType)(nil))}, - reflect.TypeOf(CallExpr{}): {reflect.TypeOf((*ast.CallExpr)(nil))}, - reflect.TypeOf(CaseClause{}): {reflect.TypeOf((*ast.CaseClause)(nil))}, - reflect.TypeOf(CommClause{}): {reflect.TypeOf((*ast.CommClause)(nil))}, - reflect.TypeOf(CompositeLit{}): {reflect.TypeOf((*ast.CompositeLit)(nil))}, - reflect.TypeOf(EmptyStmt{}): {reflect.TypeOf((*ast.EmptyStmt)(nil))}, - reflect.TypeOf(SwitchStmt{}): {reflect.TypeOf((*ast.SwitchStmt)(nil))}, - reflect.TypeOf(TypeSwitchStmt{}): {reflect.TypeOf((*ast.TypeSwitchStmt)(nil))}, - reflect.TypeOf(TypeAssertExpr{}): {reflect.TypeOf((*ast.TypeAssertExpr)(nil))}, - reflect.TypeOf(TypeSpec{}): {reflect.TypeOf((*ast.TypeSpec)(nil))}, - reflect.TypeOf(InterfaceType{}): {reflect.TypeOf((*ast.InterfaceType)(nil))}, - reflect.TypeOf(BranchStmt{}): {reflect.TypeOf((*ast.BranchStmt)(nil))}, - reflect.TypeOf(IncDecStmt{}): {reflect.TypeOf((*ast.IncDecStmt)(nil))}, - reflect.TypeOf(BasicLit{}): {reflect.TypeOf((*ast.BasicLit)(nil))}, -} - -var requiresTypeInfo = map[string]bool{ - "Function": true, - "Builtin": true, - "Object": true, -} - -type Parser struct { - // Allow nodes that rely on type information - AllowTypeInfo bool - - lex *lexer - cur item - last *item - items chan item -} - -func (p *Parser) Parse(s string) (Pattern, error) { - p.cur = item{} - p.last = nil - p.items = nil - - fset := token.NewFileSet() - p.lex = &lexer{ - f: fset.AddFile("