diff --git a/charts/stash-elasticsearch/Chart.yaml b/charts/stash-elasticsearch/Chart.yaml
index 60d4de15c..25dfe18de 100644
--- a/charts/stash-elasticsearch/Chart.yaml
+++ b/charts/stash-elasticsearch/Chart.yaml
@@ -1,8 +1,8 @@
apiVersion: v1
description: 'stash-elasticsearch - Elasticsearch database plugin for Stash by AppsCode'
name: stash-elasticsearch
-version: 7.3.2-v2
-appVersion: 7.3.2-v2
+version: 7.3.2-v3
+appVersion: 7.3.2-v3
home: https://stash.run
icon: https://cdn.appscode.com/images/products/stash/addons/elasticsearch-stash-addon.png
sources:
diff --git a/charts/stash-elasticsearch/README.md b/charts/stash-elasticsearch/README.md
index 297759c64..129004e5e 100644
--- a/charts/stash-elasticsearch/README.md
+++ b/charts/stash-elasticsearch/README.md
@@ -7,7 +7,7 @@
```console
$ helm repo add appscode https://charts.appscode.com/stable/
$ helm repo update
-$ helm install stash-elasticsearch-7.3.2-v2 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v2
+$ helm install stash-elasticsearch-7.3.2-v3 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v3
```
## Introduction
@@ -20,10 +20,10 @@ This chart deploys necessary `Function` and `Task` definition to backup or resto
## Installing the Chart
-To install the chart with the release name `stash-elasticsearch-7.3.2-v2`:
+To install the chart with the release name `stash-elasticsearch-7.3.2-v3`:
```console
-$ helm install stash-elasticsearch-7.3.2-v2 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v2
+$ helm install stash-elasticsearch-7.3.2-v3 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v3
```
The command deploys necessary `Function` and `Task` definition to backup or restore Elasticsearch 7.3.2 using Stash on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
@@ -32,10 +32,10 @@ The command deploys necessary `Function` and `Task` definition to backup or rest
## Uninstalling the Chart
-To uninstall/delete the `stash-elasticsearch-7.3.2-v2`:
+To uninstall/delete the `stash-elasticsearch-7.3.2-v3`:
```console
-$ helm delete stash-elasticsearch-7.3.2-v2 -n kube-system
+$ helm delete stash-elasticsearch-7.3.2-v3 -n kube-system
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
@@ -50,7 +50,7 @@ The following table lists the configurable parameters of the `stash-elasticsearc
| fullnameOverride | Overrides fullname template | `""` |
| image.registry | Docker registry used to pull Elasticsearch addon image | `stashed` |
| image.repository | Docker image used to backup/restore Elasticsearch database | `stash-elasticsearch` |
-| image.tag | Tag of the image that is used to backup/restore Elasticsearch database. This is usually same as the database version it can backup. | `7.3.2-v2` |
+| image.tag | Tag of the image that is used to backup/restore Elasticsearch database. This is usually same as the database version it can backup. | `7.3.2-v3` |
| backup.args | Arguments to pass to `multielasticdump` command during backup process | `""` |
| restore.args | Arguments to pass to `multielasticdump` command during restore process | `""` |
| waitTimeout | Number of seconds to wait for the database to be ready before backup/restore process. | `300` |
@@ -59,12 +59,12 @@ The following table lists the configurable parameters of the `stash-elasticsearc
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example:
```console
-$ helm install stash-elasticsearch-7.3.2-v2 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v2 --set image.registry=stashed
+$ helm install stash-elasticsearch-7.3.2-v3 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v3 --set image.registry=stashed
```
Alternatively, a YAML file that specifies the values for the parameters can be provided while
installing the chart. For example:
```console
-$ helm install stash-elasticsearch-7.3.2-v2 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v2 --values values.yaml
+$ helm install stash-elasticsearch-7.3.2-v3 appscode/stash-elasticsearch -n kube-system --version=7.3.2-v3 --values values.yaml
```
diff --git a/charts/stash-elasticsearch/doc.yaml b/charts/stash-elasticsearch/doc.yaml
index fbcb481c3..3d6df7233 100644
--- a/charts/stash-elasticsearch/doc.yaml
+++ b/charts/stash-elasticsearch/doc.yaml
@@ -10,11 +10,11 @@ repository:
name: appscode
chart:
name: stash-elasticsearch
- version: 7.3.2-v2
+ version: 7.3.2-v3
values: "-- generate from values file --"
valuesExample: "-- generate from values file --"
prerequisites:
- Kubernetes 1.11+
release:
- name: stash-elasticsearch-7.3.2-v2
+ name: stash-elasticsearch-7.3.2-v3
namespace: kube-system
diff --git a/charts/stash-elasticsearch/values.yaml b/charts/stash-elasticsearch/values.yaml
index 06fd39c06..11201bf2c 100644
--- a/charts/stash-elasticsearch/values.yaml
+++ b/charts/stash-elasticsearch/values.yaml
@@ -13,7 +13,7 @@ image:
repository: stash-elasticsearch
# Tag of the image that is used to backup/restore Elasticsearch database.
# This is usually same as the database version it can backup.
- tag: 7.3.2-v2
+ tag: 7.3.2-v3
# optional argument to send multielasticdump
backup:
# Arguments to pass to `multielasticdump` command during backup process
diff --git a/docs/examples/backup/backupconfiguration.yaml b/docs/examples/backup/backupconfiguration.yaml
index 24a7ef689..9112fc9da 100644
--- a/docs/examples/backup/backupconfiguration.yaml
+++ b/docs/examples/backup/backupconfiguration.yaml
@@ -6,7 +6,7 @@ metadata:
spec:
schedule: "*/5 * * * *"
task:
- name: elasticsearch-backup-7.3.2-v2
+ name: elasticsearch-backup-7.3.2-v3
repository:
name: gcs-repo
target:
diff --git a/docs/examples/restore/restoresession.yaml b/docs/examples/restore/restoresession.yaml
index b31a70890..f5926a0cc 100644
--- a/docs/examples/restore/restoresession.yaml
+++ b/docs/examples/restore/restoresession.yaml
@@ -7,7 +7,7 @@ metadata:
kubedb.com/kind: Elasticsearch # this label is mandatory if you are using KubeDB to deploy the database. Otherwise, Elasticsearch crd will be stuck in `Initializing` phase.
spec:
task:
- name: elasticsearch-restore-7.3.2-v2
+ name: elasticsearch-restore-7.3.2-v3
repository:
name: gcs-repo
target:
diff --git a/go.mod b/go.mod
index af92aa42c..0aeb067f6 100644
--- a/go.mod
+++ b/go.mod
@@ -21,7 +21,7 @@ require (
kmodules.xyz/custom-resources v0.0.0-20201008012351-6d8090f759d4
kmodules.xyz/offshoot-api v0.0.0-20200922211229-36acc531abab
sigs.k8s.io/yaml v1.2.0
- stash.appscode.dev/apimachinery v0.11.3-0.20201012035827-8f31689080d6
+ stash.appscode.dev/apimachinery v0.11.3
)
// release-1.18
diff --git a/go.sum b/go.sum
index d51746717..7a1c09cb9 100644
--- a/go.sum
+++ b/go.sum
@@ -32,8 +32,6 @@ github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jB
github.com/Microsoft/hcsshim v0.0.0-20190417211021-672e52e9209d/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46 h1:lsxEuwrXEAokXB9qhlbKWPpo3KMLZQ5WB5WLQRW1uq0=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
-github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
-github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OpenPeeDeeP/depguard v1.0.0/go.mod h1:7/4sitnI9YlQgTLLk734QlzXT8DuHVnAyztLplQjk+o=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -53,7 +51,6 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/appscode/go v0.0.0-20200323182826-54e98e09185a h1:cZ80NKoLRaW1PVCWXAJE+YFkBAmLZ8BnrJmH0ClY1Gs=
github.com/appscode/go v0.0.0-20200323182826-54e98e09185a/go.mod h1:lIcm8Z6VPuvcw/a3EeOWcG6R3I13iHMLYbtVP7TKufY=
github.com/appscode/go v0.0.0-20200928211031-cc0c23082d91 h1:a5T6J190+3yXrGoq7qjng7EnseLj/IMoRhmV48+Y1iU=
@@ -79,9 +76,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bifurcation/mint v0.0.0-20180715133206-93c51c6ce115/go.mod h1:zVt7zX3K/aDCk9Tj+VM7YymsX66ERvzCJzw8rFCX2JU=
+github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
-github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
-github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
github.com/caddyserver/caddy v1.0.3/go.mod h1:G+ouvOY32gENkJC+jhgl62TyhvqEsFaDiZ4uw0RzP1E=
@@ -230,8 +226,6 @@ github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.9 h1:1IxuqvBUU3S2Bi4YC7tlP9SJF1gVpCvqN0T2Qof4azE=
-github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
@@ -258,9 +252,8 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef h1:veQD95Isof8w9/WXiA+pa3tz3fJXkt5B7QaRBrM62gk=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.0.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@@ -314,8 +307,6 @@ github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJ
github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/391+sT5o=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
-github.com/gophercloud/gophercloud v0.11.0 h1:pYMP9UZBdQa3lsfIZ1tZor4EbtxiuB6BHhocenkiH/E=
-github.com/gophercloud/gophercloud v0.11.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU808e/4mzjjDA76+Ss=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
@@ -326,14 +317,12 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4 h1:z53tR0945TRRQO/fLEVPI6SMv7ZflF0TEaTAoU7tOzg=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
-github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 h1:THDBEeQ9xZ8JEaCLyLQqXMMdRqNr0QAUJTIkQAUtFjg=
-github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/grpc-ecosystem/grpc-gateway v1.14.6 h1:8ERzHx8aj1Sc47mu9n/AksaKCSWrMchFtkdrS4BIj5o=
-github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
@@ -341,8 +330,6 @@ github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
-github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/heketi/heketi v9.0.1-0.20190917153846-c2e2a4ab7ab9+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o=
@@ -393,13 +380,9 @@ github.com/kmodules/kubernetes v1.19.0-alpha.0.0.20200922200158-8b13196d8dc4 h1:
github.com/kmodules/kubernetes v1.19.0-alpha.0.0.20200922200158-8b13196d8dc4/go.mod h1:lTc732ZplaxM3c4QXZez/NbDziB4/fgeywvu0z1RkrE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
@@ -427,22 +410,16 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
-github.com/mailru/easyjson v0.7.1 h1:mdxE1MF9o53iCb2Ghj1VfWvh7ZOwHpnVG/xwXrV90U8=
-github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/marten-seemann/qtls v0.2.3/go.mod h1:xzjG7avBwGGbdZ8dTGxlBnLArsVKLvwmjgmPuiQEcYk=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
-github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
-github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
-github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
-github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-shellwords v1.0.5/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
@@ -462,8 +439,6 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb
github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4=
-github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -508,7 +483,6 @@ github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zM
github.com/opencontainers/runc v1.0.0-rc10/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runtime-spec v1.0.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
-github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -548,7 +522,6 @@ github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfm
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto=
@@ -603,8 +576,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/thecodeteam/goscaleio v0.1.0/go.mod h1:68sdkZAsK8bvEwBlbQnlLS+xU+hvLYM/iQ8KXej1AwM=
@@ -636,7 +607,6 @@ github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3Ifn
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.bytebuilders.dev/license-verifier v0.3.0 h1:OyxDrV07KfKNh0f+rtvPQYC6BedITIeTIzexW+YiUSs=
go.bytebuilders.dev/license-verifier v0.3.0/go.mod h1:0zzm7+djZ/Ff41BNZYWH80t9mMb42T3Nx2KqQGV9N8s=
go.bytebuilders.dev/license-verifier/kubernetes v0.3.0 h1:qj/pfjtG0uvsTasaNt2DkdH6xXcbLeoRS6HQLCi0k+k=
@@ -651,21 +621,12 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
-go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
-go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
-go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
-go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
-go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
-go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU=
-go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/build v0.0.0-20190927031335-2835ba2e683f/go.mod h1:fYw7AShPAhGMdXqA9gRadk/CcMsvLlClpE5oBwnS3dM=
golang.org/x/crypto v0.0.0-20180426230345-b49d69b5da94/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -685,7 +646,6 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8 h1:1wopBVtVdWnn03fZelqdXT
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200429183012-4b2356b1ed79 h1:IaQbIIB2X/Mp/DKctl6ROxz1KyMlKp4uyvL6+kQ7C88=
@@ -713,8 +673,6 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -739,22 +697,16 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-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-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -762,8 +714,6 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a h1:WXEvlFVvvGxCJLG6REjsT03iWnKLEWinaScsxF2Vm2o=
-golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20171026204733-164713f0dfce/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -790,10 +740,7 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f h1:mOhmO9WsBaJCNmaZHPtHs9wOcdqdKCjF6OPJlmDM3KI=
golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -805,9 +752,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
-golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -836,15 +782,9 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
golang.org/x/tools v0.0.0-20190909030654-5b82db07426d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200603131246-cc40288be839 h1:SxYgZ5FbVts/fm9UsuLycOG8MRWJPm7krdhgPQSayUs=
-golang.org/x/tools v0.0.0-20200603131246-cc40288be839/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=
@@ -869,9 +809,8 @@ google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
-google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 h1:6XzpBoANz1NqMNfDXzc2QmHmbb1vyMsvRfoP5rM+K1I=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
@@ -902,15 +841,11 @@ gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRN
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
-gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.1.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/gotestsum v0.3.5/go.mod h1:Mnf3e5FUzXbkCfynWBGOwLssY7gTQgCHObK9tMpAriY=
@@ -966,8 +901,6 @@ k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl
kmodules.xyz/client-go v0.0.0-20200521065424-173e32c78a20/go.mod h1:sY/eoe4ktxZEoHpr5NpAQ5s22VSwTE8psJtKVeVgLRY=
kmodules.xyz/client-go v0.0.0-20200818143024-600fef263e03/go.mod h1:sY/eoe4ktxZEoHpr5NpAQ5s22VSwTE8psJtKVeVgLRY=
kmodules.xyz/client-go v0.0.0-20200922200830-63d86b6e5b63/go.mod h1:JZN34jqk6ZlR+QOnBPpnUVBab4rmfamqxfSvLaulBMY=
-kmodules.xyz/client-go v0.0.0-20201011221802-3180ab67d845 h1:7ytqOvrfdq5Ul5SicCyy0s1YnnBSGu33hSZaBEcTbXs=
-kmodules.xyz/client-go v0.0.0-20201011221802-3180ab67d845/go.mod h1:pnRh7gtJ6ErPJQBkQeRlpD95KRtxhD4eGrYagZEU8RM=
kmodules.xyz/client-go v0.0.0-20201021051118-03dac1aea508 h1:LjidyEzvw1rSlwRQLWNfElleLJ6vr9Uu5tn5H6JO+QA=
kmodules.xyz/client-go v0.0.0-20201021051118-03dac1aea508/go.mod h1:pnRh7gtJ6ErPJQBkQeRlpD95KRtxhD4eGrYagZEU8RM=
kmodules.xyz/constants v0.0.0-20200506032633-a21e58ceec72/go.mod h1:DbiFk1bJ1KEO94t1SlAn7tzc+Zz95rSXgyUKa2nzPmY=
@@ -1002,6 +935,6 @@ sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
-stash.appscode.dev/apimachinery v0.11.3-0.20201012035827-8f31689080d6 h1:HzGwwdUhJhqJRYnAAeoparQ9nj42w6pAMoA6dpZoUlY=
-stash.appscode.dev/apimachinery v0.11.3-0.20201012035827-8f31689080d6/go.mod h1:ieNywb/MTJs/n1T2wMBEr1m13Ek+ygTnhPCsaqqcyBI=
+stash.appscode.dev/apimachinery v0.11.3 h1:QtDA1w1Piu350toPE++99NvKM1y+zqv44A9sr7LBRCw=
+stash.appscode.dev/apimachinery v0.11.3/go.mod h1:j6XQeyMu0BoUwI9+n3wuts0RpZzU8HNYaGOrCuD3I6U=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
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/NYTimes/gziphandler/.travis.yml b/vendor/github.com/NYTimes/gziphandler/.travis.yml
index 94dfae362..d2b67f69c 100644
--- a/vendor/github.com/NYTimes/gziphandler/.travis.yml
+++ b/vendor/github.com/NYTimes/gziphandler/.travis.yml
@@ -1,10 +1,6 @@
language: go
+
go:
- - 1.x
+ - 1.7
+ - 1.8
- tip
-env:
- - GO111MODULE=on
-install:
- - go mod download
-script:
- - go test -race -v
diff --git a/vendor/github.com/NYTimes/gziphandler/LICENSE b/vendor/github.com/NYTimes/gziphandler/LICENSE
deleted file mode 100644
index df6192d36..000000000
--- a/vendor/github.com/NYTimes/gziphandler/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright 2016-2017 The New York Times Company
-
- 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.
diff --git a/vendor/github.com/NYTimes/gziphandler/LICENSE.md b/vendor/github.com/NYTimes/gziphandler/LICENSE.md
new file mode 100644
index 000000000..b7e2ecb63
--- /dev/null
+++ b/vendor/github.com/NYTimes/gziphandler/LICENSE.md
@@ -0,0 +1,13 @@
+Copyright (c) 2015 The New York Times Company
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this library 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.
diff --git a/vendor/github.com/NYTimes/gziphandler/README.md b/vendor/github.com/NYTimes/gziphandler/README.md
index 6259acaca..6d7246070 100644
--- a/vendor/github.com/NYTimes/gziphandler/README.md
+++ b/vendor/github.com/NYTimes/gziphandler/README.md
@@ -6,10 +6,6 @@ response body, for clients which support it. Although it's usually simpler to
leave that to a reverse proxy (like nginx or Varnish), this package is useful
when that's undesirable.
-## Install
-```bash
-go get -u github.com/NYTimes/gziphandler
-```
## Usage
@@ -52,5 +48,5 @@ The docs can be found at [godoc.org][docs], as usual.
-[docs]: https://godoc.org/github.com/NYTimes/gziphandler
-[license]: https://github.com/NYTimes/gziphandler/blob/master/LICENSE
+[docs]: https://godoc.org/github.com/nytimes/gziphandler
+[license]: https://github.com/nytimes/gziphandler/blob/master/LICENSE.md
diff --git a/vendor/github.com/NYTimes/gziphandler/go.mod b/vendor/github.com/NYTimes/gziphandler/go.mod
deleted file mode 100644
index 801901274..000000000
--- a/vendor/github.com/NYTimes/gziphandler/go.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-module github.com/NYTimes/gziphandler
-
-go 1.11
-
-require github.com/stretchr/testify v1.3.0
diff --git a/vendor/github.com/NYTimes/gziphandler/go.sum b/vendor/github.com/NYTimes/gziphandler/go.sum
deleted file mode 100644
index 4347755af..000000000
--- a/vendor/github.com/NYTimes/gziphandler/go.sum
+++ /dev/null
@@ -1,7 +0,0 @@
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
diff --git a/vendor/github.com/NYTimes/gziphandler/gzip.go b/vendor/github.com/NYTimes/gziphandler/gzip.go
index c112bbdf8..ea6dba1e7 100644
--- a/vendor/github.com/NYTimes/gziphandler/gzip.go
+++ b/vendor/github.com/NYTimes/gziphandler/gzip.go
@@ -1,11 +1,10 @@
-package gziphandler // import "github.com/NYTimes/gziphandler"
+package gziphandler
import (
"bufio"
"compress/gzip"
"fmt"
"io"
- "mime"
"net"
"net/http"
"strconv"
@@ -29,11 +28,9 @@ const (
// The examples seem to indicate that it is.
DefaultQValue = 1.0
- // DefaultMinSize is the default minimum size until we enable gzip compression.
- // 1500 bytes is the MTU size for the internet since that is the largest size allowed at the network layer.
- // If you take a file that is 1300 bytes and compress it to 800 bytes, it’s still transmitted in that same 1500 byte packet regardless, so you’ve gained nothing.
- // That being the case, you should restrict the gzip compression to files with a size greater than a single packet, 1400 bytes (1.4KB) is a safe value.
- DefaultMinSize = 1400
+ // DefaultMinSize defines the minimum size to reach to enable compression.
+ // It's 512 bytes.
+ DefaultMinSize = 512
)
// gzipWriterPools stores a sync.Pool for each compression level for reuse of
@@ -83,71 +80,40 @@ type GzipResponseWriter struct {
minSize int // Specifed the minimum response size to gzip. If the response length is bigger than this value, it is compressed.
buf []byte // Holds the first part of the write before reaching the minSize or the end of the write.
- ignore bool // If true, then we immediately passthru writes to the underlying ResponseWriter.
-
- contentTypes []parsedContentType // Only compress if the response is one of these content-types. All are accepted if empty.
-}
-
-type GzipResponseWriterWithCloseNotify struct {
- *GzipResponseWriter
-}
-
-func (w GzipResponseWriterWithCloseNotify) CloseNotify() <-chan bool {
- return w.ResponseWriter.(http.CloseNotifier).CloseNotify()
}
// Write appends data to the gzip writer.
func (w *GzipResponseWriter) Write(b []byte) (int, error) {
- // GZIP responseWriter is initialized. Use the GZIP responseWriter.
- if w.gw != nil {
- return w.gw.Write(b)
+ // If content type is not set.
+ if _, ok := w.Header()[contentType]; !ok {
+ // It infer it from the uncompressed body.
+ w.Header().Set(contentType, http.DetectContentType(b))
}
- // If we have already decided not to use GZIP, immediately passthrough.
- if w.ignore {
- return w.ResponseWriter.Write(b)
+ // GZIP responseWriter is initialized. Use the GZIP responseWriter.
+ if w.gw != nil {
+ n, err := w.gw.Write(b)
+ return n, err
}
// Save the write into a buffer for later use in GZIP responseWriter (if content is long enough) or at close with regular responseWriter.
// On the first write, w.buf changes from nil to a valid slice
w.buf = append(w.buf, b...)
- var (
- cl, _ = strconv.Atoi(w.Header().Get(contentLength))
- ct = w.Header().Get(contentType)
- ce = w.Header().Get(contentEncoding)
- )
- // Only continue if they didn't already choose an encoding or a known unhandled content length or type.
- if ce == "" && (cl == 0 || cl >= w.minSize) && (ct == "" || handleContentType(w.contentTypes, ct)) {
- // If the current buffer is less than minSize and a Content-Length isn't set, then wait until we have more data.
- if len(w.buf) < w.minSize && cl == 0 {
- return len(b), nil
- }
- // If the Content-Length is larger than minSize or the current buffer is larger than minSize, then continue.
- if cl >= w.minSize || len(w.buf) >= w.minSize {
- // If a Content-Type wasn't specified, infer it from the current buffer.
- if ct == "" {
- ct = http.DetectContentType(w.buf)
- w.Header().Set(contentType, ct)
- }
- // If the Content-Type is acceptable to GZIP, initialize the GZIP writer.
- if handleContentType(w.contentTypes, ct) {
- if err := w.startGzip(); err != nil {
- return 0, err
- }
- return len(b), nil
- }
+ // If the global writes are bigger than the minSize, compression is enable.
+ if len(w.buf) >= w.minSize {
+ err := w.startGzip()
+ if err != nil {
+ return 0, err
}
}
- // If we got here, we should not GZIP this response.
- if err := w.startPlain(); err != nil {
- return 0, err
- }
+
return len(b), nil
}
-// startGzip initializes a GZIP writer and writes the buffer.
+// startGzip initialize any GZIP specific informations.
func (w *GzipResponseWriter) startGzip() error {
+
// Set the GZIP header.
w.Header().Set(contentEncoding, "gzip")
@@ -159,57 +125,28 @@ func (w *GzipResponseWriter) startGzip() error {
// Write the header to gzip response.
if w.code != 0 {
w.ResponseWriter.WriteHeader(w.code)
- // Ensure that no other WriteHeader's happen
- w.code = 0
}
- // Initialize and flush the buffer into the gzip response if there are any bytes.
- // If there aren't any, we shouldn't initialize it yet because on Close it will
- // write the gzip header even if nothing was ever written.
- if len(w.buf) > 0 {
- // Initialize the GZIP response.
- w.init()
- n, err := w.gw.Write(w.buf)
-
- // This should never happen (per io.Writer docs), but if the write didn't
- // accept the entire buffer but returned no specific error, we have no clue
- // what's going on, so abort just to be safe.
- if err == nil && n < len(w.buf) {
- err = io.ErrShortWrite
- }
- return err
- }
- return nil
-}
+ // Initialize the GZIP response.
+ w.init()
+
+ // Flush the buffer into the gzip reponse.
+ n, err := w.gw.Write(w.buf)
-// startPlain writes to sent bytes and buffer the underlying ResponseWriter without gzip.
-func (w *GzipResponseWriter) startPlain() error {
- if w.code != 0 {
- w.ResponseWriter.WriteHeader(w.code)
- // Ensure that no other WriteHeader's happen
- w.code = 0
- }
- w.ignore = true
- // If Write was never called then don't call Write on the underlying ResponseWriter.
- if w.buf == nil {
- return nil
- }
- n, err := w.ResponseWriter.Write(w.buf)
- w.buf = nil
// This should never happen (per io.Writer docs), but if the write didn't
// accept the entire buffer but returned no specific error, we have no clue
// what's going on, so abort just to be safe.
if err == nil && n < len(w.buf) {
- err = io.ErrShortWrite
+ return io.ErrShortWrite
}
+
+ w.buf = nil
return err
}
// WriteHeader just saves the response code until close or GZIP effective writes.
func (w *GzipResponseWriter) WriteHeader(code int) {
- if w.code == 0 {
- w.code = code
- }
+ w.code = code
}
// init graps a new gzip writer from the gzipWriterPool and writes the correct
@@ -224,18 +161,19 @@ func (w *GzipResponseWriter) init() {
// Close will close the gzip.Writer and will put it back in the gzipWriterPool.
func (w *GzipResponseWriter) Close() error {
- if w.ignore {
- return nil
- }
-
if w.gw == nil {
- // GZIP not triggered yet, write out regular response.
- err := w.startPlain()
- // Returns the error if any at write.
- if err != nil {
- err = fmt.Errorf("gziphandler: write to regular responseWriter at close gets error: %q", err.Error())
+ // Gzip not trigged yet, write out regular response.
+ if w.code != 0 {
+ w.ResponseWriter.WriteHeader(w.code)
}
- return err
+ if w.buf != nil {
+ _, writeErr := w.ResponseWriter.Write(w.buf)
+ // Returns the error if any at write.
+ if writeErr != nil {
+ return fmt.Errorf("gziphandler: write to regular responseWriter at close gets error: %q", writeErr.Error())
+ }
+ }
+ return nil
}
err := w.gw.Close()
@@ -248,14 +186,6 @@ func (w *GzipResponseWriter) Close() error {
// http.ResponseWriter if it is an http.Flusher. This makes GzipResponseWriter
// an http.Flusher.
func (w *GzipResponseWriter) Flush() {
- if w.gw == nil && !w.ignore {
- // Only flush once startGzip or startPlain has been called.
- //
- // Flush is thus a no-op until we're certain whether a plain
- // or gzipped response will be served.
- return
- }
-
if w.gw != nil {
w.gw.Flush()
}
@@ -300,44 +230,27 @@ func NewGzipLevelHandler(level int) (func(http.Handler) http.Handler, error) {
// NewGzipLevelAndMinSize behave as NewGzipLevelHandler except it let the caller
// specify the minimum size before compression.
func NewGzipLevelAndMinSize(level, minSize int) (func(http.Handler) http.Handler, error) {
- return GzipHandlerWithOpts(CompressionLevel(level), MinSize(minSize))
-}
-
-func GzipHandlerWithOpts(opts ...option) (func(http.Handler) http.Handler, error) {
- c := &config{
- level: gzip.DefaultCompression,
- minSize: DefaultMinSize,
+ if level != gzip.DefaultCompression && (level < gzip.BestSpeed || level > gzip.BestCompression) {
+ return nil, fmt.Errorf("invalid compression level requested: %d", level)
}
-
- for _, o := range opts {
- o(c)
- }
-
- if err := c.validate(); err != nil {
- return nil, err
+ if minSize < 0 {
+ return nil, fmt.Errorf("minimum size must be more than zero")
}
-
return func(h http.Handler) http.Handler {
- index := poolIndex(c.level)
+ index := poolIndex(level)
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add(vary, acceptEncoding)
+
if acceptsGzip(r) {
gw := &GzipResponseWriter{
ResponseWriter: w,
index: index,
- minSize: c.minSize,
- contentTypes: c.contentTypes,
+ minSize: minSize,
}
defer gw.Close()
- if _, ok := w.(http.CloseNotifier); ok {
- gwcn := GzipResponseWriterWithCloseNotify{gw}
- h.ServeHTTP(gwcn, r)
- } else {
- h.ServeHTTP(gw, r)
- }
-
+ h.ServeHTTP(gw, r)
} else {
h.ServeHTTP(w, r)
}
@@ -345,98 +258,6 @@ func GzipHandlerWithOpts(opts ...option) (func(http.Handler) http.Handler, error
}, nil
}
-// Parsed representation of one of the inputs to ContentTypes.
-// See https://golang.org/pkg/mime/#ParseMediaType
-type parsedContentType struct {
- mediaType string
- params map[string]string
-}
-
-// equals returns whether this content type matches another content type.
-func (pct parsedContentType) equals(mediaType string, params map[string]string) bool {
- if pct.mediaType != mediaType {
- return false
- }
- // if pct has no params, don't care about other's params
- if len(pct.params) == 0 {
- return true
- }
-
- // if pct has any params, they must be identical to other's.
- if len(pct.params) != len(params) {
- return false
- }
- for k, v := range pct.params {
- if w, ok := params[k]; !ok || v != w {
- return false
- }
- }
- return true
-}
-
-// Used for functional configuration.
-type config struct {
- minSize int
- level int
- contentTypes []parsedContentType
-}
-
-func (c *config) validate() error {
- if c.level != gzip.DefaultCompression && (c.level < gzip.BestSpeed || c.level > gzip.BestCompression) {
- return fmt.Errorf("invalid compression level requested: %d", c.level)
- }
-
- if c.minSize < 0 {
- return fmt.Errorf("minimum size must be more than zero")
- }
-
- return nil
-}
-
-type option func(c *config)
-
-func MinSize(size int) option {
- return func(c *config) {
- c.minSize = size
- }
-}
-
-func CompressionLevel(level int) option {
- return func(c *config) {
- c.level = level
- }
-}
-
-// ContentTypes specifies a list of content types to compare
-// the Content-Type header to before compressing. If none
-// match, the response will be returned as-is.
-//
-// Content types are compared in a case-insensitive, whitespace-ignored
-// manner.
-//
-// A MIME type without any other directive will match a content type
-// that has the same MIME type, regardless of that content type's other
-// directives. I.e., "text/html" will match both "text/html" and
-// "text/html; charset=utf-8".
-//
-// A MIME type with any other directive will only match a content type
-// that has the same MIME type and other directives. I.e.,
-// "text/html; charset=utf-8" will only match "text/html; charset=utf-8".
-//
-// By default, responses are gzipped regardless of
-// Content-Type.
-func ContentTypes(types []string) option {
- return func(c *config) {
- c.contentTypes = []parsedContentType{}
- for _, v := range types {
- mediaType, params, err := mime.ParseMediaType(v)
- if err == nil {
- c.contentTypes = append(c.contentTypes, parsedContentType{mediaType, params})
- }
- }
- }
-}
-
// GzipHandler wraps an HTTP handler, to transparently gzip the response body if
// the client supports it (via the Accept-Encoding header). This will compress at
// the default compression level.
@@ -452,27 +273,6 @@ func acceptsGzip(r *http.Request) bool {
return acceptedEncodings["gzip"] > 0.0
}
-// returns true if we've been configured to compress the specific content type.
-func handleContentType(contentTypes []parsedContentType, ct string) bool {
- // If contentTypes is empty we handle all content types.
- if len(contentTypes) == 0 {
- return true
- }
-
- mediaType, params, err := mime.ParseMediaType(ct)
- if err != nil {
- return false
- }
-
- for _, c := range contentTypes {
- if c.equals(mediaType, params) {
- return true
- }
- }
-
- return false
-}
-
// parseEncodings attempts to parse a list of codings, per RFC 2616, as might
// appear in an Accept-Encoding header. It returns a map of content-codings to
// quality values, and an error containing the errors encountered. It's probably
diff --git a/vendor/github.com/blang/semver/.travis.yml b/vendor/github.com/blang/semver/.travis.yml
deleted file mode 100644
index 102fb9a69..000000000
--- a/vendor/github.com/blang/semver/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-language: go
-matrix:
- include:
- - go: 1.4.3
- - go: 1.5.4
- - go: 1.6.3
- - go: 1.7
- - go: tip
- allow_failures:
- - go: tip
-install:
-- go get golang.org/x/tools/cmd/cover
-- go get github.com/mattn/goveralls
-script:
-- echo "Test and track coverage" ; $HOME/gopath/bin/goveralls -package "." -service=travis-ci
- -repotoken $COVERALLS_TOKEN
-- echo "Build examples" ; cd examples && go build
-- echo "Check if gofmt'd" ; diff -u <(echo -n) <(gofmt -d -s .)
-env:
- global:
- secure: HroGEAUQpVq9zX1b1VIkraLiywhGbzvNnTZq2TMxgK7JHP8xqNplAeF1izrR2i4QLL9nsY+9WtYss4QuPvEtZcVHUobw6XnL6radF7jS1LgfYZ9Y7oF+zogZ2I5QUMRLGA7rcxQ05s7mKq3XZQfeqaNts4bms/eZRefWuaFZbkw=
diff --git a/vendor/github.com/blang/semver/README.md b/vendor/github.com/blang/semver/README.md
index 08b2e4a3d..4399639e2 100644
--- a/vendor/github.com/blang/semver/README.md
+++ b/vendor/github.com/blang/semver/README.md
@@ -1,4 +1,4 @@
-semver for golang [![Build Status](https://travis-ci.org/blang/semver.svg?branch=master)](https://travis-ci.org/blang/semver) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
+semver for golang [![Build Status](https://drone.io/github.com/blang/semver/status.png)](https://drone.io/github.com/blang/semver/latest) [![GoDoc](https://godoc.org/github.com/blang/semver?status.png)](https://godoc.org/github.com/blang/semver) [![Coverage Status](https://img.shields.io/coveralls/blang/semver.svg)](https://coveralls.io/r/blang/semver?branch=master)
======
semver is a [Semantic Versioning](http://semver.org/) library written in golang. It fully covers spec version `2.0.0`.
@@ -41,7 +41,6 @@ Features
- Compare Helper Methods
- InPlace manipulation
- Ranges `>=1.0.0 <2.0.0 || >=3.0.0 !3.0.1-beta.1`
-- Wildcards `>=1.x`, `<=2.5.x`
- Sortable (implements sort.Interface)
- database/sql compatible (sql.Scanner/Valuer)
- encoding/json compatible (json.Marshaler/Unmarshaler)
@@ -60,8 +59,6 @@ A condition is composed of an operator and a version. The supported operators ar
- `1.0.0`, `=1.0.0`, `==1.0.0` Equal to `1.0.0`
- `!1.0.0`, `!=1.0.0` Not equal to `1.0.0`. Excludes version `1.0.0`.
-Note that spaces between the operator and the version will be gracefully tolerated.
-
A `Range` can link multiple `Ranges` separated by space:
Ranges can be linked by logical AND:
diff --git a/vendor/github.com/blang/semver/package.json b/vendor/github.com/blang/semver/package.json
index 1cf8ebdd9..568be8d94 100644
--- a/vendor/github.com/blang/semver/package.json
+++ b/vendor/github.com/blang/semver/package.json
@@ -12,6 +12,6 @@
"license": "MIT",
"name": "semver",
"releaseCmd": "git commit -a -m \"gx publish $VERSION\"",
- "version": "3.5.1"
+ "version": "3.4.0"
}
diff --git a/vendor/github.com/go-openapi/swag/.travis.yml b/vendor/github.com/go-openapi/swag/.travis.yml
index f1a3f80b3..aa26d8763 100644
--- a/vendor/github.com/go-openapi/swag/.travis.yml
+++ b/vendor/github.com/go-openapi/swag/.travis.yml
@@ -1,10 +1,12 @@
after_success:
- bash <(curl -s https://codecov.io/bash)
go:
-- 1.13.x
-- 1.14.x
+- 1.11.x
+- 1.12.x
install:
- GO111MODULE=off go get -u gotest.tools/gotestsum
+env:
+- GO111MODULE=on
language: go
notifications:
slack:
diff --git a/vendor/github.com/go-openapi/swag/convert.go b/vendor/github.com/go-openapi/swag/convert.go
index fc085aeb8..7da35c316 100644
--- a/vendor/github.com/go-openapi/swag/convert.go
+++ b/vendor/github.com/go-openapi/swag/convert.go
@@ -88,7 +88,7 @@ func ConvertFloat64(str string) (float64, error) {
return strconv.ParseFloat(str, 64)
}
-// ConvertInt8 turn a string into an int8
+// ConvertInt8 turn a string into int8 boolean
func ConvertInt8(str string) (int8, error) {
i, err := strconv.ParseInt(str, 10, 8)
if err != nil {
@@ -97,7 +97,7 @@ func ConvertInt8(str string) (int8, error) {
return int8(i), nil
}
-// ConvertInt16 turn a string into an int16
+// ConvertInt16 turn a string into a int16
func ConvertInt16(str string) (int16, error) {
i, err := strconv.ParseInt(str, 10, 16)
if err != nil {
@@ -106,7 +106,7 @@ func ConvertInt16(str string) (int16, error) {
return int16(i), nil
}
-// ConvertInt32 turn a string into an int32
+// ConvertInt32 turn a string into a int32
func ConvertInt32(str string) (int32, error) {
i, err := strconv.ParseInt(str, 10, 32)
if err != nil {
@@ -115,12 +115,12 @@ func ConvertInt32(str string) (int32, error) {
return int32(i), nil
}
-// ConvertInt64 turn a string into an int64
+// ConvertInt64 turn a string into a int64
func ConvertInt64(str string) (int64, error) {
return strconv.ParseInt(str, 10, 64)
}
-// ConvertUint8 turn a string into an uint8
+// ConvertUint8 turn a string into a uint8
func ConvertUint8(str string) (uint8, error) {
i, err := strconv.ParseUint(str, 10, 8)
if err != nil {
@@ -129,7 +129,7 @@ func ConvertUint8(str string) (uint8, error) {
return uint8(i), nil
}
-// ConvertUint16 turn a string into an uint16
+// ConvertUint16 turn a string into a uint16
func ConvertUint16(str string) (uint16, error) {
i, err := strconv.ParseUint(str, 10, 16)
if err != nil {
@@ -138,7 +138,7 @@ func ConvertUint16(str string) (uint16, error) {
return uint16(i), nil
}
-// ConvertUint32 turn a string into an uint32
+// ConvertUint32 turn a string into a uint32
func ConvertUint32(str string) (uint32, error) {
i, err := strconv.ParseUint(str, 10, 32)
if err != nil {
@@ -147,7 +147,7 @@ func ConvertUint32(str string) (uint32, error) {
return uint32(i), nil
}
-// ConvertUint64 turn a string into an uint64
+// ConvertUint64 turn a string into a uint64
func ConvertUint64(str string) (uint64, error) {
return strconv.ParseUint(str, 10, 64)
}
diff --git a/vendor/github.com/go-openapi/swag/convert_types.go b/vendor/github.com/go-openapi/swag/convert_types.go
index c49cc473a..c95e4e78b 100644
--- a/vendor/github.com/go-openapi/swag/convert_types.go
+++ b/vendor/github.com/go-openapi/swag/convert_types.go
@@ -181,12 +181,12 @@ func IntValueMap(src map[string]*int) map[string]int {
return dst
}
-// Int32 returns a pointer to of the int32 value passed in.
+// Int32 returns a pointer to of the int64 value passed in.
func Int32(v int32) *int32 {
return &v
}
-// Int32Value returns the value of the int32 pointer passed in or
+// Int32Value returns the value of the int64 pointer passed in or
// 0 if the pointer is nil.
func Int32Value(v *int32) int32 {
if v != nil {
@@ -195,7 +195,7 @@ func Int32Value(v *int32) int32 {
return 0
}
-// Int32Slice converts a slice of int32 values into a slice of
+// Int32Slice converts a slice of int64 values into a slice of
// int32 pointers
func Int32Slice(src []int32) []*int32 {
dst := make([]*int32, len(src))
@@ -299,80 +299,13 @@ func Int64ValueMap(src map[string]*int64) map[string]int64 {
return dst
}
-// Uint16 returns a pointer to of the uint16 value passed in.
-func Uint16(v uint16) *uint16 {
- return &v
-}
-
-// Uint16Value returns the value of the uint16 pointer passed in or
-// 0 if the pointer is nil.
-func Uint16Value(v *uint16) uint16 {
- if v != nil {
- return *v
- }
-
- return 0
-}
-
-// Uint16Slice converts a slice of uint16 values into a slice of
-// uint16 pointers
-func Uint16Slice(src []uint16) []*uint16 {
- dst := make([]*uint16, len(src))
- for i := 0; i < len(src); i++ {
- dst[i] = &(src[i])
- }
-
- return dst
-}
-
-// Uint16ValueSlice converts a slice of uint16 pointers into a slice of
-// uint16 values
-func Uint16ValueSlice(src []*uint16) []uint16 {
- dst := make([]uint16, len(src))
-
- for i := 0; i < len(src); i++ {
- if src[i] != nil {
- dst[i] = *(src[i])
- }
- }
-
- return dst
-}
-
-// Uint16Map converts a string map of uint16 values into a string
-// map of uint16 pointers
-func Uint16Map(src map[string]uint16) map[string]*uint16 {
- dst := make(map[string]*uint16)
-
- for k, val := range src {
- v := val
- dst[k] = &v
- }
-
- return dst
-}
-
-// Uint16ValueMap converts a string map of uint16 pointers into a string
-// map of uint16 values
-func Uint16ValueMap(src map[string]*uint16) map[string]uint16 {
- dst := make(map[string]uint16)
-
- for k, val := range src {
- if val != nil {
- dst[k] = *val
- }
- }
-
- return dst
-}
-
-// Uint returns a pointer to of the uint value passed in.
+// Uint returns a pouinter to of the uint value passed in.
func Uint(v uint) *uint {
return &v
}
-// UintValue returns the value of the uint pointer passed in or
-// 0 if the pointer is nil.
+// UintValue returns the value of the uint pouinter passed in or
+// 0 if the pouinter is nil.
func UintValue(v *uint) uint {
if v != nil {
return *v
@@ -380,8 +313,8 @@ func UintValue(v *uint) uint {
return 0
}
-// UintSlice converts a slice of uint values into a slice of
-// uint pointers
+// UintSlice converts a slice of uint values uinto a slice of
+// uint pouinters
func UintSlice(src []uint) []*uint {
dst := make([]*uint, len(src))
for i := 0; i < len(src); i++ {
@@ -390,7 +323,7 @@ func UintSlice(src []uint) []*uint {
return dst
}
-// UintValueSlice converts a slice of uint pointers into a slice of
+// UintValueSlice converts a slice of uint pouinters uinto a slice of
// uint values
func UintValueSlice(src []*uint) []uint {
dst := make([]uint, len(src))
@@ -402,8 +335,8 @@ func UintValueSlice(src []*uint) []uint {
return dst
}
-// UintMap converts a string map of uint values into a string
-// map of uint pointers
+// UintMap converts a string map of uint values uinto a string
+// map of uint pouinters
func UintMap(src map[string]uint) map[string]*uint {
dst := make(map[string]*uint)
for k, val := range src {
@@ -413,7 +346,7 @@ func UintMap(src map[string]uint) map[string]*uint {
return dst
}
-// UintValueMap converts a string map of uint pointers into a string
+// UintValueMap converts a string map of uint pouinters uinto a string
// map of uint values
func UintValueMap(src map[string]*uint) map[string]uint {
dst := make(map[string]uint)
@@ -425,13 +358,13 @@ func UintValueMap(src map[string]*uint) map[string]uint {
return dst
}
-// Uint32 returns a pointer to of the uint32 value passed in.
+// Uint32 returns a pouinter to of the uint64 value passed in.
func Uint32(v uint32) *uint32 {
return &v
}
-// Uint32Value returns the value of the uint32 pointer passed in or
-// 0 if the pointer is nil.
+// Uint32Value returns the value of the uint64 pouinter passed in or
+// 0 if the pouinter is nil.
func Uint32Value(v *uint32) uint32 {
if v != nil {
return *v
@@ -439,8 +372,8 @@ func Uint32Value(v *uint32) uint32 {
return 0
}
-// Uint32Slice converts a slice of uint32 values into a slice of
-// uint32 pointers
+// Uint32Slice converts a slice of uint64 values uinto a slice of
+// uint32 pouinters
func Uint32Slice(src []uint32) []*uint32 {
dst := make([]*uint32, len(src))
for i := 0; i < len(src); i++ {
@@ -449,7 +382,7 @@ func Uint32Slice(src []uint32) []*uint32 {
return dst
}
-// Uint32ValueSlice converts a slice of uint32 pointers into a slice of
+// Uint32ValueSlice converts a slice of uint32 pouinters uinto a slice of
// uint32 values
func Uint32ValueSlice(src []*uint32) []uint32 {
dst := make([]uint32, len(src))
@@ -461,8 +394,8 @@ func Uint32ValueSlice(src []*uint32) []uint32 {
return dst
}
-// Uint32Map converts a string map of uint32 values into a string
-// map of uint32 pointers
+// Uint32Map converts a string map of uint32 values uinto a string
+// map of uint32 pouinters
func Uint32Map(src map[string]uint32) map[string]*uint32 {
dst := make(map[string]*uint32)
for k, val := range src {
@@ -472,7 +405,7 @@ func Uint32Map(src map[string]uint32) map[string]*uint32 {
return dst
}
-// Uint32ValueMap converts a string map of uint32 pointers into a string
+// Uint32ValueMap converts a string map of uint32 pouinters uinto a string
// map of uint32 values
func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
dst := make(map[string]uint32)
@@ -484,13 +417,13 @@ func Uint32ValueMap(src map[string]*uint32) map[string]uint32 {
return dst
}
-// Uint64 returns a pointer to of the uint64 value passed in.
+// Uint64 returns a pouinter to of the uint64 value passed in.
func Uint64(v uint64) *uint64 {
return &v
}
-// Uint64Value returns the value of the uint64 pointer passed in or
-// 0 if the pointer is nil.
+// Uint64Value returns the value of the uint64 pouinter passed in or
+// 0 if the pouinter is nil.
func Uint64Value(v *uint64) uint64 {
if v != nil {
return *v
@@ -498,8 +431,8 @@ func Uint64Value(v *uint64) uint64 {
return 0
}
-// Uint64Slice converts a slice of uint64 values into a slice of
-// uint64 pointers
+// Uint64Slice converts a slice of uint64 values uinto a slice of
+// uint64 pouinters
func Uint64Slice(src []uint64) []*uint64 {
dst := make([]*uint64, len(src))
for i := 0; i < len(src); i++ {
@@ -508,7 +441,7 @@ func Uint64Slice(src []uint64) []*uint64 {
return dst
}
-// Uint64ValueSlice converts a slice of uint64 pointers into a slice of
+// Uint64ValueSlice converts a slice of uint64 pouinters uinto a slice of
// uint64 values
func Uint64ValueSlice(src []*uint64) []uint64 {
dst := make([]uint64, len(src))
@@ -520,8 +453,8 @@ func Uint64ValueSlice(src []*uint64) []uint64 {
return dst
}
-// Uint64Map converts a string map of uint64 values into a string
-// map of uint64 pointers
+// Uint64Map converts a string map of uint64 values uinto a string
+// map of uint64 pouinters
func Uint64Map(src map[string]uint64) map[string]*uint64 {
dst := make(map[string]*uint64)
for k, val := range src {
@@ -531,7 +464,7 @@ func Uint64Map(src map[string]uint64) map[string]*uint64 {
return dst
}
-// Uint64ValueMap converts a string map of uint64 pointers into a string
+// Uint64ValueMap converts a string map of uint64 pouinters uinto a string
// map of uint64 values
func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
dst := make(map[string]uint64)
@@ -543,74 +476,6 @@ func Uint64ValueMap(src map[string]*uint64) map[string]uint64 {
return dst
}
-// Float32 returns a pointer to of the float32 value passed in.
-func Float32(v float32) *float32 {
- return &v
-}
-
-// Float32Value returns the value of the float32 pointer passed in or
-// 0 if the pointer is nil.
-func Float32Value(v *float32) float32 {
- if v != nil {
- return *v
- }
-
- return 0
-}
-
-// Float32Slice converts a slice of float32 values into a slice of
-// float32 pointers
-func Float32Slice(src []float32) []*float32 {
- dst := make([]*float32, len(src))
-
- for i := 0; i < len(src); i++ {
- dst[i] = &(src[i])
- }
-
- return dst
-}
-
-// Float32ValueSlice converts a slice of float32 pointers into a slice of
-// float32 values
-func Float32ValueSlice(src []*float32) []float32 {
- dst := make([]float32, len(src))
-
- for i := 0; i < len(src); i++ {
- if src[i] != nil {
- dst[i] = *(src[i])
- }
- }
-
- return dst
-}
-
-// Float32Map converts a string map of float32 values into a string
-// map of float32 pointers
-func Float32Map(src map[string]float32) map[string]*float32 {
- dst := make(map[string]*float32)
-
- for k, val := range src {
- v := val
- dst[k] = &v
- }
-
- return dst
-}
-
-// Float32ValueMap converts a string map of float32 pointers into a string
-// map of float32 values
-func Float32ValueMap(src map[string]*float32) map[string]float32 {
- dst := make(map[string]float32)
-
- for k, val := range src {
- if val != nil {
- dst[k] = *val
- }
- }
-
- return dst
-}
-
// Float64 returns a pointer to of the float64 value passed in.
func Float64(v float64) *float64 {
return &v
diff --git a/vendor/github.com/go-openapi/swag/go.mod b/vendor/github.com/go-openapi/swag/go.mod
index 4aef463e4..15bbb0822 100644
--- a/vendor/github.com/go-openapi/swag/go.mod
+++ b/vendor/github.com/go-openapi/swag/go.mod
@@ -6,11 +6,9 @@ require (
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63
github.com/stretchr/testify v1.3.0
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
- gopkg.in/yaml.v2 v2.2.4
+ gopkg.in/yaml.v2 v2.2.2
)
replace github.com/golang/lint => golang.org/x/lint v0.0.0-20190409202823-959b441ac422
replace sourcegraph.com/sourcegraph/go-diff => github.com/sourcegraph/go-diff v0.5.1
-
-go 1.13
diff --git a/vendor/github.com/go-openapi/swag/go.sum b/vendor/github.com/go-openapi/swag/go.sum
index e8a80bacf..33469f54a 100644
--- a/vendor/github.com/go-openapi/swag/go.sum
+++ b/vendor/github.com/go-openapi/swag/go.sum
@@ -16,5 +16,5 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
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=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/go-openapi/swag/json.go b/vendor/github.com/go-openapi/swag/json.go
index 7e9902ca3..edf93d84c 100644
--- a/vendor/github.com/go-openapi/swag/json.go
+++ b/vendor/github.com/go-openapi/swag/json.go
@@ -51,7 +51,7 @@ type ejUnmarshaler interface {
UnmarshalEasyJSON(w *jlexer.Lexer)
}
-// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaler
+// WriteJSON writes json data, prefers finding an appropriate interface to short-circuit the marshaller
// so it takes the fastest option available.
func WriteJSON(data interface{}) ([]byte, error) {
if d, ok := data.(ejMarshaler); ok {
@@ -65,8 +65,8 @@ func WriteJSON(data interface{}) ([]byte, error) {
return json.Marshal(data)
}
-// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaler
-// so it takes the fastest option available
+// ReadJSON reads json data, prefers finding an appropriate interface to short-circuit the unmarshaller
+// so it takes the fastes option available
func ReadJSON(data []byte, value interface{}) error {
trimmedData := bytes.Trim(data, "\x00")
if d, ok := value.(ejUnmarshaler); ok {
@@ -189,7 +189,7 @@ func FromDynamicJSON(data, target interface{}) error {
return json.Unmarshal(b, target)
}
-// NameProvider represents an object capable of translating from go property names
+// NameProvider represents an object capabale of translating from go property names
// to json property names
// This type is thread-safe.
type NameProvider struct {
diff --git a/vendor/github.com/go-openapi/swag/loading.go b/vendor/github.com/go-openapi/swag/loading.go
index 04160b89b..70f4fb361 100644
--- a/vendor/github.com/go-openapi/swag/loading.go
+++ b/vendor/github.com/go-openapi/swag/loading.go
@@ -27,15 +27,6 @@ import (
// LoadHTTPTimeout the default timeout for load requests
var LoadHTTPTimeout = 30 * time.Second
-// LoadHTTPBasicAuthUsername the username to use when load requests require basic auth
-var LoadHTTPBasicAuthUsername = ""
-
-// LoadHTTPBasicAuthPassword the password to use when load requests require basic auth
-var LoadHTTPBasicAuthPassword = ""
-
-// LoadHTTPCustomHeaders an optional collection of custom HTTP headers for load requests
-var LoadHTTPCustomHeaders = map[string]string{}
-
// LoadFromFileOrHTTP loads the bytes from a file or a remote http server based on the path passed in
func LoadFromFileOrHTTP(path string) ([]byte, error) {
return LoadStrategy(path, ioutil.ReadFile, loadHTTPBytes(LoadHTTPTimeout))(path)
@@ -68,15 +59,6 @@ func loadHTTPBytes(timeout time.Duration) func(path string) ([]byte, error) {
if err != nil {
return nil, err
}
-
- if LoadHTTPBasicAuthUsername != "" && LoadHTTPBasicAuthPassword != "" {
- req.SetBasicAuth(LoadHTTPBasicAuthUsername, LoadHTTPBasicAuthPassword)
- }
-
- for key, val := range LoadHTTPCustomHeaders {
- req.Header.Set(key, val)
- }
-
resp, err := client.Do(req)
defer func() {
if resp != nil {
diff --git a/vendor/github.com/gophercloud/gophercloud/.travis.yml b/vendor/github.com/gophercloud/gophercloud/.travis.yml
index 31f80f8db..9153a00fc 100644
--- a/vendor/github.com/gophercloud/gophercloud/.travis.yml
+++ b/vendor/github.com/gophercloud/gophercloud/.travis.yml
@@ -7,9 +7,9 @@ install:
- GO111MODULE=off go get github.com/mattn/goveralls
- GO111MODULE=off go get golang.org/x/tools/cmd/goimports
go:
+- "1.10"
- "1.11"
- "1.12"
-- "1.13"
- "tip"
env:
global:
diff --git a/vendor/github.com/gophercloud/gophercloud/.zuul.yaml b/vendor/github.com/gophercloud/gophercloud/.zuul.yaml
index b6649a3d6..135e3b203 100644
--- a/vendor/github.com/gophercloud/gophercloud/.zuul.yaml
+++ b/vendor/github.com/gophercloud/gophercloud/.zuul.yaml
@@ -12,7 +12,6 @@
description: |
Run gophercloud acceptance test on master branch
run: .zuul/playbooks/gophercloud-acceptance-test/run.yaml
- nodeset: ubuntu-bionic
- job:
name: gophercloud-acceptance-test-ironic
@@ -20,7 +19,6 @@
description: |
Run gophercloud ironic acceptance test on master branch
run: .zuul/playbooks/gophercloud-acceptance-test-ironic/run.yaml
- nodeset: ubuntu-bionic
- job:
name: gophercloud-acceptance-test-stein
@@ -76,6 +74,16 @@
global_env:
OS_BRANCH: stable/newton
+- job:
+ name: gophercloud-acceptance-test-mitaka
+ parent: gophercloud-acceptance-test
+ description: |
+ Run gophercloud acceptance test on mitaka branch
+ vars:
+ global_env:
+ OS_BRANCH: stable/mitaka
+ nodeset: ubuntu-trusty
+
- project:
name: gophercloud/gophercloud
check:
@@ -83,6 +91,9 @@
- gophercloud-unittest
- gophercloud-acceptance-test
- gophercloud-acceptance-test-ironic
+ recheck-mitaka:
+ jobs:
+ - gophercloud-acceptance-test-mitaka
recheck-newton:
jobs:
- gophercloud-acceptance-test-newton
diff --git a/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md b/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md
index 23af89a3f..e69de29bb 100644
--- a/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md
+++ b/vendor/github.com/gophercloud/gophercloud/CHANGELOG.md
@@ -1,358 +0,0 @@
-## 0.12.0 (Unreleased)
-
-## 0.11.0 (May 14, 2020)
-
-UPGRADE NOTES
-
-* Object storage container and object names are now URL encoded [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
-* All responses now have access to the returned headers. Please report any issues this has caused [GH-1942](https://github.com/gophercloud/gophercloud/pull/1942)
-* Changes have been made to the internal HTTP client to ensure response bodies are handled in a way that enables connections to be re-used more efficiently [GH-1952](https://github.com/gophercloud/gophercloud/pull/1952)
-
-IMPROVEMENTS
-
-* Added `objectstorage/v1/containers.BulkDelete` [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
-* Added `objectstorage/v1/objects.BulkDelete` [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
-* Object storage container and object names are now URL encoded [GH-1930](https://github.com/gophercloud/gophercloud/pull/1930)
-* All responses now have access to the returned headers [GH-1942](https://github.com/gophercloud/gophercloud/pull/1942)
-* Added `compute/v2/extensions/injectnetworkinfo.InjectNetworkInfo` [GH-1941](https://github.com/gophercloud/gophercloud/pull/1941)
-* Added `compute/v2/extensions/resetnetwork.ResetNetwork` [GH-1941](https://github.com/gophercloud/gophercloud/pull/1941)
-* Added `identity/v3/extensions/trusts.ListRoles` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
-* Added `identity/v3/extensions/trusts.GetRole` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
-* Added `identity/v3/extensions/trusts.CheckRole` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
-* Added `identity/v3/extensions/oauth1.Create` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.CreateConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.DeleteConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.ListConsumers` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.GetConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.UpdateConsumer` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.RequestToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.AuthorizeToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.CreateAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.GetAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.RevokeAccessToken` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.ListAccessTokens` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.ListAccessTokenRoles` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `identity/v3/extensions/oauth1.GetAccessTokenRole` [GH-1935](https://github.com/gophercloud/gophercloud/pull/1935)
-* Added `networking/v2/extensions/agents.Update` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
-* Added `networking/v2/extensions/agents.Delete` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
-* Added `networking/v2/extensions/agents.ScheduleDHCPNetwork` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
-* Added `networking/v2/extensions/agents.RemoveDHCPNetwork` [GH-1954](https://github.com/gophercloud/gophercloud/pull/1954)
-* Added `identity/v3/projects.CreateOpts.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
-* Added `identity/v3/projects.CreateOpts.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
-* Added `identity/v3/projects.UpdateOpts.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
-* Added `identity/v3/projects.UpdateOpts.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
-* Added `identity/v3/projects.Project.Extra` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
-* Added `identity/v3/projects.Options.Options` [GH-1951](https://github.com/gophercloud/gophercloud/pull/1951)
-* Added `imageservice/v2/images.Image.OpenStackImageImportMethods` [GH-1962](https://github.com/gophercloud/gophercloud/pull/1962)
-* Added `imageservice/v2/images.Image.OpenStackImageStoreIDs` [GH-1962](https://github.com/gophercloud/gophercloud/pull/1962)
-
-BUG FIXES
-
-* Changed`identity/v3/extensions/trusts.Trust.RemainingUses` from `bool` to `int` [GH-1939](https://github.com/gophercloud/gophercloud/pull/1939)
-* Changed `identity/v3/applicationcredentials.CreateOpts.ExpiresAt` from `string` to `*time.Time` [GH-1937](https://github.com/gophercloud/gophercloud/pull/1937)
-* Fixed issue with unmarshalling/decoding slices of composed structs [GH-1964](https://github.com/gophercloud/gophercloud/pull/1964)
-
-## 0.10.0 (April 12, 2020)
-
-UPGRADE NOTES
-
-* The various `IDFromName` convenience functions have been moved to https://github.com/gophercloud/utils [GH-1897](https://github.com/gophercloud/gophercloud/pull/1897)
-* `sharedfilesystems/v2/shares.GetExportLocations` was renamed to `sharedfilesystems/v2/shares.ListExportLocations` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932)
-
-IMPROVEMENTS
-
-* Added `blockstorage/extensions/volumeactions.SetBootable` [GH-1891](https://github.com/gophercloud/gophercloud/pull/1891)
-* Added `blockstorage/extensions/backups.Export` [GH-1894](https://github.com/gophercloud/gophercloud/pull/1894)
-* Added `blockstorage/extensions/backups.Import` [GH-1894](https://github.com/gophercloud/gophercloud/pull/1894)
-* Added `placement/v1/resourceproviders.GetTraits` [GH-1899](https://github.com/gophercloud/gophercloud/pull/1899)
-* Added the ability to authenticate with Amazon EC2 Credentials [GH-1900](https://github.com/gophercloud/gophercloud/pull/1900)
-* Added ability to list Nova services by binary and host [GH-1904](https://github.com/gophercloud/gophercloud/pull/1904)
-* Added `compute/v2/extensions/services.Update` [GH-1902](https://github.com/gophercloud/gophercloud/pull/1902)
-* Added system scope to v3 authentication [GH-1908](https://github.com/gophercloud/gophercloud/pull/1908)
-* Added `identity/v3/extensions/ec2tokens.ValidateS3Token` [GH-1906](https://github.com/gophercloud/gophercloud/pull/1906)
-* Added `containerinfra/v1/clusters.Cluster.HealthStatus` [GH-1910](https://github.com/gophercloud/gophercloud/pull/1910)
-* Added `containerinfra/v1/clusters.Cluster.HealthStatusReason` [GH-1910](https://github.com/gophercloud/gophercloud/pull/1910)
-* Added `loadbalancer/v2/amphorae.Failover` [GH-1912](https://github.com/gophercloud/gophercloud/pull/1912)
-* Added `identity/v3/extensions/ec2credentials.List` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
-* Added `identity/v3/extensions/ec2credentials.Get` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
-* Added `identity/v3/extensions/ec2credentials.Create` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
-* Added `identity/v3/extensions/ec2credentials.Delete` [GH-1916](https://github.com/gophercloud/gophercloud/pull/1916)
-* Added `ErrUnexpectedResponseCode.ResponseHeader` [GH-1919](https://github.com/gophercloud/gophercloud/pull/1919)
-* Added support for TOTP authentication [GH-1922](https://github.com/gophercloud/gophercloud/pull/1922)
-* `sharedfilesystems/v2/shares.GetExportLocations` was renamed to `sharedfilesystems/v2/shares.ListExportLocations` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932)
-* Added `sharedfilesystems/v2/shares.GetExportLocation` [GH-1932](https://github.com/gophercloud/gophercloud/pull/1932)
-* Added `sharedfilesystems/v2/shares.Revert` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
-* Added `sharedfilesystems/v2/shares.ResetStatus` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
-* Added `sharedfilesystems/v2/shares.ForceDelete` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
-* Added `sharedfilesystems/v2/shares.Unmanage` [GH-1931](https://github.com/gophercloud/gophercloud/pull/1931)
-* Added `blockstorage/v3/attachments.Create` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
-* Added `blockstorage/v3/attachments.List` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
-* Added `blockstorage/v3/attachments.Get` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
-* Added `blockstorage/v3/attachments.Update` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
-* Added `blockstorage/v3/attachments.Delete` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
-* Added `blockstorage/v3/attachments.Complete` [GH-1934](https://github.com/gophercloud/gophercloud/pull/1934)
-
-BUG FIXES
-
-* Fixed issue with Orchestration `get_file` only being able to read JSON and YAML files [GH-1915](https://github.com/gophercloud/gophercloud/pull/1915)
-
-## 0.9.0 (March 10, 2020)
-
-UPGRADE NOTES
-
-* The way we implement new API result fields added by microversions has changed. Previously, we would declare a dedicated `ExtractFoo` function in a file called `microversions.go`. Now, we are declaring those fields inline of the original result struct as a pointer. [GH-1854](https://github.com/gophercloud/gophercloud/pull/1854)
-
-* `compute/v2/servers.CreateOpts.Networks` has changed from `[]Network` to `interface{}` in order to support creating servers that have no networks. [GH-1884](https://github.com/gophercloud/gophercloud/pull/1884)
-
-IMPROVEMENTS
-
-* Added `compute/v2/extensions/instanceactions.List` [GH-1848](https://github.com/gophercloud/gophercloud/pull/1848)
-* Added `compute/v2/extensions/instanceactions.Get` [GH-1848](https://github.com/gophercloud/gophercloud/pull/1848)
-* Added `networking/v2/ports.List.FixedIPs` [GH-1849](https://github.com/gophercloud/gophercloud/pull/1849)
-* Added `identity/v3/extensions/trusts.List` [GH-1855](https://github.com/gophercloud/gophercloud/pull/1855)
-* Added `identity/v3/extensions/trusts.Get` [GH-1855](https://github.com/gophercloud/gophercloud/pull/1855)
-* Added `identity/v3/extensions/trusts.Trust.ExpiresAt` [GH-1857](https://github.com/gophercloud/gophercloud/pull/1857)
-* Added `identity/v3/extensions/trusts.Trust.DeletedAt` [GH-1857](https://github.com/gophercloud/gophercloud/pull/1857)
-* Added `compute/v2/extensions/instanceactions.InstanceActionDetail` [GH-1851](https://github.com/gophercloud/gophercloud/pull/1851)
-* Added `compute/v2/extensions/instanceactions.Event` [GH-1851](https://github.com/gophercloud/gophercloud/pull/1851)
-* Added `compute/v2/extensions/instanceactions.ListOpts` [GH-1858](https://github.com/gophercloud/gophercloud/pull/1858)
-* Added `objectstorage/v1/containers.UpdateOpts.TempURLKey` [GH-1864](https://github.com/gophercloud/gophercloud/pull/1864)
-* Added `objectstorage/v1/containers.UpdateOpts.TempURLKey2` [GH-1864](https://github.com/gophercloud/gophercloud/pull/1864)
-* Added `placement/v1/resourceproviders.GetUsages` [GH-1862](https://github.com/gophercloud/gophercloud/pull/1862)
-* Added `placement/v1/resourceproviders.GetInventories` [GH-1862](https://github.com/gophercloud/gophercloud/pull/1862)
-* Added `imageservice/v2/images.ReplaceImageMinRam` [GH-1867](https://github.com/gophercloud/gophercloud/pull/1867)
-* Added `objectstorage/v1/containers.UpdateOpts.TempURLKey` [GH-1865](https://github.com/gophercloud/gophercloud/pull/1865)
-* Added `objectstorage/v1/containers.CreateOpts.TempURLKey2` [GH-1865](https://github.com/gophercloud/gophercloud/pull/1865)
-* Added `blockstorage/extensions/volumetransfers.List` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869)
-* Added `blockstorage/extensions/volumetransfers.Create` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869)
-* Added `blockstorage/extensions/volumetransfers.Accept` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869)
-* Added `blockstorage/extensions/volumetransfers.Get` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869)
-* Added `blockstorage/extensions/volumetransfers.Delete` [GH-1869](https://github.com/gophercloud/gophercloud/pull/1869)
-* Added `blockstorage/extensions/backups.RestoreFromBackup` [GH-1871](https://github.com/gophercloud/gophercloud/pull/1871)
-* Added `blockstorage/v3/volumes.CreateOpts.BackupID` [GH-1871](https://github.com/gophercloud/gophercloud/pull/1871)
-* Added `blockstorage/v3/volumes.Volume.BackupID` [GH-1871](https://github.com/gophercloud/gophercloud/pull/1871)
-* Added `identity/v3/projects.ListOpts.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882)
-* Added `identity/v3/projects.ListOpts.TagsAny` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882)
-* Added `identity/v3/projects.ListOpts.NotTags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882)
-* Added `identity/v3/projects.ListOpts.NotTagsAny` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882)
-* Added `identity/v3/projects.CreateOpts.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882)
-* Added `identity/v3/projects.UpdateOpts.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882)
-* Added `identity/v3/projects.Project.Tags` [GH-1882](https://github.com/gophercloud/gophercloud/pull/1882)
-* Changed `compute/v2/servers.CreateOpts.Networks` from `[]Network` to `interface{}` to support creating servers with no networks. [GH-1884](https://github.com/gophercloud/gophercloud/pull/1884)
-
-
-BUG FIXES
-
-* Added support for `int64` headers, which were previously being silently dropped [GH-1860](https://github.com/gophercloud/gophercloud/pull/1860)
-* Allow image properties with empty values [GH-1875](https://github.com/gophercloud/gophercloud/pull/1875)
-* Fixed `compute/v2/extensions/extendedserverattributes.ServerAttributesExt.Userdata` JSON tag [GH-1881](https://github.com/gophercloud/gophercloud/pull/1881)
-
-## 0.8.0 (February 8, 2020)
-
-UPGRADE NOTES
-
-* The behavior of `keymanager/v1/acls.SetOpts` has changed. Instead of a struct, it is now `[]SetOpt`. See [GH-1816](https://github.com/gophercloud/gophercloud/pull/1816) for implementation details.
-
-IMPROVEMENTS
-
-* The result of `containerinfra/v1/clusters.Resize` now returns only the UUID when calling `Extract`. This is a backwards-breaking change from the previous struct that was returned [GH-1649](https://github.com/gophercloud/gophercloud/pull/1649)
-* Added `compute/v2/extensions/shelveunshelve.Shelve` [GH-1799](https://github.com/gophercloud/gophercloud/pull/1799)
-* Added `compute/v2/extensions/shelveunshelve.ShelveOffload` [GH-1799](https://github.com/gophercloud/gophercloud/pull/1799)
-* Added `compute/v2/extensions/shelveunshelve.Unshelve` [GH-1799](https://github.com/gophercloud/gophercloud/pull/1799)
-* Added `containerinfra/v1/nodegroups.Get` [GH-1774](https://github.com/gophercloud/gophercloud/pull/1774)
-* Added `containerinfra/v1/nodegroups.List` [GH-1774](https://github.com/gophercloud/gophercloud/pull/1774)
-* Added `orchestration/v1/resourcetypes.List` [GH-1806](https://github.com/gophercloud/gophercloud/pull/1806)
-* Added `orchestration/v1/resourcetypes.GetSchema` [GH-1806](https://github.com/gophercloud/gophercloud/pull/1806)
-* Added `orchestration/v1/resourcetypes.GenerateTemplate` [GH-1806](https://github.com/gophercloud/gophercloud/pull/1806)
-* Added `keymanager/v1/acls.SetOpt` and changed `keymanager/v1/acls.SetOpts` to `[]SetOpt` [GH-1816](https://github.com/gophercloud/gophercloud/pull/1816)
-* Added `blockstorage/apiversions.List` [GH-458](https://github.com/gophercloud/gophercloud/pull/458)
-* Added `blockstorage/apiversions.Get` [GH-458](https://github.com/gophercloud/gophercloud/pull/458)
-* Added `StatusCodeError` interface and `GetStatusCode` convenience method [GH-1820](https://github.com/gophercloud/gophercloud/pull/1820)
-* Added pagination support to `compute/v2/extensions/usage.SingleTenant` [GH-1819](https://github.com/gophercloud/gophercloud/pull/1819)
-* Added pagination support to `compute/v2/extensions/usage.AllTenants` [GH-1819](https://github.com/gophercloud/gophercloud/pull/1819)
-* Added `placement/v1/resourceproviders.List` [GH-1815](https://github.com/gophercloud/gophercloud/pull/1815)
-* Allow `CreateMemberOptsBuilder` to be passed in `loadbalancer/v2/pools.Create` [GH-1822](https://github.com/gophercloud/gophercloud/pull/1822)
-* Added `Backup` to `loadbalancer/v2/pools.CreateMemberOpts` [GH-1824](https://github.com/gophercloud/gophercloud/pull/1824)
-* Added `MonitorAddress` to `loadbalancer/v2/pools.CreateMemberOpts` [GH-1824](https://github.com/gophercloud/gophercloud/pull/1824)
-* Added `MonitorPort` to `loadbalancer/v2/pools.CreateMemberOpts` [GH-1824](https://github.com/gophercloud/gophercloud/pull/1824)
-* Changed `Impersonation` to a non-required field in `identity/v3/extensions/trusts.CreateOpts` [GH-1818](https://github.com/gophercloud/gophercloud/pull/1818)
-* Added `InsertHeaders` to `loadbalancer/v2/listeners.UpdateOpts` [GH-1835]
-* Added `NUMATopology` to `baremetalintrospection/v1/introspection.Data` [GH-1842](https://github.com/gophercloud/gophercloud/pull/1842)
-* Added `placement/v1/resourceproviders.Create` [GH-1841](https://github.com/gophercloud/gophercloud/pull/1841)
-* Added `blockstorage/extensions/volumeactions.UploadImageOpts.Visibility` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873)
-* Added `blockstorage/extensions/volumeactions.UploadImageOpts.Protected` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873)
-* Added `blockstorage/extensions/volumeactions.VolumeImage.Visibility` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873)
-* Added `blockstorage/extensions/volumeactions.VolumeImage.Protected` [GH-1873](https://github.com/gophercloud/gophercloud/pull/1873)
-
-BUG FIXES
-
-* Changed `sort_key` to `sort_keys` in ` workflow/v2/crontriggers.ListOpts` [GH-1809](https://github.com/gophercloud/gophercloud/pull/1809)
-* Allow `blockstorage/extensions/schedulerstats.Capabilities.MaxOverSubscriptionRatio` to accept both string and int/float responses [GH-1817](https://github.com/gophercloud/gophercloud/pull/1817)
-* Fixed bug in `NewLoadBalancerV2` for situations when the LBaaS service was advertised without a `/v2.0` endpoint [GH-1829](https://github.com/gophercloud/gophercloud/pull/1829)
-* Fixed JSON tags in `baremetal/v1/ports.UpdateOperation` [GH-1840](https://github.com/gophercloud/gophercloud/pull/1840)
-* Fixed JSON tags in `networking/v2/extensions/lbaas/vips.commonResult.Extract()` [GH-1840](https://github.com/gophercloud/gophercloud/pull/1840)
-
-## 0.7.0 (December 3, 2019)
-
-IMPROVEMENTS
-
-* Allow a token to be used directly for authentication instead of generating a new token based on a given token [GH-1752](https://github.com/gophercloud/gophercloud/pull/1752)
-* Moved `tags.ServerTagsExt` to servers.TagsExt` [GH-1760](https://github.com/gophercloud/gophercloud/pull/1760)
-* Added `tags`, `tags-any`, `not-tags`, and `not-tags-any` to `compute/v2/servers.ListOpts` [GH-1759](https://github.com/gophercloud/gophercloud/pull/1759)
-* Added `AccessRule` to `identity/v3/applicationcredentials` [GH-1758](https://github.com/gophercloud/gophercloud/pull/1758)
-* Gophercloud no longer returns an error when multiple endpoints are found. Instead, it will choose the first endpoint and discard the others [GH-1766](https://github.com/gophercloud/gophercloud/pull/1766)
-* Added `networking/v2/extensions/fwaas_v2/rules.Create` [GH-1768](https://github.com/gophercloud/gophercloud/pull/1768)
-* Added `networking/v2/extensions/fwaas_v2/rules.Delete` [GH-1771](https://github.com/gophercloud/gophercloud/pull/1771)
-* Added `loadbalancer/v2/providers.List` [GH-1765](https://github.com/gophercloud/gophercloud/pull/1765)
-* Added `networking/v2/extensions/fwaas_v2/rules.Get` [GH-1772](https://github.com/gophercloud/gophercloud/pull/1772)
-* Added `networking/v2/extensions/fwaas_v2/rules.Update` [GH-1776](https://github.com/gophercloud/gophercloud/pull/1776)
-* Added `networking/v2/extensions/fwaas_v2/rules.List` [GH-1783](https://github.com/gophercloud/gophercloud/pull/1783)
-* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.CreateOpts` [GH-1785](https://github.com/gophercloud/gophercloud/pull/1785)
-* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.UpdateOpts` [GH-1786](https://github.com/gophercloud/gophercloud/pull/1786)
-* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.Monitor` [GH-1787](https://github.com/gophercloud/gophercloud/pull/1787)
-* Added `MaxRetriesDown` into `loadbalancer/v2/monitors.ListOpts` [GH-1788](https://github.com/gophercloud/gophercloud/pull/1788)
-* Updated `go.mod` dependencies, specifically to account for CVE-2019-11840 with `golang.org/x/crypto` [GH-1793](https://github.com/gophercloud/gophercloud/pull/1788)
-
-## 0.6.0 (October 17, 2019)
-
-UPGRADE NOTES
-
-* The way reauthentication works has been refactored. This should not cause a problem, but please report bugs if it does. See [GH-1746](https://github.com/gophercloud/gophercloud/pull/1746) for more information.
-
-IMPROVEMENTS
-
-* Added `networking/v2/extensions/quotas.Get` [GH-1742](https://github.com/gophercloud/gophercloud/pull/1742)
-* Added `networking/v2/extensions/quotas.Update` [GH-1747](https://github.com/gophercloud/gophercloud/pull/1747)
-* Refactored the reauthentication implementation to use goroutines and added a check to prevent an infinite loop in certain situations. [GH-1746](https://github.com/gophercloud/gophercloud/pull/1746)
-
-BUG FIXES
-
-* Changed `Flavor` to `FlavorID` in `loadbalancer/v2/loadbalancers` [GH-1744](https://github.com/gophercloud/gophercloud/pull/1744)
-* Changed `Flavor` to `FlavorID` in `networking/v2/extensions/lbaas_v2/loadbalancers` [GH-1744](https://github.com/gophercloud/gophercloud/pull/1744)
-* The `go-yaml` dependency was updated to `v2.2.4` to fix possible DDOS vulnerabilities [GH-1751](https://github.com/gophercloud/gophercloud/pull/1751)
-
-## 0.5.0 (October 13, 2019)
-
-IMPROVEMENTS
-
-* Added `VolumeType` to `compute/v2/extensions/bootfromvolume.BlockDevice`[GH-1690](https://github.com/gophercloud/gophercloud/pull/1690)
-* Added `networking/v2/extensions/layer3/portforwarding.List` [GH-1688](https://github.com/gophercloud/gophercloud/pull/1688)
-* Added `networking/v2/extensions/layer3/portforwarding.Get` [GH-1698](https://github.com/gophercloud/gophercloud/pull/1696)
-* Added `compute/v2/extensions/tags.ReplaceAll` [GH-1696](https://github.com/gophercloud/gophercloud/pull/1696)
-* Added `compute/v2/extensions/tags.Add` [GH-1696](https://github.com/gophercloud/gophercloud/pull/1696)
-* Added `networking/v2/extensions/layer3/portforwarding.Update` [GH-1703](https://github.com/gophercloud/gophercloud/pull/1703)
-* Added `ExtractDomain` method to token results in `identity/v3/tokens` [GH-1712](https://github.com/gophercloud/gophercloud/pull/1712)
-* Added `AllowedCIDRs` to `loadbalancer/v2/listeners.CreateOpts` [GH-1710](https://github.com/gophercloud/gophercloud/pull/1710)
-* Added `AllowedCIDRs` to `loadbalancer/v2/listeners.UpdateOpts` [GH-1710](https://github.com/gophercloud/gophercloud/pull/1710)
-* Added `AllowedCIDRs` to `loadbalancer/v2/listeners.Listener` [GH-1710](https://github.com/gophercloud/gophercloud/pull/1710)
-* Added `compute/v2/extensions/tags.Add` [GH-1695](https://github.com/gophercloud/gophercloud/pull/1695)
-* Added `compute/v2/extensions/tags.ReplaceAll` [GH-1694](https://github.com/gophercloud/gophercloud/pull/1694)
-* Added `compute/v2/extensions/tags.Delete` [GH-1699](https://github.com/gophercloud/gophercloud/pull/1699)
-* Added `compute/v2/extensions/tags.DeleteAll` [GH-1700](https://github.com/gophercloud/gophercloud/pull/1700)
-* Added `ImageStatusImporting` as an image status [GH-1725](https://github.com/gophercloud/gophercloud/pull/1725)
-* Added `ByPath` to `baremetalintrospection/v1/introspection.RootDiskType` [GH-1730](https://github.com/gophercloud/gophercloud/pull/1730)
-* Added `AttachedVolumes` to `compute/v2/servers.Server` [GH-1732](https://github.com/gophercloud/gophercloud/pull/1732)
-* Enable unmarshaling server tags to a `compute/v2/servers.Server` struct [GH-1734]
-* Allow setting an empty members list in `loadbalancer/v2/pools.BatchUpdateMembers` [GH-1736](https://github.com/gophercloud/gophercloud/pull/1736)
-* Allow unsetting members' subnet ID and name in `loadbalancer/v2/pools.BatchUpdateMemberOpts` [GH-1738](https://github.com/gophercloud/gophercloud/pull/1738)
-
-BUG FIXES
-
-* Changed struct type for options in `networking/v2/extensions/lbaas_v2/listeners` to `UpdateOptsBuilder` interface instead of specific UpdateOpts type [GH-1705](https://github.com/gophercloud/gophercloud/pull/1705)
-* Changed struct type for options in `networking/v2/extensions/lbaas_v2/loadbalancers` to `UpdateOptsBuilder` interface instead of specific UpdateOpts type [GH-1706](https://github.com/gophercloud/gophercloud/pull/1706)
-* Fixed issue with `blockstorage/v1/volumes.Create` where the response was expected to be 202 [GH-1720](https://github.com/gophercloud/gophercloud/pull/1720)
-* Changed `DefaultTlsContainerRef` from `string` to `*string` in `loadbalancer/v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723)
-* Changed `SniContainerRefs` from `[]string{}` to `*[]string{}` in `loadbalancer/v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723)
-* Changed `DefaultTlsContainerRef` from `string` to `*string` in `networking/v2/extensions/lbaas_v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723)
-* Changed `SniContainerRefs` from `[]string{}` to `*[]string{}` in `networking/v2/extensions/lbaas_v2/listeners.UpdateOpts` to allow the value to be removed during update. [GH-1723](https://github.com/gophercloud/gophercloud/pull/1723)
-
-
-## 0.4.0 (September 3, 2019)
-
-IMPROVEMENTS
-
-* Added `blockstorage/extensions/quotasets.results.QuotaSet.Groups` [GH-1668](https://github.com/gophercloud/gophercloud/pull/1668)
-* Added `blockstorage/extensions/quotasets.results.QuotaUsageSet.Groups` [GH-1668](https://github.com/gophercloud/gophercloud/pull/1668)
-* Added `containerinfra/v1/clusters.CreateOpts.FixedNetwork` [GH-1674](https://github.com/gophercloud/gophercloud/pull/1674)
-* Added `containerinfra/v1/clusters.CreateOpts.FixedSubnet` [GH-1676](https://github.com/gophercloud/gophercloud/pull/1676)
-* Added `containerinfra/v1/clusters.CreateOpts.FloatingIPEnabled` [GH-1677](https://github.com/gophercloud/gophercloud/pull/1677)
-* Added `CreatedAt` and `UpdatedAt` to `loadbalancers/v2/loadbalancers.LoadBalancer` [GH-1681](https://github.com/gophercloud/gophercloud/pull/1681)
-* Added `networking/v2/extensions/layer3/portforwarding.Create` [GH-1651](https://github.com/gophercloud/gophercloud/pull/1651)
-* Added `networking/v2/extensions/agents.ListDHCPNetworks` [GH-1686](https://github.com/gophercloud/gophercloud/pull/1686)
-* Added `networking/v2/extensions/layer3/portforwarding.Delete` [GH-1652](https://github.com/gophercloud/gophercloud/pull/1652)
-* Added `compute/v2/extensions/tags.List` [GH-1679](https://github.com/gophercloud/gophercloud/pull/1679)
-* Added `compute/v2/extensions/tags.Check` [GH-1679](https://github.com/gophercloud/gophercloud/pull/1679)
-
-BUG FIXES
-
-* Changed `identity/v3/endpoints.ListOpts.RegionID` from `int` to `string` [GH-1664](https://github.com/gophercloud/gophercloud/pull/1664)
-* Fixed issue where older time formats in some networking APIs/resources were unable to be parsed [GH-1671](https://github.com/gophercloud/gophercloud/pull/1664)
-* Changed `SATA`, `SCSI`, and `SAS` types to `InterfaceType` in `baremetal/v1/nodes` [GH-1683]
-
-## 0.3.0 (July 31, 2019)
-
-IMPROVEMENTS
-
-* Added `baremetal/apiversions.List` [GH-1577](https://github.com/gophercloud/gophercloud/pull/1577)
-* Added `baremetal/apiversions.Get` [GH-1577](https://github.com/gophercloud/gophercloud/pull/1577)
-* Added `compute/v2/extensions/servergroups.CreateOpts.Policy` [GH-1636](https://github.com/gophercloud/gophercloud/pull/1636)
-* Added `identity/v3/extensions/trusts.Create` [GH-1644](https://github.com/gophercloud/gophercloud/pull/1644)
-* Added `identity/v3/extensions/trusts.Delete` [GH-1644](https://github.com/gophercloud/gophercloud/pull/1644)
-* Added `CreatedAt` and `UpdatedAt` to `networking/v2/extensions/layer3/floatingips.FloatingIP` [GH-1647](https://github.com/gophercloud/gophercloud/issues/1646)
-* Added `CreatedAt` and `UpdatedAt` to `networking/v2/extensions/security/groups.SecGroup` [GH-1654](https://github.com/gophercloud/gophercloud/issues/1654)
-* Added `CreatedAt` and `UpdatedAt` to `networking/v2/networks.Network` [GH-1657](https://github.com/gophercloud/gophercloud/issues/1657)
-* Added `keymanager/v1/containers.CreateSecretRef` [GH-1659](https://github.com/gophercloud/gophercloud/issues/1659)
-* Added `keymanager/v1/containers.DeleteSecretRef` [GH-1659](https://github.com/gophercloud/gophercloud/issues/1659)
-* Added `sharedfilesystems/v2/shares.GetMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656)
-* Added `sharedfilesystems/v2/shares.GetMetadatum` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656)
-* Added `sharedfilesystems/v2/shares.SetMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656)
-* Added `sharedfilesystems/v2/shares.UpdateMetadata` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656)
-* Added `sharedfilesystems/v2/shares.DeleteMetadatum` [GH-1656](https://github.com/gophercloud/gophercloud/issues/1656)
-* Added `sharedfilesystems/v2/sharetypes.IDFromName` [GH-1662](https://github.com/gophercloud/gophercloud/issues/1662)
-
-
-
-BUG FIXES
-
-* Changed `baremetal/v1/nodes.CleanStep.Args` from `map[string]string` to `map[string]interface{}` [GH-1638](https://github.com/gophercloud/gophercloud/pull/1638)
-* Removed `URLPath` and `ExpectedCodes` from `loadbalancer/v2/monitors.ToMonitorCreateMap` since Octavia now provides default values when these fields are not specified [GH-1640](https://github.com/gophercloud/gophercloud/pull/1540)
-
-
-## 0.2.0 (June 17, 2019)
-
-IMPROVEMENTS
-
-* Added `networking/v2/extensions/qos/rules.ListBandwidthLimitRules` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584)
-* Added `networking/v2/extensions/qos/rules.GetBandwidthLimitRule` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584)
-* Added `networking/v2/extensions/qos/rules.CreateBandwidthLimitRule` [GH-1584](https://github.com/gophercloud/gophercloud/pull/1584)
-* Added `networking/v2/extensions/qos/rules.UpdateBandwidthLimitRule` [GH-1589](https://github.com/gophercloud/gophercloud/pull/1589)
-* Added `networking/v2/extensions/qos/rules.DeleteBandwidthLimitRule` [GH-1590](https://github.com/gophercloud/gophercloud/pull/1590)
-* Added `networking/v2/extensions/qos/policies.List` [GH-1591](https://github.com/gophercloud/gophercloud/pull/1591)
-* Added `networking/v2/extensions/qos/policies.Get` [GH-1593](https://github.com/gophercloud/gophercloud/pull/1593)
-* Added `networking/v2/extensions/qos/rules.ListDSCPMarkingRules` [GH-1594](https://github.com/gophercloud/gophercloud/pull/1594)
-* Added `networking/v2/extensions/qos/policies.Create` [GH-1595](https://github.com/gophercloud/gophercloud/pull/1595)
-* Added `compute/v2/extensions/diagnostics.Get` [GH-1592](https://github.com/gophercloud/gophercloud/pull/1592)
-* Added `networking/v2/extensions/qos/policies.Update` [GH-1603](https://github.com/gophercloud/gophercloud/pull/1603)
-* Added `networking/v2/extensions/qos/policies.Delete` [GH-1603](https://github.com/gophercloud/gophercloud/pull/1603)
-* Added `networking/v2/extensions/qos/rules.CreateDSCPMarkingRule` [GH-1605](https://github.com/gophercloud/gophercloud/pull/1605)
-* Added `networking/v2/extensions/qos/rules.UpdateDSCPMarkingRule` [GH-1605](https://github.com/gophercloud/gophercloud/pull/1605)
-* Added `networking/v2/extensions/qos/rules.GetDSCPMarkingRule` [GH-1609](https://github.com/gophercloud/gophercloud/pull/1609)
-* Added `networking/v2/extensions/qos/rules.DeleteDSCPMarkingRule` [GH-1609](https://github.com/gophercloud/gophercloud/pull/1609)
-* Added `networking/v2/extensions/qos/rules.ListMinimumBandwidthRules` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615)
-* Added `networking/v2/extensions/qos/rules.GetMinimumBandwidthRule` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615)
-* Added `networking/v2/extensions/qos/rules.CreateMinimumBandwidthRule` [GH-1615](https://github.com/gophercloud/gophercloud/pull/1615)
-* Added `Hostname` to `baremetalintrospection/v1/introspection.Data` [GH-1627](https://github.com/gophercloud/gophercloud/pull/1627)
-* Added `networking/v2/extensions/qos/rules.UpdateMinimumBandwidthRule` [GH-1624](https://github.com/gophercloud/gophercloud/pull/1624)
-* Added `networking/v2/extensions/qos/rules.DeleteMinimumBandwidthRule` [GH-1624](https://github.com/gophercloud/gophercloud/pull/1624)
-* Added `networking/v2/extensions/qos/ruletypes.GetRuleType` [GH-1625](https://github.com/gophercloud/gophercloud/pull/1625)
-* Added `Extra` to `baremetalintrospection/v1/introspection.Data` [GH-1611](https://github.com/gophercloud/gophercloud/pull/1611)
-* Added `blockstorage/extensions/volumeactions.SetImageMetadata` [GH-1621](https://github.com/gophercloud/gophercloud/pull/1621)
-
-BUG FIXES
-
-* Updated `networking/v2/extensions/qos/rules.UpdateBandwidthLimitRule` to use return code 200 [GH-1606](https://github.com/gophercloud/gophercloud/pull/1606)
-* Fixed bug in `compute/v2/extensions/schedulerhints.SchedulerHints.Query` where contents will now be marshalled to a string [GH-1620](https://github.com/gophercloud/gophercloud/pull/1620)
-
-## 0.1.0 (May 27, 2019)
-
-Initial tagged release.
diff --git a/vendor/github.com/gophercloud/gophercloud/auth_options.go b/vendor/github.com/gophercloud/gophercloud/auth_options.go
index 4f301305e..5ffa8d1e0 100644
--- a/vendor/github.com/gophercloud/gophercloud/auth_options.go
+++ b/vendor/github.com/gophercloud/gophercloud/auth_options.go
@@ -45,9 +45,6 @@ type AuthOptions struct {
Password string `json:"password,omitempty"`
- // Passcode is used in TOTP authentication method
- Passcode string `json:"passcode,omitempty"`
-
// At most one of DomainID and DomainName must be provided if using Username
// with Identity V3. Otherwise, either are optional.
DomainID string `json:"-"`
@@ -101,7 +98,6 @@ type AuthScope struct {
ProjectName string
DomainID string
DomainName string
- System bool
}
// ToTokenV2CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
@@ -137,8 +133,6 @@ func (opts AuthOptions) ToTokenV2CreateMap() (map[string]interface{}, error) {
return map[string]interface{}{"auth": authMap}, nil
}
-// ToTokenV3CreateMap allows AuthOptions to satisfy the AuthOptionsBuilder
-// interface in the v3 tokens package
func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
type domainReq struct {
ID *string `json:"id,omitempty"`
@@ -154,8 +148,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
type userReq struct {
ID *string `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
- Password *string `json:"password,omitempty"`
- Passcode *string `json:"passcode,omitempty"`
+ Password string `json:"password,omitempty"`
Domain *domainReq `json:"domain,omitempty"`
}
@@ -174,16 +167,11 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
Secret *string `json:"secret,omitempty"`
}
- type totpReq struct {
- User *userReq `json:"user,omitempty"`
- }
-
type identityReq struct {
Methods []string `json:"methods"`
Password *passwordReq `json:"password,omitempty"`
Token *tokenReq `json:"token,omitempty"`
ApplicationCredential *applicationCredentialReq `json:"application_credential,omitempty"`
- TOTP *totpReq `json:"totp,omitempty"`
}
type authReq struct {
@@ -198,7 +186,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
// if insufficient or incompatible information is present.
var req request
- if opts.Password == "" && opts.Passcode == "" {
+ if opts.Password == "" {
if opts.TokenID != "" {
// Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
// parameters.
@@ -286,14 +274,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
}
} else {
// Password authentication.
- if opts.Password != "" {
- req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "password")
- }
-
- // TOTP authentication.
- if opts.Passcode != "" {
- req.Auth.Identity.Methods = append(req.Auth.Identity.Methods, "totp")
- }
+ req.Auth.Identity.Methods = []string{"password"}
// At least one of Username and UserID must be specified.
if opts.Username == "" && opts.UserID == "" {
@@ -317,46 +298,23 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
}
// Configure the request for Username and Password authentication with a DomainID.
- if opts.Password != "" {
- req.Auth.Identity.Password = &passwordReq{
- User: userReq{
- Name: &opts.Username,
- Password: &opts.Password,
- Domain: &domainReq{ID: &opts.DomainID},
- },
- }
- }
- if opts.Passcode != "" {
- req.Auth.Identity.TOTP = &totpReq{
- User: &userReq{
- Name: &opts.Username,
- Passcode: &opts.Passcode,
- Domain: &domainReq{ID: &opts.DomainID},
- },
- }
+ req.Auth.Identity.Password = &passwordReq{
+ User: userReq{
+ Name: &opts.Username,
+ Password: opts.Password,
+ Domain: &domainReq{ID: &opts.DomainID},
+ },
}
}
if opts.DomainName != "" {
// Configure the request for Username and Password authentication with a DomainName.
- if opts.Password != "" {
- req.Auth.Identity.Password = &passwordReq{
- User: userReq{
- Name: &opts.Username,
- Password: &opts.Password,
- Domain: &domainReq{Name: &opts.DomainName},
- },
- }
- }
-
- if opts.Passcode != "" {
- req.Auth.Identity.TOTP = &totpReq{
- User: &userReq{
- Name: &opts.Username,
- Passcode: &opts.Passcode,
- Domain: &domainReq{Name: &opts.DomainName},
- },
- }
+ req.Auth.Identity.Password = &passwordReq{
+ User: userReq{
+ Name: &opts.Username,
+ Password: opts.Password,
+ Domain: &domainReq{Name: &opts.DomainName},
+ },
}
}
}
@@ -371,22 +329,8 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
}
// Configure the request for UserID and Password authentication.
- if opts.Password != "" {
- req.Auth.Identity.Password = &passwordReq{
- User: userReq{
- ID: &opts.UserID,
- Password: &opts.Password,
- },
- }
- }
-
- if opts.Passcode != "" {
- req.Auth.Identity.TOTP = &totpReq{
- User: &userReq{
- ID: &opts.UserID,
- Passcode: &opts.Passcode,
- },
- }
+ req.Auth.Identity.Password = &passwordReq{
+ User: userReq{ID: &opts.UserID, Password: opts.Password},
}
}
}
@@ -403,8 +347,6 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
return b, nil
}
-// ToTokenV3ScopeMap builds a scope from AuthOptions and satisfies interface in
-// the v3 tokens package.
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
// For backwards compatibility.
// If AuthOptions.Scope was not set, try to determine it.
@@ -422,14 +364,6 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
}
}
- if opts.Scope.System {
- return map[string]interface{}{
- "system": map[string]interface{}{
- "all": true,
- },
- }, nil
- }
-
if opts.Scope.ProjectName != "" {
// ProjectName provided: either DomainID or DomainName must also be supplied.
// ProjectID may not be supplied.
@@ -499,16 +433,5 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
}
func (opts AuthOptions) CanReauth() bool {
- if opts.Passcode != "" {
- // cannot reauth using TOTP passcode
- return false
- }
-
return opts.AllowReauth
}
-
-// ToTokenV3HeadersMap allows AuthOptions to satisfy the AuthOptionsBuilder
-// interface in the v3 tokens package.
-func (opts *AuthOptions) ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error) {
- return nil, nil
-}
diff --git a/vendor/github.com/gophercloud/gophercloud/errors.go b/vendor/github.com/gophercloud/gophercloud/errors.go
index 77cabf6a9..0bcb3af7f 100644
--- a/vendor/github.com/gophercloud/gophercloud/errors.go
+++ b/vendor/github.com/gophercloud/gophercloud/errors.go
@@ -2,7 +2,6 @@ package gophercloud
import (
"fmt"
- "net/http"
"strings"
)
@@ -78,12 +77,11 @@ func (e ErrMissingAnyoneOfEnvironmentVariables) Error() string {
// those listed in OkCodes is encountered.
type ErrUnexpectedResponseCode struct {
BaseError
- URL string
- Method string
- Expected []int
- Actual int
- Body []byte
- ResponseHeader http.Header
+ URL string
+ Method string
+ Expected []int
+ Actual int
+ Body []byte
}
func (e ErrUnexpectedResponseCode) Error() string {
@@ -94,23 +92,6 @@ func (e ErrUnexpectedResponseCode) Error() string {
return e.choseErrString()
}
-// GetStatusCode returns the actual status code of the error.
-func (e ErrUnexpectedResponseCode) GetStatusCode() int {
- return e.Actual
-}
-
-// StatusCodeError is a convenience interface to easily allow access to the
-// status code field of the various ErrDefault* types.
-//
-// By using this interface, you only have to make a single type cast of
-// the returned error to err.(StatusCodeError) and then call GetStatusCode()
-// instead of having a large switch statement checking for each of the
-// ErrDefault* types.
-type StatusCodeError interface {
- Error() string
- GetStatusCode() int
-}
-
// ErrDefault400 is the default error type returned on a 400 HTTP response code.
type ErrDefault400 struct {
ErrUnexpectedResponseCode
diff --git a/vendor/github.com/gophercloud/gophercloud/go.mod b/vendor/github.com/gophercloud/gophercloud/go.mod
index 46e16507d..d1ee3b472 100644
--- a/vendor/github.com/gophercloud/gophercloud/go.mod
+++ b/vendor/github.com/gophercloud/gophercloud/go.mod
@@ -1,13 +1,7 @@
module github.com/gophercloud/gophercloud
require (
- golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e
- golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933 // indirect
- golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
- golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9 // indirect
- golang.org/x/text v0.3.2 // indirect
- golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371 // indirect
- golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 // indirect
- gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
- gopkg.in/yaml.v2 v2.2.7
+ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67
+ golang.org/x/sys v0.0.0-20190209173611-3b5209105503 // indirect
+ gopkg.in/yaml.v2 v2.2.2
)
diff --git a/vendor/github.com/gophercloud/gophercloud/go.sum b/vendor/github.com/gophercloud/gophercloud/go.sum
index 9a0b94de1..33cb0be8a 100644
--- a/vendor/github.com/gophercloud/gophercloud/go.sum
+++ b/vendor/github.com/gophercloud/gophercloud/go.sum
@@ -1,26 +1,8 @@
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e h1:egKlR8l7Nu9vHGWbcUV8lqR4987UfUbBd7GbhqGzNYU=
-golang.org/x/crypto v0.0.0-20191202143827-86a70503ff7e/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-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/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE=
+golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/sys v0.0.0-20190209173611-3b5209105503 h1:5SvYFrOM3W8Mexn9/oA44Ji7vhXAZQ9hiP+1Q/DMrWg=
+golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
-gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go
index c801de555..0e8d90ff8 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go
@@ -38,7 +38,6 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
username := os.Getenv("OS_USERNAME")
userID := os.Getenv("OS_USERID")
password := os.Getenv("OS_PASSWORD")
- passcode := os.Getenv("OS_PASSCODE")
tenantID := os.Getenv("OS_TENANT_ID")
tenantName := os.Getenv("OS_TENANT_NAME")
domainID := os.Getenv("OS_DOMAIN_ID")
@@ -74,9 +73,8 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
}
}
- if password == "" && passcode == "" && applicationCredentialID == "" && applicationCredentialName == "" {
+ if password == "" && applicationCredentialID == "" && applicationCredentialName == "" {
err := gophercloud.ErrMissingEnvironmentVariable{
- // silently ignore TOTP passcode warning, since it is not a common auth method
EnvironmentVariable: "OS_PASSWORD",
}
return nilOptions, err
@@ -114,7 +112,6 @@ func AuthOptionsFromEnv() (gophercloud.AuthOptions, error) {
UserID: userID,
Username: username,
Password: password,
- Passcode: passcode,
TenantID: tenantID,
TenantName: tenantName,
DomainID: domainID,
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/client.go b/vendor/github.com/gophercloud/gophercloud/openstack/client.go
index 655a9f6b9..50f239711 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/client.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/client.go
@@ -3,12 +3,9 @@ package openstack
import (
"fmt"
"reflect"
- "strings"
"github.com/gophercloud/gophercloud"
tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
- "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens"
- "github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1"
tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
"github.com/gophercloud/gophercloud/openstack/utils"
)
@@ -70,7 +67,7 @@ Example:
ao, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(ao)
- client, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
+ client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
*/
@@ -190,61 +187,16 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
v3Client.Endpoint = endpoint
}
- var catalog *tokens3.ServiceCatalog
-
- var tokenID string
- // passthroughToken allows to passthrough the token without a scope
- var passthroughToken bool
- switch v := opts.(type) {
- case *gophercloud.AuthOptions:
- tokenID = v.TokenID
- passthroughToken = (v.Scope == nil || *v.Scope == gophercloud.AuthScope{})
- case *tokens3.AuthOptions:
- tokenID = v.TokenID
- passthroughToken = (v.Scope == tokens3.Scope{})
- }
-
- if tokenID != "" && passthroughToken {
- // passing through the token ID without requesting a new scope
- if opts.CanReauth() {
- return fmt.Errorf("cannot use AllowReauth, when the token ID is defined and auth scope is not set")
- }
-
- v3Client.SetToken(tokenID)
- result := tokens3.Get(v3Client, tokenID)
- if result.Err != nil {
- return result.Err
- }
-
- err = client.SetTokenAndAuthResult(result)
- if err != nil {
- return err
- }
-
- catalog, err = result.ExtractServiceCatalog()
- if err != nil {
- return err
- }
- } else {
- var result tokens3.CreateResult
- switch opts.(type) {
- case *ec2tokens.AuthOptions:
- result = ec2tokens.Create(v3Client, opts)
- case *oauth1.AuthOptions:
- result = oauth1.Create(v3Client, opts)
- default:
- result = tokens3.Create(v3Client, opts)
- }
+ result := tokens3.Create(v3Client, opts)
- err = client.SetTokenAndAuthResult(result)
- if err != nil {
- return err
- }
+ err = client.SetTokenAndAuthResult(result)
+ if err != nil {
+ return err
+ }
- catalog, err = result.ExtractServiceCatalog()
- if err != nil {
- return err
- }
+ catalog, err := result.ExtractServiceCatalog()
+ if err != nil {
+ return err
}
if opts.CanReauth() {
@@ -265,14 +217,6 @@ func v3auth(client *gophercloud.ProviderClient, endpoint string, opts tokens3.Au
o := *ot
o.AllowReauth = false
tao = &o
- case *ec2tokens.AuthOptions:
- o := *ot
- o.AllowReauth = false
- tao = &o
- case *oauth1.AuthOptions:
- o := *ot
- o.AllowReauth = false
- tao = &o
default:
tao = opts
}
@@ -451,11 +395,7 @@ func NewImageServiceV2(client *gophercloud.ProviderClient, eo gophercloud.Endpoi
// load balancer service.
func NewLoadBalancerV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
sc, err := initClientOpts(client, eo, "load-balancer")
-
- // Fixes edge case having an OpenStack lb endpoint with trailing version number.
- endpoint := strings.Replace(sc.Endpoint, "v2.0/", "", -1)
-
- sc.ResourceBase = endpoint + "v2.0/"
+ sc.ResourceBase = sc.Endpoint + "v2.0/"
return sc, err
}
@@ -496,8 +436,3 @@ func NewContainerInfraV1(client *gophercloud.ProviderClient, eo gophercloud.Endp
func NewWorkflowV2(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
return initClientOpts(client, eo, "workflowv2")
}
-
-// NewPlacementV1 creates a ServiceClient that may be used with the placement package.
-func NewPlacementV1(client *gophercloud.ProviderClient, eo gophercloud.EndpointOpts) (*gophercloud.ServiceClient, error) {
- return initClientOpts(client, eo, "placement")
-}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/doc.go
index af4bd512b..cedf1f4d3 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/doc.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/doc.go
@@ -7,7 +7,7 @@ Example of Creating a Service Client
ao, err := openstack.AuthOptionsFromEnv()
provider, err := openstack.AuthenticatedClient(ao)
- client, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{
+ client, err := openstack.NewNetworkV2(client, gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
})
*/
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go b/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go
index 509700790..12c8aebcf 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go
@@ -29,12 +29,11 @@ func V2EndpointURL(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpt
}
}
- // If multiple endpoints were found, use the first result
- // and disregard the other endpoints.
- //
- // This behavior matches the Python library. See GH-1764.
+ // Report an error if the options were ambiguous.
if len(endpoints) > 1 {
- endpoints = endpoints[0:1]
+ err := &ErrMultipleMatchingEndpointsV2{}
+ err.Endpoints = endpoints
+ return "", err
}
// Extract the appropriate URL from the matching Endpoint.
@@ -92,12 +91,9 @@ func V3EndpointURL(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpt
}
}
- // If multiple endpoints were found, use the first result
- // and disregard the other endpoints.
- //
- // This behavior matches the Python library. See GH-1764.
+ // Report an error if the options were ambiguous.
if len(endpoints) > 1 {
- endpoints = endpoints[0:1]
+ return "", ErrMultipleMatchingEndpointsV3{Endpoints: endpoints}
}
// Extract the URL from the matching Endpoint.
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/errors.go b/vendor/github.com/gophercloud/gophercloud/openstack/errors.go
index cba6ae5f0..df410b1c6 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/errors.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/errors.go
@@ -4,6 +4,8 @@ import (
"fmt"
"github.com/gophercloud/gophercloud"
+ tokens2 "github.com/gophercloud/gophercloud/openstack/identity/v2/tokens"
+ tokens3 "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
)
// ErrEndpointNotFound is the error when no suitable endpoint can be found
@@ -22,6 +24,28 @@ func (e ErrInvalidAvailabilityProvided) Error() string {
return fmt.Sprintf("Unexpected availability in endpoint query: %s", e.Value)
}
+// ErrMultipleMatchingEndpointsV2 is the error when more than one endpoint
+// for the given options is found in the v2 catalog
+type ErrMultipleMatchingEndpointsV2 struct {
+ gophercloud.BaseError
+ Endpoints []tokens2.Endpoint
+}
+
+func (e ErrMultipleMatchingEndpointsV2) Error() string {
+ return fmt.Sprintf("Discovered %d matching endpoints: %#v", len(e.Endpoints), e.Endpoints)
+}
+
+// ErrMultipleMatchingEndpointsV3 is the error when more than one endpoint
+// for the given options is found in the v3 catalog
+type ErrMultipleMatchingEndpointsV3 struct {
+ gophercloud.BaseError
+ Endpoints []tokens3.Endpoint
+}
+
+func (e ErrMultipleMatchingEndpointsV3) Error() string {
+ return fmt.Sprintf("Discovered %d matching endpoints: %#v", len(e.Endpoints), e.Endpoints)
+}
+
// ErrNoAuthURL is the error when the OS_AUTH_URL environment variable is not
// found
type ErrNoAuthURL struct{ gophercloud.ErrInvalidInput }
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
index f16df38e5..f21a58f10 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
@@ -60,17 +60,15 @@ func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r Create
r.Err = err
return
}
- resp, err := client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
+ _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 201},
})
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}
// Get requests details on a single tenant by ID.
func Get(client *gophercloud.ServiceClient, id string) (r GetResult) {
- resp, err := client.Get(getURL(client, id), &r.Body, nil)
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
+ _, r.Err = client.Get(getURL(client, id), &r.Body, nil)
return
}
@@ -105,16 +103,14 @@ func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder
r.Err = err
return
}
- resp, err := client.Put(updateURL(client, id), &b, &r.Body, &gophercloud.RequestOpts{
+ _, r.Err = client.Put(updateURL(client, id), &b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200},
})
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}
// Delete is the operation responsible for permanently deleting a tenant.
func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) {
- resp, err := client.Delete(deleteURL(client, id), nil)
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
+ _, r.Err = client.Delete(deleteURL(client, id), nil)
return
}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
index 2b64f108c..ab32368cc 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
@@ -87,19 +87,17 @@ func Create(client *gophercloud.ServiceClient, auth AuthOptionsBuilder) (r Creat
r.Err = err
return
}
- resp, err := client.Post(CreateURL(client), b, &r.Body, &gophercloud.RequestOpts{
+ _, r.Err = client.Post(CreateURL(client), b, &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 203},
MoreHeaders: map[string]string{"X-Auth-Token": ""},
})
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}
// Get validates and retrieves information for user's token.
func Get(client *gophercloud.ServiceClient, token string) (r GetResult) {
- resp, err := client.Get(GetURL(client, token), &r.Body, &gophercloud.RequestOpts{
+ _, r.Err = client.Get(GetURL(client, token), &r.Body, &gophercloud.RequestOpts{
OkCodes: []int{200, 203},
})
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/doc.go
deleted file mode 100644
index 1f6f807fe..000000000
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/doc.go
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
-Package tokens provides information and interaction with the EC2 token API
-resource for the OpenStack Identity service.
-
-For more information, see:
-https://docs.openstack.org/api-ref/identity/v2-ext/
-
-Example to Create a Token From an EC2 access and secret keys
-
- var authOptions tokens.AuthOptionsBuilder
- authOptions = &ec2tokens.AuthOptions{
- Access: "a7f1e798b7c2417cba4a02de97dc3cdc",
- Secret: "18f4f6761ada4e3795fa5273c30349b9",
- }
-
- token, err := ec2tokens.Create(identityClient, authOptions).ExtractToken()
- if err != nil {
- panic(err)
- }
-
-Example to auth a client using EC2 access and secret keys
-
- client, err := openstack.NewClient("http://localhost:5000/v3")
- if err != nil {
- panic(err)
- }
-
- var authOptions tokens.AuthOptionsBuilder
- authOptions = &ec2tokens.AuthOptions{
- Access: "a7f1e798b7c2417cba4a02de97dc3cdc",
- Secret: "18f4f6761ada4e3795fa5273c30349b9",
- AllowReauth: true,
- }
-
- err = openstack.AuthenticateV3(client, authOptions, gophercloud.EndpointOpts{})
- if err != nil {
- panic(err)
- }
-
-*/
-package ec2tokens
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/requests.go
deleted file mode 100644
index 32ba0e621..000000000
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/requests.go
+++ /dev/null
@@ -1,377 +0,0 @@
-package ec2tokens
-
-import (
- "crypto/hmac"
- "crypto/sha1"
- "crypto/sha256"
- "encoding/hex"
- "fmt"
- "math/rand"
- "net/url"
- "sort"
- "strings"
- "time"
-
- "github.com/gophercloud/gophercloud"
- "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
-)
-
-const (
- // EC2CredentialsAwsRequestV4 is a constant, used to generate AWS
- // Credential V4.
- EC2CredentialsAwsRequestV4 = "aws4_request"
- // EC2CredentialsHmacSha1V2 is a HMAC SHA1 signature method. Used to
- // generate AWS Credential V2.
- EC2CredentialsHmacSha1V2 = "HmacSHA1"
- // EC2CredentialsHmacSha256V2 is a HMAC SHA256 signature method. Used
- // to generate AWS Credential V2.
- EC2CredentialsHmacSha256V2 = "HmacSHA256"
- // EC2CredentialsAwsHmacV4 is an AWS signature V4 signing method.
- // More details:
- // https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
- EC2CredentialsAwsHmacV4 = "AWS4-HMAC-SHA256"
- // EC2CredentialsTimestampFormatV4 is an AWS signature V4 timestamp
- // format.
- EC2CredentialsTimestampFormatV4 = "20060102T150405Z"
- // EC2CredentialsDateFormatV4 is an AWS signature V4 date format.
- EC2CredentialsDateFormatV4 = "20060102"
-)
-
-// AuthOptions represents options for authenticating a user using EC2 credentials.
-type AuthOptions struct {
- // Access is the EC2 Credential Access ID.
- Access string `json:"access" required:"true"`
- // Secret is the EC2 Credential Secret, used to calculate signature.
- // Not used, when a Signature is is.
- Secret string `json:"-"`
- // Host is a HTTP request Host header. Used to calculate an AWS
- // signature V2. For signature V4 set the Host inside Headers map.
- // Optional.
- Host string `json:"host"`
- // Path is a HTTP request path. Optional.
- Path string `json:"path"`
- // Verb is a HTTP request method. Optional.
- Verb string `json:"verb"`
- // Headers is a map of HTTP request headers. Optional.
- Headers map[string]string `json:"headers"`
- // Region is a region name to calculate an AWS signature V4. Optional.
- Region string `json:"-"`
- // Service is a service name to calculate an AWS signature V4. Optional.
- Service string `json:"-"`
- // Params is a map of GET method parameters. Optional.
- Params map[string]string `json:"params"`
- // AllowReauth allows Gophercloud to re-authenticate automatically
- // if/when your token expires.
- AllowReauth bool `json:"-"`
- // Signature can be either a []byte (encoded to base64 automatically) or
- // a string. You can set the singature explicitly, when you already know
- // it. In this case default Params won't be automatically set. Optional.
- Signature interface{} `json:"signature"`
- // BodyHash is a HTTP request body sha256 hash. When nil and Signature
- // is not set, a random hash is generated. Optional.
- BodyHash *string `json:"body_hash"`
- // Timestamp is a timestamp to calculate a V4 signature. Optional.
- Timestamp *time.Time `json:"-"`
- // Token is a []byte string (encoded to base64 automatically) which was
- // signed by an EC2 secret key. Used by S3 tokens for validation only.
- // Token must be set with a Signature. If a Signature is not provided,
- // a Token will be generated automatically along with a Signature.
- Token []byte `json:"token,omitempty"`
-}
-
-// EC2CredentialsBuildCanonicalQueryStringV2 builds a canonical query string
-// for an AWS signature V2.
-// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L133
-func EC2CredentialsBuildCanonicalQueryStringV2(params map[string]string) string {
- var keys []string
- for k := range params {
- keys = append(keys, k)
- }
- sort.Strings(keys)
-
- var pairs []string
- for _, k := range keys {
- pairs = append(pairs, fmt.Sprintf("%s=%s", k, url.QueryEscape(params[k])))
- }
-
- return strings.Join(pairs, "&")
-}
-
-// EC2CredentialsBuildStringToSignV2 builds a string to sign an AWS signature
-// V2.
-// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L148
-func EC2CredentialsBuildStringToSignV2(opts AuthOptions) []byte {
- stringToSign := strings.Join([]string{
- opts.Verb,
- opts.Host,
- opts.Path,
- }, "\n")
-
- return []byte(strings.Join([]string{
- stringToSign,
- EC2CredentialsBuildCanonicalQueryStringV2(opts.Params),
- }, "\n"))
-}
-
-// EC2CredentialsBuildCanonicalQueryStringV2 builds a canonical query string
-// for an AWS signature V4.
-// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L244
-func EC2CredentialsBuildCanonicalQueryStringV4(verb string, params map[string]string) string {
- if verb == "POST" {
- return ""
- }
- return EC2CredentialsBuildCanonicalQueryStringV2(params)
-}
-
-// EC2CredentialsBuildCanonicalHeadersV4 builds a canonical string based on
-// "headers" map and "signedHeaders" string parameters.
-// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L216
-func EC2CredentialsBuildCanonicalHeadersV4(headers map[string]string, signedHeaders string) string {
- headersLower := make(map[string]string, len(headers))
- for k, v := range headers {
- headersLower[strings.ToLower(k)] = v
- }
-
- var headersList []string
- for _, h := range strings.Split(signedHeaders, ";") {
- if v, ok := headersLower[h]; ok {
- headersList = append(headersList, h+":"+v)
- }
- }
-
- return strings.Join(headersList, "\n") + "\n"
-}
-
-// EC2CredentialsBuildSignatureKeyV4 builds a HMAC 256 signature key based on
-// input parameters.
-// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L169
-func EC2CredentialsBuildSignatureKeyV4(secret, region, service string, date time.Time) []byte {
- kDate := sumHMAC256([]byte("AWS4"+secret), []byte(date.Format(EC2CredentialsDateFormatV4)))
- kRegion := sumHMAC256(kDate, []byte(region))
- kService := sumHMAC256(kRegion, []byte(service))
- return sumHMAC256(kService, []byte(EC2CredentialsAwsRequestV4))
-}
-
-// EC2CredentialsBuildStringToSignV4 builds an AWS v4 signature string to sign
-// based on input parameters.
-// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L251
-func EC2CredentialsBuildStringToSignV4(opts AuthOptions, signedHeaders string, bodyHash string, date time.Time) []byte {
- scope := strings.Join([]string{
- date.Format(EC2CredentialsDateFormatV4),
- opts.Region,
- opts.Service,
- EC2CredentialsAwsRequestV4,
- }, "/")
-
- canonicalRequest := strings.Join([]string{
- opts.Verb,
- opts.Path,
- EC2CredentialsBuildCanonicalQueryStringV4(opts.Verb, opts.Params),
- EC2CredentialsBuildCanonicalHeadersV4(opts.Headers, signedHeaders),
- signedHeaders,
- bodyHash,
- }, "\n")
- hash := sha256.Sum256([]byte(canonicalRequest))
-
- return []byte(strings.Join([]string{
- EC2CredentialsAwsHmacV4,
- date.Format(EC2CredentialsTimestampFormatV4),
- scope,
- hex.EncodeToString(hash[:]),
- }, "\n"))
-}
-
-// EC2CredentialsBuildSignatureV4 builds an AWS v4 signature based on input
-// parameters.
-// https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L285..L286
-func EC2CredentialsBuildSignatureV4(key []byte, stringToSign []byte) string {
- return hex.EncodeToString(sumHMAC256(key, stringToSign))
-}
-
-// EC2CredentialsBuildAuthorizationHeaderV4 builds an AWS v4 Authorization
-// header based on auth parameters, date and signature
-func EC2CredentialsBuildAuthorizationHeaderV4(opts AuthOptions, signedHeaders string, signature string, date time.Time) string {
- return fmt.Sprintf("%s Credential=%s/%s/%s/%s/%s, SignedHeaders=%s, Signature=%s",
- EC2CredentialsAwsHmacV4,
- opts.Access,
- date.Format(EC2CredentialsDateFormatV4),
- opts.Region,
- opts.Service,
- EC2CredentialsAwsRequestV4,
- signedHeaders,
- signature)
-}
-
-// ToTokenV3ScopeMap is a dummy method to satisfy tokens.AuthOptionsBuilder
-// interface.
-func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
- return nil, nil
-}
-
-// ToTokenV3HeadersMap allows AuthOptions to satisfy the AuthOptionsBuilder
-// interface in the v3 tokens package.
-func (opts *AuthOptions) ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error) {
- return nil, nil
-}
-
-// CanReauth is a method method to satisfy tokens.AuthOptionsBuilder interface
-func (opts *AuthOptions) CanReauth() bool {
- return opts.AllowReauth
-}
-
-// ToTokenV3CreateMap formats an AuthOptions into a create request.
-func (opts *AuthOptions) ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error) {
- b, err := gophercloud.BuildRequestBody(opts, "credentials")
- if err != nil {
- return nil, err
- }
-
- if opts.Signature != nil {
- return b, nil
- }
-
- // calculate signature, when it is not set
- c, _ := b["credentials"].(map[string]interface{})
- h := interfaceToMap(c, "headers")
- p := interfaceToMap(c, "params")
-
- // detect and process a signature v2
- if v, ok := p["SignatureVersion"]; ok && v == "2" {
- if _, ok := c["body_hash"]; ok {
- delete(c, "body_hash")
- }
- if _, ok := c["headers"]; ok {
- delete(c, "headers")
- }
- if v, ok := p["SignatureMethod"]; ok {
- // params is a map of strings
- strToSign := EC2CredentialsBuildStringToSignV2(*opts)
- switch v {
- case EC2CredentialsHmacSha1V2:
- // keystone uses this method only when HmacSHA256 is not available on the server side
- // https://github.com/openstack/python-keystoneclient/blob/stable/train/keystoneclient/contrib/ec2/utils.py#L151..L156
- c["signature"] = sumHMAC1([]byte(opts.Secret), strToSign)
- return b, nil
- case EC2CredentialsHmacSha256V2:
- c["signature"] = sumHMAC256([]byte(opts.Secret), strToSign)
- return b, nil
- }
- return nil, fmt.Errorf("unsupported signature method: %s", v)
- }
- return nil, fmt.Errorf("signature method must be provided")
- } else if ok {
- return nil, fmt.Errorf("unsupported signature version: %s", v)
- }
-
- // it is not a signature v2, but a signature v4
- date := time.Now().UTC()
- if opts.Timestamp != nil {
- date = *opts.Timestamp
- }
- if v, _ := c["body_hash"]; v == nil {
- // when body_hash is not set, generate a random one
- c["body_hash"] = randomBodyHash()
- }
-
- signedHeaders, _ := h["X-Amz-SignedHeaders"]
-
- stringToSign := EC2CredentialsBuildStringToSignV4(*opts, signedHeaders, c["body_hash"].(string), date)
- key := EC2CredentialsBuildSignatureKeyV4(opts.Secret, opts.Region, opts.Service, date)
- c["signature"] = EC2CredentialsBuildSignatureV4(key, stringToSign)
- h["X-Amz-Date"] = date.Format(EC2CredentialsTimestampFormatV4)
- h["Authorization"] = EC2CredentialsBuildAuthorizationHeaderV4(*opts, signedHeaders, c["signature"].(string), date)
-
- // token is only used for S3 tokens validation and will be removed when using EC2 validation
- c["token"] = stringToSign
-
- return b, nil
-}
-
-// Create authenticates and either generates a new token from EC2 credentials
-func Create(c *gophercloud.ServiceClient, opts tokens.AuthOptionsBuilder) (r tokens.CreateResult) {
- b, err := opts.ToTokenV3CreateMap(nil)
- if err != nil {
- r.Err = err
- return
- }
-
- // delete "token" element, since it is used in s3tokens
- deleteBodyElements(b, "token")
-
- resp, err := c.Post(ec2tokensURL(c), b, &r.Body, &gophercloud.RequestOpts{
- MoreHeaders: map[string]string{"X-Auth-Token": ""},
- OkCodes: []int{200},
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// ValidateS3Token authenticates an S3 request using EC2 credentials. Doesn't
-// generate a new token ID, but returns a tokens.CreateResult.
-func ValidateS3Token(c *gophercloud.ServiceClient, opts tokens.AuthOptionsBuilder) (r tokens.CreateResult) {
- b, err := opts.ToTokenV3CreateMap(nil)
- if err != nil {
- r.Err = err
- return
- }
-
- // delete unused element, since it is used in ec2tokens only
- deleteBodyElements(b, "body_hash", "headers", "host", "params", "path", "verb")
-
- resp, err := c.Post(s3tokensURL(c), b, &r.Body, &gophercloud.RequestOpts{
- MoreHeaders: map[string]string{"X-Auth-Token": ""},
- OkCodes: []int{200},
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// The following are small helper functions used to help build the signature.
-
-// sumHMAC1 is a func to implement the HMAC SHA1 signature method.
-func sumHMAC1(key []byte, data []byte) []byte {
- hash := hmac.New(sha1.New, key)
- hash.Write(data)
- return hash.Sum(nil)
-}
-
-// sumHMAC256 is a func to implement the HMAC SHA256 signature method.
-func sumHMAC256(key []byte, data []byte) []byte {
- hash := hmac.New(sha256.New, key)
- hash.Write(data)
- return hash.Sum(nil)
-}
-
-// randomBodyHash is a func to generate a random sha256 hexdigest.
-func randomBodyHash() string {
- h := make([]byte, 64)
- rand.Read(h)
- return hex.EncodeToString(h)
-}
-
-// interfaceToMap is a func used to represent a "credentials" map element as a
-// "map[string]string"
-func interfaceToMap(c map[string]interface{}, key string) map[string]string {
- // convert map[string]interface{} to map[string]string
- m := make(map[string]string)
- if v, _ := c[key].(map[string]interface{}); v != nil {
- for k, v := range v {
- m[k] = v.(string)
- }
- }
-
- c[key] = m
-
- return m
-}
-
-// deleteBodyElements deletes map body elements
-func deleteBodyElements(b map[string]interface{}, elements ...string) {
- if c, ok := b["credentials"].(map[string]interface{}); ok {
- for _, k := range elements {
- if _, ok := c[k]; ok {
- delete(c, k)
- }
- }
- }
-}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/urls.go
deleted file mode 100644
index 84b33b282..000000000
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens/urls.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package ec2tokens
-
-import "github.com/gophercloud/gophercloud"
-
-func ec2tokensURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL("ec2tokens")
-}
-
-func s3tokensURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL("s3tokens")
-}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/doc.go
deleted file mode 100644
index c5b0831ca..000000000
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/doc.go
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Package oauth1 enables management of OpenStack OAuth1 tokens and Authentication.
-
-Example to Create an OAuth1 Consumer
-
- createConsumerOpts := oauth1.CreateConsumerOpts{
- Description: "My consumer",
- }
- consumer, err := oauth1.CreateConsumer(identityClient, createConsumerOpts).Extract()
- if err != nil {
- panic(err)
- }
-
- // NOTE: Consumer secret is available only on create response
- fmt.Printf("Consumer: %+v\n", consumer)
-
-Example to Request an unauthorized OAuth1 token
-
- requestTokenOpts := oauth1.RequestTokenOpts{
- OAuthConsumerKey: consumer.ID,
- OAuthConsumerSecret: consumer.Secret,
- OAuthSignatureMethod: oauth1.HMACSHA1,
- RequestedProjectID: projectID,
- }
- requestToken, err := oauth1.RequestToken(identityClient, requestTokenOpts).Extract()
- if err != nil {
- panic(err)
- }
-
- // NOTE: Request token secret is available only on request response
- fmt.Printf("Request token: %+v\n", requestToken)
-
-Example to Authorize an unauthorized OAuth1 token
-
- authorizeTokenOpts := oauth1.AuthorizeTokenOpts{
- Roles: []oauth1.Role{
- {Name: "member"},
- },
- }
- authToken, err := oauth1.AuthorizeToken(identityClient, requestToken.OAuthToken, authorizeTokenOpts).Extract()
- if err != nil {
- panic(err)
- }
-
- fmt.Printf("Verifier ID of the unauthorized Token: %+v\n", authToken.OAuthVerifier)
-
-Example to Create an OAuth1 Access Token
-
- accessTokenOpts := oauth1.CreateAccessTokenOpts{
- OAuthConsumerKey: consumer.ID,
- OAuthConsumerSecret: consumer.Secret,
- OAuthToken: requestToken.OAuthToken,
- OAuthTokenSecret: requestToken.OAuthTokenSecret,
- OAuthVerifier: authToken.OAuthVerifier,
- OAuthSignatureMethod: oauth1.HMACSHA1,
- }
- accessToken, err := oauth1.CreateAccessToken(identityClient, accessTokenOpts).Extract()
- if err != nil {
- panic(err)
- }
-
- // NOTE: Access token secret is available only on create response
- fmt.Printf("OAuth1 Access Token: %+v\n", accessToken)
-
-Example to List User's OAuth1 Access Tokens
-
- allPages, err := oauth1.ListAccessTokens(identityClient, userID).AllPages()
- if err != nil {
- panic(err)
- }
- accessTokens, err := oauth1.ExtractAccessTokens(allPages)
- if err != nil {
- panic(err)
- }
-
- for _, accessToken := range accessTokens {
- fmt.Printf("Access Token: %+v\n", accessToken)
- }
-
-Example to Authenticate a client using OAuth1 method
-
- client, err := openstack.NewClient("http://localhost:5000/v3")
- if err != nil {
- panic(err)
- }
-
- authOptions := &oauth1.AuthOptions{
- // consumer token, created earlier
- OAuthConsumerKey: consumer.ID,
- OAuthConsumerSecret: consumer.Secret,
- // access token, created earlier
- OAuthToken: accessToken.OAuthToken,
- OAuthTokenSecret: accessToken.OAuthTokenSecret,
- OAuthSignatureMethod: oauth1.HMACSHA1,
- }
- err = openstack.AuthenticateV3(client, authOptions, gophercloud.EndpointOpts{})
- if err != nil {
- panic(err)
- }
-
-Example to Create a Token using OAuth1 method
-
- var oauth1Token struct {
- tokens.Token
- oauth1.TokenExt
- }
-
- createOpts := &oauth1.AuthOptions{
- // consumer token, created earlier
- OAuthConsumerKey: consumer.ID,
- OAuthConsumerSecret: consumer.Secret,
- // access token, created earlier
- OAuthToken: accessToken.OAuthToken,
- OAuthTokenSecret: accessToken.OAuthTokenSecret,
- OAuthSignatureMethod: oauth1.HMACSHA1,
- }
- err := tokens.Create(identityClient, createOpts).ExtractInto(&oauth1Token)
- if err != nil {
- panic(err)
- }
-
-*/
-package oauth1
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/requests.go
deleted file mode 100644
index 028b5a45b..000000000
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/requests.go
+++ /dev/null
@@ -1,587 +0,0 @@
-package oauth1
-
-import (
- "crypto/hmac"
- "crypto/sha1"
- "encoding/base64"
- "fmt"
- "io/ioutil"
- "math/rand"
- "net/url"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/gophercloud/gophercloud"
- "github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
- "github.com/gophercloud/gophercloud/pagination"
-)
-
-// Type SignatureMethod is a OAuth1 SignatureMethod type.
-type SignatureMethod string
-
-const (
- // HMACSHA1 is a recommended OAuth1 signature method.
- HMACSHA1 SignatureMethod = "HMAC-SHA1"
-
- // PLAINTEXT signature method is not recommended to be used in
- // production environment.
- PLAINTEXT SignatureMethod = "PLAINTEXT"
-
- // OAuth1TokenContentType is a supported content type for an OAuth1
- // token.
- OAuth1TokenContentType = "application/x-www-form-urlencoded"
-)
-
-// AuthOptions represents options for authenticating a user using OAuth1 tokens.
-type AuthOptions struct {
- // OAuthConsumerKey is the OAuth1 Consumer Key.
- OAuthConsumerKey string `q:"oauth_consumer_key" required:"true"`
-
- // OAuthConsumerSecret is the OAuth1 Consumer Secret. Used to generate
- // an OAuth1 request signature.
- OAuthConsumerSecret string `required:"true"`
-
- // OAuthToken is the OAuth1 Request Token.
- OAuthToken string `q:"oauth_token" required:"true"`
-
- // OAuthTokenSecret is the OAuth1 Request Token Secret. Used to generate
- // an OAuth1 request signature.
- OAuthTokenSecret string `required:"true"`
-
- // OAuthSignatureMethod is the OAuth1 signature method the Consumer used
- // to sign the request. Supported values are "HMAC-SHA1" or "PLAINTEXT".
- // "PLAINTEXT" is not recommended for production usage.
- OAuthSignatureMethod SignatureMethod `q:"oauth_signature_method" required:"true"`
-
- // OAuthTimestamp is an OAuth1 request timestamp. If nil, current Unix
- // timestamp will be used.
- OAuthTimestamp *time.Time
-
- // OAuthNonce is an OAuth1 request nonce. Nonce must be a random string,
- // uniquely generated for each request. Will be generated automatically
- // when it is not set.
- OAuthNonce string `q:"oauth_nonce"`
-
- // AllowReauth allows Gophercloud to re-authenticate automatically
- // if/when your token expires.
- AllowReauth bool
-}
-
-// ToTokenV3HeadersMap builds the headers required for an OAuth1-based create
-// request.
-func (opts AuthOptions) ToTokenV3HeadersMap(headerOpts map[string]interface{}) (map[string]string, error) {
- q, err := buildOAuth1QueryString(opts, opts.OAuthTimestamp, "")
- if err != nil {
- return nil, err
- }
-
- signatureKeys := []string{opts.OAuthConsumerSecret, opts.OAuthTokenSecret}
-
- method := headerOpts["method"].(string)
- u := headerOpts["url"].(string)
- stringToSign := buildStringToSign(method, u, q.Query())
- signature := url.QueryEscape(signString(opts.OAuthSignatureMethod, stringToSign, signatureKeys))
-
- authHeader := buildAuthHeader(q.Query(), signature)
-
- headers := map[string]string{
- "Authorization": authHeader,
- "X-Auth-Token": "",
- }
-
- return headers, nil
-}
-
-// ToTokenV3ScopeMap allows AuthOptions to satisfy the tokens.AuthOptionsBuilder
-// interface.
-func (opts AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
- return nil, nil
-}
-
-// CanReauth allows AuthOptions to satisfy the tokens.AuthOptionsBuilder
-// interface.
-func (opts AuthOptions) CanReauth() bool {
- return opts.AllowReauth
-}
-
-// ToTokenV3CreateMap builds a create request body.
-func (opts AuthOptions) ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error) {
- // identityReq defines the "identity" portion of an OAuth1-based authentication
- // create request body.
- type identityReq struct {
- Methods []string `json:"methods"`
- OAuth1 struct{} `json:"oauth1"`
- }
-
- // authReq defines the "auth" portion of an OAuth1-based authentication
- // create request body.
- type authReq struct {
- Identity identityReq `json:"identity"`
- }
-
- // oauth1Request defines how an OAuth1-based authentication create
- // request body looks.
- type oauth1Request struct {
- Auth authReq `json:"auth"`
- }
-
- var req oauth1Request
-
- req.Auth.Identity.Methods = []string{"oauth1"}
- return gophercloud.BuildRequestBody(req, "")
-}
-
-// Create authenticates and either generates a new OpenStack token from an
-// OAuth1 token.
-func Create(client *gophercloud.ServiceClient, opts tokens.AuthOptionsBuilder) (r tokens.CreateResult) {
- b, err := opts.ToTokenV3CreateMap(nil)
- if err != nil {
- r.Err = err
- return
- }
-
- headerOpts := map[string]interface{}{
- "method": "POST",
- "url": authURL(client),
- }
-
- h, err := opts.ToTokenV3HeadersMap(headerOpts)
- if err != nil {
- r.Err = err
- return
- }
-
- resp, err := client.Post(authURL(client), b, &r.Body, &gophercloud.RequestOpts{
- MoreHeaders: h,
- OkCodes: []int{201},
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// CreateConsumerOptsBuilder allows extensions to add additional parameters to
-// the CreateConsumer request.
-type CreateConsumerOptsBuilder interface {
- ToOAuth1CreateConsumerMap() (map[string]interface{}, error)
-}
-
-// CreateConsumerOpts provides options used to create a new Consumer.
-type CreateConsumerOpts struct {
- // Description is the consumer description.
- Description string `json:"description"`
-}
-
-// ToOAuth1CreateConsumerMap formats a CreateConsumerOpts into a create request.
-func (opts CreateConsumerOpts) ToOAuth1CreateConsumerMap() (map[string]interface{}, error) {
- return gophercloud.BuildRequestBody(opts, "consumer")
-}
-
-// Create creates a new Consumer.
-func CreateConsumer(client *gophercloud.ServiceClient, opts CreateConsumerOptsBuilder) (r CreateConsumerResult) {
- b, err := opts.ToOAuth1CreateConsumerMap()
- if err != nil {
- r.Err = err
- return
- }
- resp, err := client.Post(consumersURL(client), b, &r.Body, &gophercloud.RequestOpts{
- OkCodes: []int{201},
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// Delete deletes a Consumer.
-func DeleteConsumer(client *gophercloud.ServiceClient, id string) (r DeleteConsumerResult) {
- resp, err := client.Delete(consumerURL(client, id), nil)
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// List enumerates Consumers.
-func ListConsumers(client *gophercloud.ServiceClient) pagination.Pager {
- return pagination.NewPager(client, consumersURL(client), func(r pagination.PageResult) pagination.Page {
- return ConsumersPage{pagination.LinkedPageBase{PageResult: r}}
- })
-}
-
-// GetConsumer retrieves details on a single Consumer by ID.
-func GetConsumer(client *gophercloud.ServiceClient, id string) (r GetConsumerResult) {
- resp, err := client.Get(consumerURL(client, id), &r.Body, nil)
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// UpdateConsumerOpts provides options used to update a consumer.
-type UpdateConsumerOpts struct {
- // Description is the consumer description.
- Description string `json:"description"`
-}
-
-// ToOAuth1UpdateConsumerMap formats an UpdateConsumerOpts into a consumer update
-// request.
-func (opts UpdateConsumerOpts) ToOAuth1UpdateConsumerMap() (map[string]interface{}, error) {
- return gophercloud.BuildRequestBody(opts, "consumer")
-}
-
-// UpdateConsumer updates an existing Consumer.
-func UpdateConsumer(client *gophercloud.ServiceClient, id string, opts UpdateConsumerOpts) (r UpdateConsumerResult) {
- b, err := opts.ToOAuth1UpdateConsumerMap()
- if err != nil {
- r.Err = err
- return
- }
- resp, err := client.Patch(consumerURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
- OkCodes: []int{200},
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// RequestTokenOptsBuilder allows extensions to add additional parameters to the
-// RequestToken request.
-type RequestTokenOptsBuilder interface {
- ToOAuth1RequestTokenHeaders(string, string) (map[string]string, error)
-}
-
-// RequestTokenOpts provides options used to get a consumer unauthorized
-// request token.
-type RequestTokenOpts struct {
- // OAuthConsumerKey is the OAuth1 Consumer Key.
- OAuthConsumerKey string `q:"oauth_consumer_key" required:"true"`
-
- // OAuthConsumerSecret is the OAuth1 Consumer Secret. Used to generate
- // an OAuth1 request signature.
- OAuthConsumerSecret string `required:"true"`
-
- // OAuthSignatureMethod is the OAuth1 signature method the Consumer used
- // to sign the request. Supported values are "HMAC-SHA1" or "PLAINTEXT".
- // "PLAINTEXT" is not recommended for production usage.
- OAuthSignatureMethod SignatureMethod `q:"oauth_signature_method" required:"true"`
-
- // OAuthTimestamp is an OAuth1 request timestamp. If nil, current Unix
- // timestamp will be used.
- OAuthTimestamp *time.Time
-
- // OAuthNonce is an OAuth1 request nonce. Nonce must be a random string,
- // uniquely generated for each request. Will be generated automatically
- // when it is not set.
- OAuthNonce string `q:"oauth_nonce"`
-
- // RequestedProjectID is a Project ID a consumer user requested an
- // access to.
- RequestedProjectID string `h:"Requested-Project-Id"`
-}
-
-// ToOAuth1RequestTokenHeaders formats a RequestTokenOpts into a map of request
-// headers.
-func (opts RequestTokenOpts) ToOAuth1RequestTokenHeaders(method, u string) (map[string]string, error) {
- q, err := buildOAuth1QueryString(opts, opts.OAuthTimestamp, "oob")
- if err != nil {
- return nil, err
- }
-
- h, err := gophercloud.BuildHeaders(opts)
- if err != nil {
- return nil, err
- }
-
- signatureKeys := []string{opts.OAuthConsumerSecret}
- stringToSign := buildStringToSign(method, u, q.Query())
- signature := url.QueryEscape(signString(opts.OAuthSignatureMethod, stringToSign, signatureKeys))
- authHeader := buildAuthHeader(q.Query(), signature)
-
- h["Authorization"] = authHeader
-
- return h, nil
-}
-
-// RequestToken requests an unauthorized OAuth1 Token.
-func RequestToken(client *gophercloud.ServiceClient, opts RequestTokenOptsBuilder) (r TokenResult) {
- h, err := opts.ToOAuth1RequestTokenHeaders("POST", requestTokenURL(client))
- if err != nil {
- r.Err = err
- return
- }
-
- resp, err := client.Post(requestTokenURL(client), nil, nil, &gophercloud.RequestOpts{
- MoreHeaders: h,
- OkCodes: []int{201},
- KeepResponseBody: true,
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- if r.Err != nil {
- return
- }
- defer resp.Body.Close()
- if v := r.Header.Get("Content-Type"); v != OAuth1TokenContentType {
- r.Err = fmt.Errorf("unsupported Content-Type: %q", v)
- return
- }
- r.Body, r.Err = ioutil.ReadAll(resp.Body)
- return
-}
-
-// AuthorizeTokenOptsBuilder allows extensions to add additional parameters to
-// the AuthorizeToken request.
-type AuthorizeTokenOptsBuilder interface {
- ToOAuth1AuthorizeTokenMap() (map[string]interface{}, error)
-}
-
-// AuthorizeTokenOpts provides options used to authorize a request token.
-type AuthorizeTokenOpts struct {
- Roles []Role `json:"roles"`
-}
-
-// Role is a struct representing a role object in a AuthorizeTokenOpts struct.
-type Role struct {
- ID string `json:"id,omitempty"`
- Name string `json:"name,omitempty"`
-}
-
-// ToOAuth1AuthorizeTokenMap formats an AuthorizeTokenOpts into an authorize token
-// request.
-func (opts AuthorizeTokenOpts) ToOAuth1AuthorizeTokenMap() (map[string]interface{}, error) {
- for _, r := range opts.Roles {
- if r == (Role{}) {
- return nil, fmt.Errorf("role must not be empty")
- }
- }
- return gophercloud.BuildRequestBody(opts, "")
-}
-
-// AuthorizeToken authorizes an unauthorized consumer token.
-func AuthorizeToken(client *gophercloud.ServiceClient, id string, opts AuthorizeTokenOptsBuilder) (r AuthorizeTokenResult) {
- b, err := opts.ToOAuth1AuthorizeTokenMap()
- if err != nil {
- r.Err = err
- return
- }
- resp, err := client.Put(authorizeTokenURL(client, id), b, &r.Body, &gophercloud.RequestOpts{
- OkCodes: []int{200},
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// CreateAccessTokenOptsBuilder allows extensions to add additional parameters
-// to the CreateAccessToken request.
-type CreateAccessTokenOptsBuilder interface {
- ToOAuth1CreateAccessTokenHeaders(string, string) (map[string]string, error)
-}
-
-// CreateAccessTokenOpts provides options used to create an OAuth1 token.
-type CreateAccessTokenOpts struct {
- // OAuthConsumerKey is the OAuth1 Consumer Key.
- OAuthConsumerKey string `q:"oauth_consumer_key" required:"true"`
-
- // OAuthConsumerSecret is the OAuth1 Consumer Secret. Used to generate
- // an OAuth1 request signature.
- OAuthConsumerSecret string `required:"true"`
-
- // OAuthToken is the OAuth1 Request Token.
- OAuthToken string `q:"oauth_token" required:"true"`
-
- // OAuthTokenSecret is the OAuth1 Request Token Secret. Used to generate
- // an OAuth1 request signature.
- OAuthTokenSecret string `required:"true"`
-
- // OAuthVerifier is the OAuth1 verification code.
- OAuthVerifier string `q:"oauth_verifier" required:"true"`
-
- // OAuthSignatureMethod is the OAuth1 signature method the Consumer used
- // to sign the request. Supported values are "HMAC-SHA1" or "PLAINTEXT".
- // "PLAINTEXT" is not recommended for production usage.
- OAuthSignatureMethod SignatureMethod `q:"oauth_signature_method" required:"true"`
-
- // OAuthTimestamp is an OAuth1 request timestamp. If nil, current Unix
- // timestamp will be used.
- OAuthTimestamp *time.Time
-
- // OAuthNonce is an OAuth1 request nonce. Nonce must be a random string,
- // uniquely generated for each request. Will be generated automatically
- // when it is not set.
- OAuthNonce string `q:"oauth_nonce"`
-}
-
-// ToOAuth1CreateAccessTokenHeaders formats a CreateAccessTokenOpts into a map of
-// request headers.
-func (opts CreateAccessTokenOpts) ToOAuth1CreateAccessTokenHeaders(method, u string) (map[string]string, error) {
- q, err := buildOAuth1QueryString(opts, opts.OAuthTimestamp, "")
- if err != nil {
- return nil, err
- }
-
- signatureKeys := []string{opts.OAuthConsumerSecret, opts.OAuthTokenSecret}
- stringToSign := buildStringToSign(method, u, q.Query())
- signature := url.QueryEscape(signString(opts.OAuthSignatureMethod, stringToSign, signatureKeys))
- authHeader := buildAuthHeader(q.Query(), signature)
-
- headers := map[string]string{
- "Authorization": authHeader,
- }
-
- return headers, nil
-}
-
-// CreateAccessToken creates a new OAuth1 Access Token
-func CreateAccessToken(client *gophercloud.ServiceClient, opts CreateAccessTokenOptsBuilder) (r TokenResult) {
- h, err := opts.ToOAuth1CreateAccessTokenHeaders("POST", createAccessTokenURL(client))
- if err != nil {
- r.Err = err
- return
- }
-
- resp, err := client.Post(createAccessTokenURL(client), nil, nil, &gophercloud.RequestOpts{
- MoreHeaders: h,
- OkCodes: []int{201},
- KeepResponseBody: true,
- })
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- if r.Err != nil {
- return
- }
- defer resp.Body.Close()
- if v := r.Header.Get("Content-Type"); v != OAuth1TokenContentType {
- r.Err = fmt.Errorf("unsupported Content-Type: %q", v)
- return
- }
- r.Body, r.Err = ioutil.ReadAll(resp.Body)
- return
-}
-
-// GetAccessToken retrieves details on a single OAuth1 access token by an ID.
-func GetAccessToken(client *gophercloud.ServiceClient, userID string, id string) (r GetAccessTokenResult) {
- resp, err := client.Get(userAccessTokenURL(client, userID, id), &r.Body, nil)
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// RevokeAccessToken revokes an OAuth1 access token.
-func RevokeAccessToken(client *gophercloud.ServiceClient, userID string, id string) (r RevokeAccessTokenResult) {
- resp, err := client.Delete(userAccessTokenURL(client, userID, id), nil)
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// ListAccessTokens enumerates authorized access tokens.
-func ListAccessTokens(client *gophercloud.ServiceClient, userID string) pagination.Pager {
- url := userAccessTokensURL(client, userID)
- return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
- return AccessTokensPage{pagination.LinkedPageBase{PageResult: r}}
- })
-}
-
-// ListAccessTokenRoles enumerates authorized access token roles.
-func ListAccessTokenRoles(client *gophercloud.ServiceClient, userID string, id string) pagination.Pager {
- url := userAccessTokenRolesURL(client, userID, id)
- return pagination.NewPager(client, url, func(r pagination.PageResult) pagination.Page {
- return AccessTokenRolesPage{pagination.LinkedPageBase{PageResult: r}}
- })
-}
-
-// GetAccessTokenRole retrieves details on a single OAuth1 access token role by
-// an ID.
-func GetAccessTokenRole(client *gophercloud.ServiceClient, userID string, id string, roleID string) (r GetAccessTokenRoleResult) {
- resp, err := client.Get(userAccessTokenRoleURL(client, userID, id, roleID), &r.Body, nil)
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
- return
-}
-
-// The following are small helper functions used to help build the signature.
-
-// buildOAuth1QueryString builds a URLEncoded parameters string specific for
-// OAuth1-based requests.
-func buildOAuth1QueryString(opts interface{}, timestamp *time.Time, callback string) (*url.URL, error) {
- q, err := gophercloud.BuildQueryString(opts)
- if err != nil {
- return nil, err
- }
-
- query := q.Query()
-
- if timestamp != nil {
- // use provided timestamp
- query.Set("oauth_timestamp", strconv.FormatInt(timestamp.Unix(), 10))
- } else {
- // use current timestamp
- query.Set("oauth_timestamp", strconv.FormatInt(time.Now().UTC().Unix(), 10))
- }
-
- if query.Get("oauth_nonce") == "" {
- // when nonce is not set, generate a random one
- query.Set("oauth_nonce", strconv.FormatInt(rand.Int63(), 10)+query.Get("oauth_timestamp"))
- }
-
- if callback != "" {
- query.Set("oauth_callback", callback)
- }
- query.Set("oauth_version", "1.0")
-
- return &url.URL{RawQuery: query.Encode()}, nil
-}
-
-// buildStringToSign builds a string to be signed.
-func buildStringToSign(method string, u string, query url.Values) []byte {
- parsedURL, _ := url.Parse(u)
- p := parsedURL.Port()
- s := parsedURL.Scheme
-
- // Default scheme port must be stripped
- if s == "http" && p == "80" || s == "https" && p == "443" {
- parsedURL.Host = strings.TrimSuffix(parsedURL.Host, ":"+p)
- }
-
- // Ensure that URL doesn't contain queries
- parsedURL.RawQuery = ""
-
- v := strings.Join(
- []string{method, url.QueryEscape(parsedURL.String()), url.QueryEscape(query.Encode())}, "&")
-
- return []byte(v)
-}
-
-// signString signs a string using an OAuth1 signature method.
-func signString(signatureMethod SignatureMethod, strToSign []byte, signatureKeys []string) string {
- var key []byte
- for i, k := range signatureKeys {
- key = append(key, []byte(url.QueryEscape(k))...)
- if i == 0 {
- key = append(key, '&')
- }
- }
-
- var signedString string
- switch signatureMethod {
- case PLAINTEXT:
- signedString = string(key)
- default:
- h := hmac.New(sha1.New, key)
- h.Write(strToSign)
- signedString = base64.StdEncoding.EncodeToString(h.Sum(nil))
- }
-
- return signedString
-}
-
-// buildAuthHeader generates an OAuth1 Authorization header with a signature
-// calculated using an OAuth1 signature method.
-func buildAuthHeader(query url.Values, signature string) string {
- var authHeader []string
- var keys []string
- for k := range query {
- keys = append(keys, k)
- }
- sort.Strings(keys)
-
- for _, k := range keys {
- for _, v := range query[k] {
- authHeader = append(authHeader, fmt.Sprintf("%s=%q", k, url.QueryEscape(v)))
- }
- }
-
- authHeader = append(authHeader, fmt.Sprintf("oauth_signature=%q", signature))
-
- return "OAuth " + strings.Join(authHeader, ", ")
-}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/results.go
deleted file mode 100644
index bb109e98e..000000000
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/results.go
+++ /dev/null
@@ -1,305 +0,0 @@
-package oauth1
-
-import (
- "encoding/json"
- "net/url"
- "time"
-
- "github.com/gophercloud/gophercloud"
- "github.com/gophercloud/gophercloud/pagination"
-)
-
-// Consumer represents a delegated authorization request between two
-// identities.
-type Consumer struct {
- ID string `json:"id"`
- Secret string `json:"secret"`
- Description string `json:"description"`
-}
-
-type consumerResult struct {
- gophercloud.Result
-}
-
-// CreateConsumerResult is the response from a Create operation. Call its
-// Extract method to interpret it as a Consumer.
-type CreateConsumerResult struct {
- consumerResult
-}
-
-// UpdateConsumerResult is the response from a Create operation. Call its
-// Extract method to interpret it as a Consumer.
-type UpdateConsumerResult struct {
- consumerResult
-}
-
-// DeleteConsumerResult is the response from a Delete operation. Call its
-// ExtractErr to determine if the request succeeded or failed.
-type DeleteConsumerResult struct {
- gophercloud.ErrResult
-}
-
-// ConsumersPage is a single page of Region results.
-type ConsumersPage struct {
- pagination.LinkedPageBase
-}
-
-// GetConsumerResult is the response from a Get operation. Call its Extract
-// method to interpret it as a Consumer.
-type GetConsumerResult struct {
- consumerResult
-}
-
-// IsEmpty determines whether or not a page of Consumers contains any results.
-func (c ConsumersPage) IsEmpty() (bool, error) {
- consumers, err := ExtractConsumers(c)
- return len(consumers) == 0, err
-}
-
-// NextPageURL extracts the "next" link from the links section of the result.
-func (c ConsumersPage) NextPageURL() (string, error) {
- var s struct {
- Links struct {
- Next string `json:"next"`
- Previous string `json:"previous"`
- } `json:"links"`
- }
- err := c.ExtractInto(&s)
- if err != nil {
- return "", err
- }
- return s.Links.Next, err
-}
-
-// ExtractConsumers returns a slice of Consumers contained in a single page of
-// results.
-func ExtractConsumers(r pagination.Page) ([]Consumer, error) {
- var s struct {
- Consumers []Consumer `json:"consumers"`
- }
- err := (r.(ConsumersPage)).ExtractInto(&s)
- return s.Consumers, err
-}
-
-// Extract interprets any consumer result as a Consumer.
-func (c consumerResult) Extract() (*Consumer, error) {
- var s struct {
- Consumer *Consumer `json:"consumer"`
- }
- err := c.ExtractInto(&s)
- return s.Consumer, err
-}
-
-// Token contains an OAuth1 token.
-type Token struct {
- // OAuthToken is the key value for the oauth token that the Identity API returns.
- OAuthToken string `q:"oauth_token"`
- // OAuthTokenSecret is the secret value associated with the OAuth Token.
- OAuthTokenSecret string `q:"oauth_token_secret"`
- // OAUthExpiresAt is the date and time when an OAuth token expires.
- OAUthExpiresAt *time.Time `q:"-"`
-}
-
-// TokenResult is a struct to handle
-// "Content-Type: application/x-www-form-urlencoded" response.
-type TokenResult struct {
- gophercloud.Result
- Body []byte
-}
-
-// Extract interprets any OAuth1 token result as a Token.
-func (r TokenResult) Extract() (*Token, error) {
- if r.Err != nil {
- return nil, r.Err
- }
-
- values, err := url.ParseQuery(string(r.Body))
- if err != nil {
- return nil, err
- }
-
- token := &Token{
- OAuthToken: values.Get("oauth_token"),
- OAuthTokenSecret: values.Get("oauth_token_secret"),
- }
-
- if v := values.Get("oauth_expires_at"); v != "" {
- if t, err := time.Parse(gophercloud.RFC3339Milli, v); err != nil {
- return nil, err
- } else {
- token.OAUthExpiresAt = &t
- }
- }
-
- return token, nil
-}
-
-// AuthorizedToken contains an OAuth1 authorized token info.
-type AuthorizedToken struct {
- // OAuthVerifier is the ID of the token verifier.
- OAuthVerifier string `json:"oauth_verifier"`
-}
-
-type AuthorizeTokenResult struct {
- gophercloud.Result
-}
-
-// Extract interprets AuthorizeTokenResult result as a AuthorizedToken.
-func (r AuthorizeTokenResult) Extract() (*AuthorizedToken, error) {
- var s struct {
- AuthorizedToken *AuthorizedToken `json:"token"`
- }
- err := r.ExtractInto(&s)
- return s.AuthorizedToken, err
-}
-
-// AccessToken represents an AccessToken response as a struct.
-type AccessToken struct {
- ID string `json:"id"`
- ConsumerID string `json:"consumer_id"`
- ProjectID string `json:"project_id"`
- AuthorizingUserID string `json:"authorizing_user_id"`
- ExpiresAt *time.Time `json:"-"`
-}
-
-func (r *AccessToken) UnmarshalJSON(b []byte) error {
- type tmp AccessToken
- var s struct {
- tmp
- ExpiresAt *gophercloud.JSONRFC3339Milli `json:"expires_at"`
- }
- err := json.Unmarshal(b, &s)
- if err != nil {
- return err
- }
- *r = AccessToken(s.tmp)
-
- if s.ExpiresAt != nil {
- t := time.Time(*s.ExpiresAt)
- r.ExpiresAt = &t
- }
-
- return nil
-}
-
-type GetAccessTokenResult struct {
- gophercloud.Result
-}
-
-// Extract interprets any GetAccessTokenResult result as an AccessToken.
-func (r GetAccessTokenResult) Extract() (*AccessToken, error) {
- var s struct {
- AccessToken *AccessToken `json:"access_token"`
- }
- err := r.ExtractInto(&s)
- return s.AccessToken, err
-}
-
-// RevokeAccessTokenResult is the response from a Delete operation. Call its
-// ExtractErr to determine if the request succeeded or failed.
-type RevokeAccessTokenResult struct {
- gophercloud.ErrResult
-}
-
-// AccessTokensPage is a single page of Access Tokens results.
-type AccessTokensPage struct {
- pagination.LinkedPageBase
-}
-
-// IsEmpty determines whether or not a an AccessTokensPage contains any results.
-func (r AccessTokensPage) IsEmpty() (bool, error) {
- accessTokens, err := ExtractAccessTokens(r)
- return len(accessTokens) == 0, err
-}
-
-// NextPageURL extracts the "next" link from the links section of the result.
-func (r AccessTokensPage) NextPageURL() (string, error) {
- var s struct {
- Links struct {
- Next string `json:"next"`
- Previous string `json:"previous"`
- } `json:"links"`
- }
- err := r.ExtractInto(&s)
- if err != nil {
- return "", err
- }
- return s.Links.Next, err
-}
-
-// ExtractAccessTokens returns a slice of AccessTokens contained in a single
-// page of results.
-func ExtractAccessTokens(r pagination.Page) ([]AccessToken, error) {
- var s struct {
- AccessTokens []AccessToken `json:"access_tokens"`
- }
- err := (r.(AccessTokensPage)).ExtractInto(&s)
- return s.AccessTokens, err
-}
-
-// AccessTokenRole represents an Access Token Role struct.
-type AccessTokenRole struct {
- ID string `json:"id"`
- Name string `json:"name"`
- DomainID string `json:"domain_id"`
-}
-
-// AccessTokenRolesPage is a single page of Access Token roles results.
-type AccessTokenRolesPage struct {
- pagination.LinkedPageBase
-}
-
-// IsEmpty determines whether or not a an AccessTokensPage contains any results.
-func (r AccessTokenRolesPage) IsEmpty() (bool, error) {
- accessTokenRoles, err := ExtractAccessTokenRoles(r)
- return len(accessTokenRoles) == 0, err
-}
-
-// NextPageURL extracts the "next" link from the links section of the result.
-func (r AccessTokenRolesPage) NextPageURL() (string, error) {
- var s struct {
- Links struct {
- Next string `json:"next"`
- Previous string `json:"previous"`
- } `json:"links"`
- }
- err := r.ExtractInto(&s)
- if err != nil {
- return "", err
- }
- return s.Links.Next, err
-}
-
-// ExtractAccessTokenRoles returns a slice of AccessTokenRole contained in a
-// single page of results.
-func ExtractAccessTokenRoles(r pagination.Page) ([]AccessTokenRole, error) {
- var s struct {
- AccessTokenRoles []AccessTokenRole `json:"roles"`
- }
- err := (r.(AccessTokenRolesPage)).ExtractInto(&s)
- return s.AccessTokenRoles, err
-}
-
-type GetAccessTokenRoleResult struct {
- gophercloud.Result
-}
-
-// Extract interprets any GetAccessTokenRoleResult result as an AccessTokenRole.
-func (r GetAccessTokenRoleResult) Extract() (*AccessTokenRole, error) {
- var s struct {
- AccessTokenRole *AccessTokenRole `json:"role"`
- }
- err := r.ExtractInto(&s)
- return s.AccessTokenRole, err
-}
-
-// OAuth1 is an OAuth1 object, returned in OAuth1 token result.
-type OAuth1 struct {
- AccessTokenID string `json:"access_token_id"`
- ConsumerID string `json:"consumer_id"`
-}
-
-// TokenExt represents an extension of the base token result.
-type TokenExt struct {
- OAuth1 OAuth1 `json:"OS-OAUTH1"`
-}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/urls.go
deleted file mode 100644
index 9b51d53b3..000000000
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1/urls.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package oauth1
-
-import "github.com/gophercloud/gophercloud"
-
-func consumersURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL("OS-OAUTH1", "consumers")
-}
-
-func consumerURL(c *gophercloud.ServiceClient, id string) string {
- return c.ServiceURL("OS-OAUTH1", "consumers", id)
-}
-
-func requestTokenURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL("OS-OAUTH1", "request_token")
-}
-
-func authorizeTokenURL(c *gophercloud.ServiceClient, id string) string {
- return c.ServiceURL("OS-OAUTH1", "authorize", id)
-}
-
-func createAccessTokenURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL("OS-OAUTH1", "access_token")
-}
-
-func userAccessTokensURL(c *gophercloud.ServiceClient, userID string) string {
- return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens")
-}
-
-func userAccessTokenURL(c *gophercloud.ServiceClient, userID string, id string) string {
- return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens", id)
-}
-
-func userAccessTokenRolesURL(c *gophercloud.ServiceClient, userID string, id string) string {
- return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens", id, "roles")
-}
-
-func userAccessTokenRoleURL(c *gophercloud.ServiceClient, userID string, id string, roleID string) string {
- return c.ServiceURL("users", userID, "OS-OAUTH1", "access_tokens", id, "roles", roleID)
-}
-
-func authURL(c *gophercloud.ServiceClient) string {
- return c.ServiceURL("auth", "tokens")
-}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
index d8c455d16..e4d766b23 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
@@ -8,7 +8,6 @@ type Scope struct {
ProjectName string
DomainID string
DomainName string
- System bool
}
// AuthOptionsBuilder provides the ability for extensions to add additional
@@ -17,7 +16,6 @@ type AuthOptionsBuilder interface {
// ToTokenV3CreateMap assembles the Create request body, returning an error
// if parameters are missing or inconsistent.
ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error)
- ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error)
ToTokenV3ScopeMap() (map[string]interface{}, error)
CanReauth() bool
}
@@ -38,9 +36,6 @@ type AuthOptions struct {
Password string `json:"password,omitempty"`
- // Passcode is used in TOTP authentication method
- Passcode string `json:"passcode,omitempty"`
-
// At most one of DomainID and DomainName must be provided if using Username
// with Identity V3. Otherwise, either are optional.
DomainID string `json:"-"`
@@ -72,7 +67,6 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
Username: opts.Username,
UserID: opts.UserID,
Password: opts.Password,
- Passcode: opts.Passcode,
DomainID: opts.DomainID,
DomainName: opts.DomainName,
AllowReauth: opts.AllowReauth,
@@ -85,7 +79,7 @@ func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[s
return gophercloudAuthOpts.ToTokenV3CreateMap(scope)
}
-// ToTokenV3ScopeMap builds a scope request body from AuthOptions.
+// ToTokenV3CreateMap builds a scope request body from AuthOptions.
func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
scope := gophercloud.AuthScope(opts.Scope)
@@ -99,21 +93,10 @@ func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
}
func (opts *AuthOptions) CanReauth() bool {
- if opts.Passcode != "" {
- // cannot reauth using TOTP passcode
- return false
- }
-
return opts.AllowReauth
}
-// ToTokenV3HeadersMap allows AuthOptions to satisfy the AuthOptionsBuilder
-// interface in the v3 tokens package.
-func (opts *AuthOptions) ToTokenV3HeadersMap(map[string]interface{}) (map[string]string, error) {
- return nil, nil
-}
-
-func subjectTokenHeaders(subjectToken string) map[string]string {
+func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
return map[string]string{
"X-Subject-Token": subjectToken,
}
@@ -137,24 +120,30 @@ func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder) (r CreateResu
resp, err := c.Post(tokenURL(c), b, &r.Body, &gophercloud.RequestOpts{
MoreHeaders: map[string]string{"X-Auth-Token": ""},
})
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
+ r.Err = err
+ if resp != nil {
+ r.Header = resp.Header
+ }
return
}
// Get validates and retrieves information about another token.
func Get(c *gophercloud.ServiceClient, token string) (r GetResult) {
resp, err := c.Get(tokenURL(c), &r.Body, &gophercloud.RequestOpts{
- MoreHeaders: subjectTokenHeaders(token),
+ MoreHeaders: subjectTokenHeaders(c, token),
OkCodes: []int{200, 203},
})
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
+ if resp != nil {
+ r.Header = resp.Header
+ }
+ r.Err = err
return
}
// Validate determines if a specified token is valid or not.
func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
resp, err := c.Head(tokenURL(c), &gophercloud.RequestOpts{
- MoreHeaders: subjectTokenHeaders(token),
+ MoreHeaders: subjectTokenHeaders(c, token),
OkCodes: []int{200, 204, 404},
})
if err != nil {
@@ -166,9 +155,8 @@ func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
// Revoke immediately makes specified token invalid.
func Revoke(c *gophercloud.ServiceClient, token string) (r RevokeResult) {
- resp, err := c.Delete(tokenURL(c), &gophercloud.RequestOpts{
- MoreHeaders: subjectTokenHeaders(token),
+ _, r.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{
+ MoreHeaders: subjectTokenHeaders(c, token),
})
- _, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}
diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
index f1e17e9f7..6f26c96bc 100644
--- a/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
+++ b/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
@@ -109,13 +109,6 @@ func (r CreateResult) ExtractTokenID() (string, error) {
return r.Header.Get("X-Subject-Token"), r.Err
}
-// ExtractTokenID implements the gophercloud.AuthResult interface. The returned
-// string is the same as the ID field of the Token struct returned from
-// ExtractToken().
-func (r GetResult) ExtractTokenID() (string, error) {
- return r.Header.Get("X-Subject-Token"), r.Err
-}
-
// ExtractServiceCatalog returns the ServiceCatalog that was generated along
// with the user's Token.
func (r commonResult) ExtractServiceCatalog() (*ServiceCatalog, error) {
@@ -151,15 +144,6 @@ func (r commonResult) ExtractProject() (*Project, error) {
return s.Project, err
}
-// ExtractDomain returns Domain to which User is authorized.
-func (r commonResult) ExtractDomain() (*Domain, error) {
- var s struct {
- Domain *Domain `json:"domain"`
- }
- err := r.ExtractInto(&s)
- return s.Domain, err
-}
-
// CreateResult is the response from a Create request. Use ExtractToken()
// to interpret it as a Token, or ExtractServiceCatalog() to interpret it
// as a service catalog.
diff --git a/vendor/github.com/gophercloud/gophercloud/pagination/http.go b/vendor/github.com/gophercloud/gophercloud/pagination/http.go
index df3503159..757295c42 100644
--- a/vendor/github.com/gophercloud/gophercloud/pagination/http.go
+++ b/vendor/github.com/gophercloud/gophercloud/pagination/http.go
@@ -54,8 +54,7 @@ func PageResultFromParsed(resp *http.Response, body interface{}) PageResult {
// Request performs an HTTP request and extracts the http.Response from the result.
func Request(client *gophercloud.ServiceClient, headers map[string]string, url string) (*http.Response, error) {
return client.Get(url, nil, &gophercloud.RequestOpts{
- MoreHeaders: headers,
- OkCodes: []int{200, 204, 300},
- KeepResponseBody: true,
+ MoreHeaders: headers,
+ OkCodes: []int{200, 204, 300},
})
}
diff --git a/vendor/github.com/gophercloud/gophercloud/params.go b/vendor/github.com/gophercloud/gophercloud/params.go
index 219c020a2..b9986660c 100644
--- a/vendor/github.com/gophercloud/gophercloud/params.go
+++ b/vendor/github.com/gophercloud/gophercloud/params.go
@@ -450,8 +450,6 @@ func BuildHeaders(opts interface{}) (map[string]string, error) {
optsMap[tags[0]] = v.String()
case reflect.Int:
optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10)
- case reflect.Int64:
- optsMap[tags[0]] = strconv.FormatInt(v.Int(), 10)
case reflect.Bool:
optsMap[tags[0]] = strconv.FormatBool(v.Bool())
}
diff --git a/vendor/github.com/gophercloud/gophercloud/provider_client.go b/vendor/github.com/gophercloud/gophercloud/provider_client.go
index 43574402e..fce00462f 100644
--- a/vendor/github.com/gophercloud/gophercloud/provider_client.go
+++ b/vendor/github.com/gophercloud/gophercloud/provider_client.go
@@ -94,10 +94,9 @@ type ProviderClient struct {
// reauthlock represents a set of attributes used to help in the reauthentication process.
type reauthlock struct {
sync.RWMutex
- // This channel is non-nil during reauthentication. It can be used to ask the
- // goroutine doing Reauthenticate() for its result. Look at the implementation
- // of Reauthenticate() for details.
- ongoing chan<- (chan<- error)
+ reauthing bool
+ reauthingErr error
+ done *sync.Cond
}
// AuthenticatedHeaders returns a map of HTTP headers that are common for all
@@ -107,15 +106,11 @@ func (client *ProviderClient) AuthenticatedHeaders() (m map[string]string) {
return
}
if client.reauthmut != nil {
- // If a Reauthenticate is in progress, wait for it to complete.
client.reauthmut.Lock()
- ongoing := client.reauthmut.ongoing
- client.reauthmut.Unlock()
- if ongoing != nil {
- responseChannel := make(chan error)
- ongoing <- responseChannel
- _ = <-responseChannel
+ for client.reauthmut.reauthing {
+ client.reauthmut.done.Wait()
}
+ client.reauthmut.Unlock()
}
t := client.Token()
if t == "" {
@@ -228,7 +223,7 @@ func (client *ProviderClient) SetThrowaway(v bool) {
// this case, the reauthentication can be skipped if another thread has already
// reauthenticated in the meantime. If no previous token is known, an empty
// string should be passed instead to force unconditional reauthentication.
-func (client *ProviderClient) Reauthenticate(previousToken string) error {
+func (client *ProviderClient) Reauthenticate(previousToken string) (err error) {
if client.ReauthFunc == nil {
return nil
}
@@ -237,50 +232,33 @@ func (client *ProviderClient) Reauthenticate(previousToken string) error {
return client.ReauthFunc()
}
- messages := make(chan (chan<- error))
-
- // Check if a Reauthenticate is in progress, or start one if not.
client.reauthmut.Lock()
- ongoing := client.reauthmut.ongoing
- if ongoing == nil {
- client.reauthmut.ongoing = messages
+ if client.reauthmut.reauthing {
+ for !client.reauthmut.reauthing {
+ client.reauthmut.done.Wait()
+ }
+ err = client.reauthmut.reauthingErr
+ client.reauthmut.Unlock()
+ return err
}
client.reauthmut.Unlock()
- // If Reauthenticate is running elsewhere, wait for its result.
- if ongoing != nil {
- responseChannel := make(chan error)
- ongoing <- responseChannel
- return <-responseChannel
- }
+ client.reauthmut.Lock()
+ client.reauthmut.reauthing = true
+ client.reauthmut.done = sync.NewCond(client.reauthmut)
+ client.reauthmut.reauthingErr = nil
+ client.reauthmut.Unlock()
- // Perform the actual reauthentication.
- var err error
if previousToken == "" || client.TokenID == previousToken {
err = client.ReauthFunc()
- } else {
- err = nil
}
- // Mark Reauthenticate as finished.
client.reauthmut.Lock()
- client.reauthmut.ongoing = nil
+ client.reauthmut.reauthing = false
+ client.reauthmut.reauthingErr = err
+ client.reauthmut.done.Broadcast()
client.reauthmut.Unlock()
-
- // Report result to all other interested goroutines.
- //
- // This happens in a separate goroutine because another goroutine might have
- // acquired a copy of `client.reauthmut.ongoing` before we cleared it, but not
- // have come around to sending its request. By answering in a goroutine, we
- // can have that goroutine linger until all responseChannels have been sent.
- // When GC has collected all sendings ends of the channel, our receiving end
- // will be closed and the goroutine will end.
- go func() {
- for responseChannel := range messages {
- responseChannel <- err
- }
- }()
- return err
+ return
}
// RequestOpts customizes the behavior of the provider.Request() method.
@@ -305,18 +283,6 @@ type RequestOpts struct {
// ErrorContext specifies the resource error type to return if an error is encountered.
// This lets resources override default error messages based on the response status code.
ErrorContext error
- // KeepResponseBody specifies whether to keep the HTTP response body. Usually used, when the HTTP
- // response body is considered for further use. Valid when JSONResponse is nil.
- KeepResponseBody bool
-}
-
-// requestState contains temporary state for a single ProviderClient.Request() call.
-type requestState struct {
- // This flag indicates if we have reauthenticated during this request because of a 401 response.
- // It ensures that we don't reauthenticate multiple times for a single request. If we
- // reauthenticate, but keep getting 401 responses with the fresh token, reauthenticating some more
- // will just get us into an infinite loop.
- hasReauthenticated bool
}
var applicationJSON = "application/json"
@@ -324,12 +290,6 @@ var applicationJSON = "application/json"
// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication
// header will automatically be provided.
func (client *ProviderClient) Request(method, url string, options *RequestOpts) (*http.Response, error) {
- return client.doRequest(method, url, options, &requestState{
- hasReauthenticated: false,
- })
-}
-
-func (client *ProviderClient) doRequest(method, url string, options *RequestOpts, state *requestState) (*http.Response, error) {
var body io.Reader
var contentType *string
@@ -349,11 +309,6 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
contentType = &applicationJSON
}
- // Return an error, when "KeepResponseBody" is true and "JSONResponse" is not nil
- if options.KeepResponseBody && options.JSONResponse != nil {
- return nil, errors.New("cannot use KeepResponseBody when JSONResponse is not nil")
- }
-
if options.RawBody != nil {
body = options.RawBody
}
@@ -392,6 +347,9 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
req.Header.Set(k, v)
}
+ // Set connection parameter to close the connection immediately when we've got the response
+ req.Close = true
+
prereqtok := req.Header.Get("X-Auth-Token")
// Issue the request.
@@ -419,12 +377,11 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
body, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
respErr := ErrUnexpectedResponseCode{
- URL: url,
- Method: method,
- Expected: options.OkCodes,
- Actual: resp.StatusCode,
- Body: body,
- ResponseHeader: resp.Header,
+ URL: url,
+ Method: method,
+ Expected: options.OkCodes,
+ Actual: resp.StatusCode,
+ Body: body,
}
errType := options.ErrorContext
@@ -435,7 +392,7 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
err = error400er.Error400(respErr)
}
case http.StatusUnauthorized:
- if client.ReauthFunc != nil && !state.hasReauthenticated {
+ if client.ReauthFunc != nil {
err = client.Reauthenticate(prereqtok)
if err != nil {
e := &ErrUnableToReauthenticate{}
@@ -447,8 +404,7 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
seeker.Seek(0, 0)
}
}
- state.hasReauthenticated = true
- resp, err = client.doRequest(method, url, options, state)
+ resp, err = client.Request(method, url, options)
if err != nil {
switch err.(type) {
case *ErrUnexpectedResponseCode:
@@ -519,40 +475,25 @@ func (client *ProviderClient) doRequest(method, url string, options *RequestOpts
// Parse the response body as JSON, if requested to do so.
if options.JSONResponse != nil {
defer resp.Body.Close()
- // Don't decode JSON when there is no content
- if resp.StatusCode == http.StatusNoContent {
- // read till EOF, otherwise the connection will be closed and cannot be reused
- _, err = io.Copy(ioutil.Discard, resp.Body)
- return resp, err
- }
if err := json.NewDecoder(resp.Body).Decode(options.JSONResponse); err != nil {
return nil, err
}
}
- // Close unused body to allow the HTTP connection to be reused
- if !options.KeepResponseBody && options.JSONResponse == nil {
- defer resp.Body.Close()
- // read till EOF, otherwise the connection will be closed and cannot be reused
- if _, err := io.Copy(ioutil.Discard, resp.Body); err != nil {
- return nil, err
- }
- }
-
return resp, nil
}
func defaultOkCodes(method string) []int {
- switch method {
- case "GET", "HEAD":
+ switch {
+ case method == "GET":
return []int{200}
- case "POST":
+ case method == "POST":
return []int{201, 202}
- case "PUT":
+ case method == "PUT":
return []int{201, 202}
- case "PATCH":
+ case method == "PATCH":
return []int{200, 202, 204}
- case "DELETE":
+ case method == "DELETE":
return []int{202, 204}
}
diff --git a/vendor/github.com/gophercloud/gophercloud/results.go b/vendor/github.com/gophercloud/gophercloud/results.go
index 1b608103b..94a16bff0 100644
--- a/vendor/github.com/gophercloud/gophercloud/results.go
+++ b/vendor/github.com/gophercloud/gophercloud/results.go
@@ -131,18 +131,6 @@ func (r Result) extractIntoPtr(to interface{}, label string) error {
// fields of the struct or composed extension struct
// at the end of this method.
toValue.Set(newSlice)
-
- // jtopjian: This was put into place to resolve the issue
- // described at
- // https://github.com/gophercloud/gophercloud/issues/1963
- //
- // This probably isn't the best fix, but it appears to
- // be resolving the issue, so I'm going to implement it
- // for now.
- //
- // For future readers, this entire case statement could
- // use a review.
- return nil
}
}
case reflect.Struct:
diff --git a/vendor/github.com/gophercloud/gophercloud/service_client.go b/vendor/github.com/gophercloud/gophercloud/service_client.go
index dd54abe30..f222f05a6 100644
--- a/vendor/github.com/gophercloud/gophercloud/service_client.go
+++ b/vendor/github.com/gophercloud/gophercloud/service_client.go
@@ -152,11 +152,3 @@ func (client *ServiceClient) Request(method, url string, options *RequestOpts) (
}
return client.ProviderClient.Request(method, url, options)
}
-
-// ParseResponse is a helper function to parse http.Response to constituents.
-func ParseResponse(resp *http.Response, err error) (io.ReadCloser, http.Header, error) {
- if resp != nil {
- return resp.Body, resp.Header, err
- }
- return nil, nil, err
-}
diff --git a/vendor/github.com/hashicorp/golang-lru/go.mod b/vendor/github.com/hashicorp/golang-lru/go.mod
index 8ad8826b3..824cb97e8 100644
--- a/vendor/github.com/hashicorp/golang-lru/go.mod
+++ b/vendor/github.com/hashicorp/golang-lru/go.mod
@@ -1,3 +1 @@
module github.com/hashicorp/golang-lru
-
-go 1.12
diff --git a/vendor/github.com/hashicorp/golang-lru/lru.go b/vendor/github.com/hashicorp/golang-lru/lru.go
index 4e5e9d8fd..1cbe04b7d 100644
--- a/vendor/github.com/hashicorp/golang-lru/lru.go
+++ b/vendor/github.com/hashicorp/golang-lru/lru.go
@@ -37,7 +37,7 @@ func (c *Cache) Purge() {
c.lock.Unlock()
}
-// Add adds a value to the cache. Returns true if an eviction occurred.
+// Add adds a value to the cache. Returns true if an eviction occurred.
func (c *Cache) Add(key, value interface{}) (evicted bool) {
c.lock.Lock()
evicted = c.lru.Add(key, value)
@@ -71,8 +71,8 @@ func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
return value, ok
}
-// ContainsOrAdd checks if a key is in the cache without updating the
-// recent-ness or deleting it for being stale, and if not, adds the value.
+// ContainsOrAdd checks if a key is in the cache without updating the
+// recent-ness or deleting it for being stale, and if not, adds the value.
// Returns whether found and whether an eviction occurred.
func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
c.lock.Lock()
@@ -85,52 +85,18 @@ func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
return false, evicted
}
-// PeekOrAdd checks if a key is in the cache without updating the
-// recent-ness or deleting it for being stale, and if not, adds the value.
-// Returns whether found and whether an eviction occurred.
-func (c *Cache) PeekOrAdd(key, value interface{}) (previous interface{}, ok, evicted bool) {
- c.lock.Lock()
- defer c.lock.Unlock()
-
- previous, ok = c.lru.Peek(key)
- if ok {
- return previous, true, false
- }
-
- evicted = c.lru.Add(key, value)
- return nil, false, evicted
-}
-
// Remove removes the provided key from the cache.
-func (c *Cache) Remove(key interface{}) (present bool) {
+func (c *Cache) Remove(key interface{}) {
c.lock.Lock()
- present = c.lru.Remove(key)
+ c.lru.Remove(key)
c.lock.Unlock()
- return
-}
-
-// Resize changes the cache size.
-func (c *Cache) Resize(size int) (evicted int) {
- c.lock.Lock()
- evicted = c.lru.Resize(size)
- c.lock.Unlock()
- return evicted
}
// RemoveOldest removes the oldest item from the cache.
-func (c *Cache) RemoveOldest() (key interface{}, value interface{}, ok bool) {
- c.lock.Lock()
- key, value, ok = c.lru.RemoveOldest()
- c.lock.Unlock()
- return
-}
-
-// GetOldest returns the oldest entry
-func (c *Cache) GetOldest() (key interface{}, value interface{}, ok bool) {
+func (c *Cache) RemoveOldest() {
c.lock.Lock()
- key, value, ok = c.lru.GetOldest()
+ c.lru.RemoveOldest()
c.lock.Unlock()
- return
}
// Keys returns a slice of the keys in the cache, from oldest to newest.
diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
index a86c8539e..5673773b2 100644
--- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
+++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru.go
@@ -73,9 +73,6 @@ func (c *LRU) Add(key, value interface{}) (evicted bool) {
func (c *LRU) Get(key interface{}) (value interface{}, ok bool) {
if ent, ok := c.items[key]; ok {
c.evictList.MoveToFront(ent)
- if ent.Value.(*entry) == nil {
- return nil, false
- }
return ent.Value.(*entry).value, true
}
return
@@ -145,19 +142,6 @@ func (c *LRU) Len() int {
return c.evictList.Len()
}
-// Resize changes the cache size.
-func (c *LRU) Resize(size int) (evicted int) {
- diff := c.Len() - size
- if diff < 0 {
- diff = 0
- }
- for i := 0; i < diff; i++ {
- c.removeOldest()
- }
- c.size = size
- return diff
-}
-
// removeOldest removes the oldest item from the cache.
func (c *LRU) removeOldest() {
ent := c.evictList.Back()
diff --git a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
index 92d70934d..74c707744 100644
--- a/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
+++ b/vendor/github.com/hashicorp/golang-lru/simplelru/lru_interface.go
@@ -10,7 +10,7 @@ type LRUCache interface {
// updates the "recently used"-ness of the key. #value, isFound
Get(key interface{}) (value interface{}, ok bool)
- // Checks if a key exists in cache without updating the recent-ness.
+ // Check if a key exsists in cache without updating the recent-ness.
Contains(key interface{}) (ok bool)
// Returns key's value without updating the "recently used"-ness of the key.
@@ -31,9 +31,6 @@ type LRUCache interface {
// Returns the number of items in the cache.
Len() int
- // Clears all cache entries.
+ // Clear all cache entries
Purge()
-
- // Resizes cache, returning number evicted
- Resize(int) int
}
diff --git a/vendor/github.com/mailru/easyjson/jwriter/writer.go b/vendor/github.com/mailru/easyjson/jwriter/writer.go
index eb8547ccc..b9ed7ccaa 100644
--- a/vendor/github.com/mailru/easyjson/jwriter/writer.go
+++ b/vendor/github.com/mailru/easyjson/jwriter/writer.go
@@ -270,25 +270,16 @@ func (w *Writer) Bool(v bool) {
const chars = "0123456789abcdef"
-func getTable(falseValues ...int) [128]bool {
- table := [128]bool{}
-
- for i := 0; i < 128; i++ {
- table[i] = true
- }
-
- for _, v := range falseValues {
- table[v] = false
+func isNotEscapedSingleChar(c byte, escapeHTML bool) bool {
+ // Note: might make sense to use a table if there are more chars to escape. With 4 chars
+ // it benchmarks the same.
+ if escapeHTML {
+ return c != '<' && c != '>' && c != '&' && c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
+ } else {
+ return c != '\\' && c != '"' && c >= 0x20 && c < utf8.RuneSelf
}
-
- return table
}
-var (
- htmlEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '&', '<', '>', '\\')
- htmlNoEscapeTable = getTable(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, '"', '\\')
-)
-
func (w *Writer) String(s string) {
w.Buffer.AppendByte('"')
@@ -297,23 +288,15 @@ func (w *Writer) String(s string) {
p := 0 // last non-escape symbol
- var escapeTable [128]bool
- if w.NoEscapeHTML {
- escapeTable = htmlNoEscapeTable
- } else {
- escapeTable = htmlEscapeTable
- }
-
for i := 0; i < len(s); {
c := s[i]
- if c < utf8.RuneSelf {
- if escapeTable[c] {
- // single-width character, no escaping is required
- i++
- continue
- }
-
+ if isNotEscapedSingleChar(c, !w.NoEscapeHTML) {
+ // single-width character, no escaping is required
+ i++
+ continue
+ } else if c < utf8.RuneSelf {
+ // single-with character, need to escape
w.Buffer.AppendString(s[p:i])
switch c {
case '\t':
diff --git a/vendor/github.com/mitchellh/mapstructure/.travis.yml b/vendor/github.com/mitchellh/mapstructure/.travis.yml
index b122a8e3d..1689c7d73 100644
--- a/vendor/github.com/mitchellh/mapstructure/.travis.yml
+++ b/vendor/github.com/mitchellh/mapstructure/.travis.yml
@@ -6,4 +6,3 @@ go:
script:
- go test
- - go test -bench . -benchmem
diff --git a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
index 0a21e2cd1..3b3cb723f 100644
--- a/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
+++ b/vendor/github.com/mitchellh/mapstructure/CHANGELOG.md
@@ -1,22 +1,3 @@
-## 1.2.2
-
-* Do not add unsettable (unexported) values to the unused metadata key
- or "remain" value. [GH-150]
-
-## 1.2.1
-
-* Go modules checksum mismatch fix
-
-## 1.2.0
-
-* Added support to capture unused values in a field using the `",remain"` value
- in the mapstructure tag. There is an example to showcase usage.
-* Added `DecoderConfig` option to always squash embedded structs
-* `json.Number` can decode into `uint` types
-* Empty slices are preserved and not replaced with nil slices
-* Fix panic that can occur in when decoding a map into a nil slice of structs
-* Improved package documentation for godoc
-
## 1.1.2
* Fix error when decode hook decodes interface implementation into interface
diff --git a/vendor/github.com/mitchellh/mapstructure/go.mod b/vendor/github.com/mitchellh/mapstructure/go.mod
index a03ae9730..d2a712562 100644
--- a/vendor/github.com/mitchellh/mapstructure/go.mod
+++ b/vendor/github.com/mitchellh/mapstructure/go.mod
@@ -1,3 +1 @@
module github.com/mitchellh/mapstructure
-
-go 1.14
diff --git a/vendor/github.com/mitchellh/mapstructure/mapstructure.go b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
index daea3318e..256ee63fb 100644
--- a/vendor/github.com/mitchellh/mapstructure/mapstructure.go
+++ b/vendor/github.com/mitchellh/mapstructure/mapstructure.go
@@ -1,109 +1,10 @@
-// Package mapstructure exposes functionality to convert one arbitrary
-// Go type into another, typically to convert a map[string]interface{}
-// into a native Go structure.
+// Package mapstructure exposes functionality to convert an arbitrary
+// map[string]interface{} into a native Go structure.
//
// The Go structure can be arbitrarily complex, containing slices,
// other structs, etc. and the decoder will properly decode nested
// maps and so on into the proper structures in the native Go struct.
// See the examples to see what the decoder is capable of.
-//
-// The simplest function to start with is Decode.
-//
-// Field Tags
-//
-// When decoding to a struct, mapstructure will use the field name by
-// default to perform the mapping. For example, if a struct has a field
-// "Username" then mapstructure will look for a key in the source value
-// of "username" (case insensitive).
-//
-// type User struct {
-// Username string
-// }
-//
-// You can change the behavior of mapstructure by using struct tags.
-// The default struct tag that mapstructure looks for is "mapstructure"
-// but you can customize it using DecoderConfig.
-//
-// Renaming Fields
-//
-// To rename the key that mapstructure looks for, use the "mapstructure"
-// tag and set a value directly. For example, to change the "username" example
-// above to "user":
-//
-// type User struct {
-// Username string `mapstructure:"user"`
-// }
-//
-// Embedded Structs and Squashing
-//
-// Embedded structs are treated as if they're another field with that name.
-// By default, the two structs below are equivalent when decoding with
-// mapstructure:
-//
-// type Person struct {
-// Name string
-// }
-//
-// type Friend struct {
-// Person
-// }
-//
-// type Friend struct {
-// Person Person
-// }
-//
-// This would require an input that looks like below:
-//
-// map[string]interface{}{
-// "person": map[string]interface{}{"name": "alice"},
-// }
-//
-// If your "person" value is NOT nested, then you can append ",squash" to
-// your tag value and mapstructure will treat it as if the embedded struct
-// were part of the struct directly. Example:
-//
-// type Friend struct {
-// Person `mapstructure:",squash"`
-// }
-//
-// Now the following input would be accepted:
-//
-// map[string]interface{}{
-// "name": "alice",
-// }
-//
-// DecoderConfig has a field that changes the behavior of mapstructure
-// to always squash embedded structs.
-//
-// Remainder Values
-//
-// If there are any unmapped keys in the source value, mapstructure by
-// default will silently ignore them. You can error by setting ErrorUnused
-// in DecoderConfig. If you're using Metadata you can also maintain a slice
-// of the unused keys.
-//
-// You can also use the ",remain" suffix on your tag to collect all unused
-// values in a map. The field with this tag MUST be a map type and should
-// probably be a "map[string]interface{}" or "map[interface{}]interface{}".
-// See example below:
-//
-// type Friend struct {
-// Name string
-// Other map[string]interface{} `mapstructure:",remain"`
-// }
-//
-// Given the input below, Other would be populated with the other
-// values that weren't used (everything but "name"):
-//
-// map[string]interface{}{
-// "name": "bob",
-// "address": "123 Maple St.",
-// }
-//
-// Other Configuration
-//
-// mapstructure is highly configurable. See the DecoderConfig struct
-// for other features and options that are supported.
package mapstructure
import (
@@ -179,14 +80,6 @@ type DecoderConfig struct {
//
WeaklyTypedInput bool
- // Squash will squash embedded structs. A squash tag may also be
- // added to an individual struct field using a tag. For example:
- //
- // type Parent struct {
- // Child `mapstructure:",squash"`
- // }
- Squash bool
-
// Metadata is the struct that will contain extra metadata about
// the decoding. If this is nil, then no metadata will be tracked.
Metadata *Metadata
@@ -545,7 +438,6 @@ func (d *Decoder) decodeInt(name string, data interface{}, val reflect.Value) er
func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) error {
dataVal := reflect.Indirect(reflect.ValueOf(data))
dataKind := getKind(dataVal)
- dataType := dataVal.Type()
switch {
case dataKind == reflect.Int:
@@ -577,18 +469,6 @@ func (d *Decoder) decodeUint(name string, data interface{}, val reflect.Value) e
} else {
return fmt.Errorf("cannot parse '%s' as uint: %s", name, err)
}
- case dataType.PkgPath() == "encoding/json" && dataType.Name() == "Number":
- jn := data.(json.Number)
- i, err := jn.Int64()
- if err != nil {
- return fmt.Errorf(
- "error decoding json.Number into %s: %s", name, err)
- }
- if i < 0 && !d.config.WeaklyTypedInput {
- return fmt.Errorf("cannot parse '%s', %d overflows uint",
- name, i)
- }
- val.SetUint(uint64(i))
default:
return fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s'",
@@ -809,20 +689,17 @@ func (d *Decoder) decodeMapFromStruct(name string, dataVal reflect.Value, val re
keyName = tagParts[0]
}
- // If Squash is set in the config, we squash the field down.
- squash := d.config.Squash && v.Kind() == reflect.Struct
// If "squash" is specified in the tag, we squash the field down.
- if !squash {
- for _, tag := range tagParts[1:] {
- if tag == "squash" {
- squash = true
- break
- }
- }
- if squash && v.Kind() != reflect.Struct {
- return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
+ squash := false
+ for _, tag := range tagParts[1:] {
+ if tag == "squash" {
+ squash = true
+ break
}
}
+ if squash && v.Kind() != reflect.Struct {
+ return fmt.Errorf("cannot squash non-struct type '%s'", v.Type())
+ }
switch v.Kind() {
// this is an embedded struct, so handle it differently
@@ -928,8 +805,8 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
valElemType := valType.Elem()
sliceType := reflect.SliceOf(valElemType)
- // If we have a non array/slice type then we first attempt to convert.
- if dataValKind != reflect.Array && dataValKind != reflect.Slice {
+ valSlice := val
+ if valSlice.IsNil() || d.config.ZeroFields {
if d.config.WeaklyTypedInput {
switch {
// Slice and array we use the normal logic
@@ -956,17 +833,18 @@ func (d *Decoder) decodeSlice(name string, data interface{}, val reflect.Value)
}
}
- return fmt.Errorf(
- "'%s': source data must be an array or slice, got %s", name, dataValKind)
- }
+ // Check input type
+ if dataValKind != reflect.Array && dataValKind != reflect.Slice {
+ return fmt.Errorf(
+ "'%s': source data must be an array or slice, got %s", name, dataValKind)
- // If the input value is nil, then don't allocate since empty != nil
- if dataVal.IsNil() {
- return nil
- }
+ }
+
+ // If the input value is empty, then don't allocate since non-nil != nil
+ if dataVal.Len() == 0 {
+ return nil
+ }
- valSlice := val
- if valSlice.IsNil() || d.config.ZeroFields {
// Make a new slice to hold our result, same size as the original data.
valSlice = reflect.MakeSlice(sliceType, dataVal.Len(), dataVal.Len())
}
@@ -1127,11 +1005,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
field reflect.StructField
val reflect.Value
}
-
- // remainField is set to a valid field set with the "remain" tag if
- // we are keeping track of remaining values.
- var remainField *field
-
fields := []field{}
for len(structs) > 0 {
structVal := structs[0]
@@ -1144,21 +1017,13 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
fieldKind := fieldType.Type.Kind()
// If "squash" is specified in the tag, we squash the field down.
- squash := d.config.Squash && fieldKind == reflect.Struct
- remain := false
-
- // We always parse the tags cause we're looking for other tags too
+ squash := false
tagParts := strings.Split(fieldType.Tag.Get(d.config.TagName), ",")
for _, tag := range tagParts[1:] {
if tag == "squash" {
squash = true
break
}
-
- if tag == "remain" {
- remain = true
- break
- }
}
if squash {
@@ -1171,14 +1036,8 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
continue
}
- // Build our field
- fieldCurrent := field{fieldType, structVal.Field(i)}
- if remain {
- remainField = &fieldCurrent
- } else {
- // Normal struct field, store it away
- fields = append(fields, field{fieldType, structVal.Field(i)})
- }
+ // Normal struct field, store it away
+ fields = append(fields, field{fieldType, structVal.Field(i)})
}
}
@@ -1219,6 +1078,9 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
}
}
+ // Delete the key we're using from the unused map so we stop tracking
+ delete(dataValKeysUnused, rawMapKey.Interface())
+
if !fieldValue.IsValid() {
// This should never happen
panic("field is not valid")
@@ -1230,9 +1092,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
continue
}
- // Delete the key we're using from the unused map so we stop tracking
- delete(dataValKeysUnused, rawMapKey.Interface())
-
// If the name is empty string, then we're at the root, and we
// don't dot-join the fields.
if name != "" {
@@ -1244,25 +1103,6 @@ func (d *Decoder) decodeStructFromMap(name string, dataVal, val reflect.Value) e
}
}
- // If we have a "remain"-tagged field and we have unused keys then
- // we put the unused keys directly into the remain field.
- if remainField != nil && len(dataValKeysUnused) > 0 {
- // Build a map of only the unused values
- remain := map[interface{}]interface{}{}
- for key := range dataValKeysUnused {
- remain[key] = dataVal.MapIndex(reflect.ValueOf(key)).Interface()
- }
-
- // Decode it as-if we were just decoding this map onto our map.
- if err := d.decodeMap(name, remain, remainField.val); err != nil {
- errors = appendErrors(errors, err)
- }
-
- // Set the map to nil so we have none so that the next check will
- // not error (ErrorUnused)
- dataValKeysUnused = nil
- }
-
if d.config.ErrorUnused && len(dataValKeysUnused) > 0 {
keys := make([]string, 0, len(dataValKeysUnused))
for rawKey := range dataValKeysUnused {
diff --git a/vendor/go.uber.org/atomic/.gitignore b/vendor/go.uber.org/atomic/.gitignore
index c3fa25389..0a4504f11 100644
--- a/vendor/go.uber.org/atomic/.gitignore
+++ b/vendor/go.uber.org/atomic/.gitignore
@@ -1,7 +1,6 @@
-/bin
.DS_Store
/vendor
-cover.html
+/cover
cover.out
lint.log
diff --git a/vendor/go.uber.org/atomic/.travis.yml b/vendor/go.uber.org/atomic/.travis.yml
index 4e73268b6..0f3769e5f 100644
--- a/vendor/go.uber.org/atomic/.travis.yml
+++ b/vendor/go.uber.org/atomic/.travis.yml
@@ -2,26 +2,26 @@ sudo: false
language: go
go_import_path: go.uber.org/atomic
-env:
- global:
- - GO111MODULE=on
+go:
+ - 1.11.x
+ - 1.12.x
matrix:
include:
- go: 1.12.x
- - go: 1.13.x
- env: LINT=1
+ env: NO_TEST=yes LINT=yes
cache:
directories:
- vendor
-before_install:
- - go version
+install:
+ - make install_ci
script:
- - test -z "$LINT" || make lint
- - make cover
+ - test -n "$NO_TEST" || make test_ci
+ - test -n "$NO_TEST" || scripts/test-ubergo.sh
+ - test -z "$LINT" || make install_lint lint
after_success:
- bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/go.uber.org/atomic/CHANGELOG.md b/vendor/go.uber.org/atomic/CHANGELOG.md
deleted file mode 100644
index aef8b6ebc..000000000
--- a/vendor/go.uber.org/atomic/CHANGELOG.md
+++ /dev/null
@@ -1,64 +0,0 @@
-# Changelog
-All notable changes to this project will be documented in this file.
-
-The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
-and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-
-## [1.6.0] - 2020-02-24
-### Changed
-- Drop library dependency on `golang.org/x/{lint, tools}`.
-
-## [1.5.1] - 2019-11-19
-- Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together
- causing `CAS` to fail even though the old value matches.
-
-## [1.5.0] - 2019-10-29
-### Changed
-- With Go modules, only the `go.uber.org/atomic` import path is supported now.
- If you need to use the old import path, please add a `replace` directive to
- your `go.mod`.
-
-## [1.4.0] - 2019-05-01
-### Added
- - Add `atomic.Error` type for atomic operations on `error` values.
-
-## [1.3.2] - 2018-05-02
-### Added
-- Add `atomic.Duration` type for atomic operations on `time.Duration` values.
-
-## [1.3.1] - 2017-11-14
-### Fixed
-- Revert optimization for `atomic.String.Store("")` which caused data races.
-
-## [1.3.0] - 2017-11-13
-### Added
-- Add `atomic.Bool.CAS` for compare-and-swap semantics on bools.
-
-### Changed
-- Optimize `atomic.String.Store("")` by avoiding an allocation.
-
-## [1.2.0] - 2017-04-12
-### Added
-- Shadow `atomic.Value` from `sync/atomic`.
-
-## [1.1.0] - 2017-03-10
-### Added
-- Add atomic `Float64` type.
-
-### Changed
-- Support new `go.uber.org/atomic` import path.
-
-## [1.0.0] - 2016-07-18
-
-- Initial release.
-
-[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0
-[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1
-[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0
-[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0
-[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2
-[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1
-[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0
-[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0
-[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0
-[1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0
diff --git a/vendor/go.uber.org/atomic/Makefile b/vendor/go.uber.org/atomic/Makefile
index 39af0fb63..1ef263075 100644
--- a/vendor/go.uber.org/atomic/Makefile
+++ b/vendor/go.uber.org/atomic/Makefile
@@ -1,35 +1,51 @@
-# Directory to place `go install`ed binaries into.
-export GOBIN ?= $(shell pwd)/bin
+# Many Go tools take file globs or directories as arguments instead of packages.
+PACKAGE_FILES ?= *.go
-GOLINT = $(GOBIN)/golint
+# For pre go1.6
+export GO15VENDOREXPERIMENT=1
-GO_FILES ?= *.go
.PHONY: build
build:
- go build ./...
+ go build -i ./...
+
+
+.PHONY: install
+install:
+ glide --version || go get github.com/Masterminds/glide
+ glide install
+
.PHONY: test
test:
- go test -race ./...
+ go test -cover -race ./...
-.PHONY: gofmt
-gofmt:
- $(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX))
- gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true
- @[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" && cat $(FMT_LOG) && false)
-$(GOLINT):
- go install golang.org/x/lint/golint
+.PHONY: install_ci
+install_ci: install
+ go get github.com/wadey/gocovmerge
+ go get github.com/mattn/goveralls
+ go get golang.org/x/tools/cmd/cover
-.PHONY: golint
-golint: $(GOLINT)
- $(GOLINT) ./...
+.PHONY: install_lint
+install_lint:
+ go get golang.org/x/lint/golint
-.PHONY: lint
-lint: gofmt golint
-.PHONY: cover
-cover:
- go test -coverprofile=cover.out -coverpkg ./... -v ./...
- go tool cover -html=cover.out -o cover.html
+.PHONY: lint
+lint:
+ @rm -rf lint.log
+ @echo "Checking formatting..."
+ @gofmt -d -s $(PACKAGE_FILES) 2>&1 | tee lint.log
+ @echo "Checking vet..."
+ @go vet ./... 2>&1 | tee -a lint.log;)
+ @echo "Checking lint..."
+ @golint $$(go list ./...) 2>&1 | tee -a lint.log
+ @echo "Checking for unresolved FIXMEs..."
+ @git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log
+ @[ ! -s lint.log ]
+
+
+.PHONY: test_ci
+test_ci: install_ci build
+ ./scripts/cover.sh $(shell go list $(PACKAGES))
diff --git a/vendor/go.uber.org/atomic/README.md b/vendor/go.uber.org/atomic/README.md
index ade0c20f1..62eb8e576 100644
--- a/vendor/go.uber.org/atomic/README.md
+++ b/vendor/go.uber.org/atomic/README.md
@@ -3,34 +3,9 @@
Simple wrappers for primitive types to enforce atomic access.
## Installation
-
-```shell
-$ go get -u go.uber.org/atomic@v1
-```
-
-### Legacy Import Path
-
-As of v1.5.0, the import path `go.uber.org/atomic` is the only supported way
-of using this package. If you are using Go modules, this package will fail to
-compile with the legacy import path path `github.com/uber-go/atomic`.
-
-We recommend migrating your code to the new import path but if you're unable
-to do so, or if your dependencies are still using the old import path, you
-will have to add a `replace` directive to your `go.mod` file downgrading the
-legacy import path to an older version.
-
-```
-replace github.com/uber-go/atomic => github.com/uber-go/atomic v1.4.0
-```
-
-You can do so automatically by running the following command.
-
-```shell
-$ go mod edit -replace github.com/uber-go/atomic=github.com/uber-go/atomic@v1.4.0
-```
+`go get -u go.uber.org/atomic`
## Usage
-
The standard library's `sync/atomic` is powerful, but it's easy to forget which
variables must be accessed atomically. `go.uber.org/atomic` preserves all the
functionality of the standard library, but wraps the primitive types to
@@ -46,11 +21,9 @@ atom.CAS(40, 11)
See the [documentation][doc] for a complete API specification.
## Development Status
-
Stable.
----
-
+___
Released under the [MIT License](LICENSE.txt).
[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
diff --git a/vendor/go.uber.org/atomic/atomic.go b/vendor/go.uber.org/atomic/atomic.go
index ad5fa0980..1db6849fc 100644
--- a/vendor/go.uber.org/atomic/atomic.go
+++ b/vendor/go.uber.org/atomic/atomic.go
@@ -250,16 +250,11 @@ func (b *Bool) Swap(new bool) bool {
// Toggle atomically negates the Boolean and returns the previous value.
func (b *Bool) Toggle() bool {
- for {
- old := b.Load()
- if b.CAS(old, !old) {
- return old
- }
- }
+ return truthy(atomic.AddUint32(&b.v, 1) - 1)
}
func truthy(n uint32) bool {
- return n == 1
+ return n&1 == 1
}
func boolToInt(b bool) uint32 {
diff --git a/vendor/go.uber.org/atomic/glide.lock b/vendor/go.uber.org/atomic/glide.lock
new file mode 100644
index 000000000..3c72c5997
--- /dev/null
+++ b/vendor/go.uber.org/atomic/glide.lock
@@ -0,0 +1,17 @@
+hash: f14d51408e3e0e4f73b34e4039484c78059cd7fc5f4996fdd73db20dc8d24f53
+updated: 2016-10-27T00:10:51.16960137-07:00
+imports: []
+testImports:
+- name: github.com/davecgh/go-spew
+ version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
+ subpackages:
+ - spew
+- name: github.com/pmezard/go-difflib
+ version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
+ subpackages:
+ - difflib
+- name: github.com/stretchr/testify
+ version: d77da356e56a7428ad25149ca77381849a6a5232
+ subpackages:
+ - assert
+ - require
diff --git a/vendor/go.uber.org/atomic/glide.yaml b/vendor/go.uber.org/atomic/glide.yaml
new file mode 100644
index 000000000..4cf608ec0
--- /dev/null
+++ b/vendor/go.uber.org/atomic/glide.yaml
@@ -0,0 +1,6 @@
+package: go.uber.org/atomic
+testImport:
+- package: github.com/stretchr/testify
+ subpackages:
+ - assert
+ - require
diff --git a/vendor/go.uber.org/atomic/go.mod b/vendor/go.uber.org/atomic/go.mod
deleted file mode 100644
index a935daebb..000000000
--- a/vendor/go.uber.org/atomic/go.mod
+++ /dev/null
@@ -1,10 +0,0 @@
-module go.uber.org/atomic
-
-require (
- github.com/davecgh/go-spew v1.1.1 // indirect
- github.com/stretchr/testify v1.3.0
- golang.org/x/lint v0.0.0-20190930215403-16217165b5de
- golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c // indirect
-)
-
-go 1.13
diff --git a/vendor/go.uber.org/atomic/go.sum b/vendor/go.uber.org/atomic/go.sum
deleted file mode 100644
index 51b2b62af..000000000
--- a/vendor/go.uber.org/atomic/go.sum
+++ /dev/null
@@ -1,22 +0,0 @@
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd h1:/e+gpKk9r3dJobndpTytxS2gOy6m5uvpg+ISQoEcusQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/vendor/go.uber.org/multierr/.gitignore b/vendor/go.uber.org/multierr/.gitignore
index b9a05e3da..61ead8666 100644
--- a/vendor/go.uber.org/multierr/.gitignore
+++ b/vendor/go.uber.org/multierr/.gitignore
@@ -1,4 +1 @@
/vendor
-cover.html
-cover.out
-/bin
diff --git a/vendor/go.uber.org/multierr/.travis.yml b/vendor/go.uber.org/multierr/.travis.yml
index 786c917a3..5ffa8fed4 100644
--- a/vendor/go.uber.org/multierr/.travis.yml
+++ b/vendor/go.uber.org/multierr/.travis.yml
@@ -5,12 +5,11 @@ go_import_path: go.uber.org/multierr
env:
global:
- GO15VENDOREXPERIMENT=1
- - GO111MODULE=on
go:
- - 1.11.x
- - 1.12.x
- - 1.13.x
+ - 1.7
+ - 1.8
+ - tip
cache:
directories:
@@ -19,11 +18,16 @@ cache:
before_install:
- go version
+install:
+- |
+ set -e
+ make install_ci
+
script:
- |
set -e
make lint
- make cover
+ make test_ci
after_success:
- bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/go.uber.org/multierr/CHANGELOG.md b/vendor/go.uber.org/multierr/CHANGELOG.md
index f0055f895..898445d06 100644
--- a/vendor/go.uber.org/multierr/CHANGELOG.md
+++ b/vendor/go.uber.org/multierr/CHANGELOG.md
@@ -1,19 +1,6 @@
Releases
========
-v1.3.0 (2019-10-29)
-===================
-
-- Switch to Go modules.
-
-
-v1.2.0 (2019-09-26)
-===================
-
-- Support extracting and matching against wrapped errors with `errors.As`
- and `errors.Is`.
-
-
v1.1.0 (2017-06-30)
===================
diff --git a/vendor/go.uber.org/multierr/Makefile b/vendor/go.uber.org/multierr/Makefile
index 416018237..a7437d061 100644
--- a/vendor/go.uber.org/multierr/Makefile
+++ b/vendor/go.uber.org/multierr/Makefile
@@ -1,17 +1,23 @@
-# Directory to put `go install`ed binaries in.
-export GOBIN ?= $(shell pwd)/bin
+export GO15VENDOREXPERIMENT=1
+
+PACKAGES := $(shell glide nv)
GO_FILES := $(shell \
find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
-o -name '*.go' -print | cut -b3-)
+.PHONY: install
+install:
+ glide --version || go get github.com/Masterminds/glide
+ glide install
+
.PHONY: build
build:
- go build ./...
+ go build -i $(PACKAGES)
.PHONY: test
test:
- go test -race ./...
+ go test -cover -race $(PACKAGES)
.PHONY: gofmt
gofmt:
@@ -19,24 +25,50 @@ gofmt:
@gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true
@[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" | cat - $(FMT_LOG) && false)
+.PHONY: govet
+govet:
+ $(eval VET_LOG := $(shell mktemp -t govet.XXXXX))
+ @go vet $(PACKAGES) 2>&1 \
+ | grep -v '^exit status' > $(VET_LOG) || true
+ @[ ! -s "$(VET_LOG)" ] || (echo "govet failed:" | cat - $(VET_LOG) && false)
+
.PHONY: golint
golint:
- @go install golang.org/x/lint/golint
- @$(GOBIN)/golint ./...
+ @go get github.com/golang/lint/golint
+ $(eval LINT_LOG := $(shell mktemp -t golint.XXXXX))
+ @cat /dev/null > $(LINT_LOG)
+ @$(foreach pkg, $(PACKAGES), golint $(pkg) >> $(LINT_LOG) || true;)
+ @[ ! -s "$(LINT_LOG)" ] || (echo "golint failed:" | cat - $(LINT_LOG) && false)
.PHONY: staticcheck
staticcheck:
- @go install honnef.co/go/tools/cmd/staticcheck
- @$(GOBIN)/staticcheck ./...
+ @go get honnef.co/go/tools/cmd/staticcheck
+ $(eval STATICCHECK_LOG := $(shell mktemp -t staticcheck.XXXXX))
+ @staticcheck $(PACKAGES) 2>&1 > $(STATICCHECK_LOG) || true
+ @[ ! -s "$(STATICCHECK_LOG)" ] || (echo "staticcheck failed:" | cat - $(STATICCHECK_LOG) && false)
.PHONY: lint
-lint: gofmt golint staticcheck
+lint: gofmt govet golint staticcheck
.PHONY: cover
cover:
- go test -coverprofile=cover.out -coverpkg=./... -v ./...
+ ./scripts/cover.sh $(shell go list $(PACKAGES))
go tool cover -html=cover.out -o cover.html
update-license:
- @go install go.uber.org/tools/update-license
- @$(GOBIN)/update-license $(GO_FILES)
+ @go get go.uber.org/tools/update-license
+ @update-license \
+ $(shell go list -json $(PACKAGES) | \
+ jq -r '.Dir + "/" + (.GoFiles | .[])')
+
+##############################################################################
+
+.PHONY: install_ci
+install_ci: install
+ go get github.com/wadey/gocovmerge
+ go get github.com/mattn/goveralls
+ go get golang.org/x/tools/cmd/cover
+
+.PHONY: test_ci
+test_ci: install_ci
+ ./scripts/cover.sh $(shell go list $(PACKAGES))
diff --git a/vendor/go.uber.org/multierr/README.md b/vendor/go.uber.org/multierr/README.md
index 751bd65e5..065088f64 100644
--- a/vendor/go.uber.org/multierr/README.md
+++ b/vendor/go.uber.org/multierr/README.md
@@ -17,7 +17,7 @@ Released under the [MIT License].
[MIT License]: LICENSE.txt
[doc-img]: https://godoc.org/go.uber.org/multierr?status.svg
[doc]: https://godoc.org/go.uber.org/multierr
-[ci-img]: https://travis-ci.com/uber-go/multierr.svg?branch=master
+[ci-img]: https://travis-ci.org/uber-go/multierr.svg?branch=master
[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
-[ci]: https://travis-ci.com/uber-go/multierr
+[ci]: https://travis-ci.org/uber-go/multierr
[cov]: https://codecov.io/gh/uber-go/multierr
diff --git a/vendor/go.uber.org/multierr/error.go b/vendor/go.uber.org/multierr/error.go
index d4be18344..de6ce4736 100644
--- a/vendor/go.uber.org/multierr/error.go
+++ b/vendor/go.uber.org/multierr/error.go
@@ -33,7 +33,7 @@
// If only two errors are being combined, the Append function may be used
// instead.
//
-// err = multierr.Append(reader.Close(), writer.Close())
+// err = multierr.Combine(reader.Close(), writer.Close())
//
// This makes it possible to record resource cleanup failures from deferred
// blocks with the help of named return values.
@@ -99,6 +99,8 @@ var (
// Separator for single-line error messages.
_singlelineSeparator = []byte("; ")
+ _newline = []byte("\n")
+
// Prefix for multi-line messages
_multilinePrefix = []byte("the following errors occurred:")
diff --git a/vendor/go.uber.org/multierr/glide.lock b/vendor/go.uber.org/multierr/glide.lock
new file mode 100644
index 000000000..f9ea94c33
--- /dev/null
+++ b/vendor/go.uber.org/multierr/glide.lock
@@ -0,0 +1,19 @@
+hash: b53b5e9a84b9cb3cc4b2d0499e23da2feca1eec318ce9bb717ecf35bf24bf221
+updated: 2017-04-10T13:34:45.671678062-07:00
+imports:
+- name: go.uber.org/atomic
+ version: 3b8db5e93c4c02efbc313e17b2e796b0914a01fb
+testImports:
+- name: github.com/davecgh/go-spew
+ version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
+ subpackages:
+ - spew
+- name: github.com/pmezard/go-difflib
+ version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
+ subpackages:
+ - difflib
+- name: github.com/stretchr/testify
+ version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
+ subpackages:
+ - assert
+ - require
diff --git a/vendor/go.uber.org/multierr/go.mod b/vendor/go.uber.org/multierr/go.mod
deleted file mode 100644
index 5463fac72..000000000
--- a/vendor/go.uber.org/multierr/go.mod
+++ /dev/null
@@ -1,12 +0,0 @@
-module go.uber.org/multierr
-
-go 1.12
-
-require (
- github.com/stretchr/testify v1.3.0
- go.uber.org/atomic v1.5.0
- go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee
- golang.org/x/lint v0.0.0-20190930215403-16217165b5de
- golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 // indirect
- honnef.co/go/tools v0.0.1-2019.2.3
-)
diff --git a/vendor/go.uber.org/multierr/go.sum b/vendor/go.uber.org/multierr/go.sum
deleted file mode 100644
index b460913d2..000000000
--- a/vendor/go.uber.org/multierr/go.sum
+++ /dev/null
@@ -1,45 +0,0 @@
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
-go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/vendor/go.uber.org/multierr/go113.go b/vendor/go.uber.org/multierr/go113.go
deleted file mode 100644
index 264b0eac0..000000000
--- a/vendor/go.uber.org/multierr/go113.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2019 Uber Technologies, Inc.
-//
-// 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.
-
-// +build go1.13
-
-package multierr
-
-import "errors"
-
-// As attempts to find the first error in the error list that matches the type
-// of the value that target points to.
-//
-// This function allows errors.As to traverse the values stored on the
-// multierr error.
-func (merr *multiError) As(target interface{}) bool {
- for _, err := range merr.Errors() {
- if errors.As(err, target) {
- return true
- }
- }
- return false
-}
-
-// Is attempts to match the provided error against errors in the error list.
-//
-// This function allows errors.Is to traverse the values stored on the
-// multierr error.
-func (merr *multiError) Is(target error) bool {
- for _, err := range merr.Errors() {
- if errors.Is(err, target) {
- return true
- }
- }
- return false
-}
diff --git a/vendor/go.uber.org/multierr/tools.go b/vendor/go.uber.org/multierr/tools.go
deleted file mode 100644
index df93f0723..000000000
--- a/vendor/go.uber.org/multierr/tools.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2019 Uber Technologies, Inc.
-//
-// 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.
-
-// +build tools
-
-package multierr
-
-import (
- // Tools we use during development.
- _ "go.uber.org/tools/update-license"
- _ "golang.org/x/lint/golint"
- _ "honnef.co/go/tools/cmd/staticcheck"
-)
diff --git a/vendor/go.uber.org/tools/LICENSE b/vendor/go.uber.org/tools/LICENSE
deleted file mode 100644
index 858e02475..000000000
--- a/vendor/go.uber.org/tools/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2017 Uber Technologies, Inc.
-
-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/go.uber.org/tools/update-license/.gitignore b/vendor/go.uber.org/tools/update-license/.gitignore
deleted file mode 100644
index b167772c8..000000000
--- a/vendor/go.uber.org/tools/update-license/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-update-license
diff --git a/vendor/go.uber.org/tools/update-license/README.md b/vendor/go.uber.org/tools/update-license/README.md
deleted file mode 100644
index 5887df1dd..000000000
--- a/vendor/go.uber.org/tools/update-license/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# update-license
-
-This is a small tool that updates the license header for Uber's open source Golang files.
-
-## Installation
-
-```
-go get go.uber.org/tools/update-license
-```
-
-## Usage
-
-```
-update-license go_files...
-```
-
-## Further Work
-
-* Support more licenses by name (MIT, Apache 2.0, etc), file path, url (http GET)
-* Support custom owner (not just "Uber Technologies, Inc.")
-* Support more languages than go (cover go, java, js, py to start, along with LICENSE, LICENSE.txt)
-* Talk about removing custom logic for header comments (ie `@generated`, `Code generated by`), it probably makes more sense just to put the license at the top
-* Better detection support for existing licenses so they can be removed
-* Verbose, dry run support
diff --git a/vendor/go.uber.org/tools/update-license/licenses.go b/vendor/go.uber.org/tools/update-license/licenses.go
deleted file mode 100644
index 76957c21e..000000000
--- a/vendor/go.uber.org/tools/update-license/licenses.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright (c) 2019 Uber Technologies, Inc.
-//
-// 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.
-
-package main
-
-var licenseTemplates = map[string]string{
- "Apache-2.0": `// Copyright {{.Year}} {{.Owner}}
-//
-// 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.`,
- "MIT": `// Copyright (c) {{.Year}} {{.Owner}}
-//
-// 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/go.uber.org/tools/update-license/main.go b/vendor/go.uber.org/tools/update-license/main.go
deleted file mode 100644
index 269fd9b47..000000000
--- a/vendor/go.uber.org/tools/update-license/main.go
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright (c) 2019 Uber Technologies, Inc.
-//
-// 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.
-
-package main
-
-import (
- "bytes"
- "flag"
- "fmt"
- "html/template"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "sort"
- "strings"
- "time"
-)
-
-const (
- // how many lines to check for an existing copyright
- // this logic is not great and we should probably do something else
- // but this was copied from the python script
- copyrightLineLimit = 5
- headerPrefix = "// Copyright"
-)
-
-var (
- flagDryRun = flag.Bool("dry", false, "Do not edit files and just print out what files would be edited")
- flagOwner = flag.String("owner", "Uber Technologies, Inc.", "Copyright owner")
- flagLicense = flag.String(
- "license",
- "MIT",
- fmt.Sprintf(
- "Type of license to use [%s]",
- strings.Join(validLicenses(), ", "),
- ),
- )
-
- lineSkipPrefixes = []string{
- "// Code generated by",
- "// @generated",
- }
-)
-
-func main() {
- log.SetFlags(0)
- log.SetOutput(os.Stdout)
- log.SetPrefix("")
- if err := do(); err != nil {
- log.Fatal(err)
- }
-}
-
-func do() error {
- flag.Parse()
-
- if len(flag.Args()) < 1 {
- return fmt.Errorf("usage: %s GO_FILES", os.Args[0])
- }
-
- return updateFiles(
- flag.Args(),
- time.Now().UTC().Year(),
- *flagLicense,
- *flagOwner,
- *flagDryRun,
- )
-}
-
-func fullLicense(ts string, year int, owner string) string {
- var buf bytes.Buffer
- t, err := template.New("").Parse(ts)
- if err != nil {
- log.Panic("failed to parse license template", err)
- }
-
- data := struct {
- Year int
- Owner string
- }{year, owner}
- if err := t.Execute(&buf, data); err != nil {
- log.Panic("failed to execture license template", err)
- }
-
- return strings.TrimSpace(buf.String())
-}
-
-// validLicenses grabs all the license templates from the folder
-func validLicenses() []string {
- res := make([]string, 0, len(licenseTemplates))
-
- for k := range licenseTemplates {
- res = append(res, k)
- }
-
- sort.Strings(res)
- return res
-}
-
-func updateFiles(
- filePaths []string,
- year int,
- license string,
- owner string,
- dryRun bool,
-) error {
- if err := checkFilePaths(filePaths); err != nil {
- return err
- }
- for _, filePath := range filePaths {
- if err := updateFile(filePath, year, license, owner, dryRun); err != nil {
- return err
- }
- }
- return nil
-}
-
-func checkFilePaths(filePaths []string) error {
- for _, filePath := range filePaths {
- if filepath.Ext(filePath) != ".go" {
- return fmt.Errorf("%s is not a go file", filePath)
- }
- }
- return nil
-}
-
-func updateFile(
- filePath string,
- year int,
- license string,
- owner string,
- dryRun bool,
-) error {
- data, err := ioutil.ReadFile(filePath)
- if err != nil {
- return err
- }
- newData := updateData(data, year, license, owner)
- if !bytes.Equal(data, newData) {
- if dryRun {
- log.Print(filePath)
- return nil
- }
- // we could do something more complicated so that we do not
- // need to pass 0644 as the file mode, but in this case it should
- // never actually be used to create a file since we know the file
- // already exists, and it's easier to use the ReadFile/WriteFile
- // logic as it is right now, and since this is just a generation
- // program, this should be acceptable
- return ioutil.WriteFile(filePath, newData, 0644)
- }
- return nil
-}
-
-func updateData(
- data []byte,
- year int,
- license string,
- owner string,
-) []byte {
- licenseText := fullLicense(string(licenseTemplates[license]), year, owner)
-
- return []byte(
- strings.Join(
- updateLines(strings.Split(string(data), "\n"), licenseText),
- "\n",
- ),
- )
-}
-
-// a value in the returned slice may contain newlines itself
-func updateLines(lines []string, license string) []string {
- for i, line := range lines {
- if i >= copyrightLineLimit {
- break
- }
- if strings.HasPrefix(line, headerPrefix) {
- // assume that the new license text always starts with the copyright
- // string. Pretty safe to assume, right? RIGHT?
- lines[i] = strings.Split(license, "\n")[0]
- return lines
- }
- }
- return addToLines(lines, license)
-}
-
-// a value in the returned slice may contain newlines itself
-func addToLines(lines []string, license string) []string {
- i := 0
- for len(lines) > i && lineContainsSkipPrefix(lines[i]) {
- i++
- // skip comments under the generated line too
- for strings.HasPrefix(lines[i], "//") {
- i++
- }
- }
- if i == 0 {
- return append([]string{license, ""}, lines...)
- }
- return append(lines[0:i], append([]string{"", license}, lines[i:]...)...)
-}
-
-func lineContainsSkipPrefix(line string) bool {
- for _, skipPrefix := range lineSkipPrefixes {
- if strings.HasPrefix(line, skipPrefix) {
- return true
- }
- }
- return false
-}
diff --git a/vendor/go.uber.org/zap/.gitignore b/vendor/go.uber.org/zap/.gitignore
index da9d9d00b..08fbde6ce 100644
--- a/vendor/go.uber.org/zap/.gitignore
+++ b/vendor/go.uber.org/zap/.gitignore
@@ -26,7 +26,3 @@ _testmain.go
*.pprof
*.out
*.log
-
-/bin
-cover.out
-cover.html
diff --git a/vendor/go.uber.org/zap/.readme.tmpl b/vendor/go.uber.org/zap/.readme.tmpl
index 3154a1e64..c6440db8e 100644
--- a/vendor/go.uber.org/zap/.readme.tmpl
+++ b/vendor/go.uber.org/zap/.readme.tmpl
@@ -100,10 +100,9 @@ pinned in zap's [glide.lock][] file. [↩](#anchor-versions)
[doc-img]: https://godoc.org/go.uber.org/zap?status.svg
[doc]: https://godoc.org/go.uber.org/zap
-[ci-img]: https://travis-ci.com/uber-go/zap.svg?branch=master
-[ci]: https://travis-ci.com/uber-go/zap
+[ci-img]: https://travis-ci.org/uber-go/zap.svg?branch=master
+[ci]: https://travis-ci.org/uber-go/zap
[cov-img]: https://codecov.io/gh/uber-go/zap/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/zap
[benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks
[glide.lock]: https://github.com/uber-go/zap/blob/master/glide.lock
-
diff --git a/vendor/go.uber.org/zap/.travis.yml b/vendor/go.uber.org/zap/.travis.yml
index 647b4ee43..ada5ebdcc 100644
--- a/vendor/go.uber.org/zap/.travis.yml
+++ b/vendor/go.uber.org/zap/.travis.yml
@@ -1,23 +1,21 @@
language: go
sudo: false
-
+go:
+ - 1.11.x
+ - 1.12.x
go_import_path: go.uber.org/zap
env:
global:
- TEST_TIMEOUT_SCALE=10
- - GO111MODULE=on
-
-matrix:
- include:
- - go: 1.12.x
- - go: 1.13.x
- env: LINT=1
-
+cache:
+ directories:
+ - vendor
+install:
+ - make dependencies
script:
- - test -z "$LINT" || make lint
+ - make lint
- make test
- make bench
-
after_success:
- make cover
- bash <(curl -s https://codecov.io/bash)
diff --git a/vendor/go.uber.org/zap/CHANGELOG.md b/vendor/go.uber.org/zap/CHANGELOG.md
index bebdb748d..28d10677e 100644
--- a/vendor/go.uber.org/zap/CHANGELOG.md
+++ b/vendor/go.uber.org/zap/CHANGELOG.md
@@ -1,26 +1,5 @@
# Changelog
-## 1.13.0 (13 Nov 2019)
-
-Enhancements:
-* [#758][]: Add `Intp`, `Stringp`, and other similar `*p` field constructors
- to log pointers to primitives with support for `nil` values.
-
-Thanks to @jbizzle for their contributions to this release.
-
-## 1.12.0 (29 Oct 2019)
-
-Enhancements:
-* [#751][]: Migrate to Go modules.
-
-## 1.11.0 (21 Oct 2019)
-
-Enhancements:
-* [#725][]: Add `zapcore.OmitKey` to omit keys in an `EncoderConfig`.
-* [#736][]: Add `RFC3339` and `RFC3339Nano` time encoders.
-
-Thanks to @juicemia, @uhthomas for their contributions to this release.
-
## 1.10.0 (29 Apr 2019)
Bugfixes:
@@ -346,7 +325,3 @@ upgrade to the upcoming stable release.
[#610]: https://github.com/uber-go/zap/pull/610
[#675]: https://github.com/uber-go/zap/pull/675
[#704]: https://github.com/uber-go/zap/pull/704
-[#725]: https://github.com/uber-go/zap/pull/725
-[#736]: https://github.com/uber-go/zap/pull/736
-[#751]: https://github.com/uber-go/zap/pull/751
-[#758]: https://github.com/uber-go/zap/pull/758
diff --git a/vendor/go.uber.org/zap/Makefile b/vendor/go.uber.org/zap/Makefile
index 21e436c45..073e9aa91 100644
--- a/vendor/go.uber.org/zap/Makefile
+++ b/vendor/go.uber.org/zap/Makefile
@@ -1,55 +1,74 @@
-export GOBIN ?= $(shell pwd)/bin
+export GO15VENDOREXPERIMENT=1
-GOLINT = $(GOBIN)/golint
BENCH_FLAGS ?= -cpuprofile=cpu.pprof -memprofile=mem.pprof -benchmem
+PKGS ?= $(shell glide novendor)
+# Many Go tools take file globs or directories as arguments instead of packages.
+PKG_FILES ?= *.go zapcore benchmarks buffer zapgrpc zaptest zaptest/observer internal/bufferpool internal/exit internal/color internal/ztest
-# Directories containing independent Go modules.
-#
-# We track coverage only for the main module.
-MODULE_DIRS = . ./benchmarks
+# The linting tools evolve with each Go version, so run them only on the latest
+# stable release.
+GO_VERSION := $(shell go version | cut -d " " -f 3)
+GO_MINOR_VERSION := $(word 2,$(subst ., ,$(GO_VERSION)))
+LINTABLE_MINOR_VERSIONS := 12
+ifneq ($(filter $(LINTABLE_MINOR_VERSIONS),$(GO_MINOR_VERSION)),)
+SHOULD_LINT := true
+endif
-# Many Go tools take file globs or directories as arguments instead of packages.
-GO_FILES := $(shell \
- find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
- -o -name '*.go' -print | cut -b3-)
.PHONY: all
all: lint test
+.PHONY: dependencies
+dependencies:
+ @echo "Installing Glide and locked dependencies..."
+ glide --version || go get -u -f github.com/Masterminds/glide
+ glide install
+ @echo "Installing test dependencies..."
+ go install ./vendor/github.com/axw/gocov/gocov
+ go install ./vendor/github.com/mattn/goveralls
+ifdef SHOULD_LINT
+ @echo "Installing golint..."
+ go install ./vendor/github.com/golang/lint/golint
+else
+ @echo "Not installing golint, since we don't expect to lint on" $(GO_VERSION)
+endif
+
+# Disable printf-like invocation checking due to testify.assert.Error()
+VET_RULES := -printf=false
+
.PHONY: lint
-lint: $(GOLINT)
+lint:
+ifdef SHOULD_LINT
@rm -rf lint.log
@echo "Checking formatting..."
- @gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log
+ @gofmt -d -s $(PKG_FILES) 2>&1 | tee lint.log
+ @echo "Installing test dependencies for vet..."
+ @go test -i $(PKGS)
@echo "Checking vet..."
- @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go vet ./... 2>&1) &&) true | tee -a lint.log
+ @go vet $(VET_RULES) $(PKGS) 2>&1 | tee -a lint.log
@echo "Checking lint..."
- @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && $(GOLINT) ./... 2>&1) &&) true | tee -a lint.log
+ @$(foreach dir,$(PKGS),golint $(dir) 2>&1 | tee -a lint.log;)
@echo "Checking for unresolved FIXMEs..."
- @git grep -i fixme | grep -v -e Makefile | tee -a lint.log
+ @git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log
@echo "Checking for license headers..."
- @./checklicense.sh | tee -a lint.log
+ @./check_license.sh | tee -a lint.log
@[ ! -s lint.log ]
-
-$(GOLINT):
- go install golang.org/x/lint/golint
+else
+ @echo "Skipping linters on" $(GO_VERSION)
+endif
.PHONY: test
test:
- @$(foreach dir,$(MODULE_DIRS),(cd $(dir) && go test -race ./...) &&) true
+ go test -race $(PKGS)
.PHONY: cover
cover:
- go test -race -coverprofile=cover.out -coverpkg=./... ./...
- go tool cover -html=cover.out -o cover.html
+ ./scripts/cover.sh $(PKGS)
.PHONY: bench
BENCH ?= .
bench:
- @$(foreach dir,$(MODULE_DIRS), ( \
- cd $(dir) && \
- go list ./... | xargs -n1 go test -bench=$(BENCH) -run="^$$" $(BENCH_FLAGS) \
- ) &&) true
+ @$(foreach pkg,$(PKGS),go test -bench=$(BENCH) -run="^$$" $(BENCH_FLAGS) $(pkg);)
.PHONY: updatereadme
updatereadme:
diff --git a/vendor/go.uber.org/zap/README.md b/vendor/go.uber.org/zap/README.md
index bcea28a19..f4fd1cb44 100644
--- a/vendor/go.uber.org/zap/README.md
+++ b/vendor/go.uber.org/zap/README.md
@@ -64,40 +64,43 @@ id="anchor-versions">[1](#footnote-versions)
Log a message and 10 fields:
-| Package | Time | Time % to zap | Objects Allocated |
-| :------ | :--: | :-----------: | :---------------: |
-| :zap: zap | 862 ns/op | +0% | 5 allocs/op
-| :zap: zap (sugared) | 1250 ns/op | +45% | 11 allocs/op
-| zerolog | 4021 ns/op | +366% | 76 allocs/op
-| go-kit | 4542 ns/op | +427% | 105 allocs/op
-| apex/log | 26785 ns/op | +3007% | 115 allocs/op
-| logrus | 29501 ns/op | +3322% | 125 allocs/op
-| log15 | 29906 ns/op | +3369% | 122 allocs/op
+| Package | Time | Objects Allocated |
+| :--- | :---: | :---: |
+| :zap: zap | 3131 ns/op | 5 allocs/op |
+| :zap: zap (sugared) | 4173 ns/op | 21 allocs/op |
+| zerolog | 16154 ns/op | 90 allocs/op |
+| lion | 16341 ns/op | 111 allocs/op |
+| go-kit | 17049 ns/op | 126 allocs/op |
+| logrus | 23662 ns/op | 142 allocs/op |
+| log15 | 36351 ns/op | 149 allocs/op |
+| apex/log | 42530 ns/op | 126 allocs/op |
Log a message with a logger that already has 10 fields of context:
-| Package | Time | Time % to zap | Objects Allocated |
-| :------ | :--: | :-----------: | :---------------: |
-| :zap: zap | 126 ns/op | +0% | 0 allocs/op
-| :zap: zap (sugared) | 187 ns/op | +48% | 2 allocs/op
-| zerolog | 88 ns/op | -30% | 0 allocs/op
-| go-kit | 5087 ns/op | +3937% | 103 allocs/op
-| log15 | 18548 ns/op | +14621% | 73 allocs/op
-| apex/log | 26012 ns/op | +20544% | 104 allocs/op
-| logrus | 27236 ns/op | +21516% | 113 allocs/op
+| Package | Time | Objects Allocated |
+| :--- | :---: | :---: |
+| :zap: zap | 380 ns/op | 0 allocs/op |
+| :zap: zap (sugared) | 564 ns/op | 2 allocs/op |
+| zerolog | 321 ns/op | 0 allocs/op |
+| lion | 7092 ns/op | 39 allocs/op |
+| go-kit | 20226 ns/op | 115 allocs/op |
+| logrus | 22312 ns/op | 130 allocs/op |
+| log15 | 28788 ns/op | 79 allocs/op |
+| apex/log | 42063 ns/op | 115 allocs/op |
Log a static string, without any context or `printf`-style templating:
-| Package | Time | Time % to zap | Objects Allocated |
-| :------ | :--: | :-----------: | :---------------: |
-| :zap: zap | 118 ns/op | +0% | 0 allocs/op
-| :zap: zap (sugared) | 191 ns/op | +62% | 2 allocs/op
-| zerolog | 93 ns/op | -21% | 0 allocs/op
-| go-kit | 280 ns/op | +137% | 11 allocs/op
-| standard library | 499 ns/op | +323% | 2 allocs/op
-| apex/log | 1990 ns/op | +1586% | 10 allocs/op
-| logrus | 3129 ns/op | +2552% | 24 allocs/op
-| log15 | 3887 ns/op | +3194% | 23 allocs/op
+| Package | Time | Objects Allocated |
+| :--- | :---: | :---: |
+| :zap: zap | 361 ns/op | 0 allocs/op |
+| :zap: zap (sugared) | 534 ns/op | 2 allocs/op |
+| zerolog | 323 ns/op | 0 allocs/op |
+| standard library | 575 ns/op | 2 allocs/op |
+| go-kit | 922 ns/op | 13 allocs/op |
+| lion | 1413 ns/op | 10 allocs/op |
+| logrus | 2291 ns/op | 27 allocs/op |
+| apex/log | 3690 ns/op | 11 allocs/op |
+| log15 | 5954 ns/op | 26 allocs/op |
## Development Status: Stable
@@ -121,14 +124,13 @@ Released under the [MIT License](LICENSE.txt).
In particular, keep in mind that we may be
benchmarking against slightly older versions of other packages. Versions are
-pinned in the [benchmarks/go.mod][] file. [↩](#anchor-versions)
+pinned in zap's [glide.lock][] file. [↩](#anchor-versions)
[doc-img]: https://godoc.org/go.uber.org/zap?status.svg
[doc]: https://godoc.org/go.uber.org/zap
-[ci-img]: https://travis-ci.com/uber-go/zap.svg?branch=master
-[ci]: https://travis-ci.com/uber-go/zap
+[ci-img]: https://travis-ci.org/uber-go/zap.svg?branch=master
+[ci]: https://travis-ci.org/uber-go/zap
[cov-img]: https://codecov.io/gh/uber-go/zap/branch/master/graph/badge.svg
[cov]: https://codecov.io/gh/uber-go/zap
[benchmarking suite]: https://github.com/uber-go/zap/tree/master/benchmarks
-[benchmarks/go.mod]: https://github.com/uber-go/zap/blob/master/benchmarks/go.mod
-
+[glide.lock]: https://github.com/uber-go/zap/blob/master/glide.lock
diff --git a/vendor/go.uber.org/zap/checklicense.sh b/vendor/go.uber.org/zap/check_license.sh
similarity index 100%
rename from vendor/go.uber.org/zap/checklicense.sh
rename to vendor/go.uber.org/zap/check_license.sh
diff --git a/vendor/go.uber.org/zap/field.go b/vendor/go.uber.org/zap/field.go
index 83c1ea245..5130e1347 100644
--- a/vendor/go.uber.org/zap/field.go
+++ b/vendor/go.uber.org/zap/field.go
@@ -38,12 +38,6 @@ func Skip() Field {
return Field{Type: zapcore.SkipType}
}
-// nilField returns a field which will marshal explicitly as nil. See motivation
-// in https://github.com/uber-go/zap/issues/753 . If we ever make breaking
-// changes and add zapcore.NilType and zapcore.ObjectEncoder.AddNil, the
-// implementation here should be changed to reflect that.
-func nilField(key string) Field { return Reflect(key, nil) }
-
// Binary constructs a field that carries an opaque binary blob.
//
// Binary data is serialized in an encoding-appropriate format. For example,
@@ -62,15 +56,6 @@ func Bool(key string, val bool) Field {
return Field{Key: key, Type: zapcore.BoolType, Integer: ival}
}
-// Boolp constructs a field that carries a *bool. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Boolp(key string, val *bool) Field {
- if val == nil {
- return nilField(key)
- }
- return Bool(key, *val)
-}
-
// ByteString constructs a field that carries UTF-8 encoded text as a []byte.
// To log opaque binary blobs (which aren't necessarily valid UTF-8), use
// Binary.
@@ -85,15 +70,6 @@ func Complex128(key string, val complex128) Field {
return Field{Key: key, Type: zapcore.Complex128Type, Interface: val}
}
-// Complex128p constructs a field that carries a *complex128. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Complex128p(key string, val *complex128) Field {
- if val == nil {
- return nilField(key)
- }
- return Complex128(key, *val)
-}
-
// Complex64 constructs a field that carries a complex number. Unlike most
// numeric fields, this costs an allocation (to convert the complex64 to
// interface{}).
@@ -101,15 +77,6 @@ func Complex64(key string, val complex64) Field {
return Field{Key: key, Type: zapcore.Complex64Type, Interface: val}
}
-// Complex64p constructs a field that carries a *complex64. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Complex64p(key string, val *complex64) Field {
- if val == nil {
- return nilField(key)
- }
- return Complex64(key, *val)
-}
-
// Float64 constructs a field that carries a float64. The way the
// floating-point value is represented is encoder-dependent, so marshaling is
// necessarily lazy.
@@ -117,15 +84,6 @@ func Float64(key string, val float64) Field {
return Field{Key: key, Type: zapcore.Float64Type, Integer: int64(math.Float64bits(val))}
}
-// Float64p constructs a field that carries a *float64. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Float64p(key string, val *float64) Field {
- if val == nil {
- return nilField(key)
- }
- return Float64(key, *val)
-}
-
// Float32 constructs a field that carries a float32. The way the
// floating-point value is represented is encoder-dependent, so marshaling is
// necessarily lazy.
@@ -133,183 +91,66 @@ func Float32(key string, val float32) Field {
return Field{Key: key, Type: zapcore.Float32Type, Integer: int64(math.Float32bits(val))}
}
-// Float32p constructs a field that carries a *float32. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Float32p(key string, val *float32) Field {
- if val == nil {
- return nilField(key)
- }
- return Float32(key, *val)
-}
-
// Int constructs a field with the given key and value.
func Int(key string, val int) Field {
return Int64(key, int64(val))
}
-// Intp constructs a field that carries a *int. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Intp(key string, val *int) Field {
- if val == nil {
- return nilField(key)
- }
- return Int(key, *val)
-}
-
// Int64 constructs a field with the given key and value.
func Int64(key string, val int64) Field {
return Field{Key: key, Type: zapcore.Int64Type, Integer: val}
}
-// Int64p constructs a field that carries a *int64. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Int64p(key string, val *int64) Field {
- if val == nil {
- return nilField(key)
- }
- return Int64(key, *val)
-}
-
// Int32 constructs a field with the given key and value.
func Int32(key string, val int32) Field {
return Field{Key: key, Type: zapcore.Int32Type, Integer: int64(val)}
}
-// Int32p constructs a field that carries a *int32. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Int32p(key string, val *int32) Field {
- if val == nil {
- return nilField(key)
- }
- return Int32(key, *val)
-}
-
// Int16 constructs a field with the given key and value.
func Int16(key string, val int16) Field {
return Field{Key: key, Type: zapcore.Int16Type, Integer: int64(val)}
}
-// Int16p constructs a field that carries a *int16. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Int16p(key string, val *int16) Field {
- if val == nil {
- return nilField(key)
- }
- return Int16(key, *val)
-}
-
// Int8 constructs a field with the given key and value.
func Int8(key string, val int8) Field {
return Field{Key: key, Type: zapcore.Int8Type, Integer: int64(val)}
}
-// Int8p constructs a field that carries a *int8. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Int8p(key string, val *int8) Field {
- if val == nil {
- return nilField(key)
- }
- return Int8(key, *val)
-}
-
// String constructs a field with the given key and value.
func String(key string, val string) Field {
return Field{Key: key, Type: zapcore.StringType, String: val}
}
-// Stringp constructs a field that carries a *string. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Stringp(key string, val *string) Field {
- if val == nil {
- return nilField(key)
- }
- return String(key, *val)
-}
-
// Uint constructs a field with the given key and value.
func Uint(key string, val uint) Field {
return Uint64(key, uint64(val))
}
-// Uintp constructs a field that carries a *uint. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Uintp(key string, val *uint) Field {
- if val == nil {
- return nilField(key)
- }
- return Uint(key, *val)
-}
-
// Uint64 constructs a field with the given key and value.
func Uint64(key string, val uint64) Field {
return Field{Key: key, Type: zapcore.Uint64Type, Integer: int64(val)}
}
-// Uint64p constructs a field that carries a *uint64. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Uint64p(key string, val *uint64) Field {
- if val == nil {
- return nilField(key)
- }
- return Uint64(key, *val)
-}
-
// Uint32 constructs a field with the given key and value.
func Uint32(key string, val uint32) Field {
return Field{Key: key, Type: zapcore.Uint32Type, Integer: int64(val)}
}
-// Uint32p constructs a field that carries a *uint32. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Uint32p(key string, val *uint32) Field {
- if val == nil {
- return nilField(key)
- }
- return Uint32(key, *val)
-}
-
// Uint16 constructs a field with the given key and value.
func Uint16(key string, val uint16) Field {
return Field{Key: key, Type: zapcore.Uint16Type, Integer: int64(val)}
}
-// Uint16p constructs a field that carries a *uint16. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Uint16p(key string, val *uint16) Field {
- if val == nil {
- return nilField(key)
- }
- return Uint16(key, *val)
-}
-
// Uint8 constructs a field with the given key and value.
func Uint8(key string, val uint8) Field {
return Field{Key: key, Type: zapcore.Uint8Type, Integer: int64(val)}
}
-// Uint8p constructs a field that carries a *uint8. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Uint8p(key string, val *uint8) Field {
- if val == nil {
- return nilField(key)
- }
- return Uint8(key, *val)
-}
-
// Uintptr constructs a field with the given key and value.
func Uintptr(key string, val uintptr) Field {
return Field{Key: key, Type: zapcore.UintptrType, Integer: int64(val)}
}
-// Uintptrp constructs a field that carries a *uintptr. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Uintptrp(key string, val *uintptr) Field {
- if val == nil {
- return nilField(key)
- }
- return Uintptr(key, *val)
-}
-
// Reflect constructs a field with the given key and an arbitrary object. It uses
// an encoding-appropriate, reflection-based function to lazily serialize nearly
// any object into the logging context, but it's relatively slow and
@@ -342,15 +183,6 @@ func Time(key string, val time.Time) Field {
return Field{Key: key, Type: zapcore.TimeType, Integer: val.UnixNano(), Interface: val.Location()}
}
-// Timep constructs a field that carries a *time.Time. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Timep(key string, val *time.Time) Field {
- if val == nil {
- return nilField(key)
- }
- return Time(key, *val)
-}
-
// Stack constructs a field that stores a stacktrace of the current goroutine
// under provided key. Keep in mind that taking a stacktrace is eager and
// expensive (relatively speaking); this function both makes an allocation and
@@ -369,15 +201,6 @@ func Duration(key string, val time.Duration) Field {
return Field{Key: key, Type: zapcore.DurationType, Integer: int64(val)}
}
-// Durationp constructs a field that carries a *time.Duration. The returned Field will safely
-// and explicitly represent `nil` when appropriate.
-func Durationp(key string, val *time.Duration) Field {
- if val == nil {
- return nilField(key)
- }
- return Duration(key, *val)
-}
-
// Object constructs a field with the given key and ObjectMarshaler. It
// provides a flexible, but still type-safe and efficient, way to add map- or
// struct-like user-defined types to the logging context. The struct's
@@ -401,116 +224,78 @@ func Any(key string, value interface{}) Field {
return Array(key, val)
case bool:
return Bool(key, val)
- case *bool:
- return Boolp(key, val)
case []bool:
return Bools(key, val)
case complex128:
return Complex128(key, val)
- case *complex128:
- return Complex128p(key, val)
case []complex128:
return Complex128s(key, val)
case complex64:
return Complex64(key, val)
- case *complex64:
- return Complex64p(key, val)
case []complex64:
return Complex64s(key, val)
case float64:
return Float64(key, val)
- case *float64:
- return Float64p(key, val)
case []float64:
return Float64s(key, val)
case float32:
return Float32(key, val)
- case *float32:
- return Float32p(key, val)
case []float32:
return Float32s(key, val)
case int:
return Int(key, val)
- case *int:
- return Intp(key, val)
case []int:
return Ints(key, val)
case int64:
return Int64(key, val)
- case *int64:
- return Int64p(key, val)
case []int64:
return Int64s(key, val)
case int32:
return Int32(key, val)
- case *int32:
- return Int32p(key, val)
case []int32:
return Int32s(key, val)
case int16:
return Int16(key, val)
- case *int16:
- return Int16p(key, val)
case []int16:
return Int16s(key, val)
case int8:
return Int8(key, val)
- case *int8:
- return Int8p(key, val)
case []int8:
return Int8s(key, val)
case string:
return String(key, val)
- case *string:
- return Stringp(key, val)
case []string:
return Strings(key, val)
case uint:
return Uint(key, val)
- case *uint:
- return Uintp(key, val)
case []uint:
return Uints(key, val)
case uint64:
return Uint64(key, val)
- case *uint64:
- return Uint64p(key, val)
case []uint64:
return Uint64s(key, val)
case uint32:
return Uint32(key, val)
- case *uint32:
- return Uint32p(key, val)
case []uint32:
return Uint32s(key, val)
case uint16:
return Uint16(key, val)
- case *uint16:
- return Uint16p(key, val)
case []uint16:
return Uint16s(key, val)
case uint8:
return Uint8(key, val)
- case *uint8:
- return Uint8p(key, val)
case []byte:
return Binary(key, val)
case uintptr:
return Uintptr(key, val)
- case *uintptr:
- return Uintptrp(key, val)
case []uintptr:
return Uintptrs(key, val)
case time.Time:
return Time(key, val)
- case *time.Time:
- return Timep(key, val)
case []time.Time:
return Times(key, val)
case time.Duration:
return Duration(key, val)
- case *time.Duration:
- return Durationp(key, val)
case []time.Duration:
return Durations(key, val)
case error:
diff --git a/vendor/go.uber.org/zap/glide.lock b/vendor/go.uber.org/zap/glide.lock
new file mode 100644
index 000000000..881b462c0
--- /dev/null
+++ b/vendor/go.uber.org/zap/glide.lock
@@ -0,0 +1,76 @@
+hash: f073ba522c06c88ea3075bde32a8aaf0969a840a66cab6318a0897d141ffee92
+updated: 2017-07-22T18:06:49.598185334-07:00
+imports:
+- name: go.uber.org/atomic
+ version: 4e336646b2ef9fc6e47be8e21594178f98e5ebcf
+- name: go.uber.org/multierr
+ version: 3c4937480c32f4c13a875a1829af76c98ca3d40a
+testImports:
+- name: github.com/apex/log
+ version: d9b960447bfa720077b2da653cc79e533455b499
+ subpackages:
+ - handlers/json
+- name: github.com/axw/gocov
+ version: 3a69a0d2a4ef1f263e2d92b041a69593d6964fe8
+ subpackages:
+ - gocov
+- name: github.com/davecgh/go-spew
+ version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9
+ subpackages:
+ - spew
+- name: github.com/fatih/color
+ version: 62e9147c64a1ed519147b62a56a14e83e2be02c1
+- name: github.com/go-kit/kit
+ version: e10f5bf035be9af21fd5b2fb4469d5716c6ab07d
+ subpackages:
+ - log
+- name: github.com/go-logfmt/logfmt
+ version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
+- name: github.com/go-stack/stack
+ version: 54be5f394ed2c3e19dac9134a40a95ba5a017f7b
+- name: github.com/golang/lint
+ version: c5fb716d6688a859aae56d26d3e6070808df29f7
+ subpackages:
+ - golint
+- name: github.com/kr/logfmt
+ version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
+- name: github.com/mattn/go-colorable
+ version: 3fa8c76f9daed4067e4a806fb7e4dc86455c6d6a
+- name: github.com/mattn/go-isatty
+ version: fc9e8d8ef48496124e79ae0df75490096eccf6fe
+- name: github.com/mattn/goveralls
+ version: 6efce81852ad1b7567c17ad71b03aeccc9dd9ae0
+- name: github.com/pborman/uuid
+ version: e790cca94e6cc75c7064b1332e63811d4aae1a53
+- name: github.com/pkg/errors
+ version: 645ef00459ed84a119197bfb8d8205042c6df63d
+- name: github.com/pmezard/go-difflib
+ version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
+ subpackages:
+ - difflib
+- name: github.com/rs/zerolog
+ version: eed4c2b94d945e0b2456ad6aa518a443986b5f22
+- name: github.com/satori/go.uuid
+ version: 5bf94b69c6b68ee1b541973bb8e1144db23a194b
+- name: github.com/sirupsen/logrus
+ version: 7dd06bf38e1e13df288d471a57d5adbac106be9e
+- name: github.com/stretchr/testify
+ version: f6abca593680b2315d2075e0f5e2a9751e3f431a
+ subpackages:
+ - assert
+ - require
+- name: go.pedge.io/lion
+ version: 87958e8713f1fa138d993087133b97e976642159
+- name: golang.org/x/sys
+ version: c4489faa6e5ab84c0ef40d6ee878f7a030281f0f
+ subpackages:
+ - unix
+- name: golang.org/x/tools
+ version: 496819729719f9d07692195e0a94d6edd2251389
+ subpackages:
+ - cover
+- name: gopkg.in/inconshreveable/log15.v2
+ version: b105bd37f74e5d9dc7b6ad7806715c7a2b83fd3f
+ subpackages:
+ - stack
+ - term
diff --git a/vendor/go.uber.org/zap/glide.yaml b/vendor/go.uber.org/zap/glide.yaml
index 8e1d05e9a..94412594c 100644
--- a/vendor/go.uber.org/zap/glide.yaml
+++ b/vendor/go.uber.org/zap/glide.yaml
@@ -22,11 +22,12 @@ testImport:
- package: github.com/mattn/goveralls
- package: github.com/pborman/uuid
- package: github.com/pkg/errors
+- package: go.pedge.io/lion
- package: github.com/rs/zerolog
- package: golang.org/x/tools
subpackages:
- cover
-- package: golang.org/x/lint
+- package: github.com/golang/lint
subpackages:
- golint
- package: github.com/axw/gocov
diff --git a/vendor/go.uber.org/zap/go.mod b/vendor/go.uber.org/zap/go.mod
deleted file mode 100644
index 1fb6bba0b..000000000
--- a/vendor/go.uber.org/zap/go.mod
+++ /dev/null
@@ -1,11 +0,0 @@
-module go.uber.org/zap
-
-go 1.13
-
-require (
- github.com/pkg/errors v0.8.1
- github.com/stretchr/testify v1.4.0
- go.uber.org/atomic v1.5.0
- go.uber.org/multierr v1.3.0
- golang.org/x/lint v0.0.0-20190930215403-16217165b5de
-)
diff --git a/vendor/go.uber.org/zap/go.sum b/vendor/go.uber.org/zap/go.sum
deleted file mode 100644
index 9ff6735d8..000000000
--- a/vendor/go.uber.org/zap/go.sum
+++ /dev/null
@@ -1,56 +0,0 @@
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
-github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
-github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY=
-go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
-go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc=
-go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
-go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c h1:IGkKhmfzcztjm6gYkykvu/NiS8kaqbCWAEWWAyf8J5U=
-golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
-golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
-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=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
diff --git a/vendor/go.uber.org/zap/tools.go b/vendor/go.uber.org/zap/tools.go
deleted file mode 100644
index 2b6366bea..000000000
--- a/vendor/go.uber.org/zap/tools.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2019 Uber Technologies, Inc.
-//
-// 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.
-
-// +build tools
-
-package zap
-
-import (
- // Tools we use during development.
- _ "golang.org/x/lint/golint"
-)
diff --git a/vendor/go.uber.org/zap/zapcore/encoder.go b/vendor/go.uber.org/zap/zapcore/encoder.go
index 5e0a69be5..f0509522b 100644
--- a/vendor/go.uber.org/zap/zapcore/encoder.go
+++ b/vendor/go.uber.org/zap/zapcore/encoder.go
@@ -31,9 +31,6 @@ import (
// behavior.
const DefaultLineEnding = "\n"
-// OmitKey defines the key to use when callers want to remove a key from log output.
-const OmitKey = ""
-
// A LevelEncoder serializes a Level to a primitive type.
type LevelEncoder func(Level, PrimitiveArrayEncoder)
@@ -118,30 +115,11 @@ func ISO8601TimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
enc.AppendString(t.Format("2006-01-02T15:04:05.000Z0700"))
}
-// RFC3339TimeEncoder serializes a time.Time to an RFC3339-formatted string.
-func RFC3339TimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
- enc.AppendString(t.Format(time.RFC3339))
-}
-
-// RFC3339NanoTimeEncoder serializes a time.Time to an RFC3339-formatted string
-// with nanosecond precision.
-func RFC3339NanoTimeEncoder(t time.Time, enc PrimitiveArrayEncoder) {
- enc.AppendString(t.Format(time.RFC3339Nano))
-}
-
-// UnmarshalText unmarshals text to a TimeEncoder.
-// "rfc3339nano" and "RFC3339Nano" are unmarshaled to RFC3339NanoTimeEncoder.
-// "rfc3339" and "RFC3339" are unmarshaled to RFC3339TimeEncoder.
-// "iso8601" and "ISO8601" are unmarshaled to ISO8601TimeEncoder.
-// "millis" is unmarshaled to EpochMillisTimeEncoder.
-// "nanos" is unmarshaled to EpochNanosEncoder.
-// Anything else is unmarshaled to EpochTimeEncoder.
+// UnmarshalText unmarshals text to a TimeEncoder. "iso8601" and "ISO8601" are
+// unmarshaled to ISO8601TimeEncoder, "millis" is unmarshaled to
+// EpochMillisTimeEncoder, and anything else is unmarshaled to EpochTimeEncoder.
func (e *TimeEncoder) UnmarshalText(text []byte) error {
switch string(text) {
- case "rfc3339nano", "RFC3339Nano":
- *e = RFC3339NanoTimeEncoder
- case "rfc3339", "RFC3339":
- *e = RFC3339TimeEncoder
case "iso8601", "ISO8601":
*e = ISO8601TimeEncoder
case "millis":
@@ -294,8 +272,8 @@ type ObjectEncoder interface {
AddUint8(key string, value uint8)
AddUintptr(key string, value uintptr)
- // AddReflected uses reflection to serialize arbitrary objects, so it can be
- // slow and allocation-heavy.
+ // AddReflected uses reflection to serialize arbitrary objects, so it's slow
+ // and allocation-heavy.
AddReflected(key string, value interface{}) error
// OpenNamespace opens an isolated namespace where all subsequent fields will
// be added. Applications can use namespaces to prevent key collisions when
@@ -365,7 +343,6 @@ type Encoder interface {
Clone() Encoder
// EncodeEntry encodes an entry and fields, along with any accumulated
- // context, into a byte buffer and returns it. Any fields that are empty,
- // including fields on the `Entry` type, should be omitted.
+ // context, into a byte buffer and returns it.
EncodeEntry(Entry, []Field) (*buffer.Buffer, error)
}
diff --git a/vendor/go.uber.org/zap/zapcore/entry.go b/vendor/go.uber.org/zap/zapcore/entry.go
index 8273abdf0..7d9893f33 100644
--- a/vendor/go.uber.org/zap/zapcore/entry.go
+++ b/vendor/go.uber.org/zap/zapcore/entry.go
@@ -136,8 +136,7 @@ func (ec EntryCaller) TrimmedPath() string {
// An Entry represents a complete log message. The entry's structured context
// is already serialized, but the log level, time, message, and call site
-// information are available for inspection and modification. Any fields left
-// empty will be omitted when encoding.
+// information are available for inspection and modification.
//
// Entries are pooled, so any functions that accept them MUST be careful not to
// retain references to them.
diff --git a/vendor/go.uber.org/zap/zapcore/json_encoder.go b/vendor/go.uber.org/zap/zapcore/json_encoder.go
index 56256be8d..9aec4eada 100644
--- a/vendor/go.uber.org/zap/zapcore/json_encoder.go
+++ b/vendor/go.uber.org/zap/zapcore/json_encoder.go
@@ -145,29 +145,15 @@ func (enc *jsonEncoder) resetReflectBuf() {
}
}
-var nullLiteralBytes = []byte("null")
-
-// Only invoke the standard JSON encoder if there is actually something to
-// encode; otherwise write JSON null literal directly.
-func (enc *jsonEncoder) encodeReflected(obj interface{}) ([]byte, error) {
- if obj == nil {
- return nullLiteralBytes, nil
- }
- enc.resetReflectBuf()
- if err := enc.reflectEnc.Encode(obj); err != nil {
- return nil, err
- }
- enc.reflectBuf.TrimNewline()
- return enc.reflectBuf.Bytes(), nil
-}
-
func (enc *jsonEncoder) AddReflected(key string, obj interface{}) error {
- valueBytes, err := enc.encodeReflected(obj)
+ enc.resetReflectBuf()
+ err := enc.reflectEnc.Encode(obj)
if err != nil {
return err
}
+ enc.reflectBuf.TrimNewline()
enc.addKey(key)
- _, err = enc.buf.Write(valueBytes)
+ _, err = enc.buf.Write(enc.reflectBuf.Bytes())
return err
}
@@ -250,12 +236,14 @@ func (enc *jsonEncoder) AppendInt64(val int64) {
}
func (enc *jsonEncoder) AppendReflected(val interface{}) error {
- valueBytes, err := enc.encodeReflected(val)
+ enc.resetReflectBuf()
+ err := enc.reflectEnc.Encode(val)
if err != nil {
return err
}
+ enc.reflectBuf.TrimNewline()
enc.addElementSeparator()
- _, err = enc.buf.Write(valueBytes)
+ _, err = enc.buf.Write(enc.reflectBuf.Bytes())
return err
}
diff --git a/vendor/golang.org/x/lint/.travis.yml b/vendor/golang.org/x/lint/.travis.yml
deleted file mode 100644
index 50553ebd0..000000000
--- a/vendor/golang.org/x/lint/.travis.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-sudo: false
-language: go
-go:
- - 1.10.x
- - 1.11.x
- - master
-
-go_import_path: golang.org/x/lint
-
-install:
- - go get -t -v ./...
-
-script:
- - go test -v -race ./...
-
-matrix:
- allow_failures:
- - go: master
- fast_finish: true
diff --git a/vendor/golang.org/x/lint/CONTRIBUTING.md b/vendor/golang.org/x/lint/CONTRIBUTING.md
deleted file mode 100644
index 1fadda62d..000000000
--- a/vendor/golang.org/x/lint/CONTRIBUTING.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Contributing to Golint
-
-## Before filing an issue:
-
-### Are you having trouble building golint?
-
-Check you have the latest version of its dependencies. Run
-```
-go get -u golang.org/x/lint/golint
-```
-If you still have problems, consider searching for existing issues before filing a new issue.
-
-## Before sending a pull request:
-
-Have you understood the purpose of golint? Make sure to carefully read `README`.
diff --git a/vendor/golang.org/x/lint/LICENSE b/vendor/golang.org/x/lint/LICENSE
deleted file mode 100644
index 65d761bc9..000000000
--- a/vendor/golang.org/x/lint/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2013 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.
diff --git a/vendor/golang.org/x/lint/README.md b/vendor/golang.org/x/lint/README.md
deleted file mode 100644
index 4968b13ae..000000000
--- a/vendor/golang.org/x/lint/README.md
+++ /dev/null
@@ -1,88 +0,0 @@
-Golint is a linter for Go source code.
-
-[![Build Status](https://travis-ci.org/golang/lint.svg?branch=master)](https://travis-ci.org/golang/lint)
-
-## Installation
-
-Golint requires a
-[supported release of Go](https://golang.org/doc/devel/release.html#policy).
-
- go get -u golang.org/x/lint/golint
-
-To find out where `golint` was installed you can run `go list -f {{.Target}} golang.org/x/lint/golint`. For `golint` to be used globally add that directory to the `$PATH` environment setting.
-
-## Usage
-
-Invoke `golint` with one or more filenames, directories, or packages named
-by its import path. Golint uses the same
-[import path syntax](https://golang.org/cmd/go/#hdr-Import_path_syntax) as
-the `go` command and therefore
-also supports relative import paths like `./...`. Additionally the `...`
-wildcard can be used as suffix on relative and absolute file paths to recurse
-into them.
-
-The output of this tool is a list of suggestions in Vim quickfix format,
-which is accepted by lots of different editors.
-
-## Purpose
-
-Golint differs from gofmt. Gofmt reformats Go source code, whereas
-golint prints out style mistakes.
-
-Golint differs from govet. Govet is concerned with correctness, whereas
-golint is concerned with coding style. Golint is in use at Google, and it
-seeks to match the accepted style of the open source Go project.
-
-The suggestions made by golint are exactly that: suggestions.
-Golint is not perfect, and has both false positives and false negatives.
-Do not treat its output as a gold standard. We will not be adding pragmas
-or other knobs to suppress specific warnings, so do not expect or require
-code to be completely "lint-free".
-In short, this tool is not, and will never be, trustworthy enough for its
-suggestions to be enforced automatically, for example as part of a build process.
-Golint makes suggestions for many of the mechanically checkable items listed in
-[Effective Go](https://golang.org/doc/effective_go.html) and the
-[CodeReviewComments wiki page](https://golang.org/wiki/CodeReviewComments).
-
-## Scope
-
-Golint is meant to carry out the stylistic conventions put forth in
-[Effective Go](https://golang.org/doc/effective_go.html) and
-[CodeReviewComments](https://golang.org/wiki/CodeReviewComments).
-Changes that are not aligned with those documents will not be considered.
-
-## Contributions
-
-Contributions to this project are welcome provided they are [in scope](#scope),
-though please send mail before starting work on anything major.
-Contributors retain their copyright, so we need you to fill out
-[a short form](https://developers.google.com/open-source/cla/individual)
-before we can accept your contribution.
-
-## Vim
-
-Add this to your ~/.vimrc:
-
- set rtp+=$GOPATH/src/golang.org/x/lint/misc/vim
-
-If you have multiple entries in your GOPATH, replace `$GOPATH` with the right value.
-
-Running `:Lint` will run golint on the current file and populate the quickfix list.
-
-Optionally, add this to your `~/.vimrc` to automatically run `golint` on `:w`
-
- autocmd BufWritePost,FileWritePost *.go execute 'Lint' | cwindow
-
-
-## Emacs
-
-Add this to your `.emacs` file:
-
- (add-to-list 'load-path (concat (getenv "GOPATH") "/src/golang.org/x/lint/misc/emacs/"))
- (require 'golint)
-
-If you have multiple entries in your GOPATH, replace `$GOPATH` with the right value.
-
-Running M-x golint will run golint on the current file.
-
-For more usage, see [Compilation-Mode](http://www.gnu.org/software/emacs/manual/html_node/emacs/Compilation-Mode.html).
diff --git a/vendor/golang.org/x/lint/go.mod b/vendor/golang.org/x/lint/go.mod
deleted file mode 100644
index b32309c45..000000000
--- a/vendor/golang.org/x/lint/go.mod
+++ /dev/null
@@ -1,5 +0,0 @@
-module golang.org/x/lint
-
-go 1.11
-
-require golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7
diff --git a/vendor/golang.org/x/lint/go.sum b/vendor/golang.org/x/lint/go.sum
deleted file mode 100644
index 2ad45cae2..000000000
--- a/vendor/golang.org/x/lint/go.sum
+++ /dev/null
@@ -1,12 +0,0 @@
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7 h1:EBZoQjiKKPaLbPrbpssUfuHtwM6KV/vb4U85g/cigFY=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/vendor/golang.org/x/lint/golint/golint.go b/vendor/golang.org/x/lint/golint/golint.go
deleted file mode 100644
index ac024b6d2..000000000
--- a/vendor/golang.org/x/lint/golint/golint.go
+++ /dev/null
@@ -1,159 +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.
-
-// golint lints the Go source files named on its command line.
-package main
-
-import (
- "flag"
- "fmt"
- "go/build"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
-
- "golang.org/x/lint"
-)
-
-var (
- minConfidence = flag.Float64("min_confidence", 0.8, "minimum confidence of a problem to print it")
- setExitStatus = flag.Bool("set_exit_status", false, "set exit status to 1 if any issues are found")
- suggestions int
-)
-
-func usage() {
- fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
- fmt.Fprintf(os.Stderr, "\tgolint [flags] # runs on package in current directory\n")
- fmt.Fprintf(os.Stderr, "\tgolint [flags] [packages]\n")
- fmt.Fprintf(os.Stderr, "\tgolint [flags] [directories] # where a '/...' suffix includes all sub-directories\n")
- fmt.Fprintf(os.Stderr, "\tgolint [flags] [files] # all must belong to a single package\n")
- fmt.Fprintf(os.Stderr, "Flags:\n")
- flag.PrintDefaults()
-}
-
-func main() {
- flag.Usage = usage
- flag.Parse()
-
- if flag.NArg() == 0 {
- lintDir(".")
- } else {
- // dirsRun, filesRun, and pkgsRun indicate whether golint is applied to
- // directory, file or package targets. The distinction affects which
- // checks are run. It is no valid to mix target types.
- var dirsRun, filesRun, pkgsRun int
- var args []string
- for _, arg := range flag.Args() {
- if strings.HasSuffix(arg, "/...") && isDir(arg[:len(arg)-len("/...")]) {
- dirsRun = 1
- for _, dirname := range allPackagesInFS(arg) {
- args = append(args, dirname)
- }
- } else if isDir(arg) {
- dirsRun = 1
- args = append(args, arg)
- } else if exists(arg) {
- filesRun = 1
- args = append(args, arg)
- } else {
- pkgsRun = 1
- args = append(args, arg)
- }
- }
-
- if dirsRun+filesRun+pkgsRun != 1 {
- usage()
- os.Exit(2)
- }
- switch {
- case dirsRun == 1:
- for _, dir := range args {
- lintDir(dir)
- }
- case filesRun == 1:
- lintFiles(args...)
- case pkgsRun == 1:
- for _, pkg := range importPaths(args) {
- lintPackage(pkg)
- }
- }
- }
-
- if *setExitStatus && suggestions > 0 {
- fmt.Fprintf(os.Stderr, "Found %d lint suggestions; failing.\n", suggestions)
- os.Exit(1)
- }
-}
-
-func isDir(filename string) bool {
- fi, err := os.Stat(filename)
- return err == nil && fi.IsDir()
-}
-
-func exists(filename string) bool {
- _, err := os.Stat(filename)
- return err == nil
-}
-
-func lintFiles(filenames ...string) {
- files := make(map[string][]byte)
- for _, filename := range filenames {
- src, err := ioutil.ReadFile(filename)
- if err != nil {
- fmt.Fprintln(os.Stderr, err)
- continue
- }
- files[filename] = src
- }
-
- l := new(lint.Linter)
- ps, err := l.LintFiles(files)
- if err != nil {
- fmt.Fprintf(os.Stderr, "%v\n", err)
- return
- }
- for _, p := range ps {
- if p.Confidence >= *minConfidence {
- fmt.Printf("%v: %s\n", p.Position, p.Text)
- suggestions++
- }
- }
-}
-
-func lintDir(dirname string) {
- pkg, err := build.ImportDir(dirname, 0)
- lintImportedPackage(pkg, err)
-}
-
-func lintPackage(pkgname string) {
- pkg, err := build.Import(pkgname, ".", 0)
- lintImportedPackage(pkg, err)
-}
-
-func lintImportedPackage(pkg *build.Package, err error) {
- if err != nil {
- if _, nogo := err.(*build.NoGoError); nogo {
- // Don't complain if the failure is due to no Go source files.
- return
- }
- fmt.Fprintln(os.Stderr, err)
- return
- }
-
- var files []string
- files = append(files, pkg.GoFiles...)
- files = append(files, pkg.CgoFiles...)
- files = append(files, pkg.TestGoFiles...)
- if pkg.Dir != "." {
- for i, f := range files {
- files[i] = filepath.Join(pkg.Dir, f)
- }
- }
- // TODO(dsymonds): Do foo_test too (pkg.XTestGoFiles)
-
- lintFiles(files...)
-}
diff --git a/vendor/golang.org/x/lint/golint/import.go b/vendor/golang.org/x/lint/golint/import.go
deleted file mode 100644
index 2ba9dea77..000000000
--- a/vendor/golang.org/x/lint/golint/import.go
+++ /dev/null
@@ -1,309 +0,0 @@
-package main
-
-/*
-
-This file holds a direct copy of the import path matching code of
-https://github.com/golang/go/blob/master/src/cmd/go/main.go. It can be
-replaced when https://golang.org/issue/8768 is resolved.
-
-It has been updated to follow upstream changes in a few ways.
-
-*/
-
-import (
- "fmt"
- "go/build"
- "log"
- "os"
- "path"
- "path/filepath"
- "regexp"
- "runtime"
- "strings"
-)
-
-var (
- buildContext = build.Default
- goroot = filepath.Clean(runtime.GOROOT())
- gorootSrc = filepath.Join(goroot, "src")
-)
-
-// importPathsNoDotExpansion returns the import paths to use for the given
-// command line, but it does no ... expansion.
-func importPathsNoDotExpansion(args []string) []string {
- if len(args) == 0 {
- return []string{"."}
- }
- var out []string
- for _, a := range args {
- // Arguments are supposed to be import paths, but
- // as a courtesy to Windows developers, rewrite \ to /
- // in command-line arguments. Handles .\... and so on.
- if filepath.Separator == '\\' {
- a = strings.Replace(a, `\`, `/`, -1)
- }
-
- // Put argument in canonical form, but preserve leading ./.
- if strings.HasPrefix(a, "./") {
- a = "./" + path.Clean(a)
- if a == "./." {
- a = "."
- }
- } else {
- a = path.Clean(a)
- }
- if a == "all" || a == "std" {
- out = append(out, allPackages(a)...)
- continue
- }
- out = append(out, a)
- }
- return out
-}
-
-// importPaths returns the import paths to use for the given command line.
-func importPaths(args []string) []string {
- args = importPathsNoDotExpansion(args)
- var out []string
- for _, a := range args {
- if strings.Contains(a, "...") {
- if build.IsLocalImport(a) {
- out = append(out, allPackagesInFS(a)...)
- } else {
- out = append(out, allPackages(a)...)
- }
- continue
- }
- out = append(out, a)
- }
- return out
-}
-
-// matchPattern(pattern)(name) reports whether
-// name matches pattern. Pattern is a limited glob
-// pattern in which '...' means 'any string' and there
-// is no other special syntax.
-func matchPattern(pattern string) func(name string) bool {
- re := regexp.QuoteMeta(pattern)
- re = strings.Replace(re, `\.\.\.`, `.*`, -1)
- // Special case: foo/... matches foo too.
- if strings.HasSuffix(re, `/.*`) {
- re = re[:len(re)-len(`/.*`)] + `(/.*)?`
- }
- reg := regexp.MustCompile(`^` + re + `$`)
- return func(name string) bool {
- return reg.MatchString(name)
- }
-}
-
-// hasPathPrefix reports whether the path s begins with the
-// elements in prefix.
-func hasPathPrefix(s, prefix string) bool {
- switch {
- default:
- return false
- case len(s) == len(prefix):
- return s == prefix
- case len(s) > len(prefix):
- if prefix != "" && prefix[len(prefix)-1] == '/' {
- return strings.HasPrefix(s, prefix)
- }
- return s[len(prefix)] == '/' && s[:len(prefix)] == prefix
- }
-}
-
-// treeCanMatchPattern(pattern)(name) reports whether
-// name or children of name can possibly match pattern.
-// Pattern is the same limited glob accepted by matchPattern.
-func treeCanMatchPattern(pattern string) func(name string) bool {
- wildCard := false
- if i := strings.Index(pattern, "..."); i >= 0 {
- wildCard = true
- pattern = pattern[:i]
- }
- return func(name string) bool {
- return len(name) <= len(pattern) && hasPathPrefix(pattern, name) ||
- wildCard && strings.HasPrefix(name, pattern)
- }
-}
-
-// allPackages returns all the packages that can be found
-// under the $GOPATH directories and $GOROOT matching pattern.
-// The pattern is either "all" (all packages), "std" (standard packages)
-// or a path including "...".
-func allPackages(pattern string) []string {
- pkgs := matchPackages(pattern)
- if len(pkgs) == 0 {
- fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
- }
- return pkgs
-}
-
-func matchPackages(pattern string) []string {
- match := func(string) bool { return true }
- treeCanMatch := func(string) bool { return true }
- if pattern != "all" && pattern != "std" {
- match = matchPattern(pattern)
- treeCanMatch = treeCanMatchPattern(pattern)
- }
-
- have := map[string]bool{
- "builtin": true, // ignore pseudo-package that exists only for documentation
- }
- if !buildContext.CgoEnabled {
- have["runtime/cgo"] = true // ignore during walk
- }
- var pkgs []string
-
- // Commands
- cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
- filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
- if err != nil || !fi.IsDir() || path == cmd {
- return nil
- }
- name := path[len(cmd):]
- if !treeCanMatch(name) {
- return filepath.SkipDir
- }
- // Commands are all in cmd/, not in subdirectories.
- if strings.Contains(name, string(filepath.Separator)) {
- return filepath.SkipDir
- }
-
- // We use, e.g., cmd/gofmt as the pseudo import path for gofmt.
- name = "cmd/" + name
- if have[name] {
- return nil
- }
- have[name] = true
- if !match(name) {
- return nil
- }
- _, err = buildContext.ImportDir(path, 0)
- if err != nil {
- if _, noGo := err.(*build.NoGoError); !noGo {
- log.Print(err)
- }
- return nil
- }
- pkgs = append(pkgs, name)
- return nil
- })
-
- for _, src := range buildContext.SrcDirs() {
- if (pattern == "std" || pattern == "cmd") && src != gorootSrc {
- continue
- }
- src = filepath.Clean(src) + string(filepath.Separator)
- root := src
- if pattern == "cmd" {
- root += "cmd" + string(filepath.Separator)
- }
- filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
- if err != nil || !fi.IsDir() || path == src {
- return nil
- }
-
- // Avoid .foo, _foo, and testdata directory trees.
- _, elem := filepath.Split(path)
- if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
- return filepath.SkipDir
- }
-
- name := filepath.ToSlash(path[len(src):])
- if pattern == "std" && (strings.Contains(name, ".") || name == "cmd") {
- // The name "std" is only the standard library.
- // If the name is cmd, it's the root of the command tree.
- return filepath.SkipDir
- }
- if !treeCanMatch(name) {
- return filepath.SkipDir
- }
- if have[name] {
- return nil
- }
- have[name] = true
- if !match(name) {
- return nil
- }
- _, err = buildContext.ImportDir(path, 0)
- if err != nil {
- if _, noGo := err.(*build.NoGoError); noGo {
- return nil
- }
- }
- pkgs = append(pkgs, name)
- return nil
- })
- }
- return pkgs
-}
-
-// allPackagesInFS is like allPackages but is passed a pattern
-// beginning ./ or ../, meaning it should scan the tree rooted
-// at the given directory. There are ... in the pattern too.
-func allPackagesInFS(pattern string) []string {
- pkgs := matchPackagesInFS(pattern)
- if len(pkgs) == 0 {
- fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
- }
- return pkgs
-}
-
-func matchPackagesInFS(pattern string) []string {
- // Find directory to begin the scan.
- // Could be smarter but this one optimization
- // is enough for now, since ... is usually at the
- // end of a path.
- i := strings.Index(pattern, "...")
- dir, _ := path.Split(pattern[:i])
-
- // pattern begins with ./ or ../.
- // path.Clean will discard the ./ but not the ../.
- // We need to preserve the ./ for pattern matching
- // and in the returned import paths.
- prefix := ""
- if strings.HasPrefix(pattern, "./") {
- prefix = "./"
- }
- match := matchPattern(pattern)
-
- var pkgs []string
- filepath.Walk(dir, func(path string, fi os.FileInfo, err error) error {
- if err != nil || !fi.IsDir() {
- return nil
- }
- if path == dir {
- // filepath.Walk starts at dir and recurses. For the recursive case,
- // the path is the result of filepath.Join, which calls filepath.Clean.
- // The initial case is not Cleaned, though, so we do this explicitly.
- //
- // This converts a path like "./io/" to "io". Without this step, running
- // "cd $GOROOT/src/pkg; go list ./io/..." would incorrectly skip the io
- // package, because prepending the prefix "./" to the unclean path would
- // result in "././io", and match("././io") returns false.
- path = filepath.Clean(path)
- }
-
- // Avoid .foo, _foo, and testdata directory trees, but do not avoid "." or "..".
- _, elem := filepath.Split(path)
- dot := strings.HasPrefix(elem, ".") && elem != "." && elem != ".."
- if dot || strings.HasPrefix(elem, "_") || elem == "testdata" {
- return filepath.SkipDir
- }
-
- name := prefix + filepath.ToSlash(path)
- if !match(name) {
- return nil
- }
- if _, err = build.ImportDir(path, 0); err != nil {
- if _, noGo := err.(*build.NoGoError); !noGo {
- log.Print(err)
- }
- return nil
- }
- pkgs = append(pkgs, name)
- return nil
- })
- return pkgs
-}
diff --git a/vendor/golang.org/x/lint/golint/importcomment.go b/vendor/golang.org/x/lint/golint/importcomment.go
deleted file mode 100644
index d5b32f734..000000000
--- a/vendor/golang.org/x/lint/golint/importcomment.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 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 or at
-// https://developers.google.com/open-source/licenses/bsd.
-
-// +build go1.12
-
-// Require use of the correct import path only for Go 1.12+ users, so
-// any breakages coincide with people updating their CI configs or
-// whatnot.
-
-package main // import "golang.org/x/lint/golint"
diff --git a/vendor/golang.org/x/lint/lint.go b/vendor/golang.org/x/lint/lint.go
deleted file mode 100644
index 7d813e061..000000000
--- a/vendor/golang.org/x/lint/lint.go
+++ /dev/null
@@ -1,1615 +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 lint contains a linter for Go source code.
-package lint // import "golang.org/x/lint"
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "go/ast"
- "go/parser"
- "go/printer"
- "go/token"
- "go/types"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-
- "golang.org/x/tools/go/ast/astutil"
- "golang.org/x/tools/go/gcexportdata"
-)
-
-const styleGuideBase = "https://golang.org/wiki/CodeReviewComments"
-
-// A Linter lints Go source code.
-type Linter struct {
-}
-
-// Problem represents a problem in some source code.
-type Problem struct {
- Position token.Position // position in source file
- Text string // the prose that describes the problem
- Link string // (optional) the link to the style guide for the problem
- Confidence float64 // a value in (0,1] estimating the confidence in this problem's correctness
- LineText string // the source line
- Category string // a short name for the general category of the problem
-
- // If the problem has a suggested fix (the minority case),
- // ReplacementLine is a full replacement for the relevant line of the source file.
- ReplacementLine string
-}
-
-func (p *Problem) String() string {
- if p.Link != "" {
- return p.Text + "\n\n" + p.Link
- }
- return p.Text
-}
-
-type byPosition []Problem
-
-func (p byPosition) Len() int { return len(p) }
-func (p byPosition) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
-
-func (p byPosition) Less(i, j int) bool {
- pi, pj := p[i].Position, p[j].Position
-
- 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 p[i].Text < p[j].Text
-}
-
-// Lint lints src.
-func (l *Linter) Lint(filename string, src []byte) ([]Problem, error) {
- return l.LintFiles(map[string][]byte{filename: src})
-}
-
-// LintFiles lints a set of files of a single package.
-// The argument is a map of filename to source.
-func (l *Linter) LintFiles(files map[string][]byte) ([]Problem, error) {
- pkg := &pkg{
- fset: token.NewFileSet(),
- files: make(map[string]*file),
- }
- var pkgName string
- for filename, src := range files {
- if isGenerated(src) {
- continue // See issue #239
- }
- f, err := parser.ParseFile(pkg.fset, filename, src, parser.ParseComments)
- if err != nil {
- return nil, err
- }
- if pkgName == "" {
- pkgName = f.Name.Name
- } else if f.Name.Name != pkgName {
- return nil, fmt.Errorf("%s is in package %s, not %s", filename, f.Name.Name, pkgName)
- }
- pkg.files[filename] = &file{
- pkg: pkg,
- f: f,
- fset: pkg.fset,
- src: src,
- filename: filename,
- }
- }
- if len(pkg.files) == 0 {
- return nil, nil
- }
- return pkg.lint(), nil
-}
-
-var (
- genHdr = []byte("// Code generated ")
- genFtr = []byte(" DO NOT EDIT.")
-)
-
-// isGenerated reports whether the source file is generated code
-// according the rules from https://golang.org/s/generatedcode.
-func isGenerated(src []byte) bool {
- sc := bufio.NewScanner(bytes.NewReader(src))
- for sc.Scan() {
- b := sc.Bytes()
- if bytes.HasPrefix(b, genHdr) && bytes.HasSuffix(b, genFtr) && len(b) >= len(genHdr)+len(genFtr) {
- return true
- }
- }
- return false
-}
-
-// pkg represents a package being linted.
-type pkg struct {
- fset *token.FileSet
- files map[string]*file
-
- typesPkg *types.Package
- typesInfo *types.Info
-
- // sortable is the set of types in the package that implement sort.Interface.
- sortable map[string]bool
- // main is whether this is a "main" package.
- main bool
-
- problems []Problem
-}
-
-func (p *pkg) lint() []Problem {
- if err := p.typeCheck(); err != nil {
- /* TODO(dsymonds): Consider reporting these errors when golint operates on entire packages.
- if e, ok := err.(types.Error); ok {
- pos := p.fset.Position(e.Pos)
- conf := 1.0
- if strings.Contains(e.Msg, "can't find import: ") {
- // Golint is probably being run in a context that doesn't support
- // typechecking (e.g. package files aren't found), so don't warn about it.
- conf = 0
- }
- if conf > 0 {
- p.errorfAt(pos, conf, category("typechecking"), e.Msg)
- }
-
- // TODO(dsymonds): Abort if !e.Soft?
- }
- */
- }
-
- p.scanSortable()
- p.main = p.isMain()
-
- for _, f := range p.files {
- f.lint()
- }
-
- sort.Sort(byPosition(p.problems))
-
- return p.problems
-}
-
-// file represents a file being linted.
-type file struct {
- pkg *pkg
- f *ast.File
- fset *token.FileSet
- src []byte
- filename string
-}
-
-func (f *file) isTest() bool { return strings.HasSuffix(f.filename, "_test.go") }
-
-func (f *file) lint() {
- f.lintPackageComment()
- f.lintImports()
- f.lintBlankImports()
- f.lintExported()
- f.lintNames()
- f.lintElses()
- f.lintRanges()
- f.lintErrorf()
- f.lintErrors()
- f.lintErrorStrings()
- f.lintReceiverNames()
- f.lintIncDec()
- f.lintErrorReturn()
- f.lintUnexportedReturn()
- f.lintTimeNames()
- f.lintContextKeyTypes()
- f.lintContextArgs()
-}
-
-type link string
-type category string
-
-// The variadic arguments may start with link and category types,
-// and must end with a format string and any arguments.
-// It returns the new Problem.
-func (f *file) errorf(n ast.Node, confidence float64, args ...interface{}) *Problem {
- pos := f.fset.Position(n.Pos())
- if pos.Filename == "" {
- pos.Filename = f.filename
- }
- return f.pkg.errorfAt(pos, confidence, args...)
-}
-
-func (p *pkg) errorfAt(pos token.Position, confidence float64, args ...interface{}) *Problem {
- problem := Problem{
- Position: pos,
- Confidence: confidence,
- }
- if pos.Filename != "" {
- // The file might not exist in our mapping if a //line directive was encountered.
- if f, ok := p.files[pos.Filename]; ok {
- problem.LineText = srcLine(f.src, pos)
- }
- }
-
-argLoop:
- for len(args) > 1 { // always leave at least the format string in args
- switch v := args[0].(type) {
- case link:
- problem.Link = string(v)
- case category:
- problem.Category = string(v)
- default:
- break argLoop
- }
- args = args[1:]
- }
-
- problem.Text = fmt.Sprintf(args[0].(string), args[1:]...)
-
- p.problems = append(p.problems, problem)
- return &p.problems[len(p.problems)-1]
-}
-
-var newImporter = func(fset *token.FileSet) types.ImporterFrom {
- return gcexportdata.NewImporter(fset, make(map[string]*types.Package))
-}
-
-func (p *pkg) typeCheck() error {
- config := &types.Config{
- // By setting a no-op error reporter, the type checker does as much work as possible.
- Error: func(error) {},
- Importer: newImporter(p.fset),
- }
- info := &types.Info{
- Types: make(map[ast.Expr]types.TypeAndValue),
- Defs: make(map[*ast.Ident]types.Object),
- Uses: make(map[*ast.Ident]types.Object),
- Scopes: make(map[ast.Node]*types.Scope),
- }
- var anyFile *file
- var astFiles []*ast.File
- for _, f := range p.files {
- anyFile = f
- astFiles = append(astFiles, f.f)
- }
- pkg, err := config.Check(anyFile.f.Name.Name, p.fset, astFiles, info)
- // Remember the typechecking info, even if config.Check failed,
- // since we will get partial information.
- p.typesPkg = pkg
- p.typesInfo = info
- return err
-}
-
-func (p *pkg) typeOf(expr ast.Expr) types.Type {
- if p.typesInfo == nil {
- return nil
- }
- return p.typesInfo.TypeOf(expr)
-}
-
-func (p *pkg) isNamedType(typ types.Type, importPath, name string) bool {
- n, ok := typ.(*types.Named)
- if !ok {
- return false
- }
- tn := n.Obj()
- return tn != nil && tn.Pkg() != nil && tn.Pkg().Path() == importPath && tn.Name() == name
-}
-
-// scopeOf returns the tightest scope encompassing id.
-func (p *pkg) scopeOf(id *ast.Ident) *types.Scope {
- var scope *types.Scope
- if obj := p.typesInfo.ObjectOf(id); obj != nil {
- scope = obj.Parent()
- }
- if scope == p.typesPkg.Scope() {
- // We were given a top-level identifier.
- // Use the file-level scope instead of the package-level scope.
- pos := id.Pos()
- for _, f := range p.files {
- if f.f.Pos() <= pos && pos < f.f.End() {
- scope = p.typesInfo.Scopes[f.f]
- break
- }
- }
- }
- return scope
-}
-
-func (p *pkg) scanSortable() {
- p.sortable = make(map[string]bool)
-
- // bitfield for which methods exist on each type.
- const (
- Len = 1 << iota
- Less
- Swap
- )
- nmap := map[string]int{"Len": Len, "Less": Less, "Swap": Swap}
- has := make(map[string]int)
- for _, f := range p.files {
- f.walk(func(n ast.Node) bool {
- fn, ok := n.(*ast.FuncDecl)
- if !ok || fn.Recv == nil || len(fn.Recv.List) == 0 {
- return true
- }
- // TODO(dsymonds): We could check the signature to be more precise.
- recv := receiverType(fn)
- if i, ok := nmap[fn.Name.Name]; ok {
- has[recv] |= i
- }
- return false
- })
- }
- for typ, ms := range has {
- if ms == Len|Less|Swap {
- p.sortable[typ] = true
- }
- }
-}
-
-func (p *pkg) isMain() bool {
- for _, f := range p.files {
- if f.isMain() {
- return true
- }
- }
- return false
-}
-
-func (f *file) isMain() bool {
- if f.f.Name.Name == "main" {
- return true
- }
- return false
-}
-
-// lintPackageComment checks package comments. It complains if
-// there is no package comment, or if it is not of the right form.
-// This has a notable false positive in that a package comment
-// could rightfully appear in a different file of the same package,
-// but that's not easy to fix since this linter is file-oriented.
-func (f *file) lintPackageComment() {
- if f.isTest() {
- return
- }
-
- const ref = styleGuideBase + "#package-comments"
- prefix := "Package " + f.f.Name.Name + " "
-
- // Look for a detached package comment.
- // First, scan for the last comment that occurs before the "package" keyword.
- var lastCG *ast.CommentGroup
- for _, cg := range f.f.Comments {
- if cg.Pos() > f.f.Package {
- // Gone past "package" keyword.
- break
- }
- lastCG = cg
- }
- if lastCG != nil && strings.HasPrefix(lastCG.Text(), prefix) {
- endPos := f.fset.Position(lastCG.End())
- pkgPos := f.fset.Position(f.f.Package)
- if endPos.Line+1 < pkgPos.Line {
- // There isn't a great place to anchor this error;
- // the start of the blank lines between the doc and the package statement
- // is at least pointing at the location of the problem.
- pos := token.Position{
- Filename: endPos.Filename,
- // Offset not set; it is non-trivial, and doesn't appear to be needed.
- Line: endPos.Line + 1,
- Column: 1,
- }
- f.pkg.errorfAt(pos, 0.9, link(ref), category("comments"), "package comment is detached; there should be no blank lines between it and the package statement")
- return
- }
- }
-
- if f.f.Doc == nil {
- f.errorf(f.f, 0.2, link(ref), category("comments"), "should have a package comment, unless it's in another file for this package")
- return
- }
- s := f.f.Doc.Text()
- if ts := strings.TrimLeft(s, " \t"); ts != s {
- f.errorf(f.f.Doc, 1, link(ref), category("comments"), "package comment should not have leading space")
- s = ts
- }
- // Only non-main packages need to keep to this form.
- if !f.pkg.main && !strings.HasPrefix(s, prefix) {
- f.errorf(f.f.Doc, 1, link(ref), category("comments"), `package comment should be of the form "%s..."`, prefix)
- }
-}
-
-// lintBlankImports complains if a non-main package has blank imports that are
-// not documented.
-func (f *file) lintBlankImports() {
- // In package main and in tests, we don't complain about blank imports.
- if f.pkg.main || f.isTest() {
- return
- }
-
- // The first element of each contiguous group of blank imports should have
- // an explanatory comment of some kind.
- for i, imp := range f.f.Imports {
- pos := f.fset.Position(imp.Pos())
-
- if !isBlank(imp.Name) {
- continue // Ignore non-blank imports.
- }
- if i > 0 {
- prev := f.f.Imports[i-1]
- prevPos := f.fset.Position(prev.Pos())
- if isBlank(prev.Name) && prevPos.Line+1 == pos.Line {
- continue // A subsequent blank in a group.
- }
- }
-
- // This is the first blank import of a group.
- if imp.Doc == nil && imp.Comment == nil {
- ref := ""
- f.errorf(imp, 1, link(ref), category("imports"), "a blank import should be only in a main or test package, or have a comment justifying it")
- }
- }
-}
-
-// lintImports examines import blocks.
-func (f *file) lintImports() {
- for i, is := range f.f.Imports {
- _ = i
- if is.Name != nil && is.Name.Name == "." && !f.isTest() {
- f.errorf(is, 1, link(styleGuideBase+"#import-dot"), category("imports"), "should not use dot imports")
- }
-
- }
-}
-
-const docCommentsLink = styleGuideBase + "#doc-comments"
-
-// lintExported examines the exported names.
-// It complains if any required doc comments are missing,
-// or if they are not of the right form. The exact rules are in
-// lintFuncDoc, lintTypeDoc and lintValueSpecDoc; this function
-// also tracks the GenDecl structure being traversed to permit
-// doc comments for constants to be on top of the const block.
-// It also complains if the names stutter when combined with
-// the package name.
-func (f *file) lintExported() {
- if f.isTest() {
- return
- }
-
- var lastGen *ast.GenDecl // last GenDecl entered.
-
- // Set of GenDecls that have already had missing comments flagged.
- genDeclMissingComments := make(map[*ast.GenDecl]bool)
-
- f.walk(func(node ast.Node) bool {
- switch v := node.(type) {
- case *ast.GenDecl:
- if v.Tok == token.IMPORT {
- return false
- }
- // token.CONST, token.TYPE or token.VAR
- lastGen = v
- return true
- case *ast.FuncDecl:
- f.lintFuncDoc(v)
- if v.Recv == nil {
- // Only check for stutter on functions, not methods.
- // Method names are not used package-qualified.
- f.checkStutter(v.Name, "func")
- }
- // Don't proceed inside funcs.
- return false
- case *ast.TypeSpec:
- // inside a GenDecl, which usually has the doc
- doc := v.Doc
- if doc == nil {
- doc = lastGen.Doc
- }
- f.lintTypeDoc(v, doc)
- f.checkStutter(v.Name, "type")
- // Don't proceed inside types.
- return false
- case *ast.ValueSpec:
- f.lintValueSpecDoc(v, lastGen, genDeclMissingComments)
- return false
- }
- return true
- })
-}
-
-var (
- allCapsRE = regexp.MustCompile(`^[A-Z0-9_]+$`)
- anyCapsRE = regexp.MustCompile(`[A-Z]`)
-)
-
-// knownNameExceptions is a set of names that are known to be exempt from naming checks.
-// This is usually because they are constrained by having to match names in the
-// standard library.
-var knownNameExceptions = map[string]bool{
- "LastInsertId": true, // must match database/sql
- "kWh": true,
-}
-
-func isInTopLevel(f *ast.File, ident *ast.Ident) bool {
- path, _ := astutil.PathEnclosingInterval(f, ident.Pos(), ident.End())
- for _, f := range path {
- switch f.(type) {
- case *ast.File, *ast.GenDecl, *ast.ValueSpec, *ast.Ident:
- continue
- }
- return false
- }
- return true
-}
-
-// lintNames examines all names in the file.
-// It complains if any use underscores or incorrect known initialisms.
-func (f *file) lintNames() {
- // Package names need slightly different handling than other names.
- if strings.Contains(f.f.Name.Name, "_") && !strings.HasSuffix(f.f.Name.Name, "_test") {
- f.errorf(f.f, 1, link("http://golang.org/doc/effective_go.html#package-names"), category("naming"), "don't use an underscore in package name")
- }
- if anyCapsRE.MatchString(f.f.Name.Name) {
- f.errorf(f.f, 1, link("http://golang.org/doc/effective_go.html#package-names"), category("mixed-caps"), "don't use MixedCaps in package name; %s should be %s", f.f.Name.Name, strings.ToLower(f.f.Name.Name))
- }
-
- check := func(id *ast.Ident, thing string) {
- if id.Name == "_" {
- return
- }
- if knownNameExceptions[id.Name] {
- return
- }
-
- // Handle two common styles from other languages that don't belong in Go.
- if len(id.Name) >= 5 && allCapsRE.MatchString(id.Name) && strings.Contains(id.Name, "_") {
- capCount := 0
- for _, c := range id.Name {
- if 'A' <= c && c <= 'Z' {
- capCount++
- }
- }
- if capCount >= 2 {
- f.errorf(id, 0.8, link(styleGuideBase+"#mixed-caps"), category("naming"), "don't use ALL_CAPS in Go names; use CamelCase")
- return
- }
- }
- if thing == "const" || (thing == "var" && isInTopLevel(f.f, id)) {
- if len(id.Name) > 2 && id.Name[0] == 'k' && id.Name[1] >= 'A' && id.Name[1] <= 'Z' {
- should := string(id.Name[1]+'a'-'A') + id.Name[2:]
- f.errorf(id, 0.8, link(styleGuideBase+"#mixed-caps"), category("naming"), "don't use leading k in Go names; %s %s should be %s", thing, id.Name, should)
- }
- }
-
- should := lintName(id.Name)
- if id.Name == should {
- return
- }
-
- if len(id.Name) > 2 && strings.Contains(id.Name[1:], "_") {
- f.errorf(id, 0.9, link("http://golang.org/doc/effective_go.html#mixed-caps"), category("naming"), "don't use underscores in Go names; %s %s should be %s", thing, id.Name, should)
- return
- }
- f.errorf(id, 0.8, link(styleGuideBase+"#initialisms"), category("naming"), "%s %s should be %s", thing, id.Name, should)
- }
- checkList := func(fl *ast.FieldList, thing string) {
- if fl == nil {
- return
- }
- for _, f := range fl.List {
- for _, id := range f.Names {
- check(id, thing)
- }
- }
- }
- f.walk(func(node ast.Node) bool {
- switch v := node.(type) {
- case *ast.AssignStmt:
- if v.Tok == token.ASSIGN {
- return true
- }
- for _, exp := range v.Lhs {
- if id, ok := exp.(*ast.Ident); ok {
- check(id, "var")
- }
- }
- case *ast.FuncDecl:
- if f.isTest() && (strings.HasPrefix(v.Name.Name, "Example") || strings.HasPrefix(v.Name.Name, "Test") || strings.HasPrefix(v.Name.Name, "Benchmark")) {
- return true
- }
-
- thing := "func"
- if v.Recv != nil {
- thing = "method"
- }
-
- // Exclude naming warnings for functions that are exported to C but
- // not exported in the Go API.
- // See https://github.com/golang/lint/issues/144.
- if ast.IsExported(v.Name.Name) || !isCgoExported(v) {
- check(v.Name, thing)
- }
-
- checkList(v.Type.Params, thing+" parameter")
- checkList(v.Type.Results, thing+" result")
- case *ast.GenDecl:
- if v.Tok == token.IMPORT {
- return true
- }
- var thing string
- switch v.Tok {
- case token.CONST:
- thing = "const"
- case token.TYPE:
- thing = "type"
- case token.VAR:
- thing = "var"
- }
- for _, spec := range v.Specs {
- switch s := spec.(type) {
- case *ast.TypeSpec:
- check(s.Name, thing)
- case *ast.ValueSpec:
- for _, id := range s.Names {
- check(id, thing)
- }
- }
- }
- case *ast.InterfaceType:
- // Do not check interface method names.
- // They are often constrainted by the method names of concrete types.
- for _, x := range v.Methods.List {
- ft, ok := x.Type.(*ast.FuncType)
- if !ok { // might be an embedded interface name
- continue
- }
- checkList(ft.Params, "interface method parameter")
- checkList(ft.Results, "interface method result")
- }
- case *ast.RangeStmt:
- if v.Tok == token.ASSIGN {
- return true
- }
- if id, ok := v.Key.(*ast.Ident); ok {
- check(id, "range var")
- }
- if id, ok := v.Value.(*ast.Ident); ok {
- check(id, "range var")
- }
- case *ast.StructType:
- for _, f := range v.Fields.List {
- for _, id := range f.Names {
- check(id, "struct field")
- }
- }
- }
- return true
- })
-}
-
-// lintName returns a different name if it should be different.
-func lintName(name string) (should string) {
- // Fast path for simple cases: "_" and all lowercase.
- if name == "_" {
- return name
- }
- allLower := true
- for _, r := range name {
- if !unicode.IsLower(r) {
- allLower = false
- break
- }
- }
- if allLower {
- return name
- }
-
- // Split camelCase at any lower->upper transition, and split on underscores.
- // Check each word for common initialisms.
- runes := []rune(name)
- w, i := 0, 0 // index of start of word, scan
- for i+1 <= len(runes) {
- eow := false // whether we hit the end of a word
- if i+1 == len(runes) {
- eow = true
- } else if runes[i+1] == '_' {
- // underscore; shift the remainder forward over any run of underscores
- eow = true
- n := 1
- for i+n+1 < len(runes) && runes[i+n+1] == '_' {
- n++
- }
-
- // Leave at most one underscore if the underscore is between two digits
- if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
- n--
- }
-
- copy(runes[i+1:], runes[i+n+1:])
- runes = runes[:len(runes)-n]
- } else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
- // lower->non-lower
- eow = true
- }
- i++
- if !eow {
- continue
- }
-
- // [w,i) is a word.
- word := string(runes[w:i])
- if u := strings.ToUpper(word); commonInitialisms[u] {
- // Keep consistent case, which is lowercase only at the start.
- if w == 0 && unicode.IsLower(runes[w]) {
- u = strings.ToLower(u)
- }
- // All the common initialisms are ASCII,
- // so we can replace the bytes exactly.
- copy(runes[w:], []rune(u))
- } else if w > 0 && strings.ToLower(word) == word {
- // already all lowercase, and not the first word, so uppercase the first character.
- runes[w] = unicode.ToUpper(runes[w])
- }
- w = i
- }
- return string(runes)
-}
-
-// commonInitialisms is a set of common initialisms.
-// Only add entries that are highly unlikely to be non-initialisms.
-// For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
-var commonInitialisms = map[string]bool{
- "ACL": true,
- "API": true,
- "ASCII": true,
- "CPU": true,
- "CSS": true,
- "DNS": true,
- "EOF": true,
- "GUID": true,
- "HTML": true,
- "HTTP": true,
- "HTTPS": true,
- "ID": true,
- "IP": true,
- "JSON": true,
- "LHS": true,
- "QPS": true,
- "RAM": true,
- "RHS": true,
- "RPC": true,
- "SLA": true,
- "SMTP": true,
- "SQL": true,
- "SSH": true,
- "TCP": true,
- "TLS": true,
- "TTL": true,
- "UDP": true,
- "UI": true,
- "UID": true,
- "UUID": true,
- "URI": true,
- "URL": true,
- "UTF8": true,
- "VM": true,
- "XML": true,
- "XMPP": true,
- "XSRF": true,
- "XSS": true,
-}
-
-// lintTypeDoc examines the doc comment on a type.
-// It complains if they are missing from an exported type,
-// or if they are not of the standard form.
-func (f *file) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) {
- if !ast.IsExported(t.Name.Name) {
- return
- }
- if doc == nil {
- f.errorf(t, 1, link(docCommentsLink), category("comments"), "exported type %v should have comment or be unexported", t.Name)
- return
- }
-
- s := doc.Text()
- articles := [...]string{"A", "An", "The"}
- for _, a := range articles {
- if strings.HasPrefix(s, a+" ") {
- s = s[len(a)+1:]
- break
- }
- }
- if !strings.HasPrefix(s, t.Name.Name+" ") {
- f.errorf(doc, 1, link(docCommentsLink), category("comments"), `comment on exported type %v should be of the form "%v ..." (with optional leading article)`, t.Name, t.Name)
- }
-}
-
-var commonMethods = map[string]bool{
- "Error": true,
- "Read": true,
- "ServeHTTP": true,
- "String": true,
- "Write": true,
- "Unwrap": true,
-}
-
-// lintFuncDoc examines doc comments on functions and methods.
-// It complains if they are missing, or not of the right form.
-// It has specific exclusions for well-known methods (see commonMethods above).
-func (f *file) lintFuncDoc(fn *ast.FuncDecl) {
- if !ast.IsExported(fn.Name.Name) {
- // func is unexported
- return
- }
- kind := "function"
- name := fn.Name.Name
- if fn.Recv != nil && len(fn.Recv.List) > 0 {
- // method
- kind = "method"
- recv := receiverType(fn)
- if !ast.IsExported(recv) {
- // receiver is unexported
- return
- }
- if commonMethods[name] {
- return
- }
- switch name {
- case "Len", "Less", "Swap":
- if f.pkg.sortable[recv] {
- return
- }
- }
- name = recv + "." + name
- }
- if fn.Doc == nil {
- f.errorf(fn, 1, link(docCommentsLink), category("comments"), "exported %s %s should have comment or be unexported", kind, name)
- return
- }
- s := fn.Doc.Text()
- prefix := fn.Name.Name + " "
- if !strings.HasPrefix(s, prefix) {
- f.errorf(fn.Doc, 1, link(docCommentsLink), category("comments"), `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
- }
-}
-
-// lintValueSpecDoc examines package-global variables and constants.
-// It complains if they are not individually declared,
-// or if they are not suitably documented in the right form (unless they are in a block that is commented).
-func (f *file) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) {
- kind := "var"
- if gd.Tok == token.CONST {
- kind = "const"
- }
-
- if len(vs.Names) > 1 {
- // Check that none are exported except for the first.
- for _, n := range vs.Names[1:] {
- if ast.IsExported(n.Name) {
- f.errorf(vs, 1, category("comments"), "exported %s %s should have its own declaration", kind, n.Name)
- return
- }
- }
- }
-
- // Only one name.
- name := vs.Names[0].Name
- if !ast.IsExported(name) {
- return
- }
-
- if vs.Doc == nil && gd.Doc == nil {
- if genDeclMissingComments[gd] {
- return
- }
- block := ""
- if kind == "const" && gd.Lparen.IsValid() {
- block = " (or a comment on this block)"
- }
- f.errorf(vs, 1, link(docCommentsLink), category("comments"), "exported %s %s should have comment%s or be unexported", kind, name, block)
- genDeclMissingComments[gd] = true
- return
- }
- // If this GenDecl has parens and a comment, we don't check its comment form.
- if gd.Lparen.IsValid() && gd.Doc != nil {
- return
- }
- // The relevant text to check will be on either vs.Doc or gd.Doc.
- // Use vs.Doc preferentially.
- doc := vs.Doc
- if doc == nil {
- doc = gd.Doc
- }
- prefix := name + " "
- if !strings.HasPrefix(doc.Text(), prefix) {
- f.errorf(doc, 1, link(docCommentsLink), category("comments"), `comment on exported %s %s should be of the form "%s..."`, kind, name, prefix)
- }
-}
-
-func (f *file) checkStutter(id *ast.Ident, thing string) {
- pkg, name := f.f.Name.Name, id.Name
- if !ast.IsExported(name) {
- // unexported name
- return
- }
- // A name stutters if the package name is a strict prefix
- // and the next character of the name starts a new word.
- if len(name) <= len(pkg) {
- // name is too short to stutter.
- // This permits the name to be the same as the package name.
- return
- }
- if !strings.EqualFold(pkg, name[:len(pkg)]) {
- return
- }
- // We can assume the name is well-formed UTF-8.
- // If the next rune after the package name is uppercase or an underscore
- // the it's starting a new word and thus this name stutters.
- rem := name[len(pkg):]
- if next, _ := utf8.DecodeRuneInString(rem); next == '_' || unicode.IsUpper(next) {
- f.errorf(id, 0.8, link(styleGuideBase+"#package-names"), category("naming"), "%s name will be used as %s.%s by other packages, and that stutters; consider calling this %s", thing, pkg, name, rem)
- }
-}
-
-// zeroLiteral is a set of ast.BasicLit values that are zero values.
-// It is not exhaustive.
-var zeroLiteral = map[string]bool{
- "false": true, // bool
- // runes
- `'\x00'`: true,
- `'\000'`: true,
- // strings
- `""`: true,
- "``": true,
- // numerics
- "0": true,
- "0.": true,
- "0.0": true,
- "0i": true,
-}
-
-// lintElses examines else blocks. It complains about any else block whose if block ends in a return.
-func (f *file) lintElses() {
- // We don't want to flag if { } else if { } else { } constructions.
- // They will appear as an IfStmt whose Else field is also an IfStmt.
- // Record such a node so we ignore it when we visit it.
- ignore := make(map[*ast.IfStmt]bool)
-
- f.walk(func(node ast.Node) bool {
- ifStmt, ok := node.(*ast.IfStmt)
- if !ok || ifStmt.Else == nil {
- return true
- }
- if elseif, ok := ifStmt.Else.(*ast.IfStmt); ok {
- ignore[elseif] = true
- return true
- }
- if ignore[ifStmt] {
- return true
- }
- if _, ok := ifStmt.Else.(*ast.BlockStmt); !ok {
- // only care about elses without conditions
- return true
- }
- if len(ifStmt.Body.List) == 0 {
- return true
- }
- shortDecl := false // does the if statement have a ":=" initialization statement?
- if ifStmt.Init != nil {
- if as, ok := ifStmt.Init.(*ast.AssignStmt); ok && as.Tok == token.DEFINE {
- shortDecl = true
- }
- }
- lastStmt := ifStmt.Body.List[len(ifStmt.Body.List)-1]
- if _, ok := lastStmt.(*ast.ReturnStmt); ok {
- extra := ""
- if shortDecl {
- extra = " (move short variable declaration to its own line if necessary)"
- }
- f.errorf(ifStmt.Else, 1, link(styleGuideBase+"#indent-error-flow"), category("indent"), "if block ends with a return statement, so drop this else and outdent its block"+extra)
- }
- return true
- })
-}
-
-// lintRanges examines range clauses. It complains about redundant constructions.
-func (f *file) lintRanges() {
- f.walk(func(node ast.Node) bool {
- rs, ok := node.(*ast.RangeStmt)
- if !ok {
- return true
- }
-
- if isIdent(rs.Key, "_") && (rs.Value == nil || isIdent(rs.Value, "_")) {
- p := f.errorf(rs.Key, 1, category("range-loop"), "should omit values from range; this loop is equivalent to `for range ...`")
-
- newRS := *rs // shallow copy
- newRS.Value = nil
- newRS.Key = nil
- p.ReplacementLine = f.firstLineOf(&newRS, rs)
-
- return true
- }
-
- if isIdent(rs.Value, "_") {
- p := f.errorf(rs.Value, 1, category("range-loop"), "should omit 2nd value from range; this loop is equivalent to `for %s %s range ...`", f.render(rs.Key), rs.Tok)
-
- newRS := *rs // shallow copy
- newRS.Value = nil
- p.ReplacementLine = f.firstLineOf(&newRS, rs)
- }
-
- return true
- })
-}
-
-// lintErrorf examines errors.New and testing.Error calls. It complains if its only argument is an fmt.Sprintf invocation.
-func (f *file) lintErrorf() {
- f.walk(func(node ast.Node) bool {
- ce, ok := node.(*ast.CallExpr)
- if !ok || len(ce.Args) != 1 {
- return true
- }
- isErrorsNew := isPkgDot(ce.Fun, "errors", "New")
- var isTestingError bool
- se, ok := ce.Fun.(*ast.SelectorExpr)
- if ok && se.Sel.Name == "Error" {
- if typ := f.pkg.typeOf(se.X); typ != nil {
- isTestingError = typ.String() == "*testing.T"
- }
- }
- if !isErrorsNew && !isTestingError {
- return true
- }
- if !f.imports("errors") {
- return true
- }
- arg := ce.Args[0]
- ce, ok = arg.(*ast.CallExpr)
- if !ok || !isPkgDot(ce.Fun, "fmt", "Sprintf") {
- return true
- }
- errorfPrefix := "fmt"
- if isTestingError {
- errorfPrefix = f.render(se.X)
- }
- p := f.errorf(node, 1, category("errors"), "should replace %s(fmt.Sprintf(...)) with %s.Errorf(...)", f.render(se), errorfPrefix)
-
- m := f.srcLineWithMatch(ce, `^(.*)`+f.render(se)+`\(fmt\.Sprintf\((.*)\)\)(.*)$`)
- if m != nil {
- p.ReplacementLine = m[1] + errorfPrefix + ".Errorf(" + m[2] + ")" + m[3]
- }
-
- return true
- })
-}
-
-// lintErrors examines global error vars. It complains if they aren't named in the standard way.
-func (f *file) lintErrors() {
- for _, decl := range f.f.Decls {
- gd, ok := decl.(*ast.GenDecl)
- if !ok || gd.Tok != token.VAR {
- continue
- }
- for _, spec := range gd.Specs {
- spec := spec.(*ast.ValueSpec)
- if len(spec.Names) != 1 || len(spec.Values) != 1 {
- continue
- }
- ce, ok := spec.Values[0].(*ast.CallExpr)
- if !ok {
- continue
- }
- if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") {
- continue
- }
-
- id := spec.Names[0]
- prefix := "err"
- if id.IsExported() {
- prefix = "Err"
- }
- if !strings.HasPrefix(id.Name, prefix) {
- f.errorf(id, 0.9, category("naming"), "error var %s should have name of the form %sFoo", id.Name, prefix)
- }
- }
- }
-}
-
-func lintErrorString(s string) (isClean bool, conf float64) {
- const basicConfidence = 0.8
- const capConfidence = basicConfidence - 0.2
- first, firstN := utf8.DecodeRuneInString(s)
- last, _ := utf8.DecodeLastRuneInString(s)
- if last == '.' || last == ':' || last == '!' || last == '\n' {
- return false, basicConfidence
- }
- if unicode.IsUpper(first) {
- // People use proper nouns and exported Go identifiers in error strings,
- // so decrease the confidence of warnings for capitalization.
- if len(s) <= firstN {
- return false, capConfidence
- }
- // Flag strings starting with something that doesn't look like an initialism.
- if second, _ := utf8.DecodeRuneInString(s[firstN:]); !unicode.IsUpper(second) {
- return false, capConfidence
- }
- }
- return true, 0
-}
-
-// lintErrorStrings examines error strings.
-// It complains if they are capitalized or end in punctuation or a newline.
-func (f *file) lintErrorStrings() {
- f.walk(func(node ast.Node) bool {
- ce, ok := node.(*ast.CallExpr)
- if !ok {
- return true
- }
- if !isPkgDot(ce.Fun, "errors", "New") && !isPkgDot(ce.Fun, "fmt", "Errorf") {
- return true
- }
- if len(ce.Args) < 1 {
- return true
- }
- str, ok := ce.Args[0].(*ast.BasicLit)
- if !ok || str.Kind != token.STRING {
- return true
- }
- s, _ := strconv.Unquote(str.Value) // can assume well-formed Go
- if s == "" {
- return true
- }
- clean, conf := lintErrorString(s)
- if clean {
- return true
- }
-
- f.errorf(str, conf, link(styleGuideBase+"#error-strings"), category("errors"),
- "error strings should not be capitalized or end with punctuation or a newline")
- return true
- })
-}
-
-// lintReceiverNames examines receiver names. It complains about inconsistent
-// names used for the same type and names such as "this".
-func (f *file) lintReceiverNames() {
- typeReceiver := map[string]string{}
- f.walk(func(n ast.Node) bool {
- fn, ok := n.(*ast.FuncDecl)
- if !ok || fn.Recv == nil || len(fn.Recv.List) == 0 {
- return true
- }
- names := fn.Recv.List[0].Names
- if len(names) < 1 {
- return true
- }
- name := names[0].Name
- const ref = styleGuideBase + "#receiver-names"
- if name == "_" {
- f.errorf(n, 1, link(ref), category("naming"), `receiver name should not be an underscore, omit the name if it is unused`)
- return true
- }
- if name == "this" || name == "self" {
- f.errorf(n, 1, link(ref), category("naming"), `receiver name should be a reflection of its identity; don't use generic names such as "this" or "self"`)
- return true
- }
- recv := receiverType(fn)
- if prev, ok := typeReceiver[recv]; ok && prev != name {
- f.errorf(n, 1, link(ref), category("naming"), "receiver name %s should be consistent with previous receiver name %s for %s", name, prev, recv)
- return true
- }
- typeReceiver[recv] = name
- return true
- })
-}
-
-// lintIncDec examines statements that increment or decrement a variable.
-// It complains if they don't use x++ or x--.
-func (f *file) lintIncDec() {
- f.walk(func(n ast.Node) bool {
- as, ok := n.(*ast.AssignStmt)
- if !ok {
- return true
- }
- if len(as.Lhs) != 1 {
- return true
- }
- if !isOne(as.Rhs[0]) {
- return true
- }
- var suffix string
- switch as.Tok {
- case token.ADD_ASSIGN:
- suffix = "++"
- case token.SUB_ASSIGN:
- suffix = "--"
- default:
- return true
- }
- f.errorf(as, 0.8, category("unary-op"), "should replace %s with %s%s", f.render(as), f.render(as.Lhs[0]), suffix)
- return true
- })
-}
-
-// lintErrorReturn examines function declarations that return an error.
-// It complains if the error isn't the last parameter.
-func (f *file) lintErrorReturn() {
- f.walk(func(n ast.Node) bool {
- fn, ok := n.(*ast.FuncDecl)
- if !ok || fn.Type.Results == nil {
- return true
- }
- ret := fn.Type.Results.List
- if len(ret) <= 1 {
- return true
- }
- if isIdent(ret[len(ret)-1].Type, "error") {
- return true
- }
- // An error return parameter should be the last parameter.
- // Flag any error parameters found before the last.
- for _, r := range ret[:len(ret)-1] {
- if isIdent(r.Type, "error") {
- f.errorf(fn, 0.9, category("arg-order"), "error should be the last type when returning multiple items")
- break // only flag one
- }
- }
- return true
- })
-}
-
-// lintUnexportedReturn examines exported function declarations.
-// It complains if any return an unexported type.
-func (f *file) lintUnexportedReturn() {
- f.walk(func(n ast.Node) bool {
- fn, ok := n.(*ast.FuncDecl)
- if !ok {
- return true
- }
- if fn.Type.Results == nil {
- return false
- }
- if !fn.Name.IsExported() {
- return false
- }
- thing := "func"
- if fn.Recv != nil && len(fn.Recv.List) > 0 {
- thing = "method"
- if !ast.IsExported(receiverType(fn)) {
- // Don't report exported methods of unexported types,
- // such as private implementations of sort.Interface.
- return false
- }
- }
- for _, ret := range fn.Type.Results.List {
- typ := f.pkg.typeOf(ret.Type)
- if exportedType(typ) {
- continue
- }
- f.errorf(ret.Type, 0.8, category("unexported-type-in-api"),
- "exported %s %s returns unexported type %s, which can be annoying to use",
- thing, fn.Name.Name, typ)
- break // only flag one
- }
- return false
- })
-}
-
-// exportedType reports whether typ is an exported type.
-// It is imprecise, and will err on the side of returning true,
-// such as for composite types.
-func exportedType(typ types.Type) bool {
- switch T := typ.(type) {
- case *types.Named:
- // Builtin types have no package.
- return T.Obj().Pkg() == nil || T.Obj().Exported()
- case *types.Map:
- return exportedType(T.Key()) && exportedType(T.Elem())
- case interface {
- Elem() types.Type
- }: // array, slice, pointer, chan
- return exportedType(T.Elem())
- }
- // Be conservative about other types, such as struct, interface, etc.
- return true
-}
-
-// timeSuffixes is a list of name suffixes that imply a time unit.
-// This is not an exhaustive list.
-var timeSuffixes = []string{
- "Sec", "Secs", "Seconds",
- "Msec", "Msecs",
- "Milli", "Millis", "Milliseconds",
- "Usec", "Usecs", "Microseconds",
- "MS", "Ms",
-}
-
-func (f *file) lintTimeNames() {
- f.walk(func(node ast.Node) bool {
- v, ok := node.(*ast.ValueSpec)
- if !ok {
- return true
- }
- for _, name := range v.Names {
- origTyp := f.pkg.typeOf(name)
- // Look for time.Duration or *time.Duration;
- // the latter is common when using flag.Duration.
- typ := origTyp
- if pt, ok := typ.(*types.Pointer); ok {
- typ = pt.Elem()
- }
- if !f.pkg.isNamedType(typ, "time", "Duration") {
- continue
- }
- suffix := ""
- for _, suf := range timeSuffixes {
- if strings.HasSuffix(name.Name, suf) {
- suffix = suf
- break
- }
- }
- if suffix == "" {
- continue
- }
- f.errorf(v, 0.9, category("time"), "var %s is of type %v; don't use unit-specific suffix %q", name.Name, origTyp, suffix)
- }
- return true
- })
-}
-
-// lintContextKeyTypes checks for call expressions to context.WithValue with
-// basic types used for the key argument.
-// See: https://golang.org/issue/17293
-func (f *file) lintContextKeyTypes() {
- f.walk(func(node ast.Node) bool {
- switch node := node.(type) {
- case *ast.CallExpr:
- f.checkContextKeyType(node)
- }
-
- return true
- })
-}
-
-// checkContextKeyType reports an error if the call expression calls
-// context.WithValue with a key argument of basic type.
-func (f *file) checkContextKeyType(x *ast.CallExpr) {
- sel, ok := x.Fun.(*ast.SelectorExpr)
- if !ok {
- return
- }
- pkg, ok := sel.X.(*ast.Ident)
- if !ok || pkg.Name != "context" {
- return
- }
- if sel.Sel.Name != "WithValue" {
- return
- }
-
- // key is second argument to context.WithValue
- if len(x.Args) != 3 {
- return
- }
- key := f.pkg.typesInfo.Types[x.Args[1]]
-
- if ktyp, ok := key.Type.(*types.Basic); ok && ktyp.Kind() != types.Invalid {
- f.errorf(x, 1.0, category("context"), fmt.Sprintf("should not use basic type %s as key in context.WithValue", key.Type))
- }
-}
-
-// lintContextArgs examines function declarations that contain an
-// argument with a type of context.Context
-// It complains if that argument isn't the first parameter.
-func (f *file) lintContextArgs() {
- f.walk(func(n ast.Node) bool {
- fn, ok := n.(*ast.FuncDecl)
- if !ok || len(fn.Type.Params.List) <= 1 {
- return true
- }
- // A context.Context should be the first parameter of a function.
- // Flag any that show up after the first.
- for _, arg := range fn.Type.Params.List[1:] {
- if isPkgDot(arg.Type, "context", "Context") {
- f.errorf(fn, 0.9, link("https://golang.org/pkg/context/"), category("arg-order"), "context.Context should be the first parameter of a function")
- break // only flag one
- }
- }
- return true
- })
-}
-
-// containsComments returns whether the interval [start, end) contains any
-// comments without "// MATCH " prefix.
-func (f *file) containsComments(start, end token.Pos) bool {
- for _, cgroup := range f.f.Comments {
- comments := cgroup.List
- if comments[0].Slash >= end {
- // All comments starting with this group are after end pos.
- return false
- }
- if comments[len(comments)-1].Slash < start {
- // Comments group ends before start pos.
- continue
- }
- for _, c := range comments {
- if start <= c.Slash && c.Slash < end && !strings.HasPrefix(c.Text, "// MATCH ") {
- return true
- }
- }
- }
- return false
-}
-
-// receiverType returns the named type of the method receiver, sans "*",
-// or "invalid-type" if fn.Recv is ill formed.
-func receiverType(fn *ast.FuncDecl) string {
- switch e := fn.Recv.List[0].Type.(type) {
- case *ast.Ident:
- return e.Name
- case *ast.StarExpr:
- if id, ok := e.X.(*ast.Ident); ok {
- return id.Name
- }
- }
- // The parser accepts much more than just the legal forms.
- return "invalid-type"
-}
-
-func (f *file) walk(fn func(ast.Node) bool) {
- ast.Walk(walker(fn), f.f)
-}
-
-func (f *file) render(x interface{}) string {
- var buf bytes.Buffer
- if err := printer.Fprint(&buf, f.fset, x); err != nil {
- panic(err)
- }
- return buf.String()
-}
-
-func (f *file) debugRender(x interface{}) string {
- var buf bytes.Buffer
- if err := ast.Fprint(&buf, f.fset, x, nil); err != nil {
- panic(err)
- }
- return buf.String()
-}
-
-// walker adapts a function to satisfy the ast.Visitor interface.
-// The function return whether the walk should proceed into the node's children.
-type walker func(ast.Node) bool
-
-func (w walker) Visit(node ast.Node) ast.Visitor {
- if w(node) {
- return w
- }
- return nil
-}
-
-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.Ident) bool { return id != nil && id.Name == "_" }
-
-func isPkgDot(expr ast.Expr, pkg, name string) bool {
- sel, ok := expr.(*ast.SelectorExpr)
- return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
-}
-
-func isOne(expr ast.Expr) bool {
- lit, ok := expr.(*ast.BasicLit)
- return ok && lit.Kind == token.INT && lit.Value == "1"
-}
-
-func isCgoExported(f *ast.FuncDecl) bool {
- if f.Recv != nil || f.Doc == nil {
- return false
- }
-
- cgoExport := regexp.MustCompile(fmt.Sprintf("(?m)^//export %s$", regexp.QuoteMeta(f.Name.Name)))
- for _, c := range f.Doc.List {
- if cgoExport.MatchString(c.Text) {
- return true
- }
- }
- return false
-}
-
-var basicTypeKinds = map[types.BasicKind]string{
- types.UntypedBool: "bool",
- types.UntypedInt: "int",
- types.UntypedRune: "rune",
- types.UntypedFloat: "float64",
- types.UntypedComplex: "complex128",
- types.UntypedString: "string",
-}
-
-// isUntypedConst reports whether expr is an untyped constant,
-// and indicates what its default type is.
-// scope may be nil.
-func (f *file) isUntypedConst(expr ast.Expr) (defType string, ok bool) {
- // Re-evaluate expr outside of its context to see if it's untyped.
- // (An expr evaluated within, for example, an assignment context will get the type of the LHS.)
- exprStr := f.render(expr)
- tv, err := types.Eval(f.fset, f.pkg.typesPkg, expr.Pos(), exprStr)
- if err != nil {
- return "", false
- }
- if b, ok := tv.Type.(*types.Basic); ok {
- if dt, ok := basicTypeKinds[b.Kind()]; ok {
- return dt, true
- }
- }
-
- return "", false
-}
-
-// firstLineOf renders the given node and returns its first line.
-// It will also match the indentation of another node.
-func (f *file) firstLineOf(node, match ast.Node) string {
- line := f.render(node)
- if i := strings.Index(line, "\n"); i >= 0 {
- line = line[:i]
- }
- return f.indentOf(match) + line
-}
-
-func (f *file) indentOf(node ast.Node) string {
- line := srcLine(f.src, f.fset.Position(node.Pos()))
- for i, r := range line {
- switch r {
- case ' ', '\t':
- default:
- return line[:i]
- }
- }
- return line // unusual or empty line
-}
-
-func (f *file) srcLineWithMatch(node ast.Node, pattern string) (m []string) {
- line := srcLine(f.src, f.fset.Position(node.Pos()))
- line = strings.TrimSuffix(line, "\n")
- rx := regexp.MustCompile(pattern)
- return rx.FindStringSubmatch(line)
-}
-
-// imports returns true if the current file imports the specified package path.
-func (f *file) imports(importPath string) bool {
- all := astutil.Imports(f.fset, f.f)
- for _, p := range all {
- for _, i := range p {
- uq, err := strconv.Unquote(i.Path.Value)
- if err == nil && importPath == uq {
- return true
- }
- }
- }
- return false
-}
-
-// srcLine returns the complete line at p, including the terminating newline.
-func srcLine(src []byte, p token.Position) string {
- // Run to end of line in both directions if not at line start/end.
- lo, hi := p.Offset, p.Offset+1
- for lo > 0 && src[lo-1] != '\n' {
- lo--
- }
- for hi < len(src) && src[hi-1] != '\n' {
- hi++
- }
- return string(src[lo:hi])
-}
diff --git a/vendor/golang.org/x/oauth2/README.md b/vendor/golang.org/x/oauth2/README.md
index 8cfd6063e..0f443e693 100644
--- a/vendor/golang.org/x/oauth2/README.md
+++ b/vendor/golang.org/x/oauth2/README.md
@@ -16,16 +16,15 @@ Or you can manually git clone the repository to
See godoc for further documentation and examples.
-* [godoc.org/golang.org/x/oauth2](https://godoc.org/golang.org/x/oauth2)
-* [godoc.org/golang.org/x/oauth2/google](https://godoc.org/golang.org/x/oauth2/google)
+* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2)
+* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google)
## Policy for new packages
-We no longer accept new provider-specific packages in this repo if all
-they do is add a single endpoint variable. If you just want to add a
-single endpoint, add it to the
-[godoc.org/golang.org/x/oauth2/endpoints](https://godoc.org/golang.org/x/oauth2/endpoints)
-package.
+We no longer accept new provider-specific packages in this repo. For
+defining provider endpoints and provider-specific OAuth2 behavior, we
+encourage you to create packages elsewhere. We'll keep the existing
+packages for compatibility.
## Report Issues / Send Patches
diff --git a/vendor/golang.org/x/oauth2/transport.go b/vendor/golang.org/x/oauth2/transport.go
index 90657915f..aa0d34f1e 100644
--- a/vendor/golang.org/x/oauth2/transport.go
+++ b/vendor/golang.org/x/oauth2/transport.go
@@ -6,7 +6,7 @@ package oauth2
import (
"errors"
- "log"
+ "io"
"net/http"
"sync"
)
@@ -25,6 +25,9 @@ type Transport struct {
// Base is the base RoundTripper used to make HTTP requests.
// If nil, http.DefaultTransport is used.
Base http.RoundTripper
+
+ mu sync.Mutex // guards modReq
+ modReq map[*http.Request]*http.Request // original -> modified
}
// RoundTrip authorizes and authenticates the request with an
@@ -49,22 +52,35 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
req2 := cloneRequest(req) // per RoundTripper contract
token.SetAuthHeader(req2)
+ t.setModReq(req, req2)
+ res, err := t.base().RoundTrip(req2)
- // req.Body is assumed to be closed by the base RoundTripper.
+ // req.Body is assumed to have been closed by the base RoundTripper.
reqBodyClosed = true
- return t.base().RoundTrip(req2)
-}
-var cancelOnce sync.Once
+ if err != nil {
+ t.setModReq(req, nil)
+ return nil, err
+ }
+ res.Body = &onEOFReader{
+ rc: res.Body,
+ fn: func() { t.setModReq(req, nil) },
+ }
+ return res, nil
+}
-// CancelRequest does nothing. It used to be a legacy cancellation mechanism
-// but now only it only logs on first use to warn that it's deprecated.
-//
-// Deprecated: use contexts for cancellation instead.
+// CancelRequest cancels an in-flight request by closing its connection.
func (t *Transport) CancelRequest(req *http.Request) {
- cancelOnce.Do(func() {
- log.Printf("deprecated: golang.org/x/oauth2: Transport.CancelRequest no longer does anything; use contexts")
- })
+ type canceler interface {
+ CancelRequest(*http.Request)
+ }
+ if cr, ok := t.base().(canceler); ok {
+ t.mu.Lock()
+ modReq := t.modReq[req]
+ delete(t.modReq, req)
+ t.mu.Unlock()
+ cr.CancelRequest(modReq)
+ }
}
func (t *Transport) base() http.RoundTripper {
@@ -74,6 +90,19 @@ func (t *Transport) base() http.RoundTripper {
return http.DefaultTransport
}
+func (t *Transport) setModReq(orig, mod *http.Request) {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ if t.modReq == nil {
+ t.modReq = make(map[*http.Request]*http.Request)
+ }
+ if mod == nil {
+ delete(t.modReq, orig)
+ } else {
+ t.modReq[orig] = mod
+ }
+}
+
// cloneRequest returns a clone of the provided *http.Request.
// The clone is a shallow copy of the struct and its Header map.
func cloneRequest(r *http.Request) *http.Request {
@@ -87,3 +116,29 @@ func cloneRequest(r *http.Request) *http.Request {
}
return r2
}
+
+type onEOFReader struct {
+ rc io.ReadCloser
+ fn func()
+}
+
+func (r *onEOFReader) Read(p []byte) (n int, err error) {
+ n, err = r.rc.Read(p)
+ if err == io.EOF {
+ r.runFunc()
+ }
+ return
+}
+
+func (r *onEOFReader) Close() error {
+ err := r.rc.Close()
+ r.runFunc()
+ return err
+}
+
+func (r *onEOFReader) runFunc() {
+ if fn := r.fn; fn != nil {
+ fn()
+ r.fn = nil
+ }
+}
diff --git a/vendor/golang.org/x/time/rate/rate.go b/vendor/golang.org/x/time/rate/rate.go
index a114b1aa5..ae93e2471 100644
--- a/vendor/golang.org/x/time/rate/rate.go
+++ b/vendor/golang.org/x/time/rate/rate.go
@@ -196,7 +196,7 @@ func (lim *Limiter) Reserve() *Reservation {
// ReserveN returns a Reservation that indicates how long the caller must wait before n events happen.
// The Limiter takes this Reservation into account when allowing future events.
-// The returned Reservation’s OK() method returns false if n exceeds the Limiter's burst size.
+// ReserveN returns false if n exceeds the Limiter's burst size.
// Usage example:
// r := lim.ReserveN(time.Now(), 1)
// if !r.OK() {
@@ -223,12 +223,7 @@ func (lim *Limiter) Wait(ctx context.Context) (err error) {
// canceled, or the expected wait time exceeds the Context's Deadline.
// The burst limit is ignored if the rate limit is Inf.
func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) {
- lim.mu.Lock()
- burst := lim.burst
- limit := lim.limit
- lim.mu.Unlock()
-
- if n > burst && limit != Inf {
+ if n > lim.burst && lim.limit != Inf {
return fmt.Errorf("rate: Wait(n=%d) exceeds limiter's burst %d", n, lim.burst)
}
// Check if ctx is already cancelled
@@ -286,23 +281,6 @@ func (lim *Limiter) SetLimitAt(now time.Time, newLimit Limit) {
lim.limit = newLimit
}
-// SetBurst is shorthand for SetBurstAt(time.Now(), newBurst).
-func (lim *Limiter) SetBurst(newBurst int) {
- lim.SetBurstAt(time.Now(), newBurst)
-}
-
-// SetBurstAt sets a new burst size for the limiter.
-func (lim *Limiter) SetBurstAt(now time.Time, newBurst int) {
- lim.mu.Lock()
- defer lim.mu.Unlock()
-
- now, _, tokens := lim.advance(now)
-
- lim.last = now
- lim.tokens = tokens
- lim.burst = newBurst
-}
-
// reserveN is a helper method for AllowN, ReserveN, and WaitN.
// maxFutureReserve specifies the maximum reservation wait duration allowed.
// reserveN returns Reservation, not *Reservation, to avoid allocation in AllowN and WaitN.
@@ -392,9 +370,5 @@ func (limit Limit) durationFromTokens(tokens float64) time.Duration {
// tokensFromDuration is a unit conversion function from a time duration to the number of tokens
// which could be accumulated during that duration at a rate of limit tokens per second.
func (limit Limit) tokensFromDuration(d time.Duration) float64 {
- // Split the integer and fractional parts ourself to minimize rounding errors.
- // See golang.org/issues/34861.
- sec := float64(d/time.Second) * float64(limit)
- nsec := float64(d%time.Second) * float64(limit)
- return sec + nsec/1e9
+ return d.Seconds() * float64(limit)
}
diff --git a/vendor/golang.org/x/tools/AUTHORS b/vendor/golang.org/x/tools/AUTHORS
deleted file mode 100644
index 15167cd74..000000000
--- a/vendor/golang.org/x/tools/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code refers to The Go Authors for copyright purposes.
-# The master list of authors is in the main Go distribution,
-# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/tools/CONTRIBUTORS b/vendor/golang.org/x/tools/CONTRIBUTORS
deleted file mode 100644
index 1c4577e96..000000000
--- a/vendor/golang.org/x/tools/CONTRIBUTORS
+++ /dev/null
@@ -1,3 +0,0 @@
-# This source code was written by the Go contributors.
-# The master list of contributors is in the main Go distribution,
-# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/tools/LICENSE b/vendor/golang.org/x/tools/LICENSE
deleted file mode 100644
index 6a66aea5e..000000000
--- a/vendor/golang.org/x/tools/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-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.
diff --git a/vendor/golang.org/x/tools/PATENTS b/vendor/golang.org/x/tools/PATENTS
deleted file mode 100644
index 733099041..000000000
--- a/vendor/golang.org/x/tools/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Go project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Go, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of Go. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of Go or any code incorporated within this
-implementation of Go constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of Go
-shall terminate as of the date such litigation is filed.
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 ea56b724e..000000000
--- a/vendor/golang.org/x/tools/go/analysis/doc.go
+++ /dev/null
@@ -1,301 +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.
-
-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/astutil/enclosing.go b/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
deleted file mode 100644
index 6b7052b89..000000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/enclosing.go
+++ /dev/null
@@ -1,627 +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 astutil
-
-// This file defines utilities for working with source positions.
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "sort"
-)
-
-// PathEnclosingInterval returns the node that encloses the source
-// interval [start, end), and all its ancestors up to the AST root.
-//
-// The definition of "enclosing" used by this function considers
-// additional whitespace abutting a node to be enclosed by it.
-// In this example:
-//
-// z := x + y // add them
-// <-A->
-// <----B----->
-//
-// the ast.BinaryExpr(+) node is considered to enclose interval B
-// even though its [Pos()..End()) is actually only interval A.
-// This behaviour makes user interfaces more tolerant of imperfect
-// input.
-//
-// This function treats tokens as nodes, though they are not included
-// in the result. e.g. PathEnclosingInterval("+") returns the
-// enclosing ast.BinaryExpr("x + y").
-//
-// If start==end, the 1-char interval following start is used instead.
-//
-// The 'exact' result is true if the interval contains only path[0]
-// and perhaps some adjacent whitespace. It is false if the interval
-// overlaps multiple children of path[0], or if it contains only
-// interior whitespace of path[0].
-// In this example:
-//
-// z := x + y // add them
-// <--C--> <---E-->
-// ^
-// D
-//
-// intervals C, D and E are inexact. C is contained by the
-// z-assignment statement, because it spans three of its children (:=,
-// x, +). So too is the 1-char interval D, because it contains only
-// interior whitespace of the assignment. E is considered interior
-// whitespace of the BlockStmt containing the assignment.
-//
-// Precondition: [start, end) both lie within the same file as root.
-// TODO(adonovan): return (nil, false) in this case and remove precond.
-// Requires FileSet; see loader.tokenFileContainsPos.
-//
-// Postcondition: path is never nil; it always contains at least 'root'.
-//
-func PathEnclosingInterval(root *ast.File, start, end token.Pos) (path []ast.Node, exact bool) {
- // fmt.Printf("EnclosingInterval %d %d\n", start, end) // debugging
-
- // Precondition: node.[Pos..End) and adjoining whitespace contain [start, end).
- var visit func(node ast.Node) bool
- visit = func(node ast.Node) bool {
- path = append(path, node)
-
- nodePos := node.Pos()
- nodeEnd := node.End()
-
- // fmt.Printf("visit(%T, %d, %d)\n", node, nodePos, nodeEnd) // debugging
-
- // Intersect [start, end) with interval of node.
- if start < nodePos {
- start = nodePos
- }
- if end > nodeEnd {
- end = nodeEnd
- }
-
- // Find sole child that contains [start, end).
- children := childrenOf(node)
- l := len(children)
- for i, child := range children {
- // [childPos, childEnd) is unaugmented interval of child.
- childPos := child.Pos()
- childEnd := child.End()
-
- // [augPos, augEnd) is whitespace-augmented interval of child.
- augPos := childPos
- augEnd := childEnd
- if i > 0 {
- augPos = children[i-1].End() // start of preceding whitespace
- }
- if i < l-1 {
- nextChildPos := children[i+1].Pos()
- // Does [start, end) lie between child and next child?
- if start >= augEnd && end <= nextChildPos {
- return false // inexact match
- }
- augEnd = nextChildPos // end of following whitespace
- }
-
- // fmt.Printf("\tchild %d: [%d..%d)\tcontains interval [%d..%d)?\n",
- // i, augPos, augEnd, start, end) // debugging
-
- // Does augmented child strictly contain [start, end)?
- if augPos <= start && end <= augEnd {
- _, isToken := child.(tokenNode)
- return isToken || visit(child)
- }
-
- // Does [start, end) overlap multiple children?
- // i.e. left-augmented child contains start
- // but LR-augmented child does not contain end.
- if start < childEnd && end > augEnd {
- break
- }
- }
-
- // No single child contained [start, end),
- // so node is the result. Is it exact?
-
- // (It's tempting to put this condition before the
- // child loop, but it gives the wrong result in the
- // case where a node (e.g. ExprStmt) and its sole
- // child have equal intervals.)
- if start == nodePos && end == nodeEnd {
- return true // exact match
- }
-
- return false // inexact: overlaps multiple children
- }
-
- if start > end {
- start, end = end, start
- }
-
- if start < root.End() && end > root.Pos() {
- if start == end {
- end = start + 1 // empty interval => interval of size 1
- }
- exact = visit(root)
-
- // Reverse the path:
- for i, l := 0, len(path); i < l/2; i++ {
- path[i], path[l-1-i] = path[l-1-i], path[i]
- }
- } else {
- // Selection lies within whitespace preceding the
- // first (or following the last) declaration in the file.
- // The result nonetheless always includes the ast.File.
- path = append(path, root)
- }
-
- return
-}
-
-// tokenNode is a dummy implementation of ast.Node for a single token.
-// They are used transiently by PathEnclosingInterval but never escape
-// this package.
-//
-type tokenNode struct {
- pos token.Pos
- end token.Pos
-}
-
-func (n tokenNode) Pos() token.Pos {
- return n.pos
-}
-
-func (n tokenNode) End() token.Pos {
- return n.end
-}
-
-func tok(pos token.Pos, len int) ast.Node {
- return tokenNode{pos, pos + token.Pos(len)}
-}
-
-// childrenOf returns the direct non-nil children of ast.Node n.
-// It may include fake ast.Node implementations for bare tokens.
-// it is not safe to call (e.g.) ast.Walk on such nodes.
-//
-func childrenOf(n ast.Node) []ast.Node {
- var children []ast.Node
-
- // First add nodes for all true subtrees.
- ast.Inspect(n, func(node ast.Node) bool {
- if node == n { // push n
- return true // recur
- }
- if node != nil { // push child
- children = append(children, node)
- }
- return false // no recursion
- })
-
- // Then add fake Nodes for bare tokens.
- switch n := n.(type) {
- case *ast.ArrayType:
- children = append(children,
- tok(n.Lbrack, len("[")),
- tok(n.Elt.End(), len("]")))
-
- case *ast.AssignStmt:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.BasicLit:
- children = append(children,
- tok(n.ValuePos, len(n.Value)))
-
- case *ast.BinaryExpr:
- children = append(children, tok(n.OpPos, len(n.Op.String())))
-
- case *ast.BlockStmt:
- children = append(children,
- tok(n.Lbrace, len("{")),
- tok(n.Rbrace, len("}")))
-
- case *ast.BranchStmt:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.CallExpr:
- children = append(children,
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
- if n.Ellipsis != 0 {
- children = append(children, tok(n.Ellipsis, len("...")))
- }
-
- case *ast.CaseClause:
- if n.List == nil {
- children = append(children,
- tok(n.Case, len("default")))
- } else {
- children = append(children,
- tok(n.Case, len("case")))
- }
- children = append(children, tok(n.Colon, len(":")))
-
- case *ast.ChanType:
- switch n.Dir {
- case ast.RECV:
- children = append(children, tok(n.Begin, len("<-chan")))
- case ast.SEND:
- children = append(children, tok(n.Begin, len("chan<-")))
- case ast.RECV | ast.SEND:
- children = append(children, tok(n.Begin, len("chan")))
- }
-
- case *ast.CommClause:
- if n.Comm == nil {
- children = append(children,
- tok(n.Case, len("default")))
- } else {
- children = append(children,
- tok(n.Case, len("case")))
- }
- children = append(children, tok(n.Colon, len(":")))
-
- case *ast.Comment:
- // nop
-
- case *ast.CommentGroup:
- // nop
-
- case *ast.CompositeLit:
- children = append(children,
- tok(n.Lbrace, len("{")),
- tok(n.Rbrace, len("{")))
-
- case *ast.DeclStmt:
- // nop
-
- case *ast.DeferStmt:
- children = append(children,
- tok(n.Defer, len("defer")))
-
- case *ast.Ellipsis:
- children = append(children,
- tok(n.Ellipsis, len("...")))
-
- case *ast.EmptyStmt:
- // nop
-
- case *ast.ExprStmt:
- // nop
-
- case *ast.Field:
- // TODO(adonovan): Field.{Doc,Comment,Tag}?
-
- case *ast.FieldList:
- children = append(children,
- tok(n.Opening, len("(")),
- tok(n.Closing, len(")")))
-
- case *ast.File:
- // TODO test: Doc
- children = append(children,
- tok(n.Package, len("package")))
-
- case *ast.ForStmt:
- children = append(children,
- tok(n.For, len("for")))
-
- case *ast.FuncDecl:
- // TODO(adonovan): FuncDecl.Comment?
-
- // Uniquely, FuncDecl breaks the invariant that
- // preorder traversal yields tokens in lexical order:
- // in fact, FuncDecl.Recv precedes FuncDecl.Type.Func.
- //
- // As a workaround, we inline the case for FuncType
- // here and order things correctly.
- //
- children = nil // discard ast.Walk(FuncDecl) info subtrees
- children = append(children, tok(n.Type.Func, len("func")))
- if n.Recv != nil {
- children = append(children, n.Recv)
- }
- children = append(children, n.Name)
- if n.Type.Params != nil {
- children = append(children, n.Type.Params)
- }
- if n.Type.Results != nil {
- children = append(children, n.Type.Results)
- }
- if n.Body != nil {
- children = append(children, n.Body)
- }
-
- case *ast.FuncLit:
- // nop
-
- case *ast.FuncType:
- if n.Func != 0 {
- children = append(children,
- tok(n.Func, len("func")))
- }
-
- case *ast.GenDecl:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
- if n.Lparen != 0 {
- children = append(children,
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
- }
-
- case *ast.GoStmt:
- children = append(children,
- tok(n.Go, len("go")))
-
- case *ast.Ident:
- children = append(children,
- tok(n.NamePos, len(n.Name)))
-
- case *ast.IfStmt:
- children = append(children,
- tok(n.If, len("if")))
-
- case *ast.ImportSpec:
- // TODO(adonovan): ImportSpec.{Doc,EndPos}?
-
- case *ast.IncDecStmt:
- children = append(children,
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.IndexExpr:
- children = append(children,
- tok(n.Lbrack, len("{")),
- tok(n.Rbrack, len("}")))
-
- case *ast.InterfaceType:
- children = append(children,
- tok(n.Interface, len("interface")))
-
- case *ast.KeyValueExpr:
- children = append(children,
- tok(n.Colon, len(":")))
-
- case *ast.LabeledStmt:
- children = append(children,
- tok(n.Colon, len(":")))
-
- case *ast.MapType:
- children = append(children,
- tok(n.Map, len("map")))
-
- case *ast.ParenExpr:
- children = append(children,
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
-
- case *ast.RangeStmt:
- children = append(children,
- tok(n.For, len("for")),
- tok(n.TokPos, len(n.Tok.String())))
-
- case *ast.ReturnStmt:
- children = append(children,
- tok(n.Return, len("return")))
-
- case *ast.SelectStmt:
- children = append(children,
- tok(n.Select, len("select")))
-
- case *ast.SelectorExpr:
- // nop
-
- case *ast.SendStmt:
- children = append(children,
- tok(n.Arrow, len("<-")))
-
- case *ast.SliceExpr:
- children = append(children,
- tok(n.Lbrack, len("[")),
- tok(n.Rbrack, len("]")))
-
- case *ast.StarExpr:
- children = append(children, tok(n.Star, len("*")))
-
- case *ast.StructType:
- children = append(children, tok(n.Struct, len("struct")))
-
- case *ast.SwitchStmt:
- children = append(children, tok(n.Switch, len("switch")))
-
- case *ast.TypeAssertExpr:
- children = append(children,
- tok(n.Lparen-1, len(".")),
- tok(n.Lparen, len("(")),
- tok(n.Rparen, len(")")))
-
- case *ast.TypeSpec:
- // TODO(adonovan): TypeSpec.{Doc,Comment}?
-
- case *ast.TypeSwitchStmt:
- children = append(children, tok(n.Switch, len("switch")))
-
- case *ast.UnaryExpr:
- children = append(children, tok(n.OpPos, len(n.Op.String())))
-
- case *ast.ValueSpec:
- // TODO(adonovan): ValueSpec.{Doc,Comment}?
-
- case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt:
- // nop
- }
-
- // TODO(adonovan): opt: merge the logic of ast.Inspect() into
- // the switch above so we can make interleaved callbacks for
- // both Nodes and Tokens in the right order and avoid the need
- // to sort.
- sort.Sort(byPos(children))
-
- return children
-}
-
-type byPos []ast.Node
-
-func (sl byPos) Len() int {
- return len(sl)
-}
-func (sl byPos) Less(i, j int) bool {
- return sl[i].Pos() < sl[j].Pos()
-}
-func (sl byPos) Swap(i, j int) {
- sl[i], sl[j] = sl[j], sl[i]
-}
-
-// NodeDescription returns a description of the concrete type of n suitable
-// for a user interface.
-//
-// TODO(adonovan): in some cases (e.g. Field, FieldList, Ident,
-// StarExpr) we could be much more specific given the path to the AST
-// root. Perhaps we should do that.
-//
-func NodeDescription(n ast.Node) string {
- switch n := n.(type) {
- case *ast.ArrayType:
- return "array type"
- case *ast.AssignStmt:
- return "assignment"
- case *ast.BadDecl:
- return "bad declaration"
- case *ast.BadExpr:
- return "bad expression"
- case *ast.BadStmt:
- return "bad statement"
- case *ast.BasicLit:
- return "basic literal"
- case *ast.BinaryExpr:
- return fmt.Sprintf("binary %s operation", n.Op)
- case *ast.BlockStmt:
- return "block"
- case *ast.BranchStmt:
- switch n.Tok {
- case token.BREAK:
- return "break statement"
- case token.CONTINUE:
- return "continue statement"
- case token.GOTO:
- return "goto statement"
- case token.FALLTHROUGH:
- return "fall-through statement"
- }
- case *ast.CallExpr:
- if len(n.Args) == 1 && !n.Ellipsis.IsValid() {
- return "function call (or conversion)"
- }
- return "function call"
- case *ast.CaseClause:
- return "case clause"
- case *ast.ChanType:
- return "channel type"
- case *ast.CommClause:
- return "communication clause"
- case *ast.Comment:
- return "comment"
- case *ast.CommentGroup:
- return "comment group"
- case *ast.CompositeLit:
- return "composite literal"
- case *ast.DeclStmt:
- return NodeDescription(n.Decl) + " statement"
- case *ast.DeferStmt:
- return "defer statement"
- case *ast.Ellipsis:
- return "ellipsis"
- case *ast.EmptyStmt:
- return "empty statement"
- case *ast.ExprStmt:
- return "expression statement"
- case *ast.Field:
- // Can be any of these:
- // struct {x, y int} -- struct field(s)
- // struct {T} -- anon struct field
- // interface {I} -- interface embedding
- // interface {f()} -- interface method
- // func (A) func(B) C -- receiver, param(s), result(s)
- return "field/method/parameter"
- case *ast.FieldList:
- return "field/method/parameter list"
- case *ast.File:
- return "source file"
- case *ast.ForStmt:
- return "for loop"
- case *ast.FuncDecl:
- return "function declaration"
- case *ast.FuncLit:
- return "function literal"
- case *ast.FuncType:
- return "function type"
- case *ast.GenDecl:
- switch n.Tok {
- case token.IMPORT:
- return "import declaration"
- case token.CONST:
- return "constant declaration"
- case token.TYPE:
- return "type declaration"
- case token.VAR:
- return "variable declaration"
- }
- case *ast.GoStmt:
- return "go statement"
- case *ast.Ident:
- return "identifier"
- case *ast.IfStmt:
- return "if statement"
- case *ast.ImportSpec:
- return "import specification"
- case *ast.IncDecStmt:
- if n.Tok == token.INC {
- return "increment statement"
- }
- return "decrement statement"
- case *ast.IndexExpr:
- return "index expression"
- case *ast.InterfaceType:
- return "interface type"
- case *ast.KeyValueExpr:
- return "key/value association"
- case *ast.LabeledStmt:
- return "statement label"
- case *ast.MapType:
- return "map type"
- case *ast.Package:
- return "package"
- case *ast.ParenExpr:
- return "parenthesized " + NodeDescription(n.X)
- case *ast.RangeStmt:
- return "range loop"
- case *ast.ReturnStmt:
- return "return statement"
- case *ast.SelectStmt:
- return "select statement"
- case *ast.SelectorExpr:
- return "selector"
- case *ast.SendStmt:
- return "channel send"
- case *ast.SliceExpr:
- return "slice expression"
- case *ast.StarExpr:
- return "*-operation" // load/store expr or pointer type
- case *ast.StructType:
- return "struct type"
- case *ast.SwitchStmt:
- return "switch statement"
- case *ast.TypeAssertExpr:
- return "type assertion"
- case *ast.TypeSpec:
- return "type specification"
- case *ast.TypeSwitchStmt:
- return "type switch"
- case *ast.UnaryExpr:
- return fmt.Sprintf("unary %s operation", n.Op)
- case *ast.ValueSpec:
- return "value specification"
-
- }
- panic(fmt.Sprintf("unexpected node type: %T", n))
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
deleted file mode 100644
index 2087ceec9..000000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go
+++ /dev/null
@@ -1,482 +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 astutil contains common utilities for working with the Go AST.
-package astutil // import "golang.org/x/tools/go/ast/astutil"
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "strconv"
- "strings"
-)
-
-// AddImport adds the import path to the file f, if absent.
-func AddImport(fset *token.FileSet, f *ast.File, path string) (added bool) {
- return AddNamedImport(fset, f, "", path)
-}
-
-// AddNamedImport adds the import with the given name and path to the file f, if absent.
-// If name is not empty, it is used to rename the import.
-//
-// For example, calling
-// AddNamedImport(fset, f, "pathpkg", "path")
-// adds
-// import pathpkg "path"
-func AddNamedImport(fset *token.FileSet, f *ast.File, name, path string) (added bool) {
- if imports(f, name, path) {
- return false
- }
-
- newImport := &ast.ImportSpec{
- Path: &ast.BasicLit{
- Kind: token.STRING,
- Value: strconv.Quote(path),
- },
- }
- if name != "" {
- newImport.Name = &ast.Ident{Name: name}
- }
-
- // Find an import decl to add to.
- // The goal is to find an existing import
- // whose import path has the longest shared
- // prefix with path.
- var (
- bestMatch = -1 // length of longest shared prefix
- lastImport = -1 // index in f.Decls of the file's final import decl
- impDecl *ast.GenDecl // import decl containing the best match
- impIndex = -1 // spec index in impDecl containing the best match
-
- isThirdPartyPath = isThirdParty(path)
- )
- for i, decl := range f.Decls {
- gen, ok := decl.(*ast.GenDecl)
- if ok && gen.Tok == token.IMPORT {
- lastImport = i
- // Do not add to import "C", to avoid disrupting the
- // association with its doc comment, breaking cgo.
- if declImports(gen, "C") {
- continue
- }
-
- // Match an empty import decl if that's all that is available.
- if len(gen.Specs) == 0 && bestMatch == -1 {
- impDecl = gen
- }
-
- // Compute longest shared prefix with imports in this group and find best
- // matched import spec.
- // 1. Always prefer import spec with longest shared prefix.
- // 2. While match length is 0,
- // - for stdlib package: prefer first import spec.
- // - for third party package: prefer first third party import spec.
- // We cannot use last import spec as best match for third party package
- // because grouped imports are usually placed last by goimports -local
- // flag.
- // See issue #19190.
- seenAnyThirdParty := false
- for j, spec := range gen.Specs {
- impspec := spec.(*ast.ImportSpec)
- p := importPath(impspec)
- n := matchLen(p, path)
- if n > bestMatch || (bestMatch == 0 && !seenAnyThirdParty && isThirdPartyPath) {
- bestMatch = n
- impDecl = gen
- impIndex = j
- }
- seenAnyThirdParty = seenAnyThirdParty || isThirdParty(p)
- }
- }
- }
-
- // If no import decl found, add one after the last import.
- if impDecl == nil {
- impDecl = &ast.GenDecl{
- Tok: token.IMPORT,
- }
- if lastImport >= 0 {
- impDecl.TokPos = f.Decls[lastImport].End()
- } else {
- // There are no existing imports.
- // Our new import, preceded by a blank line, goes after the package declaration
- // and after the comment, if any, that starts on the same line as the
- // package declaration.
- impDecl.TokPos = f.Package
-
- file := fset.File(f.Package)
- pkgLine := file.Line(f.Package)
- for _, c := range f.Comments {
- if file.Line(c.Pos()) > pkgLine {
- break
- }
- // +2 for a blank line
- impDecl.TokPos = c.End() + 2
- }
- }
- f.Decls = append(f.Decls, nil)
- copy(f.Decls[lastImport+2:], f.Decls[lastImport+1:])
- f.Decls[lastImport+1] = impDecl
- }
-
- // Insert new import at insertAt.
- insertAt := 0
- if impIndex >= 0 {
- // insert after the found import
- insertAt = impIndex + 1
- }
- impDecl.Specs = append(impDecl.Specs, nil)
- copy(impDecl.Specs[insertAt+1:], impDecl.Specs[insertAt:])
- impDecl.Specs[insertAt] = newImport
- pos := impDecl.Pos()
- if insertAt > 0 {
- // If there is a comment after an existing import, preserve the comment
- // position by adding the new import after the comment.
- if spec, ok := impDecl.Specs[insertAt-1].(*ast.ImportSpec); ok && spec.Comment != nil {
- pos = spec.Comment.End()
- } else {
- // Assign same position as the previous import,
- // so that the sorter sees it as being in the same block.
- pos = impDecl.Specs[insertAt-1].Pos()
- }
- }
- if newImport.Name != nil {
- newImport.Name.NamePos = pos
- }
- newImport.Path.ValuePos = pos
- newImport.EndPos = pos
-
- // Clean up parens. impDecl contains at least one spec.
- if len(impDecl.Specs) == 1 {
- // Remove unneeded parens.
- impDecl.Lparen = token.NoPos
- } else if !impDecl.Lparen.IsValid() {
- // impDecl needs parens added.
- impDecl.Lparen = impDecl.Specs[0].Pos()
- }
-
- f.Imports = append(f.Imports, newImport)
-
- if len(f.Decls) <= 1 {
- return true
- }
-
- // Merge all the import declarations into the first one.
- var first *ast.GenDecl
- for i := 0; i < len(f.Decls); i++ {
- decl := f.Decls[i]
- gen, ok := decl.(*ast.GenDecl)
- if !ok || gen.Tok != token.IMPORT || declImports(gen, "C") {
- continue
- }
- if first == nil {
- first = gen
- continue // Don't touch the first one.
- }
- // We now know there is more than one package in this import
- // declaration. Ensure that it ends up parenthesized.
- first.Lparen = first.Pos()
- // Move the imports of the other import declaration to the first one.
- for _, spec := range gen.Specs {
- spec.(*ast.ImportSpec).Path.ValuePos = first.Pos()
- first.Specs = append(first.Specs, spec)
- }
- f.Decls = append(f.Decls[:i], f.Decls[i+1:]...)
- i--
- }
-
- return true
-}
-
-func isThirdParty(importPath string) bool {
- // Third party package import path usually contains "." (".com", ".org", ...)
- // This logic is taken from golang.org/x/tools/imports package.
- return strings.Contains(importPath, ".")
-}
-
-// DeleteImport deletes the import path from the file f, if present.
-// If there are duplicate import declarations, all matching ones are deleted.
-func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool) {
- return DeleteNamedImport(fset, f, "", path)
-}
-
-// DeleteNamedImport deletes the import with the given name and path from the file f, if present.
-// If there are duplicate import declarations, all matching ones are deleted.
-func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
- var delspecs []*ast.ImportSpec
- var delcomments []*ast.CommentGroup
-
- // Find the import nodes that import path, if any.
- for i := 0; i < len(f.Decls); i++ {
- decl := f.Decls[i]
- gen, ok := decl.(*ast.GenDecl)
- if !ok || gen.Tok != token.IMPORT {
- continue
- }
- for j := 0; j < len(gen.Specs); j++ {
- spec := gen.Specs[j]
- impspec := spec.(*ast.ImportSpec)
- if importName(impspec) != name || importPath(impspec) != path {
- continue
- }
-
- // We found an import spec that imports path.
- // Delete it.
- delspecs = append(delspecs, impspec)
- deleted = true
- copy(gen.Specs[j:], gen.Specs[j+1:])
- gen.Specs = gen.Specs[:len(gen.Specs)-1]
-
- // If this was the last import spec in this decl,
- // delete the decl, too.
- if len(gen.Specs) == 0 {
- copy(f.Decls[i:], f.Decls[i+1:])
- f.Decls = f.Decls[:len(f.Decls)-1]
- i--
- break
- } else if len(gen.Specs) == 1 {
- if impspec.Doc != nil {
- delcomments = append(delcomments, impspec.Doc)
- }
- if impspec.Comment != nil {
- delcomments = append(delcomments, impspec.Comment)
- }
- for _, cg := range f.Comments {
- // Found comment on the same line as the import spec.
- if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line {
- delcomments = append(delcomments, cg)
- break
- }
- }
-
- spec := gen.Specs[0].(*ast.ImportSpec)
-
- // Move the documentation right after the import decl.
- if spec.Doc != nil {
- for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Doc.Pos()).Line {
- fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
- }
- }
- for _, cg := range f.Comments {
- if cg.End() < spec.Pos() && fset.Position(cg.End()).Line == fset.Position(spec.Pos()).Line {
- for fset.Position(gen.TokPos).Line+1 < fset.Position(spec.Pos()).Line {
- fset.File(gen.TokPos).MergeLine(fset.Position(gen.TokPos).Line)
- }
- break
- }
- }
- }
- if j > 0 {
- lastImpspec := gen.Specs[j-1].(*ast.ImportSpec)
- lastLine := fset.Position(lastImpspec.Path.ValuePos).Line
- line := fset.Position(impspec.Path.ValuePos).Line
-
- // We deleted an entry but now there may be
- // a blank line-sized hole where the import was.
- if line-lastLine > 1 || !gen.Rparen.IsValid() {
- // There was a blank line immediately preceding the deleted import,
- // so there's no need to close the hole. The right parenthesis is
- // invalid after AddImport to an import statement without parenthesis.
- // Do nothing.
- } else if line != fset.File(gen.Rparen).LineCount() {
- // There was no blank line. Close the hole.
- fset.File(gen.Rparen).MergeLine(line)
- }
- }
- j--
- }
- }
-
- // Delete imports from f.Imports.
- for i := 0; i < len(f.Imports); i++ {
- imp := f.Imports[i]
- for j, del := range delspecs {
- if imp == del {
- copy(f.Imports[i:], f.Imports[i+1:])
- f.Imports = f.Imports[:len(f.Imports)-1]
- copy(delspecs[j:], delspecs[j+1:])
- delspecs = delspecs[:len(delspecs)-1]
- i--
- break
- }
- }
- }
-
- // Delete comments from f.Comments.
- for i := 0; i < len(f.Comments); i++ {
- cg := f.Comments[i]
- for j, del := range delcomments {
- if cg == del {
- copy(f.Comments[i:], f.Comments[i+1:])
- f.Comments = f.Comments[:len(f.Comments)-1]
- copy(delcomments[j:], delcomments[j+1:])
- delcomments = delcomments[:len(delcomments)-1]
- i--
- break
- }
- }
- }
-
- if len(delspecs) > 0 {
- panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
- }
-
- return
-}
-
-// RewriteImport rewrites any import of path oldPath to path newPath.
-func RewriteImport(fset *token.FileSet, f *ast.File, oldPath, newPath string) (rewrote bool) {
- for _, imp := range f.Imports {
- if importPath(imp) == oldPath {
- rewrote = true
- // record old End, because the default is to compute
- // it using the length of imp.Path.Value.
- imp.EndPos = imp.End()
- imp.Path.Value = strconv.Quote(newPath)
- }
- }
- return
-}
-
-// UsesImport reports whether a given import is used.
-func UsesImport(f *ast.File, path string) (used bool) {
- spec := importSpec(f, path)
- if spec == nil {
- return
- }
-
- name := spec.Name.String()
- switch name {
- case "":
- // If the package name is not explicitly specified,
- // make an educated guess. This is not guaranteed to be correct.
- lastSlash := strings.LastIndex(path, "/")
- if lastSlash == -1 {
- name = path
- } else {
- name = path[lastSlash+1:]
- }
- case "_", ".":
- // Not sure if this import is used - err on the side of caution.
- return true
- }
-
- ast.Walk(visitFn(func(n ast.Node) {
- sel, ok := n.(*ast.SelectorExpr)
- if ok && isTopName(sel.X, name) {
- used = true
- }
- }), f)
-
- return
-}
-
-type visitFn func(node ast.Node)
-
-func (fn visitFn) Visit(node ast.Node) ast.Visitor {
- fn(node)
- return fn
-}
-
-// imports reports whether f has an import with the specified name and path.
-func imports(f *ast.File, name, path string) bool {
- for _, s := range f.Imports {
- if importName(s) == name && importPath(s) == path {
- return true
- }
- }
- return false
-}
-
-// importSpec returns the import spec if f imports path,
-// or nil otherwise.
-func importSpec(f *ast.File, path string) *ast.ImportSpec {
- for _, s := range f.Imports {
- if importPath(s) == path {
- return s
- }
- }
- return nil
-}
-
-// importName returns the name of s,
-// or "" if the import is not named.
-func importName(s *ast.ImportSpec) string {
- if s.Name == nil {
- return ""
- }
- return s.Name.Name
-}
-
-// importPath returns the unquoted import path of s,
-// or "" if the path is not properly quoted.
-func importPath(s *ast.ImportSpec) string {
- t, err := strconv.Unquote(s.Path.Value)
- if err != nil {
- return ""
- }
- return t
-}
-
-// declImports reports whether gen contains an import of path.
-func declImports(gen *ast.GenDecl, path string) bool {
- if gen.Tok != token.IMPORT {
- return false
- }
- for _, spec := range gen.Specs {
- impspec := spec.(*ast.ImportSpec)
- if importPath(impspec) == path {
- return true
- }
- }
- return false
-}
-
-// matchLen returns the length of the longest path segment prefix shared by x and y.
-func matchLen(x, y string) int {
- n := 0
- for i := 0; i < len(x) && i < len(y) && x[i] == y[i]; i++ {
- if x[i] == '/' {
- n++
- }
- }
- return n
-}
-
-// isTopName returns true if n is a top-level unresolved identifier with the given name.
-func isTopName(n ast.Expr, name string) bool {
- id, ok := n.(*ast.Ident)
- return ok && id.Name == name && id.Obj == nil
-}
-
-// Imports returns the file imports grouped by paragraph.
-func Imports(fset *token.FileSet, f *ast.File) [][]*ast.ImportSpec {
- var groups [][]*ast.ImportSpec
-
- for _, decl := range f.Decls {
- genDecl, ok := decl.(*ast.GenDecl)
- if !ok || genDecl.Tok != token.IMPORT {
- break
- }
-
- group := []*ast.ImportSpec{}
-
- var lastLine int
- for _, spec := range genDecl.Specs {
- importSpec := spec.(*ast.ImportSpec)
- pos := importSpec.Path.ValuePos
- line := fset.Position(pos).Line
- if lastLine > 0 && pos > 0 && line-lastLine > 1 {
- groups = append(groups, group)
- group = []*ast.ImportSpec{}
- }
- group = append(group, importSpec)
- lastLine = line
- }
- groups = append(groups, group)
- }
-
- return groups
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go b/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
deleted file mode 100644
index cf72ea990..000000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/rewrite.go
+++ /dev/null
@@ -1,477 +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 astutil
-
-import (
- "fmt"
- "go/ast"
- "reflect"
- "sort"
-)
-
-// An ApplyFunc is invoked by Apply for each node n, even if n is nil,
-// before and/or after the node's children, using a Cursor describing
-// the current node and providing operations on it.
-//
-// The return value of ApplyFunc controls the syntax tree traversal.
-// See Apply for details.
-type ApplyFunc func(*Cursor) bool
-
-// Apply traverses a syntax tree recursively, starting with root,
-// and calling pre and post for each node as described below.
-// Apply returns the syntax tree, possibly modified.
-//
-// If pre is not nil, it is called for each node before the node's
-// children are traversed (pre-order). If pre returns false, no
-// children are traversed, and post is not called for that node.
-//
-// If post is not nil, and a prior call of pre didn't return false,
-// post is called for each node after its children are traversed
-// (post-order). If post returns false, traversal is terminated and
-// Apply returns immediately.
-//
-// Only fields that refer to AST nodes are considered children;
-// i.e., token.Pos, Scopes, Objects, and fields of basic types
-// (strings, etc.) are ignored.
-//
-// Children are traversed in the order in which they appear in the
-// respective node's struct definition. A package's files are
-// traversed in the filenames' alphabetical order.
-//
-func Apply(root ast.Node, pre, post ApplyFunc) (result ast.Node) {
- parent := &struct{ ast.Node }{root}
- defer func() {
- if r := recover(); r != nil && r != abort {
- panic(r)
- }
- result = parent.Node
- }()
- a := &application{pre: pre, post: post}
- a.apply(parent, "Node", nil, root)
- return
-}
-
-var abort = new(int) // singleton, to signal termination of Apply
-
-// A Cursor describes a node encountered during Apply.
-// Information about the node and its parent is available
-// from the Node, Parent, Name, and Index methods.
-//
-// If p is a variable of type and value of the current parent node
-// c.Parent(), and f is the field identifier with name c.Name(),
-// the following invariants hold:
-//
-// p.f == c.Node() if c.Index() < 0
-// p.f[c.Index()] == c.Node() if c.Index() >= 0
-//
-// The methods Replace, Delete, InsertBefore, and InsertAfter
-// can be used to change the AST without disrupting Apply.
-type Cursor struct {
- parent ast.Node
- name string
- iter *iterator // valid if non-nil
- node ast.Node
-}
-
-// Node returns the current Node.
-func (c *Cursor) Node() ast.Node { return c.node }
-
-// Parent returns the parent of the current Node.
-func (c *Cursor) Parent() ast.Node { return c.parent }
-
-// Name returns the name of the parent Node field that contains the current Node.
-// If the parent is a *ast.Package and the current Node is a *ast.File, Name returns
-// the filename for the current Node.
-func (c *Cursor) Name() string { return c.name }
-
-// Index reports the index >= 0 of the current Node in the slice of Nodes that
-// contains it, or a value < 0 if the current Node is not part of a slice.
-// The index of the current node changes if InsertBefore is called while
-// processing the current node.
-func (c *Cursor) Index() int {
- if c.iter != nil {
- return c.iter.index
- }
- return -1
-}
-
-// field returns the current node's parent field value.
-func (c *Cursor) field() reflect.Value {
- return reflect.Indirect(reflect.ValueOf(c.parent)).FieldByName(c.name)
-}
-
-// Replace replaces the current Node with n.
-// The replacement node is not walked by Apply.
-func (c *Cursor) Replace(n ast.Node) {
- if _, ok := c.node.(*ast.File); ok {
- file, ok := n.(*ast.File)
- if !ok {
- panic("attempt to replace *ast.File with non-*ast.File")
- }
- c.parent.(*ast.Package).Files[c.name] = file
- return
- }
-
- v := c.field()
- if i := c.Index(); i >= 0 {
- v = v.Index(i)
- }
- v.Set(reflect.ValueOf(n))
-}
-
-// Delete deletes the current Node from its containing slice.
-// If the current Node is not part of a slice, Delete panics.
-// As a special case, if the current node is a package file,
-// Delete removes it from the package's Files map.
-func (c *Cursor) Delete() {
- if _, ok := c.node.(*ast.File); ok {
- delete(c.parent.(*ast.Package).Files, c.name)
- return
- }
-
- i := c.Index()
- if i < 0 {
- panic("Delete node not contained in slice")
- }
- v := c.field()
- l := v.Len()
- reflect.Copy(v.Slice(i, l), v.Slice(i+1, l))
- v.Index(l - 1).Set(reflect.Zero(v.Type().Elem()))
- v.SetLen(l - 1)
- c.iter.step--
-}
-
-// InsertAfter inserts n after the current Node in its containing slice.
-// If the current Node is not part of a slice, InsertAfter panics.
-// Apply does not walk n.
-func (c *Cursor) InsertAfter(n ast.Node) {
- i := c.Index()
- if i < 0 {
- panic("InsertAfter node not contained in slice")
- }
- v := c.field()
- v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
- l := v.Len()
- reflect.Copy(v.Slice(i+2, l), v.Slice(i+1, l))
- v.Index(i + 1).Set(reflect.ValueOf(n))
- c.iter.step++
-}
-
-// InsertBefore inserts n before the current Node in its containing slice.
-// If the current Node is not part of a slice, InsertBefore panics.
-// Apply will not walk n.
-func (c *Cursor) InsertBefore(n ast.Node) {
- i := c.Index()
- if i < 0 {
- panic("InsertBefore node not contained in slice")
- }
- v := c.field()
- v.Set(reflect.Append(v, reflect.Zero(v.Type().Elem())))
- l := v.Len()
- reflect.Copy(v.Slice(i+1, l), v.Slice(i, l))
- v.Index(i).Set(reflect.ValueOf(n))
- c.iter.index++
-}
-
-// application carries all the shared data so we can pass it around cheaply.
-type application struct {
- pre, post ApplyFunc
- cursor Cursor
- iter iterator
-}
-
-func (a *application) apply(parent ast.Node, name string, iter *iterator, n ast.Node) {
- // convert typed nil into untyped nil
- if v := reflect.ValueOf(n); v.Kind() == reflect.Ptr && v.IsNil() {
- n = nil
- }
-
- // avoid heap-allocating a new cursor for each apply call; reuse a.cursor instead
- saved := a.cursor
- a.cursor.parent = parent
- a.cursor.name = name
- a.cursor.iter = iter
- a.cursor.node = n
-
- if a.pre != nil && !a.pre(&a.cursor) {
- a.cursor = saved
- return
- }
-
- // walk children
- // (the order of the cases matches the order of the corresponding node types in go/ast)
- switch n := n.(type) {
- case nil:
- // nothing to do
-
- // Comments and fields
- case *ast.Comment:
- // nothing to do
-
- case *ast.CommentGroup:
- if n != nil {
- a.applyList(n, "List")
- }
-
- case *ast.Field:
- a.apply(n, "Doc", nil, n.Doc)
- a.applyList(n, "Names")
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Tag", nil, n.Tag)
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.FieldList:
- a.applyList(n, "List")
-
- // Expressions
- case *ast.BadExpr, *ast.Ident, *ast.BasicLit:
- // nothing to do
-
- case *ast.Ellipsis:
- a.apply(n, "Elt", nil, n.Elt)
-
- case *ast.FuncLit:
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.CompositeLit:
- a.apply(n, "Type", nil, n.Type)
- a.applyList(n, "Elts")
-
- case *ast.ParenExpr:
- a.apply(n, "X", nil, n.X)
-
- case *ast.SelectorExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Sel", nil, n.Sel)
-
- case *ast.IndexExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Index", nil, n.Index)
-
- case *ast.SliceExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Low", nil, n.Low)
- a.apply(n, "High", nil, n.High)
- a.apply(n, "Max", nil, n.Max)
-
- case *ast.TypeAssertExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Type", nil, n.Type)
-
- case *ast.CallExpr:
- a.apply(n, "Fun", nil, n.Fun)
- a.applyList(n, "Args")
-
- case *ast.StarExpr:
- a.apply(n, "X", nil, n.X)
-
- case *ast.UnaryExpr:
- a.apply(n, "X", nil, n.X)
-
- case *ast.BinaryExpr:
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Y", nil, n.Y)
-
- case *ast.KeyValueExpr:
- a.apply(n, "Key", nil, n.Key)
- a.apply(n, "Value", nil, n.Value)
-
- // Types
- case *ast.ArrayType:
- a.apply(n, "Len", nil, n.Len)
- a.apply(n, "Elt", nil, n.Elt)
-
- case *ast.StructType:
- a.apply(n, "Fields", nil, n.Fields)
-
- case *ast.FuncType:
- a.apply(n, "Params", nil, n.Params)
- a.apply(n, "Results", nil, n.Results)
-
- case *ast.InterfaceType:
- a.apply(n, "Methods", nil, n.Methods)
-
- case *ast.MapType:
- a.apply(n, "Key", nil, n.Key)
- a.apply(n, "Value", nil, n.Value)
-
- case *ast.ChanType:
- a.apply(n, "Value", nil, n.Value)
-
- // Statements
- case *ast.BadStmt:
- // nothing to do
-
- case *ast.DeclStmt:
- a.apply(n, "Decl", nil, n.Decl)
-
- case *ast.EmptyStmt:
- // nothing to do
-
- case *ast.LabeledStmt:
- a.apply(n, "Label", nil, n.Label)
- a.apply(n, "Stmt", nil, n.Stmt)
-
- case *ast.ExprStmt:
- a.apply(n, "X", nil, n.X)
-
- case *ast.SendStmt:
- a.apply(n, "Chan", nil, n.Chan)
- a.apply(n, "Value", nil, n.Value)
-
- case *ast.IncDecStmt:
- a.apply(n, "X", nil, n.X)
-
- case *ast.AssignStmt:
- a.applyList(n, "Lhs")
- a.applyList(n, "Rhs")
-
- case *ast.GoStmt:
- a.apply(n, "Call", nil, n.Call)
-
- case *ast.DeferStmt:
- a.apply(n, "Call", nil, n.Call)
-
- case *ast.ReturnStmt:
- a.applyList(n, "Results")
-
- case *ast.BranchStmt:
- a.apply(n, "Label", nil, n.Label)
-
- case *ast.BlockStmt:
- a.applyList(n, "List")
-
- case *ast.IfStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Cond", nil, n.Cond)
- a.apply(n, "Body", nil, n.Body)
- a.apply(n, "Else", nil, n.Else)
-
- case *ast.CaseClause:
- a.applyList(n, "List")
- a.applyList(n, "Body")
-
- case *ast.SwitchStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Tag", nil, n.Tag)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.TypeSwitchStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Assign", nil, n.Assign)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.CommClause:
- a.apply(n, "Comm", nil, n.Comm)
- a.applyList(n, "Body")
-
- case *ast.SelectStmt:
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.ForStmt:
- a.apply(n, "Init", nil, n.Init)
- a.apply(n, "Cond", nil, n.Cond)
- a.apply(n, "Post", nil, n.Post)
- a.apply(n, "Body", nil, n.Body)
-
- case *ast.RangeStmt:
- a.apply(n, "Key", nil, n.Key)
- a.apply(n, "Value", nil, n.Value)
- a.apply(n, "X", nil, n.X)
- a.apply(n, "Body", nil, n.Body)
-
- // Declarations
- case *ast.ImportSpec:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Name", nil, n.Name)
- a.apply(n, "Path", nil, n.Path)
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.ValueSpec:
- a.apply(n, "Doc", nil, n.Doc)
- a.applyList(n, "Names")
- a.apply(n, "Type", nil, n.Type)
- a.applyList(n, "Values")
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.TypeSpec:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Name", nil, n.Name)
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Comment", nil, n.Comment)
-
- case *ast.BadDecl:
- // nothing to do
-
- case *ast.GenDecl:
- a.apply(n, "Doc", nil, n.Doc)
- a.applyList(n, "Specs")
-
- case *ast.FuncDecl:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Recv", nil, n.Recv)
- a.apply(n, "Name", nil, n.Name)
- a.apply(n, "Type", nil, n.Type)
- a.apply(n, "Body", nil, n.Body)
-
- // Files and packages
- case *ast.File:
- a.apply(n, "Doc", nil, n.Doc)
- a.apply(n, "Name", nil, n.Name)
- a.applyList(n, "Decls")
- // Don't walk n.Comments; they have either been walked already if
- // they are Doc comments, or they can be easily walked explicitly.
-
- case *ast.Package:
- // collect and sort names for reproducible behavior
- var names []string
- for name := range n.Files {
- names = append(names, name)
- }
- sort.Strings(names)
- for _, name := range names {
- a.apply(n, name, nil, n.Files[name])
- }
-
- default:
- panic(fmt.Sprintf("Apply: unexpected node type %T", n))
- }
-
- if a.post != nil && !a.post(&a.cursor) {
- panic(abort)
- }
-
- a.cursor = saved
-}
-
-// An iterator controls iteration over a slice of nodes.
-type iterator struct {
- index, step int
-}
-
-func (a *application) applyList(parent ast.Node, name string) {
- // avoid heap-allocating a new iterator for each applyList call; reuse a.iter instead
- saved := a.iter
- a.iter.index = 0
- for {
- // must reload parent.name each time, since cursor modifications might change it
- v := reflect.Indirect(reflect.ValueOf(parent)).FieldByName(name)
- if a.iter.index >= v.Len() {
- break
- }
-
- // element x may be nil in a bad AST - be cautious
- var x ast.Node
- if e := v.Index(a.iter.index); e.IsValid() {
- x = e.Interface().(ast.Node)
- }
-
- a.iter.step = 1
- a.apply(parent, name, &a.iter, x)
- a.iter.index += a.iter.step
- }
- a.iter = saved
-}
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/util.go b/vendor/golang.org/x/tools/go/ast/astutil/util.go
deleted file mode 100644
index 763062982..000000000
--- a/vendor/golang.org/x/tools/go/ast/astutil/util.go
+++ /dev/null
@@ -1,14 +0,0 @@
-package astutil
-
-import "go/ast"
-
-// Unparen returns e with any enclosing parentheses stripped.
-func Unparen(e ast.Expr) ast.Expr {
- for {
- p, ok := e.(*ast.ParenExpr)
- if !ok {
- return e
- }
- e = p.X
- }
-}
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/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
deleted file mode 100644
index f8363d8fa..000000000
--- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go
+++ /dev/null
@@ -1,109 +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 gcexportdata provides functions for locating, reading, and
-// writing export data files containing type information produced by the
-// gc compiler. This package supports go1.7 export data format and all
-// later versions.
-//
-// Although it might seem convenient for this package to live alongside
-// go/types in the standard library, this would cause version skew
-// problems for developer tools that use it, since they must be able to
-// consume the outputs of the gc compiler both before and after a Go
-// update such as from Go 1.7 to Go 1.8. Because this package lives in
-// golang.org/x/tools, sites can update their version of this repo some
-// time before the Go 1.8 release and rebuild and redeploy their
-// developer tools, which will then be able to consume both Go 1.7 and
-// Go 1.8 export data files, so they will work before and after the
-// Go update. (See discussion at https://golang.org/issue/15651.)
-//
-package gcexportdata // import "golang.org/x/tools/go/gcexportdata"
-
-import (
- "bufio"
- "bytes"
- "fmt"
- "go/token"
- "go/types"
- "io"
- "io/ioutil"
-
- "golang.org/x/tools/go/internal/gcimporter"
-)
-
-// Find returns the name of an object (.o) or archive (.a) file
-// containing type information for the specified import path,
-// using the workspace layout conventions of go/build.
-// If no file was found, an empty filename is returned.
-//
-// A relative srcDir is interpreted relative to the current working directory.
-//
-// Find also returns the package's resolved (canonical) import path,
-// reflecting the effects of srcDir and vendoring on importPath.
-func Find(importPath, srcDir string) (filename, path string) {
- return gcimporter.FindPkg(importPath, srcDir)
-}
-
-// NewReader returns a reader for the export data section of an object
-// (.o) or archive (.a) file read from r. The new reader may provide
-// additional trailing data beyond the end of the export data.
-func NewReader(r io.Reader) (io.Reader, error) {
- buf := bufio.NewReader(r)
- _, err := gcimporter.FindExportData(buf)
- // If we ever switch to a zip-like archive format with the ToC
- // at the end, we can return the correct portion of export data,
- // but for now we must return the entire rest of the file.
- return buf, err
-}
-
-// Read reads export data from in, decodes it, and returns type
-// information for the package.
-// The package name is specified by path.
-// File position information is added to fset.
-//
-// Read may inspect and add to the imports map to ensure that references
-// within the export data to other packages are consistent. The caller
-// must ensure that imports[path] does not exist, or exists but is
-// incomplete (see types.Package.Complete), and Read inserts the
-// resulting package into this map entry.
-//
-// On return, the state of the reader is undefined.
-func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) {
- data, err := ioutil.ReadAll(in)
- if err != nil {
- return nil, fmt.Errorf("reading export data for %q: %v", path, err)
- }
-
- if bytes.HasPrefix(data, []byte("!")) {
- return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path)
- }
-
- // The App Engine Go runtime v1.6 uses the old export data format.
- // TODO(adonovan): delete once v1.7 has been around for a while.
- if bytes.HasPrefix(data, []byte("package ")) {
- return gcimporter.ImportData(imports, path, path, bytes.NewReader(data))
- }
-
- // The indexed export format starts with an 'i'; the older
- // binary export format starts with a 'c', 'd', or 'v'
- // (from "version"). Select appropriate importer.
- if len(data) > 0 && data[0] == 'i' {
- _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path)
- return pkg, err
- }
-
- _, pkg, err := gcimporter.BImportData(fset, imports, data, path)
- return pkg, err
-}
-
-// Write writes encoded type information for the specified package to out.
-// The FileSet provides file position information for named objects.
-func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error {
- b, err := gcimporter.IExportData(fset, pkg)
- if err != nil {
- return err
- }
- _, err = out.Write(b)
- return err
-}
diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go
deleted file mode 100644
index efe221e7e..000000000
--- a/vendor/golang.org/x/tools/go/gcexportdata/importer.go
+++ /dev/null
@@ -1,73 +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 gcexportdata
-
-import (
- "fmt"
- "go/token"
- "go/types"
- "os"
-)
-
-// NewImporter returns a new instance of the types.Importer interface
-// that reads type information from export data files written by gc.
-// The Importer also satisfies types.ImporterFrom.
-//
-// Export data files are located using "go build" workspace conventions
-// and the build.Default context.
-//
-// Use this importer instead of go/importer.For("gc", ...) to avoid the
-// version-skew problems described in the documentation of this package,
-// or to control the FileSet or access the imports map populated during
-// package loading.
-//
-func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom {
- return importer{fset, imports}
-}
-
-type importer struct {
- fset *token.FileSet
- imports map[string]*types.Package
-}
-
-func (imp importer) Import(importPath string) (*types.Package, error) {
- return imp.ImportFrom(importPath, "", 0)
-}
-
-func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) {
- filename, path := Find(importPath, srcDir)
- if filename == "" {
- if importPath == "unsafe" {
- // Even for unsafe, call Find first in case
- // the package was vendored.
- return types.Unsafe, nil
- }
- return nil, fmt.Errorf("can't find import: %s", importPath)
- }
-
- if pkg, ok := imp.imports[path]; ok && pkg.Complete() {
- return pkg, nil // cache hit
- }
-
- // open file
- f, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer func() {
- f.Close()
- if err != nil {
- // add file name to error
- err = fmt.Errorf("reading export data: %s: %v", filename, err)
- }
- }()
-
- r, err := NewReader(f)
- if err != nil {
- return nil, err
- }
-
- return Read(r, imp.fset, imp.imports, path)
-}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
deleted file mode 100644
index a807d0aaa..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/bexport.go
+++ /dev/null
@@ -1,852 +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.
-
-// Binary package export.
-// This file was derived from $GOROOT/src/cmd/compile/internal/gc/bexport.go;
-// see that file for specification of the format.
-
-package gcimporter
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- "go/types"
- "math"
- "math/big"
- "sort"
- "strings"
-)
-
-// If debugFormat is set, each integer and string value is preceded by a marker
-// and position information in the encoding. This mechanism permits an importer
-// to recognize immediately when it is out of sync. The importer recognizes this
-// mode automatically (i.e., it can import export data produced with debugging
-// support even if debugFormat is not set at the time of import). This mode will
-// lead to massively larger export data (by a factor of 2 to 3) and should only
-// be enabled during development and debugging.
-//
-// NOTE: This flag is the first flag to enable if importing dies because of
-// (suspected) format errors, and whenever a change is made to the format.
-const debugFormat = false // default: false
-
-// If trace is set, debugging output is printed to std out.
-const trace = false // default: false
-
-// Current export format version. Increase with each format change.
-// Note: The latest binary (non-indexed) export format is at version 6.
-// This exporter is still at level 4, but it doesn't matter since
-// the binary importer can handle older versions just fine.
-// 6: package height (CL 105038) -- NOT IMPLEMENTED HERE
-// 5: improved position encoding efficiency (issue 20080, CL 41619) -- NOT IMPLEMEMTED HERE
-// 4: type name objects support type aliases, uses aliasTag
-// 3: Go1.8 encoding (same as version 2, aliasTag defined but never used)
-// 2: removed unused bool in ODCL export (compiler only)
-// 1: header format change (more regular), export package for _ struct fields
-// 0: Go1.7 encoding
-const exportVersion = 4
-
-// trackAllTypes enables cycle tracking for all types, not just named
-// types. The existing compiler invariants assume that unnamed types
-// that are not completely set up are not used, or else there are spurious
-// errors.
-// If disabled, only named types are tracked, possibly leading to slightly
-// less efficient encoding in rare cases. It also prevents the export of
-// some corner-case type declarations (but those are not handled correctly
-// with with the textual export format either).
-// TODO(gri) enable and remove once issues caused by it are fixed
-const trackAllTypes = false
-
-type exporter struct {
- fset *token.FileSet
- out bytes.Buffer
-
- // object -> index maps, indexed in order of serialization
- strIndex map[string]int
- pkgIndex map[*types.Package]int
- typIndex map[types.Type]int
-
- // position encoding
- posInfoFormat bool
- prevFile string
- prevLine int
-
- // debugging support
- written int // bytes written
- indent int // for trace
-}
-
-// internalError represents an error generated inside this package.
-type internalError string
-
-func (e internalError) Error() string { return "gcimporter: " + string(e) }
-
-func internalErrorf(format string, args ...interface{}) error {
- return internalError(fmt.Sprintf(format, args...))
-}
-
-// BExportData returns binary export data for pkg.
-// If no file set is provided, position info will be missing.
-func BExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
- defer func() {
- if e := recover(); e != nil {
- if ierr, ok := e.(internalError); ok {
- err = ierr
- return
- }
- // Not an internal error; panic again.
- panic(e)
- }
- }()
-
- p := exporter{
- fset: fset,
- strIndex: map[string]int{"": 0}, // empty string is mapped to 0
- pkgIndex: make(map[*types.Package]int),
- typIndex: make(map[types.Type]int),
- posInfoFormat: true, // TODO(gri) might become a flag, eventually
- }
-
- // write version info
- // The version string must start with "version %d" where %d is the version
- // number. Additional debugging information may follow after a blank; that
- // text is ignored by the importer.
- p.rawStringln(fmt.Sprintf("version %d", exportVersion))
- var debug string
- if debugFormat {
- debug = "debug"
- }
- p.rawStringln(debug) // cannot use p.bool since it's affected by debugFormat; also want to see this clearly
- p.bool(trackAllTypes)
- p.bool(p.posInfoFormat)
-
- // --- generic export data ---
-
- // populate type map with predeclared "known" types
- for index, typ := range predeclared() {
- p.typIndex[typ] = index
- }
- if len(p.typIndex) != len(predeclared()) {
- return nil, internalError("duplicate entries in type map?")
- }
-
- // write package data
- p.pkg(pkg, true)
- if trace {
- p.tracef("\n")
- }
-
- // write objects
- objcount := 0
- scope := pkg.Scope()
- for _, name := range scope.Names() {
- if !ast.IsExported(name) {
- continue
- }
- if trace {
- p.tracef("\n")
- }
- p.obj(scope.Lookup(name))
- objcount++
- }
-
- // indicate end of list
- if trace {
- p.tracef("\n")
- }
- p.tag(endTag)
-
- // for self-verification only (redundant)
- p.int(objcount)
-
- if trace {
- p.tracef("\n")
- }
-
- // --- end of export data ---
-
- return p.out.Bytes(), nil
-}
-
-func (p *exporter) pkg(pkg *types.Package, emptypath bool) {
- if pkg == nil {
- panic(internalError("unexpected nil pkg"))
- }
-
- // if we saw the package before, write its index (>= 0)
- if i, ok := p.pkgIndex[pkg]; ok {
- p.index('P', i)
- return
- }
-
- // otherwise, remember the package, write the package tag (< 0) and package data
- if trace {
- p.tracef("P%d = { ", len(p.pkgIndex))
- defer p.tracef("} ")
- }
- p.pkgIndex[pkg] = len(p.pkgIndex)
-
- p.tag(packageTag)
- p.string(pkg.Name())
- if emptypath {
- p.string("")
- } else {
- p.string(pkg.Path())
- }
-}
-
-func (p *exporter) obj(obj types.Object) {
- switch obj := obj.(type) {
- case *types.Const:
- p.tag(constTag)
- p.pos(obj)
- p.qualifiedName(obj)
- p.typ(obj.Type())
- p.value(obj.Val())
-
- case *types.TypeName:
- if obj.IsAlias() {
- p.tag(aliasTag)
- p.pos(obj)
- p.qualifiedName(obj)
- } else {
- p.tag(typeTag)
- }
- p.typ(obj.Type())
-
- case *types.Var:
- p.tag(varTag)
- p.pos(obj)
- p.qualifiedName(obj)
- p.typ(obj.Type())
-
- case *types.Func:
- p.tag(funcTag)
- p.pos(obj)
- p.qualifiedName(obj)
- sig := obj.Type().(*types.Signature)
- p.paramList(sig.Params(), sig.Variadic())
- p.paramList(sig.Results(), false)
-
- default:
- panic(internalErrorf("unexpected object %v (%T)", obj, obj))
- }
-}
-
-func (p *exporter) pos(obj types.Object) {
- if !p.posInfoFormat {
- return
- }
-
- file, line := p.fileLine(obj)
- if file == p.prevFile {
- // common case: write line delta
- // delta == 0 means different file or no line change
- delta := line - p.prevLine
- p.int(delta)
- if delta == 0 {
- p.int(-1) // -1 means no file change
- }
- } else {
- // different file
- p.int(0)
- // Encode filename as length of common prefix with previous
- // filename, followed by (possibly empty) suffix. Filenames
- // frequently share path prefixes, so this can save a lot
- // of space and make export data size less dependent on file
- // path length. The suffix is unlikely to be empty because
- // file names tend to end in ".go".
- n := commonPrefixLen(p.prevFile, file)
- p.int(n) // n >= 0
- p.string(file[n:]) // write suffix only
- p.prevFile = file
- p.int(line)
- }
- p.prevLine = line
-}
-
-func (p *exporter) fileLine(obj types.Object) (file string, line int) {
- if p.fset != nil {
- pos := p.fset.Position(obj.Pos())
- file = pos.Filename
- line = pos.Line
- }
- return
-}
-
-func commonPrefixLen(a, b string) int {
- if len(a) > len(b) {
- a, b = b, a
- }
- // len(a) <= len(b)
- i := 0
- for i < len(a) && a[i] == b[i] {
- i++
- }
- return i
-}
-
-func (p *exporter) qualifiedName(obj types.Object) {
- p.string(obj.Name())
- p.pkg(obj.Pkg(), false)
-}
-
-func (p *exporter) typ(t types.Type) {
- if t == nil {
- panic(internalError("nil type"))
- }
-
- // Possible optimization: Anonymous pointer types *T where
- // T is a named type are common. We could canonicalize all
- // such types *T to a single type PT = *T. This would lead
- // to at most one *T entry in typIndex, and all future *T's
- // would be encoded as the respective index directly. Would
- // save 1 byte (pointerTag) per *T and reduce the typIndex
- // size (at the cost of a canonicalization map). We can do
- // this later, without encoding format change.
-
- // if we saw the type before, write its index (>= 0)
- if i, ok := p.typIndex[t]; ok {
- p.index('T', i)
- return
- }
-
- // otherwise, remember the type, write the type tag (< 0) and type data
- if trackAllTypes {
- if trace {
- p.tracef("T%d = {>\n", len(p.typIndex))
- defer p.tracef("<\n} ")
- }
- p.typIndex[t] = len(p.typIndex)
- }
-
- switch t := t.(type) {
- case *types.Named:
- if !trackAllTypes {
- // if we don't track all types, track named types now
- p.typIndex[t] = len(p.typIndex)
- }
-
- p.tag(namedTag)
- p.pos(t.Obj())
- p.qualifiedName(t.Obj())
- p.typ(t.Underlying())
- if !types.IsInterface(t) {
- p.assocMethods(t)
- }
-
- case *types.Array:
- p.tag(arrayTag)
- p.int64(t.Len())
- p.typ(t.Elem())
-
- case *types.Slice:
- p.tag(sliceTag)
- p.typ(t.Elem())
-
- case *dddSlice:
- p.tag(dddTag)
- p.typ(t.elem)
-
- case *types.Struct:
- p.tag(structTag)
- p.fieldList(t)
-
- case *types.Pointer:
- p.tag(pointerTag)
- p.typ(t.Elem())
-
- case *types.Signature:
- p.tag(signatureTag)
- p.paramList(t.Params(), t.Variadic())
- p.paramList(t.Results(), false)
-
- case *types.Interface:
- p.tag(interfaceTag)
- p.iface(t)
-
- case *types.Map:
- p.tag(mapTag)
- p.typ(t.Key())
- p.typ(t.Elem())
-
- case *types.Chan:
- p.tag(chanTag)
- p.int(int(3 - t.Dir())) // hack
- p.typ(t.Elem())
-
- default:
- panic(internalErrorf("unexpected type %T: %s", t, t))
- }
-}
-
-func (p *exporter) assocMethods(named *types.Named) {
- // Sort methods (for determinism).
- var methods []*types.Func
- for i := 0; i < named.NumMethods(); i++ {
- methods = append(methods, named.Method(i))
- }
- sort.Sort(methodsByName(methods))
-
- p.int(len(methods))
-
- if trace && methods != nil {
- p.tracef("associated methods {>\n")
- }
-
- for i, m := range methods {
- if trace && i > 0 {
- p.tracef("\n")
- }
-
- p.pos(m)
- name := m.Name()
- p.string(name)
- if !exported(name) {
- p.pkg(m.Pkg(), false)
- }
-
- sig := m.Type().(*types.Signature)
- p.paramList(types.NewTuple(sig.Recv()), false)
- p.paramList(sig.Params(), sig.Variadic())
- p.paramList(sig.Results(), false)
- p.int(0) // dummy value for go:nointerface pragma - ignored by importer
- }
-
- if trace && methods != nil {
- p.tracef("<\n} ")
- }
-}
-
-type methodsByName []*types.Func
-
-func (x methodsByName) Len() int { return len(x) }
-func (x methodsByName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x methodsByName) Less(i, j int) bool { return x[i].Name() < x[j].Name() }
-
-func (p *exporter) fieldList(t *types.Struct) {
- if trace && t.NumFields() > 0 {
- p.tracef("fields {>\n")
- defer p.tracef("<\n} ")
- }
-
- p.int(t.NumFields())
- for i := 0; i < t.NumFields(); i++ {
- if trace && i > 0 {
- p.tracef("\n")
- }
- p.field(t.Field(i))
- p.string(t.Tag(i))
- }
-}
-
-func (p *exporter) field(f *types.Var) {
- if !f.IsField() {
- panic(internalError("field expected"))
- }
-
- p.pos(f)
- p.fieldName(f)
- p.typ(f.Type())
-}
-
-func (p *exporter) iface(t *types.Interface) {
- // TODO(gri): enable importer to load embedded interfaces,
- // then emit Embeddeds and ExplicitMethods separately here.
- p.int(0)
-
- n := t.NumMethods()
- if trace && n > 0 {
- p.tracef("methods {>\n")
- defer p.tracef("<\n} ")
- }
- p.int(n)
- for i := 0; i < n; i++ {
- if trace && i > 0 {
- p.tracef("\n")
- }
- p.method(t.Method(i))
- }
-}
-
-func (p *exporter) method(m *types.Func) {
- sig := m.Type().(*types.Signature)
- if sig.Recv() == nil {
- panic(internalError("method expected"))
- }
-
- p.pos(m)
- p.string(m.Name())
- if m.Name() != "_" && !ast.IsExported(m.Name()) {
- p.pkg(m.Pkg(), false)
- }
-
- // interface method; no need to encode receiver.
- p.paramList(sig.Params(), sig.Variadic())
- p.paramList(sig.Results(), false)
-}
-
-func (p *exporter) fieldName(f *types.Var) {
- name := f.Name()
-
- if f.Anonymous() {
- // anonymous field - we distinguish between 3 cases:
- // 1) field name matches base type name and is exported
- // 2) field name matches base type name and is not exported
- // 3) field name doesn't match base type name (alias name)
- bname := basetypeName(f.Type())
- if name == bname {
- if ast.IsExported(name) {
- name = "" // 1) we don't need to know the field name or package
- } else {
- name = "?" // 2) use unexported name "?" to force package export
- }
- } else {
- // 3) indicate alias and export name as is
- // (this requires an extra "@" but this is a rare case)
- p.string("@")
- }
- }
-
- p.string(name)
- if name != "" && !ast.IsExported(name) {
- p.pkg(f.Pkg(), false)
- }
-}
-
-func basetypeName(typ types.Type) string {
- switch typ := deref(typ).(type) {
- case *types.Basic:
- return typ.Name()
- case *types.Named:
- return typ.Obj().Name()
- default:
- return "" // unnamed type
- }
-}
-
-func (p *exporter) paramList(params *types.Tuple, variadic bool) {
- // use negative length to indicate unnamed parameters
- // (look at the first parameter only since either all
- // names are present or all are absent)
- n := params.Len()
- if n > 0 && params.At(0).Name() == "" {
- n = -n
- }
- p.int(n)
- for i := 0; i < params.Len(); i++ {
- q := params.At(i)
- t := q.Type()
- if variadic && i == params.Len()-1 {
- t = &dddSlice{t.(*types.Slice).Elem()}
- }
- p.typ(t)
- if n > 0 {
- name := q.Name()
- p.string(name)
- if name != "_" {
- p.pkg(q.Pkg(), false)
- }
- }
- p.string("") // no compiler-specific info
- }
-}
-
-func (p *exporter) value(x constant.Value) {
- if trace {
- p.tracef("= ")
- }
-
- switch x.Kind() {
- case constant.Bool:
- tag := falseTag
- if constant.BoolVal(x) {
- tag = trueTag
- }
- p.tag(tag)
-
- case constant.Int:
- if v, exact := constant.Int64Val(x); exact {
- // common case: x fits into an int64 - use compact encoding
- p.tag(int64Tag)
- p.int64(v)
- return
- }
- // uncommon case: large x - use float encoding
- // (powers of 2 will be encoded efficiently with exponent)
- p.tag(floatTag)
- p.float(constant.ToFloat(x))
-
- case constant.Float:
- p.tag(floatTag)
- p.float(x)
-
- case constant.Complex:
- p.tag(complexTag)
- p.float(constant.Real(x))
- p.float(constant.Imag(x))
-
- case constant.String:
- p.tag(stringTag)
- p.string(constant.StringVal(x))
-
- case constant.Unknown:
- // package contains type errors
- p.tag(unknownTag)
-
- default:
- panic(internalErrorf("unexpected value %v (%T)", x, x))
- }
-}
-
-func (p *exporter) float(x constant.Value) {
- if x.Kind() != constant.Float {
- panic(internalErrorf("unexpected constant %v, want float", x))
- }
- // extract sign (there is no -0)
- sign := constant.Sign(x)
- if sign == 0 {
- // x == 0
- p.int(0)
- return
- }
- // x != 0
-
- var f big.Float
- if v, exact := constant.Float64Val(x); exact {
- // float64
- f.SetFloat64(v)
- } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
- // TODO(gri): add big.Rat accessor to constant.Value.
- r := valueToRat(num)
- f.SetRat(r.Quo(r, valueToRat(denom)))
- } else {
- // Value too large to represent as a fraction => inaccessible.
- // TODO(gri): add big.Float accessor to constant.Value.
- f.SetFloat64(math.MaxFloat64) // FIXME
- }
-
- // extract exponent such that 0.5 <= m < 1.0
- var m big.Float
- exp := f.MantExp(&m)
-
- // extract mantissa as *big.Int
- // - set exponent large enough so mant satisfies mant.IsInt()
- // - get *big.Int from mant
- m.SetMantExp(&m, int(m.MinPrec()))
- mant, acc := m.Int(nil)
- if acc != big.Exact {
- panic(internalError("internal error"))
- }
-
- p.int(sign)
- p.int(exp)
- p.string(string(mant.Bytes()))
-}
-
-func valueToRat(x constant.Value) *big.Rat {
- // Convert little-endian to big-endian.
- // I can't believe this is necessary.
- bytes := constant.Bytes(x)
- for i := 0; i < len(bytes)/2; i++ {
- bytes[i], bytes[len(bytes)-1-i] = bytes[len(bytes)-1-i], bytes[i]
- }
- return new(big.Rat).SetInt(new(big.Int).SetBytes(bytes))
-}
-
-func (p *exporter) bool(b bool) bool {
- if trace {
- p.tracef("[")
- defer p.tracef("= %v] ", b)
- }
-
- x := 0
- if b {
- x = 1
- }
- p.int(x)
- return b
-}
-
-// ----------------------------------------------------------------------------
-// Low-level encoders
-
-func (p *exporter) index(marker byte, index int) {
- if index < 0 {
- panic(internalError("invalid index < 0"))
- }
- if debugFormat {
- p.marker('t')
- }
- if trace {
- p.tracef("%c%d ", marker, index)
- }
- p.rawInt64(int64(index))
-}
-
-func (p *exporter) tag(tag int) {
- if tag >= 0 {
- panic(internalError("invalid tag >= 0"))
- }
- if debugFormat {
- p.marker('t')
- }
- if trace {
- p.tracef("%s ", tagString[-tag])
- }
- p.rawInt64(int64(tag))
-}
-
-func (p *exporter) int(x int) {
- p.int64(int64(x))
-}
-
-func (p *exporter) int64(x int64) {
- if debugFormat {
- p.marker('i')
- }
- if trace {
- p.tracef("%d ", x)
- }
- p.rawInt64(x)
-}
-
-func (p *exporter) string(s string) {
- if debugFormat {
- p.marker('s')
- }
- if trace {
- p.tracef("%q ", s)
- }
- // if we saw the string before, write its index (>= 0)
- // (the empty string is mapped to 0)
- if i, ok := p.strIndex[s]; ok {
- p.rawInt64(int64(i))
- return
- }
- // otherwise, remember string and write its negative length and bytes
- p.strIndex[s] = len(p.strIndex)
- p.rawInt64(-int64(len(s)))
- for i := 0; i < len(s); i++ {
- p.rawByte(s[i])
- }
-}
-
-// marker emits a marker byte and position information which makes
-// it easy for a reader to detect if it is "out of sync". Used for
-// debugFormat format only.
-func (p *exporter) marker(m byte) {
- p.rawByte(m)
- // Enable this for help tracking down the location
- // of an incorrect marker when running in debugFormat.
- if false && trace {
- p.tracef("#%d ", p.written)
- }
- p.rawInt64(int64(p.written))
-}
-
-// rawInt64 should only be used by low-level encoders.
-func (p *exporter) rawInt64(x int64) {
- var tmp [binary.MaxVarintLen64]byte
- n := binary.PutVarint(tmp[:], x)
- for i := 0; i < n; i++ {
- p.rawByte(tmp[i])
- }
-}
-
-// rawStringln should only be used to emit the initial version string.
-func (p *exporter) rawStringln(s string) {
- for i := 0; i < len(s); i++ {
- p.rawByte(s[i])
- }
- p.rawByte('\n')
-}
-
-// rawByte is the bottleneck interface to write to p.out.
-// rawByte escapes b as follows (any encoding does that
-// hides '$'):
-//
-// '$' => '|' 'S'
-// '|' => '|' '|'
-//
-// Necessary so other tools can find the end of the
-// export data by searching for "$$".
-// rawByte should only be used by low-level encoders.
-func (p *exporter) rawByte(b byte) {
- switch b {
- case '$':
- // write '$' as '|' 'S'
- b = 'S'
- fallthrough
- case '|':
- // write '|' as '|' '|'
- p.out.WriteByte('|')
- p.written++
- }
- p.out.WriteByte(b)
- p.written++
-}
-
-// tracef is like fmt.Printf but it rewrites the format string
-// to take care of indentation.
-func (p *exporter) tracef(format string, args ...interface{}) {
- if strings.ContainsAny(format, "<>\n") {
- var buf bytes.Buffer
- for i := 0; i < len(format); i++ {
- // no need to deal with runes
- ch := format[i]
- switch ch {
- case '>':
- p.indent++
- continue
- case '<':
- p.indent--
- continue
- }
- buf.WriteByte(ch)
- if ch == '\n' {
- for j := p.indent; j > 0; j-- {
- buf.WriteString(". ")
- }
- }
- }
- format = buf.String()
- }
- fmt.Printf(format, args...)
-}
-
-// Debugging support.
-// (tagString is only used when tracing is enabled)
-var tagString = [...]string{
- // Packages
- -packageTag: "package",
-
- // Types
- -namedTag: "named type",
- -arrayTag: "array",
- -sliceTag: "slice",
- -dddTag: "ddd",
- -structTag: "struct",
- -pointerTag: "pointer",
- -signatureTag: "signature",
- -interfaceTag: "interface",
- -mapTag: "map",
- -chanTag: "chan",
-
- // Values
- -falseTag: "false",
- -trueTag: "true",
- -int64Tag: "int64",
- -floatTag: "float",
- -fractionTag: "fraction",
- -complexTag: "complex",
- -stringTag: "string",
- -unknownTag: "unknown",
-
- // Type aliases
- -aliasTag: "alias",
-}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
deleted file mode 100644
index e9f73d14a..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/bimport.go
+++ /dev/null
@@ -1,1039 +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.
-
-// This file is a copy of $GOROOT/src/go/internal/gcimporter/bimport.go.
-
-package gcimporter
-
-import (
- "encoding/binary"
- "fmt"
- "go/constant"
- "go/token"
- "go/types"
- "sort"
- "strconv"
- "strings"
- "sync"
- "unicode"
- "unicode/utf8"
-)
-
-type importer struct {
- imports map[string]*types.Package
- data []byte
- importpath string
- buf []byte // for reading strings
- version int // export format version
-
- // object lists
- strList []string // in order of appearance
- pathList []string // in order of appearance
- pkgList []*types.Package // in order of appearance
- typList []types.Type // in order of appearance
- interfaceList []*types.Interface // for delayed completion only
- trackAllTypes bool
-
- // position encoding
- posInfoFormat bool
- prevFile string
- prevLine int
- fake fakeFileSet
-
- // debugging support
- debugFormat bool
- read int // bytes read
-}
-
-// BImportData imports a package from the serialized package data
-// and returns the number of bytes consumed and a reference to the package.
-// If the export data version is not recognized or the format is otherwise
-// compromised, an error is returned.
-func BImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
- // catch panics and return them as errors
- const currentVersion = 6
- version := -1 // unknown version
- defer func() {
- if e := recover(); e != nil {
- // Return a (possibly nil or incomplete) package unchanged (see #16088).
- if version > currentVersion {
- err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
- } else {
- err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
- }
- }
- }()
-
- p := importer{
- imports: imports,
- data: data,
- importpath: path,
- version: version,
- strList: []string{""}, // empty string is mapped to 0
- pathList: []string{""}, // empty string is mapped to 0
- fake: fakeFileSet{
- fset: fset,
- files: make(map[string]*token.File),
- },
- }
-
- // read version info
- var versionstr string
- if b := p.rawByte(); b == 'c' || b == 'd' {
- // Go1.7 encoding; first byte encodes low-level
- // encoding format (compact vs debug).
- // For backward-compatibility only (avoid problems with
- // old installed packages). Newly compiled packages use
- // the extensible format string.
- // TODO(gri) Remove this support eventually; after Go1.8.
- if b == 'd' {
- p.debugFormat = true
- }
- p.trackAllTypes = p.rawByte() == 'a'
- p.posInfoFormat = p.int() != 0
- versionstr = p.string()
- if versionstr == "v1" {
- version = 0
- }
- } else {
- // Go1.8 extensible encoding
- // read version string and extract version number (ignore anything after the version number)
- versionstr = p.rawStringln(b)
- if s := strings.SplitN(versionstr, " ", 3); len(s) >= 2 && s[0] == "version" {
- if v, err := strconv.Atoi(s[1]); err == nil && v > 0 {
- version = v
- }
- }
- }
- p.version = version
-
- // read version specific flags - extend as necessary
- switch p.version {
- // case currentVersion:
- // ...
- // fallthrough
- case currentVersion, 5, 4, 3, 2, 1:
- p.debugFormat = p.rawStringln(p.rawByte()) == "debug"
- p.trackAllTypes = p.int() != 0
- p.posInfoFormat = p.int() != 0
- case 0:
- // Go1.7 encoding format - nothing to do here
- default:
- errorf("unknown bexport format version %d (%q)", p.version, versionstr)
- }
-
- // --- generic export data ---
-
- // populate typList with predeclared "known" types
- p.typList = append(p.typList, predeclared()...)
-
- // read package data
- pkg = p.pkg()
-
- // read objects of phase 1 only (see cmd/compile/internal/gc/bexport.go)
- objcount := 0
- for {
- tag := p.tagOrIndex()
- if tag == endTag {
- break
- }
- p.obj(tag)
- objcount++
- }
-
- // self-verification
- if count := p.int(); count != objcount {
- errorf("got %d objects; want %d", objcount, count)
- }
-
- // ignore compiler-specific import data
-
- // complete interfaces
- // TODO(gri) re-investigate if we still need to do this in a delayed fashion
- for _, typ := range p.interfaceList {
- typ.Complete()
- }
-
- // record all referenced packages as imports
- list := append(([]*types.Package)(nil), p.pkgList[1:]...)
- sort.Sort(byPath(list))
- pkg.SetImports(list)
-
- // package was imported completely and without errors
- pkg.MarkComplete()
-
- return p.read, pkg, nil
-}
-
-func errorf(format string, args ...interface{}) {
- panic(fmt.Sprintf(format, args...))
-}
-
-func (p *importer) pkg() *types.Package {
- // if the package was seen before, i is its index (>= 0)
- i := p.tagOrIndex()
- if i >= 0 {
- return p.pkgList[i]
- }
-
- // otherwise, i is the package tag (< 0)
- if i != packageTag {
- errorf("unexpected package tag %d version %d", i, p.version)
- }
-
- // read package data
- name := p.string()
- var path string
- if p.version >= 5 {
- path = p.path()
- } else {
- path = p.string()
- }
- if p.version >= 6 {
- p.int() // package height; unused by go/types
- }
-
- // we should never see an empty package name
- if name == "" {
- errorf("empty package name in import")
- }
-
- // an empty path denotes the package we are currently importing;
- // it must be the first package we see
- if (path == "") != (len(p.pkgList) == 0) {
- errorf("package path %q for pkg index %d", path, len(p.pkgList))
- }
-
- // if the package was imported before, use that one; otherwise create a new one
- if path == "" {
- path = p.importpath
- }
- pkg := p.imports[path]
- if pkg == nil {
- pkg = types.NewPackage(path, name)
- p.imports[path] = pkg
- } else if pkg.Name() != name {
- errorf("conflicting names %s and %s for package %q", pkg.Name(), name, path)
- }
- p.pkgList = append(p.pkgList, pkg)
-
- return pkg
-}
-
-// objTag returns the tag value for each object kind.
-func objTag(obj types.Object) int {
- switch obj.(type) {
- case *types.Const:
- return constTag
- case *types.TypeName:
- return typeTag
- case *types.Var:
- return varTag
- case *types.Func:
- return funcTag
- default:
- errorf("unexpected object: %v (%T)", obj, obj) // panics
- panic("unreachable")
- }
-}
-
-func sameObj(a, b types.Object) bool {
- // Because unnamed types are not canonicalized, we cannot simply compare types for
- // (pointer) identity.
- // Ideally we'd check equality of constant values as well, but this is good enough.
- return objTag(a) == objTag(b) && types.Identical(a.Type(), b.Type())
-}
-
-func (p *importer) declare(obj types.Object) {
- pkg := obj.Pkg()
- if alt := pkg.Scope().Insert(obj); alt != nil {
- // This can only trigger if we import a (non-type) object a second time.
- // Excluding type aliases, this cannot happen because 1) we only import a package
- // once; and b) we ignore compiler-specific export data which may contain
- // functions whose inlined function bodies refer to other functions that
- // were already imported.
- // However, type aliases require reexporting the original type, so we need
- // to allow it (see also the comment in cmd/compile/internal/gc/bimport.go,
- // method importer.obj, switch case importing functions).
- // TODO(gri) review/update this comment once the gc compiler handles type aliases.
- if !sameObj(obj, alt) {
- errorf("inconsistent import:\n\t%v\npreviously imported as:\n\t%v\n", obj, alt)
- }
- }
-}
-
-func (p *importer) obj(tag int) {
- switch tag {
- case constTag:
- pos := p.pos()
- pkg, name := p.qualifiedName()
- typ := p.typ(nil, nil)
- val := p.value()
- p.declare(types.NewConst(pos, pkg, name, typ, val))
-
- case aliasTag:
- // TODO(gri) verify type alias hookup is correct
- pos := p.pos()
- pkg, name := p.qualifiedName()
- typ := p.typ(nil, nil)
- p.declare(types.NewTypeName(pos, pkg, name, typ))
-
- case typeTag:
- p.typ(nil, nil)
-
- case varTag:
- pos := p.pos()
- pkg, name := p.qualifiedName()
- typ := p.typ(nil, nil)
- p.declare(types.NewVar(pos, pkg, name, typ))
-
- case funcTag:
- pos := p.pos()
- pkg, name := p.qualifiedName()
- params, isddd := p.paramList()
- result, _ := p.paramList()
- sig := types.NewSignature(nil, params, result, isddd)
- p.declare(types.NewFunc(pos, pkg, name, sig))
-
- default:
- errorf("unexpected object tag %d", tag)
- }
-}
-
-const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go
-
-func (p *importer) pos() token.Pos {
- if !p.posInfoFormat {
- return token.NoPos
- }
-
- file := p.prevFile
- line := p.prevLine
- delta := p.int()
- line += delta
- if p.version >= 5 {
- if delta == deltaNewFile {
- if n := p.int(); n >= 0 {
- // file changed
- file = p.path()
- line = n
- }
- }
- } else {
- if delta == 0 {
- if n := p.int(); n >= 0 {
- // file changed
- file = p.prevFile[:n] + p.string()
- line = p.int()
- }
- }
- }
- p.prevFile = file
- p.prevLine = line
-
- return p.fake.pos(file, line, 0)
-}
-
-// Synthesize a token.Pos
-type fakeFileSet struct {
- fset *token.FileSet
- files map[string]*token.File
-}
-
-func (s *fakeFileSet) pos(file string, line, column int) token.Pos {
- // TODO(mdempsky): Make use of column.
-
- // Since we don't know the set of needed file positions, we
- // reserve maxlines positions per file.
- const maxlines = 64 * 1024
- f := s.files[file]
- if f == nil {
- f = s.fset.AddFile(file, -1, maxlines)
- s.files[file] = f
- // Allocate the fake linebreak indices on first use.
- // TODO(adonovan): opt: save ~512KB using a more complex scheme?
- fakeLinesOnce.Do(func() {
- fakeLines = make([]int, maxlines)
- for i := range fakeLines {
- fakeLines[i] = i
- }
- })
- f.SetLines(fakeLines)
- }
-
- if line > maxlines {
- line = 1
- }
-
- // Treat the file as if it contained only newlines
- // and column=1: use the line number as the offset.
- return f.Pos(line - 1)
-}
-
-var (
- fakeLines []int
- fakeLinesOnce sync.Once
-)
-
-func (p *importer) qualifiedName() (pkg *types.Package, name string) {
- name = p.string()
- pkg = p.pkg()
- return
-}
-
-func (p *importer) record(t types.Type) {
- p.typList = append(p.typList, t)
-}
-
-// A dddSlice is a types.Type representing ...T parameters.
-// It only appears for parameter types and does not escape
-// the importer.
-type dddSlice struct {
- elem types.Type
-}
-
-func (t *dddSlice) Underlying() types.Type { return t }
-func (t *dddSlice) String() string { return "..." + t.elem.String() }
-
-// parent is the package which declared the type; parent == nil means
-// the package currently imported. The parent package is needed for
-// exported struct fields and interface methods which don't contain
-// explicit package information in the export data.
-//
-// A non-nil tname is used as the "owner" of the result type; i.e.,
-// the result type is the underlying type of tname. tname is used
-// to give interface methods a named receiver type where possible.
-func (p *importer) typ(parent *types.Package, tname *types.Named) types.Type {
- // if the type was seen before, i is its index (>= 0)
- i := p.tagOrIndex()
- if i >= 0 {
- return p.typList[i]
- }
-
- // otherwise, i is the type tag (< 0)
- switch i {
- case namedTag:
- // read type object
- pos := p.pos()
- parent, name := p.qualifiedName()
- scope := parent.Scope()
- obj := scope.Lookup(name)
-
- // if the object doesn't exist yet, create and insert it
- if obj == nil {
- obj = types.NewTypeName(pos, parent, name, nil)
- scope.Insert(obj)
- }
-
- if _, ok := obj.(*types.TypeName); !ok {
- errorf("pkg = %s, name = %s => %s", parent, name, obj)
- }
-
- // associate new named type with obj if it doesn't exist yet
- t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)
-
- // but record the existing type, if any
- tname := obj.Type().(*types.Named) // tname is either t0 or the existing type
- p.record(tname)
-
- // read underlying type
- t0.SetUnderlying(p.typ(parent, t0))
-
- // interfaces don't have associated methods
- if types.IsInterface(t0) {
- return tname
- }
-
- // read associated methods
- for i := p.int(); i > 0; i-- {
- // TODO(gri) replace this with something closer to fieldName
- pos := p.pos()
- name := p.string()
- if !exported(name) {
- p.pkg()
- }
-
- recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
- params, isddd := p.paramList()
- result, _ := p.paramList()
- p.int() // go:nointerface pragma - discarded
-
- sig := types.NewSignature(recv.At(0), params, result, isddd)
- t0.AddMethod(types.NewFunc(pos, parent, name, sig))
- }
-
- return tname
-
- case arrayTag:
- t := new(types.Array)
- if p.trackAllTypes {
- p.record(t)
- }
-
- n := p.int64()
- *t = *types.NewArray(p.typ(parent, nil), n)
- return t
-
- case sliceTag:
- t := new(types.Slice)
- if p.trackAllTypes {
- p.record(t)
- }
-
- *t = *types.NewSlice(p.typ(parent, nil))
- return t
-
- case dddTag:
- t := new(dddSlice)
- if p.trackAllTypes {
- p.record(t)
- }
-
- t.elem = p.typ(parent, nil)
- return t
-
- case structTag:
- t := new(types.Struct)
- if p.trackAllTypes {
- p.record(t)
- }
-
- *t = *types.NewStruct(p.fieldList(parent))
- return t
-
- case pointerTag:
- t := new(types.Pointer)
- if p.trackAllTypes {
- p.record(t)
- }
-
- *t = *types.NewPointer(p.typ(parent, nil))
- return t
-
- case signatureTag:
- t := new(types.Signature)
- if p.trackAllTypes {
- p.record(t)
- }
-
- params, isddd := p.paramList()
- result, _ := p.paramList()
- *t = *types.NewSignature(nil, params, result, isddd)
- return t
-
- case interfaceTag:
- // Create a dummy entry in the type list. This is safe because we
- // cannot expect the interface type to appear in a cycle, as any
- // such cycle must contain a named type which would have been
- // first defined earlier.
- // TODO(gri) Is this still true now that we have type aliases?
- // See issue #23225.
- n := len(p.typList)
- if p.trackAllTypes {
- p.record(nil)
- }
-
- var embeddeds []types.Type
- for n := p.int(); n > 0; n-- {
- p.pos()
- embeddeds = append(embeddeds, p.typ(parent, nil))
- }
-
- t := newInterface(p.methodList(parent, tname), embeddeds)
- p.interfaceList = append(p.interfaceList, t)
- if p.trackAllTypes {
- p.typList[n] = t
- }
- return t
-
- case mapTag:
- t := new(types.Map)
- if p.trackAllTypes {
- p.record(t)
- }
-
- key := p.typ(parent, nil)
- val := p.typ(parent, nil)
- *t = *types.NewMap(key, val)
- return t
-
- case chanTag:
- t := new(types.Chan)
- if p.trackAllTypes {
- p.record(t)
- }
-
- dir := chanDir(p.int())
- val := p.typ(parent, nil)
- *t = *types.NewChan(dir, val)
- return t
-
- default:
- errorf("unexpected type tag %d", i) // panics
- panic("unreachable")
- }
-}
-
-func chanDir(d int) types.ChanDir {
- // tag values must match the constants in cmd/compile/internal/gc/go.go
- switch d {
- case 1 /* Crecv */ :
- return types.RecvOnly
- case 2 /* Csend */ :
- return types.SendOnly
- case 3 /* Cboth */ :
- return types.SendRecv
- default:
- errorf("unexpected channel dir %d", d)
- return 0
- }
-}
-
-func (p *importer) fieldList(parent *types.Package) (fields []*types.Var, tags []string) {
- if n := p.int(); n > 0 {
- fields = make([]*types.Var, n)
- tags = make([]string, n)
- for i := range fields {
- fields[i], tags[i] = p.field(parent)
- }
- }
- return
-}
-
-func (p *importer) field(parent *types.Package) (*types.Var, string) {
- pos := p.pos()
- pkg, name, alias := p.fieldName(parent)
- typ := p.typ(parent, nil)
- tag := p.string()
-
- anonymous := false
- if name == "" {
- // anonymous field - typ must be T or *T and T must be a type name
- switch typ := deref(typ).(type) {
- case *types.Basic: // basic types are named types
- pkg = nil // // objects defined in Universe scope have no package
- name = typ.Name()
- case *types.Named:
- name = typ.Obj().Name()
- default:
- errorf("named base type expected")
- }
- anonymous = true
- } else if alias {
- // anonymous field: we have an explicit name because it's an alias
- anonymous = true
- }
-
- return types.NewField(pos, pkg, name, typ, anonymous), tag
-}
-
-func (p *importer) methodList(parent *types.Package, baseType *types.Named) (methods []*types.Func) {
- if n := p.int(); n > 0 {
- methods = make([]*types.Func, n)
- for i := range methods {
- methods[i] = p.method(parent, baseType)
- }
- }
- return
-}
-
-func (p *importer) method(parent *types.Package, baseType *types.Named) *types.Func {
- pos := p.pos()
- pkg, name, _ := p.fieldName(parent)
- // If we don't have a baseType, use a nil receiver.
- // A receiver using the actual interface type (which
- // we don't know yet) will be filled in when we call
- // types.Interface.Complete.
- var recv *types.Var
- if baseType != nil {
- recv = types.NewVar(token.NoPos, parent, "", baseType)
- }
- params, isddd := p.paramList()
- result, _ := p.paramList()
- sig := types.NewSignature(recv, params, result, isddd)
- return types.NewFunc(pos, pkg, name, sig)
-}
-
-func (p *importer) fieldName(parent *types.Package) (pkg *types.Package, name string, alias bool) {
- name = p.string()
- pkg = parent
- if pkg == nil {
- // use the imported package instead
- pkg = p.pkgList[0]
- }
- if p.version == 0 && name == "_" {
- // version 0 didn't export a package for _ fields
- return
- }
- switch name {
- case "":
- // 1) field name matches base type name and is exported: nothing to do
- case "?":
- // 2) field name matches base type name and is not exported: need package
- name = ""
- pkg = p.pkg()
- case "@":
- // 3) field name doesn't match type name (alias)
- name = p.string()
- alias = true
- fallthrough
- default:
- if !exported(name) {
- pkg = p.pkg()
- }
- }
- return
-}
-
-func (p *importer) paramList() (*types.Tuple, bool) {
- n := p.int()
- if n == 0 {
- return nil, false
- }
- // negative length indicates unnamed parameters
- named := true
- if n < 0 {
- n = -n
- named = false
- }
- // n > 0
- params := make([]*types.Var, n)
- isddd := false
- for i := range params {
- params[i], isddd = p.param(named)
- }
- return types.NewTuple(params...), isddd
-}
-
-func (p *importer) param(named bool) (*types.Var, bool) {
- t := p.typ(nil, nil)
- td, isddd := t.(*dddSlice)
- if isddd {
- t = types.NewSlice(td.elem)
- }
-
- var pkg *types.Package
- var name string
- if named {
- name = p.string()
- if name == "" {
- errorf("expected named parameter")
- }
- if name != "_" {
- pkg = p.pkg()
- }
- if i := strings.Index(name, "·"); i > 0 {
- name = name[:i] // cut off gc-specific parameter numbering
- }
- }
-
- // read and discard compiler-specific info
- p.string()
-
- return types.NewVar(token.NoPos, pkg, name, t), isddd
-}
-
-func exported(name string) bool {
- ch, _ := utf8.DecodeRuneInString(name)
- return unicode.IsUpper(ch)
-}
-
-func (p *importer) value() constant.Value {
- switch tag := p.tagOrIndex(); tag {
- case falseTag:
- return constant.MakeBool(false)
- case trueTag:
- return constant.MakeBool(true)
- case int64Tag:
- return constant.MakeInt64(p.int64())
- case floatTag:
- return p.float()
- case complexTag:
- re := p.float()
- im := p.float()
- return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
- case stringTag:
- return constant.MakeString(p.string())
- case unknownTag:
- return constant.MakeUnknown()
- default:
- errorf("unexpected value tag %d", tag) // panics
- panic("unreachable")
- }
-}
-
-func (p *importer) float() constant.Value {
- sign := p.int()
- if sign == 0 {
- return constant.MakeInt64(0)
- }
-
- exp := p.int()
- mant := []byte(p.string()) // big endian
-
- // remove leading 0's if any
- for len(mant) > 0 && mant[0] == 0 {
- mant = mant[1:]
- }
-
- // convert to little endian
- // TODO(gri) go/constant should have a more direct conversion function
- // (e.g., once it supports a big.Float based implementation)
- for i, j := 0, len(mant)-1; i < j; i, j = i+1, j-1 {
- mant[i], mant[j] = mant[j], mant[i]
- }
-
- // adjust exponent (constant.MakeFromBytes creates an integer value,
- // but mant represents the mantissa bits such that 0.5 <= mant < 1.0)
- exp -= len(mant) << 3
- if len(mant) > 0 {
- for msd := mant[len(mant)-1]; msd&0x80 == 0; msd <<= 1 {
- exp++
- }
- }
-
- x := constant.MakeFromBytes(mant)
- switch {
- case exp < 0:
- d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
- x = constant.BinaryOp(x, token.QUO, d)
- case exp > 0:
- x = constant.Shift(x, token.SHL, uint(exp))
- }
-
- if sign < 0 {
- x = constant.UnaryOp(token.SUB, x, 0)
- }
- return x
-}
-
-// ----------------------------------------------------------------------------
-// Low-level decoders
-
-func (p *importer) tagOrIndex() int {
- if p.debugFormat {
- p.marker('t')
- }
-
- return int(p.rawInt64())
-}
-
-func (p *importer) int() int {
- x := p.int64()
- if int64(int(x)) != x {
- errorf("exported integer too large")
- }
- return int(x)
-}
-
-func (p *importer) int64() int64 {
- if p.debugFormat {
- p.marker('i')
- }
-
- return p.rawInt64()
-}
-
-func (p *importer) path() string {
- if p.debugFormat {
- p.marker('p')
- }
- // if the path was seen before, i is its index (>= 0)
- // (the empty string is at index 0)
- i := p.rawInt64()
- if i >= 0 {
- return p.pathList[i]
- }
- // otherwise, i is the negative path length (< 0)
- a := make([]string, -i)
- for n := range a {
- a[n] = p.string()
- }
- s := strings.Join(a, "/")
- p.pathList = append(p.pathList, s)
- return s
-}
-
-func (p *importer) string() string {
- if p.debugFormat {
- p.marker('s')
- }
- // if the string was seen before, i is its index (>= 0)
- // (the empty string is at index 0)
- i := p.rawInt64()
- if i >= 0 {
- return p.strList[i]
- }
- // otherwise, i is the negative string length (< 0)
- if n := int(-i); n <= cap(p.buf) {
- p.buf = p.buf[:n]
- } else {
- p.buf = make([]byte, n)
- }
- for i := range p.buf {
- p.buf[i] = p.rawByte()
- }
- s := string(p.buf)
- p.strList = append(p.strList, s)
- return s
-}
-
-func (p *importer) marker(want byte) {
- if got := p.rawByte(); got != want {
- errorf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
- }
-
- pos := p.read
- if n := int(p.rawInt64()); n != pos {
- errorf("incorrect position: got %d; want %d", n, pos)
- }
-}
-
-// rawInt64 should only be used by low-level decoders.
-func (p *importer) rawInt64() int64 {
- i, err := binary.ReadVarint(p)
- if err != nil {
- errorf("read error: %v", err)
- }
- return i
-}
-
-// rawStringln should only be used to read the initial version string.
-func (p *importer) rawStringln(b byte) string {
- p.buf = p.buf[:0]
- for b != '\n' {
- p.buf = append(p.buf, b)
- b = p.rawByte()
- }
- return string(p.buf)
-}
-
-// needed for binary.ReadVarint in rawInt64
-func (p *importer) ReadByte() (byte, error) {
- return p.rawByte(), nil
-}
-
-// byte is the bottleneck interface for reading p.data.
-// It unescapes '|' 'S' to '$' and '|' '|' to '|'.
-// rawByte should only be used by low-level decoders.
-func (p *importer) rawByte() byte {
- b := p.data[0]
- r := 1
- if b == '|' {
- b = p.data[1]
- r = 2
- switch b {
- case 'S':
- b = '$'
- case '|':
- // nothing to do
- default:
- errorf("unexpected escape sequence in export data")
- }
- }
- p.data = p.data[r:]
- p.read += r
- return b
-
-}
-
-// ----------------------------------------------------------------------------
-// Export format
-
-// Tags. Must be < 0.
-const (
- // Objects
- packageTag = -(iota + 1)
- constTag
- typeTag
- varTag
- funcTag
- endTag
-
- // Types
- namedTag
- arrayTag
- sliceTag
- dddTag
- structTag
- pointerTag
- signatureTag
- interfaceTag
- mapTag
- chanTag
-
- // Values
- falseTag
- trueTag
- int64Tag
- floatTag
- fractionTag // not used by gc
- complexTag
- stringTag
- nilTag // only used by gc (appears in exported inlined function bodies)
- unknownTag // not used by gc (only appears in packages with errors)
-
- // Type aliases
- aliasTag
-)
-
-var predeclOnce sync.Once
-var predecl []types.Type // initialized lazily
-
-func predeclared() []types.Type {
- predeclOnce.Do(func() {
- // initialize lazily to be sure that all
- // elements have been initialized before
- predecl = []types.Type{ // basic types
- types.Typ[types.Bool],
- types.Typ[types.Int],
- types.Typ[types.Int8],
- types.Typ[types.Int16],
- types.Typ[types.Int32],
- types.Typ[types.Int64],
- types.Typ[types.Uint],
- types.Typ[types.Uint8],
- types.Typ[types.Uint16],
- types.Typ[types.Uint32],
- types.Typ[types.Uint64],
- types.Typ[types.Uintptr],
- types.Typ[types.Float32],
- types.Typ[types.Float64],
- types.Typ[types.Complex64],
- types.Typ[types.Complex128],
- types.Typ[types.String],
-
- // basic type aliases
- types.Universe.Lookup("byte").Type(),
- types.Universe.Lookup("rune").Type(),
-
- // error
- types.Universe.Lookup("error").Type(),
-
- // untyped types
- types.Typ[types.UntypedBool],
- types.Typ[types.UntypedInt],
- types.Typ[types.UntypedRune],
- types.Typ[types.UntypedFloat],
- types.Typ[types.UntypedComplex],
- types.Typ[types.UntypedString],
- types.Typ[types.UntypedNil],
-
- // package unsafe
- types.Typ[types.UnsafePointer],
-
- // invalid type
- types.Typ[types.Invalid], // only appears in packages with errors
-
- // used internally by gc; never used by this package or in .a files
- anyType{},
- }
- })
- return predecl
-}
-
-type anyType struct{}
-
-func (t anyType) Underlying() types.Type { return t }
-func (t anyType) String() string { return "any" }
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go b/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
deleted file mode 100644
index f33dc5613..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/exportdata.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2011 The Go 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 is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go.
-
-// This file implements FindExportData.
-
-package gcimporter
-
-import (
- "bufio"
- "fmt"
- "io"
- "strconv"
- "strings"
-)
-
-func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
- // See $GOROOT/include/ar.h.
- hdr := make([]byte, 16+12+6+6+8+10+2)
- _, err = io.ReadFull(r, hdr)
- if err != nil {
- return
- }
- // leave for debugging
- if false {
- fmt.Printf("header: %s", hdr)
- }
- s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
- size, err = strconv.Atoi(s)
- if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
- err = fmt.Errorf("invalid archive header")
- return
- }
- name = strings.TrimSpace(string(hdr[:16]))
- return
-}
-
-// FindExportData positions the reader r at the beginning of the
-// export data section of an underlying GC-created object/archive
-// file by reading from it. The reader must be positioned at the
-// start of the file before calling this function. The hdr result
-// is the string before the export data, either "$$" or "$$B".
-//
-func FindExportData(r *bufio.Reader) (hdr string, err error) {
- // Read first line to make sure this is an object file.
- line, err := r.ReadSlice('\n')
- if err != nil {
- err = fmt.Errorf("can't find export data (%v)", err)
- return
- }
-
- if string(line) == "!\n" {
- // Archive file. Scan to __.PKGDEF.
- var name string
- if name, _, err = readGopackHeader(r); err != nil {
- return
- }
-
- // First entry should be __.PKGDEF.
- if name != "__.PKGDEF" {
- err = fmt.Errorf("go archive is missing __.PKGDEF")
- return
- }
-
- // Read first line of __.PKGDEF data, so that line
- // is once again the first line of the input.
- if line, err = r.ReadSlice('\n'); err != nil {
- err = fmt.Errorf("can't find export data (%v)", err)
- return
- }
- }
-
- // Now at __.PKGDEF in archive or still at beginning of file.
- // Either way, line should begin with "go object ".
- if !strings.HasPrefix(string(line), "go object ") {
- err = fmt.Errorf("not a Go object file")
- return
- }
-
- // Skip over object header to export data.
- // Begins after first line starting with $$.
- for line[0] != '$' {
- if line, err = r.ReadSlice('\n'); err != nil {
- err = fmt.Errorf("can't find export data (%v)", err)
- return
- }
- }
- hdr = string(line)
-
- return
-}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
deleted file mode 100644
index 8dcd8bbb7..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go
+++ /dev/null
@@ -1,1078 +0,0 @@
-// Copyright 2011 The Go 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 is a modified copy of $GOROOT/src/go/internal/gcimporter/gcimporter.go,
-// but it also contains the original source-based importer code for Go1.6.
-// Once we stop supporting 1.6, we can remove that code.
-
-// Package gcimporter provides various functions for reading
-// gc-generated object files that can be used to implement the
-// Importer interface defined by the Go 1.5 standard library package.
-package gcimporter // import "golang.org/x/tools/go/internal/gcimporter"
-
-import (
- "bufio"
- "errors"
- "fmt"
- "go/build"
- "go/constant"
- "go/token"
- "go/types"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
- "strconv"
- "strings"
- "text/scanner"
-)
-
-// debugging/development support
-const debug = false
-
-var pkgExts = [...]string{".a", ".o"}
-
-// FindPkg returns the filename and unique package id for an import
-// path based on package information provided by build.Import (using
-// the build.Default build.Context). A relative srcDir is interpreted
-// relative to the current working directory.
-// If no file was found, an empty filename is returned.
-//
-func FindPkg(path, srcDir string) (filename, id string) {
- if path == "" {
- return
- }
-
- var noext string
- switch {
- default:
- // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x"
- // Don't require the source files to be present.
- if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282
- srcDir = abs
- }
- bp, _ := build.Import(path, srcDir, build.FindOnly|build.AllowBinary)
- if bp.PkgObj == "" {
- id = path // make sure we have an id to print in error message
- return
- }
- noext = strings.TrimSuffix(bp.PkgObj, ".a")
- id = bp.ImportPath
-
- case build.IsLocalImport(path):
- // "./x" -> "/this/directory/x.ext", "/this/directory/x"
- noext = filepath.Join(srcDir, path)
- id = noext
-
- case filepath.IsAbs(path):
- // for completeness only - go/build.Import
- // does not support absolute imports
- // "/x" -> "/x.ext", "/x"
- noext = path
- id = path
- }
-
- if false { // for debugging
- if path != id {
- fmt.Printf("%s -> %s\n", path, id)
- }
- }
-
- // try extensions
- for _, ext := range pkgExts {
- filename = noext + ext
- if f, err := os.Stat(filename); err == nil && !f.IsDir() {
- return
- }
- }
-
- filename = "" // not found
- return
-}
-
-// ImportData imports a package by reading the gc-generated export data,
-// adds the corresponding package object to the packages map indexed by id,
-// and returns the object.
-//
-// The packages map must contains all packages already imported. The data
-// reader position must be the beginning of the export data section. The
-// filename is only used in error messages.
-//
-// If packages[id] contains the completely imported package, that package
-// can be used directly, and there is no need to call this function (but
-// there is also no harm but for extra time used).
-//
-func ImportData(packages map[string]*types.Package, filename, id string, data io.Reader) (pkg *types.Package, err error) {
- // support for parser error handling
- defer func() {
- switch r := recover().(type) {
- case nil:
- // nothing to do
- case importError:
- err = r
- default:
- panic(r) // internal error
- }
- }()
-
- var p parser
- p.init(filename, id, data, packages)
- pkg = p.parseExport()
-
- return
-}
-
-// Import imports a gc-generated package given its import path and srcDir, adds
-// the corresponding package object to the packages map, and returns the object.
-// The packages map must contain all packages already imported.
-//
-func Import(packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
- var rc io.ReadCloser
- var filename, id string
- if lookup != nil {
- // With custom lookup specified, assume that caller has
- // converted path to a canonical import path for use in the map.
- if path == "unsafe" {
- return types.Unsafe, nil
- }
- id = path
-
- // No need to re-import if the package was imported completely before.
- if pkg = packages[id]; pkg != nil && pkg.Complete() {
- return
- }
- f, err := lookup(path)
- if err != nil {
- return nil, err
- }
- rc = f
- } else {
- filename, id = FindPkg(path, srcDir)
- if filename == "" {
- if path == "unsafe" {
- return types.Unsafe, nil
- }
- return nil, fmt.Errorf("can't find import: %q", id)
- }
-
- // no need to re-import if the package was imported completely before
- if pkg = packages[id]; pkg != nil && pkg.Complete() {
- return
- }
-
- // open file
- f, err := os.Open(filename)
- if err != nil {
- return nil, err
- }
- defer func() {
- if err != nil {
- // add file name to error
- err = fmt.Errorf("%s: %v", filename, err)
- }
- }()
- rc = f
- }
- defer rc.Close()
-
- var hdr string
- buf := bufio.NewReader(rc)
- if hdr, err = FindExportData(buf); err != nil {
- return
- }
-
- switch hdr {
- case "$$\n":
- // Work-around if we don't have a filename; happens only if lookup != nil.
- // Either way, the filename is only needed for importer error messages, so
- // this is fine.
- if filename == "" {
- filename = path
- }
- return ImportData(packages, filename, id, buf)
-
- case "$$B\n":
- var data []byte
- data, err = ioutil.ReadAll(buf)
- if err != nil {
- break
- }
-
- // TODO(gri): allow clients of go/importer to provide a FileSet.
- // Or, define a new standard go/types/gcexportdata package.
- fset := token.NewFileSet()
-
- // The indexed export format starts with an 'i'; the older
- // binary export format starts with a 'c', 'd', or 'v'
- // (from "version"). Select appropriate importer.
- if len(data) > 0 && data[0] == 'i' {
- _, pkg, err = IImportData(fset, packages, data[1:], id)
- } else {
- _, pkg, err = BImportData(fset, packages, data, id)
- }
-
- default:
- err = fmt.Errorf("unknown export data header: %q", hdr)
- }
-
- return
-}
-
-// ----------------------------------------------------------------------------
-// Parser
-
-// TODO(gri) Imported objects don't have position information.
-// Ideally use the debug table line info; alternatively
-// create some fake position (or the position of the
-// import). That way error messages referring to imported
-// objects can print meaningful information.
-
-// parser parses the exports inside a gc compiler-produced
-// object/archive file and populates its scope with the results.
-type parser struct {
- scanner scanner.Scanner
- tok rune // current token
- lit string // literal string; only valid for Ident, Int, String tokens
- id string // package id of imported package
- sharedPkgs map[string]*types.Package // package id -> package object (across importer)
- localPkgs map[string]*types.Package // package id -> package object (just this package)
-}
-
-func (p *parser) init(filename, id string, src io.Reader, packages map[string]*types.Package) {
- p.scanner.Init(src)
- p.scanner.Error = func(_ *scanner.Scanner, msg string) { p.error(msg) }
- p.scanner.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanChars | scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments
- p.scanner.Whitespace = 1<<'\t' | 1<<' '
- p.scanner.Filename = filename // for good error messages
- p.next()
- p.id = id
- p.sharedPkgs = packages
- if debug {
- // check consistency of packages map
- for _, pkg := range packages {
- if pkg.Name() == "" {
- fmt.Printf("no package name for %s\n", pkg.Path())
- }
- }
- }
-}
-
-func (p *parser) next() {
- p.tok = p.scanner.Scan()
- switch p.tok {
- case scanner.Ident, scanner.Int, scanner.Char, scanner.String, '·':
- p.lit = p.scanner.TokenText()
- default:
- p.lit = ""
- }
- if debug {
- fmt.Printf("%s: %q -> %q\n", scanner.TokenString(p.tok), p.scanner.TokenText(), p.lit)
- }
-}
-
-func declTypeName(pkg *types.Package, name string) *types.TypeName {
- scope := pkg.Scope()
- if obj := scope.Lookup(name); obj != nil {
- return obj.(*types.TypeName)
- }
- obj := types.NewTypeName(token.NoPos, pkg, name, nil)
- // a named type may be referred to before the underlying type
- // is known - set it up
- types.NewNamed(obj, nil, nil)
- scope.Insert(obj)
- return obj
-}
-
-// ----------------------------------------------------------------------------
-// Error handling
-
-// Internal errors are boxed as importErrors.
-type importError struct {
- pos scanner.Position
- err error
-}
-
-func (e importError) Error() string {
- return fmt.Sprintf("import error %s (byte offset = %d): %s", e.pos, e.pos.Offset, e.err)
-}
-
-func (p *parser) error(err interface{}) {
- if s, ok := err.(string); ok {
- err = errors.New(s)
- }
- // panic with a runtime.Error if err is not an error
- panic(importError{p.scanner.Pos(), err.(error)})
-}
-
-func (p *parser) errorf(format string, args ...interface{}) {
- p.error(fmt.Sprintf(format, args...))
-}
-
-func (p *parser) expect(tok rune) string {
- lit := p.lit
- if p.tok != tok {
- p.errorf("expected %s, got %s (%s)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
- }
- p.next()
- return lit
-}
-
-func (p *parser) expectSpecial(tok string) {
- sep := 'x' // not white space
- i := 0
- for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
- sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
- p.next()
- i++
- }
- if i < len(tok) {
- p.errorf("expected %q, got %q", tok, tok[0:i])
- }
-}
-
-func (p *parser) expectKeyword(keyword string) {
- lit := p.expect(scanner.Ident)
- if lit != keyword {
- p.errorf("expected keyword %s, got %q", keyword, lit)
- }
-}
-
-// ----------------------------------------------------------------------------
-// Qualified and unqualified names
-
-// PackageId = string_lit .
-//
-func (p *parser) parsePackageID() string {
- id, err := strconv.Unquote(p.expect(scanner.String))
- if err != nil {
- p.error(err)
- }
- // id == "" stands for the imported package id
- // (only known at time of package installation)
- if id == "" {
- id = p.id
- }
- return id
-}
-
-// PackageName = ident .
-//
-func (p *parser) parsePackageName() string {
- return p.expect(scanner.Ident)
-}
-
-// dotIdentifier = ( ident | '·' ) { ident | int | '·' } .
-func (p *parser) parseDotIdent() string {
- ident := ""
- if p.tok != scanner.Int {
- sep := 'x' // not white space
- for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
- ident += p.lit
- sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
- p.next()
- }
- }
- if ident == "" {
- p.expect(scanner.Ident) // use expect() for error handling
- }
- return ident
-}
-
-// QualifiedName = "@" PackageId "." ( "?" | dotIdentifier ) .
-//
-func (p *parser) parseQualifiedName() (id, name string) {
- p.expect('@')
- id = p.parsePackageID()
- p.expect('.')
- // Per rev f280b8a485fd (10/2/2013), qualified names may be used for anonymous fields.
- if p.tok == '?' {
- p.next()
- } else {
- name = p.parseDotIdent()
- }
- return
-}
-
-// getPkg returns the package for a given id. If the package is
-// not found, create the package and add it to the p.localPkgs
-// and p.sharedPkgs maps. name is the (expected) name of the
-// package. If name == "", the package name is expected to be
-// set later via an import clause in the export data.
-//
-// id identifies a package, usually by a canonical package path like
-// "encoding/json" but possibly by a non-canonical import path like
-// "./json".
-//
-func (p *parser) getPkg(id, name string) *types.Package {
- // package unsafe is not in the packages maps - handle explicitly
- if id == "unsafe" {
- return types.Unsafe
- }
-
- pkg := p.localPkgs[id]
- if pkg == nil {
- // first import of id from this package
- pkg = p.sharedPkgs[id]
- if pkg == nil {
- // first import of id by this importer;
- // add (possibly unnamed) pkg to shared packages
- pkg = types.NewPackage(id, name)
- p.sharedPkgs[id] = pkg
- }
- // add (possibly unnamed) pkg to local packages
- if p.localPkgs == nil {
- p.localPkgs = make(map[string]*types.Package)
- }
- p.localPkgs[id] = pkg
- } else if name != "" {
- // package exists already and we have an expected package name;
- // make sure names match or set package name if necessary
- if pname := pkg.Name(); pname == "" {
- pkg.SetName(name)
- } else if pname != name {
- p.errorf("%s package name mismatch: %s (given) vs %s (expected)", id, pname, name)
- }
- }
- return pkg
-}
-
-// parseExportedName is like parseQualifiedName, but
-// the package id is resolved to an imported *types.Package.
-//
-func (p *parser) parseExportedName() (pkg *types.Package, name string) {
- id, name := p.parseQualifiedName()
- pkg = p.getPkg(id, "")
- return
-}
-
-// ----------------------------------------------------------------------------
-// Types
-
-// BasicType = identifier .
-//
-func (p *parser) parseBasicType() types.Type {
- id := p.expect(scanner.Ident)
- obj := types.Universe.Lookup(id)
- if obj, ok := obj.(*types.TypeName); ok {
- return obj.Type()
- }
- p.errorf("not a basic type: %s", id)
- return nil
-}
-
-// ArrayType = "[" int_lit "]" Type .
-//
-func (p *parser) parseArrayType(parent *types.Package) types.Type {
- // "[" already consumed and lookahead known not to be "]"
- lit := p.expect(scanner.Int)
- p.expect(']')
- elem := p.parseType(parent)
- n, err := strconv.ParseInt(lit, 10, 64)
- if err != nil {
- p.error(err)
- }
- return types.NewArray(elem, n)
-}
-
-// MapType = "map" "[" Type "]" Type .
-//
-func (p *parser) parseMapType(parent *types.Package) types.Type {
- p.expectKeyword("map")
- p.expect('[')
- key := p.parseType(parent)
- p.expect(']')
- elem := p.parseType(parent)
- return types.NewMap(key, elem)
-}
-
-// Name = identifier | "?" | QualifiedName .
-//
-// For unqualified and anonymous names, the returned package is the parent
-// package unless parent == nil, in which case the returned package is the
-// package being imported. (The parent package is not nil if the the name
-// is an unqualified struct field or interface method name belonging to a
-// type declared in another package.)
-//
-// For qualified names, the returned package is nil (and not created if
-// it doesn't exist yet) unless materializePkg is set (which creates an
-// unnamed package with valid package path). In the latter case, a
-// subsequent import clause is expected to provide a name for the package.
-//
-func (p *parser) parseName(parent *types.Package, materializePkg bool) (pkg *types.Package, name string) {
- pkg = parent
- if pkg == nil {
- pkg = p.sharedPkgs[p.id]
- }
- switch p.tok {
- case scanner.Ident:
- name = p.lit
- p.next()
- case '?':
- // anonymous
- p.next()
- case '@':
- // exported name prefixed with package path
- pkg = nil
- var id string
- id, name = p.parseQualifiedName()
- if materializePkg {
- pkg = p.getPkg(id, "")
- }
- default:
- p.error("name expected")
- }
- return
-}
-
-func deref(typ types.Type) types.Type {
- if p, _ := typ.(*types.Pointer); p != nil {
- return p.Elem()
- }
- return typ
-}
-
-// Field = Name Type [ string_lit ] .
-//
-func (p *parser) parseField(parent *types.Package) (*types.Var, string) {
- pkg, name := p.parseName(parent, true)
-
- if name == "_" {
- // Blank fields should be package-qualified because they
- // are unexported identifiers, but gc does not qualify them.
- // Assuming that the ident belongs to the current package
- // causes types to change during re-exporting, leading
- // to spurious "can't assign A to B" errors from go/types.
- // As a workaround, pretend all blank fields belong
- // to the same unique dummy package.
- const blankpkg = "<_>"
- pkg = p.getPkg(blankpkg, blankpkg)
- }
-
- typ := p.parseType(parent)
- anonymous := false
- if name == "" {
- // anonymous field - typ must be T or *T and T must be a type name
- switch typ := deref(typ).(type) {
- case *types.Basic: // basic types are named types
- pkg = nil // objects defined in Universe scope have no package
- name = typ.Name()
- case *types.Named:
- name = typ.Obj().Name()
- default:
- p.errorf("anonymous field expected")
- }
- anonymous = true
- }
- tag := ""
- if p.tok == scanner.String {
- s := p.expect(scanner.String)
- var err error
- tag, err = strconv.Unquote(s)
- if err != nil {
- p.errorf("invalid struct tag %s: %s", s, err)
- }
- }
- return types.NewField(token.NoPos, pkg, name, typ, anonymous), tag
-}
-
-// StructType = "struct" "{" [ FieldList ] "}" .
-// FieldList = Field { ";" Field } .
-//
-func (p *parser) parseStructType(parent *types.Package) types.Type {
- var fields []*types.Var
- var tags []string
-
- p.expectKeyword("struct")
- p.expect('{')
- for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
- if i > 0 {
- p.expect(';')
- }
- fld, tag := p.parseField(parent)
- if tag != "" && tags == nil {
- tags = make([]string, i)
- }
- if tags != nil {
- tags = append(tags, tag)
- }
- fields = append(fields, fld)
- }
- p.expect('}')
-
- return types.NewStruct(fields, tags)
-}
-
-// Parameter = ( identifier | "?" ) [ "..." ] Type [ string_lit ] .
-//
-func (p *parser) parseParameter() (par *types.Var, isVariadic bool) {
- _, name := p.parseName(nil, false)
- // remove gc-specific parameter numbering
- if i := strings.Index(name, "·"); i >= 0 {
- name = name[:i]
- }
- if p.tok == '.' {
- p.expectSpecial("...")
- isVariadic = true
- }
- typ := p.parseType(nil)
- if isVariadic {
- typ = types.NewSlice(typ)
- }
- // ignore argument tag (e.g. "noescape")
- if p.tok == scanner.String {
- p.next()
- }
- // TODO(gri) should we provide a package?
- par = types.NewVar(token.NoPos, nil, name, typ)
- return
-}
-
-// Parameters = "(" [ ParameterList ] ")" .
-// ParameterList = { Parameter "," } Parameter .
-//
-func (p *parser) parseParameters() (list []*types.Var, isVariadic bool) {
- p.expect('(')
- for p.tok != ')' && p.tok != scanner.EOF {
- if len(list) > 0 {
- p.expect(',')
- }
- par, variadic := p.parseParameter()
- list = append(list, par)
- if variadic {
- if isVariadic {
- p.error("... not on final argument")
- }
- isVariadic = true
- }
- }
- p.expect(')')
-
- return
-}
-
-// Signature = Parameters [ Result ] .
-// Result = Type | Parameters .
-//
-func (p *parser) parseSignature(recv *types.Var) *types.Signature {
- params, isVariadic := p.parseParameters()
-
- // optional result type
- var results []*types.Var
- if p.tok == '(' {
- var variadic bool
- results, variadic = p.parseParameters()
- if variadic {
- p.error("... not permitted on result type")
- }
- }
-
- return types.NewSignature(recv, types.NewTuple(params...), types.NewTuple(results...), isVariadic)
-}
-
-// InterfaceType = "interface" "{" [ MethodList ] "}" .
-// MethodList = Method { ";" Method } .
-// Method = Name Signature .
-//
-// The methods of embedded interfaces are always "inlined"
-// by the compiler and thus embedded interfaces are never
-// visible in the export data.
-//
-func (p *parser) parseInterfaceType(parent *types.Package) types.Type {
- var methods []*types.Func
-
- p.expectKeyword("interface")
- p.expect('{')
- for i := 0; p.tok != '}' && p.tok != scanner.EOF; i++ {
- if i > 0 {
- p.expect(';')
- }
- pkg, name := p.parseName(parent, true)
- sig := p.parseSignature(nil)
- methods = append(methods, types.NewFunc(token.NoPos, pkg, name, sig))
- }
- p.expect('}')
-
- // Complete requires the type's embedded interfaces to be fully defined,
- // but we do not define any
- return newInterface(methods, nil).Complete()
-}
-
-// ChanType = ( "chan" [ "<-" ] | "<-" "chan" ) Type .
-//
-func (p *parser) parseChanType(parent *types.Package) types.Type {
- dir := types.SendRecv
- if p.tok == scanner.Ident {
- p.expectKeyword("chan")
- if p.tok == '<' {
- p.expectSpecial("<-")
- dir = types.SendOnly
- }
- } else {
- p.expectSpecial("<-")
- p.expectKeyword("chan")
- dir = types.RecvOnly
- }
- elem := p.parseType(parent)
- return types.NewChan(dir, elem)
-}
-
-// Type =
-// BasicType | TypeName | ArrayType | SliceType | StructType |
-// PointerType | FuncType | InterfaceType | MapType | ChanType |
-// "(" Type ")" .
-//
-// BasicType = ident .
-// TypeName = ExportedName .
-// SliceType = "[" "]" Type .
-// PointerType = "*" Type .
-// FuncType = "func" Signature .
-//
-func (p *parser) parseType(parent *types.Package) types.Type {
- switch p.tok {
- case scanner.Ident:
- switch p.lit {
- default:
- return p.parseBasicType()
- case "struct":
- return p.parseStructType(parent)
- case "func":
- // FuncType
- p.next()
- return p.parseSignature(nil)
- case "interface":
- return p.parseInterfaceType(parent)
- case "map":
- return p.parseMapType(parent)
- case "chan":
- return p.parseChanType(parent)
- }
- case '@':
- // TypeName
- pkg, name := p.parseExportedName()
- return declTypeName(pkg, name).Type()
- case '[':
- p.next() // look ahead
- if p.tok == ']' {
- // SliceType
- p.next()
- return types.NewSlice(p.parseType(parent))
- }
- return p.parseArrayType(parent)
- case '*':
- // PointerType
- p.next()
- return types.NewPointer(p.parseType(parent))
- case '<':
- return p.parseChanType(parent)
- case '(':
- // "(" Type ")"
- p.next()
- typ := p.parseType(parent)
- p.expect(')')
- return typ
- }
- p.errorf("expected type, got %s (%q)", scanner.TokenString(p.tok), p.lit)
- return nil
-}
-
-// ----------------------------------------------------------------------------
-// Declarations
-
-// ImportDecl = "import" PackageName PackageId .
-//
-func (p *parser) parseImportDecl() {
- p.expectKeyword("import")
- name := p.parsePackageName()
- p.getPkg(p.parsePackageID(), name)
-}
-
-// int_lit = [ "+" | "-" ] { "0" ... "9" } .
-//
-func (p *parser) parseInt() string {
- s := ""
- switch p.tok {
- case '-':
- s = "-"
- p.next()
- case '+':
- p.next()
- }
- return s + p.expect(scanner.Int)
-}
-
-// number = int_lit [ "p" int_lit ] .
-//
-func (p *parser) parseNumber() (typ *types.Basic, val constant.Value) {
- // mantissa
- mant := constant.MakeFromLiteral(p.parseInt(), token.INT, 0)
- if mant == nil {
- panic("invalid mantissa")
- }
-
- if p.lit == "p" {
- // exponent (base 2)
- p.next()
- exp, err := strconv.ParseInt(p.parseInt(), 10, 0)
- if err != nil {
- p.error(err)
- }
- if exp < 0 {
- denom := constant.MakeInt64(1)
- denom = constant.Shift(denom, token.SHL, uint(-exp))
- typ = types.Typ[types.UntypedFloat]
- val = constant.BinaryOp(mant, token.QUO, denom)
- return
- }
- if exp > 0 {
- mant = constant.Shift(mant, token.SHL, uint(exp))
- }
- typ = types.Typ[types.UntypedFloat]
- val = mant
- return
- }
-
- typ = types.Typ[types.UntypedInt]
- val = mant
- return
-}
-
-// ConstDecl = "const" ExportedName [ Type ] "=" Literal .
-// Literal = bool_lit | int_lit | float_lit | complex_lit | rune_lit | string_lit .
-// bool_lit = "true" | "false" .
-// complex_lit = "(" float_lit "+" float_lit "i" ")" .
-// rune_lit = "(" int_lit "+" int_lit ")" .
-// string_lit = `"` { unicode_char } `"` .
-//
-func (p *parser) parseConstDecl() {
- p.expectKeyword("const")
- pkg, name := p.parseExportedName()
-
- var typ0 types.Type
- if p.tok != '=' {
- // constant types are never structured - no need for parent type
- typ0 = p.parseType(nil)
- }
-
- p.expect('=')
- var typ types.Type
- var val constant.Value
- switch p.tok {
- case scanner.Ident:
- // bool_lit
- if p.lit != "true" && p.lit != "false" {
- p.error("expected true or false")
- }
- typ = types.Typ[types.UntypedBool]
- val = constant.MakeBool(p.lit == "true")
- p.next()
-
- case '-', scanner.Int:
- // int_lit
- typ, val = p.parseNumber()
-
- case '(':
- // complex_lit or rune_lit
- p.next()
- if p.tok == scanner.Char {
- p.next()
- p.expect('+')
- typ = types.Typ[types.UntypedRune]
- _, val = p.parseNumber()
- p.expect(')')
- break
- }
- _, re := p.parseNumber()
- p.expect('+')
- _, im := p.parseNumber()
- p.expectKeyword("i")
- p.expect(')')
- typ = types.Typ[types.UntypedComplex]
- val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
-
- case scanner.Char:
- // rune_lit
- typ = types.Typ[types.UntypedRune]
- val = constant.MakeFromLiteral(p.lit, token.CHAR, 0)
- p.next()
-
- case scanner.String:
- // string_lit
- typ = types.Typ[types.UntypedString]
- val = constant.MakeFromLiteral(p.lit, token.STRING, 0)
- p.next()
-
- default:
- p.errorf("expected literal got %s", scanner.TokenString(p.tok))
- }
-
- if typ0 == nil {
- typ0 = typ
- }
-
- pkg.Scope().Insert(types.NewConst(token.NoPos, pkg, name, typ0, val))
-}
-
-// TypeDecl = "type" ExportedName Type .
-//
-func (p *parser) parseTypeDecl() {
- p.expectKeyword("type")
- pkg, name := p.parseExportedName()
- obj := declTypeName(pkg, name)
-
- // The type object may have been imported before and thus already
- // have a type associated with it. We still need to parse the type
- // structure, but throw it away if the object already has a type.
- // This ensures that all imports refer to the same type object for
- // a given type declaration.
- typ := p.parseType(pkg)
-
- if name := obj.Type().(*types.Named); name.Underlying() == nil {
- name.SetUnderlying(typ)
- }
-}
-
-// VarDecl = "var" ExportedName Type .
-//
-func (p *parser) parseVarDecl() {
- p.expectKeyword("var")
- pkg, name := p.parseExportedName()
- typ := p.parseType(pkg)
- pkg.Scope().Insert(types.NewVar(token.NoPos, pkg, name, typ))
-}
-
-// Func = Signature [ Body ] .
-// Body = "{" ... "}" .
-//
-func (p *parser) parseFunc(recv *types.Var) *types.Signature {
- sig := p.parseSignature(recv)
- if p.tok == '{' {
- p.next()
- for i := 1; i > 0; p.next() {
- switch p.tok {
- case '{':
- i++
- case '}':
- i--
- }
- }
- }
- return sig
-}
-
-// MethodDecl = "func" Receiver Name Func .
-// Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" .
-//
-func (p *parser) parseMethodDecl() {
- // "func" already consumed
- p.expect('(')
- recv, _ := p.parseParameter() // receiver
- p.expect(')')
-
- // determine receiver base type object
- base := deref(recv.Type()).(*types.Named)
-
- // parse method name, signature, and possibly inlined body
- _, name := p.parseName(nil, false)
- sig := p.parseFunc(recv)
-
- // methods always belong to the same package as the base type object
- pkg := base.Obj().Pkg()
-
- // add method to type unless type was imported before
- // and method exists already
- // TODO(gri) This leads to a quadratic algorithm - ok for now because method counts are small.
- base.AddMethod(types.NewFunc(token.NoPos, pkg, name, sig))
-}
-
-// FuncDecl = "func" ExportedName Func .
-//
-func (p *parser) parseFuncDecl() {
- // "func" already consumed
- pkg, name := p.parseExportedName()
- typ := p.parseFunc(nil)
- pkg.Scope().Insert(types.NewFunc(token.NoPos, pkg, name, typ))
-}
-
-// Decl = [ ImportDecl | ConstDecl | TypeDecl | VarDecl | FuncDecl | MethodDecl ] "\n" .
-//
-func (p *parser) parseDecl() {
- if p.tok == scanner.Ident {
- switch p.lit {
- case "import":
- p.parseImportDecl()
- case "const":
- p.parseConstDecl()
- case "type":
- p.parseTypeDecl()
- case "var":
- p.parseVarDecl()
- case "func":
- p.next() // look ahead
- if p.tok == '(' {
- p.parseMethodDecl()
- } else {
- p.parseFuncDecl()
- }
- }
- }
- p.expect('\n')
-}
-
-// ----------------------------------------------------------------------------
-// Export
-
-// Export = "PackageClause { Decl } "$$" .
-// PackageClause = "package" PackageName [ "safe" ] "\n" .
-//
-func (p *parser) parseExport() *types.Package {
- p.expectKeyword("package")
- name := p.parsePackageName()
- if p.tok == scanner.Ident && p.lit == "safe" {
- // package was compiled with -u option - ignore
- p.next()
- }
- p.expect('\n')
-
- pkg := p.getPkg(p.id, name)
-
- for p.tok != '$' && p.tok != scanner.EOF {
- p.parseDecl()
- }
-
- if ch := p.scanner.Peek(); p.tok != '$' || ch != '$' {
- // don't call next()/expect() since reading past the
- // export data may cause scanner errors (e.g. NUL chars)
- p.errorf("expected '$$', got %s %c", scanner.TokenString(p.tok), ch)
- }
-
- if n := p.scanner.ErrorCount; n != 0 {
- p.errorf("expected no scanner errors, got %d", n)
- }
-
- // Record all locally referenced packages as imports.
- var imports []*types.Package
- for id, pkg2 := range p.localPkgs {
- if pkg2.Name() == "" {
- p.errorf("%s package has no name", id)
- }
- if id == p.id {
- continue // avoid self-edge
- }
- imports = append(imports, pkg2)
- }
- sort.Sort(byPath(imports))
- pkg.SetImports(imports)
-
- // package was imported completely and without errors
- pkg.MarkComplete()
-
- return pkg
-}
-
-type byPath []*types.Package
-
-func (a byPath) Len() int { return len(a) }
-func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go
deleted file mode 100644
index 4be32a2e5..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/iexport.go
+++ /dev/null
@@ -1,739 +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.
-
-// Indexed binary package export.
-// This file was derived from $GOROOT/src/cmd/compile/internal/gc/iexport.go;
-// see that file for specification of the format.
-
-package gcimporter
-
-import (
- "bytes"
- "encoding/binary"
- "go/ast"
- "go/constant"
- "go/token"
- "go/types"
- "io"
- "math/big"
- "reflect"
- "sort"
-)
-
-// Current indexed export format version. Increase with each format change.
-// 0: Go1.11 encoding
-const iexportVersion = 0
-
-// IExportData returns the binary export data for pkg.
-//
-// If no file set is provided, position info will be missing.
-// The package path of the top-level package will not be recorded,
-// so that calls to IImportData can override with a provided package path.
-func IExportData(fset *token.FileSet, pkg *types.Package) (b []byte, err error) {
- defer func() {
- if e := recover(); e != nil {
- if ierr, ok := e.(internalError); ok {
- err = ierr
- return
- }
- // Not an internal error; panic again.
- panic(e)
- }
- }()
-
- p := iexporter{
- out: bytes.NewBuffer(nil),
- fset: fset,
- allPkgs: map[*types.Package]bool{},
- stringIndex: map[string]uint64{},
- declIndex: map[types.Object]uint64{},
- typIndex: map[types.Type]uint64{},
- localpkg: pkg,
- }
-
- for i, pt := range predeclared() {
- p.typIndex[pt] = uint64(i)
- }
- if len(p.typIndex) > predeclReserved {
- panic(internalErrorf("too many predeclared types: %d > %d", len(p.typIndex), predeclReserved))
- }
-
- // Initialize work queue with exported declarations.
- scope := pkg.Scope()
- for _, name := range scope.Names() {
- if ast.IsExported(name) {
- p.pushDecl(scope.Lookup(name))
- }
- }
-
- // Loop until no more work.
- for !p.declTodo.empty() {
- p.doDecl(p.declTodo.popHead())
- }
-
- // Append indices to data0 section.
- dataLen := uint64(p.data0.Len())
- w := p.newWriter()
- w.writeIndex(p.declIndex)
- w.flush()
-
- // Assemble header.
- var hdr intWriter
- hdr.WriteByte('i')
- hdr.uint64(iexportVersion)
- hdr.uint64(uint64(p.strings.Len()))
- hdr.uint64(dataLen)
-
- // Flush output.
- io.Copy(p.out, &hdr)
- io.Copy(p.out, &p.strings)
- io.Copy(p.out, &p.data0)
-
- return p.out.Bytes(), nil
-}
-
-// writeIndex writes out an object index. mainIndex indicates whether
-// we're writing out the main index, which is also read by
-// non-compiler tools and includes a complete package description
-// (i.e., name and height).
-func (w *exportWriter) writeIndex(index map[types.Object]uint64) {
- // Build a map from packages to objects from that package.
- pkgObjs := map[*types.Package][]types.Object{}
-
- // For the main index, make sure to include every package that
- // we reference, even if we're not exporting (or reexporting)
- // any symbols from it.
- pkgObjs[w.p.localpkg] = nil
- for pkg := range w.p.allPkgs {
- pkgObjs[pkg] = nil
- }
-
- for obj := range index {
- pkgObjs[obj.Pkg()] = append(pkgObjs[obj.Pkg()], obj)
- }
-
- var pkgs []*types.Package
- for pkg, objs := range pkgObjs {
- pkgs = append(pkgs, pkg)
-
- sort.Slice(objs, func(i, j int) bool {
- return objs[i].Name() < objs[j].Name()
- })
- }
-
- sort.Slice(pkgs, func(i, j int) bool {
- return w.exportPath(pkgs[i]) < w.exportPath(pkgs[j])
- })
-
- w.uint64(uint64(len(pkgs)))
- for _, pkg := range pkgs {
- w.string(w.exportPath(pkg))
- w.string(pkg.Name())
- w.uint64(uint64(0)) // package height is not needed for go/types
-
- objs := pkgObjs[pkg]
- w.uint64(uint64(len(objs)))
- for _, obj := range objs {
- w.string(obj.Name())
- w.uint64(index[obj])
- }
- }
-}
-
-type iexporter struct {
- fset *token.FileSet
- out *bytes.Buffer
-
- localpkg *types.Package
-
- // allPkgs tracks all packages that have been referenced by
- // the export data, so we can ensure to include them in the
- // main index.
- allPkgs map[*types.Package]bool
-
- declTodo objQueue
-
- strings intWriter
- stringIndex map[string]uint64
-
- data0 intWriter
- declIndex map[types.Object]uint64
- typIndex map[types.Type]uint64
-}
-
-// stringOff returns the offset of s within the string section.
-// If not already present, it's added to the end.
-func (p *iexporter) stringOff(s string) uint64 {
- off, ok := p.stringIndex[s]
- if !ok {
- off = uint64(p.strings.Len())
- p.stringIndex[s] = off
-
- p.strings.uint64(uint64(len(s)))
- p.strings.WriteString(s)
- }
- return off
-}
-
-// pushDecl adds n to the declaration work queue, if not already present.
-func (p *iexporter) pushDecl(obj types.Object) {
- // Package unsafe is known to the compiler and predeclared.
- assert(obj.Pkg() != types.Unsafe)
-
- if _, ok := p.declIndex[obj]; ok {
- return
- }
-
- p.declIndex[obj] = ^uint64(0) // mark n present in work queue
- p.declTodo.pushTail(obj)
-}
-
-// exportWriter handles writing out individual data section chunks.
-type exportWriter struct {
- p *iexporter
-
- data intWriter
- currPkg *types.Package
- prevFile string
- prevLine int64
-}
-
-func (w *exportWriter) exportPath(pkg *types.Package) string {
- if pkg == w.p.localpkg {
- return ""
- }
- return pkg.Path()
-}
-
-func (p *iexporter) doDecl(obj types.Object) {
- w := p.newWriter()
- w.setPkg(obj.Pkg(), false)
-
- switch obj := obj.(type) {
- case *types.Var:
- w.tag('V')
- w.pos(obj.Pos())
- w.typ(obj.Type(), obj.Pkg())
-
- case *types.Func:
- sig, _ := obj.Type().(*types.Signature)
- if sig.Recv() != nil {
- panic(internalErrorf("unexpected method: %v", sig))
- }
- w.tag('F')
- w.pos(obj.Pos())
- w.signature(sig)
-
- case *types.Const:
- w.tag('C')
- w.pos(obj.Pos())
- w.value(obj.Type(), obj.Val())
-
- case *types.TypeName:
- if obj.IsAlias() {
- w.tag('A')
- w.pos(obj.Pos())
- w.typ(obj.Type(), obj.Pkg())
- break
- }
-
- // Defined type.
- w.tag('T')
- w.pos(obj.Pos())
-
- underlying := obj.Type().Underlying()
- w.typ(underlying, obj.Pkg())
-
- t := obj.Type()
- if types.IsInterface(t) {
- break
- }
-
- named, ok := t.(*types.Named)
- if !ok {
- panic(internalErrorf("%s is not a defined type", t))
- }
-
- n := named.NumMethods()
- w.uint64(uint64(n))
- for i := 0; i < n; i++ {
- m := named.Method(i)
- w.pos(m.Pos())
- w.string(m.Name())
- sig, _ := m.Type().(*types.Signature)
- w.param(sig.Recv())
- w.signature(sig)
- }
-
- default:
- panic(internalErrorf("unexpected object: %v", obj))
- }
-
- p.declIndex[obj] = w.flush()
-}
-
-func (w *exportWriter) tag(tag byte) {
- w.data.WriteByte(tag)
-}
-
-func (w *exportWriter) pos(pos token.Pos) {
- if w.p.fset == nil {
- w.int64(0)
- return
- }
-
- p := w.p.fset.Position(pos)
- file := p.Filename
- line := int64(p.Line)
-
- // When file is the same as the last position (common case),
- // we can save a few bytes by delta encoding just the line
- // number.
- //
- // Note: Because data objects may be read out of order (or not
- // at all), we can only apply delta encoding within a single
- // object. This is handled implicitly by tracking prevFile and
- // prevLine as fields of exportWriter.
-
- if file == w.prevFile {
- delta := line - w.prevLine
- w.int64(delta)
- if delta == deltaNewFile {
- w.int64(-1)
- }
- } else {
- w.int64(deltaNewFile)
- w.int64(line) // line >= 0
- w.string(file)
- w.prevFile = file
- }
- w.prevLine = line
-}
-
-func (w *exportWriter) pkg(pkg *types.Package) {
- // Ensure any referenced packages are declared in the main index.
- w.p.allPkgs[pkg] = true
-
- w.string(w.exportPath(pkg))
-}
-
-func (w *exportWriter) qualifiedIdent(obj types.Object) {
- // Ensure any referenced declarations are written out too.
- w.p.pushDecl(obj)
-
- w.string(obj.Name())
- w.pkg(obj.Pkg())
-}
-
-func (w *exportWriter) typ(t types.Type, pkg *types.Package) {
- w.data.uint64(w.p.typOff(t, pkg))
-}
-
-func (p *iexporter) newWriter() *exportWriter {
- return &exportWriter{p: p}
-}
-
-func (w *exportWriter) flush() uint64 {
- off := uint64(w.p.data0.Len())
- io.Copy(&w.p.data0, &w.data)
- return off
-}
-
-func (p *iexporter) typOff(t types.Type, pkg *types.Package) uint64 {
- off, ok := p.typIndex[t]
- if !ok {
- w := p.newWriter()
- w.doTyp(t, pkg)
- off = predeclReserved + w.flush()
- p.typIndex[t] = off
- }
- return off
-}
-
-func (w *exportWriter) startType(k itag) {
- w.data.uint64(uint64(k))
-}
-
-func (w *exportWriter) doTyp(t types.Type, pkg *types.Package) {
- switch t := t.(type) {
- case *types.Named:
- w.startType(definedType)
- w.qualifiedIdent(t.Obj())
-
- case *types.Pointer:
- w.startType(pointerType)
- w.typ(t.Elem(), pkg)
-
- case *types.Slice:
- w.startType(sliceType)
- w.typ(t.Elem(), pkg)
-
- case *types.Array:
- w.startType(arrayType)
- w.uint64(uint64(t.Len()))
- w.typ(t.Elem(), pkg)
-
- case *types.Chan:
- w.startType(chanType)
- // 1 RecvOnly; 2 SendOnly; 3 SendRecv
- var dir uint64
- switch t.Dir() {
- case types.RecvOnly:
- dir = 1
- case types.SendOnly:
- dir = 2
- case types.SendRecv:
- dir = 3
- }
- w.uint64(dir)
- w.typ(t.Elem(), pkg)
-
- case *types.Map:
- w.startType(mapType)
- w.typ(t.Key(), pkg)
- w.typ(t.Elem(), pkg)
-
- case *types.Signature:
- w.startType(signatureType)
- w.setPkg(pkg, true)
- w.signature(t)
-
- case *types.Struct:
- w.startType(structType)
- w.setPkg(pkg, true)
-
- n := t.NumFields()
- w.uint64(uint64(n))
- for i := 0; i < n; i++ {
- f := t.Field(i)
- w.pos(f.Pos())
- w.string(f.Name())
- w.typ(f.Type(), pkg)
- w.bool(f.Anonymous())
- w.string(t.Tag(i)) // note (or tag)
- }
-
- case *types.Interface:
- w.startType(interfaceType)
- w.setPkg(pkg, true)
-
- n := t.NumEmbeddeds()
- w.uint64(uint64(n))
- for i := 0; i < n; i++ {
- f := t.Embedded(i)
- w.pos(f.Obj().Pos())
- w.typ(f.Obj().Type(), f.Obj().Pkg())
- }
-
- n = t.NumExplicitMethods()
- w.uint64(uint64(n))
- for i := 0; i < n; i++ {
- m := t.ExplicitMethod(i)
- w.pos(m.Pos())
- w.string(m.Name())
- sig, _ := m.Type().(*types.Signature)
- w.signature(sig)
- }
-
- default:
- panic(internalErrorf("unexpected type: %v, %v", t, reflect.TypeOf(t)))
- }
-}
-
-func (w *exportWriter) setPkg(pkg *types.Package, write bool) {
- if write {
- w.pkg(pkg)
- }
-
- w.currPkg = pkg
-}
-
-func (w *exportWriter) signature(sig *types.Signature) {
- w.paramList(sig.Params())
- w.paramList(sig.Results())
- if sig.Params().Len() > 0 {
- w.bool(sig.Variadic())
- }
-}
-
-func (w *exportWriter) paramList(tup *types.Tuple) {
- n := tup.Len()
- w.uint64(uint64(n))
- for i := 0; i < n; i++ {
- w.param(tup.At(i))
- }
-}
-
-func (w *exportWriter) param(obj types.Object) {
- w.pos(obj.Pos())
- w.localIdent(obj)
- w.typ(obj.Type(), obj.Pkg())
-}
-
-func (w *exportWriter) value(typ types.Type, v constant.Value) {
- w.typ(typ, nil)
-
- switch v.Kind() {
- case constant.Bool:
- w.bool(constant.BoolVal(v))
- case constant.Int:
- var i big.Int
- if i64, exact := constant.Int64Val(v); exact {
- i.SetInt64(i64)
- } else if ui64, exact := constant.Uint64Val(v); exact {
- i.SetUint64(ui64)
- } else {
- i.SetString(v.ExactString(), 10)
- }
- w.mpint(&i, typ)
- case constant.Float:
- f := constantToFloat(v)
- w.mpfloat(f, typ)
- case constant.Complex:
- w.mpfloat(constantToFloat(constant.Real(v)), typ)
- w.mpfloat(constantToFloat(constant.Imag(v)), typ)
- case constant.String:
- w.string(constant.StringVal(v))
- case constant.Unknown:
- // package contains type errors
- default:
- panic(internalErrorf("unexpected value %v (%T)", v, v))
- }
-}
-
-// constantToFloat converts a constant.Value with kind constant.Float to a
-// big.Float.
-func constantToFloat(x constant.Value) *big.Float {
- assert(x.Kind() == constant.Float)
- // Use the same floating-point precision (512) as cmd/compile
- // (see Mpprec in cmd/compile/internal/gc/mpfloat.go).
- const mpprec = 512
- var f big.Float
- f.SetPrec(mpprec)
- if v, exact := constant.Float64Val(x); exact {
- // float64
- f.SetFloat64(v)
- } else if num, denom := constant.Num(x), constant.Denom(x); num.Kind() == constant.Int {
- // TODO(gri): add big.Rat accessor to constant.Value.
- n := valueToRat(num)
- d := valueToRat(denom)
- f.SetRat(n.Quo(n, d))
- } else {
- // Value too large to represent as a fraction => inaccessible.
- // TODO(gri): add big.Float accessor to constant.Value.
- _, ok := f.SetString(x.ExactString())
- assert(ok)
- }
- return &f
-}
-
-// mpint exports a multi-precision integer.
-//
-// For unsigned types, small values are written out as a single
-// byte. Larger values are written out as a length-prefixed big-endian
-// byte string, where the length prefix is encoded as its complement.
-// For example, bytes 0, 1, and 2 directly represent the integer
-// values 0, 1, and 2; while bytes 255, 254, and 253 indicate a 1-,
-// 2-, and 3-byte big-endian string follow.
-//
-// Encoding for signed types use the same general approach as for
-// unsigned types, except small values use zig-zag encoding and the
-// bottom bit of length prefix byte for large values is reserved as a
-// sign bit.
-//
-// The exact boundary between small and large encodings varies
-// according to the maximum number of bytes needed to encode a value
-// of type typ. As a special case, 8-bit types are always encoded as a
-// single byte.
-//
-// TODO(mdempsky): Is this level of complexity really worthwhile?
-func (w *exportWriter) mpint(x *big.Int, typ types.Type) {
- basic, ok := typ.Underlying().(*types.Basic)
- if !ok {
- panic(internalErrorf("unexpected type %v (%T)", typ.Underlying(), typ.Underlying()))
- }
-
- signed, maxBytes := intSize(basic)
-
- negative := x.Sign() < 0
- if !signed && negative {
- panic(internalErrorf("negative unsigned integer; type %v, value %v", typ, x))
- }
-
- b := x.Bytes()
- if len(b) > 0 && b[0] == 0 {
- panic(internalErrorf("leading zeros"))
- }
- if uint(len(b)) > maxBytes {
- panic(internalErrorf("bad mpint length: %d > %d (type %v, value %v)", len(b), maxBytes, typ, x))
- }
-
- maxSmall := 256 - maxBytes
- if signed {
- maxSmall = 256 - 2*maxBytes
- }
- if maxBytes == 1 {
- maxSmall = 256
- }
-
- // Check if x can use small value encoding.
- if len(b) <= 1 {
- var ux uint
- if len(b) == 1 {
- ux = uint(b[0])
- }
- if signed {
- ux <<= 1
- if negative {
- ux--
- }
- }
- if ux < maxSmall {
- w.data.WriteByte(byte(ux))
- return
- }
- }
-
- n := 256 - uint(len(b))
- if signed {
- n = 256 - 2*uint(len(b))
- if negative {
- n |= 1
- }
- }
- if n < maxSmall || n >= 256 {
- panic(internalErrorf("encoding mistake: %d, %v, %v => %d", len(b), signed, negative, n))
- }
-
- w.data.WriteByte(byte(n))
- w.data.Write(b)
-}
-
-// mpfloat exports a multi-precision floating point number.
-//
-// The number's value is decomposed into mantissa × 2**exponent, where
-// mantissa is an integer. The value is written out as mantissa (as a
-// multi-precision integer) and then the exponent, except exponent is
-// omitted if mantissa is zero.
-func (w *exportWriter) mpfloat(f *big.Float, typ types.Type) {
- if f.IsInf() {
- panic("infinite constant")
- }
-
- // Break into f = mant × 2**exp, with 0.5 <= mant < 1.
- var mant big.Float
- exp := int64(f.MantExp(&mant))
-
- // Scale so that mant is an integer.
- prec := mant.MinPrec()
- mant.SetMantExp(&mant, int(prec))
- exp -= int64(prec)
-
- manti, acc := mant.Int(nil)
- if acc != big.Exact {
- panic(internalErrorf("mantissa scaling failed for %f (%s)", f, acc))
- }
- w.mpint(manti, typ)
- if manti.Sign() != 0 {
- w.int64(exp)
- }
-}
-
-func (w *exportWriter) bool(b bool) bool {
- var x uint64
- if b {
- x = 1
- }
- w.uint64(x)
- return b
-}
-
-func (w *exportWriter) int64(x int64) { w.data.int64(x) }
-func (w *exportWriter) uint64(x uint64) { w.data.uint64(x) }
-func (w *exportWriter) string(s string) { w.uint64(w.p.stringOff(s)) }
-
-func (w *exportWriter) localIdent(obj types.Object) {
- // Anonymous parameters.
- if obj == nil {
- w.string("")
- return
- }
-
- name := obj.Name()
- if name == "_" {
- w.string("_")
- return
- }
-
- w.string(name)
-}
-
-type intWriter struct {
- bytes.Buffer
-}
-
-func (w *intWriter) int64(x int64) {
- var buf [binary.MaxVarintLen64]byte
- n := binary.PutVarint(buf[:], x)
- w.Write(buf[:n])
-}
-
-func (w *intWriter) uint64(x uint64) {
- var buf [binary.MaxVarintLen64]byte
- n := binary.PutUvarint(buf[:], x)
- w.Write(buf[:n])
-}
-
-func assert(cond bool) {
- if !cond {
- panic("internal error: assertion failed")
- }
-}
-
-// The below is copied from go/src/cmd/compile/internal/gc/syntax.go.
-
-// objQueue is a FIFO queue of types.Object. The zero value of objQueue is
-// a ready-to-use empty queue.
-type objQueue struct {
- ring []types.Object
- head, tail int
-}
-
-// empty returns true if q contains no Nodes.
-func (q *objQueue) empty() bool {
- return q.head == q.tail
-}
-
-// pushTail appends n to the tail of the queue.
-func (q *objQueue) pushTail(obj types.Object) {
- if len(q.ring) == 0 {
- q.ring = make([]types.Object, 16)
- } else if q.head+len(q.ring) == q.tail {
- // Grow the ring.
- nring := make([]types.Object, len(q.ring)*2)
- // Copy the old elements.
- part := q.ring[q.head%len(q.ring):]
- if q.tail-q.head <= len(part) {
- part = part[:q.tail-q.head]
- copy(nring, part)
- } else {
- pos := copy(nring, part)
- copy(nring[pos:], q.ring[:q.tail%len(q.ring)])
- }
- q.ring, q.head, q.tail = nring, 0, q.tail-q.head
- }
-
- q.ring[q.tail%len(q.ring)] = obj
- q.tail++
-}
-
-// popHead pops a node from the head of the queue. It panics if q is empty.
-func (q *objQueue) popHead() types.Object {
- if q.empty() {
- panic("dequeue empty")
- }
- obj := q.ring[q.head%len(q.ring)]
- q.head++
- return obj
-}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
deleted file mode 100644
index a31a88026..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
+++ /dev/null
@@ -1,630 +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.
-
-// Indexed package import.
-// See cmd/compile/internal/gc/iexport.go for the export data format.
-
-// This file is a copy of $GOROOT/src/go/internal/gcimporter/iimport.go.
-
-package gcimporter
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "go/constant"
- "go/token"
- "go/types"
- "io"
- "sort"
-)
-
-type intReader struct {
- *bytes.Reader
- path string
-}
-
-func (r *intReader) int64() int64 {
- i, err := binary.ReadVarint(r.Reader)
- if err != nil {
- errorf("import %q: read varint error: %v", r.path, err)
- }
- return i
-}
-
-func (r *intReader) uint64() uint64 {
- i, err := binary.ReadUvarint(r.Reader)
- if err != nil {
- errorf("import %q: read varint error: %v", r.path, err)
- }
- return i
-}
-
-const predeclReserved = 32
-
-type itag uint64
-
-const (
- // Types
- definedType itag = iota
- pointerType
- sliceType
- arrayType
- chanType
- mapType
- signatureType
- structType
- interfaceType
-)
-
-// IImportData imports a package from the serialized package data
-// and returns the number of bytes consumed and a reference to the package.
-// If the export data version is not recognized or the format is otherwise
-// compromised, an error is returned.
-func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) {
- const currentVersion = 1
- version := int64(-1)
- defer func() {
- if e := recover(); e != nil {
- if version > currentVersion {
- err = fmt.Errorf("cannot import %q (%v), export data is newer version - update tool", path, e)
- } else {
- err = fmt.Errorf("cannot import %q (%v), possibly version skew - reinstall package", path, e)
- }
- }
- }()
-
- r := &intReader{bytes.NewReader(data), path}
-
- version = int64(r.uint64())
- switch version {
- case currentVersion, 0:
- default:
- errorf("unknown iexport format version %d", version)
- }
-
- sLen := int64(r.uint64())
- dLen := int64(r.uint64())
-
- whence, _ := r.Seek(0, io.SeekCurrent)
- stringData := data[whence : whence+sLen]
- declData := data[whence+sLen : whence+sLen+dLen]
- r.Seek(sLen+dLen, io.SeekCurrent)
-
- p := iimporter{
- ipath: path,
- version: int(version),
-
- stringData: stringData,
- stringCache: make(map[uint64]string),
- pkgCache: make(map[uint64]*types.Package),
-
- declData: declData,
- pkgIndex: make(map[*types.Package]map[string]uint64),
- typCache: make(map[uint64]types.Type),
-
- fake: fakeFileSet{
- fset: fset,
- files: make(map[string]*token.File),
- },
- }
-
- for i, pt := range predeclared() {
- p.typCache[uint64(i)] = pt
- }
-
- pkgList := make([]*types.Package, r.uint64())
- for i := range pkgList {
- pkgPathOff := r.uint64()
- pkgPath := p.stringAt(pkgPathOff)
- pkgName := p.stringAt(r.uint64())
- _ = r.uint64() // package height; unused by go/types
-
- if pkgPath == "" {
- pkgPath = path
- }
- pkg := imports[pkgPath]
- if pkg == nil {
- pkg = types.NewPackage(pkgPath, pkgName)
- imports[pkgPath] = pkg
- } else if pkg.Name() != pkgName {
- errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
- }
-
- p.pkgCache[pkgPathOff] = pkg
-
- nameIndex := make(map[string]uint64)
- for nSyms := r.uint64(); nSyms > 0; nSyms-- {
- name := p.stringAt(r.uint64())
- nameIndex[name] = r.uint64()
- }
-
- p.pkgIndex[pkg] = nameIndex
- pkgList[i] = pkg
- }
- if len(pkgList) == 0 {
- errorf("no packages found for %s", path)
- panic("unreachable")
- }
- p.ipkg = pkgList[0]
- names := make([]string, 0, len(p.pkgIndex[p.ipkg]))
- for name := range p.pkgIndex[p.ipkg] {
- names = append(names, name)
- }
- sort.Strings(names)
- for _, name := range names {
- p.doDecl(p.ipkg, name)
- }
-
- for _, typ := range p.interfaceList {
- typ.Complete()
- }
-
- // record all referenced packages as imports
- list := append(([]*types.Package)(nil), pkgList[1:]...)
- sort.Sort(byPath(list))
- p.ipkg.SetImports(list)
-
- // package was imported completely and without errors
- p.ipkg.MarkComplete()
-
- consumed, _ := r.Seek(0, io.SeekCurrent)
- return int(consumed), p.ipkg, nil
-}
-
-type iimporter struct {
- ipath string
- ipkg *types.Package
- version int
-
- stringData []byte
- stringCache map[uint64]string
- pkgCache map[uint64]*types.Package
-
- declData []byte
- pkgIndex map[*types.Package]map[string]uint64
- typCache map[uint64]types.Type
-
- fake fakeFileSet
- interfaceList []*types.Interface
-}
-
-func (p *iimporter) doDecl(pkg *types.Package, name string) {
- // See if we've already imported this declaration.
- if obj := pkg.Scope().Lookup(name); obj != nil {
- return
- }
-
- off, ok := p.pkgIndex[pkg][name]
- if !ok {
- errorf("%v.%v not in index", pkg, name)
- }
-
- r := &importReader{p: p, currPkg: pkg}
- r.declReader.Reset(p.declData[off:])
-
- r.obj(name)
-}
-
-func (p *iimporter) stringAt(off uint64) string {
- if s, ok := p.stringCache[off]; ok {
- return s
- }
-
- slen, n := binary.Uvarint(p.stringData[off:])
- if n <= 0 {
- errorf("varint failed")
- }
- spos := off + uint64(n)
- s := string(p.stringData[spos : spos+slen])
- p.stringCache[off] = s
- return s
-}
-
-func (p *iimporter) pkgAt(off uint64) *types.Package {
- if pkg, ok := p.pkgCache[off]; ok {
- return pkg
- }
- path := p.stringAt(off)
- if path == p.ipath {
- return p.ipkg
- }
- errorf("missing package %q in %q", path, p.ipath)
- return nil
-}
-
-func (p *iimporter) typAt(off uint64, base *types.Named) types.Type {
- if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) {
- return t
- }
-
- if off < predeclReserved {
- errorf("predeclared type missing from cache: %v", off)
- }
-
- r := &importReader{p: p}
- r.declReader.Reset(p.declData[off-predeclReserved:])
- t := r.doType(base)
-
- if base == nil || !isInterface(t) {
- p.typCache[off] = t
- }
- return t
-}
-
-type importReader struct {
- p *iimporter
- declReader bytes.Reader
- currPkg *types.Package
- prevFile string
- prevLine int64
- prevColumn int64
-}
-
-func (r *importReader) obj(name string) {
- tag := r.byte()
- pos := r.pos()
-
- switch tag {
- case 'A':
- typ := r.typ()
-
- r.declare(types.NewTypeName(pos, r.currPkg, name, typ))
-
- case 'C':
- typ, val := r.value()
-
- r.declare(types.NewConst(pos, r.currPkg, name, typ, val))
-
- case 'F':
- sig := r.signature(nil)
-
- r.declare(types.NewFunc(pos, r.currPkg, name, sig))
-
- case 'T':
- // Types can be recursive. We need to setup a stub
- // declaration before recursing.
- obj := types.NewTypeName(pos, r.currPkg, name, nil)
- named := types.NewNamed(obj, nil, nil)
- r.declare(obj)
-
- underlying := r.p.typAt(r.uint64(), named).Underlying()
- named.SetUnderlying(underlying)
-
- if !isInterface(underlying) {
- for n := r.uint64(); n > 0; n-- {
- mpos := r.pos()
- mname := r.ident()
- recv := r.param()
- msig := r.signature(recv)
-
- named.AddMethod(types.NewFunc(mpos, r.currPkg, mname, msig))
- }
- }
-
- case 'V':
- typ := r.typ()
-
- r.declare(types.NewVar(pos, r.currPkg, name, typ))
-
- default:
- errorf("unexpected tag: %v", tag)
- }
-}
-
-func (r *importReader) declare(obj types.Object) {
- obj.Pkg().Scope().Insert(obj)
-}
-
-func (r *importReader) value() (typ types.Type, val constant.Value) {
- typ = r.typ()
-
- switch b := typ.Underlying().(*types.Basic); b.Info() & types.IsConstType {
- case types.IsBoolean:
- val = constant.MakeBool(r.bool())
-
- case types.IsString:
- val = constant.MakeString(r.string())
-
- case types.IsInteger:
- val = r.mpint(b)
-
- case types.IsFloat:
- val = r.mpfloat(b)
-
- case types.IsComplex:
- re := r.mpfloat(b)
- im := r.mpfloat(b)
- val = constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
-
- default:
- if b.Kind() == types.Invalid {
- val = constant.MakeUnknown()
- return
- }
- errorf("unexpected type %v", typ) // panics
- panic("unreachable")
- }
-
- return
-}
-
-func intSize(b *types.Basic) (signed bool, maxBytes uint) {
- if (b.Info() & types.IsUntyped) != 0 {
- return true, 64
- }
-
- switch b.Kind() {
- case types.Float32, types.Complex64:
- return true, 3
- case types.Float64, types.Complex128:
- return true, 7
- }
-
- signed = (b.Info() & types.IsUnsigned) == 0
- switch b.Kind() {
- case types.Int8, types.Uint8:
- maxBytes = 1
- case types.Int16, types.Uint16:
- maxBytes = 2
- case types.Int32, types.Uint32:
- maxBytes = 4
- default:
- maxBytes = 8
- }
-
- return
-}
-
-func (r *importReader) mpint(b *types.Basic) constant.Value {
- signed, maxBytes := intSize(b)
-
- maxSmall := 256 - maxBytes
- if signed {
- maxSmall = 256 - 2*maxBytes
- }
- if maxBytes == 1 {
- maxSmall = 256
- }
-
- n, _ := r.declReader.ReadByte()
- if uint(n) < maxSmall {
- v := int64(n)
- if signed {
- v >>= 1
- if n&1 != 0 {
- v = ^v
- }
- }
- return constant.MakeInt64(v)
- }
-
- v := -n
- if signed {
- v = -(n &^ 1) >> 1
- }
- if v < 1 || uint(v) > maxBytes {
- errorf("weird decoding: %v, %v => %v", n, signed, v)
- }
-
- buf := make([]byte, v)
- io.ReadFull(&r.declReader, buf)
-
- // convert to little endian
- // TODO(gri) go/constant should have a more direct conversion function
- // (e.g., once it supports a big.Float based implementation)
- for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 {
- buf[i], buf[j] = buf[j], buf[i]
- }
-
- x := constant.MakeFromBytes(buf)
- if signed && n&1 != 0 {
- x = constant.UnaryOp(token.SUB, x, 0)
- }
- return x
-}
-
-func (r *importReader) mpfloat(b *types.Basic) constant.Value {
- x := r.mpint(b)
- if constant.Sign(x) == 0 {
- return x
- }
-
- exp := r.int64()
- switch {
- case exp > 0:
- x = constant.Shift(x, token.SHL, uint(exp))
- case exp < 0:
- d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
- x = constant.BinaryOp(x, token.QUO, d)
- }
- return x
-}
-
-func (r *importReader) ident() string {
- return r.string()
-}
-
-func (r *importReader) qualifiedIdent() (*types.Package, string) {
- name := r.string()
- pkg := r.pkg()
- return pkg, name
-}
-
-func (r *importReader) pos() token.Pos {
- if r.p.version >= 1 {
- r.posv1()
- } else {
- r.posv0()
- }
-
- if r.prevFile == "" && r.prevLine == 0 && r.prevColumn == 0 {
- return token.NoPos
- }
- return r.p.fake.pos(r.prevFile, int(r.prevLine), int(r.prevColumn))
-}
-
-func (r *importReader) posv0() {
- delta := r.int64()
- if delta != deltaNewFile {
- r.prevLine += delta
- } else if l := r.int64(); l == -1 {
- r.prevLine += deltaNewFile
- } else {
- r.prevFile = r.string()
- r.prevLine = l
- }
-}
-
-func (r *importReader) posv1() {
- delta := r.int64()
- r.prevColumn += delta >> 1
- if delta&1 != 0 {
- delta = r.int64()
- r.prevLine += delta >> 1
- if delta&1 != 0 {
- r.prevFile = r.string()
- }
- }
-}
-
-func (r *importReader) typ() types.Type {
- return r.p.typAt(r.uint64(), nil)
-}
-
-func isInterface(t types.Type) bool {
- _, ok := t.(*types.Interface)
- return ok
-}
-
-func (r *importReader) pkg() *types.Package { return r.p.pkgAt(r.uint64()) }
-func (r *importReader) string() string { return r.p.stringAt(r.uint64()) }
-
-func (r *importReader) doType(base *types.Named) types.Type {
- switch k := r.kind(); k {
- default:
- errorf("unexpected kind tag in %q: %v", r.p.ipath, k)
- return nil
-
- case definedType:
- pkg, name := r.qualifiedIdent()
- r.p.doDecl(pkg, name)
- return pkg.Scope().Lookup(name).(*types.TypeName).Type()
- case pointerType:
- return types.NewPointer(r.typ())
- case sliceType:
- return types.NewSlice(r.typ())
- case arrayType:
- n := r.uint64()
- return types.NewArray(r.typ(), int64(n))
- case chanType:
- dir := chanDir(int(r.uint64()))
- return types.NewChan(dir, r.typ())
- case mapType:
- return types.NewMap(r.typ(), r.typ())
- case signatureType:
- r.currPkg = r.pkg()
- return r.signature(nil)
-
- case structType:
- r.currPkg = r.pkg()
-
- fields := make([]*types.Var, r.uint64())
- tags := make([]string, len(fields))
- for i := range fields {
- fpos := r.pos()
- fname := r.ident()
- ftyp := r.typ()
- emb := r.bool()
- tag := r.string()
-
- fields[i] = types.NewField(fpos, r.currPkg, fname, ftyp, emb)
- tags[i] = tag
- }
- return types.NewStruct(fields, tags)
-
- case interfaceType:
- r.currPkg = r.pkg()
-
- embeddeds := make([]types.Type, r.uint64())
- for i := range embeddeds {
- _ = r.pos()
- embeddeds[i] = r.typ()
- }
-
- methods := make([]*types.Func, r.uint64())
- for i := range methods {
- mpos := r.pos()
- mname := r.ident()
-
- // TODO(mdempsky): Matches bimport.go, but I
- // don't agree with this.
- var recv *types.Var
- if base != nil {
- recv = types.NewVar(token.NoPos, r.currPkg, "", base)
- }
-
- msig := r.signature(recv)
- methods[i] = types.NewFunc(mpos, r.currPkg, mname, msig)
- }
-
- typ := newInterface(methods, embeddeds)
- r.p.interfaceList = append(r.p.interfaceList, typ)
- return typ
- }
-}
-
-func (r *importReader) kind() itag {
- return itag(r.uint64())
-}
-
-func (r *importReader) signature(recv *types.Var) *types.Signature {
- params := r.paramList()
- results := r.paramList()
- variadic := params.Len() > 0 && r.bool()
- return types.NewSignature(recv, params, results, variadic)
-}
-
-func (r *importReader) paramList() *types.Tuple {
- xs := make([]*types.Var, r.uint64())
- for i := range xs {
- xs[i] = r.param()
- }
- return types.NewTuple(xs...)
-}
-
-func (r *importReader) param() *types.Var {
- pos := r.pos()
- name := r.ident()
- typ := r.typ()
- return types.NewParam(pos, r.currPkg, name, typ)
-}
-
-func (r *importReader) bool() bool {
- return r.uint64() != 0
-}
-
-func (r *importReader) int64() int64 {
- n, err := binary.ReadVarint(&r.declReader)
- if err != nil {
- errorf("readVarint: %v", err)
- }
- return n
-}
-
-func (r *importReader) uint64() uint64 {
- n, err := binary.ReadUvarint(&r.declReader)
- if err != nil {
- errorf("readUvarint: %v", err)
- }
- return n
-}
-
-func (r *importReader) byte() byte {
- x, err := r.declReader.ReadByte()
- if err != nil {
- errorf("declReader.ReadByte: %v", err)
- }
- return x
-}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go
deleted file mode 100644
index 463f25227..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface10.go
+++ /dev/null
@@ -1,21 +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.
-
-// +build !go1.11
-
-package gcimporter
-
-import "go/types"
-
-func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
- named := make([]*types.Named, len(embeddeds))
- for i, e := range embeddeds {
- var ok bool
- named[i], ok = e.(*types.Named)
- if !ok {
- panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11")
- }
- }
- return types.NewInterface(methods, named)
-}
diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go b/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go
deleted file mode 100644
index ab28b95cb..000000000
--- a/vendor/golang.org/x/tools/go/internal/gcimporter/newInterface11.go
+++ /dev/null
@@ -1,13 +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.
-
-// +build go1.11
-
-package gcimporter
-
-import "go/types"
-
-func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface {
- return types.NewInterfaceType(methods, embeddeds)
-}
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/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 cb6b14c1b..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 b82c90d7c..000000000
--- a/vendor/golang.org/x/tools/go/packages/golist_overlay.go
+++ /dev/null
@@ -1,457 +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
- }
- isXTest := strings.HasSuffix(pkgName, "_test")
- if isXTest {
- pkgPath += "_test"
- }
- id := pkgPath
- if isTestFile && !isXTest {
- 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}
- }
- }
- // TODO(rstambler): Handle forTest for x_tests.
- }
- }
- 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 1e6f9a467..000000000
--- a/vendor/golang.org/x/tools/go/packages/packages.go
+++ /dev/null
@@ -1,1200 +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"
- "reflect"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/tools/go/gcexportdata"
- "golang.org/x/tools/internal/gocommand"
- "golang.org/x/tools/internal/packagesinternal"
-)
-
-// 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 {
- // 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 looks for an external driver binary, and if
-// it does not find it falls back to the built in go list driver.
-func defaultDriver(cfg *Config, patterns ...string) (*driverResponse, error) {
- driver := findExternalDriver(cfg)
- if driver == nil {
- driver = goListDriver
- }
- return driver(cfg, patterns...)
-}
-
-// 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
- }
-}
-
-// 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 {
- // TODO: remove this when we stop supporting 1.14.
- rtc := reflect.ValueOf(tc).Elem()
- usesCgo := rtc.FieldByName("UsesCgo")
- if !usesCgo.IsValid() {
- appendError(Error{
- Msg: "TypecheckCgo requires Go 1.15+",
- Kind: ListError,
- })
- return
- }
- usesCgo.SetBool(true)
- }
- 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/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go
deleted file mode 100644
index e37b49491..000000000
--- a/vendor/golang.org/x/tools/internal/event/core/event.go
+++ /dev/null
@@ -1,85 +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 core provides support for event based telemetry.
-package core
-
-import (
- "fmt"
- "time"
-
- "golang.org/x/tools/internal/event/label"
-)
-
-// Event holds the information about an event of note that ocurred.
-type Event struct {
- at time.Time
-
- // As events are often on the stack, storing the first few labels directly
- // in the event can avoid an allocation at all for the very common cases of
- // simple events.
- // The length needs to be large enough to cope with the majority of events
- // but no so large as to cause undue stack pressure.
- // A log message with two values will use 3 labels (one for each value and
- // one for the message itself).
-
- static [3]label.Label // inline storage for the first few labels
- dynamic []label.Label // dynamically sized storage for remaining labels
-}
-
-// eventLabelMap implements label.Map for a the labels of an Event.
-type eventLabelMap struct {
- event Event
-}
-
-func (ev Event) At() time.Time { return ev.at }
-
-func (ev Event) Format(f fmt.State, r rune) {
- if !ev.at.IsZero() {
- fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 "))
- }
- for index := 0; ev.Valid(index); index++ {
- if l := ev.Label(index); l.Valid() {
- fmt.Fprintf(f, "\n\t%v", l)
- }
- }
-}
-
-func (ev Event) Valid(index int) bool {
- return index >= 0 && index < len(ev.static)+len(ev.dynamic)
-}
-
-func (ev Event) Label(index int) label.Label {
- if index < len(ev.static) {
- return ev.static[index]
- }
- return ev.dynamic[index-len(ev.static)]
-}
-
-func (ev Event) Find(key label.Key) label.Label {
- for _, l := range ev.static {
- if l.Key() == key {
- return l
- }
- }
- for _, l := range ev.dynamic {
- if l.Key() == key {
- return l
- }
- }
- return label.Label{}
-}
-
-func MakeEvent(static [3]label.Label, labels []label.Label) Event {
- return Event{
- static: static,
- dynamic: labels,
- }
-}
-
-// CloneEvent event returns a copy of the event with the time adjusted to at.
-func CloneEvent(ev Event, at time.Time) Event {
- ev.at = at
- return ev
-}
diff --git a/vendor/golang.org/x/tools/internal/event/core/export.go b/vendor/golang.org/x/tools/internal/event/core/export.go
deleted file mode 100644
index 05f3a9a57..000000000
--- a/vendor/golang.org/x/tools/internal/event/core/export.go
+++ /dev/null
@@ -1,70 +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 core
-
-import (
- "context"
- "sync/atomic"
- "time"
- "unsafe"
-
- "golang.org/x/tools/internal/event/label"
-)
-
-// Exporter is a function that handles events.
-// It may return a modified context and event.
-type Exporter func(context.Context, Event, label.Map) context.Context
-
-var (
- exporter unsafe.Pointer
-)
-
-// SetExporter sets the global exporter function that handles all events.
-// The exporter is called synchronously from the event call site, so it should
-// return quickly so as not to hold up user code.
-func SetExporter(e Exporter) {
- p := unsafe.Pointer(&e)
- if e == nil {
- // &e is always valid, and so p is always valid, but for the early abort
- // of ProcessEvent to be efficient it needs to make the nil check on the
- // pointer without having to dereference it, so we make the nil function
- // also a nil pointer
- p = nil
- }
- atomic.StorePointer(&exporter, p)
-}
-
-// deliver is called to deliver an event to the supplied exporter.
-// it will fill in the time.
-func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context {
- // add the current time to the event
- ev.at = time.Now()
- // hand the event off to the current exporter
- return exporter(ctx, ev, ev)
-}
-
-// Export is called to deliver an event to the global exporter if set.
-func Export(ctx context.Context, ev Event) context.Context {
- // get the global exporter and abort early if there is not one
- exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
- if exporterPtr == nil {
- return ctx
- }
- return deliver(ctx, *exporterPtr, ev)
-}
-
-// ExportPair is called to deliver a start event to the supplied exporter.
-// It also returns a function that will deliver the end event to the same
-// exporter.
-// It will fill in the time.
-func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
- // get the global exporter and abort early if there is not one
- exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
- if exporterPtr == nil {
- return ctx, func() {}
- }
- ctx = deliver(ctx, *exporterPtr, begin)
- return ctx, func() { deliver(ctx, *exporterPtr, end) }
-}
diff --git a/vendor/golang.org/x/tools/internal/event/core/fast.go b/vendor/golang.org/x/tools/internal/event/core/fast.go
deleted file mode 100644
index 06c1d4615..000000000
--- a/vendor/golang.org/x/tools/internal/event/core/fast.go
+++ /dev/null
@@ -1,77 +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 core
-
-import (
- "context"
-
- "golang.org/x/tools/internal/event/keys"
- "golang.org/x/tools/internal/event/label"
-)
-
-// Log1 takes a message and one label delivers a log event to the exporter.
-// It is a customized version of Print that is faster and does no allocation.
-func Log1(ctx context.Context, message string, t1 label.Label) {
- Export(ctx, MakeEvent([3]label.Label{
- keys.Msg.Of(message),
- t1,
- }, nil))
-}
-
-// Log2 takes a message and two labels and delivers a log event to the exporter.
-// It is a customized version of Print that is faster and does no allocation.
-func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) {
- Export(ctx, MakeEvent([3]label.Label{
- keys.Msg.Of(message),
- t1,
- t2,
- }, nil))
-}
-
-// Metric1 sends a label event to the exporter with the supplied labels.
-func Metric1(ctx context.Context, t1 label.Label) context.Context {
- return Export(ctx, MakeEvent([3]label.Label{
- keys.Metric.New(),
- t1,
- }, nil))
-}
-
-// Metric2 sends a label event to the exporter with the supplied labels.
-func Metric2(ctx context.Context, t1, t2 label.Label) context.Context {
- return Export(ctx, MakeEvent([3]label.Label{
- keys.Metric.New(),
- t1,
- t2,
- }, nil))
-}
-
-// Start1 sends a span start event with the supplied label list to the exporter.
-// It also returns a function that will end the span, which should normally be
-// deferred.
-func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) {
- return ExportPair(ctx,
- MakeEvent([3]label.Label{
- keys.Start.Of(name),
- t1,
- }, nil),
- MakeEvent([3]label.Label{
- keys.End.New(),
- }, nil))
-}
-
-// Start2 sends a span start event with the supplied label list to the exporter.
-// It also returns a function that will end the span, which should normally be
-// deferred.
-func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) {
- return ExportPair(ctx,
- MakeEvent([3]label.Label{
- keys.Start.Of(name),
- t1,
- t2,
- }, nil),
- MakeEvent([3]label.Label{
- keys.End.New(),
- }, nil))
-}
diff --git a/vendor/golang.org/x/tools/internal/event/doc.go b/vendor/golang.org/x/tools/internal/event/doc.go
deleted file mode 100644
index 5dc6e6bab..000000000
--- a/vendor/golang.org/x/tools/internal/event/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 event provides a set of packages that cover the main
-// concepts of telemetry in an implementation agnostic way.
-package event
diff --git a/vendor/golang.org/x/tools/internal/event/event.go b/vendor/golang.org/x/tools/internal/event/event.go
deleted file mode 100644
index 4d55e577d..000000000
--- a/vendor/golang.org/x/tools/internal/event/event.go
+++ /dev/null
@@ -1,127 +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 event
-
-import (
- "context"
-
- "golang.org/x/tools/internal/event/core"
- "golang.org/x/tools/internal/event/keys"
- "golang.org/x/tools/internal/event/label"
-)
-
-// Exporter is a function that handles events.
-// It may return a modified context and event.
-type Exporter func(context.Context, core.Event, label.Map) context.Context
-
-// SetExporter sets the global exporter function that handles all events.
-// The exporter is called synchronously from the event call site, so it should
-// return quickly so as not to hold up user code.
-func SetExporter(e Exporter) {
- core.SetExporter(core.Exporter(e))
-}
-
-// Log takes a message and a label list and combines them into a single event
-// before delivering them to the exporter.
-func Log(ctx context.Context, message string, labels ...label.Label) {
- core.Export(ctx, core.MakeEvent([3]label.Label{
- keys.Msg.Of(message),
- }, labels))
-}
-
-// IsLog returns true if the event was built by the Log function.
-// It is intended to be used in exporters to identify the semantics of the
-// event when deciding what to do with it.
-func IsLog(ev core.Event) bool {
- return ev.Label(0).Key() == keys.Msg
-}
-
-// Error takes a message and a label list and combines them into a single event
-// before delivering them to the exporter. It captures the error in the
-// delivered event.
-func Error(ctx context.Context, message string, err error, labels ...label.Label) {
- core.Export(ctx, core.MakeEvent([3]label.Label{
- keys.Msg.Of(message),
- keys.Err.Of(err),
- }, labels))
-}
-
-// IsError returns true if the event was built by the Error function.
-// It is intended to be used in exporters to identify the semantics of the
-// event when deciding what to do with it.
-func IsError(ev core.Event) bool {
- return ev.Label(0).Key() == keys.Msg &&
- ev.Label(1).Key() == keys.Err
-}
-
-// Metric sends a label event to the exporter with the supplied labels.
-func Metric(ctx context.Context, labels ...label.Label) {
- core.Export(ctx, core.MakeEvent([3]label.Label{
- keys.Metric.New(),
- }, labels))
-}
-
-// IsMetric returns true if the event was built by the Metric function.
-// It is intended to be used in exporters to identify the semantics of the
-// event when deciding what to do with it.
-func IsMetric(ev core.Event) bool {
- return ev.Label(0).Key() == keys.Metric
-}
-
-// Label sends a label event to the exporter with the supplied labels.
-func Label(ctx context.Context, labels ...label.Label) context.Context {
- return core.Export(ctx, core.MakeEvent([3]label.Label{
- keys.Label.New(),
- }, labels))
-}
-
-// IsLabel returns true if the event was built by the Label function.
-// It is intended to be used in exporters to identify the semantics of the
-// event when deciding what to do with it.
-func IsLabel(ev core.Event) bool {
- return ev.Label(0).Key() == keys.Label
-}
-
-// Start sends a span start event with the supplied label list to the exporter.
-// It also returns a function that will end the span, which should normally be
-// deferred.
-func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) {
- return core.ExportPair(ctx,
- core.MakeEvent([3]label.Label{
- keys.Start.Of(name),
- }, labels),
- core.MakeEvent([3]label.Label{
- keys.End.New(),
- }, nil))
-}
-
-// IsStart returns true if the event was built by the Start function.
-// It is intended to be used in exporters to identify the semantics of the
-// event when deciding what to do with it.
-func IsStart(ev core.Event) bool {
- return ev.Label(0).Key() == keys.Start
-}
-
-// IsEnd returns true if the event was built by the End function.
-// It is intended to be used in exporters to identify the semantics of the
-// event when deciding what to do with it.
-func IsEnd(ev core.Event) bool {
- return ev.Label(0).Key() == keys.End
-}
-
-// Detach returns a context without an associated span.
-// This allows the creation of spans that are not children of the current span.
-func Detach(ctx context.Context) context.Context {
- return core.Export(ctx, core.MakeEvent([3]label.Label{
- keys.Detach.New(),
- }, nil))
-}
-
-// IsDetach returns true if the event was built by the Detach function.
-// It is intended to be used in exporters to identify the semantics of the
-// event when deciding what to do with it.
-func IsDetach(ev core.Event) bool {
- return ev.Label(0).Key() == keys.Detach
-}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/keys.go b/vendor/golang.org/x/tools/internal/event/keys/keys.go
deleted file mode 100644
index a02206e30..000000000
--- a/vendor/golang.org/x/tools/internal/event/keys/keys.go
+++ /dev/null
@@ -1,564 +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 keys
-
-import (
- "fmt"
- "io"
- "math"
- "strconv"
-
- "golang.org/x/tools/internal/event/label"
-)
-
-// Value represents a key for untyped values.
-type Value struct {
- name string
- description string
-}
-
-// New creates a new Key for untyped values.
-func New(name, description string) *Value {
- return &Value{name: name, description: description}
-}
-
-func (k *Value) Name() string { return k.name }
-func (k *Value) Description() string { return k.description }
-
-func (k *Value) Format(w io.Writer, buf []byte, l label.Label) {
- fmt.Fprint(w, k.From(l))
-}
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Value) Get(lm label.Map) interface{} {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return nil
-}
-
-// From can be used to get a value from a Label.
-func (k *Value) From(t label.Label) interface{} { return t.UnpackValue() }
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Value) Of(value interface{}) label.Label { return label.OfValue(k, value) }
-
-// Tag represents a key for tagging labels that have no value.
-// These are used when the existence of the label is the entire information it
-// carries, such as marking events to be of a specific kind, or from a specific
-// package.
-type Tag struct {
- name string
- description string
-}
-
-// NewTag creates a new Key for tagging labels.
-func NewTag(name, description string) *Tag {
- return &Tag{name: name, description: description}
-}
-
-func (k *Tag) Name() string { return k.name }
-func (k *Tag) Description() string { return k.description }
-
-func (k *Tag) Format(w io.Writer, buf []byte, l label.Label) {}
-
-// New creates a new Label with this key.
-func (k *Tag) New() label.Label { return label.OfValue(k, nil) }
-
-// Int represents a key
-type Int struct {
- name string
- description string
-}
-
-// NewInt creates a new Key for int values.
-func NewInt(name, description string) *Int {
- return &Int{name: name, description: description}
-}
-
-func (k *Int) Name() string { return k.name }
-func (k *Int) Description() string { return k.description }
-
-func (k *Int) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Int) Of(v int) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Int) Get(lm label.Map) int {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *Int) From(t label.Label) int { return int(t.Unpack64()) }
-
-// Int8 represents a key
-type Int8 struct {
- name string
- description string
-}
-
-// NewInt8 creates a new Key for int8 values.
-func NewInt8(name, description string) *Int8 {
- return &Int8{name: name, description: description}
-}
-
-func (k *Int8) Name() string { return k.name }
-func (k *Int8) Description() string { return k.description }
-
-func (k *Int8) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Int8) Of(v int8) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Int8) Get(lm label.Map) int8 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *Int8) From(t label.Label) int8 { return int8(t.Unpack64()) }
-
-// Int16 represents a key
-type Int16 struct {
- name string
- description string
-}
-
-// NewInt16 creates a new Key for int16 values.
-func NewInt16(name, description string) *Int16 {
- return &Int16{name: name, description: description}
-}
-
-func (k *Int16) Name() string { return k.name }
-func (k *Int16) Description() string { return k.description }
-
-func (k *Int16) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Int16) Of(v int16) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Int16) Get(lm label.Map) int16 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *Int16) From(t label.Label) int16 { return int16(t.Unpack64()) }
-
-// Int32 represents a key
-type Int32 struct {
- name string
- description string
-}
-
-// NewInt32 creates a new Key for int32 values.
-func NewInt32(name, description string) *Int32 {
- return &Int32{name: name, description: description}
-}
-
-func (k *Int32) Name() string { return k.name }
-func (k *Int32) Description() string { return k.description }
-
-func (k *Int32) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendInt(buf, int64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Int32) Of(v int32) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Int32) Get(lm label.Map) int32 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *Int32) From(t label.Label) int32 { return int32(t.Unpack64()) }
-
-// Int64 represents a key
-type Int64 struct {
- name string
- description string
-}
-
-// NewInt64 creates a new Key for int64 values.
-func NewInt64(name, description string) *Int64 {
- return &Int64{name: name, description: description}
-}
-
-func (k *Int64) Name() string { return k.name }
-func (k *Int64) Description() string { return k.description }
-
-func (k *Int64) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendInt(buf, k.From(l), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Int64) Of(v int64) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Int64) Get(lm label.Map) int64 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *Int64) From(t label.Label) int64 { return int64(t.Unpack64()) }
-
-// UInt represents a key
-type UInt struct {
- name string
- description string
-}
-
-// NewUInt creates a new Key for uint values.
-func NewUInt(name, description string) *UInt {
- return &UInt{name: name, description: description}
-}
-
-func (k *UInt) Name() string { return k.name }
-func (k *UInt) Description() string { return k.description }
-
-func (k *UInt) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *UInt) Of(v uint) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *UInt) Get(lm label.Map) uint {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *UInt) From(t label.Label) uint { return uint(t.Unpack64()) }
-
-// UInt8 represents a key
-type UInt8 struct {
- name string
- description string
-}
-
-// NewUInt8 creates a new Key for uint8 values.
-func NewUInt8(name, description string) *UInt8 {
- return &UInt8{name: name, description: description}
-}
-
-func (k *UInt8) Name() string { return k.name }
-func (k *UInt8) Description() string { return k.description }
-
-func (k *UInt8) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *UInt8) Of(v uint8) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *UInt8) Get(lm label.Map) uint8 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *UInt8) From(t label.Label) uint8 { return uint8(t.Unpack64()) }
-
-// UInt16 represents a key
-type UInt16 struct {
- name string
- description string
-}
-
-// NewUInt16 creates a new Key for uint16 values.
-func NewUInt16(name, description string) *UInt16 {
- return &UInt16{name: name, description: description}
-}
-
-func (k *UInt16) Name() string { return k.name }
-func (k *UInt16) Description() string { return k.description }
-
-func (k *UInt16) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *UInt16) Of(v uint16) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *UInt16) Get(lm label.Map) uint16 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *UInt16) From(t label.Label) uint16 { return uint16(t.Unpack64()) }
-
-// UInt32 represents a key
-type UInt32 struct {
- name string
- description string
-}
-
-// NewUInt32 creates a new Key for uint32 values.
-func NewUInt32(name, description string) *UInt32 {
- return &UInt32{name: name, description: description}
-}
-
-func (k *UInt32) Name() string { return k.name }
-func (k *UInt32) Description() string { return k.description }
-
-func (k *UInt32) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendUint(buf, uint64(k.From(l)), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *UInt32) Of(v uint32) label.Label { return label.Of64(k, uint64(v)) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *UInt32) Get(lm label.Map) uint32 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *UInt32) From(t label.Label) uint32 { return uint32(t.Unpack64()) }
-
-// UInt64 represents a key
-type UInt64 struct {
- name string
- description string
-}
-
-// NewUInt64 creates a new Key for uint64 values.
-func NewUInt64(name, description string) *UInt64 {
- return &UInt64{name: name, description: description}
-}
-
-func (k *UInt64) Name() string { return k.name }
-func (k *UInt64) Description() string { return k.description }
-
-func (k *UInt64) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendUint(buf, k.From(l), 10))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *UInt64) Of(v uint64) label.Label { return label.Of64(k, v) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *UInt64) Get(lm label.Map) uint64 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *UInt64) From(t label.Label) uint64 { return t.Unpack64() }
-
-// Float32 represents a key
-type Float32 struct {
- name string
- description string
-}
-
-// NewFloat32 creates a new Key for float32 values.
-func NewFloat32(name, description string) *Float32 {
- return &Float32{name: name, description: description}
-}
-
-func (k *Float32) Name() string { return k.name }
-func (k *Float32) Description() string { return k.description }
-
-func (k *Float32) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendFloat(buf, float64(k.From(l)), 'E', -1, 32))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Float32) Of(v float32) label.Label {
- return label.Of64(k, uint64(math.Float32bits(v)))
-}
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Float32) Get(lm label.Map) float32 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *Float32) From(t label.Label) float32 {
- return math.Float32frombits(uint32(t.Unpack64()))
-}
-
-// Float64 represents a key
-type Float64 struct {
- name string
- description string
-}
-
-// NewFloat64 creates a new Key for int64 values.
-func NewFloat64(name, description string) *Float64 {
- return &Float64{name: name, description: description}
-}
-
-func (k *Float64) Name() string { return k.name }
-func (k *Float64) Description() string { return k.description }
-
-func (k *Float64) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendFloat(buf, k.From(l), 'E', -1, 64))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Float64) Of(v float64) label.Label {
- return label.Of64(k, math.Float64bits(v))
-}
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Float64) Get(lm label.Map) float64 {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return 0
-}
-
-// From can be used to get a value from a Label.
-func (k *Float64) From(t label.Label) float64 {
- return math.Float64frombits(t.Unpack64())
-}
-
-// String represents a key
-type String struct {
- name string
- description string
-}
-
-// NewString creates a new Key for int64 values.
-func NewString(name, description string) *String {
- return &String{name: name, description: description}
-}
-
-func (k *String) Name() string { return k.name }
-func (k *String) Description() string { return k.description }
-
-func (k *String) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendQuote(buf, k.From(l)))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *String) Of(v string) label.Label { return label.OfString(k, v) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *String) Get(lm label.Map) string {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return ""
-}
-
-// From can be used to get a value from a Label.
-func (k *String) From(t label.Label) string { return t.UnpackString() }
-
-// Boolean represents a key
-type Boolean struct {
- name string
- description string
-}
-
-// NewBoolean creates a new Key for bool values.
-func NewBoolean(name, description string) *Boolean {
- return &Boolean{name: name, description: description}
-}
-
-func (k *Boolean) Name() string { return k.name }
-func (k *Boolean) Description() string { return k.description }
-
-func (k *Boolean) Format(w io.Writer, buf []byte, l label.Label) {
- w.Write(strconv.AppendBool(buf, k.From(l)))
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Boolean) Of(v bool) label.Label {
- if v {
- return label.Of64(k, 1)
- }
- return label.Of64(k, 0)
-}
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Boolean) Get(lm label.Map) bool {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return false
-}
-
-// From can be used to get a value from a Label.
-func (k *Boolean) From(t label.Label) bool { return t.Unpack64() > 0 }
-
-// Error represents a key
-type Error struct {
- name string
- description string
-}
-
-// NewError creates a new Key for int64 values.
-func NewError(name, description string) *Error {
- return &Error{name: name, description: description}
-}
-
-func (k *Error) Name() string { return k.name }
-func (k *Error) Description() string { return k.description }
-
-func (k *Error) Format(w io.Writer, buf []byte, l label.Label) {
- io.WriteString(w, k.From(l).Error())
-}
-
-// Of creates a new Label with this key and the supplied value.
-func (k *Error) Of(v error) label.Label { return label.OfValue(k, v) }
-
-// Get can be used to get a label for the key from a label.Map.
-func (k *Error) Get(lm label.Map) error {
- if t := lm.Find(k); t.Valid() {
- return k.From(t)
- }
- return nil
-}
-
-// From can be used to get a value from a Label.
-func (k *Error) From(t label.Label) error {
- err, _ := t.UnpackValue().(error)
- return err
-}
diff --git a/vendor/golang.org/x/tools/internal/event/keys/standard.go b/vendor/golang.org/x/tools/internal/event/keys/standard.go
deleted file mode 100644
index 7e9586659..000000000
--- a/vendor/golang.org/x/tools/internal/event/keys/standard.go
+++ /dev/null
@@ -1,22 +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 keys
-
-var (
- // Msg is a key used to add message strings to label lists.
- Msg = NewString("message", "a readable message")
- // Label is a key used to indicate an event adds labels to the context.
- Label = NewTag("label", "a label context marker")
- // Start is used for things like traces that have a name.
- Start = NewString("start", "span start")
- // Metric is a key used to indicate an event records metrics.
- End = NewTag("end", "a span end marker")
- // Metric is a key used to indicate an event records metrics.
- Detach = NewTag("detach", "a span detach marker")
- // Err is a key used to add error values to label lists.
- Err = NewError("error", "an error that occurred")
- // Metric is a key used to indicate an event records metrics.
- Metric = NewTag("metric", "a metric event marker")
-)
diff --git a/vendor/golang.org/x/tools/internal/event/label/label.go b/vendor/golang.org/x/tools/internal/event/label/label.go
deleted file mode 100644
index b55c12eb2..000000000
--- a/vendor/golang.org/x/tools/internal/event/label/label.go
+++ /dev/null
@@ -1,213 +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 label
-
-import (
- "fmt"
- "io"
- "reflect"
- "unsafe"
-)
-
-// Key is used as the identity of a Label.
-// Keys are intended to be compared by pointer only, the name should be unique
-// for communicating with external systems, but it is not required or enforced.
-type Key interface {
- // Name returns the key name.
- Name() string
- // Description returns a string that can be used to describe the value.
- Description() string
-
- // Format is used in formatting to append the value of the label to the
- // supplied buffer.
- // The formatter may use the supplied buf as a scratch area to avoid
- // allocations.
- Format(w io.Writer, buf []byte, l Label)
-}
-
-// Label holds a key and value pair.
-// It is normally used when passing around lists of labels.
-type Label struct {
- key Key
- packed uint64
- untyped interface{}
-}
-
-// Map is the interface to a collection of Labels indexed by key.
-type Map interface {
- // Find returns the label that matches the supplied key.
- Find(key Key) Label
-}
-
-// List is the interface to something that provides an iterable
-// list of labels.
-// Iteration should start from 0 and continue until Valid returns false.
-type List interface {
- // Valid returns true if the index is within range for the list.
- // It does not imply the label at that index will itself be valid.
- Valid(index int) bool
- // Label returns the label at the given index.
- Label(index int) Label
-}
-
-// list implements LabelList for a list of Labels.
-type list struct {
- labels []Label
-}
-
-// filter wraps a LabelList filtering out specific labels.
-type filter struct {
- keys []Key
- underlying List
-}
-
-// listMap implements LabelMap for a simple list of labels.
-type listMap struct {
- labels []Label
-}
-
-// mapChain implements LabelMap for a list of underlying LabelMap.
-type mapChain struct {
- maps []Map
-}
-
-// OfValue creates a new label from the key and value.
-// This method is for implementing new key types, label creation should
-// normally be done with the Of method of the key.
-func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} }
-
-// UnpackValue assumes the label was built using LabelOfValue and returns the value
-// that was passed to that constructor.
-// This method is for implementing new key types, for type safety normal
-// access should be done with the From method of the key.
-func (t Label) UnpackValue() interface{} { return t.untyped }
-
-// Of64 creates a new label from a key and a uint64. This is often
-// used for non uint64 values that can be packed into a uint64.
-// This method is for implementing new key types, label creation should
-// normally be done with the Of method of the key.
-func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} }
-
-// Unpack64 assumes the label was built using LabelOf64 and returns the value that
-// was passed to that constructor.
-// This method is for implementing new key types, for type safety normal
-// access should be done with the From method of the key.
-func (t Label) Unpack64() uint64 { return t.packed }
-
-// OfString creates a new label from a key and a string.
-// This method is for implementing new key types, label creation should
-// normally be done with the Of method of the key.
-func OfString(k Key, v string) Label {
- hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
- return Label{
- key: k,
- packed: uint64(hdr.Len),
- untyped: unsafe.Pointer(hdr.Data),
- }
-}
-
-// UnpackString assumes the label was built using LabelOfString and returns the
-// value that was passed to that constructor.
-// This method is for implementing new key types, for type safety normal
-// access should be done with the From method of the key.
-func (t Label) UnpackString() string {
- var v string
- hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
- hdr.Data = uintptr(t.untyped.(unsafe.Pointer))
- hdr.Len = int(t.packed)
- return *(*string)(unsafe.Pointer(hdr))
-}
-
-// Valid returns true if the Label is a valid one (it has a key).
-func (t Label) Valid() bool { return t.key != nil }
-
-// Key returns the key of this Label.
-func (t Label) Key() Key { return t.key }
-
-// Format is used for debug printing of labels.
-func (t Label) Format(f fmt.State, r rune) {
- if !t.Valid() {
- io.WriteString(f, `nil`)
- return
- }
- io.WriteString(f, t.Key().Name())
- io.WriteString(f, "=")
- var buf [128]byte
- t.Key().Format(f, buf[:0], t)
-}
-
-func (l *list) Valid(index int) bool {
- return index >= 0 && index < len(l.labels)
-}
-
-func (l *list) Label(index int) Label {
- return l.labels[index]
-}
-
-func (f *filter) Valid(index int) bool {
- return f.underlying.Valid(index)
-}
-
-func (f *filter) Label(index int) Label {
- l := f.underlying.Label(index)
- for _, f := range f.keys {
- if l.Key() == f {
- return Label{}
- }
- }
- return l
-}
-
-func (lm listMap) Find(key Key) Label {
- for _, l := range lm.labels {
- if l.Key() == key {
- return l
- }
- }
- return Label{}
-}
-
-func (c mapChain) Find(key Key) Label {
- for _, src := range c.maps {
- l := src.Find(key)
- if l.Valid() {
- return l
- }
- }
- return Label{}
-}
-
-var emptyList = &list{}
-
-func NewList(labels ...Label) List {
- if len(labels) == 0 {
- return emptyList
- }
- return &list{labels: labels}
-}
-
-func Filter(l List, keys ...Key) List {
- if len(keys) == 0 {
- return l
- }
- return &filter{keys: keys, underlying: l}
-}
-
-func NewMap(labels ...Label) Map {
- return listMap{labels: labels}
-}
-
-func MergeMaps(srcs ...Map) Map {
- var nonNil []Map
- for _, src := range srcs {
- if src != nil {
- nonNil = append(nonNil, src)
- }
- }
- if len(nonNil) == 1 {
- return nonNil[0]
- }
- return mapChain{maps: nonNil}
-}
diff --git a/vendor/golang.org/x/tools/internal/gocommand/invoke.go b/vendor/golang.org/x/tools/internal/gocommand/invoke.go
deleted file mode 100644
index 9aa798456..000000000
--- a/vendor/golang.org/x/tools/internal/gocommand/invoke.go
+++ /dev/null
@@ -1,187 +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 gocommand is a helper for calling the go command.
-package gocommand
-
-import (
- "bytes"
- "context"
- "fmt"
- "io"
- "os"
- "os/exec"
- "regexp"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/tools/internal/event"
-)
-
-// 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
-}
-
-// 1.13: go: updates to go.mod needed, but contents have changed
-// 1.14: go: updating go.mod: existing contents have changed since last read
-var modConcurrencyError = regexp.MustCompile(`go:.*go.mod.*contents have changed`)
-
-// Run calls Runner.RunRaw, serializing requests if they fight over
-// go.mod changes.
-func (runner *Runner) Run(ctx context.Context, inv Invocation) (*bytes.Buffer, error) {
- stdout, _, friendly, _ := runner.RunRaw(ctx, inv)
- return stdout, friendly
-}
-
-// RunRaw calls Invocation.runRaw, serializing requests if they fight over
-// go.mod changes.
-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 {
- runner.serializeLoads--
- runner.loadMu.Unlock()
- }
- }()
-
- for {
- stdout, stderr, friendlyErr, err := inv.runRaw(ctx)
- 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++
- locked = true
- }
- }
-}
-
-// An Invocation represents a call to the go command.
-type Invocation struct {
- Verb string
- Args []string
- BuildFlags []string
- Env []string
- WorkingDir string
- Logf func(format string, args ...interface{})
-}
-
-// RunRaw is like RunPiped, but also returns the raw stderr and error for callers
-// that want to do low-level error handling/recovery.
-func (i *Invocation) runRaw(ctx context.Context) (stdout *bytes.Buffer, stderr *bytes.Buffer, friendlyError error, rawError error) {
- stdout = &bytes.Buffer{}
- stderr = &bytes.Buffer{}
- rawError = i.RunPiped(ctx, stdout, stderr)
- if rawError != nil {
- friendlyError = rawError
- // Check for 'go' executable not being found.
- if ee, ok := rawError.(*exec.Error); ok && ee.Err == exec.ErrNotFound {
- friendlyError = fmt.Errorf("go command required, not found: %v", ee)
- }
- if ctx.Err() != nil {
- friendlyError = ctx.Err()
- }
- friendlyError = fmt.Errorf("err: %v: stderr: %s", friendlyError, stderr)
- }
- return
-}
-
-// RunPiped is like Run, but relies on the given stdout/stderr
-func (i *Invocation) RunPiped(ctx context.Context, stdout, stderr io.Writer) error {
- log := i.Logf
- if log == nil {
- log = func(string, ...interface{}) {}
- }
-
- goArgs := []string{i.Verb}
- switch i.Verb {
- case "mod":
- // mod needs the sub-verb before build flags.
- goArgs = append(goArgs, i.Args[0])
- goArgs = append(goArgs, i.BuildFlags...)
- goArgs = append(goArgs, i.Args[1:]...)
- case "env":
- // env doesn't take build flags.
- goArgs = append(goArgs, i.Args...)
- default:
- goArgs = append(goArgs, i.BuildFlags...)
- goArgs = append(goArgs, i.Args...)
- }
- cmd := exec.Command("go", goArgs...)
- cmd.Stdout = stdout
- cmd.Stderr = stderr
- // On darwin the cwd gets resolved to the real path, which breaks anything that
- // expects the working directory to keep the original path, including the
- // go command when dealing with modules.
- // The Go stdlib has a special feature where if the cwd and the PWD are the
- // same node then it trusts the PWD, so by setting it in the env for the child
- // process we fix up all the paths returned by the go command.
- cmd.Env = append(os.Environ(), i.Env...)
- if i.WorkingDir != "" {
- 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)
-}
-
-// runCmdContext is like exec.CommandContext except it sends os.Interrupt
-// before os.Kill.
-func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
- if err := cmd.Start(); err != nil {
- return err
- }
- resChan := make(chan error, 1)
- go func() {
- resChan <- cmd.Wait()
- }()
-
- select {
- case err := <-resChan:
- return err
- case <-ctx.Done():
- }
- // Cancelled. Interrupt and see if it ends voluntarily.
- cmd.Process.Signal(os.Interrupt)
- select {
- case err := <-resChan:
- return err
- case <-time.After(time.Second):
- }
- // Didn't shut down in response to interrupt. Kill it hard.
- cmd.Process.Kill()
- return <-resChan
-}
-
-func cmdDebugStr(cmd *exec.Cmd) string {
- env := make(map[string]string)
- for _, kv := range cmd.Env {
- split := strings.Split(kv, "=")
- k, v := split[0], split[1]
- env[k] = v
- }
-
- return fmt.Sprintf("GOROOT=%v GOPATH=%v GO111MODULE=%v GOPROXY=%v PWD=%v go %v", env["GOROOT"], env["GOPATH"], env["GO111MODULE"], env["GOPROXY"], env["PWD"], cmd.Args)
-}
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 ff5a6b17d..000000000
--- a/vendor/golang.org/x/tools/internal/packagesinternal/packages.go
+++ /dev/null
@@ -1,12 +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) {}
diff --git a/vendor/golang.org/x/xerrors/LICENSE b/vendor/golang.org/x/xerrors/LICENSE
deleted file mode 100644
index e4a47e17f..000000000
--- a/vendor/golang.org/x/xerrors/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2019 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.
diff --git a/vendor/golang.org/x/xerrors/PATENTS b/vendor/golang.org/x/xerrors/PATENTS
deleted file mode 100644
index 733099041..000000000
--- a/vendor/golang.org/x/xerrors/PATENTS
+++ /dev/null
@@ -1,22 +0,0 @@
-Additional IP Rights Grant (Patents)
-
-"This implementation" means the copyrightable works distributed by
-Google as part of the Go project.
-
-Google hereby grants to You a perpetual, worldwide, non-exclusive,
-no-charge, royalty-free, irrevocable (except as stated in this section)
-patent license to make, have made, use, offer to sell, sell, import,
-transfer and otherwise run, modify and propagate the contents of this
-implementation of Go, where such license applies only to those patent
-claims, both currently owned or controlled by Google and acquired in
-the future, licensable by Google that are necessarily infringed by this
-implementation of Go. This grant does not include claims that would be
-infringed only as a consequence of further modification of this
-implementation. If you or your agent or exclusive licensee institute or
-order or agree to the institution of patent litigation against any
-entity (including a cross-claim or counterclaim in a lawsuit) alleging
-that this implementation of Go or any code incorporated within this
-implementation of Go constitutes direct or contributory patent
-infringement, or inducement of patent infringement, then any patent
-rights granted to you under this License for this implementation of Go
-shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/xerrors/README b/vendor/golang.org/x/xerrors/README
deleted file mode 100644
index aac7867a5..000000000
--- a/vendor/golang.org/x/xerrors/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This repository holds the transition packages for the new Go 1.13 error values.
-See golang.org/design/29934-error-values.
diff --git a/vendor/golang.org/x/xerrors/adaptor.go b/vendor/golang.org/x/xerrors/adaptor.go
deleted file mode 100644
index 4317f2483..000000000
--- a/vendor/golang.org/x/xerrors/adaptor.go
+++ /dev/null
@@ -1,193 +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 xerrors
-
-import (
- "bytes"
- "fmt"
- "io"
- "reflect"
- "strconv"
-)
-
-// FormatError calls the FormatError method of f with an errors.Printer
-// configured according to s and verb, and writes the result to s.
-func FormatError(f Formatter, s fmt.State, verb rune) {
- // Assuming this function is only called from the Format method, and given
- // that FormatError takes precedence over Format, it cannot be called from
- // any package that supports errors.Formatter. It is therefore safe to
- // disregard that State may be a specific printer implementation and use one
- // of our choice instead.
-
- // limitations: does not support printing error as Go struct.
-
- var (
- sep = " " // separator before next error
- p = &state{State: s}
- direct = true
- )
-
- var err error = f
-
- switch verb {
- // Note that this switch must match the preference order
- // for ordinary string printing (%#v before %+v, and so on).
-
- case 'v':
- if s.Flag('#') {
- if stringer, ok := err.(fmt.GoStringer); ok {
- io.WriteString(&p.buf, stringer.GoString())
- goto exit
- }
- // proceed as if it were %v
- } else if s.Flag('+') {
- p.printDetail = true
- sep = "\n - "
- }
- case 's':
- case 'q', 'x', 'X':
- // Use an intermediate buffer in the rare cases that precision,
- // truncation, or one of the alternative verbs (q, x, and X) are
- // specified.
- direct = false
-
- default:
- p.buf.WriteString("%!")
- p.buf.WriteRune(verb)
- p.buf.WriteByte('(')
- switch {
- case err != nil:
- p.buf.WriteString(reflect.TypeOf(f).String())
- default:
- p.buf.WriteString("")
- }
- p.buf.WriteByte(')')
- io.Copy(s, &p.buf)
- return
- }
-
-loop:
- for {
- switch v := err.(type) {
- case Formatter:
- err = v.FormatError((*printer)(p))
- case fmt.Formatter:
- v.Format(p, 'v')
- break loop
- default:
- io.WriteString(&p.buf, v.Error())
- break loop
- }
- if err == nil {
- break
- }
- if p.needColon || !p.printDetail {
- p.buf.WriteByte(':')
- p.needColon = false
- }
- p.buf.WriteString(sep)
- p.inDetail = false
- p.needNewline = false
- }
-
-exit:
- width, okW := s.Width()
- prec, okP := s.Precision()
-
- if !direct || (okW && width > 0) || okP {
- // Construct format string from State s.
- format := []byte{'%'}
- if s.Flag('-') {
- format = append(format, '-')
- }
- if s.Flag('+') {
- format = append(format, '+')
- }
- if s.Flag(' ') {
- format = append(format, ' ')
- }
- if okW {
- format = strconv.AppendInt(format, int64(width), 10)
- }
- if okP {
- format = append(format, '.')
- format = strconv.AppendInt(format, int64(prec), 10)
- }
- format = append(format, string(verb)...)
- fmt.Fprintf(s, string(format), p.buf.String())
- } else {
- io.Copy(s, &p.buf)
- }
-}
-
-var detailSep = []byte("\n ")
-
-// state tracks error printing state. It implements fmt.State.
-type state struct {
- fmt.State
- buf bytes.Buffer
-
- printDetail bool
- inDetail bool
- needColon bool
- needNewline bool
-}
-
-func (s *state) Write(b []byte) (n int, err error) {
- if s.printDetail {
- if len(b) == 0 {
- return 0, nil
- }
- if s.inDetail && s.needColon {
- s.needNewline = true
- if b[0] == '\n' {
- b = b[1:]
- }
- }
- k := 0
- for i, c := range b {
- if s.needNewline {
- if s.inDetail && s.needColon {
- s.buf.WriteByte(':')
- s.needColon = false
- }
- s.buf.Write(detailSep)
- s.needNewline = false
- }
- if c == '\n' {
- s.buf.Write(b[k:i])
- k = i + 1
- s.needNewline = true
- }
- }
- s.buf.Write(b[k:])
- if !s.inDetail {
- s.needColon = true
- }
- } else if !s.inDetail {
- s.buf.Write(b)
- }
- return len(b), nil
-}
-
-// printer wraps a state to implement an xerrors.Printer.
-type printer state
-
-func (s *printer) Print(args ...interface{}) {
- if !s.inDetail || s.printDetail {
- fmt.Fprint((*state)(s), args...)
- }
-}
-
-func (s *printer) Printf(format string, args ...interface{}) {
- if !s.inDetail || s.printDetail {
- fmt.Fprintf((*state)(s), format, args...)
- }
-}
-
-func (s *printer) Detail() bool {
- s.inDetail = true
- return s.printDetail
-}
diff --git a/vendor/golang.org/x/xerrors/codereview.cfg b/vendor/golang.org/x/xerrors/codereview.cfg
deleted file mode 100644
index 3f8b14b64..000000000
--- a/vendor/golang.org/x/xerrors/codereview.cfg
+++ /dev/null
@@ -1 +0,0 @@
-issuerepo: golang/go
diff --git a/vendor/golang.org/x/xerrors/doc.go b/vendor/golang.org/x/xerrors/doc.go
deleted file mode 100644
index eef99d9d5..000000000
--- a/vendor/golang.org/x/xerrors/doc.go
+++ /dev/null
@@ -1,22 +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 xerrors implements functions to manipulate errors.
-//
-// This package is based on the Go 2 proposal for error values:
-// https://golang.org/design/29934-error-values
-//
-// These functions were incorporated into the standard library's errors package
-// in Go 1.13:
-// - Is
-// - As
-// - Unwrap
-//
-// Also, Errorf's %w verb was incorporated into fmt.Errorf.
-//
-// Use this package to get equivalent behavior in all supported Go versions.
-//
-// No other features of this package were included in Go 1.13, and at present
-// there are no plans to include any of them.
-package xerrors // import "golang.org/x/xerrors"
diff --git a/vendor/golang.org/x/xerrors/errors.go b/vendor/golang.org/x/xerrors/errors.go
deleted file mode 100644
index e88d3772d..000000000
--- a/vendor/golang.org/x/xerrors/errors.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2011 The Go 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 xerrors
-
-import "fmt"
-
-// errorString is a trivial implementation of error.
-type errorString struct {
- s string
- frame Frame
-}
-
-// New returns an error that formats as the given text.
-//
-// The returned error contains a Frame set to the caller's location and
-// implements Formatter to show this information when printed with details.
-func New(text string) error {
- return &errorString{text, Caller(1)}
-}
-
-func (e *errorString) Error() string {
- return e.s
-}
-
-func (e *errorString) Format(s fmt.State, v rune) { FormatError(e, s, v) }
-
-func (e *errorString) FormatError(p Printer) (next error) {
- p.Print(e.s)
- e.frame.Format(p)
- return nil
-}
diff --git a/vendor/golang.org/x/xerrors/fmt.go b/vendor/golang.org/x/xerrors/fmt.go
deleted file mode 100644
index 829862ddf..000000000
--- a/vendor/golang.org/x/xerrors/fmt.go
+++ /dev/null
@@ -1,187 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-import (
- "fmt"
- "strings"
- "unicode"
- "unicode/utf8"
-
- "golang.org/x/xerrors/internal"
-)
-
-const percentBangString = "%!"
-
-// Errorf formats according to a format specifier and returns the string as a
-// value that satisfies error.
-//
-// The returned error includes the file and line number of the caller when
-// formatted with additional detail enabled. If the last argument is an error
-// the returned error's Format method will return it if the format string ends
-// with ": %s", ": %v", or ": %w". If the last argument is an error and the
-// format string ends with ": %w", the returned error implements an Unwrap
-// method returning it.
-//
-// If the format specifier includes a %w verb with an error operand in a
-// position other than at the end, the returned error will still implement an
-// Unwrap method returning the operand, but the error's Format method will not
-// return the wrapped error.
-//
-// It is invalid to include more than one %w verb or to supply it with an
-// operand that does not implement the error interface. The %w verb is otherwise
-// a synonym for %v.
-func Errorf(format string, a ...interface{}) error {
- format = formatPlusW(format)
- // Support a ": %[wsv]" suffix, which works well with xerrors.Formatter.
- wrap := strings.HasSuffix(format, ": %w")
- idx, format2, ok := parsePercentW(format)
- percentWElsewhere := !wrap && idx >= 0
- if !percentWElsewhere && (wrap || strings.HasSuffix(format, ": %s") || strings.HasSuffix(format, ": %v")) {
- err := errorAt(a, len(a)-1)
- if err == nil {
- return &noWrapError{fmt.Sprintf(format, a...), nil, Caller(1)}
- }
- // TODO: this is not entirely correct. The error value could be
- // printed elsewhere in format if it mixes numbered with unnumbered
- // substitutions. With relatively small changes to doPrintf we can
- // have it optionally ignore extra arguments and pass the argument
- // list in its entirety.
- msg := fmt.Sprintf(format[:len(format)-len(": %s")], a[:len(a)-1]...)
- frame := Frame{}
- if internal.EnableTrace {
- frame = Caller(1)
- }
- if wrap {
- return &wrapError{msg, err, frame}
- }
- return &noWrapError{msg, err, frame}
- }
- // Support %w anywhere.
- // TODO: don't repeat the wrapped error's message when %w occurs in the middle.
- msg := fmt.Sprintf(format2, a...)
- if idx < 0 {
- return &noWrapError{msg, nil, Caller(1)}
- }
- err := errorAt(a, idx)
- if !ok || err == nil {
- // Too many %ws or argument of %w is not an error. Approximate the Go
- // 1.13 fmt.Errorf message.
- return &noWrapError{fmt.Sprintf("%sw(%s)", percentBangString, msg), nil, Caller(1)}
- }
- frame := Frame{}
- if internal.EnableTrace {
- frame = Caller(1)
- }
- return &wrapError{msg, err, frame}
-}
-
-func errorAt(args []interface{}, i int) error {
- if i < 0 || i >= len(args) {
- return nil
- }
- err, ok := args[i].(error)
- if !ok {
- return nil
- }
- return err
-}
-
-// formatPlusW is used to avoid the vet check that will barf at %w.
-func formatPlusW(s string) string {
- return s
-}
-
-// Return the index of the only %w in format, or -1 if none.
-// Also return a rewritten format string with %w replaced by %v, and
-// false if there is more than one %w.
-// TODO: handle "%[N]w".
-func parsePercentW(format string) (idx int, newFormat string, ok bool) {
- // Loosely copied from golang.org/x/tools/go/analysis/passes/printf/printf.go.
- idx = -1
- ok = true
- n := 0
- sz := 0
- var isW bool
- for i := 0; i < len(format); i += sz {
- if format[i] != '%' {
- sz = 1
- continue
- }
- // "%%" is not a format directive.
- if i+1 < len(format) && format[i+1] == '%' {
- sz = 2
- continue
- }
- sz, isW = parsePrintfVerb(format[i:])
- if isW {
- if idx >= 0 {
- ok = false
- } else {
- idx = n
- }
- // "Replace" the last character, the 'w', with a 'v'.
- p := i + sz - 1
- format = format[:p] + "v" + format[p+1:]
- }
- n++
- }
- return idx, format, ok
-}
-
-// Parse the printf verb starting with a % at s[0].
-// Return how many bytes it occupies and whether the verb is 'w'.
-func parsePrintfVerb(s string) (int, bool) {
- // Assume only that the directive is a sequence of non-letters followed by a single letter.
- sz := 0
- var r rune
- for i := 1; i < len(s); i += sz {
- r, sz = utf8.DecodeRuneInString(s[i:])
- if unicode.IsLetter(r) {
- return i + sz, r == 'w'
- }
- }
- return len(s), false
-}
-
-type noWrapError struct {
- msg string
- err error
- frame Frame
-}
-
-func (e *noWrapError) Error() string {
- return fmt.Sprint(e)
-}
-
-func (e *noWrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }
-
-func (e *noWrapError) FormatError(p Printer) (next error) {
- p.Print(e.msg)
- e.frame.Format(p)
- return e.err
-}
-
-type wrapError struct {
- msg string
- err error
- frame Frame
-}
-
-func (e *wrapError) Error() string {
- return fmt.Sprint(e)
-}
-
-func (e *wrapError) Format(s fmt.State, v rune) { FormatError(e, s, v) }
-
-func (e *wrapError) FormatError(p Printer) (next error) {
- p.Print(e.msg)
- e.frame.Format(p)
- return e.err
-}
-
-func (e *wrapError) Unwrap() error {
- return e.err
-}
diff --git a/vendor/golang.org/x/xerrors/format.go b/vendor/golang.org/x/xerrors/format.go
deleted file mode 100644
index 1bc9c26b9..000000000
--- a/vendor/golang.org/x/xerrors/format.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xerrors
-
-// A Formatter formats error messages.
-type Formatter interface {
- error
-
- // FormatError prints the receiver's first error and returns the next error in
- // the error chain, if any.
- FormatError(p Printer) (next error)
-}
-
-// A Printer formats error messages.
-//
-// The most common implementation of Printer is the one provided by package fmt
-// during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message
-// typically provide their own implementations.
-type Printer interface {
- // Print appends args to the message output.
- Print(args ...interface{})
-
- // Printf writes a formatted string.
- Printf(format string, args ...interface{})
-
- // Detail reports whether error detail is requested.
- // After the first call to Detail, all text written to the Printer
- // is formatted as additional detail, or ignored when
- // detail has not been requested.
- // If Detail returns false, the caller can avoid printing the detail at all.
- Detail() bool
-}
diff --git a/vendor/golang.org/x/xerrors/frame.go b/vendor/golang.org/x/xerrors/frame.go
deleted file mode 100644
index 0de628ec5..000000000
--- a/vendor/golang.org/x/xerrors/frame.go
+++ /dev/null
@@ -1,56 +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 xerrors
-
-import (
- "runtime"
-)
-
-// A Frame contains part of a call stack.
-type Frame struct {
- // Make room for three PCs: the one we were asked for, what it called,
- // and possibly a PC for skipPleaseUseCallersFrames. See:
- // https://go.googlesource.com/go/+/032678e0fb/src/runtime/extern.go#169
- frames [3]uintptr
-}
-
-// Caller returns a Frame that describes a frame on the caller's stack.
-// The argument skip is the number of frames to skip over.
-// Caller(0) returns the frame for the caller of Caller.
-func Caller(skip int) Frame {
- var s Frame
- runtime.Callers(skip+1, s.frames[:])
- return s
-}
-
-// location reports the file, line, and function of a frame.
-//
-// The returned function may be "" even if file and line are not.
-func (f Frame) location() (function, file string, line int) {
- frames := runtime.CallersFrames(f.frames[:])
- if _, ok := frames.Next(); !ok {
- return "", "", 0
- }
- fr, ok := frames.Next()
- if !ok {
- return "", "", 0
- }
- return fr.Function, fr.File, fr.Line
-}
-
-// Format prints the stack as error detail.
-// It should be called from an error's Format implementation
-// after printing any other error detail.
-func (f Frame) Format(p Printer) {
- if p.Detail() {
- function, file, line := f.location()
- if function != "" {
- p.Printf("%s\n ", function)
- }
- if file != "" {
- p.Printf("%s:%d\n", file, line)
- }
- }
-}
diff --git a/vendor/golang.org/x/xerrors/go.mod b/vendor/golang.org/x/xerrors/go.mod
deleted file mode 100644
index 870d4f612..000000000
--- a/vendor/golang.org/x/xerrors/go.mod
+++ /dev/null
@@ -1,3 +0,0 @@
-module golang.org/x/xerrors
-
-go 1.11
diff --git a/vendor/golang.org/x/xerrors/internal/internal.go b/vendor/golang.org/x/xerrors/internal/internal.go
deleted file mode 100644
index 89f4eca5d..000000000
--- a/vendor/golang.org/x/xerrors/internal/internal.go
+++ /dev/null
@@ -1,8 +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 internal
-
-// EnableTrace indicates whether stack information should be recorded in errors.
-var EnableTrace = true
diff --git a/vendor/golang.org/x/xerrors/wrap.go b/vendor/golang.org/x/xerrors/wrap.go
deleted file mode 100644
index 9a3b51037..000000000
--- a/vendor/golang.org/x/xerrors/wrap.go
+++ /dev/null
@@ -1,106 +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 xerrors
-
-import (
- "reflect"
-)
-
-// A Wrapper provides context around another error.
-type Wrapper interface {
- // Unwrap returns the next error in the error chain.
- // If there is no next error, Unwrap returns nil.
- Unwrap() error
-}
-
-// Opaque returns an error with the same error formatting as err
-// but that does not match err and cannot be unwrapped.
-func Opaque(err error) error {
- return noWrapper{err}
-}
-
-type noWrapper struct {
- error
-}
-
-func (e noWrapper) FormatError(p Printer) (next error) {
- if f, ok := e.error.(Formatter); ok {
- return f.FormatError(p)
- }
- p.Print(e.error)
- return nil
-}
-
-// Unwrap returns the result of calling the Unwrap method on err, if err implements
-// Unwrap. Otherwise, Unwrap returns nil.
-func Unwrap(err error) error {
- u, ok := err.(Wrapper)
- if !ok {
- return nil
- }
- return u.Unwrap()
-}
-
-// Is reports whether any error in err's chain matches target.
-//
-// An error is considered to match a target if it is equal to that target or if
-// it implements a method Is(error) bool such that Is(target) returns true.
-func Is(err, target error) bool {
- if target == nil {
- return err == target
- }
-
- isComparable := reflect.TypeOf(target).Comparable()
- for {
- if isComparable && err == target {
- return true
- }
- if x, ok := err.(interface{ Is(error) bool }); ok && x.Is(target) {
- return true
- }
- // TODO: consider supporing target.Is(err). This would allow
- // user-definable predicates, but also may allow for coping with sloppy
- // APIs, thereby making it easier to get away with them.
- if err = Unwrap(err); err == nil {
- return false
- }
- }
-}
-
-// As finds the first error in err's chain that matches the type to which target
-// points, and if so, sets the target to its value and returns true. An error
-// matches a type if it is assignable to the target type, or if it has a method
-// As(interface{}) bool such that As(target) returns true. As will panic if target
-// is not a non-nil pointer to a type which implements error or is of interface type.
-//
-// The As method should set the target to its value and return true if err
-// matches the type to which target points.
-func As(err error, target interface{}) bool {
- if target == nil {
- panic("errors: target cannot be nil")
- }
- val := reflect.ValueOf(target)
- typ := val.Type()
- if typ.Kind() != reflect.Ptr || val.IsNil() {
- panic("errors: target must be a non-nil pointer")
- }
- if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) {
- panic("errors: *target must be interface or implement error")
- }
- targetType := typ.Elem()
- for err != nil {
- if reflect.TypeOf(err).AssignableTo(targetType) {
- val.Elem().Set(reflect.ValueOf(err))
- return true
- }
- if x, ok := err.(interface{ As(interface{}) bool }); ok && x.As(target) {
- return true
- }
- err = Unwrap(err)
- }
- return false
-}
-
-var errorType = reflect.TypeOf((*error)(nil)).Elem()
diff --git a/vendor/google.golang.org/appengine/.travis.yml b/vendor/google.golang.org/appengine/.travis.yml
index 6d03f4d36..70ffe89d5 100644
--- a/vendor/google.golang.org/appengine/.travis.yml
+++ b/vendor/google.golang.org/appengine/.travis.yml
@@ -10,6 +10,8 @@ script:
matrix:
include:
+ - go: 1.8.x
+ env: GOAPP=true
- go: 1.9.x
env: GOAPP=true
- go: 1.10.x
diff --git a/vendor/google.golang.org/appengine/go.mod b/vendor/google.golang.org/appengine/go.mod
index 635c34f5a..451592798 100644
--- a/vendor/google.golang.org/appengine/go.mod
+++ b/vendor/google.golang.org/appengine/go.mod
@@ -1,9 +1,10 @@
module google.golang.org/appengine
-go 1.11
-
require (
github.com/golang/protobuf v1.3.1
+ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect
golang.org/x/net v0.0.0-20190603091049-60506f45cf65
+ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c // indirect
golang.org/x/text v0.3.2
+ golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b // indirect
)
diff --git a/vendor/google.golang.org/appengine/go.sum b/vendor/google.golang.org/appengine/go.sum
index ce22f6856..cb3232556 100644
--- a/vendor/google.golang.org/appengine/go.sum
+++ b/vendor/google.golang.org/appengine/go.sum
@@ -1,11 +1,22 @@
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225 h1:kNX+jCowfMYzvlSvJu5pQWEmyWFrBXJ3PBy10xKMXK8=
+golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
diff --git a/vendor/google.golang.org/appengine/internal/api.go b/vendor/google.golang.org/appengine/internal/api.go
index 721053c20..a6ec19e14 100644
--- a/vendor/google.golang.org/appengine/internal/api.go
+++ b/vendor/google.golang.org/appengine/internal/api.go
@@ -58,11 +58,8 @@ var (
apiHTTPClient = &http.Client{
Transport: &http.Transport{
- Proxy: http.ProxyFromEnvironment,
- Dial: limitDial,
- MaxIdleConns: 1000,
- MaxIdleConnsPerHost: 10000,
- IdleConnTimeout: 90 * time.Second,
+ Proxy: http.ProxyFromEnvironment,
+ Dial: limitDial,
},
}
diff --git a/vendor/google.golang.org/appengine/internal/net.go b/vendor/google.golang.org/appengine/internal/net.go
index fe429720e..3b94cf0c6 100644
--- a/vendor/google.golang.org/appengine/internal/net.go
+++ b/vendor/google.golang.org/appengine/internal/net.go
@@ -32,7 +32,7 @@ func limitDial(network, addr string) (net.Conn, error) {
// Dial with a timeout in case the API host is MIA.
// The connection should normally be very fast.
- conn, err := net.DialTimeout(network, addr, 10*time.Second)
+ conn, err := net.DialTimeout(network, addr, 500*time.Millisecond)
if err != nil {
limitRelease()
return nil, err
diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go
index d2c2308f1..1f7e87e67 100644
--- a/vendor/gopkg.in/yaml.v2/apic.go
+++ b/vendor/gopkg.in/yaml.v2/apic.go
@@ -86,7 +86,6 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) {
raw_buffer: make([]byte, 0, output_raw_buffer_size),
states: make([]yaml_emitter_state_t, 0, initial_stack_size),
events: make([]yaml_event_t, 0, initial_queue_size),
- best_width: -1,
}
}
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 7c241b71a..000000000
--- a/vendor/honnef.co/go/tools/LICENSE-THIRD-PARTY
+++ /dev/null
@@ -1,226 +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.
-
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/config/config.go b/vendor/honnef.co/go/tools/config/config.go
deleted file mode 100644
index c22093a6d..000000000
--- a/vendor/honnef.co/go/tools/config/config.go
+++ /dev/null
@@ -1,224 +0,0 @@
-package config
-
-import (
- "bytes"
- "fmt"
- "os"
- "path/filepath"
- "reflect"
- "strings"
-
- "github.com/BurntSushi/toml"
- "golang.org/x/tools/go/analysis"
-)
-
-var Analyzer = &analysis.Analyzer{
- Name: "config",
- Doc: "loads configuration for the current package tree",
- Run: func(pass *analysis.Pass) (interface{}, error) {
- if len(pass.Files) == 0 {
- cfg := DefaultConfig
- return &cfg, nil
- }
- cache, err := os.UserCacheDir()
- if err != nil {
- cache = ""
- }
- var path string
- for _, f := range pass.Files {
- p := pass.Fset.PositionFor(f.Pos(), true).Filename
- // 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.
- cfg := DefaultConfig
- return &cfg, nil
- }
-
- dir := filepath.Dir(path)
- 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"},
- 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",
- },
- 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 5d8ce186b..000000000
--- a/vendor/honnef.co/go/tools/deprecated/stdlib.go
+++ /dev/null
@@ -1,112 +0,0 @@
-package deprecated
-
-type Deprecation struct {
- DeprecatedSince int
- AlternativeAvailableSince int
-}
-
-var Stdlib = map[string]Deprecation{
- "image/jpeg.Reader": {4, 0},
- // 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},
-
- // 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},
- "InterfaceAnnounceMessage": {7, 0},
- "InterfaceMulticastAddrMessage": {7, 0},
- "syscall.FormatMessage": {5, 0},
-}
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 1ed9563a3..000000000
--- a/vendor/honnef.co/go/tools/facts/generated.go
+++ /dev/null
@@ -1,86 +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
-)
-
-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
- }
- if strings.HasPrefix(text, `by "stringer `) {
- return Stringer, 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 861ca4110..000000000
--- a/vendor/honnef.co/go/tools/facts/purity.go
+++ /dev/null
@@ -1,175 +0,0 @@
-package facts
-
-import (
- "go/token"
- "go/types"
- "reflect"
-
- "golang.org/x/tools/go/analysis"
- "honnef.co/go/tools/functions"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/ssa"
-)
-
-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{buildssa.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[*ssa.Function]struct{}{}
- ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).Pkg
- var check func(ssafn *ssa.Function) (ret bool)
- check = func(ssafn *ssa.Function) (ret bool) {
- if ssafn.Object() == nil {
- // TODO(dh): support closures
- return false
- }
- if pass.ImportObjectFact(ssafn.Object(), new(IsPure)) {
- return true
- }
- if ssafn.Pkg != ssapkg {
- // Function is in another package but wasn't marked as
- // pure, ergo it isn't pure
- return false
- }
- // Break recursion
- if _, ok := seen[ssafn]; ok {
- return false
- }
-
- seen[ssafn] = struct{}{}
- defer func() {
- if ret {
- pass.ExportObjectFact(ssafn.Object(), &IsPure{})
- }
- }()
-
- if functions.IsStub(ssafn) {
- return false
- }
-
- if _, ok := pureStdlib[ssafn.Object().(*types.Func).FullName()]; ok {
- return true
- }
-
- if ssafn.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 ssafn.Params {
- if _, ok := param.Type().Underlying().(*types.Basic); !ok {
- return false
- }
- }
-
- if ssafn.Blocks == nil {
- return false
- }
- checkCall := func(common *ssa.CallCommon) bool {
- if common.IsInvoke() {
- return false
- }
- builtin, ok := common.Value.(*ssa.Builtin)
- if !ok {
- if common.StaticCallee() != ssafn {
- if common.StaticCallee() == nil {
- return false
- }
- if !check(common.StaticCallee()) {
- return false
- }
- }
- } else {
- switch builtin.Name() {
- case "len", "cap", "make", "new":
- default:
- return false
- }
- }
- return true
- }
- for _, b := range ssafn.Blocks {
- for _, ins := range b.Instrs {
- switch ins := ins.(type) {
- case *ssa.Call:
- if !checkCall(ins.Common()) {
- return false
- }
- case *ssa.Defer:
- if !checkCall(&ins.Call) {
- return false
- }
- case *ssa.Select:
- return false
- case *ssa.Send:
- return false
- case *ssa.Go:
- return false
- case *ssa.Panic:
- return false
- case *ssa.Store:
- return false
- case *ssa.FieldAddr:
- return false
- case *ssa.UnOp:
- if ins.Op == token.MUL || ins.Op == token.AND {
- return false
- }
- }
- }
- }
- return true
- }
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- check(ssafn)
- }
-
- 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 15877a2f9..000000000
--- a/vendor/honnef.co/go/tools/functions/loops.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package functions
-
-import "honnef.co/go/tools/ssa"
-
-type Loop struct{ ssa.BlockSet }
-
-func FindLoops(fn *ssa.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{}
- set.Add(n)
- sets = append(sets, set)
- continue
- }
- set := Loop{}
- 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 *ssa.BasicBlock, list []*ssa.BasicBlock) []*ssa.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/pure.go b/vendor/honnef.co/go/tools/functions/pure.go
deleted file mode 100644
index 8bc558771..000000000
--- a/vendor/honnef.co/go/tools/functions/pure.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package functions
-
-import (
- "honnef.co/go/tools/ssa"
-)
-
-func filterDebug(instr []ssa.Instruction) []ssa.Instruction {
- var out []ssa.Instruction
- for _, ins := range instr {
- if _, ok := ins.(*ssa.DebugRef); !ok {
- out = append(out, ins)
- }
- }
- return out
-}
-
-// IsStub reports whether a function is a stub. A function is
-// considered a stub if it has no instructions or exactly one
-// instruction, which must be either returning only constant values or
-// a panic.
-func IsStub(fn *ssa.Function) bool {
- if len(fn.Blocks) == 0 {
- return true
- }
- if len(fn.Blocks) > 1 {
- return false
- }
- instrs := filterDebug(fn.Blocks[0].Instrs)
- if len(instrs) != 1 {
- return false
- }
-
- switch instrs[0].(type) {
- case *ssa.Return:
- // Since this is the only instruction, the return value must
- // be a constant. We consider all constants as stubs, not just
- // the zero value. This does not, unfortunately, cover zero
- // initialised structs, as these cause additional
- // instructions.
- return true
- case *ssa.Panic:
- return true
- default:
- return false
- }
-}
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 3e9c3a23f..000000000
--- a/vendor/honnef.co/go/tools/functions/terminates.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package functions
-
-import "honnef.co/go/tools/ssa"
-
-// 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 *ssa.Function) bool {
- if fn.Blocks == nil {
- // assuming that a function terminates is the conservative
- // choice
- return true
- }
-
- for _, block := range fn.Blocks {
- if len(block.Instrs) == 0 {
- continue
- }
- if _, ok := block.Instrs[len(block.Instrs)-1].(*ssa.Return); ok {
- 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 2b33ca106..000000000
--- a/vendor/honnef.co/go/tools/internal/cache/cache.go
+++ /dev/null
@@ -1,474 +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 || size < 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, _ := ioutil.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())))
-}
-
-// 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 := []byte(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")
- if err := ioutil.WriteFile(file, entry, 0666); 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/buildssa/buildssa.go b/vendor/honnef.co/go/tools/internal/passes/buildssa/buildssa.go
deleted file mode 100644
index fde918d12..000000000
--- a/vendor/honnef.co/go/tools/internal/passes/buildssa/buildssa.go
+++ /dev/null
@@ -1,116 +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 buildssa defines an Analyzer that constructs the SSA
-// representation 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 buildssa
-
-import (
- "go/ast"
- "go/types"
- "reflect"
-
- "golang.org/x/tools/go/analysis"
- "honnef.co/go/tools/ssa"
-)
-
-var Analyzer = &analysis.Analyzer{
- Name: "buildssa",
- Doc: "build SSA-form IR for later passes",
- Run: run,
- ResultType: reflect.TypeOf(new(SSA)),
-}
-
-// SSA provides SSA-form intermediate representation for all the
-// non-blank source functions in the current package.
-type SSA struct {
- Pkg *ssa.Package
- SrcFuncs []*ssa.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, SSA 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 SSA objects belonging
- // to a single Program.
-
- mode := ssa.GlobalDebug
-
- prog := ssa.NewProgram(pass.Fset, mode)
-
- // Create SSA 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(pass.Pkg.Imports())
-
- // Create and build the primary package.
- ssapkg := prog.CreatePackage(pass.Pkg, pass.Files, pass.TypesInfo, false)
- ssapkg.Build()
-
- // Compute list of source functions, including literals,
- // in source order.
- var funcs []*ssa.Function
- var addAnons func(f *ssa.Function)
- addAnons = func(f *ssa.Function) {
- funcs = append(funcs, f)
- for _, anon := range f.AnonFuncs {
- addAnons(anon)
- }
- }
- addAnons(ssapkg.Members["init"].(*ssa.Function))
- for _, f := range pass.Files {
- for _, decl := range f.Decls {
- if fdecl, ok := decl.(*ast.FuncDecl); ok {
-
- // SSA will not build a Function
- // for a FuncDecl named blank.
- // That's arguably too strict but
- // relaxing it would break uniqueness of
- // names of package members.
- if fdecl.Name.Name == "_" {
- continue
- }
-
- // (init functions have distinct Func
- // objects named "init" and distinct
- // ssa.Functions named "init#1", ...)
-
- fn := pass.TypesInfo.Defs[fdecl.Name].(*types.Func)
- if fn == nil {
- panic(fn)
- }
-
- f := ssapkg.Prog.FuncValue(fn)
- if f == nil {
- panic(fn)
- }
-
- addAnons(f)
- }
- }
- }
-
- return &SSA{Pkg: ssapkg, 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 3f3f1708f..000000000
--- a/vendor/honnef.co/go/tools/internal/renameio/renameio.go
+++ /dev/null
@@ -1,83 +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"
- "io/ioutil"
- "os"
- "path/filepath"
- "runtime"
- "strings"
- "time"
-)
-
-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) (err error) {
- return WriteToFile(filename, bytes.NewReader(data))
-}
-
-// 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) (err error) {
- f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)+patternSuffix)
- 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
- }
-
- var start time.Time
- for {
- err := os.Rename(f.Name(), filename)
- if err == nil || runtime.GOOS != "windows" || !strings.HasSuffix(err.Error(), "Access is denied.") {
- return err
- }
-
- // Windows seems to occasionally trigger spurious "Access is denied" errors
- // here (see golang.org/issue/31247). We're not sure why. It's probably
- // worth a little extra latency to avoid propagating the spurious errors.
- if start.IsZero() {
- start = time.Now()
- } else if time.Since(start) >= 500*time.Millisecond {
- return err
- }
- time.Sleep(5 * time.Millisecond)
- }
-}
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 affee6607..000000000
--- a/vendor/honnef.co/go/tools/internal/sharedcheck/lint.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package sharedcheck
-
-import (
- "go/ast"
- "go/types"
-
- "golang.org/x/tools/go/analysis"
- "honnef.co/go/tools/internal/passes/buildssa"
- . "honnef.co/go/tools/lint/lintdsl"
- "honnef.co/go/tools/ssa"
-)
-
-func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- fn := func(node ast.Node) bool {
- rng, ok := node.(*ast.RangeStmt)
- if !ok || !IsBlank(rng.Key) {
- return true
- }
-
- v, _ := ssafn.ValueForExpr(rng.X)
-
- // Check that we're converting from string to []rune
- val, _ := v.(*ssa.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(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
- // SSA 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(ssafn.Syntax(), fn)
- }
- return nil, nil
-}
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 de5a8f128..000000000
--- a/vendor/honnef.co/go/tools/lint/lint.go
+++ /dev/null
@@ -1,491 +0,0 @@
-// Package lint provides the foundation for tools like staticcheck
-package lint // import "honnef.co/go/tools/lint"
-
-import (
- "bytes"
- "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"
-)
-
-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.Pos
-}
-
-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
-}
-
-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
-}
-
-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
-
- 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)
- var problems []Problem
- for _, cum := range l.CumulativeCheckers {
- for _, res := range cum.Result() {
- pkg := tpkgToPkg[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)
- problems = append(problems, p)
- }
- }
- }
-
- for _, pkg := range pkgs {
- for _, ig := range pkg.ignores {
- for i := range pkg.problems {
- p := &pkg.problems[i]
- if ig.Match(*p) {
- p.Severity = Ignored
- }
- }
- for i := range problems {
- p := &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
- }
- 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: DisplayPosition(pkg.Fset, 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] != 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
-}
-
-type Positioner interface {
- Pos() token.Pos
-}
-
-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 3b939e95f..000000000
--- a/vendor/honnef.co/go/tools/lint/lintdsl/lintdsl.go
+++ /dev/null
@@ -1,400 +0,0 @@
-// Package lintdsl provides helpers for implementing static analysis
-// checks. Dot-importing this package is encouraged.
-package lintdsl
-
-import (
- "bytes"
- "flag"
- "fmt"
- "go/ast"
- "go/constant"
- "go/printer"
- "go/token"
- "go/types"
- "strings"
-
- "golang.org/x/tools/go/analysis"
- "honnef.co/go/tools/facts"
- "honnef.co/go/tools/lint"
- "honnef.co/go/tools/ssa"
-)
-
-type packager interface {
- Package() *ssa.Package
-}
-
-func CallName(call *ssa.CallCommon) string {
- if call.IsInvoke() {
- return ""
- }
- switch v := call.Value.(type) {
- case *ssa.Function:
- fn, ok := v.Object().(*types.Func)
- if !ok {
- return ""
- }
- return lint.FuncName(fn)
- case *ssa.Builtin:
- return v.Name()
- }
- return ""
-}
-
-func IsCallTo(call *ssa.CallCommon, name string) bool { return CallName(call) == name }
-func IsType(T types.Type, name string) bool { return types.TypeString(T, nil) == name }
-
-func FilterDebug(instr []ssa.Instruction) []ssa.Instruction {
- var out []ssa.Instruction
- for _, ins := range instr {
- if _, ok := ins.(*ssa.DebugRef); !ok {
- out = append(out, ins)
- }
- }
- return out
-}
-
-func IsExample(fn *ssa.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 lint.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")
-}
-
-func IsInMain(pass *analysis.Pass, node lint.Positioner) bool {
- if node, ok := node.(packager); ok {
- return node.Package().Pkg.Name() == "main"
- }
- return pass.Pkg.Name() == "main"
-}
-
-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 IsGoVersion(pass *analysis.Pass, minor int) bool {
- version := pass.Analyzer.Flags.Lookup("go").Value.(flag.Getter).Get().(int)
- return version >= minor
-}
-
-func CallNameAST(pass *analysis.Pass, call *ast.CallExpr) string {
- switch fun := 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 {
- for _, name := range names {
- if IsCallToAST(pass, node, name) {
- return true
- }
- }
- return false
-}
-
-func Render(pass *analysis.Pass, x interface{}) string {
- var buf bytes.Buffer
- if err := printer.Fprint(&buf, pass.Fset, x); err != nil {
- panic(err)
- }
- return buf.String()
-}
-
-func RenderArgs(pass *analysis.Pass, args []ast.Expr) string {
- var ss []string
- for _, arg := range args {
- ss = append(ss, Render(pass, arg))
- }
- return strings.Join(ss, ", ")
-}
-
-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 Inspect(node ast.Node, fn func(node ast.Node) bool) {
- if node == nil {
- return
- }
- ast.Inspect(node, fn)
-}
-
-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 lint.Positioner) *ast.File {
- pass.Fset.PositionFor(node.Pos(), true)
- 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
-}
-
-func ReportfFG(pass *analysis.Pass, pos token.Pos, f string, args ...interface{}) {
- file := lint.DisplayPosition(pass.Fset, pos).Filename
- m := pass.ResultOf[facts.Generated].(map[string]facts.Generator)
- if _, ok := m[file]; ok {
- return
- }
- pass.Reportf(pos, f, args...)
-}
-
-func ReportNodef(pass *analysis.Pass, node ast.Node, format string, args ...interface{}) {
- msg := fmt.Sprintf(format, args...)
- pass.Report(analysis.Diagnostic{Pos: node.Pos(), End: node.End(), Message: msg})
-}
-
-func ReportNodefFG(pass *analysis.Pass, node ast.Node, format string, args ...interface{}) {
- file := lint.DisplayPosition(pass.Fset, node.Pos()).Filename
- m := pass.ResultOf[facts.Generated].(map[string]facts.Generator)
- if _, ok := m[file]; ok {
- return
- }
- ReportNodef(pass, node, format, args...)
-}
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 9385431f8..000000000
--- a/vendor/honnef.co/go/tools/lint/lintutil/format/format.go
+++ /dev/null
@@ -1,135 +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 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, "%v: %s\n", relativePositionString(p.Pos), p.String())
-}
-
-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"`
- }
- jp := struct {
- Code string `json:"code"`
- Severity string `json:"severity,omitempty"`
- Location location `json:"location"`
- End location `json:"end"`
- Message string `json:"message"`
- }{
- 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,
- }
- _ = 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)
-}
-
-func (o *Stylish) Stats(total, errors, warnings int) {
- if o.tw != nil {
- o.tw.Flush()
- fmt.Fprintln(o.W)
- }
- fmt.Fprintf(o.W, " ✖ %d problems (%d errors, %d warnings)\n",
- total, errors, warnings)
-}
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 fe0279f92..000000000
--- a/vendor/honnef.co/go/tools/lint/lintutil/util.go
+++ /dev/null
@@ -1,392 +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/atomic"
-
- "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")
-
- 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)
-
- 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,
- })
- 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
- )
-
- 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 {
- 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)
- }
- if errors > 0 {
- exit(1)
- }
- exit(0)
-}
-
-type Options struct {
- Config config.Config
-
- Tags string
- LintTests bool
- GoVersion int
-}
-
-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,
- }
- 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()
- }
- }()
- }
-
- return l.Lint(cfg, paths)
-}
-
-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,
- }
-}
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 3b22a63fa..000000000
--- a/vendor/honnef.co/go/tools/lint/runner.go
+++ /dev/null
@@ -1,970 +0,0 @@
-package lint
-
-/*
-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.
-
-*/
-
-import (
- "bytes"
- "encoding/gob"
- "encoding/hex"
- "fmt"
- "go/ast"
- "go/token"
- "go/types"
- "reflect"
- "regexp"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "sync/atomic"
-
- "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"
-)
-
-// 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.
-
-type Package struct {
- dependents uint64
-
- *packages.Package
- Imports []*Package
- initial bool
- fromSource bool
- hash string
- done chan struct{}
-
- resultsMu sync.Mutex
- // results maps analyzer IDs to analyzer results
- results []*result
-
- cfg *config.Config
- 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 bool
-}
-
-func (pkg *Package) decUse() {
- atomic.AddUint64(&pkg.dependents, ^uint64(0))
- if atomic.LoadUint64(&pkg.dependents) == 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 {
- ld loader.Loader
- cache *cache.Cache
-
- analyzerIDs analyzerIDs
-
- // limits parallelism of loading packages
- loadSem chan struct{}
-
- goVersion int
- stats *Stats
-}
-
-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,
- }
- 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) 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, err := passActionID(pkg, a)
- if err != nil {
- return nil, false
- }
- 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
- ret, err := ac.analyzer.Run(pass)
- 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})
- }
- }
-
- buf := &bytes.Buffer{}
- if err := gob.NewEncoder(buf).Encode(facts); err != nil {
- return nil, err
- }
- aID, err := passActionID(ac.pkg, ac.analyzer)
- if err != nil {
- return nil, err
- }
- aID = cache.Subkey(aID, "facts")
- if err := r.cache.PutBytes(aID, buf.Bytes()); err != nil {
- return nil, err
- }
- }
-
- return ret, 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
-// accomodate 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) {
- 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{}{}
- 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)
- }
-
- var dcfg packages.Config
- if cfg != nil {
- dcfg = *cfg
- }
-
- atomic.StoreUint32(&r.stats.State, StateGraph)
- initialPkgs, err := r.ld.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 = packageHash(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. If the package is in the set of initial
-// packages, it will be loaded from source, otherwise it will be
-// loaded from export data. In the case that the package was loaded
-// from export data, cached facts will also be loaded.
-//
-// Currently, only cached facts for this package will be loaded, not
-// for any of its dependencies.
-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))
- }
-
- // Load type information
- if pkg.initial {
- // Load package from source
- pkg.fromSource = true
- return r.ld.LoadFromSource(pkg.Package)
- }
-
- // Load package from export data
- if err := r.ld.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 := r.ld.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 {
- pkg.fromSource = true
- // XXX we added facts to the maps, we need to get rid of those
- return r.ld.LoadFromSource(pkg.Package)
- }
-
- return nil
-}
-
-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 interna 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 || r.hasFacts(a) {
- 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.
- 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.
-}
-
-// hasFacts reports whether an analysis exports any facts. An analysis
-// that has a transitive dependency that exports facts is considered
-// to be exporting facts.
-func (r *Runner) hasFacts(a *analysis.Analyzer) bool {
- ret := 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 {
- ret = true
- }
- for _, req := range a.Requires {
- if ret {
- break
- }
- dfs(req)
- }
- }
- dfs(a)
- return ret
-}
-
-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: 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 packageHash(pkg *Package) (string, error) {
- key := cache.NewHash("package hash")
- fmt.Fprintf(key, "pkgpath %s\n", pkg.PkgPath)
- for _, f := range pkg.CompiledGoFiles {
- h, err := cache.FileHash(f)
- if err != nil {
- return "", err
- }
- fmt.Fprintf(key, "file %s %x\n", f, h)
- }
-
- 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
-}
-
-// passActionID computes an ActionID for an analysis pass.
-func passActionID(pkg *Package, analyzer *analysis.Analyzer) (cache.ActionID, error) {
- key := cache.NewHash("action ID")
- fmt.Fprintf(key, "pkgpath %s\n", pkg.PkgPath)
- fmt.Fprintf(key, "pkghash %s\n", pkg.hash)
- fmt.Fprintf(key, "analyzer %s\n", analyzer.Name)
-
- return key.Sum(), nil
-}
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 2f6508559..000000000
--- a/vendor/honnef.co/go/tools/lint/stats.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package lint
-
-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
-}
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 9c6885d48..000000000
--- a/vendor/honnef.co/go/tools/loader/loader.go
+++ /dev/null
@@ -1,197 +0,0 @@
-package loader
-
-import (
- "fmt"
- "go/ast"
- "go/parser"
- "go/scanner"
- "go/token"
- "go/types"
- "log"
- "os"
- "sync"
-
- "golang.org/x/tools/go/gcexportdata"
- "golang.org/x/tools/go/packages"
-)
-
-type Loader struct {
- exportMu sync.RWMutex
-}
-
-// 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 (ld *Loader) 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
- })
- return pkgs, nil
-}
-
-// LoadFromExport loads a package from export data. All of its
-// dependencies must have been loaded already.
-func (ld *Loader) LoadFromExport(pkg *packages.Package) error {
- ld.exportMu.Lock()
- defer ld.exportMu.Unlock()
-
- 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 (ld *Loader) LoadFromSource(pkg *packages.Package) error {
- ld.exportMu.RLock()
- defer ld.exportMu.RUnlock()
-
- 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
- }
- 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/printf/fuzz.go b/vendor/honnef.co/go/tools/printf/fuzz.go
deleted file mode 100644
index 8ebf357fb..000000000
--- a/vendor/honnef.co/go/tools/printf/fuzz.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// +build gofuzz
-
-package printf
-
-func Fuzz(data []byte) int {
- _, err := Parse(string(data))
- if err == nil {
- return 1
- }
- return 0
-}
diff --git a/vendor/honnef.co/go/tools/printf/printf.go b/vendor/honnef.co/go/tools/printf/printf.go
deleted file mode 100644
index 754db9b16..000000000
--- a/vendor/honnef.co/go/tools/printf/printf.go
+++ /dev/null
@@ -1,197 +0,0 @@
-// Package printf implements a parser for fmt.Printf-style format
-// strings.
-//
-// It parses verbs according to the following syntax:
-// Numeric -> '0'-'9'
-// Letter -> 'a'-'z' | 'A'-'Z'
-// Index -> '[' Numeric+ ']'
-// Star -> '*'
-// Star -> Index '*'
-//
-// Precision -> Numeric+ | Star
-// Width -> Numeric+ | Star
-//
-// WidthAndPrecision -> Width '.' Precision
-// WidthAndPrecision -> Width '.'
-// WidthAndPrecision -> Width
-// WidthAndPrecision -> '.' Precision
-// WidthAndPrecision -> '.'
-//
-// Flag -> '+' | '-' | '#' | ' ' | '0'
-// Verb -> Letter | '%'
-//
-// Input -> '%' [ Flag+ ] [ WidthAndPrecision ] [ Index ] Verb
-package printf
-
-import (
- "errors"
- "regexp"
- "strconv"
- "strings"
-)
-
-// ErrInvalid is returned for invalid format strings or verbs.
-var ErrInvalid = errors.New("invalid format string")
-
-type Verb struct {
- Letter rune
- Flags string
-
- Width Argument
- Precision Argument
- // Which value in the argument list the verb uses.
- // -1 denotes the next argument,
- // values > 0 denote explicit arguments.
- // The value 0 denotes that no argument is consumed. This is the case for %%.
- Value int
-
- Raw string
-}
-
-// Argument is an implicit or explicit width or precision.
-type Argument interface {
- isArgument()
-}
-
-// The Default value, when no width or precision is provided.
-type Default struct{}
-
-// Zero is the implicit zero value.
-// This value may only appear for precisions in format strings like %6.f
-type Zero struct{}
-
-// Star is a * value, which may either refer to the next argument (Index == -1) or an explicit argument.
-type Star struct{ Index int }
-
-// A Literal value, such as 6 in %6d.
-type Literal int
-
-func (Default) isArgument() {}
-func (Zero) isArgument() {}
-func (Star) isArgument() {}
-func (Literal) isArgument() {}
-
-// Parse parses f and returns a list of actions.
-// An action may either be a literal string, or a Verb.
-func Parse(f string) ([]interface{}, error) {
- var out []interface{}
- for len(f) > 0 {
- if f[0] == '%' {
- v, n, err := ParseVerb(f)
- if err != nil {
- return nil, err
- }
- f = f[n:]
- out = append(out, v)
- } else {
- n := strings.IndexByte(f, '%')
- if n > -1 {
- out = append(out, f[:n])
- f = f[n:]
- } else {
- out = append(out, f)
- f = ""
- }
- }
- }
-
- return out, nil
-}
-
-func atoi(s string) int {
- n, _ := strconv.Atoi(s)
- return n
-}
-
-// ParseVerb parses the verb at the beginning of f.
-// It returns the verb, how much of the input was consumed, and an error, if any.
-func ParseVerb(f string) (Verb, int, error) {
- if len(f) < 2 {
- return Verb{}, 0, ErrInvalid
- }
- const (
- flags = 1
-
- width = 2
- widthStar = 3
- widthIndex = 5
-
- dot = 6
- prec = 7
- precStar = 8
- precIndex = 10
-
- verbIndex = 11
- verb = 12
- )
-
- m := re.FindStringSubmatch(f)
- if m == nil {
- return Verb{}, 0, ErrInvalid
- }
-
- v := Verb{
- Letter: []rune(m[verb])[0],
- Flags: m[flags],
- Raw: m[0],
- }
-
- if m[width] != "" {
- // Literal width
- v.Width = Literal(atoi(m[width]))
- } else if m[widthStar] != "" {
- // Star width
- if m[widthIndex] != "" {
- v.Width = Star{atoi(m[widthIndex])}
- } else {
- v.Width = Star{-1}
- }
- } else {
- // Default width
- v.Width = Default{}
- }
-
- if m[dot] == "" {
- // default precision
- v.Precision = Default{}
- } else {
- if m[prec] != "" {
- // Literal precision
- v.Precision = Literal(atoi(m[prec]))
- } else if m[precStar] != "" {
- // Star precision
- if m[precIndex] != "" {
- v.Precision = Star{atoi(m[precIndex])}
- } else {
- v.Precision = Star{-1}
- }
- } else {
- // Zero precision
- v.Precision = Zero{}
- }
- }
-
- if m[verb] == "%" {
- v.Value = 0
- } else if m[verbIndex] != "" {
- v.Value = atoi(m[verbIndex])
- } else {
- v.Value = -1
- }
-
- return v, len(m[0]), nil
-}
-
-const (
- flags = `([+#0 -]*)`
- verb = `([a-zA-Z%])`
- index = `(?:\[([0-9]+)\])`
- star = `((` + index + `)?\*)`
- width1 = `([0-9]+)`
- width2 = star
- width = `(?:` + width1 + `|` + width2 + `)`
- precision = width
- widthAndPrecision = `(?:(?:` + width + `)?(?:(\.)(?:` + precision + `)?)?)`
-)
-
-var re = regexp.MustCompile(`^%` + flags + widthAndPrecision + `?` + index + `?` + verb)
diff --git a/vendor/honnef.co/go/tools/simple/CONTRIBUTING.md b/vendor/honnef.co/go/tools/simple/CONTRIBUTING.md
deleted file mode 100644
index c54c6c50a..000000000
--- a/vendor/honnef.co/go/tools/simple/CONTRIBUTING.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Contributing to gosimple
-
-## Before filing an issue:
-
-### Are you having trouble building gosimple?
-
-Check you have the latest version of its dependencies. Run
-```
-go get -u honnef.co/go/tools/simple
-```
-If you still have problems, consider searching for existing issues before filing a new issue.
-
-## Before sending a pull request:
-
-Have you understood the purpose of gosimple? Make sure to carefully read `README`.
diff --git a/vendor/honnef.co/go/tools/simple/analysis.go b/vendor/honnef.co/go/tools/simple/analysis.go
deleted file mode 100644
index abb1648fa..000000000
--- a/vendor/honnef.co/go/tools/simple/analysis.go
+++ /dev/null
@@ -1,223 +0,0 @@
-package simple
-
-import (
- "flag"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "honnef.co/go/tools/facts"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/lint/lintutil"
-)
-
-func newFlagSet() flag.FlagSet {
- fs := flag.NewFlagSet("", flag.PanicOnError)
- fs.Var(lintutil.NewVersionFlag(), "go", "Target Go version")
- return *fs
-}
-
-var Analyzers = map[string]*analysis.Analyzer{
- "S1000": {
- Name: "S1000",
- Run: LintSingleCaseSelect,
- Doc: Docs["S1000"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1001": {
- Name: "S1001",
- Run: LintLoopCopy,
- Doc: Docs["S1001"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1002": {
- Name: "S1002",
- Run: LintIfBoolCmp,
- Doc: Docs["S1002"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1003": {
- Name: "S1003",
- Run: LintStringsContains,
- Doc: Docs["S1003"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1004": {
- Name: "S1004",
- Run: LintBytesCompare,
- Doc: Docs["S1004"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1005": {
- Name: "S1005",
- Run: LintUnnecessaryBlank,
- Doc: Docs["S1005"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1006": {
- Name: "S1006",
- Run: LintForTrue,
- Doc: Docs["S1006"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1007": {
- Name: "S1007",
- Run: LintRegexpRaw,
- Doc: Docs["S1007"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1008": {
- Name: "S1008",
- Run: LintIfReturn,
- Doc: Docs["S1008"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1009": {
- Name: "S1009",
- Run: LintRedundantNilCheckWithLen,
- Doc: Docs["S1009"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1010": {
- Name: "S1010",
- Run: LintSlicing,
- Doc: Docs["S1010"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1011": {
- Name: "S1011",
- Run: LintLoopAppend,
- Doc: Docs["S1011"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1012": {
- Name: "S1012",
- Run: LintTimeSince,
- Doc: Docs["S1012"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1016": {
- Name: "S1016",
- Run: LintSimplerStructConversion,
- Doc: Docs["S1016"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1017": {
- Name: "S1017",
- Run: LintTrim,
- Doc: Docs["S1017"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1018": {
- Name: "S1018",
- Run: LintLoopSlide,
- Doc: Docs["S1018"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1019": {
- Name: "S1019",
- Run: LintMakeLenCap,
- Doc: Docs["S1019"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1020": {
- Name: "S1020",
- Run: LintAssertNotNil,
- Doc: Docs["S1020"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1021": {
- Name: "S1021",
- Run: LintDeclareAssign,
- Doc: Docs["S1021"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1023": {
- Name: "S1023",
- Run: LintRedundantBreak,
- Doc: Docs["S1023"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1024": {
- Name: "S1024",
- Run: LintTimeUntil,
- Doc: Docs["S1024"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1025": {
- Name: "S1025",
- Run: LintRedundantSprintf,
- Doc: Docs["S1025"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1028": {
- Name: "S1028",
- Run: LintErrorsNewSprintf,
- Doc: Docs["S1028"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1029": {
- Name: "S1029",
- Run: LintRangeStringRunes,
- Doc: Docs["S1029"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "S1030": {
- Name: "S1030",
- Run: LintBytesBufferConversions,
- Doc: Docs["S1030"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1031": {
- Name: "S1031",
- Run: LintNilCheckAroundRange,
- Doc: Docs["S1031"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1032": {
- Name: "S1032",
- Run: LintSortHelpers,
- Doc: Docs["S1032"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1033": {
- Name: "S1033",
- Run: LintGuardedDelete,
- Doc: Docs["S1033"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "S1034": {
- Name: "S1034",
- Run: LintSimplifyTypeSwitch,
- Doc: Docs["S1034"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
-}
diff --git a/vendor/honnef.co/go/tools/simple/doc.go b/vendor/honnef.co/go/tools/simple/doc.go
deleted file mode 100644
index eb0072de5..000000000
--- a/vendor/honnef.co/go/tools/simple/doc.go
+++ /dev/null
@@ -1,425 +0,0 @@
-package simple
-
-import "honnef.co/go/tools/lint"
-
-var Docs = map[string]*lint.Documentation{
- "S1000": &lint.Documentation{
- Title: `Use plain channel send or receive instead of single-case select`,
- Text: `Select statements with a single case can be replaced with a simple
-send or receive.
-
-Before:
-
- select {
- case x := <-ch:
- fmt.Println(x)
- }
-
-After:
-
- x := <-ch
- fmt.Println(x)`,
- Since: "2017.1",
- },
-
- "S1001": &lint.Documentation{
- Title: `Replace for loop with call to copy`,
- Text: `Use copy() for copying elements from one slice to another.
-
-Before:
-
- for i, x := range src {
- dst[i] = x
- }
-
-After:
-
- copy(dst, src)`,
- Since: "2017.1",
- },
-
- "S1002": &lint.Documentation{
- Title: `Omit comparison with boolean constant`,
- Text: `Before:
-
- if x == true {}
-
-After:
-
- if x {}`,
- Since: "2017.1",
- },
-
- "S1003": &lint.Documentation{
- Title: `Replace call to strings.Index with strings.Contains`,
- Text: `Before:
-
- if strings.Index(x, y) != -1 {}
-
-After:
-
- if strings.Contains(x, y) {}`,
- Since: "2017.1",
- },
-
- "S1004": &lint.Documentation{
- Title: `Replace call to bytes.Compare with bytes.Equal`,
- Text: `Before:
-
- if bytes.Compare(x, y) == 0 {}
-
-After:
-
- if bytes.Equal(x, y) {}`,
- Since: "2017.1",
- },
-
- "S1005": &lint.Documentation{
- Title: `Drop unnecessary use of the blank identifier`,
- Text: `In many cases, assigning to the blank identifier is unnecessary.
-
-Before:
-
- for _ = range s {}
- x, _ = someMap[key]
- _ = <-ch
-
-After:
-
- for range s{}
- x = someMap[key]
- <-ch`,
- Since: "2017.1",
- },
-
- "S1006": &lint.Documentation{
- Title: `Use for { ... } for infinite loops`,
- Text: `For infinite loops, using for { ... } is the most idiomatic choice.`,
- Since: "2017.1",
- },
-
- "S1007": &lint.Documentation{
- Title: `Simplify regular expression by using raw string literal`,
- Text: `Raw string literals use ` + "`" + ` instead of " and do not support
-any escape sequences. This means that the backslash (\) can be used
-freely, without the need of escaping.
-
-Since regular expressions have their own escape sequences, raw strings
-can improve their readability.
-
-Before:
-
- regexp.Compile("\\A(\\w+) profile: total \\d+\\n\\z")
-
-After:
-
- regexp.Compile(` + "`" + `\A(\w+) profile: total \d+\n\z` + "`" + `)`,
- Since: "2017.1",
- },
-
- "S1008": &lint.Documentation{
- Title: `Simplify returning boolean expression`,
- Text: `Before:
-
- if {
- return true
- }
- return false
-
-After:
-
- return `,
- Since: "2017.1",
- },
-
- "S1009": &lint.Documentation{
- Title: `Omit redundant nil check on slices`,
- Text: `The len function is defined for all slices, even nil ones, which have
-a length of zero. It is not necessary to check if a slice is not nil
-before checking that its length is not zero.
-
-Before:
-
- if x != nil && len(x) != 0 {}
-
-After:
-
- if len(x) != 0 {}`,
- Since: "2017.1",
- },
-
- "S1010": &lint.Documentation{
- Title: `Omit default slice index`,
- Text: `When slicing, the second index defaults to the length of the value,
-making s[n:len(s)] and s[n:] equivalent.`,
- Since: "2017.1",
- },
-
- "S1011": &lint.Documentation{
- Title: `Use a single append to concatenate two slices`,
- Text: `Before:
-
- for _, e := range y {
- x = append(x, e)
- }
-
-After:
-
- x = append(x, y...)`,
- Since: "2017.1",
- },
-
- "S1012": &lint.Documentation{
- Title: `Replace time.Now().Sub(x) with time.Since(x)`,
- Text: `The time.Since helper has the same effect as using time.Now().Sub(x)
-but is easier to read.
-
-Before:
-
- time.Now().Sub(x)
-
-After:
-
- time.Since(x)`,
- Since: "2017.1",
- },
-
- "S1016": &lint.Documentation{
- Title: `Use a type conversion instead of manually copying struct fields`,
- Text: `Two struct types with identical fields can be converted between each
-other. In older versions of Go, the fields had to have identical
-struct tags. Since Go 1.8, however, struct tags are ignored during
-conversions. It is thus not necessary to manually copy every field
-individually.
-
-Before:
-
- var x T1
- y := T2{
- Field1: x.Field1,
- Field2: x.Field2,
- }
-
-After:
-
- var x T1
- y := T2(x)`,
- Since: "2017.1",
- },
-
- "S1017": &lint.Documentation{
- Title: `Replace manual trimming with strings.TrimPrefix`,
- Text: `Instead of using strings.HasPrefix and manual slicing, use the
-strings.TrimPrefix function. If the string doesn't start with the
-prefix, the original string will be returned. Using strings.TrimPrefix
-reduces complexity, and avoids common bugs, such as off-by-one
-mistakes.
-
-Before:
-
- if strings.HasPrefix(str, prefix) {
- str = str[len(prefix):]
- }
-
-After:
-
- str = strings.TrimPrefix(str, prefix)`,
- Since: "2017.1",
- },
-
- "S1018": &lint.Documentation{
- Title: `Use copy for sliding elements`,
- Text: `copy() permits using the same source and destination slice, even with
-overlapping ranges. This makes it ideal for sliding elements in a
-slice.
-
-Before:
-
- for i := 0; i < n; i++ {
- bs[i] = bs[offset+i]
- }
-
-After:
-
- copy(bs[:n], bs[offset:])`,
- Since: "2017.1",
- },
-
- "S1019": &lint.Documentation{
- Title: `Simplify make call by omitting redundant arguments`,
- Text: `The make function has default values for the length and capacity
-arguments. For channels and maps, the length defaults to zero.
-Additionally, for slices the capacity defaults to the length.`,
- Since: "2017.1",
- },
-
- "S1020": &lint.Documentation{
- Title: `Omit redundant nil check in type assertion`,
- Text: `Before:
-
- if _, ok := i.(T); ok && i != nil {}
-
-After:
-
- if _, ok := i.(T); ok {}`,
- Since: "2017.1",
- },
-
- "S1021": &lint.Documentation{
- Title: `Merge variable declaration and assignment`,
- Text: `Before:
-
- var x uint
- x = 1
-
-After:
-
- var x uint = 1`,
- Since: "2017.1",
- },
-
- "S1023": &lint.Documentation{
- Title: `Omit redundant control flow`,
- Text: `Functions that have no return value do not need a return statement as
-the final statement of the function.
-
-Switches in Go do not have automatic fallthrough, unlike languages
-like C. It is not necessary to have a break statement as the final
-statement in a case block.`,
- Since: "2017.1",
- },
-
- "S1024": &lint.Documentation{
- Title: `Replace x.Sub(time.Now()) with time.Until(x)`,
- Text: `The time.Until helper has the same effect as using x.Sub(time.Now())
-but is easier to read.
-
-Before:
-
- x.Sub(time.Now())
-
-After:
-
- time.Until(x)`,
- Since: "2017.1",
- },
-
- "S1025": &lint.Documentation{
- Title: `Don't use fmt.Sprintf("%s", x) unnecessarily`,
- Text: `In many instances, there are easier and more efficient ways of getting
-a value's string representation. Whenever a value's underlying type is
-a string already, or the type has a String method, they should be used
-directly.
-
-Given the following shared definitions
-
- type T1 string
- type T2 int
-
- func (T2) String() string { return "Hello, world" }
-
- var x string
- var y T1
- var z T2
-
-we can simplify the following
-
- fmt.Sprintf("%s", x)
- fmt.Sprintf("%s", y)
- fmt.Sprintf("%s", z)
-
-to
-
- x
- string(y)
- z.String()`,
- Since: "2017.1",
- },
-
- "S1028": &lint.Documentation{
- Title: `Simplify error construction with fmt.Errorf`,
- Text: `Before:
-
- errors.New(fmt.Sprintf(...))
-
-After:
-
- fmt.Errorf(...)`,
- Since: "2017.1",
- },
-
- "S1029": &lint.Documentation{
- Title: `Range over the string directly`,
- Text: `Ranging over a string will yield byte offsets and runes. If the offset
-isn't used, this is functionally equivalent to converting the string
-to a slice of runes and ranging over that. Ranging directly over the
-string will be more performant, however, as it avoids allocating a new
-slice, the size of which depends on the length of the string.
-
-Before:
-
- for _, r := range []rune(s) {}
-
-After:
-
- for _, r := range s {}`,
- Since: "2017.1",
- },
-
- "S1030": &lint.Documentation{
- Title: `Use bytes.Buffer.String or bytes.Buffer.Bytes`,
- Text: `bytes.Buffer has both a String and a Bytes method. It is never
-necessary to use string(buf.Bytes()) or []byte(buf.String()) – simply
-use the other method.`,
- Since: "2017.1",
- },
-
- "S1031": &lint.Documentation{
- Title: `Omit redundant nil check around loop`,
- Text: `You can use range on nil slices and maps, the loop will simply never
-execute. This makes an additional nil check around the loop
-unnecessary.
-
-Before:
-
- if s != nil {
- for _, x := range s {
- ...
- }
- }
-
-After:
-
- for _, x := range s {
- ...
- }`,
- Since: "2017.1",
- },
-
- "S1032": &lint.Documentation{
- Title: `Use sort.Ints(x), sort.Float64s(x), and sort.Strings(x)`,
- Text: `The sort.Ints, sort.Float64s and sort.Strings functions are easier to
-read than sort.Sort(sort.IntSlice(x)), sort.Sort(sort.Float64Slice(x))
-and sort.Sort(sort.StringSlice(x)).
-
-Before:
-
- sort.Sort(sort.StringSlice(x))
-
-After:
-
- sort.Strings(x)`,
- Since: "2019.1",
- },
-
- "S1033": &lint.Documentation{
- Title: `Unnecessary guard around call to delete`,
- Text: `Calling delete on a nil map is a no-op.`,
- Since: "2019.2",
- },
-
- "S1034": &lint.Documentation{
- Title: `Use result of type assertion to simplify cases`,
- Since: "2019.2",
- },
-}
diff --git a/vendor/honnef.co/go/tools/simple/lint.go b/vendor/honnef.co/go/tools/simple/lint.go
deleted file mode 100644
index c78a7bb7a..000000000
--- a/vendor/honnef.co/go/tools/simple/lint.go
+++ /dev/null
@@ -1,1816 +0,0 @@
-// Package simple contains a linter for Go source code.
-package simple // import "honnef.co/go/tools/simple"
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- "go/types"
- "reflect"
- "sort"
- "strings"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/inspector"
- "golang.org/x/tools/go/types/typeutil"
- . "honnef.co/go/tools/arg"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/internal/sharedcheck"
- "honnef.co/go/tools/lint"
- . "honnef.co/go/tools/lint/lintdsl"
-)
-
-func LintSingleCaseSelect(pass *analysis.Pass) (interface{}, error) {
- isSingleSelect := func(node ast.Node) bool {
- v, ok := node.(*ast.SelectStmt)
- if !ok {
- return false
- }
- return len(v.Body.List) == 1
- }
-
- seen := map[ast.Node]struct{}{}
- fn := func(node ast.Node) {
- switch v := node.(type) {
- case *ast.ForStmt:
- if len(v.Body.List) != 1 {
- return
- }
- if !isSingleSelect(v.Body.List[0]) {
- return
- }
- if _, ok := v.Body.List[0].(*ast.SelectStmt).Body.List[0].(*ast.CommClause).Comm.(*ast.SendStmt); ok {
- // Don't suggest using range for channel sends
- return
- }
- seen[v.Body.List[0]] = struct{}{}
- ReportNodefFG(pass, node, "should use for range instead of for { select {} }")
- case *ast.SelectStmt:
- if _, ok := seen[v]; ok {
- return
- }
- if !isSingleSelect(v) {
- return
- }
- ReportNodefFG(pass, node, "should use a simple channel send/receive instead of select with a single case")
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ForStmt)(nil), (*ast.SelectStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintLoopCopy(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- loop := node.(*ast.RangeStmt)
-
- if loop.Key == nil {
- return
- }
- if len(loop.Body.List) != 1 {
- return
- }
- stmt, ok := loop.Body.List[0].(*ast.AssignStmt)
- if !ok {
- return
- }
- if stmt.Tok != token.ASSIGN || len(stmt.Lhs) != 1 || len(stmt.Rhs) != 1 {
- return
- }
- lhs, ok := stmt.Lhs[0].(*ast.IndexExpr)
- if !ok {
- return
- }
-
- if _, ok := pass.TypesInfo.TypeOf(lhs.X).(*types.Slice); !ok {
- return
- }
- lidx, ok := lhs.Index.(*ast.Ident)
- if !ok {
- return
- }
- key, ok := loop.Key.(*ast.Ident)
- if !ok {
- return
- }
- if pass.TypesInfo.TypeOf(lhs) == nil || pass.TypesInfo.TypeOf(stmt.Rhs[0]) == nil {
- return
- }
- if pass.TypesInfo.ObjectOf(lidx) != pass.TypesInfo.ObjectOf(key) {
- return
- }
- if !types.Identical(pass.TypesInfo.TypeOf(lhs), pass.TypesInfo.TypeOf(stmt.Rhs[0])) {
- return
- }
- if _, ok := pass.TypesInfo.TypeOf(loop.X).(*types.Slice); !ok {
- return
- }
-
- if rhs, ok := stmt.Rhs[0].(*ast.IndexExpr); ok {
- rx, ok := rhs.X.(*ast.Ident)
- _ = rx
- if !ok {
- return
- }
- ridx, ok := rhs.Index.(*ast.Ident)
- if !ok {
- return
- }
- if pass.TypesInfo.ObjectOf(ridx) != pass.TypesInfo.ObjectOf(key) {
- return
- }
- } else if rhs, ok := stmt.Rhs[0].(*ast.Ident); ok {
- value, ok := loop.Value.(*ast.Ident)
- if !ok {
- return
- }
- if pass.TypesInfo.ObjectOf(rhs) != pass.TypesInfo.ObjectOf(value) {
- return
- }
- } else {
- return
- }
- ReportNodefFG(pass, loop, "should use copy() instead of a loop")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.RangeStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintIfBoolCmp(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- expr := node.(*ast.BinaryExpr)
- if expr.Op != token.EQL && expr.Op != token.NEQ {
- return
- }
- x := IsBoolConst(pass, expr.X)
- y := IsBoolConst(pass, expr.Y)
- if !x && !y {
- return
- }
- var other ast.Expr
- var val bool
- if x {
- val = BoolConst(pass, expr.X)
- other = expr.Y
- } else {
- val = BoolConst(pass, expr.Y)
- other = expr.X
- }
- basic, ok := pass.TypesInfo.TypeOf(other).Underlying().(*types.Basic)
- if !ok || basic.Kind() != types.Bool {
- return
- }
- op := ""
- if (expr.Op == token.EQL && !val) || (expr.Op == token.NEQ && val) {
- op = "!"
- }
- r := op + Render(pass, other)
- l1 := len(r)
- r = strings.TrimLeft(r, "!")
- if (l1-len(r))%2 == 1 {
- r = "!" + r
- }
- if IsInTest(pass, node) {
- return
- }
- ReportNodefFG(pass, expr, "should omit comparison to bool constant, can be simplified to %s", r)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintBytesBufferConversions(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if len(call.Args) != 1 {
- return
- }
-
- argCall, ok := call.Args[0].(*ast.CallExpr)
- if !ok {
- return
- }
- sel, ok := argCall.Fun.(*ast.SelectorExpr)
- if !ok {
- return
- }
-
- typ := pass.TypesInfo.TypeOf(call.Fun)
- if typ == types.Universe.Lookup("string").Type() && IsCallToAST(pass, call.Args[0], "(*bytes.Buffer).Bytes") {
- ReportNodefFG(pass, call, "should use %v.String() instead of %v", Render(pass, sel.X), Render(pass, call))
- } else if typ, ok := typ.(*types.Slice); ok && typ.Elem() == types.Universe.Lookup("byte").Type() && IsCallToAST(pass, call.Args[0], "(*bytes.Buffer).String") {
- ReportNodefFG(pass, call, "should use %v.Bytes() instead of %v", Render(pass, sel.X), Render(pass, call))
- }
-
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintStringsContains(pass *analysis.Pass) (interface{}, error) {
- // map of value to token to bool value
- allowed := map[int64]map[token.Token]bool{
- -1: {token.GTR: true, token.NEQ: true, token.EQL: false},
- 0: {token.GEQ: true, token.LSS: false},
- }
- fn := func(node ast.Node) {
- expr := node.(*ast.BinaryExpr)
- switch expr.Op {
- case token.GEQ, token.GTR, token.NEQ, token.LSS, token.EQL:
- default:
- return
- }
-
- value, ok := ExprToInt(pass, expr.Y)
- if !ok {
- return
- }
-
- allowedOps, ok := allowed[value]
- if !ok {
- return
- }
- b, ok := allowedOps[expr.Op]
- if !ok {
- return
- }
-
- call, ok := expr.X.(*ast.CallExpr)
- if !ok {
- return
- }
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return
- }
- pkgIdent, ok := sel.X.(*ast.Ident)
- if !ok {
- return
- }
- funIdent := sel.Sel
- if pkgIdent.Name != "strings" && pkgIdent.Name != "bytes" {
- return
- }
- newFunc := ""
- switch funIdent.Name {
- case "IndexRune":
- newFunc = "ContainsRune"
- case "IndexAny":
- newFunc = "ContainsAny"
- case "Index":
- newFunc = "Contains"
- default:
- return
- }
-
- prefix := ""
- if !b {
- prefix = "!"
- }
- ReportNodefFG(pass, node, "should use %s%s.%s(%s) instead", prefix, pkgIdent.Name, newFunc, RenderArgs(pass, call.Args))
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintBytesCompare(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- expr := node.(*ast.BinaryExpr)
- if expr.Op != token.NEQ && expr.Op != token.EQL {
- return
- }
- call, ok := expr.X.(*ast.CallExpr)
- if !ok {
- return
- }
- if !IsCallToAST(pass, call, "bytes.Compare") {
- return
- }
- value, ok := ExprToInt(pass, expr.Y)
- if !ok || value != 0 {
- return
- }
- args := RenderArgs(pass, call.Args)
- prefix := ""
- if expr.Op == token.NEQ {
- prefix = "!"
- }
- ReportNodefFG(pass, node, "should use %sbytes.Equal(%s) instead", prefix, args)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintForTrue(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- loop := node.(*ast.ForStmt)
- if loop.Init != nil || loop.Post != nil {
- return
- }
- if !IsBoolConst(pass, loop.Cond) || !BoolConst(pass, loop.Cond) {
- return
- }
- ReportNodefFG(pass, loop, "should use for {} instead of for true {}")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ForStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintRegexpRaw(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !IsCallToAST(pass, call, "regexp.MustCompile") &&
- !IsCallToAST(pass, call, "regexp.Compile") {
- return
- }
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return
- }
- if len(call.Args) != 1 {
- // invalid function call
- return
- }
- lit, ok := call.Args[Arg("regexp.Compile.expr")].(*ast.BasicLit)
- if !ok {
- // TODO(dominikh): support string concat, maybe support constants
- return
- }
- if lit.Kind != token.STRING {
- // invalid function call
- return
- }
- if lit.Value[0] != '"' {
- // already a raw string
- return
- }
- val := lit.Value
- if !strings.Contains(val, `\\`) {
- return
- }
- if strings.Contains(val, "`") {
- return
- }
-
- bs := false
- for _, c := range val {
- if !bs && c == '\\' {
- bs = true
- continue
- }
- if bs && c == '\\' {
- bs = false
- continue
- }
- if bs {
- // backslash followed by non-backslash -> escape sequence
- return
- }
- }
-
- ReportNodefFG(pass, call, "should use raw string (`...`) with regexp.%s to avoid having to escape twice", sel.Sel.Name)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintIfReturn(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- block := node.(*ast.BlockStmt)
- l := len(block.List)
- if l < 2 {
- return
- }
- n1, n2 := block.List[l-2], block.List[l-1]
-
- if len(block.List) >= 3 {
- if _, ok := block.List[l-3].(*ast.IfStmt); ok {
- // Do not flag a series of if statements
- return
- }
- }
- // if statement with no init, no else, a single condition
- // checking an identifier or function call and just a return
- // statement in the body, that returns a boolean constant
- ifs, ok := n1.(*ast.IfStmt)
- if !ok {
- return
- }
- if ifs.Else != nil || ifs.Init != nil {
- return
- }
- if len(ifs.Body.List) != 1 {
- return
- }
- if op, ok := ifs.Cond.(*ast.BinaryExpr); ok {
- switch op.Op {
- case token.EQL, token.LSS, token.GTR, token.NEQ, token.LEQ, token.GEQ:
- default:
- return
- }
- }
- ret1, ok := ifs.Body.List[0].(*ast.ReturnStmt)
- if !ok {
- return
- }
- if len(ret1.Results) != 1 {
- return
- }
- if !IsBoolConst(pass, ret1.Results[0]) {
- return
- }
-
- ret2, ok := n2.(*ast.ReturnStmt)
- if !ok {
- return
- }
- if len(ret2.Results) != 1 {
- return
- }
- if !IsBoolConst(pass, ret2.Results[0]) {
- return
- }
-
- if ret1.Results[0].(*ast.Ident).Name == ret2.Results[0].(*ast.Ident).Name {
- // we want the function to return true and false, not the
- // same value both times.
- return
- }
-
- ReportNodefFG(pass, n1, "should use 'return ' instead of 'if { return }; return '")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BlockStmt)(nil)}, fn)
- return nil, nil
-}
-
-// LintRedundantNilCheckWithLen checks for the following reduntant nil-checks:
-//
-// if x == nil || len(x) == 0 {}
-// if x != nil && len(x) != 0 {}
-// if x != nil && len(x) == N {} (where N != 0)
-// if x != nil && len(x) > N {}
-// if x != nil && len(x) >= N {} (where N != 0)
-//
-func LintRedundantNilCheckWithLen(pass *analysis.Pass) (interface{}, error) {
- isConstZero := func(expr ast.Expr) (isConst bool, isZero bool) {
- _, ok := expr.(*ast.BasicLit)
- if ok {
- return true, IsZero(expr)
- }
- id, ok := expr.(*ast.Ident)
- if !ok {
- return false, false
- }
- c, ok := pass.TypesInfo.ObjectOf(id).(*types.Const)
- if !ok {
- return false, false
- }
- return true, c.Val().Kind() == constant.Int && c.Val().String() == "0"
- }
-
- fn := func(node ast.Node) {
- // check that expr is "x || y" or "x && y"
- expr := node.(*ast.BinaryExpr)
- if expr.Op != token.LOR && expr.Op != token.LAND {
- return
- }
- eqNil := expr.Op == token.LOR
-
- // check that x is "xx == nil" or "xx != nil"
- x, ok := expr.X.(*ast.BinaryExpr)
- if !ok {
- return
- }
- if eqNil && x.Op != token.EQL {
- return
- }
- if !eqNil && x.Op != token.NEQ {
- return
- }
- xx, ok := x.X.(*ast.Ident)
- if !ok {
- return
- }
- if !IsNil(pass, x.Y) {
- return
- }
-
- // check that y is "len(xx) == 0" or "len(xx) ... "
- y, ok := expr.Y.(*ast.BinaryExpr)
- if !ok {
- return
- }
- if eqNil && y.Op != token.EQL { // must be len(xx) *==* 0
- return
- }
- yx, ok := y.X.(*ast.CallExpr)
- if !ok {
- return
- }
- yxFun, ok := yx.Fun.(*ast.Ident)
- if !ok || yxFun.Name != "len" || len(yx.Args) != 1 {
- return
- }
- yxArg, ok := yx.Args[Arg("len.v")].(*ast.Ident)
- if !ok {
- return
- }
- if yxArg.Name != xx.Name {
- return
- }
-
- if eqNil && !IsZero(y.Y) { // must be len(x) == *0*
- return
- }
-
- if !eqNil {
- isConst, isZero := isConstZero(y.Y)
- if !isConst {
- return
- }
- switch y.Op {
- case token.EQL:
- // avoid false positive for "xx != nil && len(xx) == 0"
- if isZero {
- return
- }
- case token.GEQ:
- // avoid false positive for "xx != nil && len(xx) >= 0"
- if isZero {
- return
- }
- case token.NEQ:
- // avoid false positive for "xx != nil && len(xx) != "
- if !isZero {
- return
- }
- case token.GTR:
- // ok
- default:
- return
- }
- }
-
- // finally check that xx type is one of array, slice, map or chan
- // this is to prevent false positive in case if xx is a pointer to an array
- var nilType string
- switch pass.TypesInfo.TypeOf(xx).(type) {
- case *types.Slice:
- nilType = "nil slices"
- case *types.Map:
- nilType = "nil maps"
- case *types.Chan:
- nilType = "nil channels"
- default:
- return
- }
- ReportNodefFG(pass, expr, "should omit nil check; len() for %s is defined as zero", nilType)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintSlicing(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- n := node.(*ast.SliceExpr)
- if n.Max != nil {
- return
- }
- s, ok := n.X.(*ast.Ident)
- if !ok || s.Obj == nil {
- return
- }
- call, ok := n.High.(*ast.CallExpr)
- if !ok || len(call.Args) != 1 || call.Ellipsis.IsValid() {
- return
- }
- fun, ok := call.Fun.(*ast.Ident)
- if !ok || fun.Name != "len" {
- return
- }
- if _, ok := pass.TypesInfo.ObjectOf(fun).(*types.Builtin); !ok {
- return
- }
- arg, ok := call.Args[Arg("len.v")].(*ast.Ident)
- if !ok || arg.Obj != s.Obj {
- return
- }
- ReportNodefFG(pass, n, "should omit second index in slice, s[a:len(s)] is identical to s[a:]")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.SliceExpr)(nil)}, fn)
- return nil, nil
-}
-
-func refersTo(pass *analysis.Pass, expr ast.Expr, ident *ast.Ident) bool {
- found := false
- fn := func(node ast.Node) bool {
- ident2, ok := node.(*ast.Ident)
- if !ok {
- return true
- }
- if pass.TypesInfo.ObjectOf(ident) == pass.TypesInfo.ObjectOf(ident2) {
- found = true
- return false
- }
- return true
- }
- ast.Inspect(expr, fn)
- return found
-}
-
-func LintLoopAppend(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- loop := node.(*ast.RangeStmt)
- if !IsBlank(loop.Key) {
- return
- }
- val, ok := loop.Value.(*ast.Ident)
- if !ok {
- return
- }
- if len(loop.Body.List) != 1 {
- return
- }
- stmt, ok := loop.Body.List[0].(*ast.AssignStmt)
- if !ok {
- return
- }
- if stmt.Tok != token.ASSIGN || len(stmt.Lhs) != 1 || len(stmt.Rhs) != 1 {
- return
- }
- if refersTo(pass, stmt.Lhs[0], val) {
- return
- }
- call, ok := stmt.Rhs[0].(*ast.CallExpr)
- if !ok {
- return
- }
- if len(call.Args) != 2 || call.Ellipsis.IsValid() {
- return
- }
- fun, ok := call.Fun.(*ast.Ident)
- if !ok {
- return
- }
- obj := pass.TypesInfo.ObjectOf(fun)
- fn, ok := obj.(*types.Builtin)
- if !ok || fn.Name() != "append" {
- return
- }
-
- src := pass.TypesInfo.TypeOf(loop.X)
- dst := pass.TypesInfo.TypeOf(call.Args[Arg("append.slice")])
- // TODO(dominikh) remove nil check once Go issue #15173 has
- // been fixed
- if src == nil {
- return
- }
- if !types.Identical(src, dst) {
- return
- }
-
- if Render(pass, stmt.Lhs[0]) != Render(pass, call.Args[Arg("append.slice")]) {
- return
- }
-
- el, ok := call.Args[Arg("append.elems")].(*ast.Ident)
- if !ok {
- return
- }
- if pass.TypesInfo.ObjectOf(val) != pass.TypesInfo.ObjectOf(el) {
- return
- }
- ReportNodefFG(pass, loop, "should replace loop with %s = append(%s, %s...)",
- Render(pass, stmt.Lhs[0]), Render(pass, call.Args[Arg("append.slice")]), Render(pass, loop.X))
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.RangeStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintTimeSince(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return
- }
- if !IsCallToAST(pass, sel.X, "time.Now") {
- return
- }
- if sel.Sel.Name != "Sub" {
- return
- }
- ReportNodefFG(pass, call, "should use time.Since instead of time.Now().Sub")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintTimeUntil(pass *analysis.Pass) (interface{}, error) {
- if !IsGoVersion(pass, 8) {
- return nil, nil
- }
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !IsCallToAST(pass, call, "(time.Time).Sub") {
- return
- }
- if !IsCallToAST(pass, call.Args[Arg("(time.Time).Sub.u")], "time.Now") {
- return
- }
- ReportNodefFG(pass, call, "should use time.Until instead of t.Sub(time.Now())")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintUnnecessaryBlank(pass *analysis.Pass) (interface{}, error) {
- fn1 := func(node ast.Node) {
- assign := node.(*ast.AssignStmt)
- if len(assign.Lhs) != 2 || len(assign.Rhs) != 1 {
- return
- }
- if !IsBlank(assign.Lhs[1]) {
- return
- }
- switch rhs := assign.Rhs[0].(type) {
- case *ast.IndexExpr:
- // The type-checker should make sure that it's a map, but
- // let's be safe.
- if _, ok := pass.TypesInfo.TypeOf(rhs.X).Underlying().(*types.Map); !ok {
- return
- }
- case *ast.UnaryExpr:
- if rhs.Op != token.ARROW {
- return
- }
- default:
- return
- }
- cp := *assign
- cp.Lhs = cp.Lhs[0:1]
- ReportNodefFG(pass, assign, "should write %s instead of %s", Render(pass, &cp), Render(pass, assign))
- }
-
- fn2 := func(node ast.Node) {
- stmt := node.(*ast.AssignStmt)
- if len(stmt.Lhs) != len(stmt.Rhs) {
- return
- }
- for i, lh := range stmt.Lhs {
- rh := stmt.Rhs[i]
- if !IsBlank(lh) {
- continue
- }
- expr, ok := rh.(*ast.UnaryExpr)
- if !ok {
- continue
- }
- if expr.Op != token.ARROW {
- continue
- }
- ReportNodefFG(pass, lh, "'_ = <-ch' can be simplified to '<-ch'")
- }
- }
-
- fn3 := func(node ast.Node) {
- rs := node.(*ast.RangeStmt)
-
- // for x, _
- if !IsBlank(rs.Key) && IsBlank(rs.Value) {
- ReportNodefFG(pass, rs.Value, "should omit value from range; this loop is equivalent to `for %s %s range ...`", Render(pass, rs.Key), rs.Tok)
- }
- // for _, _ || for _
- if IsBlank(rs.Key) && (IsBlank(rs.Value) || rs.Value == nil) {
- ReportNodefFG(pass, rs.Key, "should omit values from range; this loop is equivalent to `for range ...`")
- }
- }
-
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.AssignStmt)(nil)}, fn1)
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.AssignStmt)(nil)}, fn2)
- if IsGoVersion(pass, 4) {
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.RangeStmt)(nil)}, fn3)
- }
- return nil, nil
-}
-
-func LintSimplerStructConversion(pass *analysis.Pass) (interface{}, error) {
- var skip ast.Node
- fn := func(node ast.Node) {
- // Do not suggest type conversion between pointers
- if unary, ok := node.(*ast.UnaryExpr); ok && unary.Op == token.AND {
- if lit, ok := unary.X.(*ast.CompositeLit); ok {
- skip = lit
- }
- return
- }
-
- if node == skip {
- return
- }
-
- lit, ok := node.(*ast.CompositeLit)
- if !ok {
- return
- }
- typ1, _ := pass.TypesInfo.TypeOf(lit.Type).(*types.Named)
- if typ1 == nil {
- return
- }
- s1, ok := typ1.Underlying().(*types.Struct)
- if !ok {
- return
- }
-
- var typ2 *types.Named
- var ident *ast.Ident
- getSelType := func(expr ast.Expr) (types.Type, *ast.Ident, bool) {
- sel, ok := expr.(*ast.SelectorExpr)
- if !ok {
- return nil, nil, false
- }
- ident, ok := sel.X.(*ast.Ident)
- if !ok {
- return nil, nil, false
- }
- typ := pass.TypesInfo.TypeOf(sel.X)
- return typ, ident, typ != nil
- }
- if len(lit.Elts) == 0 {
- return
- }
- if s1.NumFields() != len(lit.Elts) {
- return
- }
- for i, elt := range lit.Elts {
- var t types.Type
- var id *ast.Ident
- var ok bool
- switch elt := elt.(type) {
- case *ast.SelectorExpr:
- t, id, ok = getSelType(elt)
- if !ok {
- return
- }
- if i >= s1.NumFields() || s1.Field(i).Name() != elt.Sel.Name {
- return
- }
- case *ast.KeyValueExpr:
- var sel *ast.SelectorExpr
- sel, ok = elt.Value.(*ast.SelectorExpr)
- if !ok {
- return
- }
-
- if elt.Key.(*ast.Ident).Name != sel.Sel.Name {
- return
- }
- t, id, ok = getSelType(elt.Value)
- }
- if !ok {
- return
- }
- // All fields must be initialized from the same object
- if ident != nil && ident.Obj != id.Obj {
- return
- }
- typ2, _ = t.(*types.Named)
- if typ2 == nil {
- return
- }
- ident = id
- }
-
- if typ2 == nil {
- return
- }
-
- if typ1.Obj().Pkg() != typ2.Obj().Pkg() {
- // Do not suggest type conversions between different
- // packages. Types in different packages might only match
- // by coincidence. Furthermore, if the dependency ever
- // adds more fields to its type, it could break the code
- // that relies on the type conversion to work.
- return
- }
-
- s2, ok := typ2.Underlying().(*types.Struct)
- if !ok {
- return
- }
- if typ1 == typ2 {
- return
- }
- if IsGoVersion(pass, 8) {
- if !types.IdenticalIgnoreTags(s1, s2) {
- return
- }
- } else {
- if !types.Identical(s1, s2) {
- return
- }
- }
- ReportNodefFG(pass, node, "should convert %s (type %s) to %s instead of using struct literal",
- ident.Name, typ2.Obj().Name(), typ1.Obj().Name())
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.UnaryExpr)(nil), (*ast.CompositeLit)(nil)}, fn)
- return nil, nil
-}
-
-func LintTrim(pass *analysis.Pass) (interface{}, error) {
- sameNonDynamic := func(node1, node2 ast.Node) bool {
- if reflect.TypeOf(node1) != reflect.TypeOf(node2) {
- return false
- }
-
- switch node1 := node1.(type) {
- case *ast.Ident:
- return node1.Obj == node2.(*ast.Ident).Obj
- case *ast.SelectorExpr:
- return Render(pass, node1) == Render(pass, node2)
- case *ast.IndexExpr:
- return Render(pass, node1) == Render(pass, node2)
- }
- return false
- }
-
- isLenOnIdent := func(fn ast.Expr, ident ast.Expr) bool {
- call, ok := fn.(*ast.CallExpr)
- if !ok {
- return false
- }
- if fn, ok := call.Fun.(*ast.Ident); !ok || fn.Name != "len" {
- return false
- }
- if len(call.Args) != 1 {
- return false
- }
- return sameNonDynamic(call.Args[Arg("len.v")], ident)
- }
-
- fn := func(node ast.Node) {
- var pkg string
- var fun string
-
- ifstmt := node.(*ast.IfStmt)
- if ifstmt.Init != nil {
- return
- }
- if ifstmt.Else != nil {
- return
- }
- if len(ifstmt.Body.List) != 1 {
- return
- }
- condCall, ok := ifstmt.Cond.(*ast.CallExpr)
- if !ok {
- return
- }
- switch {
- case IsCallToAST(pass, condCall, "strings.HasPrefix"):
- pkg = "strings"
- fun = "HasPrefix"
- case IsCallToAST(pass, condCall, "strings.HasSuffix"):
- pkg = "strings"
- fun = "HasSuffix"
- case IsCallToAST(pass, condCall, "strings.Contains"):
- pkg = "strings"
- fun = "Contains"
- case IsCallToAST(pass, condCall, "bytes.HasPrefix"):
- pkg = "bytes"
- fun = "HasPrefix"
- case IsCallToAST(pass, condCall, "bytes.HasSuffix"):
- pkg = "bytes"
- fun = "HasSuffix"
- case IsCallToAST(pass, condCall, "bytes.Contains"):
- pkg = "bytes"
- fun = "Contains"
- default:
- return
- }
-
- assign, ok := ifstmt.Body.List[0].(*ast.AssignStmt)
- if !ok {
- return
- }
- if assign.Tok != token.ASSIGN {
- return
- }
- if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
- return
- }
- if !sameNonDynamic(condCall.Args[0], assign.Lhs[0]) {
- return
- }
-
- switch rhs := assign.Rhs[0].(type) {
- case *ast.CallExpr:
- if len(rhs.Args) < 2 || !sameNonDynamic(condCall.Args[0], rhs.Args[0]) || !sameNonDynamic(condCall.Args[1], rhs.Args[1]) {
- return
- }
- if IsCallToAST(pass, condCall, "strings.HasPrefix") && IsCallToAST(pass, rhs, "strings.TrimPrefix") ||
- IsCallToAST(pass, condCall, "strings.HasSuffix") && IsCallToAST(pass, rhs, "strings.TrimSuffix") ||
- IsCallToAST(pass, condCall, "strings.Contains") && IsCallToAST(pass, rhs, "strings.Replace") ||
- IsCallToAST(pass, condCall, "bytes.HasPrefix") && IsCallToAST(pass, rhs, "bytes.TrimPrefix") ||
- IsCallToAST(pass, condCall, "bytes.HasSuffix") && IsCallToAST(pass, rhs, "bytes.TrimSuffix") ||
- IsCallToAST(pass, condCall, "bytes.Contains") && IsCallToAST(pass, rhs, "bytes.Replace") {
- ReportNodefFG(pass, ifstmt, "should replace this if statement with an unconditional %s", CallNameAST(pass, rhs))
- }
- return
- case *ast.SliceExpr:
- slice := rhs
- if !ok {
- return
- }
- if slice.Slice3 {
- return
- }
- if !sameNonDynamic(slice.X, condCall.Args[0]) {
- return
- }
- var index ast.Expr
- switch fun {
- case "HasPrefix":
- // TODO(dh) We could detect a High that is len(s), but another
- // rule will already flag that, anyway.
- if slice.High != nil {
- return
- }
- index = slice.Low
- case "HasSuffix":
- if slice.Low != nil {
- n, ok := ExprToInt(pass, slice.Low)
- if !ok || n != 0 {
- return
- }
- }
- index = slice.High
- }
-
- switch index := index.(type) {
- case *ast.CallExpr:
- if fun != "HasPrefix" {
- return
- }
- if fn, ok := index.Fun.(*ast.Ident); !ok || fn.Name != "len" {
- return
- }
- if len(index.Args) != 1 {
- return
- }
- id3 := index.Args[Arg("len.v")]
- switch oid3 := condCall.Args[1].(type) {
- case *ast.BasicLit:
- if pkg != "strings" {
- return
- }
- lit, ok := id3.(*ast.BasicLit)
- if !ok {
- return
- }
- s1, ok1 := ExprToString(pass, lit)
- s2, ok2 := ExprToString(pass, condCall.Args[1])
- if !ok1 || !ok2 || s1 != s2 {
- return
- }
- default:
- if !sameNonDynamic(id3, oid3) {
- return
- }
- }
- case *ast.BasicLit, *ast.Ident:
- if fun != "HasPrefix" {
- return
- }
- if pkg != "strings" {
- return
- }
- string, ok1 := ExprToString(pass, condCall.Args[1])
- int, ok2 := ExprToInt(pass, slice.Low)
- if !ok1 || !ok2 || int != int64(len(string)) {
- return
- }
- case *ast.BinaryExpr:
- if fun != "HasSuffix" {
- return
- }
- if index.Op != token.SUB {
- return
- }
- if !isLenOnIdent(index.X, condCall.Args[0]) ||
- !isLenOnIdent(index.Y, condCall.Args[1]) {
- return
- }
- default:
- return
- }
-
- var replacement string
- switch fun {
- case "HasPrefix":
- replacement = "TrimPrefix"
- case "HasSuffix":
- replacement = "TrimSuffix"
- }
- ReportNodefFG(pass, ifstmt, "should replace this if statement with an unconditional %s.%s", pkg, replacement)
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.IfStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintLoopSlide(pass *analysis.Pass) (interface{}, error) {
- // TODO(dh): detect bs[i+offset] in addition to bs[offset+i]
- // TODO(dh): consider merging this function with LintLoopCopy
- // TODO(dh): detect length that is an expression, not a variable name
- // TODO(dh): support sliding to a different offset than the beginning of the slice
-
- fn := func(node ast.Node) {
- /*
- for i := 0; i < n; i++ {
- bs[i] = bs[offset+i]
- }
-
- ↓
-
- copy(bs[:n], bs[offset:offset+n])
- */
-
- loop := node.(*ast.ForStmt)
- if len(loop.Body.List) != 1 || loop.Init == nil || loop.Cond == nil || loop.Post == nil {
- return
- }
- assign, ok := loop.Init.(*ast.AssignStmt)
- if !ok || len(assign.Lhs) != 1 || len(assign.Rhs) != 1 || !IsZero(assign.Rhs[0]) {
- return
- }
- initvar, ok := assign.Lhs[0].(*ast.Ident)
- if !ok {
- return
- }
- post, ok := loop.Post.(*ast.IncDecStmt)
- if !ok || post.Tok != token.INC {
- return
- }
- postvar, ok := post.X.(*ast.Ident)
- if !ok || pass.TypesInfo.ObjectOf(postvar) != pass.TypesInfo.ObjectOf(initvar) {
- return
- }
- bin, ok := loop.Cond.(*ast.BinaryExpr)
- if !ok || bin.Op != token.LSS {
- return
- }
- binx, ok := bin.X.(*ast.Ident)
- if !ok || pass.TypesInfo.ObjectOf(binx) != pass.TypesInfo.ObjectOf(initvar) {
- return
- }
- biny, ok := bin.Y.(*ast.Ident)
- if !ok {
- return
- }
-
- assign, ok = loop.Body.List[0].(*ast.AssignStmt)
- if !ok || len(assign.Lhs) != 1 || len(assign.Rhs) != 1 || assign.Tok != token.ASSIGN {
- return
- }
- lhs, ok := assign.Lhs[0].(*ast.IndexExpr)
- if !ok {
- return
- }
- rhs, ok := assign.Rhs[0].(*ast.IndexExpr)
- if !ok {
- return
- }
-
- bs1, ok := lhs.X.(*ast.Ident)
- if !ok {
- return
- }
- bs2, ok := rhs.X.(*ast.Ident)
- if !ok {
- return
- }
- obj1 := pass.TypesInfo.ObjectOf(bs1)
- obj2 := pass.TypesInfo.ObjectOf(bs2)
- if obj1 != obj2 {
- return
- }
- if _, ok := obj1.Type().Underlying().(*types.Slice); !ok {
- return
- }
-
- index1, ok := lhs.Index.(*ast.Ident)
- if !ok || pass.TypesInfo.ObjectOf(index1) != pass.TypesInfo.ObjectOf(initvar) {
- return
- }
- index2, ok := rhs.Index.(*ast.BinaryExpr)
- if !ok || index2.Op != token.ADD {
- return
- }
- add1, ok := index2.X.(*ast.Ident)
- if !ok {
- return
- }
- add2, ok := index2.Y.(*ast.Ident)
- if !ok || pass.TypesInfo.ObjectOf(add2) != pass.TypesInfo.ObjectOf(initvar) {
- return
- }
-
- ReportNodefFG(pass, loop, "should use copy(%s[:%s], %s[%s:]) instead", Render(pass, bs1), Render(pass, biny), Render(pass, bs1), Render(pass, add1))
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ForStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintMakeLenCap(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if fn, ok := call.Fun.(*ast.Ident); !ok || fn.Name != "make" {
- // FIXME check whether make is indeed the built-in function
- return
- }
- switch len(call.Args) {
- case 2:
- // make(T, len)
- if _, ok := pass.TypesInfo.TypeOf(call.Args[Arg("make.t")]).Underlying().(*types.Slice); ok {
- break
- }
- if IsZero(call.Args[Arg("make.size[0]")]) {
- ReportNodefFG(pass, call.Args[Arg("make.size[0]")], "should use make(%s) instead", Render(pass, call.Args[Arg("make.t")]))
- }
- case 3:
- // make(T, len, cap)
- if Render(pass, call.Args[Arg("make.size[0]")]) == Render(pass, call.Args[Arg("make.size[1]")]) {
- ReportNodefFG(pass, call.Args[Arg("make.size[0]")],
- "should use make(%s, %s) instead",
- Render(pass, call.Args[Arg("make.t")]), Render(pass, call.Args[Arg("make.size[0]")]))
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintAssertNotNil(pass *analysis.Pass) (interface{}, error) {
- isNilCheck := func(ident *ast.Ident, expr ast.Expr) bool {
- xbinop, ok := expr.(*ast.BinaryExpr)
- if !ok || xbinop.Op != token.NEQ {
- return false
- }
- xident, ok := xbinop.X.(*ast.Ident)
- if !ok || xident.Obj != ident.Obj {
- return false
- }
- if !IsNil(pass, xbinop.Y) {
- return false
- }
- return true
- }
- isOKCheck := func(ident *ast.Ident, expr ast.Expr) bool {
- yident, ok := expr.(*ast.Ident)
- if !ok || yident.Obj != ident.Obj {
- return false
- }
- return true
- }
- fn1 := func(node ast.Node) {
- ifstmt := node.(*ast.IfStmt)
- assign, ok := ifstmt.Init.(*ast.AssignStmt)
- if !ok || len(assign.Lhs) != 2 || len(assign.Rhs) != 1 || !IsBlank(assign.Lhs[0]) {
- return
- }
- assert, ok := assign.Rhs[0].(*ast.TypeAssertExpr)
- if !ok {
- return
- }
- binop, ok := ifstmt.Cond.(*ast.BinaryExpr)
- if !ok || binop.Op != token.LAND {
- return
- }
- assertIdent, ok := assert.X.(*ast.Ident)
- if !ok {
- return
- }
- assignIdent, ok := assign.Lhs[1].(*ast.Ident)
- if !ok {
- return
- }
- if !(isNilCheck(assertIdent, binop.X) && isOKCheck(assignIdent, binop.Y)) &&
- !(isNilCheck(assertIdent, binop.Y) && isOKCheck(assignIdent, binop.X)) {
- return
- }
- ReportNodefFG(pass, ifstmt, "when %s is true, %s can't be nil", Render(pass, assignIdent), Render(pass, assertIdent))
- }
- fn2 := func(node ast.Node) {
- // Check that outer ifstmt is an 'if x != nil {}'
- ifstmt := node.(*ast.IfStmt)
- if ifstmt.Init != nil {
- return
- }
- if ifstmt.Else != nil {
- return
- }
- if len(ifstmt.Body.List) != 1 {
- return
- }
- binop, ok := ifstmt.Cond.(*ast.BinaryExpr)
- if !ok {
- return
- }
- if binop.Op != token.NEQ {
- return
- }
- lhs, ok := binop.X.(*ast.Ident)
- if !ok {
- return
- }
- if !IsNil(pass, binop.Y) {
- return
- }
-
- // Check that inner ifstmt is an `if _, ok := x.(T); ok {}`
- ifstmt, ok = ifstmt.Body.List[0].(*ast.IfStmt)
- if !ok {
- return
- }
- assign, ok := ifstmt.Init.(*ast.AssignStmt)
- if !ok || len(assign.Lhs) != 2 || len(assign.Rhs) != 1 || !IsBlank(assign.Lhs[0]) {
- return
- }
- assert, ok := assign.Rhs[0].(*ast.TypeAssertExpr)
- if !ok {
- return
- }
- assertIdent, ok := assert.X.(*ast.Ident)
- if !ok {
- return
- }
- if lhs.Obj != assertIdent.Obj {
- return
- }
- assignIdent, ok := assign.Lhs[1].(*ast.Ident)
- if !ok {
- return
- }
- if !isOKCheck(assignIdent, ifstmt.Cond) {
- return
- }
- ReportNodefFG(pass, ifstmt, "when %s is true, %s can't be nil", Render(pass, assignIdent), Render(pass, assertIdent))
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.IfStmt)(nil)}, fn1)
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.IfStmt)(nil)}, fn2)
- return nil, nil
-}
-
-func LintDeclareAssign(pass *analysis.Pass) (interface{}, error) {
- hasMultipleAssignments := func(root ast.Node, ident *ast.Ident) bool {
- num := 0
- ast.Inspect(root, func(node ast.Node) bool {
- if num >= 2 {
- return false
- }
- assign, ok := node.(*ast.AssignStmt)
- if !ok {
- return true
- }
- for _, lhs := range assign.Lhs {
- if oident, ok := lhs.(*ast.Ident); ok {
- if oident.Obj == ident.Obj {
- num++
- }
- }
- }
-
- return true
- })
- return num >= 2
- }
- fn := func(node ast.Node) {
- block := node.(*ast.BlockStmt)
- if len(block.List) < 2 {
- return
- }
- for i, stmt := range block.List[:len(block.List)-1] {
- _ = i
- decl, ok := stmt.(*ast.DeclStmt)
- if !ok {
- continue
- }
- gdecl, ok := decl.Decl.(*ast.GenDecl)
- if !ok || gdecl.Tok != token.VAR || len(gdecl.Specs) != 1 {
- continue
- }
- vspec, ok := gdecl.Specs[0].(*ast.ValueSpec)
- if !ok || len(vspec.Names) != 1 || len(vspec.Values) != 0 {
- continue
- }
-
- assign, ok := block.List[i+1].(*ast.AssignStmt)
- if !ok || assign.Tok != token.ASSIGN {
- continue
- }
- if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
- continue
- }
- ident, ok := assign.Lhs[0].(*ast.Ident)
- if !ok {
- continue
- }
- if vspec.Names[0].Obj != ident.Obj {
- continue
- }
-
- if refersTo(pass, assign.Rhs[0], ident) {
- continue
- }
- if hasMultipleAssignments(block, ident) {
- continue
- }
-
- ReportNodefFG(pass, decl, "should merge variable declaration with assignment on next line")
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BlockStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintRedundantBreak(pass *analysis.Pass) (interface{}, error) {
- fn1 := func(node ast.Node) {
- clause := node.(*ast.CaseClause)
- if len(clause.Body) < 2 {
- return
- }
- branch, ok := clause.Body[len(clause.Body)-1].(*ast.BranchStmt)
- if !ok || branch.Tok != token.BREAK || branch.Label != nil {
- return
- }
- ReportNodefFG(pass, branch, "redundant break statement")
- }
- fn2 := func(node ast.Node) {
- var ret *ast.FieldList
- var body *ast.BlockStmt
- switch x := node.(type) {
- case *ast.FuncDecl:
- ret = x.Type.Results
- body = x.Body
- case *ast.FuncLit:
- ret = x.Type.Results
- body = x.Body
- default:
- panic(fmt.Sprintf("unreachable: %T", node))
- }
- // if the func has results, a return can't be redundant.
- // similarly, if there are no statements, there can be
- // no return.
- if ret != nil || body == nil || len(body.List) < 1 {
- return
- }
- rst, ok := body.List[len(body.List)-1].(*ast.ReturnStmt)
- if !ok {
- return
- }
- // we don't need to check rst.Results as we already
- // checked x.Type.Results to be nil.
- ReportNodefFG(pass, rst, "redundant return statement")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CaseClause)(nil)}, fn1)
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.FuncDecl)(nil), (*ast.FuncLit)(nil)}, fn2)
- return nil, nil
-}
-
-func isStringer(T types.Type, msCache *typeutil.MethodSetCache) bool {
- ms := msCache.MethodSet(T)
- sel := ms.Lookup(nil, "String")
- if sel == nil {
- return false
- }
- fn, ok := sel.Obj().(*types.Func)
- if !ok {
- // should be unreachable
- return false
- }
- sig := fn.Type().(*types.Signature)
- if sig.Params().Len() != 0 {
- return false
- }
- if sig.Results().Len() != 1 {
- return false
- }
- if !IsType(sig.Results().At(0).Type(), "string") {
- return false
- }
- return true
-}
-
-func LintRedundantSprintf(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !IsCallToAST(pass, call, "fmt.Sprintf") {
- return
- }
- if len(call.Args) != 2 {
- return
- }
- if s, ok := ExprToString(pass, call.Args[Arg("fmt.Sprintf.format")]); !ok || s != "%s" {
- return
- }
- arg := call.Args[Arg("fmt.Sprintf.a[0]")]
- typ := pass.TypesInfo.TypeOf(arg)
-
- ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).Pkg
- if isStringer(typ, &ssapkg.Prog.MethodSets) {
- ReportNodef(pass, call, "should use String() instead of fmt.Sprintf")
- return
- }
-
- if typ.Underlying() == types.Universe.Lookup("string").Type() {
- if typ == types.Universe.Lookup("string").Type() {
- ReportNodefFG(pass, call, "the argument is already a string, there's no need to use fmt.Sprintf")
- } else {
- ReportNodefFG(pass, call, "the argument's underlying type is a string, should use a simple conversion instead of fmt.Sprintf")
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintErrorsNewSprintf(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if !IsCallToAST(pass, node, "errors.New") {
- return
- }
- call := node.(*ast.CallExpr)
- if !IsCallToAST(pass, call.Args[Arg("errors.New.text")], "fmt.Sprintf") {
- return
- }
- ReportNodefFG(pass, node, "should use fmt.Errorf(...) instead of errors.New(fmt.Sprintf(...))")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func LintRangeStringRunes(pass *analysis.Pass) (interface{}, error) {
- return sharedcheck.CheckRangeStringRunes(pass)
-}
-
-func LintNilCheckAroundRange(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- ifstmt := node.(*ast.IfStmt)
- cond, ok := ifstmt.Cond.(*ast.BinaryExpr)
- if !ok {
- return
- }
-
- if cond.Op != token.NEQ || !IsNil(pass, cond.Y) || len(ifstmt.Body.List) != 1 {
- return
- }
-
- loop, ok := ifstmt.Body.List[0].(*ast.RangeStmt)
- if !ok {
- return
- }
- ifXIdent, ok := cond.X.(*ast.Ident)
- if !ok {
- return
- }
- rangeXIdent, ok := loop.X.(*ast.Ident)
- if !ok {
- return
- }
- if ifXIdent.Obj != rangeXIdent.Obj {
- return
- }
- switch pass.TypesInfo.TypeOf(rangeXIdent).(type) {
- case *types.Slice, *types.Map:
- ReportNodefFG(pass, node, "unnecessary nil check around range")
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.IfStmt)(nil)}, fn)
- return nil, nil
-}
-
-func isPermissibleSort(pass *analysis.Pass, node ast.Node) bool {
- call := node.(*ast.CallExpr)
- typeconv, ok := call.Args[0].(*ast.CallExpr)
- if !ok {
- return true
- }
-
- sel, ok := typeconv.Fun.(*ast.SelectorExpr)
- if !ok {
- return true
- }
- name := SelectorName(pass, sel)
- switch name {
- case "sort.IntSlice", "sort.Float64Slice", "sort.StringSlice":
- default:
- return true
- }
-
- return false
-}
-
-func LintSortHelpers(pass *analysis.Pass) (interface{}, error) {
- type Error struct {
- node ast.Node
- msg string
- }
- var allErrors []Error
- fn := func(node ast.Node) {
- var body *ast.BlockStmt
- switch node := node.(type) {
- case *ast.FuncLit:
- body = node.Body
- case *ast.FuncDecl:
- body = node.Body
- default:
- panic(fmt.Sprintf("unreachable: %T", node))
- }
- if body == nil {
- return
- }
-
- var errors []Error
- permissible := false
- fnSorts := func(node ast.Node) bool {
- if permissible {
- return false
- }
- if !IsCallToAST(pass, node, "sort.Sort") {
- return true
- }
- if isPermissibleSort(pass, node) {
- permissible = true
- return false
- }
- call := node.(*ast.CallExpr)
- typeconv := call.Args[Arg("sort.Sort.data")].(*ast.CallExpr)
- sel := typeconv.Fun.(*ast.SelectorExpr)
- name := SelectorName(pass, sel)
-
- switch name {
- case "sort.IntSlice":
- errors = append(errors, Error{node, "should use sort.Ints(...) instead of sort.Sort(sort.IntSlice(...))"})
- case "sort.Float64Slice":
- errors = append(errors, Error{node, "should use sort.Float64s(...) instead of sort.Sort(sort.Float64Slice(...))"})
- case "sort.StringSlice":
- errors = append(errors, Error{node, "should use sort.Strings(...) instead of sort.Sort(sort.StringSlice(...))"})
- }
- return true
- }
- ast.Inspect(body, fnSorts)
-
- if permissible {
- return
- }
- allErrors = append(allErrors, errors...)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.FuncLit)(nil), (*ast.FuncDecl)(nil)}, fn)
- sort.Slice(allErrors, func(i, j int) bool {
- return allErrors[i].node.Pos() < allErrors[j].node.Pos()
- })
- var prev token.Pos
- for _, err := range allErrors {
- if err.node.Pos() == prev {
- continue
- }
- prev = err.node.Pos()
- ReportNodefFG(pass, err.node, "%s", err.msg)
- }
- return nil, nil
-}
-
-func LintGuardedDelete(pass *analysis.Pass) (interface{}, error) {
- isCommaOkMapIndex := func(stmt ast.Stmt) (b *ast.Ident, m ast.Expr, key ast.Expr, ok bool) {
- // Has to be of the form `_, = []
-
- assign, ok := stmt.(*ast.AssignStmt)
- if !ok {
- return nil, nil, nil, false
- }
- if len(assign.Lhs) != 2 || len(assign.Rhs) != 1 {
- return nil, nil, nil, false
- }
- if !IsBlank(assign.Lhs[0]) {
- return nil, nil, nil, false
- }
- ident, ok := assign.Lhs[1].(*ast.Ident)
- if !ok {
- return nil, nil, nil, false
- }
- index, ok := assign.Rhs[0].(*ast.IndexExpr)
- if !ok {
- return nil, nil, nil, false
- }
- if _, ok := pass.TypesInfo.TypeOf(index.X).(*types.Map); !ok {
- return nil, nil, nil, false
- }
- key = index.Index
- return ident, index.X, key, true
- }
- fn := func(node ast.Node) {
- stmt := node.(*ast.IfStmt)
- if len(stmt.Body.List) != 1 {
- return
- }
- if stmt.Else != nil {
- return
- }
- expr, ok := stmt.Body.List[0].(*ast.ExprStmt)
- if !ok {
- return
- }
- call, ok := expr.X.(*ast.CallExpr)
- if !ok {
- return
- }
- if !IsCallToAST(pass, call, "delete") {
- return
- }
- b, m, key, ok := isCommaOkMapIndex(stmt.Init)
- if !ok {
- return
- }
- if cond, ok := stmt.Cond.(*ast.Ident); !ok || pass.TypesInfo.ObjectOf(cond) != pass.TypesInfo.ObjectOf(b) {
- return
- }
- if Render(pass, call.Args[0]) != Render(pass, m) || Render(pass, call.Args[1]) != Render(pass, key) {
- return
- }
- ReportNodefFG(pass, stmt, "unnecessary guard around call to delete")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.IfStmt)(nil)}, fn)
- return nil, nil
-}
-
-func LintSimplifyTypeSwitch(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- stmt := node.(*ast.TypeSwitchStmt)
- if stmt.Init != nil {
- // bailing out for now, can't anticipate how type switches with initializers are being used
- return
- }
- expr, ok := stmt.Assign.(*ast.ExprStmt)
- if !ok {
- // the user is in fact assigning the result
- return
- }
- assert := expr.X.(*ast.TypeAssertExpr)
- ident, ok := assert.X.(*ast.Ident)
- if !ok {
- return
- }
- x := pass.TypesInfo.ObjectOf(ident)
- var allOffenders []ast.Node
- for _, clause := range stmt.Body.List {
- clause := clause.(*ast.CaseClause)
- if len(clause.List) != 1 {
- continue
- }
- hasUnrelatedAssertion := false
- var offenders []ast.Node
- ast.Inspect(clause, func(node ast.Node) bool {
- assert2, ok := node.(*ast.TypeAssertExpr)
- if !ok {
- return true
- }
- ident, ok := assert2.X.(*ast.Ident)
- if !ok {
- hasUnrelatedAssertion = true
- return false
- }
- if pass.TypesInfo.ObjectOf(ident) != x {
- hasUnrelatedAssertion = true
- return false
- }
-
- if !types.Identical(pass.TypesInfo.TypeOf(clause.List[0]), pass.TypesInfo.TypeOf(assert2.Type)) {
- hasUnrelatedAssertion = true
- return false
- }
- offenders = append(offenders, assert2)
- return true
- })
- if !hasUnrelatedAssertion {
- // don't flag cases that have other type assertions
- // unrelated to the one in the case clause. often
- // times, this is done for symmetry, when two
- // different values have to be asserted to the same
- // type.
- allOffenders = append(allOffenders, offenders...)
- }
- }
- if len(allOffenders) != 0 {
- at := ""
- for _, offender := range allOffenders {
- pos := lint.DisplayPosition(pass.Fset, offender.Pos())
- at += "\n\t" + pos.String()
- }
- ReportNodefFG(pass, expr, "assigning the result of this type assertion to a variable (switch %s := %s.(type)) could eliminate the following type assertions:%s", Render(pass, ident), Render(pass, ident), at)
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.TypeSwitchStmt)(nil)}, fn)
- return nil, nil
-}
diff --git a/vendor/honnef.co/go/tools/ssa/LICENSE b/vendor/honnef.co/go/tools/ssa/LICENSE
deleted file mode 100644
index aee48041e..000000000
--- a/vendor/honnef.co/go/tools/ssa/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/ssa/blockopt.go b/vendor/honnef.co/go/tools/ssa/blockopt.go
deleted file mode 100644
index 22c9a4c0d..000000000
--- a/vendor/honnef.co/go/tools/ssa/blockopt.go
+++ /dev/null
@@ -1,195 +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 ssa
-
-// 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.Index = -1
- for _, succ := range b.Succs {
- if succ.Index == 0 {
- markReachable(succ)
- }
- }
-}
-
-func DeleteUnreachableBlocks(f *Function) {
- deleteUnreachableBlocks(f)
-}
-
-// 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.Index temporarily as the mark bit.
- for _, b := range f.Blocks {
- b.Index = white
- }
- markReachable(f.Blocks[0])
- if f.Recover != nil {
- markReachable(f.Recover)
- }
- for i, b := range f.Blocks {
- if b.Index == white {
- for _, c := range b.Succs {
- if c.Index == 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
- }
- 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
- }
- b := a.Succs[0]
- if len(b.Preds) != 1 {
- 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
-}
-
-func OptimizeBlocks(f *Function) {
- optimizeBlocks(f)
-}
-
-// optimizeBlocks() performs some simple block optimizations on a
-// completed function: dead block elimination, block fusion, jump
-// threading.
-//
-func optimizeBlocks(f *Function) {
- 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/ssa/builder.go b/vendor/honnef.co/go/tools/ssa/builder.go
deleted file mode 100644
index 317ac0611..000000000
--- a/vendor/honnef.co/go/tools/ssa/builder.go
+++ /dev/null
@@ -1,2379 +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 ssa
-
-// This file implements the BUILD phase of SSA construction.
-//
-// SSA 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.
-// ssa.Packages are created in arbitrary order.
-//
-// In the BUILD phase (builder.go), the builder traverses the AST of
-// each Go source function and generates SSA 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 BUILD phases for distinct packages are independent and are
-// executed in parallel.
-//
-// TODO(adonovan): indeed, building functions is now embarrassingly parallel.
-// Audit for concurrency then benchmark using more goroutines.
-//
-// 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"
- "sync"
-)
-
-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()
-
- // SSA Value constants.
- vZero = intConst(0)
- vOne = intConst(1)
- vTrue = NewConst(constant.MakeBool(true), tBool)
-)
-
-// builder holds state associated with the package currently being built.
-// Its methods contain all the logic for AST-to-SSA conversion.
-type builder struct{}
-
-// 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) {
- switch e := e.(type) {
- case *ast.ParenExpr:
- b.cond(fn, e.X, t, f)
- return
-
- case *ast.BinaryExpr:
- switch e.Op {
- case token.LAND:
- ltrue := fn.newBasicBlock("cond.true")
- b.cond(fn, e.X, ltrue, f)
- fn.currentBlock = ltrue
- b.cond(fn, e.Y, t, f)
- return
-
- case token.LOR:
- lfalse := fn.newBasicBlock("cond.false")
- b.cond(fn, e.X, t, lfalse)
- fn.currentBlock = lfalse
- b.cond(fn, e.Y, t, f)
- return
- }
-
- case *ast.UnaryExpr:
- if e.Op == token.NOT {
- b.cond(fn, e.X, f, t)
- return
- }
- }
-
- // 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.
- emitIf(fn, b.expr(fn, e), t, f)
-}
-
-// 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 = NewConst(constant.MakeBool(false), t)
-
- case token.LOR:
- b.cond(fn, e.X, done, rhs)
- short = 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)
- fn.currentBlock = done
-
- phi := &Phi{Edges: edges, Comment: e.Op.String()}
- phi.pos = e.OpPos
- phi.typ = t
- return done.emit(phi)
-}
-
-// exprN lowers a multi-result expression e to SSA 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 UnaryExpr (when Op
-// is token.ARROW).
-//
-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)
-
- case *ast.IndexExpr:
- mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map)
- lookup := &Lookup{
- X: b.expr(fn, e.X),
- Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()),
- CommaOk: true,
- }
- lookup.setType(typ)
- lookup.setPos(e.Lbrack)
- return fn.emit(lookup)
-
- case *ast.TypeAssertExpr:
- return emitTypeTest(fn, b.expr(fn, e.X), typ.At(0).Type(), e.Lparen)
-
- case *ast.UnaryExpr: // must be receive <-
- unop := &UnOp{
- Op: token.ARROW,
- X: b.expr(fn, e.X),
- CommaOk: true,
- }
- unop.setType(typ)
- unop.setPos(e.OpPos)
- return fn.emit(unop)
- }
- panic(fmt.Sprintf("exprN(%T) in %s", e, fn))
-}
-
-// builtin emits to fn SSA 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, pos token.Pos) 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, pos)
- alloc.Comment = "makeslice"
- v := &Slice{
- X: alloc,
- High: n,
- }
- v.setPos(pos)
- v.setType(typ)
- return fn.emit(v)
- }
- v := &MakeSlice{
- Len: n,
- Cap: m,
- }
- v.setPos(pos)
- v.setType(typ)
- return fn.emit(v)
-
- case *types.Map:
- var res Value
- if len(args) == 2 {
- res = b.expr(fn, args[1])
- }
- v := &MakeMap{Reserve: res}
- v.setPos(pos)
- v.setType(typ)
- return fn.emit(v)
-
- case *types.Chan:
- var sz Value = vZero
- if len(args) == 2 {
- sz = b.expr(fn, args[1])
- }
- v := &MakeChan{Size: sz}
- v.setPos(pos)
- v.setType(typ)
- return fn.emit(v)
- }
-
- case "new":
- alloc := emitNew(fn, deref(typ), pos)
- alloc.Comment = "new"
- 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 intConst(at.Len())
- }
- // Otherwise treat as normal.
-
- case "panic":
- fn.emit(&Panic{
- X: emitConv(fn, b.expr(fn, args[0]), tEface),
- pos: pos,
- })
- fn.currentBlock = fn.newBasicBlock("unreachable")
- return vTrue // 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 SSA 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, pos: e.Pos(), expr: e}
-
- case *ast.CompositeLit:
- t := deref(fn.Pkg.typeOf(e))
- var v *Alloc
- if escaping {
- v = emitNew(fn, t, e.Lbrace)
- } else {
- v = fn.addLocal(t, e.Lbrace)
- }
- v.Comment = "complit"
- var sb storebuf
- b.compLit(fn, v, e, true, &sb)
- sb.emit(fn)
- return &address{addr: v, pos: e.Lbrace, 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)
- last := len(sel.Index()) - 1
- return &address{
- addr: emitFieldSelection(fn, v, sel.Index()[last], true, e.Sel),
- pos: e.Sel.Pos(),
- 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()),
- t: t.Elem(),
- pos: e.Lbrack,
- }
- default:
- panic("unexpected container type in IndexExpr: " + t.String())
- }
- v := &IndexAddr{
- X: x,
- Index: emitConv(fn, b.expr(fn, e.Index), tInt),
- }
- v.setPos(e.Lbrack)
- v.setType(et)
- return &address{addr: fn.emit(v), pos: e.Lbrack, expr: e}
-
- case *ast.StarExpr:
- return &address{addr: b.expr(fn, e.X), pos: e.Star, expr: e}
- }
-
- panic(fmt.Sprintf("unexpected address expression: %T", e))
-}
-
-type store struct {
- lhs lvalue
- rhs Value
-}
-
-type storebuf struct{ stores []store }
-
-func (sb *storebuf) store(lhs lvalue, rhs Value) {
- sb.stores = append(sb.stores, store{lhs, rhs})
-}
-
-func (sb *storebuf) emit(fn *Function) {
- for _, s := range sb.stores {
- s.lhs.store(fn, s.rhs)
- }
-}
-
-// 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) {
- // 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)
- } else {
- loc.store(fn, ptr)
- }
- 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)
- } else {
- loc.store(fn, rhs)
- }
-}
-
-// expr lowers a single-result expression e to SSA 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 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)
- } 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),
- pos: e.Type.Func,
- parent: fn,
- Pkg: fn.Pkg,
- Prog: fn.Prog,
- syntax: e,
- }
- fn.AnonFuncs = append(fn.AnonFuncs, fn2)
- 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)
-
- case *ast.TypeAssertExpr: // single-result form only
- return emitTypeAssert(fn, b.expr(fn, e.X), tv.Type, e.Lparen)
-
- 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)
- if y != x {
- switch y := y.(type) {
- case *Convert:
- y.pos = e.Lparen
- case *ChangeType:
- y.pos = e.Lparen
- case *MakeInterface:
- y.pos = e.Lparen
- }
- }
- 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.Lparen); v != nil {
- return v
- }
- }
- }
- // Regular function call.
- var v Call
- b.setCall(fn, e, &v.Call)
- v.setType(tv.Type)
- return fn.emit(&v)
-
- 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)
- }
- return addr.address(fn)
- case token.ADD:
- return b.expr(fn, e.X)
- case token.NOT, token.ARROW, token.SUB, token.XOR: // ! <- - ^
- v := &UnOp{
- Op: e.Op,
- X: b.expr(fn, e.X),
- }
- v.setPos(e.OpPos)
- v.setType(tv.Type)
- return fn.emit(v)
- 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.OpPos)
-
- 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.OpPos)
- // The type of x==y may be UntypedBool.
- return emitConv(fn, cmp, DefaultType(tv.Type))
- 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.setPos(e.Lbrack)
- v.setType(tv.Type)
- return fn.emit(v)
-
- 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 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) // var (address)
- }
- return v // (func)
- }
- // Local var.
- return emitLoad(fn, fn.lookup(obj, false)) // 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)
-
- 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)
- 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, token.NoPos)
- }
- c := &MakeClosure{
- Fn: makeBound(fn.Prog, obj),
- Bindings: []Value{v},
- }
- c.setPos(e.Sel.Pos())
- c.setType(tv.Type)
- return fn.emit(c)
-
- case types.FieldVal:
- indices := sel.Index()
- last := len(indices) - 1
- v := b.expr(fn, e.X)
- v = emitImplicitSelections(fn, v, indices[:last])
- 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),
- }
- v.setPos(e.Lbrack)
- v.setType(t.Elem())
- return fn.emit(v)
-
- case *types.Map:
- // Maps are not addressable.
- mapt := fn.Pkg.typeOf(e.X).Underlying().(*types.Map)
- v := &Lookup{
- X: b.expr(fn, e.X),
- Index: emitConv(fn, b.expr(fn, e.Index), mapt.Key()),
- }
- v.setPos(e.Lbrack)
- v.setType(mapt.Elem())
- return fn.emit(v)
-
- case *types.Basic: // => string
- // Strings are not addressable.
- v := &Lookup{
- X: b.expr(fn, e.X),
- Index: b.expr(fn, e.Index),
- }
- v.setPos(e.Lbrack)
- v.setType(tByte)
- return fn.emit(v)
-
- case *types.Slice, *types.Pointer: // *array
- // Addressable slice/array; use IndexAddr and Load.
- return b.addr(fn, e, false).load(fn)
-
- 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)
- }
-
- 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) 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])
- if !wantAddr && isPointer(v.Type()) {
- v = emitLoad(fn, v)
- }
- 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) {
- c.pos = e.Lparen
-
- // 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)
- 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())
- 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))
- }
- } 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())
- }
-
- // 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, nilConst(st))
- } else {
- // Replace a suffix of args with a slice containing it.
- at := types.NewArray(vt, int64(len(varargs)))
- a := emitNew(fn, at, token.NoPos)
- a.setPos(e.Rparen)
- a.Comment = "varargs"
- for i, arg := range varargs {
- iaddr := &IndexAddr{
- X: a,
- Index: intConst(int64(i)),
- }
- iaddr.setType(types.NewPointer(vt))
- fn.emit(iaddr)
- emitStore(fn, iaddr, arg, arg.Pos())
- }
- s := &Slice{X: a}
- s.setType(st)
- args[offset+np] = fn.emit(s)
- 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, pos token.Pos) {
- oldv := loc.load(fn)
- loc.store(fn, emitArith(fn, op, oldv, emitConv(fn, val, oldv.Type()), loc.typ(), pos))
-}
-
-// 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)
- }
-
- 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))
- }
- }
- }
-}
-
-// 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) {
- // 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)
- 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)
- }
- 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))
- }
- }
-}
-
-// 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, e.Lbrace, nil},
- zeroValue(fn, deref(addr.Type())))
- isZero = true
- }
- for i, e := range e.Elts {
- fieldIndex := i
- pos := e.Pos()
- 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
- pos = kv.Colon
- e = kv.Value
- break
- }
- }
- }
- sf := t.Field(fieldIndex)
- faddr := &FieldAddr{
- X: addr,
- Field: fieldIndex,
- }
- faddr.setType(types.NewPointer(sf.Type()))
- fn.emit(faddr)
- b.assign(fn, &address{addr: faddr, pos: pos, expr: e}, e, isZero, sb)
- }
-
- 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.Lbrace)
- alloc.Comment = "slicelit"
- array = alloc
- case *types.Array:
- at = t
- array = addr
-
- if !isZero && int64(len(e.Elts)) != at.Len() {
- // memclear
- sb.store(&address{array, e.Lbrace, nil},
- zeroValue(fn, deref(array.Type())))
- }
- }
-
- var idx *Const
- for _, e := range e.Elts {
- pos := e.Pos()
- if kv, ok := e.(*ast.KeyValueExpr); ok {
- idx = b.expr(fn, kv.Key).(*Const)
- pos = kv.Colon
- e = kv.Value
- } else {
- var idxval int64
- if idx != nil {
- idxval = idx.Int64() + 1
- }
- idx = intConst(idxval)
- }
- iaddr := &IndexAddr{
- X: array,
- Index: idx,
- }
- iaddr.setType(types.NewPointer(at.Elem()))
- fn.emit(iaddr)
- if t != at { // slice
- // backing array is unaliased => storebuf not needed.
- b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, nil)
- } else {
- b.assign(fn, &address{addr: iaddr, pos: pos, expr: e}, e, true, sb)
- }
- }
-
- if t != at { // slice
- s := &Slice{X: array}
- s.setPos(e.Lbrace)
- s.setType(typ)
- sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, fn.emit(s))
- }
-
- case *types.Map:
- m := &MakeMap{Reserve: intConst(int64(len(e.Elts)))}
- m.setPos(e.Lbrace)
- m.setType(typ)
- fn.emit(m)
- 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()),
- t: t.Elem(),
- pos: e.Colon,
- }
-
- // 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)
- }
- sb.store(&address{addr: addr, pos: e.Lbrace, expr: e}, m)
-
- default:
- panic("unexpected CompositeLit type: " + t.String())
- }
-}
-
-// switchStmt emits to fn code for the switch statement s, optionally
-// labelled by label.
-//
-func (b *builder) switchStmt(fn *Function, s *ast.SwitchStmt, label *lblock) {
- // We treat SwitchStmt like a sequential if-else chain.
- // Multiway dispatch can be recovered later by ssautil.Switches()
- // to those cases that are free of side effects.
- if s.Init != nil {
- b.stmt(fn, s.Init)
- }
- var tag Value = vTrue
- if s.Tag != nil {
- tag = b.expr(fn, s.Tag)
- }
- 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")
- // TODO(adonovan): opt: when tag==vTrue, we'd
- // get better code if we use b.cond(cond)
- // instead of BinOp(EQL, tag, b.expr(cond))
- // followed by If. Don't forget conversions
- // though.
- cond := emitCompare(fn, token.EQL, tag, b.expr(fn, cond), cond.Pos())
- emitIf(fn, cond, body, nextCond)
- 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)
- fn.currentBlock = nextCond
- }
- if dfltBlock != nil {
- emitJump(fn, dfltBlock)
- 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)
- fn.currentBlock = done
-}
-
-// typeSwitchStmt emits to fn code for the type switch statement s, optionally
-// labelled by label.
-//
-func (b *builder) typeSwitchStmt(fn *Function, s *ast.TypeSwitchStmt, label *lblock) {
- // We treat TypeSwitchStmt like a sequential if-else chain.
- // Multiway dispatch can be recovered later by ssautil.Switches().
-
- // Typeswitch lowering:
- //
- // var x X
- // switch y := x.(type) {
- // case T1, T2: S1 // >1 (y := x)
- // case nil: SN // nil (y := x)
- // default: SD // 0 types (y := x)
- // case T3: S3 // 1 type (y := x.(T3))
- // }
- //
- // ...s.Init...
- // x := eval x
- // .caseT1:
- // t1, ok1 := typeswitch,ok x
- // if ok1 then goto S1 else goto .caseT2
- // .caseT2:
- // t2, ok2 := typeswitch,ok x
- // if ok2 then goto S1 else goto .caseNil
- // .S1:
- // y := x
- // ...S1...
- // goto done
- // .caseNil:
- // if t2, ok2 := typeswitch,ok x
- // if x == nil then goto SN else goto .caseT3
- // .SN:
- // y := x
- // ...SN...
- // goto done
- // .caseT3:
- // t3, ok3 := typeswitch,ok x
- // if ok3 then goto S3 else goto default
- // .S3:
- // y := t3
- // ...S3...
- // goto done
- // .default:
- // y := x
- // ...SD...
- // goto done
- // .done:
-
- if s.Init != nil {
- b.stmt(fn, s.Init)
- }
-
- var x Value
- switch ass := s.Assign.(type) {
- case *ast.ExprStmt: // x.(type)
- x = b.expr(fn, unparen(ass.X).(*ast.TypeAssertExpr).X)
- case *ast.AssignStmt: // y := x.(type)
- x = b.expr(fn, unparen(ass.Rhs[0]).(*ast.TypeAssertExpr).X)
- }
-
- done := fn.newBasicBlock("typeswitch.done")
- if label != nil {
- label._break = done
- }
- var default_ *ast.CaseClause
- for _, clause := range s.Body.List {
- cc := clause.(*ast.CaseClause)
- if cc.List == nil {
- default_ = cc
- continue
- }
- body := fn.newBasicBlock("typeswitch.body")
- var next *BasicBlock
- var casetype types.Type
- var ti Value // ti, ok := typeassert,ok x
- for _, cond := range cc.List {
- next = fn.newBasicBlock("typeswitch.next")
- casetype = fn.Pkg.typeOf(cond)
- var condv Value
- if casetype == tUntypedNil {
- condv = emitCompare(fn, token.EQL, x, nilConst(x.Type()), token.NoPos)
- ti = x
- } else {
- yok := emitTypeTest(fn, x, casetype, cc.Case)
- ti = emitExtract(fn, yok, 0)
- condv = emitExtract(fn, yok, 1)
- }
- emitIf(fn, condv, body, next)
- fn.currentBlock = next
- }
- if len(cc.List) != 1 {
- ti = x
- }
- fn.currentBlock = body
- b.typeCaseBody(fn, cc, ti, done)
- fn.currentBlock = next
- }
- if default_ != nil {
- b.typeCaseBody(fn, default_, x, done)
- } else {
- emitJump(fn, done)
- }
- fn.currentBlock = done
-}
-
-func (b *builder) typeCaseBody(fn *Function, cc *ast.CaseClause, x Value, done *BasicBlock) {
- 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.
- emitStore(fn, fn.addNamedLocal(obj), x, obj.Pos())
- }
- fn.targets = &targets{
- tail: fn.targets,
- _break: done,
- }
- b.stmtList(fn, cc.Body)
- fn.targets = fn.targets.tail
- emitJump(fn, 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) {
- // 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)
- fn.currentBlock = done
- return
- }
- }
-
- // 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()),
- 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
- // sequential if-else chain, in effect:
- //
- // idx, recvOk, r0...r_n-1 := select(...)
- // if idx == 0 { // receive on channel 0 (first receive => r0)
- // x, ok := r0, recvOk
- // ...state0...
- // } else if v == 1 { // send on channel 1
- // ...state1...
- // } else {
- // ...default...
- // }
- sel := &Select{
- States: states,
- Blocking: blocking,
- }
- sel.setPos(s.Select)
- 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)
- idx := emitExtract(fn, sel, 0)
-
- done := fn.newBasicBlock("select.done")
- if label != nil {
- label._break = done
- }
-
- var defaultBody *[]ast.Stmt
- 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 {
- defaultBody = &clause.Body
- continue
- }
- body := fn.newBasicBlock("select.body")
- next := fn.newBasicBlock("select.next")
- emitIf(fn, emitCompare(fn, token.EQL, idx, intConst(int64(state)), token.NoPos), body, next)
- fn.currentBlock = 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)
- 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)
- if debugInfo {
- emitDebugRef(fn, states[state].DebugNode.(ast.Expr), v, false)
- }
- x.store(fn, v)
-
- 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))
- }
- r++
- }
- b.stmtList(fn, clause.Body)
- fn.targets = fn.targets.tail
- emitJump(fn, done)
- fn.currentBlock = next
- state++
- }
- if defaultBody != nil {
- fn.targets = &targets{
- tail: fn.targets,
- _break: done,
- }
- b.stmtList(fn, *defaultBody)
- fn.targets = fn.targets.tail
- } else {
- // A blocking select must match some case.
- // (This should really be a runtime.errorString, not a string.)
- fn.emit(&Panic{
- X: emitConv(fn, stringConst("blocking select matched no case"), tEface),
- })
- fn.currentBlock = fn.newBasicBlock("unreachable")
- }
- emitJump(fn, done)
- fn.currentBlock = done
-}
-
-// 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)
- 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)
-
- if s.Post != nil {
- fn.currentBlock = cont
- b.stmt(fn, s.Post)
- emitJump(fn, loop) // 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, pos token.Pos) (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 = 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)
- }
-
- index := fn.addLocal(tInt, token.NoPos)
- emitStore(fn, index, intConst(-1), pos)
-
- loop = fn.newBasicBlock("rangeindex.loop")
- emitJump(fn, loop)
- fn.currentBlock = loop
-
- incr := &BinOp{
- Op: token.ADD,
- X: emitLoad(fn, index),
- Y: vOne,
- }
- incr.setType(tInt)
- emitStore(fn, index, fn.emit(incr), pos)
-
- body := fn.newBasicBlock("rangeindex.body")
- done = fn.newBasicBlock("rangeindex.done")
- emitIf(fn, emitCompare(fn, token.LSS, incr, length, token.NoPos), body, done)
- fn.currentBlock = body
-
- k = emitLoad(fn, index)
- 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)
-
- 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))
-
- case *types.Slice:
- instr := &IndexAddr{
- X: x,
- Index: k,
- }
- instr.setType(types.NewPointer(t.Elem()))
- v = emitLoad(fn, fn.emit(instr))
-
- 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, pos token.Pos) (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.setPos(pos)
- rng.setType(tRangeIter)
- it := fn.emit(rng)
-
- loop = fn.newBasicBlock("rangeiter.loop")
- emitJump(fn, loop)
- 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)
-
- body := fn.newBasicBlock("rangeiter.body")
- done = fn.newBasicBlock("rangeiter.done")
- emitIf(fn, emitExtract(fn, okv, 0), body, done)
- fn.currentBlock = body
-
- if tk != tInvalid {
- k = emitExtract(fn, okv, 1)
- }
- if tv != tInvalid {
- v = emitExtract(fn, okv, 2)
- }
- 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, pos token.Pos) (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)
- fn.currentBlock = loop
- recv := &UnOp{
- Op: token.ARROW,
- X: x,
- CommaOk: true,
- }
- recv.setPos(pos)
- recv.setType(types.NewTuple(
- newVar("k", x.Type().Underlying().(*types.Chan).Elem()),
- varOk,
- ))
- ko := fn.emit(recv)
- body := fn.newBasicBlock("rangechan.body")
- done = fn.newBasicBlock("rangechan.done")
- emitIf(fn, emitExtract(fn, ko, 1), body, done)
- fn.currentBlock = body
- if tk != nil {
- k = emitExtract(fn, ko, 0)
- }
- 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) {
- 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, s.For)
-
- case *types.Chan:
- k, loop, done = b.rangeChan(fn, x, tk, s.For)
-
- case *types.Map, *types.Basic: // string
- k, v, loop, done = b.rangeIter(fn, x, tk, tv, s.For)
-
- 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)
- }
- if tv != nil {
- vl.store(fn, v)
- }
-
- 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) // back-edge
- fn.currentBlock = done
-}
-
-// stmt lowers statement s to SSA 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)
- 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:
- fn.emit(&Send{
- Chan: b.expr(fn, s.Chan),
- X: emitConv(fn, b.expr(fn, s.Value),
- fn.Pkg.typeOf(s.Chan).Underlying().(*types.Chan).Elem()),
- pos: s.Arrow,
- })
-
- 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, NewConst(constant.MakeInt64(1), loc.typ()), op, s.Pos())
-
- case *ast.AssignStmt:
- switch s.Tok {
- case token.ASSIGN, token.DEFINE:
- b.assignStmt(fn, s.Lhs, s.Rhs, s.Tok == token.DEFINE)
-
- 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.Pos())
- }
-
- case *ast.GoStmt:
- // The "intrinsics" new/make/len/cap are forbidden here.
- // panic is treated like an ordinary function call.
- v := Go{pos: s.Go}
- b.setCall(fn, s.Call, &v.Call)
- fn.emit(&v)
-
- case *ast.DeferStmt:
- // The "intrinsics" new/make/len/cap are forbidden here.
- // panic is treated like an ordinary function call.
- v := Defer{pos: s.Defer}
- b.setCall(fn, s.Call, &v.Call)
- fn.emit(&v)
-
- // A deferred call can cause recovery from panic,
- // and control resumes at the Recover block.
- createRecoverBlock(fn)
-
- case *ast.ReturnStmt:
- 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),
- fn.Signature.Results().At(i).Type()))
- }
- } 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())
- results = append(results, v)
- }
- }
- if fn.namedResults != nil {
- // Function has named result parameters (NRPs).
- // Perform parallel assignment of return operands to NRPs.
- for i, r := range results {
- emitStore(fn, fn.namedResults[i], r, s.Return)
- }
- }
- // Run function calls deferred in this
- // function when explicitly returning from it.
- fn.emit(new(RunDefers))
- if fn.namedResults != nil {
- // Reload NRPs to form the result tuple.
- results = results[:0]
- for _, r := range fn.namedResults {
- results = append(results, emitLoad(fn, r))
- }
- }
- fn.emit(&Return{Results: results, pos: s.Return})
- 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
- }
- emitJump(fn, block)
- 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")
- }
- b.cond(fn, s.Cond, then, els)
- fn.currentBlock = then
- b.stmt(fn, s.Body)
- emitJump(fn, done)
-
- if s.Else != nil {
- fn.currentBlock = els
- b.stmt(fn, s.Else)
- emitJump(fn, done)
- }
-
- fn.currentBlock = done
-
- case *ast.SwitchStmt:
- b.switchStmt(fn, s, label)
-
- case *ast.TypeSwitchStmt:
- b.typeSwitchStmt(fn, s, label)
-
- case *ast.SelectStmt:
- b.selectStmt(fn, s, label)
-
- case *ast.ForStmt:
- b.forStmt(fn, s, label)
-
- case *ast.RangeStmt:
- b.rangeStmt(fn, s, label)
-
- default:
- panic(fmt.Sprintf("unexpected statement kind: %T", s))
- }
-}
-
-// buildFunction builds SSA 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.syntax.(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 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 {
- fn.addParamObj(recv)
- }
- params := fn.Signature.Params()
- for i, n := 0, params.Len(); i < n; i++ {
- fn.addParamObj(params.At(i))
- }
- }
- return
- }
- if fn.Prog.mode&LogSource != 0 {
- defer logStack("build function %s @ %s", fn, fn.Prog.Fset.Position(fn.pos))()
- }
- fn.startBody()
- fn.createSyntacticParams(recvField, functype)
- b.stmt(fn, body)
- if cb := fn.currentBlock; cb != nil && (cb == fn.Blocks[0] || cb == fn.Recover || 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))
- }
- fn.finishBody()
-}
-
-// buildFuncDecl builds SSA 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)
- }
- b.buildFunction(fn)
-}
-
-// Build calls Package.Build for each package in prog.
-// Building occurs in parallel unless the BuildSerially mode flag was set.
-//
-// 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() {
- var wg sync.WaitGroup
- for _, p := range prog.packages {
- if prog.mode&BuildSerially != 0 {
- p.Build()
- } else {
- wg.Add(1)
- go func(p *Package) {
- p.Build()
- wg.Done()
- }(p)
- }
- }
- wg.Wait()
-}
-
-// Build builds SSA 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()
-
- var done *BasicBlock
-
- if p.Prog.mode&BareInits == 0 {
- // Make init() skip if package is already initialized.
- initguard := p.Var("init$guard")
- doinit := init.newBasicBlock("init.start")
- done = init.newBasicBlock("init.done")
- emitIf(init, emitLoad(init, initguard), done, doinit)
- init.currentBlock = doinit
- emitStore(init, initguard, vTrue, token.NoPos)
-
- // 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.Call.pos = init.pos
- v.setType(types.NewTuple())
- init.emit(&v)
- }
- }
-
- var b builder
-
- // 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), pos: v.Pos()}
- } else {
- lval = blank{}
- }
- b.assign(init, lval, varinit.Rhs, true, 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), v.Pos())
- }
- }
- }
-
- // 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().
- if p.Prog.mode&BareInits == 0 {
- emitJump(init, done)
- init.currentBlock = done
- }
- init.emit(new(Return))
- 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/ssa/const.go b/vendor/honnef.co/go/tools/ssa/const.go
deleted file mode 100644
index f95d9e114..000000000
--- a/vendor/honnef.co/go/tools/ssa/const.go
+++ /dev/null
@@ -1,169 +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 ssa
-
-// This file defines the Const SSA value type.
-
-import (
- "fmt"
- "go/constant"
- "go/token"
- "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{typ, 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 s string
- if c.Value == nil {
- s = "nil"
- } else if c.Value.Kind() == constant.String {
- s = constant.StringVal(c.Value)
- const max = 20
- // TODO(adonovan): don't cut a rune in half.
- if len(s) > max {
- s = s[:max-3] + "..." // abbreviate
- }
- s = strconv.Quote(s)
- } else {
- s = c.Value.String()
- }
- return s + ":" + relType(c.Type(), from)
-}
-
-func (c *Const) Name() string {
- return c.RelString(nil)
-}
-
-func (c *Const) String() string {
- return c.Name()
-}
-
-func (c *Const) Type() types.Type {
- return c.typ
-}
-
-func (c *Const) Referrers() *[]Instruction {
- return nil
-}
-
-func (c *Const) Parent() *Function { return nil }
-
-func (c *Const) Pos() token.Pos {
- return token.NoPos
-}
-
-// IsNil returns true if this constant represents a typed or untyped nil value.
-func (c *Const) IsNil() bool {
- return c.Value == nil
-}
-
-// TODO(adonovan): move everything below into honnef.co/go/tools/ssa/interp.
-
-// 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/ssa/create.go b/vendor/honnef.co/go/tools/ssa/create.go
deleted file mode 100644
index 85163a0c5..000000000
--- a/vendor/honnef.co/go/tools/ssa/create.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 ssa
-
-// This file implements the CREATE phase of SSA 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 SSA Program.
-//
-// mode controls diagnostics and checking during SSA 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
- pos: obj.Pos(),
- }
- 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,
- syntax: syntax,
- pos: obj.Pos(),
- Pkg: pkg,
- Prog: pkg.Prog,
- }
- if syntax == nil {
- fn.Synthetic = "loaded from gc object file"
- }
-
- pkg.values[obj] = 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 SSA 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 SSA 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)
- }
-
- // Add init() function.
- p.init = &Function{
- name: "init",
- Signature: new(types.Signature),
- Synthetic: "package initializer",
- Pkg: p,
- Prog: prog,
- }
- p.Members[p.init.name] = 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)
- }
- }
- }
- }
- }
-
- if prog.mode&BareInits == 0 {
- // 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 ssa.Program, which is
-// false---yet this function remains very convenient.
-// Clients should use (*Program).Package instead where possible.
-// SSA 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/ssa/doc.go b/vendor/honnef.co/go/tools/ssa/doc.go
deleted file mode 100644
index 0f71fda00..000000000
--- a/vendor/honnef.co/go/tools/ssa/doc.go
+++ /dev/null
@@ -1,125 +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 ssa defines a representation of the elements of Go programs
-// (packages, types, functions, variables and constants) using a
-// static single-assignment (SSA) form intermediate representation
-// (IR) for the bodies of functions.
-//
-// THIS INTERFACE IS EXPERIMENTAL AND IS LIKELY TO CHANGE.
-//
-// For an introduction to SSA form, 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.
-//
-// The level of abstraction of the SSA form is intentionally close to
-// the source language to facilitate construction of source analysis
-// tools. It is not intended for machine code generation.
-//
-// All looping, branching and switching constructs are replaced with
-// unstructured control flow. Higher-level control flow constructs
-// such as multi-way branch can be reconstructed as needed; see
-// ssautil.Switches() for an example.
-//
-// The simplest way to create the SSA representation of a package is
-// to load typed syntax trees using golang.org/x/tools/go/packages, then
-// invoke the ssautil.Packages helper function. See ExampleLoadPackages
-// and ExampleWholeProgram for examples.
-// The resulting ssa.Program contains all the packages and their
-// members, but SSA code is not created for function bodies until a
-// subsequent call to (*Package).Build or (*Program).Build.
-//
-// The builder initially builds a naive SSA 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 SSA 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 ✔ ✔
-// *Builtin ✔
-// *Call ✔ ✔
-// *ChangeInterface ✔ ✔
-// *ChangeType ✔ ✔
-// *Const ✔
-// *Convert ✔ ✔
-// *DebugRef ✔
-// *Defer ✔
-// *Extract ✔ ✔
-// *Field ✔ ✔
-// *FieldAddr ✔ ✔
-// *FreeVar ✔
-// *Function ✔ ✔ (func)
-// *Global ✔ ✔ (var)
-// *Go ✔
-// *If ✔
-// *Index ✔ ✔
-// *IndexAddr ✔ ✔
-// *Jump ✔
-// *Lookup ✔ ✔
-// *MakeChan ✔ ✔
-// *MakeClosure ✔ ✔
-// *MakeInterface ✔ ✔
-// *MakeMap ✔ ✔
-// *MakeSlice ✔ ✔
-// *MapUpdate ✔
-// *NamedConst ✔ (const)
-// *Next ✔ ✔
-// *Panic ✔
-// *Parameter ✔
-// *Phi ✔ ✔
-// *Range ✔ ✔
-// *Return ✔
-// *RunDefers ✔
-// *Select ✔ ✔
-// *Send ✔
-// *Slice ✔ ✔
-// *Store ✔
-// *Type ✔ (type)
-// *TypeAssert ✔ ✔
-// *UnOp ✔ ✔
-//
-// 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 SSA 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 ssa/ssautil 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,
-// ssa.Values/Instructions.
-//
-package ssa // import "honnef.co/go/tools/ssa"
diff --git a/vendor/honnef.co/go/tools/ssa/dom.go b/vendor/honnef.co/go/tools/ssa/dom.go
deleted file mode 100644
index a036be87c..000000000
--- a/vendor/honnef.co/go/tools/ssa/dom.go
+++ /dev/null
@@ -1,343 +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 ssa
-
-// 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"
- "math/big"
- "os"
- "sort"
-)
-
-// Idom returns the block that immediately dominates b:
-// its parent in the dominator tree, if any.
-// Neither the entry node (b.Index==0) nor recover node
-// (b==b.Parent().Recover()) 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
-}
-
-// ltState holds the working state for Lengauer-Tarjan algorithm
-// (during which domInfo.pre is repurposed for CFG DFS preorder number).
-type ltState struct {
- // Each slice is indexed by b.Index.
- sdom []*BasicBlock // b's semidominator
- parent []*BasicBlock // b's parent in DFS traversal of CFG
- ancestor []*BasicBlock // b's ancestor with least sdom
-}
-
-// dfs implements the depth-first search part of the LT algorithm.
-func (lt *ltState) dfs(v *BasicBlock, i int32, preorder []*BasicBlock) int32 {
- preorder[i] = v
- v.dom.pre = i // For now: DFS preorder of spanning tree of CFG
- i++
- lt.sdom[v.Index] = v
- lt.link(nil, v)
- for _, w := range v.Succs {
- if lt.sdom[w.Index] == nil {
- lt.parent[w.Index] = v
- i = lt.dfs(w, i, preorder)
- }
- }
- return i
-}
-
-// eval implements the EVAL part of the LT algorithm.
-func (lt *ltState) eval(v *BasicBlock) *BasicBlock {
- // TODO(adonovan): opt: do path compression per simple LT.
- u := v
- for ; lt.ancestor[v.Index] != nil; v = lt.ancestor[v.Index] {
- if lt.sdom[v.Index].dom.pre < lt.sdom[u.Index].dom.pre {
- u = v
- }
- }
- return u
-}
-
-// link implements the LINK part of the LT algorithm.
-func (lt *ltState) link(v, w *BasicBlock) {
- lt.ancestor[w.Index] = v
-}
-
-// buildDomTree computes the dominator tree of f using the LT algorithm.
-// Precondition: all blocks are reachable (e.g. optimizeBlocks has been run).
-//
-func buildDomTree(f *Function) {
- // The step numbers refer to the original LT paper; the
- // reordering is due to Georgiadis.
-
- // Clear any previous domInfo.
- for _, b := range f.Blocks {
- b.dom = domInfo{}
- }
-
- n := len(f.Blocks)
- // Allocate space for 5 contiguous [n]*BasicBlock arrays:
- // sdom, parent, ancestor, preorder, buckets.
- space := make([]*BasicBlock, 5*n)
- lt := ltState{
- sdom: space[0:n],
- parent: space[n : 2*n],
- ancestor: space[2*n : 3*n],
- }
-
- // Step 1. Number vertices by depth-first preorder.
- preorder := space[3*n : 4*n]
- root := f.Blocks[0]
- prenum := lt.dfs(root, 0, preorder)
- recover := f.Recover
- if recover != nil {
- lt.dfs(recover, prenum, preorder)
- }
-
- buckets := space[4*n : 5*n]
- copy(buckets, preorder)
-
- // In reverse preorder...
- for i := int32(n) - 1; i > 0; i-- {
- w := preorder[i]
-
- // Step 3. Implicitly define the immediate dominator of each node.
- for v := buckets[i]; v != w; v = buckets[v.dom.pre] {
- u := lt.eval(v)
- if lt.sdom[u.Index].dom.pre < i {
- v.dom.idom = u
- } else {
- v.dom.idom = w
- }
- }
-
- // Step 2. Compute the semidominators of all nodes.
- lt.sdom[w.Index] = lt.parent[w.Index]
- for _, v := range w.Preds {
- u := lt.eval(v)
- if lt.sdom[u.Index].dom.pre < lt.sdom[w.Index].dom.pre {
- lt.sdom[w.Index] = lt.sdom[u.Index]
- }
- }
-
- lt.link(lt.parent[w.Index], w)
-
- if lt.parent[w.Index] == lt.sdom[w.Index] {
- w.dom.idom = lt.parent[w.Index]
- } else {
- buckets[i] = buckets[lt.sdom[w.Index].dom.pre]
- buckets[lt.sdom[w.Index].dom.pre] = w
- }
- }
-
- // The final 'Step 3' is now outside the loop.
- for v := buckets[0]; v != root; v = buckets[v.dom.pre] {
- v.dom.idom = root
- }
-
- // Step 4. Explicitly define the immediate dominator of each
- // node, in preorder.
- for _, w := range preorder[1:] {
- if w == root || w == recover {
- w.dom.idom = nil
- } else {
- if w.dom.idom != lt.sdom[w.Index] {
- w.dom.idom = w.dom.idom.dom.idom
- }
- // Calculate Children relation as inverse of Idom.
- w.dom.idom.dom.children = append(w.dom.idom.dom.children, w)
- }
- }
-
- pre, post := numberDomTree(root, 0, 0)
- if recover != nil {
- numberDomTree(recover, pre, post)
- }
-
- // printDomTreeDot(os.Stderr, f) // debugging
- // printDomTreeText(os.Stderr, root, 0) // debugging
-
- if f.Prog.mode&SanityCheckFunctions != 0 {
- sanityCheckDomTree(f)
- }
-}
-
-// 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
-}
-
-// 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, b := range f.Blocks {
- if i == 0 || b == f.Recover {
- // 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 || b == f.Recover {
- continue
- }
- // Compute intersection across predecessors.
- var x big.Int
- x.Set(&all)
- for _, pred := range b.Preds {
- x.And(&x, &D[pred.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).
- // The Recover block (if any) must be treated specially so we skip it.
- ok := true
- for i := 0; i < n; i++ {
- for j := 0; j < n; j++ {
- b, c := f.Blocks[i], f.Blocks[j]
- if c == f.Recover {
- continue
- }
- 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 *bytes.Buffer, 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, "}")
-}
diff --git a/vendor/honnef.co/go/tools/ssa/emit.go b/vendor/honnef.co/go/tools/ssa/emit.go
deleted file mode 100644
index 6bf9ec32d..000000000
--- a/vendor/honnef.co/go/tools/ssa/emit.go
+++ /dev/null
@@ -1,469 +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 ssa
-
-// Helpers for emitting SSA instructions.
-
-import (
- "fmt"
- "go/ast"
- "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, pos token.Pos) *Alloc {
- v := &Alloc{Heap: true}
- v.setType(types.NewPointer(typ))
- v.setPos(pos)
- f.emit(v)
- 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) *UnOp {
- v := &UnOp{Op: token.MUL, X: addr}
- v.setType(deref(addr.Type()))
- f.emit(v)
- return v
-}
-
-// 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,
- })
-}
-
-// 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, pos token.Pos) Value {
- switch op {
- case token.SHL, token.SHR:
- x = emitConv(f, x, t)
- // 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])
- }
-
- 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)
- y = emitConv(f, y, t)
-
- default:
- panic("illegal op in emitArith: " + op.String())
-
- }
- v := &BinOp{
- Op: op,
- X: x,
- Y: y,
- }
- v.setPos(pos)
- v.setType(t)
- return f.emit(v)
-}
-
-// 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, pos token.Pos) 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 == vTrue && op == token.EQL {
- 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())
- } else if _, ok := yt.(*types.Interface); ok {
- x = emitConv(f, x, y.Type())
- } else if _, ok := x.(*Const); ok {
- x = emitConv(f, x, y.Type())
- } else if _, ok := y.(*Const); ok {
- y = emitConv(f, y, x.Type())
- //lint:ignore SA9003 no-op
- } else {
- // other cases, e.g. channels. No-op.
- }
-
- v := &BinOp{
- Op: op,
- X: x,
- Y: y,
- }
- v.setPos(pos)
- v.setType(tBool)
- return f.emit(v)
-}
-
-// 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) 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)
- }
-
- // 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)
- }
-
- // Untyped nil constant? Return interface-typed nil constant.
- if ut_src == tUntypedNil {
- return 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, DefaultType(ut_src))
- }
-
- f.Pkg.Prog.needMethodsOf(val.Type())
- mi := &MakeInterface{X: val}
- mi.setType(typ)
- return f.emit(mi)
- }
-
- // 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 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)
- }
-
- 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, pos token.Pos) *Store {
- s := &Store{
- Addr: addr,
- Val: emitConv(f, val, deref(addr.Type())),
- pos: pos,
- }
- f.emit(s)
- 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) {
- b := f.currentBlock
- b.emit(new(Jump))
- addEdge(b, target)
- f.currentBlock = nil
-}
-
-// 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) {
- b := f.currentBlock
- b.emit(&If{Cond: cond})
- addEdge(b, tblock)
- addEdge(b, fblock)
- f.currentBlock = nil
-}
-
-// 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) Value {
- e := &Extract{Tuple: tuple, Index: index}
- e.setType(tuple.Type().(*types.Tuple).At(index).Type())
- return f.emit(e)
-}
-
-// 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, pos token.Pos) Value {
- a := &TypeAssert{X: x, AssertedType: t}
- a.setPos(pos)
- a.setType(t)
- return f.emit(a)
-}
-
-// 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, pos token.Pos) Value {
- a := &TypeAssert{
- X: x,
- AssertedType: t,
- CommaOk: true,
- }
- a.setPos(pos)
- a.setType(types.NewTuple(
- newVar("value", t),
- varOk,
- ))
- return f.emit(a)
-}
-
-// 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) {
- tresults := f.Signature.Results()
- nr := tresults.Len()
- if nr == 1 {
- call.typ = tresults.At(0).Type()
- } else {
- call.typ = tresults
- }
- tuple := f.emit(call)
- 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)
- // 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.emit(&ret)
- 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) 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)
- // Load the field's value iff indirectly embedded.
- if isPointer(fld.Type()) {
- v = emitLoad(f, v)
- }
- } else {
- instr := &Field{
- X: v,
- Field: index,
- }
- instr.setType(fld.Type())
- v = f.emit(instr)
- }
- }
- 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.setPos(id.Pos())
- instr.setType(types.NewPointer(fld.Type()))
- v = f.emit(instr)
- // Load the field's value iff we don't want its address.
- if !wantAddr {
- v = emitLoad(f, v)
- }
- } else {
- instr := &Field{
- X: v,
- Field: index,
- }
- instr.setPos(id.Pos())
- instr.setType(fld.Type())
- v = f.emit(instr)
- }
- 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) Value {
- switch t.Underlying().(type) {
- case *types.Struct, *types.Array:
- return emitLoad(f, f.addLocal(t, token.NoPos))
- default:
- return zeroConst(t)
- }
-}
-
-// createRecoverBlock emits to f a block of code to return after a
-// recovered panic, and sets f.Recover to it.
-//
-// If f's result parameters are named, the code loads and returns
-// their current values, otherwise it returns the zero values of their
-// type.
-//
-// Idempotent.
-//
-func createRecoverBlock(f *Function) {
- if f.Recover != nil {
- return // already created
- }
- saved := f.currentBlock
-
- f.Recover = f.newBasicBlock("recover")
- f.currentBlock = f.Recover
-
- var results []Value
- if f.namedResults != nil {
- // Reload NRPs to form value tuple.
- for _, r := range f.namedResults {
- results = append(results, emitLoad(f, r))
- }
- } else {
- R := f.Signature.Results()
- for i, n := 0, R.Len(); i < n; i++ {
- T := R.At(i).Type()
-
- // Return zero value of each result type.
- results = append(results, zeroValue(f, T))
- }
- }
- f.emit(&Return{Results: results})
-
- f.currentBlock = saved
-}
diff --git a/vendor/honnef.co/go/tools/ssa/func.go b/vendor/honnef.co/go/tools/ssa/func.go
deleted file mode 100644
index 222eea641..000000000
--- a/vendor/honnef.co/go/tools/ssa/func.go
+++ /dev/null
@@ -1,765 +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 ssa
-
-// This file implements the Function and BasicBlock types.
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "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)
-}
-
-// 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) Value {
- 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))
-}
-
-// 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
- }
- }
-}
-
-func (b *BasicBlock) RemovePred(p *BasicBlock) {
- b.removePred(p)
-}
-
-// 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, pos token.Pos) *Parameter {
- v := &Parameter{
- name: name,
- typ: typ,
- pos: pos,
- parent: f,
- }
- f.Params = append(f.Params, v)
- return v
-}
-
-func (f *Function) addParamObj(obj types.Object) *Parameter {
- name := obj.Name()
- if name == "" {
- name = fmt.Sprintf("arg%d", len(f.Params))
- }
- param := f.addParam(name, obj.Type(), obj.Pos())
- 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) {
- param := f.addParamObj(obj)
- spill := &Alloc{Comment: obj.Name()}
- spill.setType(types.NewPointer(obj.Type()))
- spill.setPos(obj.Pos())
- f.objects[obj] = spill
- f.Locals = append(f.Locals, spill)
- f.emit(spill)
- f.emit(&Store{Addr: spill, Val: param})
-}
-
-// startBody initializes the function prior to generating SSA code for its body.
-// Precondition: f.Type() already set.
-//
-func (f *Function) startBody() {
- f.currentBlock = f.newBasicBlock("entry")
- f.objects = make(map[types.Object]Value) // needed for some synthetics, e.g. init
-}
-
-// 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])
- }
- // Anonymous receiver? No need to spill.
- if field.Names == nil {
- f.addParamObj(f.Signature.Recv())
- }
- }
- }
-
- // 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])
- }
- // Anonymous parameter? No need to spill.
- if field.Names == nil {
- f.addParamObj(f.Signature.Params().At(len(f.Params) - n))
- }
- }
- }
-
- // 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))
- }
- }
- }
-}
-
-// numberRegisters assigns numbers to all SSA registers
-// (value-defining Instructions) in f, to aid debugging.
-// (Non-Instruction Values are named at construction.)
-//
-func numberRegisters(f *Function) {
- v := 0
- for _, b := range f.Blocks {
- for _, instr := range b.Instrs {
- switch instr.(type) {
- case Value:
- instr.(interface {
- setNum(int)
- }).setNum(v)
- v++
- }
- }
- }
-}
-
-// 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)
- }
- }
- }
- }
- }
-}
-
-// finishBody() finalizes the function after SSA code generation of its body.
-func (f *Function) finishBody() {
- f.objects = nil
- f.currentBlock = nil
- f.lblocks = nil
-
- // Don't pin the AST in memory (except in debug mode).
- if n := f.syntax; n != nil && !f.debugInfo() {
- f.syntax = extentNode{n.Pos(), n.End()}
- }
-
- // 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]
-
- // comma-ok receiving from a time.Tick channel will never return
- // ok == false, so any branching on the value of ok can be
- // replaced with an unconditional jump. This will primarily match
- // `for range time.Tick(x)` loops, but it can also match
- // user-written code.
- for _, block := range f.Blocks {
- if len(block.Instrs) < 3 {
- continue
- }
- if len(block.Succs) != 2 {
- continue
- }
- var instrs []*Instruction
- for i, ins := range block.Instrs {
- if _, ok := ins.(*DebugRef); ok {
- continue
- }
- instrs = append(instrs, &block.Instrs[i])
- }
-
- for i, ins := range instrs {
- unop, ok := (*ins).(*UnOp)
- if !ok || unop.Op != token.ARROW {
- continue
- }
- call, ok := unop.X.(*Call)
- if !ok {
- continue
- }
- if call.Common().IsInvoke() {
- continue
- }
-
- // OPT(dh): surely there is a more efficient way of doing
- // this, than using FullName. We should already have
- // resolved time.Tick somewhere?
- v, ok := call.Common().Value.(*Function)
- if !ok {
- continue
- }
- t, ok := v.Object().(*types.Func)
- if !ok {
- continue
- }
- if t.FullName() != "time.Tick" {
- continue
- }
- ex, ok := (*instrs[i+1]).(*Extract)
- if !ok || ex.Tuple != unop || ex.Index != 1 {
- continue
- }
-
- ifstmt, ok := (*instrs[i+2]).(*If)
- if !ok || ifstmt.Cond != ex {
- continue
- }
-
- *instrs[i+2] = NewJump(block)
- succ := block.Succs[1]
- block.Succs = block.Succs[0:1]
- succ.RemovePred(block)
- }
- }
-
- optimizeBlocks(f)
-
- buildReferrers(f)
-
- buildDomTree(f)
-
- if f.Prog.mode&NaiveForm == 0 {
- // For debugging pre-state of lifting pass:
- // numberRegisters(f)
- // f.WriteTo(os.Stderr)
- lift(f)
- }
-
- f.namedResults = nil // (used by lifting)
-
- numberRegisters(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 (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) *Alloc {
- l := f.addLocal(obj.Type(), obj.Pos())
- l.Comment = obj.Name()
- f.objects[obj] = l
- return l
-}
-
-func (f *Function) addLocalForIdent(id *ast.Ident) *Alloc {
- return f.addNamedLocal(f.Pkg.info.Defs[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, pos token.Pos) *Alloc {
- v := &Alloc{}
- v.setType(types.NewPointer(typ))
- v.setPos(pos)
- f.Locals = append(f.Locals, v)
- f.emit(v)
- 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 ssa.Value for " + obj.String())
- }
- outer := f.parent.lookup(obj, true) // escaping
- v := &FreeVar{
- name: obj.Name(),
- typ: outer.Type(),
- pos: outer.Pos(),
- 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) Value {
- return f.currentBlock.emit(instr)
-}
-
-// 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())
- }
-
- if f.Recover != nil {
- fmt.Fprintf(buf, "# Recover: %s\n", f.Recover)
- }
-
- 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")
- }
-
- // NB. column calculations are confused by non-ASCII
- // characters and assume 8-space tabs.
- const punchcard = 80 // for old time's sake.
- const tabwidth = 8
- for _, b := range f.Blocks {
- if b == nil {
- // Corrupt CFG.
- fmt.Fprintf(buf, ".nil:\n")
- continue
- }
- n, _ := fmt.Fprintf(buf, "%d:", b.Index)
- bmsg := fmt.Sprintf("%s P:%d S:%d", b.Comment, len(b.Preds), len(b.Succs))
- fmt.Fprintf(buf, "%*s%s\n", punchcard-1-n-len(bmsg), "", bmsg)
-
- if false { // CFG debugging
- fmt.Fprintf(buf, "\t# CFG: %s --> %s --> %s\n", b.Preds, b, b.Succs)
- }
- for _, instr := range b.Instrs {
- buf.WriteString("\t")
- switch v := instr.(type) {
- case Value:
- l := punchcard - tabwidth
- // Left-align the instruction.
- if name := v.Name(); name != "" {
- n, _ := fmt.Fprintf(buf, "%s = ", name)
- l -= n
- }
- n, _ := buf.WriteString(instr.String())
- l -= n
- // Right-align the type if there's space.
- if t := v.Type(); t != nil {
- buf.WriteByte(' ')
- ts := relType(t, from)
- l -= len(ts) + len(" ") // (spaces before and after type)
- if l > 0 {
- fmt.Fprintf(buf, "%*s", l, "")
- }
- buf.WriteString(ts)
- }
- case nil:
- // Be robust against bad transforms.
- buf.WriteString("")
- default:
- buf.WriteString(instr.String())
- }
- buf.WriteString("\n")
- }
- }
- fmt.Fprintf(buf, "\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
-// SSA 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}
-}
-
-type extentNode [2]token.Pos
-
-func (n extentNode) Pos() token.Pos { return n[0] }
-func (n extentNode) End() token.Pos { return n[1] }
-
-// Syntax returns an ast.Node whose Pos/End methods provide the
-// lexical extent of the function if it was defined by Go source code
-// (f.Synthetic==""), or nil otherwise.
-//
-// If f was built with debug information (see Package.SetDebugRef),
-// the result is the *ast.FuncDecl or *ast.FuncLit that declared the
-// function. Otherwise, it is an opaque Node providing only position
-// information; this avoids pinning the AST in memory.
-//
-func (f *Function) Syntax() ast.Node { return f.syntax }
diff --git a/vendor/honnef.co/go/tools/ssa/identical.go b/vendor/honnef.co/go/tools/ssa/identical.go
deleted file mode 100644
index 53cbee107..000000000
--- a/vendor/honnef.co/go/tools/ssa/identical.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// +build go1.8
-
-package ssa
-
-import "go/types"
-
-var structTypesIdentical = types.IdenticalIgnoreTags
diff --git a/vendor/honnef.co/go/tools/ssa/identical_17.go b/vendor/honnef.co/go/tools/ssa/identical_17.go
deleted file mode 100644
index da89d3339..000000000
--- a/vendor/honnef.co/go/tools/ssa/identical_17.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// +build !go1.8
-
-package ssa
-
-import "go/types"
-
-var structTypesIdentical = types.Identical
diff --git a/vendor/honnef.co/go/tools/ssa/lift.go b/vendor/honnef.co/go/tools/ssa/lift.go
deleted file mode 100644
index 531358fa3..000000000
--- a/vendor/honnef.co/go/tools/ssa/lift.go
+++ /dev/null
@@ -1,657 +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 ssa
-
-// 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 φ-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.)
-
-// 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/token"
- "go/types"
- "math/big"
- "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) {
- p := &df[u.Index]
- *p = append(*p, v)
-}
-
-// build builds the dominance frontier df for the dominator (sub)tree
-// rooted at u, using the Cytron et al. algorithm.
-//
-// 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(u *BasicBlock) {
- // Encounter each node u in postorder of dom tree.
- for _, child := range u.dom.children {
- df.build(child)
- }
- for _, vb := range u.Succs {
- if v := vb.dom; v.idom != u {
- df.add(u, vb)
- }
- }
- for _, w := range u.dom.children {
- for _, vb := range df[w.Index] {
- // TODO(adonovan): opt: use word-parallel bitwise union.
- if v := vb.dom; v.idom != u {
- df.add(u, vb)
- }
- }
- }
-}
-
-func buildDomFrontier(fn *Function) domFrontier {
- df := make(domFrontier, len(fn.Blocks))
- df.build(fn.Blocks[0])
- if fn.Recover != nil {
- df.build(fn.Recover)
- }
- return df
-}
-
-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]
-}
-
-// lift replaces local and new Allocs accessed only with
-// load/store by SSA registers, inserting φ-nodes where necessary.
-// The result is a program in classical pruned SSA 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.
- df := buildDomFrontier(fn)
-
- 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)
- }
- }
- }
-
- newPhis := make(newPhiMap)
-
- // 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
-
- // A counter used to generate ~unique ids for Phi nodes, as an
- // aid to debugging. We use large numbers to make them highly
- // visible. All nodes are renumbered later.
- fresh := 1000
-
- // 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:
- index := -1
- if liftAlloc(df, instr, newPhis, &fresh) {
- index = numAllocs
- numAllocs++
- }
- instr.index = index
- case *Defer:
- usesDefer = true
- case *RunDefers:
- b.rundefers++
- }
- }
- }
-
- // 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)
-
- // Eliminate dead φ-nodes.
- removeDeadPhis(fn.Blocks, newPhis)
-
- // Prepend remaining live φ-nodes to each block.
- for _, b := range fn.Blocks {
- nps := newPhis[b]
- j := len(nps)
-
- rundefersToKill := b.rundefers
- if usesDefer {
- rundefersToKill = 0
- }
-
- if j+b.gaps+rundefersToKill == 0 {
- continue // fast path: no new phis or gaps
- }
-
- // Compact nps + non-nil Instrs into a new slice.
- // TODO(adonovan): opt: compact in situ (rightwards)
- // if Instrs has sufficient space or slack.
- dst := make([]Instruction, len(b.Instrs)+j-b.gaps-rundefersToKill)
- for i, np := range nps {
- dst[i] = np.phi
- }
- 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]
-}
-
-// removeDeadPhis removes φ-nodes not transitively needed by a
-// non-Phi, non-DebugRef instruction.
-func removeDeadPhis(blocks []*BasicBlock, newPhis newPhiMap) {
- // First pass: find the set of "live" φ-nodes: those reachable
- // from some non-Phi instruction.
- //
- // We compute reachability in reverse, starting from each φ,
- // rather than forwards, starting from each live non-Phi
- // instruction, because this way visits much less of the
- // Value graph.
- livePhis := make(map[*Phi]bool)
- for _, npList := range newPhis {
- for _, np := range npList {
- phi := np.phi
- if !livePhis[phi] && phiHasDirectReferrer(phi) {
- markLivePhi(livePhis, phi)
- }
- }
- }
-
- // Existing φ-nodes due to && and || operators
- // are all considered live (see Go issue 19622).
- for _, b := range blocks {
- for _, phi := range b.phis() {
- markLivePhi(livePhis, phi.(*Phi))
- }
- }
-
- // Second pass: eliminate unused phis from newPhis.
- for block, npList := range newPhis {
- j := 0
- for _, np := range npList {
- if livePhis[np.phi] {
- npList[j] = np
- j++
- } else {
- // discard it, first removing it from referrers
- for _, val := range np.phi.Edges {
- if refs := val.Referrers(); refs != nil {
- *refs = removeInstr(*refs, np.phi)
- }
- }
- np.phi.block = nil
- }
- }
- newPhis[block] = npList[:j]
- }
-}
-
-// markLivePhi marks phi, and all φ-nodes transitively reachable via
-// its Operands, live.
-func markLivePhi(livePhis map[*Phi]bool, phi *Phi) {
- livePhis[phi] = true
- for _, rand := range phi.Operands(nil) {
- if q, ok := (*rand).(*Phi); ok {
- if !livePhis[q] {
- markLivePhi(livePhis, q)
- }
- }
- }
-}
-
-// phiHasDirectReferrer reports whether phi is directly referred to by
-// a non-Phi instruction. Such instructions are the
-// roots of the liveness traversal.
-func phiHasDirectReferrer(phi *Phi) bool {
- for _, instr := range *phi.Referrers() {
- if _, ok := instr.(*Phi); !ok {
- return true
- }
- }
- return false
-}
-
-type BlockSet struct{ big.Int } // (inherit methods from Int)
-
-// add adds b to the set and returns true if the set changed.
-func (s *BlockSet) Add(b *BasicBlock) bool {
- i := b.Index
- if s.Bit(i) != 0 {
- return false
- }
- s.SetBit(&s.Int, i, 1)
- return true
-}
-
-func (s *BlockSet) Has(b *BasicBlock) bool {
- return s.Bit(b.Index) == 1
-}
-
-// take removes an arbitrary element from a set s and
-// returns its index, or returns -1 if empty.
-func (s *BlockSet) Take() int {
- l := s.BitLen()
- for i := 0; i < l; i++ {
- if s.Bit(i) == 1 {
- s.SetBit(&s.Int, i, 0)
- return i
- }
- }
- return -1
-}
-
-// newPhi is a pair of a newly introduced φ-node and the lifted Alloc
-// it replaces.
-type newPhi struct {
- phi *Phi
- alloc *Alloc
-}
-
-// newPhiMap records for each basic block, the set of newPhis that
-// must be prepended to the block.
-type newPhiMap map[*BasicBlock][]newPhi
-
-// liftAlloc determines whether alloc can be lifted into registers,
-// and if so, it populates newPhis with all the φ-nodes it may require
-// and returns true.
-//
-// fresh is a source of fresh ids for phi nodes.
-//
-func liftAlloc(df domFrontier, alloc *Alloc, newPhis newPhiMap, fresh *int) bool {
- // Don't lift aggregates into registers, because we don't have
- // a way to express their zero-constants.
- switch deref(alloc.Type()).Underlying().(type) {
- case *types.Array, *types.Struct:
- return false
- }
-
- // Don't lift named return values in functions that defer
- // calls that may recover from panic.
- if fn := alloc.Parent(); fn.Recover != nil {
- for _, nr := range fn.namedResults {
- if nr == alloc {
- return false
- }
- }
- }
-
- // Compute defblocks, the set of blocks containing a
- // definition of the alloc cell.
- var defblocks BlockSet
- for _, instr := range *alloc.Referrers() {
- // Bail out if we discover the alloc is not liftable;
- // the only operations permitted to use the alloc are
- // loads/stores into the cell, and DebugRef.
- switch instr := instr.(type) {
- case *Store:
- if instr.Val == alloc {
- return false // address used as value
- }
- if instr.Addr != alloc {
- panic("Alloc.Referrers is inconsistent")
- }
- defblocks.Add(instr.Block())
- case *UnOp:
- if instr.Op != token.MUL {
- return false // not a load
- }
- if instr.X != alloc {
- panic("Alloc.Referrers is inconsistent")
- }
- case *DebugRef:
- // ok
- default:
- return false // some other instruction
- }
- }
- // The Alloc itself counts as a (zero) definition of the cell.
- defblocks.Add(alloc.Block())
-
- if debugLifting {
- fmt.Fprintln(os.Stderr, "\tlifting ", alloc, alloc.Name())
- }
-
- fn := alloc.Parent()
-
- // Φ-insertion.
- //
- // What follows is the body of the main loop of the insert-φ
- // function described by Cytron et al, but instead of using
- // counter tricks, we just reset the 'hasAlready' and 'work'
- // sets each iteration. These are bitmaps so it's pretty cheap.
- //
- // TODO(adonovan): opt: recycle slice storage for W,
- // hasAlready, defBlocks across liftAlloc calls.
- var hasAlready BlockSet
-
- // Initialize W and work to defblocks.
- var work BlockSet = defblocks // blocks seen
- var W BlockSet // blocks to do
- W.Set(&defblocks.Int)
-
- // Traverse iterated dominance frontier, inserting φ-nodes.
- for i := W.Take(); i != -1; i = W.Take() {
- u := fn.Blocks[i]
- for _, v := range df[u.Index] {
- if hasAlready.Add(v) {
- // Create φ-node.
- // It will be prepended to v.Instrs later, if needed.
- phi := &Phi{
- Edges: make([]Value, len(v.Preds)),
- Comment: alloc.Comment,
- }
- // This is merely a debugging aid:
- phi.setNum(*fresh)
- *fresh++
-
- phi.pos = alloc.Pos()
- phi.setType(deref(alloc.Type()))
- phi.block = v
- if debugLifting {
- fmt.Fprintf(os.Stderr, "\tplace %s = %s at block %s\n", phi.Name(), phi, v)
- }
- newPhis[v] = append(newPhis[v], newPhi{phi, alloc})
-
- if work.Add(v) {
- W.Add(v)
- }
- }
- }
- }
-
- return true
-}
-
-// replaceAll replaces all intraprocedural uses of x with y,
-// updating x.Referrers and y.Referrers.
-// Precondition: x.Referrers() != nil, i.e. x must be local to some function.
-//
-func replaceAll(x, y Value) {
- var rands []*Value
- pxrefs := x.Referrers()
- pyrefs := y.Referrers()
- for _, instr := range *pxrefs {
- rands = instr.Operands(rands[:0]) // recycle storage
- for _, rand := range rands {
- if *rand != nil {
- if *rand == x {
- *rand = y
- }
- }
- }
- if pyrefs != nil {
- *pyrefs = append(*pyrefs, instr) // dups ok
- }
- }
- *pxrefs = nil // x is now unreferenced
-}
-
-// renamed returns the value to which alloc is being renamed,
-// constructing it lazily if it's the implicit zero initialization.
-//
-func renamed(renaming []Value, alloc *Alloc) Value {
- v := renaming[alloc.index]
- if v == nil {
- v = zeroConst(deref(alloc.Type()))
- renaming[alloc.index] = v
- }
- return v
-}
-
-// rename implements the (Cytron et al) SSA renaming algorithm, a
-// preorder traversal of the dominator tree replacing all loads of
-// Alloc cells with the value stored to that cell by the dominating
-// store instruction. For lifting, we need only consider loads,
-// stores and φ-nodes.
-//
-// renaming is a map from *Alloc (keyed by index number) to its
-// dominating stored value; newPhis[x] is the set of new φ-nodes to be
-// prepended to block x.
-//
-func rename(u *BasicBlock, renaming []Value, newPhis newPhiMap) {
- // Each φ-node becomes the new name for its associated Alloc.
- for _, np := range newPhis[u] {
- phi := np.phi
- alloc := np.alloc
- renaming[alloc.index] = phi
- }
-
- // Rename loads and stores of allocs.
- for i, instr := range u.Instrs {
- switch instr := instr.(type) {
- case *Alloc:
- if instr.index >= 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())
- }
- // Remove the store from the referrer list of the stored value.
- if refs := instr.Val.Referrers(); refs != nil {
- *refs = removeInstr(*refs, instr)
- }
- // Delete the Store.
- u.Instrs[i] = nil
- u.gaps++
- }
-
- case *UnOp:
- if instr.Op == token.MUL {
- if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // load of Alloc cell
- newval := renamed(renaming, alloc)
- if debugLifting {
- fmt.Fprintf(os.Stderr, "\tupdate load %s = %s with %s\n",
- instr.Name(), instr, newval.Name())
- }
- // Replace all references to
- // the loaded value by the
- // dominating stored value.
- replaceAll(instr, newval)
- // Delete the Load.
- u.Instrs[i] = nil
- u.gaps++
- }
- }
-
- case *DebugRef:
- if alloc, ok := instr.X.(*Alloc); ok && alloc.index >= 0 { // ref of Alloc cell
- if instr.IsAddr {
- instr.X = renamed(renaming, alloc)
- 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++
- }
- }
- }
- }
-
- // For each φ-node in a CFG successor, rename the edge.
- for _, v := range u.Succs {
- phis := newPhis[v]
- if len(phis) == 0 {
- continue
- }
- i := v.predIndex(u)
- for _, np := range phis {
- phi := np.phi
- alloc := np.alloc
- newval := renamed(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.
- for i, v := range u.dom.children {
- r := renaming
- if i < len(u.dom.children)-1 {
- // On all but the final iteration, we must make
- // a copy to avoid destructive update.
- r = make([]Value, len(renaming))
- copy(r, renaming)
- }
- rename(v, r, newPhis)
- }
-
-}
diff --git a/vendor/honnef.co/go/tools/ssa/lvalue.go b/vendor/honnef.co/go/tools/ssa/lvalue.go
deleted file mode 100644
index eb5d71e18..000000000
--- a/vendor/honnef.co/go/tools/ssa/lvalue.go
+++ /dev/null
@@ -1,123 +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 ssa
-
-// lvalues are the union of addressable expressions and map-index
-// expressions.
-
-import (
- "go/ast"
- "go/token"
- "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) // stores v into the location
- load(fn *Function) 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
- pos token.Pos // source position
- expr ast.Expr // source syntax of the value (not address) [debug mode]
-}
-
-func (a *address) load(fn *Function) Value {
- load := emitLoad(fn, a.addr)
- load.pos = a.pos
- return load
-}
-
-func (a *address) store(fn *Function, v Value) {
- store := emitStore(fn, a.addr, v, a.pos)
- 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 or string. These locations are not addressable
-// since pointers cannot be formed from them, but they do support
-// load(), and in the case of maps, store().
-//
-type element struct {
- m, k Value // map or string
- t types.Type // map element type or string byte type
- pos token.Pos // source position of colon ({k:v}) or lbrack (m[k]=v)
-}
-
-func (e *element) load(fn *Function) Value {
- l := &Lookup{
- X: e.m,
- Index: e.k,
- }
- l.setPos(e.pos)
- l.setType(e.t)
- return fn.emit(l)
-}
-
-func (e *element) store(fn *Function, v Value) {
- up := &MapUpdate{
- Map: e.m,
- Key: e.k,
- Value: emitConv(fn, v, e.t),
- }
- up.pos = e.pos
- fn.emit(up)
-}
-
-func (e *element) address(fn *Function) Value {
- panic("map/string 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) Value {
- panic("blank.load is illegal")
-}
-
-func (bl blank) store(fn *Function, v Value) {
- s := &BlankStore{
- Val: v,
- }
- fn.emit(s)
-}
-
-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/ssa/methods.go b/vendor/honnef.co/go/tools/ssa/methods.go
deleted file mode 100644
index 9cf383916..000000000
--- a/vendor/honnef.co/go/tools/ssa/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 ssa
-
-// 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/ssa/mode.go b/vendor/honnef.co/go/tools/ssa/mode.go
deleted file mode 100644
index d2a269893..000000000
--- a/vendor/honnef.co/go/tools/ssa/mode.go
+++ /dev/null
@@ -1,100 +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 ssa
-
-// 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 = ssa.BuilderMode(0)
-// func init() { flag.Var(&mode, "build", ssa.BuilderModeDoc) }
-//
-type BuilderMode uint
-
-const (
- PrintPackages BuilderMode = 1 << iota // Print package inventory to stdout
- PrintFunctions // Print function SSA code to stdout
- LogSource // Log source locations as SSA builder progresses
- SanityCheckFunctions // Perform sanity checking of function bodies
- NaiveForm // Build naïve SSA form: don't replace local loads/stores with registers
- BuildSerially // Build packages serially, not in parallel.
- GlobalDebug // Enable debug info for all packages
- BareInits // Build init functions without guards or calls to dependent inits
-)
-
-const BuilderModeDoc = `Options controlling the SSA builder.
-The value is a sequence of zero or more of these letters:
-C perform sanity [C]hecking of the SSA form.
-D include [D]ebug info for every function.
-P print [P]ackage inventory.
-F print [F]unction SSA code.
-S log [S]ource locations as SSA builder progresses.
-L build distinct packages seria[L]ly instead of in parallel.
-N build [N]aive SSA form: don't replace local loads/stores with registers.
-I build bare [I]nit functions: no init guards or calls to dependent inits.
-`
-
-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&LogSource != 0 {
- buf.WriteByte('S')
- }
- if m&SanityCheckFunctions != 0 {
- buf.WriteByte('C')
- }
- if m&NaiveForm != 0 {
- buf.WriteByte('N')
- }
- if m&BuildSerially != 0 {
- buf.WriteByte('L')
- }
- 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 'S':
- mode |= LogSource | BuildSerially
- case 'C':
- mode |= SanityCheckFunctions
- case 'N':
- mode |= NaiveForm
- case 'L':
- mode |= BuildSerially
- 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/ssa/print.go b/vendor/honnef.co/go/tools/ssa/print.go
deleted file mode 100644
index 6fd277277..000000000
--- a/vendor/honnef.co/go/tools/ssa/print.go
+++ /dev/null
@@ -1,435 +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 ssa
-
-// 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 {
- var from *types.Package
- if i != nil {
- from = i.Parent().pkg()
- }
- switch v := v.(type) {
- case Member: // *Function or *Global
- return v.RelString(from)
- case *Const:
- 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", v.Name(), relType(v.Type(), from))
-}
-
-func (v *FreeVar) String() string {
- from := v.Parent().pkg()
- return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from))
-}
-
-func (v *Builtin) String() string {
- return fmt.Sprintf("builtin %s", v.Name())
-}
-
-// Instruction.String()
-
-func (v *Alloc) String() string {
- op := "local"
- if v.Heap {
- op = "new"
- }
- from := v.Parent().pkg()
- return fmt.Sprintf("%s %s (%s)", op, relType(deref(v.Type()), from), v.Comment)
-}
-
-func (v *Phi) String() string {
- var b bytes.Buffer
- b.WriteString("phi [")
- for i, edge := range v.Edges {
- if i > 0 {
- 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)
- }
- b.WriteString("]")
- if v.Comment != "" {
- b.WriteString(" #")
- b.WriteString(v.Comment)
- }
- return b.String()
-}
-
-func printCall(v *CallCommon, prefix string, instr Instruction) string {
- var b bytes.Buffer
- b.WriteString(prefix)
- if !v.IsInvoke() {
- b.WriteString(relName(v.Value, instr))
- } else {
- fmt.Fprintf(&b, "invoke %s.%s", relName(v.Value, instr), v.Method.Name())
- }
- b.WriteString("(")
- for i, arg := range v.Args {
- if i > 0 {
- b.WriteString(", ")
- }
- b.WriteString(relName(arg, instr))
- }
- if v.Signature().Variadic() {
- b.WriteString("...")
- }
- b.WriteString(")")
- return b.String()
-}
-
-func (c *CallCommon) String() string {
- return printCall(c, "", nil)
-}
-
-func (v *Call) String() string {
- return printCall(&v.Call, "", v)
-}
-
-func (v *BinOp) String() string {
- return fmt.Sprintf("%s %s %s", relName(v.X, v), v.Op.String(), relName(v.Y, v))
-}
-
-func (v *UnOp) String() string {
- return fmt.Sprintf("%s%s%s", v.Op, relName(v.X, v), commaOk(v.CommaOk))
-}
-
-func printConv(prefix string, v, x Value) string {
- from := v.Parent().pkg()
- return fmt.Sprintf("%s %s <- %s (%s)",
- prefix,
- relType(v.Type(), from),
- relType(x.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("change interface", v, v.X) }
-func (v *MakeInterface) String() string { return printConv("make", v, v.X) }
-
-func (v *MakeClosure) String() string {
- var b bytes.Buffer
- fmt.Fprintf(&b, "make closure %s", relName(v.Fn, v))
- if v.Bindings != nil {
- b.WriteString(" [")
- for i, c := range v.Bindings {
- if i > 0 {
- b.WriteString(", ")
- }
- b.WriteString(relName(c, v))
- }
- b.WriteString("]")
- }
- return b.String()
-}
-
-func (v *MakeSlice) String() string {
- from := v.Parent().pkg()
- return fmt.Sprintf("make %s %s %s",
- relType(v.Type(), from),
- relName(v.Len, v),
- relName(v.Cap, v))
-}
-
-func (v *Slice) String() string {
- var b bytes.Buffer
- b.WriteString("slice ")
- b.WriteString(relName(v.X, v))
- b.WriteString("[")
- if v.Low != nil {
- b.WriteString(relName(v.Low, v))
- }
- b.WriteString(":")
- if v.High != nil {
- b.WriteString(relName(v.High, v))
- }
- if v.Max != nil {
- b.WriteString(":")
- b.WriteString(relName(v.Max, v))
- }
- b.WriteString("]")
- return b.String()
-}
-
-func (v *MakeMap) String() string {
- res := ""
- if v.Reserve != nil {
- res = relName(v.Reserve, v)
- }
- from := v.Parent().pkg()
- return fmt.Sprintf("make %s %s", relType(v.Type(), from), res)
-}
-
-func (v *MakeChan) String() string {
- from := v.Parent().pkg()
- return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v))
-}
-
-func (v *FieldAddr) String() string {
- 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("&%s.%s [#%d]", relName(v.X, v), name, v.Field)
-}
-
-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()
- }
- return fmt.Sprintf("%s.%s [#%d]", relName(v.X, v), name, v.Field)
-}
-
-func (v *IndexAddr) String() string {
- return fmt.Sprintf("&%s[%s]", relName(v.X, v), relName(v.Index, v))
-}
-
-func (v *Index) String() string {
- return fmt.Sprintf("%s[%s]", relName(v.X, v), relName(v.Index, v))
-}
-
-func (v *Lookup) String() string {
- return fmt.Sprintf("%s[%s]%s", relName(v.X, v), relName(v.Index, v), commaOk(v.CommaOk))
-}
-
-func (v *Range) String() string {
- return "range " + relName(v.X, v)
-}
-
-func (v *Next) String() string {
- return "next " + relName(v.Iter, v)
-}
-
-func (v *TypeAssert) String() string {
- from := v.Parent().pkg()
- return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from))
-}
-
-func (v *Extract) String() string {
- return fmt.Sprintf("extract %s #%d", relName(v.Tuple, v), v.Index)
-}
-
-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
- }
- return fmt.Sprintf("jump %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 goto %d else %d", relName(s.Cond, s), tblock, fblock)
-}
-
-func (s *Go) String() string {
- return printCall(&s.Call, "go ", s)
-}
-
-func (s *Panic) String() string {
- return "panic " + relName(s.X, s)
-}
-
-func (s *Return) String() string {
- var b bytes.Buffer
- b.WriteString("return")
- for i, r := range s.Results {
- if i == 0 {
- b.WriteString(" ")
- } else {
- 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 (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"
- }
- return fmt.Sprintf("select %sblocking [%s]", non, b.String())
-}
-
-func (s *Store) String() string {
- return fmt.Sprintf("*%s = %s", relName(s.Addr, s), relName(s.Val, s))
-}
-
-func (s *BlankStore) String() string {
- return fmt.Sprintf("_ = %s", relName(s.Val, s))
-}
-
-func (s *MapUpdate) String() string {
- return fmt.Sprintf("%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")
-}
-
-func commaOk(x bool) string {
- if x {
- return ",ok"
- }
- return ""
-}
diff --git a/vendor/honnef.co/go/tools/ssa/sanity.go b/vendor/honnef.co/go/tools/ssa/sanity.go
deleted file mode 100644
index 1d29b66b0..000000000
--- a/vendor/honnef.co/go/tools/ssa/sanity.go
+++ /dev/null
@@ -1,535 +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 ssa
-
-// An optional pass for sanity-checking invariants of the SSA 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 SSA 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:
- s.errorf("control flow instruction not at end of block")
- 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]
- if _, ok := prev.(*Phi); !ok {
- s.errorf("Phi instruction follows a non-Phi: %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 '%s' has no value for edge #%d from %s", instr.Comment, 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 *Lookup:
- 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 *Sigma:
- // TODO(adonovan): implement checks.
- 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 {
- 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 != 0 {
- s.errorf("Panic-terminated block has %d successors; expected none", nsuccs)
- return
- }
-
- 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,
- // as is the Recover block, if any.)
- if (index > 0 && b != b.parent.Recover) && 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 {
- 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.Syntax() != 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)
- }
- if fn.Recover != nil && fn.Blocks[fn.Recover.Index] != fn.Recover {
- s.errorf("Recover block is not in Blocks slice")
- }
-
- 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 ssa.Function ("init#%d").
- } else {
- panic(fmt.Sprintf("%s: %T.Object().Name() = %s, want %s",
- pkg.Pkg.Path(), mem, obj.Name(), name))
- }
- }
- if obj.Pos() != mem.Pos() {
- panic(fmt.Sprintf("%s Pos=%d obj.Pos=%d", mem, mem.Pos(), obj.Pos()))
- }
- }
-}
diff --git a/vendor/honnef.co/go/tools/ssa/source.go b/vendor/honnef.co/go/tools/ssa/source.go
deleted file mode 100644
index 8d9cca170..000000000
--- a/vendor/honnef.co/go/tools/ssa/source.go
+++ /dev/null
@@ -1,293 +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 ssa
-
-// 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 SSA 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
- }
- }
- // SSA 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 SSA code for pkg has been built, so it can be
-// used to quickly reject check inputs that will cause
-// EnclosingFunction to fail, prior to SSA 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:
- if decl.Recv == nil && decl.Name.Name == "init" {
- // Explicit init() function.
- for _, b := range pkg.init.Blocks {
- for _, instr := range b.Instrs {
- if instr, ok := instr.(*Call); ok {
- if callee, ok := instr.Call.Value.(*Function); ok && callee.Pkg == pkg && callee.Pos() == decl.Name.NamePos {
- return callee
- }
- }
- }
- }
- // Hack: return non-nil when SSA is not yet
- // built so that HasEnclosingFunction works.
- return pkg.init
- }
- // Declared function/method.
- return findNamedFunc(pkg, decl.Name.NamePos)
- }
- }
- 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 {
- // Look at all package members and method sets of named types.
- // Not very efficient.
- for _, mem := range pkg.Members {
- switch mem := mem.(type) {
- case *Function:
- if mem.Pos() == pos {
- return mem
- }
- case *Type:
- mset := pkg.Prog.MethodSets.MethodSet(types.NewPointer(mem.Type()))
- for i, n := 0, mset.Len(); i < n; i++ {
- // Don't call Program.Method: avoid creating wrappers.
- obj := mset.At(i).Obj().(*types.Func)
- if obj.Pos() == pos {
- return pkg.values[obj].(*Function)
- }
- }
- }
- }
- return nil
-}
-
-// ValueForExpr returns the SSA 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 ssa.Value given a source position, use
-// astutil.PathEnclosingInterval to locate the ast.Node, then
-// EnclosingFunction to locate the Function, then ValueForExpr to find
-// the ssa.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 SSA Package corresponding to the specified
-// type-checker package object.
-// It returns nil if no such SSA 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 SSA 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 SSA 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 SSA 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 SSA 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; SSA 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/ssa/ssa.go b/vendor/honnef.co/go/tools/ssa/ssa.go
deleted file mode 100644
index aeddd65e5..000000000
--- a/vendor/honnef.co/go/tools/ssa/ssa.go
+++ /dev/null
@@ -1,1745 +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 ssa
-
-// This package defines a high-level intermediate representation for
-// Go programs using static single-assignment (SSA) form.
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- "go/types"
- "sync"
-
- "golang.org/x/tools/go/types/typeutil"
-)
-
-// A Program is a partial or complete Go program converted to SSA form.
-type Program struct {
- Fset *token.FileSet // position information for the files of this Program
- 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 SSA 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)
- 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
-
- // 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
- Pos() token.Pos // position of member's declaration, if known
- 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 SSA value that can be referenced by an instruction.
-type Value interface {
- // 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 SSA Value is not semantically significant,
- // and may not even be unique within a function.
- Name() string
-
- // 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, Const 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, Const and Global.
- //
- // Instruction.Operands contains the inverse of this relation.
- Referrers() *[]Instruction
-
- // Pos returns the location of the AST token most closely
- // associated with the operation that gave rise to this value,
- // or token.NoPos if it was not explicit in the source.
- //
- // For each ast.Node type, a particular token is designated as
- // the closest location for the expression, e.g. the Lparen
- // for an *ast.CallExpr. This permits a compact but
- // approximate mapping from Values to source positions for use
- // in diagnostic messages, for example.
- //
- // (Do not use this position to determine which Value
- // corresponds to an ast.Expr; use Function.ValueForExpr
- // instead. NB: it requires that the function was built with
- // debug information.)
- Pos() token.Pos
-}
-
-// An Instruction is an SSA 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 {
- // String returns the disassembled form of this value.
- //
- // Examples of Instructions that are Values:
- // "x + y" (BinOp)
- // "len([])" (Call)
- // Note that the name of the Value is not printed.
- //
- // Examples of Instructions that are not Values:
- // "return x" (Return)
- // "*y = x" (Store)
- //
- // (The separation 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
-
- // 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
-
- // Pos returns the location of the AST token most closely
- // associated with the operation that gave rise to this
- // instruction, or token.NoPos if it was not explicit in the
- // source.
- //
- // For each ast.Node type, a particular token is designated as
- // the closest location for the expression, e.g. the Go token
- // for an *ast.GoStmt. This permits a compact but approximate
- // mapping from Instructions to source positions for use in
- // diagnostic messages, for example.
- //
- // (Do not use this position to determine which Instruction
- // corresponds to an ast.Expr; see the notes for Value.Pos.
- // This position may be used to determine which non-Value
- // Instruction corresponds to some ast.Stmts, but not all: If
- // and Jump instructions have no Pos(), for example.)
- Pos() token.Pos
-}
-
-// A Node is a node in the SSA 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 SSA graph algorithms. Clients should
-// use the more specific and informative Value or Instruction
-// interfaces where appropriate.
-//
-type Node interface {
- // Common methods:
- String() string
- 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().
-//
-// Recover is an optional second entry point to which control resumes
-// after a recovered panic. The Recover block may contain only a return
-// statement, preceded by a load of the function's named return
-// parameters, if any.
-//
-// 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 {
- 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
- pos token.Pos
-
- Synthetic string // provenance of synthetic function; "" for true source functions
- syntax ast.Node // *ast.Func{Decl,Lit}; replaced with simple ast.Node after build, unless debug mode
- 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
- Recover *BasicBlock // optional; control transfers here after recovered panic
- AnonFuncs []*Function // anonymous functions directly beneath this one
- referrers []Instruction // referring instructions (iff Parent() != nil)
-
- // 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
- targets *targets // linked stack of branch targets
- lblocks map[*ast.Object]*lblock // labelled blocks
-}
-
-// BasicBlock represents an SSA basic block.
-//
-// The final element of Instrs is always an explicit transfer of
-// control (If, Jump, Return, or Panic).
-//
-// 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 SSA 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
- 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 {
- name string
- typ types.Type
- pos token.Pos
- 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 {
- name string
- object types.Object // a *types.Var; nil for non-source locals
- typ types.Type
- pos token.Pos
- parent *Function
- referrers []Instruction
-}
-
-// 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:
-// 42:int
-// "hello":untyped string
-// 3+4i:MyComplex
-//
-type Const struct {
- typ types.Type
- 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 {
- name string
- object types.Object // a *types.Var; may be nil for synthetics e.g. init$guard
- typ types.Type
- pos token.Pos
-
- 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 ssa-defined
-// intrinsics:
-//
-// // wrapnilchk returns ptr if non-nil, panics otherwise.
-// // (For use in indirection wrappers.)
-// func ssa: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 {
- 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
-// "local" alloc. Each local 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 "new" alloc. Each new 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:
-// t0 = local int
-// t1 = new int
-//
-type Alloc struct {
- register
- Comment string
- Heap bool
- index int // dense numbering; for lifting
-}
-
-var _ Instruction = (*Sigma)(nil)
-var _ Value = (*Sigma)(nil)
-
-type Sigma struct {
- register
- X Value
- Branch bool
-}
-
-func (p *Sigma) Value() Value {
- v := p.X
- for {
- sigma, ok := v.(*Sigma)
- if !ok {
- break
- }
- v = sigma
- }
- return v
-}
-
-func (p *Sigma) String() string {
- return fmt.Sprintf("σ [%s.%t]", relName(p.X, p), p.Branch)
-}
-
-// 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-φ
-// 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:
-// t2 = phi [0: t0, 1: t1]
-//
-type Phi struct {
- register
- Comment string // a hint as to its purpose
- Edges []Value // Edges[i] is value for Block().Preds[i]
-}
-
-// 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:
-// t2 = println(t0, t1)
-// t4 = t3()
-// t7 = invoke t5.Println(...t6)
-//
-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:
-// t1 = t0 + 1:int
-//
-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.
-// ARROW is channel receive.
-// MUL is pointer indirection (load).
-// XOR is bitwise complement.
-// SUB is negation.
-// NOT is logical negation.
-//
-// If CommaOk and Op=ARROW, 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 (ARROW) implicit in ranging over a channel,
-// Pos() returns the ast.RangeStmt.For.
-// For implicit memory loads (STAR), Pos() returns the position of the
-// most closely associated source-level construct; the details are not
-// specified.
-//
-// Example printed form:
-// t0 = *x
-// t2 = <-t1,ok
-//
-type UnOp struct {
- register
- Op token.Token // One of: NOT SUB ARROW MUL XOR ! - <- * ^
- X Value
- CommaOk bool
-}
-
-// 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:
-// t1 = changetype *int <- IntPtr (t0)
-//
-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 SSA construction.
-//
-// Pos() returns the ast.CallExpr.Lparen, if the instruction arose
-// from an explicit conversion in the source.
-//
-// Example printed form:
-// t1 = convert []byte <- string (t0)
-//
-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:
-// t1 = change interface interface{} <- I (t0)
-//
-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:
-// t1 = make interface{} <- int (42:int)
-// t2 = make Stringer <- t0
-//
-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:
-// t0 = make closure anon@1.2 [x y z]
-// t1 = make closure bound$(main.I).add [i]
-//
-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 = make map[string]int t0
-// t1 = make StringIntMap t0
-//
-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:
-// t0 = make chan int 0
-// t0 = make IntChan 0
-//
-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:
-// t1 = make []string 1:int t0
-// t1 = make StringSlice 1:int t0
-//
-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:
-// t1 = slice t0[1:]
-//
-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:
-// t1 = &t0.name [#1]
-//
-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:
-// t1 = t0.name [#1]
-//
-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 Lookup 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:
-// t2 = &t0[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:
-// t2 = t0[t1]
-//
-type Index struct {
- register
- X Value // array
- Index Value // integer index
-}
-
-// The Lookup instruction yields element Index of collection X, a map
-// or string. Index is an integer expression if X is a string or the
-// appropriate key type if X is 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:
-// t2 = t0[t1]
-// t5 = t3[t4],ok
-//
-type Lookup struct {
- register
- X Value // string or map
- Index Value // numeric or key-typed index
- CommaOk bool // return a value,ok pair
-}
-
-// 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_i (0<=i 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:
-// t1 = typeassert t0.(int)
-// t3 = typeassert,ok t2.(T)
-//
-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, UnOp(ARROW) and
-// IndexExpr(Map).
-//
-// Example printed form:
-// t1 = extract t0 #1
-//
-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 done
-//
-type Jump 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 NoPos.
-//
-// Example printed form:
-// if t0 goto done else body
-//
-type If struct {
- anInstruction
- Cond Value
-}
-
-// 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, Lookup or UnOp(ARROW) 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 nil:I, 2:int
-//
-type Return struct {
- anInstruction
- Results []Value
- pos token.Pos
-}
-
-// 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 no successors.
-//
-// 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 t0
-//
-type Panic struct {
- anInstruction
- X Value // an interface{}
- pos token.Pos
-}
-
-// 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(t0, t1)
-// go t3()
-// go invoke t5.Println(...t6)
-//
-type Go struct {
- anInstruction
- Call CallCommon
- pos token.Pos
-}
-
-// 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(t0, t1)
-// defer t3()
-// defer invoke t5.Println(...t6)
-//
-type Defer struct {
- anInstruction
- Call CallCommon
- pos token.Pos
-}
-
-// The Send instruction sends X on channel Chan.
-//
-// Pos() returns the ast.SendStmt.Arrow, if explicit in the source.
-//
-// Example printed form:
-// send t0 <- t1
-//
-type Send struct {
- anInstruction
- Chan, X Value
- pos token.Pos
-}
-
-// 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:
-// *x = y
-//
-type Store struct {
- anInstruction
- Addr Value
- Val Value
- pos token.Pos
-}
-
-// 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:
-// _ = t0
-//
-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:
-// t0[t1] = t2
-//
-type MapUpdate struct {
- anInstruction
- Map Value
- Key Value
- Value Value
- pos token.Pos
-}
-
-// A DebugRef instruction maps a source-level expression Expr to the
-// SSA 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.
-//
-// If Expr is an *ast.Ident denoting a var or func, Object() returns
-// the object; though this information can be obtained from the type
-// checker, including it here greatly facilitates debugging.
-// For non-Ident expressions, Object() returns nil.
-//
-// 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 SSA 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 SSA form.
-//
-// Clients must not assume that the 'id' value (and the Name() derived
-// from it) is unique within a function. As always in this API,
-// semantics are determined only by identity; names exist only to
-// facilitate debugging.
-//
-type register struct {
- anInstruction
- num int // "name" of virtual register, e.g. "t0". Not guaranteed unique.
- typ types.Type // type of virtual register
- pos token.Pos // position of source expression, or NoPos
- referrers []Instruction
-}
-
-// anInstruction is a mix-in embedded by all Instructions.
-// It provides the implementations of the Block and setBlock methods.
-type anInstruction struct {
- 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:
-// t2 = println(t0, t1)
-// go t3()
-// defer t5(...t6)
-//
-// 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:
-// t1 = invoke t0.String()
-// go invoke t3.Run(t2)
-// defer invoke t4.Handle(...t5)
-//
-// 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)
- pos token.Pos // position of CallExpr.Lparen, iff explicit in source
-}
-
-// IsInvoke returns true if this call has "invoke" (not "call") mode.
-func (c *CallCommon) IsInvoke() bool {
- return c.Method != nil
-}
-
-func (c *CallCommon) Pos() token.Pos { return c.pos }
-
-// 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 // returns the result value of the call (*Call) or nil (*Go, *Defer)
-}
-
-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) Pos() token.Pos { return v.pos }
-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) Pos() token.Pos { return v.pos }
-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) Pos() token.Pos { return v.pos }
-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) Type() types.Type { return v.typ }
-func (v *Parameter) Name() string { return v.name }
-func (v *Parameter) Object() types.Object { return v.object }
-func (v *Parameter) Referrers() *[]Instruction { return &v.referrers }
-func (v *Parameter) Pos() token.Pos { return v.pos }
-func (v *Parameter) Parent() *Function { return v.parent }
-
-func (v *Alloc) Type() types.Type { return v.typ }
-func (v *Alloc) Referrers() *[]Instruction { return &v.referrers }
-func (v *Alloc) Pos() token.Pos { return v.pos }
-
-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.num) }
-func (v *register) setNum(num int) { v.num = num }
-func (v *register) Referrers() *[]Instruction { return &v.referrers }
-func (v *register) Pos() token.Pos { return v.pos }
-func (v *register) setPos(pos token.Pos) { v.pos = pos }
-
-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 (v *Call) Pos() token.Pos { return v.Call.pos }
-func (s *Defer) Pos() token.Pos { return s.pos }
-func (s *Go) Pos() token.Pos { return s.pos }
-func (s *MapUpdate) Pos() token.Pos { return s.pos }
-func (s *Panic) Pos() token.Pos { return s.pos }
-func (s *Return) Pos() token.Pos { return s.pos }
-func (s *Send) Pos() token.Pos { return s.pos }
-func (s *Store) Pos() token.Pos { return s.pos }
-func (s *BlankStore) Pos() token.Pos { return token.NoPos }
-func (s *If) Pos() token.Pos { return token.NoPos }
-func (s *Jump) Pos() token.Pos { return token.NoPos }
-func (s *RunDefers) Pos() token.Pos { return token.NoPos }
-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 (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 (v *Lookup) 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 (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)
-}
-
-// 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/ssa/staticcheck.conf b/vendor/honnef.co/go/tools/ssa/staticcheck.conf
deleted file mode 100644
index d7b38bc35..000000000
--- a/vendor/honnef.co/go/tools/ssa/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/ssa/testmain.go b/vendor/honnef.co/go/tools/ssa/testmain.go
deleted file mode 100644
index 8ec15ba50..000000000
--- a/vendor/honnef.co/go/tools/ssa/testmain.go
+++ /dev/null
@@ -1,271 +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 ssa
-
-// CreateTestMainPackage synthesizes a main package that runs all the
-// tests of the supplied packages.
-// It is closely coupled to $GOROOT/src/cmd/go/test.go and $GOROOT/src/testing.
-//
-// TODO(adonovan): throws this all away now that x/tools/go/packages
-// provides access to the actual synthetic test main files.
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/parser"
- "go/types"
- "log"
- "os"
- "strings"
- "text/template"
-)
-
-// FindTests returns the Test, Benchmark, and Example functions
-// (as defined by "go test") defined in the specified package,
-// and its TestMain function, if any.
-//
-// Deprecated: use x/tools/go/packages to access synthetic testmain packages.
-func FindTests(pkg *Package) (tests, benchmarks, examples []*Function, main *Function) {
- prog := pkg.Prog
-
- // The first two of these may be nil: if the program doesn't import "testing",
- // it can't contain any tests, but it may yet contain Examples.
- var testSig *types.Signature // func(*testing.T)
- var benchmarkSig *types.Signature // func(*testing.B)
- var exampleSig = types.NewSignature(nil, nil, nil, false) // func()
-
- // Obtain the types from the parameters of testing.MainStart.
- if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
- mainStart := testingPkg.Func("MainStart")
- params := mainStart.Signature.Params()
- testSig = funcField(params.At(1).Type())
- benchmarkSig = funcField(params.At(2).Type())
-
- // Does the package define this function?
- // func TestMain(*testing.M)
- if f := pkg.Func("TestMain"); f != nil {
- sig := f.Type().(*types.Signature)
- starM := mainStart.Signature.Results().At(0).Type() // *testing.M
- if sig.Results().Len() == 0 &&
- sig.Params().Len() == 1 &&
- types.Identical(sig.Params().At(0).Type(), starM) {
- main = f
- }
- }
- }
-
- // TODO(adonovan): use a stable order, e.g. lexical.
- for _, mem := range pkg.Members {
- if f, ok := mem.(*Function); ok &&
- ast.IsExported(f.Name()) &&
- strings.HasSuffix(prog.Fset.Position(f.Pos()).Filename, "_test.go") {
-
- switch {
- case testSig != nil && isTestSig(f, "Test", testSig):
- tests = append(tests, f)
- case benchmarkSig != nil && isTestSig(f, "Benchmark", benchmarkSig):
- benchmarks = append(benchmarks, f)
- case isTestSig(f, "Example", exampleSig):
- examples = append(examples, f)
- default:
- continue
- }
- }
- }
- return
-}
-
-// Like isTest, but checks the signature too.
-func isTestSig(f *Function, prefix string, sig *types.Signature) bool {
- return isTest(f.Name(), prefix) && types.Identical(f.Signature, sig)
-}
-
-// Given the type of one of the three slice parameters of testing.Main,
-// returns the function type.
-func funcField(slice types.Type) *types.Signature {
- return slice.(*types.Slice).Elem().Underlying().(*types.Struct).Field(1).Type().(*types.Signature)
-}
-
-// isTest tells whether name looks like a test (or benchmark, according to prefix).
-// It is a Test (say) if there is a character after Test that is not a lower-case letter.
-// We don't want TesticularCancer.
-// Plundered from $GOROOT/src/cmd/go/test.go
-func isTest(name, prefix string) bool {
- if !strings.HasPrefix(name, prefix) {
- return false
- }
- if len(name) == len(prefix) { // "Test" is ok
- return true
- }
- return ast.IsExported(name[len(prefix):])
-}
-
-// CreateTestMainPackage creates and returns a synthetic "testmain"
-// package for the specified package if it defines tests, benchmarks or
-// executable examples, or nil otherwise. The new package is named
-// "main" and provides a function named "main" that runs the tests,
-// similar to the one that would be created by the 'go test' tool.
-//
-// Subsequent calls to prog.AllPackages include the new package.
-// The package pkg must belong to the program prog.
-//
-// Deprecated: use x/tools/go/packages to access synthetic testmain packages.
-func (prog *Program) CreateTestMainPackage(pkg *Package) *Package {
- if pkg.Prog != prog {
- log.Fatal("Package does not belong to Program")
- }
-
- // Template data
- var data struct {
- Pkg *Package
- Tests, Benchmarks, Examples []*Function
- Main *Function
- Go18 bool
- }
- data.Pkg = pkg
-
- // Enumerate tests.
- data.Tests, data.Benchmarks, data.Examples, data.Main = FindTests(pkg)
- if data.Main == nil &&
- data.Tests == nil && data.Benchmarks == nil && data.Examples == nil {
- return nil
- }
-
- // Synthesize source for testmain package.
- path := pkg.Pkg.Path() + "$testmain"
- tmpl := testmainTmpl
- if testingPkg := prog.ImportedPackage("testing"); testingPkg != nil {
- // In Go 1.8, testing.MainStart's first argument is an interface, not a func.
- data.Go18 = types.IsInterface(testingPkg.Func("MainStart").Signature.Params().At(0).Type())
- } else {
- // The program does not import "testing", but FindTests
- // returned non-nil, which must mean there were Examples
- // but no Test, Benchmark, or TestMain functions.
-
- // We'll simply call them from testmain.main; this will
- // ensure they don't panic, but will not check any
- // "Output:" comments.
- // (We should not execute an Example that has no
- // "Output:" comment, but it's impossible to tell here.)
- tmpl = examplesOnlyTmpl
- }
- var buf bytes.Buffer
- if err := tmpl.Execute(&buf, data); err != nil {
- log.Fatalf("internal error expanding template for %s: %v", path, err)
- }
- if false { // debugging
- fmt.Fprintln(os.Stderr, buf.String())
- }
-
- // Parse and type-check the testmain package.
- f, err := parser.ParseFile(prog.Fset, path+".go", &buf, parser.Mode(0))
- if err != nil {
- log.Fatalf("internal error parsing %s: %v", path, err)
- }
- conf := types.Config{
- DisableUnusedImportCheck: true,
- Importer: importer{pkg},
- }
- files := []*ast.File{f}
- 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),
- }
- testmainPkg, err := conf.Check(path, prog.Fset, files, info)
- if err != nil {
- log.Fatalf("internal error type-checking %s: %v", path, err)
- }
-
- // Create and build SSA code.
- testmain := prog.CreatePackage(testmainPkg, files, info, false)
- testmain.SetDebugMode(false)
- testmain.Build()
- testmain.Func("main").Synthetic = "test main function"
- testmain.Func("init").Synthetic = "package initializer"
- return testmain
-}
-
-// An implementation of types.Importer for an already loaded SSA program.
-type importer struct {
- pkg *Package // package under test; may be non-importable
-}
-
-func (imp importer) Import(path string) (*types.Package, error) {
- if p := imp.pkg.Prog.ImportedPackage(path); p != nil {
- return p.Pkg, nil
- }
- if path == imp.pkg.Pkg.Path() {
- return imp.pkg.Pkg, nil
- }
- return nil, fmt.Errorf("not found") // can't happen
-}
-
-var testmainTmpl = template.Must(template.New("testmain").Parse(`
-package main
-
-import "io"
-import "os"
-import "testing"
-import p {{printf "%q" .Pkg.Pkg.Path}}
-
-{{if .Go18}}
-type deps struct{}
-
-func (deps) ImportPath() string { return "" }
-func (deps) MatchString(pat, str string) (bool, error) { return true, nil }
-func (deps) StartCPUProfile(io.Writer) error { return nil }
-func (deps) StartTestLog(io.Writer) {}
-func (deps) StopCPUProfile() {}
-func (deps) StopTestLog() error { return nil }
-func (deps) WriteHeapProfile(io.Writer) error { return nil }
-func (deps) WriteProfileTo(string, io.Writer, int) error { return nil }
-
-var match deps
-{{else}}
-func match(_, _ string) (bool, error) { return true, nil }
-{{end}}
-
-func main() {
- tests := []testing.InternalTest{
-{{range .Tests}}
- { {{printf "%q" .Name}}, p.{{.Name}} },
-{{end}}
- }
- benchmarks := []testing.InternalBenchmark{
-{{range .Benchmarks}}
- { {{printf "%q" .Name}}, p.{{.Name}} },
-{{end}}
- }
- examples := []testing.InternalExample{
-{{range .Examples}}
- {Name: {{printf "%q" .Name}}, F: p.{{.Name}}},
-{{end}}
- }
- m := testing.MainStart(match, tests, benchmarks, examples)
-{{with .Main}}
- p.{{.Name}}(m)
-{{else}}
- os.Exit(m.Run())
-{{end}}
-}
-
-`))
-
-var examplesOnlyTmpl = template.Must(template.New("examples").Parse(`
-package main
-
-import p {{printf "%q" .Pkg.Pkg.Path}}
-
-func main() {
-{{range .Examples}}
- p.{{.Name}}()
-{{end}}
-}
-`))
diff --git a/vendor/honnef.co/go/tools/ssa/util.go b/vendor/honnef.co/go/tools/ssa/util.go
deleted file mode 100644
index ddb118460..000000000
--- a/vendor/honnef.co/go/tools/ssa/util.go
+++ /dev/null
@@ -1,119 +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 ssa
-
-// 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()
-}
-
-// DefaultType returns the default "typed" type for an "untyped" type;
-// it returns the incoming type for all other types. The default type
-// for untyped nil is untyped nil.
-//
-// Exported to ssa/interp.
-//
-// TODO(adonovan): use go/types.DefaultType after 1.8.
-//
-func DefaultType(typ types.Type) types.Type {
- if t, ok := typ.(*types.Basic); ok {
- k := t.Kind()
- switch k {
- case types.UntypedBool:
- k = types.Bool
- case types.UntypedInt:
- k = types.Int
- case types.UntypedRune:
- k = types.Rune
- case types.UntypedFloat:
- k = types.Float64
- case types.UntypedComplex:
- k = types.Complex128
- case types.UntypedString:
- k = types.String
- }
- typ = types.Typ[k]
- }
- return typ
-}
-
-// 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/ssa/wrappers.go b/vendor/honnef.co/go/tools/ssa/wrappers.go
deleted file mode 100644
index a4ae71d8c..000000000
--- a/vendor/honnef.co/go/tools/ssa/wrappers.go
+++ /dev/null
@@ -1,290 +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 ssa
-
-// 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,
- pos: obj.Pos(),
- }
- fn.startBody()
- fn.addSpilledParam(recv)
- createParams(fn, start)
-
- indices := sel.Index()
-
- var v Value = fn.Locals[0] // spilled receiver
- if isPointer(sel.Recv()) {
- v = emitLoad(fn, v)
-
- // 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: "ssa: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,
- stringConst(deref(sel.Recv()).String()),
- stringConst(sel.Obj().Name()),
- }
- c.setType(v.Type())
- v = fn.emit(&c)
- }
- }
-
- // 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])
-
- // 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)
- }
- 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)
- }
- for _, arg := range fn.Params[1:] {
- c.Call.Args = append(c.Call.Args, arg)
- }
- emitTailCall(fn, &c)
- 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))
- }
-}
-
-// -- 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,
- pos: obj.Pos(),
- }
-
- 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)
- 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/ssa/write.go b/vendor/honnef.co/go/tools/ssa/write.go
deleted file mode 100644
index 89761a18a..000000000
--- a/vendor/honnef.co/go/tools/ssa/write.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package ssa
-
-func NewJump(parent *BasicBlock) *Jump {
- return &Jump{anInstruction{parent}}
-}
diff --git a/vendor/honnef.co/go/tools/ssautil/ssautil.go b/vendor/honnef.co/go/tools/ssautil/ssautil.go
deleted file mode 100644
index 72c3c919d..000000000
--- a/vendor/honnef.co/go/tools/ssautil/ssautil.go
+++ /dev/null
@@ -1,58 +0,0 @@
-package ssautil
-
-import (
- "honnef.co/go/tools/ssa"
-)
-
-func Reachable(from, to *ssa.BasicBlock) bool {
- if from == to {
- return true
- }
- if from.Dominates(to) {
- return true
- }
-
- found := false
- Walk(from, func(b *ssa.BasicBlock) bool {
- if b == to {
- found = true
- return false
- }
- return true
- })
- return found
-}
-
-func Walk(b *ssa.BasicBlock, fn func(*ssa.BasicBlock) bool) {
- seen := map[*ssa.BasicBlock]bool{}
- wl := []*ssa.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 *ssa.Slice) ([]ssa.Value, bool) {
- var out []ssa.Value
- slice, ok := x.X.(*ssa.Alloc)
- if !ok || slice.Comment != "varargs" {
- return nil, false
- }
- for _, ref := range *slice.Referrers() {
- idx, ok := ref.(*ssa.IndexAddr)
- if !ok {
- continue
- }
- v := (*idx.Referrers())[0].(*ssa.Store).Val
- out = append(out, v)
- }
- return out, true
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/CONTRIBUTING.md b/vendor/honnef.co/go/tools/staticcheck/CONTRIBUTING.md
deleted file mode 100644
index b12c7afc7..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/CONTRIBUTING.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Contributing to staticcheck
-
-## Before filing an issue:
-
-### Are you having trouble building staticcheck?
-
-Check you have the latest version of its dependencies. Run
-```
-go get -u honnef.co/go/tools/staticcheck
-```
-If you still have problems, consider searching for existing issues before filing a new issue.
-
-## Before sending a pull request:
-
-Have you understood the purpose of staticcheck? Make sure to carefully read `README`.
diff --git a/vendor/honnef.co/go/tools/staticcheck/analysis.go b/vendor/honnef.co/go/tools/staticcheck/analysis.go
deleted file mode 100644
index 442aebe5a..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/analysis.go
+++ /dev/null
@@ -1,525 +0,0 @@
-package staticcheck
-
-import (
- "flag"
-
- "honnef.co/go/tools/facts"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/lint/lintutil"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
-)
-
-func newFlagSet() flag.FlagSet {
- fs := flag.NewFlagSet("", flag.PanicOnError)
- fs.Var(lintutil.NewVersionFlag(), "go", "Target Go version")
- return *fs
-}
-
-var Analyzers = map[string]*analysis.Analyzer{
- "SA1000": {
- Name: "SA1000",
- Run: callChecker(checkRegexpRules),
- Doc: Docs["SA1000"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1001": {
- Name: "SA1001",
- Run: CheckTemplate,
- Doc: Docs["SA1001"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1002": {
- Name: "SA1002",
- Run: callChecker(checkTimeParseRules),
- Doc: Docs["SA1002"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1003": {
- Name: "SA1003",
- Run: callChecker(checkEncodingBinaryRules),
- Doc: Docs["SA1003"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1004": {
- Name: "SA1004",
- Run: CheckTimeSleepConstant,
- Doc: Docs["SA1004"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1005": {
- Name: "SA1005",
- Run: CheckExec,
- Doc: Docs["SA1005"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1006": {
- Name: "SA1006",
- Run: CheckUnsafePrintf,
- Doc: Docs["SA1006"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1007": {
- Name: "SA1007",
- Run: callChecker(checkURLsRules),
- Doc: Docs["SA1007"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1008": {
- Name: "SA1008",
- Run: CheckCanonicalHeaderKey,
- Doc: Docs["SA1008"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1010": {
- Name: "SA1010",
- Run: callChecker(checkRegexpFindAllRules),
- Doc: Docs["SA1010"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1011": {
- Name: "SA1011",
- Run: callChecker(checkUTF8CutsetRules),
- Doc: Docs["SA1011"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1012": {
- Name: "SA1012",
- Run: CheckNilContext,
- Doc: Docs["SA1012"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1013": {
- Name: "SA1013",
- Run: CheckSeeker,
- Doc: Docs["SA1013"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1014": {
- Name: "SA1014",
- Run: callChecker(checkUnmarshalPointerRules),
- Doc: Docs["SA1014"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1015": {
- Name: "SA1015",
- Run: CheckLeakyTimeTick,
- Doc: Docs["SA1015"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1016": {
- Name: "SA1016",
- Run: CheckUntrappableSignal,
- Doc: Docs["SA1016"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1017": {
- Name: "SA1017",
- Run: callChecker(checkUnbufferedSignalChanRules),
- Doc: Docs["SA1017"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1018": {
- Name: "SA1018",
- Run: callChecker(checkStringsReplaceZeroRules),
- Doc: Docs["SA1018"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1019": {
- Name: "SA1019",
- Run: CheckDeprecated,
- Doc: Docs["SA1019"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Deprecated},
- Flags: newFlagSet(),
- },
- "SA1020": {
- Name: "SA1020",
- Run: callChecker(checkListenAddressRules),
- Doc: Docs["SA1020"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1021": {
- Name: "SA1021",
- Run: callChecker(checkBytesEqualIPRules),
- Doc: Docs["SA1021"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1023": {
- Name: "SA1023",
- Run: CheckWriterBufferModified,
- Doc: Docs["SA1023"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1024": {
- Name: "SA1024",
- Run: callChecker(checkUniqueCutsetRules),
- Doc: Docs["SA1024"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1025": {
- Name: "SA1025",
- Run: CheckTimerResetReturnValue,
- Doc: Docs["SA1025"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA1026": {
- Name: "SA1026",
- Run: callChecker(checkUnsupportedMarshal),
- Doc: Docs["SA1026"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA1027": {
- Name: "SA1027",
- Run: callChecker(checkAtomicAlignment),
- Doc: Docs["SA1027"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
-
- "SA2000": {
- Name: "SA2000",
- Run: CheckWaitgroupAdd,
- Doc: Docs["SA2000"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA2001": {
- Name: "SA2001",
- Run: CheckEmptyCriticalSection,
- Doc: Docs["SA2001"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA2002": {
- Name: "SA2002",
- Run: CheckConcurrentTesting,
- Doc: Docs["SA2002"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA2003": {
- Name: "SA2003",
- Run: CheckDeferLock,
- Doc: Docs["SA2003"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
-
- "SA3000": {
- Name: "SA3000",
- Run: CheckTestMainExit,
- Doc: Docs["SA3000"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA3001": {
- Name: "SA3001",
- Run: CheckBenchmarkN,
- Doc: Docs["SA3001"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
-
- "SA4000": {
- Name: "SA4000",
- Run: CheckLhsRhsIdentical,
- Doc: Docs["SA4000"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.TokenFile, facts.Generated},
- Flags: newFlagSet(),
- },
- "SA4001": {
- Name: "SA4001",
- Run: CheckIneffectiveCopy,
- Doc: Docs["SA4001"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4002": {
- Name: "SA4002",
- Run: CheckDiffSizeComparison,
- Doc: Docs["SA4002"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA4003": {
- Name: "SA4003",
- Run: CheckExtremeComparison,
- Doc: Docs["SA4003"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4004": {
- Name: "SA4004",
- Run: CheckIneffectiveLoop,
- Doc: Docs["SA4004"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4006": {
- Name: "SA4006",
- Run: CheckUnreadVariableValues,
- Doc: Docs["SA4006"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "SA4008": {
- Name: "SA4008",
- Run: CheckLoopCondition,
- Doc: Docs["SA4008"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4009": {
- Name: "SA4009",
- Run: CheckArgOverwritten,
- Doc: Docs["SA4009"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4010": {
- Name: "SA4010",
- Run: CheckIneffectiveAppend,
- Doc: Docs["SA4010"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4011": {
- Name: "SA4011",
- Run: CheckScopedBreak,
- Doc: Docs["SA4011"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4012": {
- Name: "SA4012",
- Run: CheckNaNComparison,
- Doc: Docs["SA4012"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4013": {
- Name: "SA4013",
- Run: CheckDoubleNegation,
- Doc: Docs["SA4013"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4014": {
- Name: "SA4014",
- Run: CheckRepeatedIfElse,
- Doc: Docs["SA4014"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4015": {
- Name: "SA4015",
- Run: callChecker(checkMathIntRules),
- Doc: Docs["SA4015"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA4016": {
- Name: "SA4016",
- Run: CheckSillyBitwiseOps,
- Doc: Docs["SA4016"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, facts.TokenFile},
- Flags: newFlagSet(),
- },
- "SA4017": {
- Name: "SA4017",
- Run: CheckPureFunctions,
- Doc: Docs["SA4017"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, facts.Purity},
- Flags: newFlagSet(),
- },
- "SA4018": {
- Name: "SA4018",
- Run: CheckSelfAssignment,
- Doc: Docs["SA4018"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile},
- Flags: newFlagSet(),
- },
- "SA4019": {
- Name: "SA4019",
- Run: CheckDuplicateBuildConstraints,
- Doc: Docs["SA4019"].String(),
- Requires: []*analysis.Analyzer{facts.Generated},
- Flags: newFlagSet(),
- },
- "SA4020": {
- Name: "SA4020",
- Run: CheckUnreachableTypeCases,
- Doc: Docs["SA4020"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA4021": {
- Name: "SA4021",
- Run: CheckSingleArgAppend,
- Doc: Docs["SA4021"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile},
- Flags: newFlagSet(),
- },
-
- "SA5000": {
- Name: "SA5000",
- Run: CheckNilMaps,
- Doc: Docs["SA5000"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5001": {
- Name: "SA5001",
- Run: CheckEarlyDefer,
- Doc: Docs["SA5001"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5002": {
- Name: "SA5002",
- Run: CheckInfiniteEmptyLoop,
- Doc: Docs["SA5002"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5003": {
- Name: "SA5003",
- Run: CheckDeferInInfiniteLoop,
- Doc: Docs["SA5003"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5004": {
- Name: "SA5004",
- Run: CheckLoopEmptyDefault,
- Doc: Docs["SA5004"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5005": {
- Name: "SA5005",
- Run: CheckCyclicFinalizer,
- Doc: Docs["SA5005"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5007": {
- Name: "SA5007",
- Run: CheckInfiniteRecursion,
- Doc: Docs["SA5007"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5008": {
- Name: "SA5008",
- Run: CheckStructTags,
- Doc: Docs["SA5008"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA5009": {
- Name: "SA5009",
- Run: callChecker(checkPrintfRules),
- Doc: Docs["SA5009"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
-
- "SA6000": {
- Name: "SA6000",
- Run: callChecker(checkRegexpMatchLoopRules),
- Doc: Docs["SA6000"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA6001": {
- Name: "SA6001",
- Run: CheckMapBytesKey,
- Doc: Docs["SA6001"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA6002": {
- Name: "SA6002",
- Run: callChecker(checkSyncPoolValueRules),
- Doc: Docs["SA6002"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer},
- Flags: newFlagSet(),
- },
- "SA6003": {
- Name: "SA6003",
- Run: CheckRangeStringRunes,
- Doc: Docs["SA6003"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "SA6005": {
- Name: "SA6005",
- Run: CheckToLowerToUpperComparison,
- Doc: Docs["SA6005"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
-
- "SA9001": {
- Name: "SA9001",
- Run: CheckDubiousDeferInChannelRangeLoop,
- Doc: Docs["SA9001"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA9002": {
- Name: "SA9002",
- Run: CheckNonOctalFileMode,
- Doc: Docs["SA9002"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- "SA9003": {
- Name: "SA9003",
- Run: CheckEmptyBranch,
- Doc: Docs["SA9003"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, facts.TokenFile, facts.Generated},
- Flags: newFlagSet(),
- },
- "SA9004": {
- Name: "SA9004",
- Run: CheckMissingEnumTypesInDeclaration,
- Doc: Docs["SA9004"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
- // Filtering generated code because it may include empty structs generated from data models.
- "SA9005": {
- Name: "SA9005",
- Run: callChecker(checkNoopMarshal),
- Doc: Docs["SA9005"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, valueRangesAnalyzer, facts.Generated, facts.TokenFile},
- Flags: newFlagSet(),
- },
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/buildtag.go b/vendor/honnef.co/go/tools/staticcheck/buildtag.go
deleted file mode 100644
index 888d3e9dc..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/buildtag.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package staticcheck
-
-import (
- "go/ast"
- "strings"
-
- . "honnef.co/go/tools/lint/lintdsl"
-)
-
-func buildTags(f *ast.File) [][]string {
- var out [][]string
- for _, line := range strings.Split(Preamble(f), "\n") {
- if !strings.HasPrefix(line, "+build ") {
- continue
- }
- line = strings.TrimSpace(strings.TrimPrefix(line, "+build "))
- fields := strings.Fields(line)
- out = append(out, fields)
- }
- return out
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/doc.go b/vendor/honnef.co/go/tools/staticcheck/doc.go
deleted file mode 100644
index 4a87d4a24..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/doc.go
+++ /dev/null
@@ -1,764 +0,0 @@
-package staticcheck
-
-import "honnef.co/go/tools/lint"
-
-var Docs = map[string]*lint.Documentation{
- "SA1000": &lint.Documentation{
- Title: `Invalid regular expression`,
- Since: "2017.1",
- },
-
- "SA1001": &lint.Documentation{
- Title: `Invalid template`,
- Since: "2017.1",
- },
-
- "SA1002": &lint.Documentation{
- Title: `Invalid format in time.Parse`,
- Since: "2017.1",
- },
-
- "SA1003": &lint.Documentation{
- Title: `Unsupported argument to functions in encoding/binary`,
- Text: `The encoding/binary package can only serialize types with known sizes.
-This precludes the use of the int and uint types, as their sizes
-differ on different architectures. Furthermore, it doesn't support
-serializing maps, channels, strings, or functions.
-
-Before Go 1.8, bool wasn't supported, either.`,
- Since: "2017.1",
- },
-
- "SA1004": &lint.Documentation{
- Title: `Suspiciously small untyped constant in time.Sleep`,
- Text: `The time.Sleep function takes a time.Duration as its only argument.
-Durations are expressed in nanoseconds. Thus, calling time.Sleep(1)
-will sleep for 1 nanosecond. This is a common source of bugs, as sleep
-functions in other languages often accept seconds or milliseconds.
-
-The time package provides constants such as time.Second to express
-large durations. These can be combined with arithmetic to express
-arbitrary durations, for example '5 * time.Second' for 5 seconds.
-
-If you truly meant to sleep for a tiny amount of time, use
-'n * time.Nanosecond' to signal to staticcheck that you did mean to sleep
-for some amount of nanoseconds.`,
- Since: "2017.1",
- },
-
- "SA1005": &lint.Documentation{
- Title: `Invalid first argument to exec.Command`,
- Text: `os/exec runs programs directly (using variants of the fork and exec
-system calls on Unix systems). This shouldn't be confused with running
-a command in a shell. The shell will allow for features such as input
-redirection, pipes, and general scripting. The shell is also
-responsible for splitting the user's input into a program name and its
-arguments. For example, the equivalent to
-
- ls / /tmp
-
-would be
-
- exec.Command("ls", "/", "/tmp")
-
-If you want to run a command in a shell, consider using something like
-the following – but be aware that not all systems, particularly
-Windows, will have a /bin/sh program:
-
- exec.Command("/bin/sh", "-c", "ls | grep Awesome")`,
- Since: "2017.1",
- },
-
- "SA1006": &lint.Documentation{
- Title: `Printf with dynamic first argument and no further arguments`,
- Text: `Using fmt.Printf with a dynamic first argument can lead to unexpected
-output. The first argument is a format string, where certain character
-combinations have special meaning. If, for example, a user were to
-enter a string such as
-
- Interest rate: 5%
-
-and you printed it with
-
- fmt.Printf(s)
-
-it would lead to the following output:
-
- Interest rate: 5%!(NOVERB).
-
-Similarly, forming the first parameter via string concatenation with
-user input should be avoided for the same reason. When printing user
-input, either use a variant of fmt.Print, or use the %s Printf verb
-and pass the string as an argument.`,
- Since: "2017.1",
- },
-
- "SA1007": &lint.Documentation{
- Title: `Invalid URL in net/url.Parse`,
- Since: "2017.1",
- },
-
- "SA1008": &lint.Documentation{
- Title: `Non-canonical key in http.Header map`,
- Text: `Keys in http.Header maps are canonical, meaning they follow a specific
-combination of uppercase and lowercase letters. Methods such as
-http.Header.Add and http.Header.Del convert inputs into this canonical
-form before manipulating the map.
-
-When manipulating http.Header maps directly, as opposed to using the
-provided methods, care should be taken to stick to canonical form in
-order to avoid inconsistencies. The following piece of code
-demonstrates one such inconsistency:
-
- h := http.Header{}
- h["etag"] = []string{"1234"}
- h.Add("etag", "5678")
- fmt.Println(h)
-
- // Output:
- // map[Etag:[5678] etag:[1234]]
-
-The easiest way of obtaining the canonical form of a key is to use
-http.CanonicalHeaderKey.`,
- Since: "2017.1",
- },
-
- "SA1010": &lint.Documentation{
- Title: `(*regexp.Regexp).FindAll called with n == 0, which will always return zero results`,
- Text: `If n >= 0, the function returns at most n matches/submatches. To
-return all results, specify a negative number.`,
- Since: "2017.1",
- },
-
- "SA1011": &lint.Documentation{
- Title: `Various methods in the strings package expect valid UTF-8, but invalid input is provided`,
- Since: "2017.1",
- },
-
- "SA1012": &lint.Documentation{
- Title: `A nil context.Context is being passed to a function, consider using context.TODO instead`,
- Since: "2017.1",
- },
-
- "SA1013": &lint.Documentation{
- Title: `io.Seeker.Seek is being called with the whence constant as the first argument, but it should be the second`,
- Since: "2017.1",
- },
-
- "SA1014": &lint.Documentation{
- Title: `Non-pointer value passed to Unmarshal or Decode`,
- Since: "2017.1",
- },
-
- "SA1015": &lint.Documentation{
- Title: `Using time.Tick in a way that will leak. Consider using time.NewTicker, and only use time.Tick in tests, commands and endless functions`,
- Since: "2017.1",
- },
-
- "SA1016": &lint.Documentation{
- Title: `Trapping a signal that cannot be trapped`,
- Text: `Not all signals can be intercepted by a process. Speficially, on
-UNIX-like systems, the syscall.SIGKILL and syscall.SIGSTOP signals are
-never passed to the process, but instead handled directly by the
-kernel. It is therefore pointless to try and handle these signals.`,
- Since: "2017.1",
- },
-
- "SA1017": &lint.Documentation{
- Title: `Channels used with os/signal.Notify should be buffered`,
- Text: `The os/signal package uses non-blocking channel sends when delivering
-signals. If the receiving end of the channel isn't ready and the
-channel is either unbuffered or full, the signal will be dropped. To
-avoid missing signals, the channel should be buffered and of the
-appropriate size. For a channel used for notification of just one
-signal value, a buffer of size 1 is sufficient.`,
- Since: "2017.1",
- },
-
- "SA1018": &lint.Documentation{
- Title: `strings.Replace called with n == 0, which does nothing`,
- Text: `With n == 0, zero instances will be replaced. To replace all
-instances, use a negative number, or use strings.ReplaceAll.`,
- Since: "2017.1",
- },
-
- "SA1019": &lint.Documentation{
- Title: `Using a deprecated function, variable, constant or field`,
- Since: "2017.1",
- },
-
- "SA1020": &lint.Documentation{
- Title: `Using an invalid host:port pair with a net.Listen-related function`,
- Since: "2017.1",
- },
-
- "SA1021": &lint.Documentation{
- Title: `Using bytes.Equal to compare two net.IP`,
- Text: `A net.IP stores an IPv4 or IPv6 address as a slice of bytes. The
-length of the slice for an IPv4 address, however, can be either 4 or
-16 bytes long, using different ways of representing IPv4 addresses. In
-order to correctly compare two net.IPs, the net.IP.Equal method should
-be used, as it takes both representations into account.`,
- Since: "2017.1",
- },
-
- "SA1023": &lint.Documentation{
- Title: `Modifying the buffer in an io.Writer implementation`,
- Text: `Write must not modify the slice data, even temporarily.`,
- Since: "2017.1",
- },
-
- "SA1024": &lint.Documentation{
- Title: `A string cutset contains duplicate characters`,
- Text: `The strings.TrimLeft and strings.TrimRight functions take cutsets, not
-prefixes. A cutset is treated as a set of characters to remove from a
-string. For example,
-
- strings.TrimLeft("42133word", "1234"))
-
-will result in the string "word" – any characters that are 1, 2, 3 or
-4 are cut from the left of the string.
-
-In order to remove one string from another, use strings.TrimPrefix instead.`,
- Since: "2017.1",
- },
-
- "SA1025": &lint.Documentation{
- Title: `It is not possible to use (*time.Timer).Reset's return value correctly`,
- Since: "2019.1",
- },
-
- "SA1026": &lint.Documentation{
- Title: `Cannot marshal channels or functions`,
- Since: "2019.2",
- },
-
- "SA1027": &lint.Documentation{
- Title: `Atomic access to 64-bit variable must be 64-bit aligned`,
- Text: `On ARM, x86-32, and 32-bit MIPS, it is the caller's responsibility to
-arrange for 64-bit alignment of 64-bit words accessed atomically. The
-first word in a variable or in an allocated struct, array, or slice
-can be relied upon to be 64-bit aligned.
-
-You can use the structlayout tool to inspect the alignment of fields
-in a struct.`,
- Since: "2019.2",
- },
-
- "SA2000": &lint.Documentation{
- Title: `sync.WaitGroup.Add called inside the goroutine, leading to a race condition`,
- Since: "2017.1",
- },
-
- "SA2001": &lint.Documentation{
- Title: `Empty critical section, did you mean to defer the unlock?`,
- Text: `Empty critical sections of the kind
-
- mu.Lock()
- mu.Unlock()
-
-are very often a typo, and the following was intended instead:
-
- mu.Lock()
- defer mu.Unlock()
-
-Do note that sometimes empty critical sections can be useful, as a
-form of signaling to wait on another goroutine. Many times, there are
-simpler ways of achieving the same effect. When that isn't the case,
-the code should be amply commented to avoid confusion. Combining such
-comments with a //lint:ignore directive can be used to suppress this
-rare false positive.`,
- Since: "2017.1",
- },
-
- "SA2002": &lint.Documentation{
- Title: `Called testing.T.FailNow or SkipNow in a goroutine, which isn't allowed`,
- Since: "2017.1",
- },
-
- "SA2003": &lint.Documentation{
- Title: `Deferred Lock right after locking, likely meant to defer Unlock instead`,
- Since: "2017.1",
- },
-
- "SA3000": &lint.Documentation{
- Title: `TestMain doesn't call os.Exit, hiding test failures`,
- Text: `Test executables (and in turn 'go test') exit with a non-zero status
-code if any tests failed. When specifying your own TestMain function,
-it is your responsibility to arrange for this, by calling os.Exit with
-the correct code. The correct code is returned by (*testing.M).Run, so
-the usual way of implementing TestMain is to end it with
-os.Exit(m.Run()).`,
- Since: "2017.1",
- },
-
- "SA3001": &lint.Documentation{
- Title: `Assigning to b.N in benchmarks distorts the results`,
- Text: `The testing package dynamically sets b.N to improve the reliability of
-benchmarks and uses it in computations to determine the duration of a
-single operation. Benchmark code must not alter b.N as this would
-falsify results.`,
- Since: "2017.1",
- },
-
- "SA4000": &lint.Documentation{
- Title: `Boolean expression has identical expressions on both sides`,
- Since: "2017.1",
- },
-
- "SA4001": &lint.Documentation{
- Title: `&*x gets simplified to x, it does not copy x`,
- Since: "2017.1",
- },
-
- "SA4002": &lint.Documentation{
- Title: `Comparing strings with known different sizes has predictable results`,
- Since: "2017.1",
- },
-
- "SA4003": &lint.Documentation{
- Title: `Comparing unsigned values against negative values is pointless`,
- Since: "2017.1",
- },
-
- "SA4004": &lint.Documentation{
- Title: `The loop exits unconditionally after one iteration`,
- Since: "2017.1",
- },
-
- "SA4005": &lint.Documentation{
- Title: `Field assignment that will never be observed. Did you mean to use a pointer receiver?`,
- Since: "2017.1",
- },
-
- "SA4006": &lint.Documentation{
- Title: `A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?`,
- Since: "2017.1",
- },
-
- "SA4008": &lint.Documentation{
- Title: `The variable in the loop condition never changes, are you incrementing the wrong variable?`,
- Since: "2017.1",
- },
-
- "SA4009": &lint.Documentation{
- Title: `A function argument is overwritten before its first use`,
- Since: "2017.1",
- },
-
- "SA4010": &lint.Documentation{
- Title: `The result of append will never be observed anywhere`,
- Since: "2017.1",
- },
-
- "SA4011": &lint.Documentation{
- Title: `Break statement with no effect. Did you mean to break out of an outer loop?`,
- Since: "2017.1",
- },
-
- "SA4012": &lint.Documentation{
- Title: `Comparing a value against NaN even though no value is equal to NaN`,
- Since: "2017.1",
- },
-
- "SA4013": &lint.Documentation{
- Title: `Negating a boolean twice (!!b) is the same as writing b. This is either redundant, or a typo.`,
- Since: "2017.1",
- },
-
- "SA4014": &lint.Documentation{
- Title: `An if/else if chain has repeated conditions and no side-effects; if the condition didn't match the first time, it won't match the second time, either`,
- Since: "2017.1",
- },
-
- "SA4015": &lint.Documentation{
- Title: `Calling functions like math.Ceil on floats converted from integers doesn't do anything useful`,
- Since: "2017.1",
- },
-
- "SA4016": &lint.Documentation{
- Title: `Certain bitwise operations, such as x ^ 0, do not do anything useful`,
- Since: "2017.1",
- },
-
- "SA4017": &lint.Documentation{
- Title: `A pure function's return value is discarded, making the call pointless`,
- Since: "2017.1",
- },
-
- "SA4018": &lint.Documentation{
- Title: `Self-assignment of variables`,
- Since: "2017.1",
- },
-
- "SA4019": &lint.Documentation{
- Title: `Multiple, identical build constraints in the same file`,
- Since: "2017.1",
- },
-
- "SA4020": &lint.Documentation{
- Title: `Unreachable case clause in a type switch`,
- Text: `In a type switch like the following
-
- type T struct{}
- func (T) Read(b []byte) (int, error) { return 0, nil }
-
- var v interface{} = T{}
-
- switch v.(type) {
- case io.Reader:
- // ...
- case T:
- // unreachable
- }
-
-the second case clause can never be reached because T implements
-io.Reader and case clauses are evaluated in source order.
-
-Another example:
-
- type T struct{}
- func (T) Read(b []byte) (int, error) { return 0, nil }
- func (T) Close() error { return nil }
-
- var v interface{} = T{}
-
- switch v.(type) {
- case io.Reader:
- // ...
- case io.ReadCloser:
- // unreachable
- }
-
-Even though T has a Close method and thus implements io.ReadCloser,
-io.Reader will always match first. The method set of io.Reader is a
-subset of io.ReadCloser. Thus it is impossible to match the second
-case without matching the first case.
-
-
-Structurally equivalent interfaces
-
-A special case of the previous example are structurally identical
-interfaces. Given these declarations
-
- type T error
- type V error
-
- func doSomething() error {
- err, ok := doAnotherThing()
- if ok {
- return T(err)
- }
-
- return U(err)
- }
-
-the following type switch will have an unreachable case clause:
-
- switch doSomething().(type) {
- case T:
- // ...
- case V:
- // unreachable
- }
-
-T will always match before V because they are structurally equivalent
-and therefore doSomething()'s return value implements both.`,
- Since: "2019.2",
- },
-
- "SA4021": &lint.Documentation{
- Title: `x = append(y) is equivalent to x = y`,
- Since: "2019.2",
- },
-
- "SA5000": &lint.Documentation{
- Title: `Assignment to nil map`,
- Since: "2017.1",
- },
-
- "SA5001": &lint.Documentation{
- Title: `Defering Close before checking for a possible error`,
- Since: "2017.1",
- },
-
- "SA5002": &lint.Documentation{
- Title: `The empty for loop (for {}) spins and can block the scheduler`,
- Since: "2017.1",
- },
-
- "SA5003": &lint.Documentation{
- Title: `Defers in infinite loops will never execute`,
- Text: `Defers are scoped to the surrounding function, not the surrounding
-block. In a function that never returns, i.e. one containing an
-infinite loop, defers will never execute.`,
- Since: "2017.1",
- },
-
- "SA5004": &lint.Documentation{
- Title: `for { select { ... with an empty default branch spins`,
- Since: "2017.1",
- },
-
- "SA5005": &lint.Documentation{
- Title: `The finalizer references the finalized object, preventing garbage collection`,
- Text: `A finalizer is a function associated with an object that runs when the
-garbage collector is ready to collect said object, that is when the
-object is no longer referenced by anything.
-
-If the finalizer references the object, however, it will always remain
-as the final reference to that object, preventing the garbage
-collector from collecting the object. The finalizer will never run,
-and the object will never be collected, leading to a memory leak. That
-is why the finalizer should instead use its first argument to operate
-on the object. That way, the number of references can temporarily go
-to zero before the object is being passed to the finalizer.`,
- Since: "2017.1",
- },
-
- "SA5006": &lint.Documentation{
- Title: `Slice index out of bounds`,
- Since: "2017.1",
- },
-
- "SA5007": &lint.Documentation{
- Title: `Infinite recursive call`,
- Text: `A function that calls itself recursively needs to have an exit
-condition. Otherwise it will recurse forever, until the system runs
-out of memory.
-
-This issue can be caused by simple bugs such as forgetting to add an
-exit condition. It can also happen "on purpose". Some languages have
-tail call optimization which makes certain infinite recursive calls
-safe to use. Go, however, does not implement TCO, and as such a loop
-should be used instead.`,
- Since: "2017.1",
- },
-
- "SA5008": &lint.Documentation{
- Title: `Invalid struct tag`,
- Since: "2019.2",
- },
-
- "SA5009": &lint.Documentation{
- Title: `Invalid Printf call`,
- Since: "2019.2",
- },
-
- "SA6000": &lint.Documentation{
- Title: `Using regexp.Match or related in a loop, should use regexp.Compile`,
- Since: "2017.1",
- },
-
- "SA6001": &lint.Documentation{
- Title: `Missing an optimization opportunity when indexing maps by byte slices`,
-
- Text: `Map keys must be comparable, which precludes the use of byte slices.
-This usually leads to using string keys and converting byte slices to
-strings.
-
-Normally, a conversion of a byte slice to a string needs to copy the data and
-causes allocations. The compiler, however, recognizes m[string(b)] and
-uses the data of b directly, without copying it, because it knows that
-the data can't change during the map lookup. This leads to the
-counter-intuitive situation that
-
- k := string(b)
- println(m[k])
- println(m[k])
-
-will be less efficient than
-
- println(m[string(b)])
- println(m[string(b)])
-
-because the first version needs to copy and allocate, while the second
-one does not.
-
-For some history on this optimization, check out commit
-f5f5a8b6209f84961687d993b93ea0d397f5d5bf in the Go repository.`,
- Since: "2017.1",
- },
-
- "SA6002": &lint.Documentation{
- Title: `Storing non-pointer values in sync.Pool allocates memory`,
- Text: `A sync.Pool is used to avoid unnecessary allocations and reduce the
-amount of work the garbage collector has to do.
-
-When passing a value that is not a pointer to a function that accepts
-an interface, the value needs to be placed on the heap, which means an
-additional allocation. Slices are a common thing to put in sync.Pools,
-and they're structs with 3 fields (length, capacity, and a pointer to
-an array). In order to avoid the extra allocation, one should store a
-pointer to the slice instead.
-
-See the comments on https://go-review.googlesource.com/c/go/+/24371
-that discuss this problem.`,
- Since: "2017.1",
- },
-
- "SA6003": &lint.Documentation{
- Title: `Converting a string to a slice of runes before ranging over it`,
- Text: `You may want to loop over the runes in a string. Instead of converting
-the string to a slice of runes and looping over that, you can loop
-over the string itself. That is,
-
- for _, r := range s {}
-
-and
-
- for _, r := range []rune(s) {}
-
-will yield the same values. The first version, however, will be faster
-and avoid unnecessary memory allocations.
-
-Do note that if you are interested in the indices, ranging over a
-string and over a slice of runes will yield different indices. The
-first one yields byte offsets, while the second one yields indices in
-the slice of runes.`,
- Since: "2017.1",
- },
-
- "SA6005": &lint.Documentation{
- Title: `Inefficient string comparison with strings.ToLower or strings.ToUpper`,
- Text: `Converting two strings to the same case and comparing them like so
-
- if strings.ToLower(s1) == strings.ToLower(s2) {
- ...
- }
-
-is significantly more expensive than comparing them with
-strings.EqualFold(s1, s2). This is due to memory usage as well as
-computational complexity.
-
-strings.ToLower will have to allocate memory for the new strings, as
-well as convert both strings fully, even if they differ on the very
-first byte. strings.EqualFold, on the other hand, compares the strings
-one character at a time. It doesn't need to create two intermediate
-strings and can return as soon as the first non-matching character has
-been found.
-
-For a more in-depth explanation of this issue, see
-https://blog.digitalocean.com/how-to-efficiently-compare-strings-in-go/`,
- Since: "2019.2",
- },
-
- "SA9001": &lint.Documentation{
- Title: `Defers in range loops may not run when you expect them to`,
- Since: "2017.1",
- },
-
- "SA9002": &lint.Documentation{
- Title: `Using a non-octal os.FileMode that looks like it was meant to be in octal.`,
- Since: "2017.1",
- },
-
- "SA9003": &lint.Documentation{
- Title: `Empty body in an if or else branch`,
- Since: "2017.1",
- },
-
- "SA9004": &lint.Documentation{
- Title: `Only the first constant has an explicit type`,
-
- Text: `In a constant declaration such as the following:
-
- const (
- First byte = 1
- Second = 2
- )
-
-the constant Second does not have the same type as the constant First.
-This construct shouldn't be confused with
-
- const (
- First byte = iota
- Second
- )
-
-where First and Second do indeed have the same type. The type is only
-passed on when no explicit value is assigned to the constant.
-
-When declaring enumerations with explicit values it is therefore
-important not to write
-
- const (
- EnumFirst EnumType = 1
- EnumSecond = 2
- EnumThird = 3
- )
-
-This discrepancy in types can cause various confusing behaviors and
-bugs.
-
-
-Wrong type in variable declarations
-
-The most obvious issue with such incorrect enumerations expresses
-itself as a compile error:
-
- package pkg
-
- const (
- EnumFirst uint8 = 1
- EnumSecond = 2
- )
-
- func fn(useFirst bool) {
- x := EnumSecond
- if useFirst {
- x = EnumFirst
- }
- }
-
-fails to compile with
-
- ./const.go:11:5: cannot use EnumFirst (type uint8) as type int in assignment
-
-
-Losing method sets
-
-A more subtle issue occurs with types that have methods and optional
-interfaces. Consider the following:
-
- package main
-
- import "fmt"
-
- type Enum int
-
- func (e Enum) String() string {
- return "an enum"
- }
-
- const (
- EnumFirst Enum = 1
- EnumSecond = 2
- )
-
- func main() {
- fmt.Println(EnumFirst)
- fmt.Println(EnumSecond)
- }
-
-This code will output
-
- an enum
- 2
-
-as EnumSecond has no explicit type, and thus defaults to int.`,
- Since: "2019.1",
- },
-
- "SA9005": &lint.Documentation{
- Title: `Trying to marshal a struct with no public fields nor custom marshaling`,
- Text: `The encoding/json and encoding/xml packages only operate on exported
-fields in structs, not unexported ones. It is usually an error to try
-to (un)marshal structs that only consist of unexported fields.
-
-This check will not flag calls involving types that define custom
-marshaling behavior, e.g. via MarshalJSON methods. It will also not
-flag empty structs.`,
- Since: "2019.2",
- },
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/knowledge.go b/vendor/honnef.co/go/tools/staticcheck/knowledge.go
deleted file mode 100644
index 4c12b866a..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/knowledge.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package staticcheck
-
-import (
- "reflect"
-
- "golang.org/x/tools/go/analysis"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/ssa"
- "honnef.co/go/tools/staticcheck/vrp"
-)
-
-var valueRangesAnalyzer = &analysis.Analyzer{
- Name: "vrp",
- Doc: "calculate value ranges of functions",
- Run: func(pass *analysis.Pass) (interface{}, error) {
- m := map[*ssa.Function]vrp.Ranges{}
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- vr := vrp.BuildGraph(ssafn).Solve()
- m[ssafn] = vr
- }
- return m, nil
- },
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- ResultType: reflect.TypeOf(map[*ssa.Function]vrp.Ranges{}),
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/lint.go b/vendor/honnef.co/go/tools/staticcheck/lint.go
deleted file mode 100644
index 1558cbf94..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/lint.go
+++ /dev/null
@@ -1,3360 +0,0 @@
-// Package staticcheck contains a linter for Go source code.
-package staticcheck // import "honnef.co/go/tools/staticcheck"
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- "go/types"
- htmltemplate "html/template"
- "net/http"
- "reflect"
- "regexp"
- "regexp/syntax"
- "sort"
- "strconv"
- "strings"
- texttemplate "text/template"
- "unicode"
-
- . "honnef.co/go/tools/arg"
- "honnef.co/go/tools/deprecated"
- "honnef.co/go/tools/facts"
- "honnef.co/go/tools/functions"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/internal/sharedcheck"
- "honnef.co/go/tools/lint"
- . "honnef.co/go/tools/lint/lintdsl"
- "honnef.co/go/tools/printf"
- "honnef.co/go/tools/ssa"
- "honnef.co/go/tools/ssautil"
- "honnef.co/go/tools/staticcheck/vrp"
-
- "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"
- "golang.org/x/tools/go/types/typeutil"
-)
-
-func validRegexp(call *Call) {
- arg := call.Args[0]
- err := ValidateRegexp(arg.Value)
- if err != nil {
- arg.Invalid(err.Error())
- }
-}
-
-type runeSlice []rune
-
-func (rs runeSlice) Len() int { return len(rs) }
-func (rs runeSlice) Less(i int, j int) bool { return rs[i] < rs[j] }
-func (rs runeSlice) Swap(i int, j int) { rs[i], rs[j] = rs[j], rs[i] }
-
-func utf8Cutset(call *Call) {
- arg := call.Args[1]
- if InvalidUTF8(arg.Value) {
- arg.Invalid(MsgInvalidUTF8)
- }
-}
-
-func uniqueCutset(call *Call) {
- arg := call.Args[1]
- if !UniqueStringCutset(arg.Value) {
- arg.Invalid(MsgNonUniqueCutset)
- }
-}
-
-func unmarshalPointer(name string, arg int) CallCheck {
- return func(call *Call) {
- if !Pointer(call.Args[arg].Value) {
- call.Args[arg].Invalid(fmt.Sprintf("%s expects to unmarshal into a pointer, but the provided value is not a pointer", name))
- }
- }
-}
-
-func pointlessIntMath(call *Call) {
- if ConvertedFromInt(call.Args[0].Value) {
- call.Invalid(fmt.Sprintf("calling %s on a converted integer is pointless", CallName(call.Instr.Common())))
- }
-}
-
-func checkValidHostPort(arg int) CallCheck {
- return func(call *Call) {
- if !ValidHostPort(call.Args[arg].Value) {
- call.Args[arg].Invalid(MsgInvalidHostPort)
- }
- }
-}
-
-var (
- checkRegexpRules = map[string]CallCheck{
- "regexp.MustCompile": validRegexp,
- "regexp.Compile": validRegexp,
- "regexp.Match": validRegexp,
- "regexp.MatchReader": validRegexp,
- "regexp.MatchString": validRegexp,
- }
-
- checkTimeParseRules = map[string]CallCheck{
- "time.Parse": func(call *Call) {
- arg := call.Args[Arg("time.Parse.layout")]
- err := ValidateTimeLayout(arg.Value)
- if err != nil {
- arg.Invalid(err.Error())
- }
- },
- }
-
- checkEncodingBinaryRules = map[string]CallCheck{
- "encoding/binary.Write": func(call *Call) {
- arg := call.Args[Arg("encoding/binary.Write.data")]
- if !CanBinaryMarshal(call.Pass, arg.Value) {
- arg.Invalid(fmt.Sprintf("value of type %s cannot be used with binary.Write", arg.Value.Value.Type()))
- }
- },
- }
-
- checkURLsRules = map[string]CallCheck{
- "net/url.Parse": func(call *Call) {
- arg := call.Args[Arg("net/url.Parse.rawurl")]
- err := ValidateURL(arg.Value)
- if err != nil {
- arg.Invalid(err.Error())
- }
- },
- }
-
- checkSyncPoolValueRules = map[string]CallCheck{
- "(*sync.Pool).Put": func(call *Call) {
- arg := call.Args[Arg("(*sync.Pool).Put.x")]
- typ := arg.Value.Value.Type()
- if !IsPointerLike(typ) {
- arg.Invalid("argument should be pointer-like to avoid allocations")
- }
- },
- }
-
- checkRegexpFindAllRules = map[string]CallCheck{
- "(*regexp.Regexp).FindAll": RepeatZeroTimes("a FindAll method", 1),
- "(*regexp.Regexp).FindAllIndex": RepeatZeroTimes("a FindAll method", 1),
- "(*regexp.Regexp).FindAllString": RepeatZeroTimes("a FindAll method", 1),
- "(*regexp.Regexp).FindAllStringIndex": RepeatZeroTimes("a FindAll method", 1),
- "(*regexp.Regexp).FindAllStringSubmatch": RepeatZeroTimes("a FindAll method", 1),
- "(*regexp.Regexp).FindAllStringSubmatchIndex": RepeatZeroTimes("a FindAll method", 1),
- "(*regexp.Regexp).FindAllSubmatch": RepeatZeroTimes("a FindAll method", 1),
- "(*regexp.Regexp).FindAllSubmatchIndex": RepeatZeroTimes("a FindAll method", 1),
- }
-
- checkUTF8CutsetRules = map[string]CallCheck{
- "strings.IndexAny": utf8Cutset,
- "strings.LastIndexAny": utf8Cutset,
- "strings.ContainsAny": utf8Cutset,
- "strings.Trim": utf8Cutset,
- "strings.TrimLeft": utf8Cutset,
- "strings.TrimRight": utf8Cutset,
- }
-
- checkUniqueCutsetRules = map[string]CallCheck{
- "strings.Trim": uniqueCutset,
- "strings.TrimLeft": uniqueCutset,
- "strings.TrimRight": uniqueCutset,
- }
-
- checkUnmarshalPointerRules = map[string]CallCheck{
- "encoding/xml.Unmarshal": unmarshalPointer("xml.Unmarshal", 1),
- "(*encoding/xml.Decoder).Decode": unmarshalPointer("Decode", 0),
- "(*encoding/xml.Decoder).DecodeElement": unmarshalPointer("DecodeElement", 0),
- "encoding/json.Unmarshal": unmarshalPointer("json.Unmarshal", 1),
- "(*encoding/json.Decoder).Decode": unmarshalPointer("Decode", 0),
- }
-
- checkUnbufferedSignalChanRules = map[string]CallCheck{
- "os/signal.Notify": func(call *Call) {
- arg := call.Args[Arg("os/signal.Notify.c")]
- if UnbufferedChannel(arg.Value) {
- arg.Invalid("the channel used with signal.Notify should be buffered")
- }
- },
- }
-
- checkMathIntRules = map[string]CallCheck{
- "math.Ceil": pointlessIntMath,
- "math.Floor": pointlessIntMath,
- "math.IsNaN": pointlessIntMath,
- "math.Trunc": pointlessIntMath,
- "math.IsInf": pointlessIntMath,
- }
-
- checkStringsReplaceZeroRules = map[string]CallCheck{
- "strings.Replace": RepeatZeroTimes("strings.Replace", 3),
- "bytes.Replace": RepeatZeroTimes("bytes.Replace", 3),
- }
-
- checkListenAddressRules = map[string]CallCheck{
- "net/http.ListenAndServe": checkValidHostPort(0),
- "net/http.ListenAndServeTLS": checkValidHostPort(0),
- }
-
- checkBytesEqualIPRules = map[string]CallCheck{
- "bytes.Equal": func(call *Call) {
- if ConvertedFrom(call.Args[Arg("bytes.Equal.a")].Value, "net.IP") &&
- ConvertedFrom(call.Args[Arg("bytes.Equal.b")].Value, "net.IP") {
- call.Invalid("use net.IP.Equal to compare net.IPs, not bytes.Equal")
- }
- },
- }
-
- checkRegexpMatchLoopRules = map[string]CallCheck{
- "regexp.Match": loopedRegexp("regexp.Match"),
- "regexp.MatchReader": loopedRegexp("regexp.MatchReader"),
- "regexp.MatchString": loopedRegexp("regexp.MatchString"),
- }
-
- checkNoopMarshal = map[string]CallCheck{
- // TODO(dh): should we really flag XML? Even an empty struct
- // produces a non-zero amount of data, namely its type name.
- // Let's see if we encounter any false positives.
- //
- // Also, should we flag gob?
- "encoding/json.Marshal": checkNoopMarshalImpl(Arg("json.Marshal.v"), "MarshalJSON", "MarshalText"),
- "encoding/xml.Marshal": checkNoopMarshalImpl(Arg("xml.Marshal.v"), "MarshalXML", "MarshalText"),
- "(*encoding/json.Encoder).Encode": checkNoopMarshalImpl(Arg("(*encoding/json.Encoder).Encode.v"), "MarshalJSON", "MarshalText"),
- "(*encoding/xml.Encoder).Encode": checkNoopMarshalImpl(Arg("(*encoding/xml.Encoder).Encode.v"), "MarshalXML", "MarshalText"),
-
- "encoding/json.Unmarshal": checkNoopMarshalImpl(Arg("json.Unmarshal.v"), "UnmarshalJSON", "UnmarshalText"),
- "encoding/xml.Unmarshal": checkNoopMarshalImpl(Arg("xml.Unmarshal.v"), "UnmarshalXML", "UnmarshalText"),
- "(*encoding/json.Decoder).Decode": checkNoopMarshalImpl(Arg("(*encoding/json.Decoder).Decode.v"), "UnmarshalJSON", "UnmarshalText"),
- "(*encoding/xml.Decoder).Decode": checkNoopMarshalImpl(Arg("(*encoding/xml.Decoder).Decode.v"), "UnmarshalXML", "UnmarshalText"),
- }
-
- checkUnsupportedMarshal = map[string]CallCheck{
- "encoding/json.Marshal": checkUnsupportedMarshalImpl(Arg("json.Marshal.v"), "json", "MarshalJSON", "MarshalText"),
- "encoding/xml.Marshal": checkUnsupportedMarshalImpl(Arg("xml.Marshal.v"), "xml", "MarshalXML", "MarshalText"),
- "(*encoding/json.Encoder).Encode": checkUnsupportedMarshalImpl(Arg("(*encoding/json.Encoder).Encode.v"), "json", "MarshalJSON", "MarshalText"),
- "(*encoding/xml.Encoder).Encode": checkUnsupportedMarshalImpl(Arg("(*encoding/xml.Encoder).Encode.v"), "xml", "MarshalXML", "MarshalText"),
- }
-
- checkAtomicAlignment = map[string]CallCheck{
- "sync/atomic.AddInt64": checkAtomicAlignmentImpl,
- "sync/atomic.AddUint64": checkAtomicAlignmentImpl,
- "sync/atomic.CompareAndSwapInt64": checkAtomicAlignmentImpl,
- "sync/atomic.CompareAndSwapUint64": checkAtomicAlignmentImpl,
- "sync/atomic.LoadInt64": checkAtomicAlignmentImpl,
- "sync/atomic.LoadUint64": checkAtomicAlignmentImpl,
- "sync/atomic.StoreInt64": checkAtomicAlignmentImpl,
- "sync/atomic.StoreUint64": checkAtomicAlignmentImpl,
- "sync/atomic.SwapInt64": checkAtomicAlignmentImpl,
- "sync/atomic.SwapUint64": checkAtomicAlignmentImpl,
- }
-
- // TODO(dh): detect printf wrappers
- checkPrintfRules = map[string]CallCheck{
- "fmt.Errorf": func(call *Call) { checkPrintfCall(call, 0, 1) },
- "fmt.Printf": func(call *Call) { checkPrintfCall(call, 0, 1) },
- "fmt.Sprintf": func(call *Call) { checkPrintfCall(call, 0, 1) },
- "fmt.Fprintf": func(call *Call) { checkPrintfCall(call, 1, 2) },
- }
-)
-
-func checkPrintfCall(call *Call, fIdx, vIdx int) {
- f := call.Args[fIdx]
- var args []ssa.Value
- switch v := call.Args[vIdx].Value.Value.(type) {
- case *ssa.Slice:
- var ok bool
- args, ok = ssautil.Vararg(v)
- if !ok {
- // We don't know what the actual arguments to the function are
- return
- }
- case *ssa.Const:
- // nil, i.e. no arguments
- default:
- // We don't know what the actual arguments to the function are
- return
- }
- checkPrintfCallImpl(call, f.Value.Value, args)
-}
-
-type verbFlag int
-
-const (
- isInt verbFlag = 1 << iota
- isBool
- isFP
- isString
- isPointer
- isPseudoPointer
- isSlice
- isAny
- noRecurse
-)
-
-var verbs = [...]verbFlag{
- 'b': isPseudoPointer | isInt | isFP,
- 'c': isInt,
- 'd': isPseudoPointer | isInt,
- 'e': isFP,
- 'E': isFP,
- 'f': isFP,
- 'F': isFP,
- 'g': isFP,
- 'G': isFP,
- 'o': isPseudoPointer | isInt,
- 'p': isSlice | isPointer | noRecurse,
- 'q': isInt | isString,
- 's': isString,
- 't': isBool,
- 'T': isAny,
- 'U': isInt,
- 'v': isAny,
- 'X': isPseudoPointer | isInt | isString,
- 'x': isPseudoPointer | isInt | isString,
-}
-
-func checkPrintfCallImpl(call *Call, f ssa.Value, args []ssa.Value) {
- var msCache *typeutil.MethodSetCache
- if f.Parent() != nil {
- msCache = &f.Parent().Prog.MethodSets
- }
-
- elem := func(T types.Type, verb rune) ([]types.Type, bool) {
- if verbs[verb]&noRecurse != 0 {
- return []types.Type{T}, false
- }
- switch T := T.(type) {
- case *types.Slice:
- if verbs[verb]&isSlice != 0 {
- return []types.Type{T}, false
- }
- if verbs[verb]&isString != 0 && IsType(T.Elem().Underlying(), "byte") {
- return []types.Type{T}, false
- }
- return []types.Type{T.Elem()}, true
- case *types.Map:
- key := T.Key()
- val := T.Elem()
- return []types.Type{key, val}, true
- case *types.Struct:
- out := make([]types.Type, 0, T.NumFields())
- for i := 0; i < T.NumFields(); i++ {
- out = append(out, T.Field(i).Type())
- }
- return out, true
- case *types.Array:
- return []types.Type{T.Elem()}, true
- default:
- return []types.Type{T}, false
- }
- }
- isInfo := func(T types.Type, info types.BasicInfo) bool {
- basic, ok := T.Underlying().(*types.Basic)
- return ok && basic.Info()&info != 0
- }
-
- isStringer := func(T types.Type, ms *types.MethodSet) bool {
- sel := ms.Lookup(nil, "String")
- if sel == nil {
- return false
- }
- fn, ok := sel.Obj().(*types.Func)
- if !ok {
- // should be unreachable
- return false
- }
- sig := fn.Type().(*types.Signature)
- if sig.Params().Len() != 0 {
- return false
- }
- if sig.Results().Len() != 1 {
- return false
- }
- if !IsType(sig.Results().At(0).Type(), "string") {
- return false
- }
- return true
- }
- isError := func(T types.Type, ms *types.MethodSet) bool {
- sel := ms.Lookup(nil, "Error")
- if sel == nil {
- return false
- }
- fn, ok := sel.Obj().(*types.Func)
- if !ok {
- // should be unreachable
- return false
- }
- sig := fn.Type().(*types.Signature)
- if sig.Params().Len() != 0 {
- return false
- }
- if sig.Results().Len() != 1 {
- return false
- }
- if !IsType(sig.Results().At(0).Type(), "string") {
- return false
- }
- return true
- }
-
- isFormatter := func(T types.Type, ms *types.MethodSet) bool {
- sel := ms.Lookup(nil, "Format")
- if sel == nil {
- return false
- }
- fn, ok := sel.Obj().(*types.Func)
- if !ok {
- // should be unreachable
- return false
- }
- sig := fn.Type().(*types.Signature)
- if sig.Params().Len() != 2 {
- return false
- }
- // TODO(dh): check the types of the arguments for more
- // precision
- if sig.Results().Len() != 0 {
- return false
- }
- return true
- }
-
- seen := map[types.Type]bool{}
- var checkType func(verb rune, T types.Type, top bool) bool
- checkType = func(verb rune, T types.Type, top bool) bool {
- if top {
- for k := range seen {
- delete(seen, k)
- }
- }
- if seen[T] {
- return true
- }
- seen[T] = true
- if int(verb) >= len(verbs) {
- // Unknown verb
- return true
- }
-
- flags := verbs[verb]
- if flags == 0 {
- // Unknown verb
- return true
- }
-
- ms := msCache.MethodSet(T)
- if isFormatter(T, ms) {
- // the value is responsible for formatting itself
- return true
- }
-
- if flags&isString != 0 && (isStringer(T, ms) || isError(T, ms)) {
- // Check for stringer early because we're about to dereference
- return true
- }
-
- T = T.Underlying()
- if flags&(isPointer|isPseudoPointer) == 0 && top {
- T = Dereference(T)
- }
- if flags&isPseudoPointer != 0 && top {
- t := Dereference(T)
- if _, ok := t.Underlying().(*types.Struct); ok {
- T = t
- }
- }
-
- if _, ok := T.(*types.Interface); ok {
- // We don't know what's in the interface
- return true
- }
-
- var info types.BasicInfo
- if flags&isInt != 0 {
- info |= types.IsInteger
- }
- if flags&isBool != 0 {
- info |= types.IsBoolean
- }
- if flags&isFP != 0 {
- info |= types.IsFloat | types.IsComplex
- }
- if flags&isString != 0 {
- info |= types.IsString
- }
-
- if info != 0 && isInfo(T, info) {
- return true
- }
-
- if flags&isString != 0 && (IsType(T, "[]byte") || isStringer(T, ms) || isError(T, ms)) {
- return true
- }
-
- if flags&isPointer != 0 && IsPointerLike(T) {
- return true
- }
- if flags&isPseudoPointer != 0 {
- switch U := T.Underlying().(type) {
- case *types.Pointer:
- if !top {
- return true
- }
-
- if _, ok := U.Elem().Underlying().(*types.Struct); !ok {
- return true
- }
- case *types.Chan, *types.Signature:
- return true
- }
- }
-
- if flags&isSlice != 0 {
- if _, ok := T.(*types.Slice); ok {
- return true
- }
- }
-
- if flags&isAny != 0 {
- return true
- }
-
- elems, ok := elem(T.Underlying(), verb)
- if !ok {
- return false
- }
- for _, elem := range elems {
- if !checkType(verb, elem, false) {
- return false
- }
- }
-
- return true
- }
-
- k, ok := f.(*ssa.Const)
- if !ok {
- return
- }
- actions, err := printf.Parse(constant.StringVal(k.Value))
- if err != nil {
- call.Invalid("couldn't parse format string")
- return
- }
-
- ptr := 1
- hasExplicit := false
-
- checkStar := func(verb printf.Verb, star printf.Argument) bool {
- if star, ok := star.(printf.Star); ok {
- idx := 0
- if star.Index == -1 {
- idx = ptr
- ptr++
- } else {
- hasExplicit = true
- idx = star.Index
- ptr = star.Index + 1
- }
- if idx == 0 {
- call.Invalid(fmt.Sprintf("Printf format %s reads invalid arg 0; indices are 1-based", verb.Raw))
- return false
- }
- if idx > len(args) {
- call.Invalid(
- fmt.Sprintf("Printf format %s reads arg #%d, but call has only %d args",
- verb.Raw, idx, len(args)))
- return false
- }
- if arg, ok := args[idx-1].(*ssa.MakeInterface); ok {
- if !isInfo(arg.X.Type(), types.IsInteger) {
- call.Invalid(fmt.Sprintf("Printf format %s reads non-int arg #%d as argument of *", verb.Raw, idx))
- }
- }
- }
- return true
- }
-
- // We only report one problem per format string. Making a
- // mistake with an index tends to invalidate all future
- // implicit indices.
- for _, action := range actions {
- verb, ok := action.(printf.Verb)
- if !ok {
- continue
- }
-
- if !checkStar(verb, verb.Width) || !checkStar(verb, verb.Precision) {
- return
- }
-
- off := ptr
- if verb.Value != -1 {
- hasExplicit = true
- off = verb.Value
- }
- if off > len(args) {
- call.Invalid(
- fmt.Sprintf("Printf format %s reads arg #%d, but call has only %d args",
- verb.Raw, off, len(args)))
- return
- } else if verb.Value == 0 && verb.Letter != '%' {
- call.Invalid(fmt.Sprintf("Printf format %s reads invalid arg 0; indices are 1-based", verb.Raw))
- return
- } else if off != 0 {
- arg, ok := args[off-1].(*ssa.MakeInterface)
- if ok {
- if !checkType(verb.Letter, arg.X.Type(), true) {
- call.Invalid(fmt.Sprintf("Printf format %s has arg #%d of wrong type %s",
- verb.Raw, ptr, args[ptr-1].(*ssa.MakeInterface).X.Type()))
- return
- }
- }
- }
-
- switch verb.Value {
- case -1:
- // Consume next argument
- ptr++
- case 0:
- // Don't consume any arguments
- default:
- ptr = verb.Value + 1
- }
- }
-
- if !hasExplicit && ptr <= len(args) {
- call.Invalid(fmt.Sprintf("Printf call needs %d args but has %d args", ptr-1, len(args)))
- }
-}
-
-func checkAtomicAlignmentImpl(call *Call) {
- sizes := call.Pass.TypesSizes
- if sizes.Sizeof(types.Typ[types.Uintptr]) != 4 {
- // Not running on a 32-bit platform
- return
- }
- v, ok := call.Args[0].Value.Value.(*ssa.FieldAddr)
- if !ok {
- // TODO(dh): also check indexing into arrays and slices
- return
- }
- T := v.X.Type().Underlying().(*types.Pointer).Elem().Underlying().(*types.Struct)
- fields := make([]*types.Var, 0, T.NumFields())
- for i := 0; i < T.NumFields() && i <= v.Field; i++ {
- fields = append(fields, T.Field(i))
- }
-
- off := sizes.Offsetsof(fields)[v.Field]
- if off%8 != 0 {
- msg := fmt.Sprintf("address of non 64-bit aligned field %s passed to %s",
- T.Field(v.Field).Name(),
- CallName(call.Instr.Common()))
- call.Invalid(msg)
- }
-}
-
-func checkNoopMarshalImpl(argN int, meths ...string) CallCheck {
- return func(call *Call) {
- if IsGenerated(call.Pass, call.Instr.Pos()) {
- return
- }
- arg := call.Args[argN]
- T := arg.Value.Value.Type()
- Ts, ok := Dereference(T).Underlying().(*types.Struct)
- if !ok {
- return
- }
- if Ts.NumFields() == 0 {
- return
- }
- fields := FlattenFields(Ts)
- for _, field := range fields {
- if field.Var.Exported() {
- return
- }
- }
- // OPT(dh): we could use a method set cache here
- ms := call.Instr.Parent().Prog.MethodSets.MethodSet(T)
- // TODO(dh): we're not checking the signature, which can cause false negatives.
- // This isn't a huge problem, however, since vet complains about incorrect signatures.
- for _, meth := range meths {
- if ms.Lookup(nil, meth) != nil {
- return
- }
- }
- arg.Invalid("struct doesn't have any exported fields, nor custom marshaling")
- }
-}
-
-func checkUnsupportedMarshalImpl(argN int, tag string, meths ...string) CallCheck {
- // TODO(dh): flag slices and maps of unsupported types
- return func(call *Call) {
- msCache := &call.Instr.Parent().Prog.MethodSets
-
- arg := call.Args[argN]
- T := arg.Value.Value.Type()
- Ts, ok := Dereference(T).Underlying().(*types.Struct)
- if !ok {
- return
- }
- ms := msCache.MethodSet(T)
- // TODO(dh): we're not checking the signature, which can cause false negatives.
- // This isn't a huge problem, however, since vet complains about incorrect signatures.
- for _, meth := range meths {
- if ms.Lookup(nil, meth) != nil {
- return
- }
- }
- fields := FlattenFields(Ts)
- for _, field := range fields {
- if !(field.Var.Exported()) {
- continue
- }
- if reflect.StructTag(field.Tag).Get(tag) == "-" {
- continue
- }
- ms := msCache.MethodSet(field.Var.Type())
- // TODO(dh): we're not checking the signature, which can cause false negatives.
- // This isn't a huge problem, however, since vet complains about incorrect signatures.
- for _, meth := range meths {
- if ms.Lookup(nil, meth) != nil {
- return
- }
- }
- switch field.Var.Type().Underlying().(type) {
- case *types.Chan, *types.Signature:
- arg.Invalid(fmt.Sprintf("trying to marshal chan or func value, field %s", fieldPath(T, field.Path)))
- }
- }
- }
-}
-
-func fieldPath(start types.Type, indices []int) string {
- p := start.String()
- for _, idx := range indices {
- field := Dereference(start).Underlying().(*types.Struct).Field(idx)
- start = field.Type()
- p += "." + field.Name()
- }
- return p
-}
-
-func isInLoop(b *ssa.BasicBlock) bool {
- sets := functions.FindLoops(b.Parent())
- for _, set := range sets {
- if set.Has(b) {
- return true
- }
- }
- return false
-}
-
-func CheckUntrappableSignal(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !IsCallToAnyAST(pass, call,
- "os/signal.Ignore", "os/signal.Notify", "os/signal.Reset") {
- return
- }
- for _, arg := range call.Args {
- if conv, ok := arg.(*ast.CallExpr); ok && isName(pass, conv.Fun, "os.Signal") {
- arg = conv.Args[0]
- }
-
- if isName(pass, arg, "os.Kill") || isName(pass, arg, "syscall.SIGKILL") {
- ReportNodef(pass, arg, "%s cannot be trapped (did you mean syscall.SIGTERM?)", Render(pass, arg))
- }
- if isName(pass, arg, "syscall.SIGSTOP") {
- ReportNodef(pass, arg, "%s signal cannot be trapped", Render(pass, arg))
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckTemplate(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- var kind string
- if IsCallToAST(pass, call, "(*text/template.Template).Parse") {
- kind = "text"
- } else if IsCallToAST(pass, call, "(*html/template.Template).Parse") {
- kind = "html"
- } else {
- return
- }
- sel := call.Fun.(*ast.SelectorExpr)
- if !IsCallToAST(pass, sel.X, "text/template.New") &&
- !IsCallToAST(pass, sel.X, "html/template.New") {
- // TODO(dh): this is a cheap workaround for templates with
- // different delims. A better solution with less false
- // negatives would use data flow analysis to see where the
- // template comes from and where it has been
- return
- }
- s, ok := ExprToString(pass, call.Args[Arg("(*text/template.Template).Parse.text")])
- if !ok {
- return
- }
- var err error
- switch kind {
- case "text":
- _, err = texttemplate.New("").Parse(s)
- case "html":
- _, err = htmltemplate.New("").Parse(s)
- }
- if err != nil {
- // TODO(dominikh): whitelist other parse errors, if any
- if strings.Contains(err.Error(), "unexpected") {
- ReportNodef(pass, call.Args[Arg("(*text/template.Template).Parse.text")], "%s", err)
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckTimeSleepConstant(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !IsCallToAST(pass, call, "time.Sleep") {
- return
- }
- lit, ok := call.Args[Arg("time.Sleep.d")].(*ast.BasicLit)
- if !ok {
- return
- }
- n, err := strconv.Atoi(lit.Value)
- if err != nil {
- return
- }
- if n == 0 || n > 120 {
- // time.Sleep(0) is a seldom used pattern in concurrency
- // tests. >120 might be intentional. 120 was chosen
- // because the user could've meant 2 minutes.
- return
- }
- recommendation := "time.Sleep(time.Nanosecond)"
- if n != 1 {
- recommendation = fmt.Sprintf("time.Sleep(%d * time.Nanosecond)", n)
- }
- ReportNodef(pass, call.Args[Arg("time.Sleep.d")],
- "sleeping for %d nanoseconds is probably a bug. Be explicit if it isn't: %s", n, recommendation)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckWaitgroupAdd(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- g := node.(*ast.GoStmt)
- fun, ok := g.Call.Fun.(*ast.FuncLit)
- if !ok {
- return
- }
- if len(fun.Body.List) == 0 {
- return
- }
- stmt, ok := fun.Body.List[0].(*ast.ExprStmt)
- if !ok {
- return
- }
- if IsCallToAST(pass, stmt.X, "(*sync.WaitGroup).Add") {
- ReportNodef(pass, stmt, "should call %s before starting the goroutine to avoid a race",
- Render(pass, stmt))
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.GoStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckInfiniteEmptyLoop(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- loop := node.(*ast.ForStmt)
- if len(loop.Body.List) != 0 || loop.Post != nil {
- return
- }
-
- if loop.Init != nil {
- // TODO(dh): this isn't strictly necessary, it just makes
- // the check easier.
- return
- }
- // An empty loop is bad news in two cases: 1) The loop has no
- // condition. In that case, it's just a loop that spins
- // forever and as fast as it can, keeping a core busy. 2) The
- // loop condition only consists of variable or field reads and
- // operators on those. The only way those could change their
- // value is with unsynchronised access, which constitutes a
- // data race.
- //
- // If the condition contains any function calls, its behaviour
- // is dynamic and the loop might terminate. Similarly for
- // channel receives.
-
- if loop.Cond != nil {
- if hasSideEffects(loop.Cond) {
- return
- }
- if ident, ok := loop.Cond.(*ast.Ident); ok {
- if k, ok := pass.TypesInfo.ObjectOf(ident).(*types.Const); ok {
- if !constant.BoolVal(k.Val()) {
- // don't flag `for false {}` loops. They're a debug aid.
- return
- }
- }
- }
- ReportNodef(pass, loop, "loop condition never changes or has a race condition")
- }
- ReportNodef(pass, loop, "this loop will spin, using 100%% CPU")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ForStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckDeferInInfiniteLoop(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- mightExit := false
- var defers []ast.Stmt
- loop := node.(*ast.ForStmt)
- if loop.Cond != nil {
- return
- }
- fn2 := func(node ast.Node) bool {
- switch stmt := node.(type) {
- case *ast.ReturnStmt:
- mightExit = true
- return false
- case *ast.BranchStmt:
- // TODO(dominikh): if this sees a break in a switch or
- // select, it doesn't check if it breaks the loop or
- // just the select/switch. This causes some false
- // negatives.
- if stmt.Tok == token.BREAK {
- mightExit = true
- return false
- }
- case *ast.DeferStmt:
- defers = append(defers, stmt)
- case *ast.FuncLit:
- // Don't look into function bodies
- return false
- }
- return true
- }
- ast.Inspect(loop.Body, fn2)
- if mightExit {
- return
- }
- for _, stmt := range defers {
- ReportNodef(pass, stmt, "defers in this infinite loop will never run")
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ForStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckDubiousDeferInChannelRangeLoop(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- loop := node.(*ast.RangeStmt)
- typ := pass.TypesInfo.TypeOf(loop.X)
- _, ok := typ.Underlying().(*types.Chan)
- if !ok {
- return
- }
- fn2 := func(node ast.Node) bool {
- switch stmt := node.(type) {
- case *ast.DeferStmt:
- ReportNodef(pass, stmt, "defers in this range loop won't run unless the channel gets closed")
- case *ast.FuncLit:
- // Don't look into function bodies
- return false
- }
- return true
- }
- ast.Inspect(loop.Body, fn2)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.RangeStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckTestMainExit(pass *analysis.Pass) (interface{}, error) {
- var (
- fnmain ast.Node
- callsExit bool
- callsRun bool
- arg types.Object
- )
- fn := func(node ast.Node, push bool) bool {
- if !push {
- if fnmain != nil && node == fnmain {
- if !callsExit && callsRun {
- ReportNodef(pass, fnmain, "TestMain should call os.Exit to set exit code")
- }
- fnmain = nil
- callsExit = false
- callsRun = false
- arg = nil
- }
- return true
- }
-
- switch node := node.(type) {
- case *ast.FuncDecl:
- if fnmain != nil {
- return true
- }
- if !isTestMain(pass, node) {
- return false
- }
- fnmain = node
- arg = pass.TypesInfo.ObjectOf(node.Type.Params.List[0].Names[0])
- return true
- case *ast.CallExpr:
- if IsCallToAST(pass, node, "os.Exit") {
- callsExit = true
- return false
- }
- sel, ok := node.Fun.(*ast.SelectorExpr)
- if !ok {
- return true
- }
- ident, ok := sel.X.(*ast.Ident)
- if !ok {
- return true
- }
- if arg != pass.TypesInfo.ObjectOf(ident) {
- return true
- }
- if sel.Sel.Name == "Run" {
- callsRun = true
- return false
- }
- return true
- default:
- // unreachable
- return true
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.FuncDecl)(nil), (*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func isTestMain(pass *analysis.Pass, decl *ast.FuncDecl) bool {
- if decl.Name.Name != "TestMain" {
- return false
- }
- if len(decl.Type.Params.List) != 1 {
- return false
- }
- arg := decl.Type.Params.List[0]
- if len(arg.Names) != 1 {
- return false
- }
- return IsOfType(pass, arg.Type, "*testing.M")
-}
-
-func CheckExec(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if !IsCallToAST(pass, call, "os/exec.Command") {
- return
- }
- val, ok := ExprToString(pass, call.Args[Arg("os/exec.Command.name")])
- if !ok {
- return
- }
- if !strings.Contains(val, " ") || strings.Contains(val, `\`) || strings.Contains(val, "/") {
- return
- }
- ReportNodef(pass, call.Args[Arg("os/exec.Command.name")],
- "first argument to exec.Command looks like a shell command, but a program name or path are expected")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckLoopEmptyDefault(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- loop := node.(*ast.ForStmt)
- if len(loop.Body.List) != 1 || loop.Cond != nil || loop.Init != nil {
- return
- }
- sel, ok := loop.Body.List[0].(*ast.SelectStmt)
- if !ok {
- return
- }
- for _, c := range sel.Body.List {
- if comm, ok := c.(*ast.CommClause); ok && comm.Comm == nil && len(comm.Body) == 0 {
- ReportNodef(pass, comm, "should not have an empty default case in a for+select loop. The loop will spin.")
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ForStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckLhsRhsIdentical(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- op := node.(*ast.BinaryExpr)
- switch op.Op {
- case token.EQL, token.NEQ:
- if basic, ok := pass.TypesInfo.TypeOf(op.X).Underlying().(*types.Basic); ok {
- if kind := basic.Kind(); kind == types.Float32 || kind == types.Float64 {
- // f == f and f != f might be used to check for NaN
- return
- }
- }
- case token.SUB, token.QUO, token.AND, token.REM, token.OR, token.XOR, token.AND_NOT,
- token.LAND, token.LOR, token.LSS, token.GTR, token.LEQ, token.GEQ:
- default:
- // For some ops, such as + and *, it can make sense to
- // have identical operands
- return
- }
-
- if Render(pass, op.X) != Render(pass, op.Y) {
- return
- }
- l1, ok1 := op.X.(*ast.BasicLit)
- l2, ok2 := op.Y.(*ast.BasicLit)
- if ok1 && ok2 && l1.Kind == token.INT && l2.Kind == l1.Kind && l1.Value == "0" && l2.Value == l1.Value && IsGenerated(pass, l1.Pos()) {
- // cgo generates the following function call:
- // _cgoCheckPointer(_cgoBase0, 0 == 0) – it uses 0 == 0
- // instead of true in case the user shadowed the
- // identifier. Ideally we'd restrict this exception to
- // calls of _cgoCheckPointer, but it's not worth the
- // hassle of keeping track of the stack.
- // are very rare to begin with, and we're mostly checking
- // for them to catch typos such as 1 == 1 where the user
- // meant to type i == 1. The odds of a false negative for
- // 0 == 0 are slim.
- return
- }
- ReportNodef(pass, op, "identical expressions on the left and right side of the '%s' operator", op.Op)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckScopedBreak(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- var body *ast.BlockStmt
- switch node := node.(type) {
- case *ast.ForStmt:
- body = node.Body
- case *ast.RangeStmt:
- body = node.Body
- default:
- panic(fmt.Sprintf("unreachable: %T", node))
- }
- for _, stmt := range body.List {
- var blocks [][]ast.Stmt
- switch stmt := stmt.(type) {
- case *ast.SwitchStmt:
- for _, c := range stmt.Body.List {
- blocks = append(blocks, c.(*ast.CaseClause).Body)
- }
- case *ast.SelectStmt:
- for _, c := range stmt.Body.List {
- blocks = append(blocks, c.(*ast.CommClause).Body)
- }
- default:
- continue
- }
-
- for _, body := range blocks {
- if len(body) == 0 {
- continue
- }
- lasts := []ast.Stmt{body[len(body)-1]}
- // TODO(dh): unfold all levels of nested block
- // statements, not just a single level if statement
- if ifs, ok := lasts[0].(*ast.IfStmt); ok {
- if len(ifs.Body.List) == 0 {
- continue
- }
- lasts[0] = ifs.Body.List[len(ifs.Body.List)-1]
-
- if block, ok := ifs.Else.(*ast.BlockStmt); ok {
- if len(block.List) != 0 {
- lasts = append(lasts, block.List[len(block.List)-1])
- }
- }
- }
- for _, last := range lasts {
- branch, ok := last.(*ast.BranchStmt)
- if !ok || branch.Tok != token.BREAK || branch.Label != nil {
- continue
- }
- ReportNodef(pass, branch, "ineffective break statement. Did you mean to break out of the outer loop?")
- }
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ForStmt)(nil), (*ast.RangeStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckUnsafePrintf(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- var arg int
- if IsCallToAnyAST(pass, call, "fmt.Printf", "fmt.Sprintf", "log.Printf") {
- arg = Arg("fmt.Printf.format")
- } else if IsCallToAnyAST(pass, call, "fmt.Fprintf") {
- arg = Arg("fmt.Fprintf.format")
- } else {
- return
- }
- if len(call.Args) != arg+1 {
- return
- }
- switch call.Args[arg].(type) {
- case *ast.CallExpr, *ast.Ident:
- default:
- return
- }
- ReportNodef(pass, call.Args[arg],
- "printf-style function with dynamic format string and no further arguments should use print-style function instead")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckEarlyDefer(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- block := node.(*ast.BlockStmt)
- if len(block.List) < 2 {
- return
- }
- for i, stmt := range block.List {
- if i == len(block.List)-1 {
- break
- }
- assign, ok := stmt.(*ast.AssignStmt)
- if !ok {
- continue
- }
- if len(assign.Rhs) != 1 {
- continue
- }
- if len(assign.Lhs) < 2 {
- continue
- }
- if lhs, ok := assign.Lhs[len(assign.Lhs)-1].(*ast.Ident); ok && lhs.Name == "_" {
- continue
- }
- call, ok := assign.Rhs[0].(*ast.CallExpr)
- if !ok {
- continue
- }
- sig, ok := pass.TypesInfo.TypeOf(call.Fun).(*types.Signature)
- if !ok {
- continue
- }
- if sig.Results().Len() < 2 {
- continue
- }
- last := sig.Results().At(sig.Results().Len() - 1)
- // FIXME(dh): check that it's error from universe, not
- // another type of the same name
- if last.Type().String() != "error" {
- continue
- }
- lhs, ok := assign.Lhs[0].(*ast.Ident)
- if !ok {
- continue
- }
- def, ok := block.List[i+1].(*ast.DeferStmt)
- if !ok {
- continue
- }
- sel, ok := def.Call.Fun.(*ast.SelectorExpr)
- if !ok {
- continue
- }
- ident, ok := selectorX(sel).(*ast.Ident)
- if !ok {
- continue
- }
- if ident.Obj != lhs.Obj {
- continue
- }
- if sel.Sel.Name != "Close" {
- continue
- }
- ReportNodef(pass, def, "should check returned error before deferring %s", Render(pass, def.Call))
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BlockStmt)(nil)}, fn)
- return nil, nil
-}
-
-func selectorX(sel *ast.SelectorExpr) ast.Node {
- switch x := sel.X.(type) {
- case *ast.SelectorExpr:
- return selectorX(x)
- default:
- return x
- }
-}
-
-func CheckEmptyCriticalSection(pass *analysis.Pass) (interface{}, error) {
- // Initially it might seem like this check would be easier to
- // implement in SSA. After all, we're only checking for two
- // consecutive method calls. In reality, however, there may be any
- // number of other instructions between the lock and unlock, while
- // still constituting an empty critical section. For example,
- // given `m.x().Lock(); m.x().Unlock()`, there will be a call to
- // x(). In the AST-based approach, this has a tiny potential for a
- // false positive (the second call to x might be doing work that
- // is protected by the mutex). In an SSA-based approach, however,
- // it would miss a lot of real bugs.
-
- mutexParams := func(s ast.Stmt) (x ast.Expr, funcName string, ok bool) {
- expr, ok := s.(*ast.ExprStmt)
- if !ok {
- return nil, "", false
- }
- call, ok := expr.X.(*ast.CallExpr)
- if !ok {
- return nil, "", false
- }
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return nil, "", false
- }
-
- fn, ok := pass.TypesInfo.ObjectOf(sel.Sel).(*types.Func)
- if !ok {
- return nil, "", false
- }
- sig := fn.Type().(*types.Signature)
- if sig.Params().Len() != 0 || sig.Results().Len() != 0 {
- return nil, "", false
- }
-
- return sel.X, fn.Name(), true
- }
-
- fn := func(node ast.Node) {
- block := node.(*ast.BlockStmt)
- if len(block.List) < 2 {
- return
- }
- for i := range block.List[:len(block.List)-1] {
- sel1, method1, ok1 := mutexParams(block.List[i])
- sel2, method2, ok2 := mutexParams(block.List[i+1])
-
- if !ok1 || !ok2 || Render(pass, sel1) != Render(pass, sel2) {
- continue
- }
- if (method1 == "Lock" && method2 == "Unlock") ||
- (method1 == "RLock" && method2 == "RUnlock") {
- ReportNodef(pass, block.List[i+1], "empty critical section")
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BlockStmt)(nil)}, fn)
- return nil, nil
-}
-
-// cgo produces code like fn(&*_Cvar_kSomeCallbacks) which we don't
-// want to flag.
-var cgoIdent = regexp.MustCompile(`^_C(func|var)_.+$`)
-
-func CheckIneffectiveCopy(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if unary, ok := node.(*ast.UnaryExpr); ok {
- if star, ok := unary.X.(*ast.StarExpr); ok && unary.Op == token.AND {
- ident, ok := star.X.(*ast.Ident)
- if !ok || !cgoIdent.MatchString(ident.Name) {
- ReportNodef(pass, unary, "&*x will be simplified to x. It will not copy x.")
- }
- }
- }
-
- if star, ok := node.(*ast.StarExpr); ok {
- if unary, ok := star.X.(*ast.UnaryExpr); ok && unary.Op == token.AND {
- ReportNodef(pass, star, "*&x will be simplified to x. It will not copy x.")
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.UnaryExpr)(nil), (*ast.StarExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckDiffSizeComparison(pass *analysis.Pass) (interface{}, error) {
- ranges := pass.ResultOf[valueRangesAnalyzer].(map[*ssa.Function]vrp.Ranges)
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, b := range ssafn.Blocks {
- for _, ins := range b.Instrs {
- binop, ok := ins.(*ssa.BinOp)
- if !ok {
- continue
- }
- if binop.Op != token.EQL && binop.Op != token.NEQ {
- continue
- }
- _, ok1 := binop.X.(*ssa.Slice)
- _, ok2 := binop.Y.(*ssa.Slice)
- if !ok1 && !ok2 {
- continue
- }
- r := ranges[ssafn]
- r1, ok1 := r.Get(binop.X).(vrp.StringInterval)
- r2, ok2 := r.Get(binop.Y).(vrp.StringInterval)
- if !ok1 || !ok2 {
- continue
- }
- if r1.Length.Intersection(r2.Length).Empty() {
- pass.Reportf(binop.Pos(), "comparing strings of different sizes for equality will always return false")
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckCanonicalHeaderKey(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node, push bool) bool {
- if !push {
- return false
- }
- assign, ok := node.(*ast.AssignStmt)
- if ok {
- // TODO(dh): This risks missing some Header reads, for
- // example in `h1["foo"] = h2["foo"]` – these edge
- // cases are probably rare enough to ignore for now.
- for _, expr := range assign.Lhs {
- op, ok := expr.(*ast.IndexExpr)
- if !ok {
- continue
- }
- if IsOfType(pass, op.X, "net/http.Header") {
- return false
- }
- }
- return true
- }
- op, ok := node.(*ast.IndexExpr)
- if !ok {
- return true
- }
- if !IsOfType(pass, op.X, "net/http.Header") {
- return true
- }
- s, ok := ExprToString(pass, op.Index)
- if !ok {
- return true
- }
- if s == http.CanonicalHeaderKey(s) {
- return true
- }
- ReportNodef(pass, op, "keys in http.Header are canonicalized, %q is not canonical; fix the constant or use http.CanonicalHeaderKey", s)
- return true
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes([]ast.Node{(*ast.AssignStmt)(nil), (*ast.IndexExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckBenchmarkN(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- assign := node.(*ast.AssignStmt)
- if len(assign.Lhs) != 1 || len(assign.Rhs) != 1 {
- return
- }
- sel, ok := assign.Lhs[0].(*ast.SelectorExpr)
- if !ok {
- return
- }
- if sel.Sel.Name != "N" {
- return
- }
- if !IsOfType(pass, sel.X, "*testing.B") {
- return
- }
- ReportNodef(pass, assign, "should not assign to %s", Render(pass, sel))
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.AssignStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckUnreadVariableValues(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- if IsExample(ssafn) {
- continue
- }
- node := ssafn.Syntax()
- if node == nil {
- continue
- }
- if gen, ok := Generator(pass, node.Pos()); ok && gen == facts.Goyacc {
- // Don't flag unused values in code generated by goyacc.
- // There may be hundreds of those due to the way the state
- // machine is constructed.
- continue
- }
-
- switchTags := map[ssa.Value]struct{}{}
- ast.Inspect(node, func(node ast.Node) bool {
- s, ok := node.(*ast.SwitchStmt)
- if !ok {
- return true
- }
- v, _ := ssafn.ValueForExpr(s.Tag)
- switchTags[v] = struct{}{}
- return true
- })
-
- hasUse := func(v ssa.Value) bool {
- if _, ok := switchTags[v]; ok {
- return true
- }
- refs := v.Referrers()
- if refs == nil {
- // TODO investigate why refs can be nil
- return true
- }
- return len(FilterDebug(*refs)) > 0
- }
-
- ast.Inspect(node, func(node ast.Node) bool {
- assign, ok := node.(*ast.AssignStmt)
- if !ok {
- return true
- }
- if len(assign.Lhs) > 1 && len(assign.Rhs) == 1 {
- // Either a function call with multiple return values,
- // or a comma-ok assignment
-
- val, _ := ssafn.ValueForExpr(assign.Rhs[0])
- if val == nil {
- return true
- }
- refs := val.Referrers()
- if refs == nil {
- return true
- }
- for _, ref := range *refs {
- ex, ok := ref.(*ssa.Extract)
- if !ok {
- continue
- }
- if !hasUse(ex) {
- lhs := assign.Lhs[ex.Index]
- if ident, ok := lhs.(*ast.Ident); !ok || ok && ident.Name == "_" {
- continue
- }
- ReportNodef(pass, lhs, "this value of %s is never used", lhs)
- }
- }
- return true
- }
- for i, lhs := range assign.Lhs {
- rhs := assign.Rhs[i]
- if ident, ok := lhs.(*ast.Ident); !ok || ok && ident.Name == "_" {
- continue
- }
- val, _ := ssafn.ValueForExpr(rhs)
- if val == nil {
- continue
- }
-
- if !hasUse(val) {
- ReportNodef(pass, lhs, "this value of %s is never used", lhs)
- }
- }
- return true
- })
- }
- return nil, nil
-}
-
-func CheckPredeterminedBooleanExprs(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- ssabinop, ok := ins.(*ssa.BinOp)
- if !ok {
- continue
- }
- switch ssabinop.Op {
- case token.GTR, token.LSS, token.EQL, token.NEQ, token.LEQ, token.GEQ:
- default:
- continue
- }
-
- xs, ok1 := consts(ssabinop.X, nil, nil)
- ys, ok2 := consts(ssabinop.Y, nil, nil)
- if !ok1 || !ok2 || len(xs) == 0 || len(ys) == 0 {
- continue
- }
-
- trues := 0
- for _, x := range xs {
- for _, y := range ys {
- if x.Value == nil {
- if y.Value == nil {
- trues++
- }
- continue
- }
- if constant.Compare(x.Value, ssabinop.Op, y.Value) {
- trues++
- }
- }
- }
- b := trues != 0
- if trues == 0 || trues == len(xs)*len(ys) {
- pass.Reportf(ssabinop.Pos(), "binary expression is always %t for all possible values (%s %s %s)",
- b, xs, ssabinop.Op, ys)
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckNilMaps(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- mu, ok := ins.(*ssa.MapUpdate)
- if !ok {
- continue
- }
- c, ok := mu.Map.(*ssa.Const)
- if !ok {
- continue
- }
- if c.Value != nil {
- continue
- }
- pass.Reportf(mu.Pos(), "assignment to nil map")
- }
- }
- }
- return nil, nil
-}
-
-func CheckExtremeComparison(pass *analysis.Pass) (interface{}, error) {
- isobj := func(expr ast.Expr, name string) bool {
- sel, ok := expr.(*ast.SelectorExpr)
- if !ok {
- return false
- }
- return IsObject(pass.TypesInfo.ObjectOf(sel.Sel), name)
- }
-
- fn := func(node ast.Node) {
- expr := node.(*ast.BinaryExpr)
- tx := pass.TypesInfo.TypeOf(expr.X)
- basic, ok := tx.Underlying().(*types.Basic)
- if !ok {
- return
- }
-
- var max string
- var min string
-
- switch basic.Kind() {
- case types.Uint8:
- max = "math.MaxUint8"
- case types.Uint16:
- max = "math.MaxUint16"
- case types.Uint32:
- max = "math.MaxUint32"
- case types.Uint64:
- max = "math.MaxUint64"
- case types.Uint:
- max = "math.MaxUint64"
-
- case types.Int8:
- min = "math.MinInt8"
- max = "math.MaxInt8"
- case types.Int16:
- min = "math.MinInt16"
- max = "math.MaxInt16"
- case types.Int32:
- min = "math.MinInt32"
- max = "math.MaxInt32"
- case types.Int64:
- min = "math.MinInt64"
- max = "math.MaxInt64"
- case types.Int:
- min = "math.MinInt64"
- max = "math.MaxInt64"
- }
-
- if (expr.Op == token.GTR || expr.Op == token.GEQ) && isobj(expr.Y, max) ||
- (expr.Op == token.LSS || expr.Op == token.LEQ) && isobj(expr.X, max) {
- ReportNodef(pass, expr, "no value of type %s is greater than %s", basic, max)
- }
- if expr.Op == token.LEQ && isobj(expr.Y, max) ||
- expr.Op == token.GEQ && isobj(expr.X, max) {
- ReportNodef(pass, expr, "every value of type %s is <= %s", basic, max)
- }
-
- if (basic.Info() & types.IsUnsigned) != 0 {
- if (expr.Op == token.LSS || expr.Op == token.LEQ) && IsIntLiteral(expr.Y, "0") ||
- (expr.Op == token.GTR || expr.Op == token.GEQ) && IsIntLiteral(expr.X, "0") {
- ReportNodef(pass, expr, "no value of type %s is less than 0", basic)
- }
- if expr.Op == token.GEQ && IsIntLiteral(expr.Y, "0") ||
- expr.Op == token.LEQ && IsIntLiteral(expr.X, "0") {
- ReportNodef(pass, expr, "every value of type %s is >= 0", basic)
- }
- } else {
- if (expr.Op == token.LSS || expr.Op == token.LEQ) && isobj(expr.Y, min) ||
- (expr.Op == token.GTR || expr.Op == token.GEQ) && isobj(expr.X, min) {
- ReportNodef(pass, expr, "no value of type %s is less than %s", basic, min)
- }
- if expr.Op == token.GEQ && isobj(expr.Y, min) ||
- expr.Op == token.LEQ && isobj(expr.X, min) {
- ReportNodef(pass, expr, "every value of type %s is >= %s", basic, min)
- }
- }
-
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func consts(val ssa.Value, out []*ssa.Const, visitedPhis map[string]bool) ([]*ssa.Const, bool) {
- if visitedPhis == nil {
- visitedPhis = map[string]bool{}
- }
- var ok bool
- switch val := val.(type) {
- case *ssa.Phi:
- if visitedPhis[val.Name()] {
- break
- }
- visitedPhis[val.Name()] = true
- vals := val.Operands(nil)
- for _, phival := range vals {
- out, ok = consts(*phival, out, visitedPhis)
- if !ok {
- return nil, false
- }
- }
- case *ssa.Const:
- out = append(out, val)
- case *ssa.Convert:
- out, ok = consts(val.X, out, visitedPhis)
- if !ok {
- return nil, false
- }
- default:
- return nil, false
- }
- if len(out) < 2 {
- return out, true
- }
- uniq := []*ssa.Const{out[0]}
- for _, val := range out[1:] {
- if val.Value == uniq[len(uniq)-1].Value {
- continue
- }
- uniq = append(uniq, val)
- }
- return uniq, true
-}
-
-func CheckLoopCondition(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- fn := func(node ast.Node) bool {
- loop, ok := node.(*ast.ForStmt)
- if !ok {
- return true
- }
- if loop.Init == nil || loop.Cond == nil || loop.Post == nil {
- return true
- }
- init, ok := loop.Init.(*ast.AssignStmt)
- if !ok || len(init.Lhs) != 1 || len(init.Rhs) != 1 {
- return true
- }
- cond, ok := loop.Cond.(*ast.BinaryExpr)
- if !ok {
- return true
- }
- x, ok := cond.X.(*ast.Ident)
- if !ok {
- return true
- }
- lhs, ok := init.Lhs[0].(*ast.Ident)
- if !ok {
- return true
- }
- if x.Obj != lhs.Obj {
- return true
- }
- if _, ok := loop.Post.(*ast.IncDecStmt); !ok {
- return true
- }
-
- v, isAddr := ssafn.ValueForExpr(cond.X)
- if v == nil || isAddr {
- return true
- }
- switch v := v.(type) {
- case *ssa.Phi:
- ops := v.Operands(nil)
- if len(ops) != 2 {
- return true
- }
- _, ok := (*ops[0]).(*ssa.Const)
- if !ok {
- return true
- }
- sigma, ok := (*ops[1]).(*ssa.Sigma)
- if !ok {
- return true
- }
- if sigma.X != v {
- return true
- }
- case *ssa.UnOp:
- return true
- }
- ReportNodef(pass, cond, "variable in loop condition never changes")
-
- return true
- }
- Inspect(ssafn.Syntax(), fn)
- }
- return nil, nil
-}
-
-func CheckArgOverwritten(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- fn := func(node ast.Node) bool {
- var typ *ast.FuncType
- var body *ast.BlockStmt
- switch fn := node.(type) {
- case *ast.FuncDecl:
- typ = fn.Type
- body = fn.Body
- case *ast.FuncLit:
- typ = fn.Type
- body = fn.Body
- }
- if body == nil {
- return true
- }
- if len(typ.Params.List) == 0 {
- return true
- }
- for _, field := range typ.Params.List {
- for _, arg := range field.Names {
- obj := pass.TypesInfo.ObjectOf(arg)
- var ssaobj *ssa.Parameter
- for _, param := range ssafn.Params {
- if param.Object() == obj {
- ssaobj = param
- break
- }
- }
- if ssaobj == nil {
- continue
- }
- refs := ssaobj.Referrers()
- if refs == nil {
- continue
- }
- if len(FilterDebug(*refs)) != 0 {
- continue
- }
-
- assigned := false
- ast.Inspect(body, func(node ast.Node) bool {
- assign, ok := node.(*ast.AssignStmt)
- if !ok {
- return true
- }
- for _, lhs := range assign.Lhs {
- ident, ok := lhs.(*ast.Ident)
- if !ok {
- continue
- }
- if pass.TypesInfo.ObjectOf(ident) == obj {
- assigned = true
- return false
- }
- }
- return true
- })
- if assigned {
- ReportNodef(pass, arg, "argument %s is overwritten before first use", arg)
- }
- }
- }
- return true
- }
- Inspect(ssafn.Syntax(), fn)
- }
- return nil, nil
-}
-
-func CheckIneffectiveLoop(pass *analysis.Pass) (interface{}, error) {
- // This check detects some, but not all unconditional loop exits.
- // We give up in the following cases:
- //
- // - a goto anywhere in the loop. The goto might skip over our
- // return, and we don't check that it doesn't.
- //
- // - any nested, unlabelled continue, even if it is in another
- // loop or closure.
- fn := func(node ast.Node) {
- var body *ast.BlockStmt
- switch fn := node.(type) {
- case *ast.FuncDecl:
- body = fn.Body
- case *ast.FuncLit:
- body = fn.Body
- default:
- panic(fmt.Sprintf("unreachable: %T", node))
- }
- if body == nil {
- return
- }
- labels := map[*ast.Object]ast.Stmt{}
- ast.Inspect(body, func(node ast.Node) bool {
- label, ok := node.(*ast.LabeledStmt)
- if !ok {
- return true
- }
- labels[label.Label.Obj] = label.Stmt
- return true
- })
-
- ast.Inspect(body, func(node ast.Node) bool {
- var loop ast.Node
- var body *ast.BlockStmt
- switch node := node.(type) {
- case *ast.ForStmt:
- body = node.Body
- loop = node
- case *ast.RangeStmt:
- typ := pass.TypesInfo.TypeOf(node.X)
- if _, ok := typ.Underlying().(*types.Map); ok {
- // looping once over a map is a valid pattern for
- // getting an arbitrary element.
- return true
- }
- body = node.Body
- loop = node
- default:
- return true
- }
- if len(body.List) < 2 {
- // avoid flagging the somewhat common pattern of using
- // a range loop to get the first element in a slice,
- // or the first rune in a string.
- return true
- }
- var unconditionalExit ast.Node
- hasBranching := false
- for _, stmt := range body.List {
- switch stmt := stmt.(type) {
- case *ast.BranchStmt:
- switch stmt.Tok {
- case token.BREAK:
- if stmt.Label == nil || labels[stmt.Label.Obj] == loop {
- unconditionalExit = stmt
- }
- case token.CONTINUE:
- if stmt.Label == nil || labels[stmt.Label.Obj] == loop {
- unconditionalExit = nil
- return false
- }
- }
- case *ast.ReturnStmt:
- unconditionalExit = stmt
- case *ast.IfStmt, *ast.ForStmt, *ast.RangeStmt, *ast.SwitchStmt, *ast.SelectStmt:
- hasBranching = true
- }
- }
- if unconditionalExit == nil || !hasBranching {
- return false
- }
- ast.Inspect(body, func(node ast.Node) bool {
- if branch, ok := node.(*ast.BranchStmt); ok {
-
- switch branch.Tok {
- case token.GOTO:
- unconditionalExit = nil
- return false
- case token.CONTINUE:
- if branch.Label != nil && labels[branch.Label.Obj] != loop {
- return true
- }
- unconditionalExit = nil
- return false
- }
- }
- return true
- })
- if unconditionalExit != nil {
- ReportNodef(pass, unconditionalExit, "the surrounding loop is unconditionally terminated")
- }
- return true
- })
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.FuncDecl)(nil), (*ast.FuncLit)(nil)}, fn)
- return nil, nil
-}
-
-func CheckNilContext(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- if len(call.Args) == 0 {
- return
- }
- if typ, ok := pass.TypesInfo.TypeOf(call.Args[0]).(*types.Basic); !ok || typ.Kind() != types.UntypedNil {
- return
- }
- sig, ok := pass.TypesInfo.TypeOf(call.Fun).(*types.Signature)
- if !ok {
- return
- }
- if sig.Params().Len() == 0 {
- return
- }
- if !IsType(sig.Params().At(0).Type(), "context.Context") {
- return
- }
- ReportNodef(pass, call.Args[0],
- "do not pass a nil Context, even if a function permits it; pass context.TODO if you are unsure about which Context to use")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckSeeker(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- sel, ok := call.Fun.(*ast.SelectorExpr)
- if !ok {
- return
- }
- if sel.Sel.Name != "Seek" {
- return
- }
- if len(call.Args) != 2 {
- return
- }
- arg0, ok := call.Args[Arg("(io.Seeker).Seek.offset")].(*ast.SelectorExpr)
- if !ok {
- return
- }
- switch arg0.Sel.Name {
- case "SeekStart", "SeekCurrent", "SeekEnd":
- default:
- return
- }
- pkg, ok := arg0.X.(*ast.Ident)
- if !ok {
- return
- }
- if pkg.Name != "io" {
- return
- }
- ReportNodef(pass, call, "the first argument of io.Seeker is the offset, but an io.Seek* constant is being used instead")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckIneffectiveAppend(pass *analysis.Pass) (interface{}, error) {
- isAppend := func(ins ssa.Value) bool {
- call, ok := ins.(*ssa.Call)
- if !ok {
- return false
- }
- if call.Call.IsInvoke() {
- return false
- }
- if builtin, ok := call.Call.Value.(*ssa.Builtin); !ok || builtin.Name() != "append" {
- return false
- }
- return true
- }
-
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- val, ok := ins.(ssa.Value)
- if !ok || !isAppend(val) {
- continue
- }
-
- isUsed := false
- visited := map[ssa.Instruction]bool{}
- var walkRefs func(refs []ssa.Instruction)
- walkRefs = func(refs []ssa.Instruction) {
- loop:
- for _, ref := range refs {
- if visited[ref] {
- continue
- }
- visited[ref] = true
- if _, ok := ref.(*ssa.DebugRef); ok {
- continue
- }
- switch ref := ref.(type) {
- case *ssa.Phi:
- walkRefs(*ref.Referrers())
- case *ssa.Sigma:
- walkRefs(*ref.Referrers())
- case ssa.Value:
- if !isAppend(ref) {
- isUsed = true
- } else {
- walkRefs(*ref.Referrers())
- }
- case ssa.Instruction:
- isUsed = true
- break loop
- }
- }
- }
- refs := val.Referrers()
- if refs == nil {
- continue
- }
- walkRefs(*refs)
- if !isUsed {
- pass.Reportf(ins.Pos(), "this result of append is never used, except maybe in other appends")
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckConcurrentTesting(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- gostmt, ok := ins.(*ssa.Go)
- if !ok {
- continue
- }
- var fn *ssa.Function
- switch val := gostmt.Call.Value.(type) {
- case *ssa.Function:
- fn = val
- case *ssa.MakeClosure:
- fn = val.Fn.(*ssa.Function)
- default:
- continue
- }
- if fn.Blocks == nil {
- continue
- }
- for _, block := range fn.Blocks {
- for _, ins := range block.Instrs {
- call, ok := ins.(*ssa.Call)
- if !ok {
- continue
- }
- if call.Call.IsInvoke() {
- continue
- }
- callee := call.Call.StaticCallee()
- if callee == nil {
- continue
- }
- recv := callee.Signature.Recv()
- if recv == nil {
- continue
- }
- if !IsType(recv.Type(), "*testing.common") {
- continue
- }
- fn, ok := call.Call.StaticCallee().Object().(*types.Func)
- if !ok {
- continue
- }
- name := fn.Name()
- switch name {
- case "FailNow", "Fatal", "Fatalf", "SkipNow", "Skip", "Skipf":
- default:
- continue
- }
- pass.Reportf(gostmt.Pos(), "the goroutine calls T.%s, which must be called in the same goroutine as the test", name)
- }
- }
- }
- }
- }
- return nil, nil
-}
-
-func eachCall(ssafn *ssa.Function, fn func(caller *ssa.Function, site ssa.CallInstruction, callee *ssa.Function)) {
- for _, b := range ssafn.Blocks {
- for _, instr := range b.Instrs {
- if site, ok := instr.(ssa.CallInstruction); ok {
- if g := site.Common().StaticCallee(); g != nil {
- fn(ssafn, site, g)
- }
- }
- }
- }
-}
-
-func CheckCyclicFinalizer(pass *analysis.Pass) (interface{}, error) {
- fn := func(caller *ssa.Function, site ssa.CallInstruction, callee *ssa.Function) {
- if callee.RelString(nil) != "runtime.SetFinalizer" {
- return
- }
- arg0 := site.Common().Args[Arg("runtime.SetFinalizer.obj")]
- if iface, ok := arg0.(*ssa.MakeInterface); ok {
- arg0 = iface.X
- }
- unop, ok := arg0.(*ssa.UnOp)
- if !ok {
- return
- }
- v, ok := unop.X.(*ssa.Alloc)
- if !ok {
- return
- }
- arg1 := site.Common().Args[Arg("runtime.SetFinalizer.finalizer")]
- if iface, ok := arg1.(*ssa.MakeInterface); ok {
- arg1 = iface.X
- }
- mc, ok := arg1.(*ssa.MakeClosure)
- if !ok {
- return
- }
- for _, b := range mc.Bindings {
- if b == v {
- pos := lint.DisplayPosition(pass.Fset, mc.Fn.Pos())
- pass.Reportf(site.Pos(), "the finalizer closes over the object, preventing the finalizer from ever running (at %s)", pos)
- }
- }
- }
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- eachCall(ssafn, fn)
- }
- return nil, nil
-}
-
-/*
-func CheckSliceOutOfBounds(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- ia, ok := ins.(*ssa.IndexAddr)
- if !ok {
- continue
- }
- if _, ok := ia.X.Type().Underlying().(*types.Slice); !ok {
- continue
- }
- sr, ok1 := c.funcDescs.Get(ssafn).Ranges[ia.X].(vrp.SliceInterval)
- idxr, ok2 := c.funcDescs.Get(ssafn).Ranges[ia.Index].(vrp.IntInterval)
- if !ok1 || !ok2 || !sr.IsKnown() || !idxr.IsKnown() || sr.Length.Empty() || idxr.Empty() {
- continue
- }
- if idxr.Lower.Cmp(sr.Length.Upper) >= 0 {
- ReportNodef(pass, ia, "index out of bounds")
- }
- }
- }
- }
- return nil, nil
-}
-*/
-
-func CheckDeferLock(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- instrs := FilterDebug(block.Instrs)
- if len(instrs) < 2 {
- continue
- }
- for i, ins := range instrs[:len(instrs)-1] {
- call, ok := ins.(*ssa.Call)
- if !ok {
- continue
- }
- if !IsCallTo(call.Common(), "(*sync.Mutex).Lock") && !IsCallTo(call.Common(), "(*sync.RWMutex).RLock") {
- continue
- }
- nins, ok := instrs[i+1].(*ssa.Defer)
- if !ok {
- continue
- }
- if !IsCallTo(&nins.Call, "(*sync.Mutex).Lock") && !IsCallTo(&nins.Call, "(*sync.RWMutex).RLock") {
- continue
- }
- if call.Common().Args[0] != nins.Call.Args[0] {
- continue
- }
- name := shortCallName(call.Common())
- alt := ""
- switch name {
- case "Lock":
- alt = "Unlock"
- case "RLock":
- alt = "RUnlock"
- }
- pass.Reportf(nins.Pos(), "deferring %s right after having locked already; did you mean to defer %s?", name, alt)
- }
- }
- }
- return nil, nil
-}
-
-func CheckNaNComparison(pass *analysis.Pass) (interface{}, error) {
- isNaN := func(v ssa.Value) bool {
- call, ok := v.(*ssa.Call)
- if !ok {
- return false
- }
- return IsCallTo(call.Common(), "math.NaN")
- }
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- ins, ok := ins.(*ssa.BinOp)
- if !ok {
- continue
- }
- if isNaN(ins.X) || isNaN(ins.Y) {
- pass.Reportf(ins.Pos(), "no value is equal to NaN, not even NaN itself")
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckInfiniteRecursion(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- eachCall(ssafn, func(caller *ssa.Function, site ssa.CallInstruction, callee *ssa.Function) {
- if callee != ssafn {
- return
- }
- if _, ok := site.(*ssa.Go); ok {
- // Recursively spawning goroutines doesn't consume
- // stack space infinitely, so don't flag it.
- return
- }
-
- block := site.Block()
- canReturn := false
- for _, b := range ssafn.Blocks {
- if block.Dominates(b) {
- continue
- }
- if len(b.Instrs) == 0 {
- continue
- }
- if _, ok := b.Instrs[len(b.Instrs)-1].(*ssa.Return); ok {
- canReturn = true
- break
- }
- }
- if canReturn {
- return
- }
- pass.Reportf(site.Pos(), "infinite recursive call")
- })
- }
- return nil, nil
-}
-
-func objectName(obj types.Object) string {
- if obj == nil {
- return ""
- }
- var name string
- if obj.Pkg() != nil && obj.Pkg().Scope().Lookup(obj.Name()) == obj {
- s := obj.Pkg().Path()
- if s != "" {
- name += s + "."
- }
- }
- name += obj.Name()
- return name
-}
-
-func isName(pass *analysis.Pass, expr ast.Expr, name string) bool {
- var obj types.Object
- switch expr := expr.(type) {
- case *ast.Ident:
- obj = pass.TypesInfo.ObjectOf(expr)
- case *ast.SelectorExpr:
- obj = pass.TypesInfo.ObjectOf(expr.Sel)
- }
- return objectName(obj) == name
-}
-
-func CheckLeakyTimeTick(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- if IsInMain(pass, ssafn) || IsInTest(pass, ssafn) {
- continue
- }
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- call, ok := ins.(*ssa.Call)
- if !ok || !IsCallTo(call.Common(), "time.Tick") {
- continue
- }
- if !functions.Terminates(call.Parent()) {
- continue
- }
- pass.Reportf(call.Pos(), "using time.Tick leaks the underlying ticker, consider using it only in endless functions, tests and the main package, and use time.NewTicker here")
- }
- }
- }
- return nil, nil
-}
-
-func CheckDoubleNegation(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- unary1 := node.(*ast.UnaryExpr)
- unary2, ok := unary1.X.(*ast.UnaryExpr)
- if !ok {
- return
- }
- if unary1.Op != token.NOT || unary2.Op != token.NOT {
- return
- }
- ReportNodef(pass, unary1, "negating a boolean twice has no effect; is this a typo?")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.UnaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func hasSideEffects(node ast.Node) bool {
- dynamic := false
- ast.Inspect(node, func(node ast.Node) bool {
- switch node := node.(type) {
- case *ast.CallExpr:
- dynamic = true
- return false
- case *ast.UnaryExpr:
- if node.Op == token.ARROW {
- dynamic = true
- return false
- }
- }
- return true
- })
- return dynamic
-}
-
-func CheckRepeatedIfElse(pass *analysis.Pass) (interface{}, error) {
- seen := map[ast.Node]bool{}
-
- var collectConds func(ifstmt *ast.IfStmt, inits []ast.Stmt, conds []ast.Expr) ([]ast.Stmt, []ast.Expr)
- collectConds = func(ifstmt *ast.IfStmt, inits []ast.Stmt, conds []ast.Expr) ([]ast.Stmt, []ast.Expr) {
- seen[ifstmt] = true
- if ifstmt.Init != nil {
- inits = append(inits, ifstmt.Init)
- }
- conds = append(conds, ifstmt.Cond)
- if elsestmt, ok := ifstmt.Else.(*ast.IfStmt); ok {
- return collectConds(elsestmt, inits, conds)
- }
- return inits, conds
- }
- fn := func(node ast.Node) {
- ifstmt := node.(*ast.IfStmt)
- if seen[ifstmt] {
- return
- }
- inits, conds := collectConds(ifstmt, nil, nil)
- if len(inits) > 0 {
- return
- }
- for _, cond := range conds {
- if hasSideEffects(cond) {
- return
- }
- }
- counts := map[string]int{}
- for _, cond := range conds {
- s := Render(pass, cond)
- counts[s]++
- if counts[s] == 2 {
- ReportNodef(pass, cond, "this condition occurs multiple times in this if/else if chain")
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.IfStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckSillyBitwiseOps(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- ins, ok := ins.(*ssa.BinOp)
- if !ok {
- continue
- }
-
- if c, ok := ins.Y.(*ssa.Const); !ok || c.Value == nil || c.Value.Kind() != constant.Int || c.Uint64() != 0 {
- continue
- }
- switch ins.Op {
- case token.AND, token.OR, token.XOR:
- default:
- // we do not flag shifts because too often, x<<0 is part
- // of a pattern, x<<0, x<<8, x<<16, ...
- continue
- }
- path, _ := astutil.PathEnclosingInterval(File(pass, ins), ins.Pos(), ins.Pos())
- if len(path) == 0 {
- continue
- }
- if node, ok := path[0].(*ast.BinaryExpr); !ok || !IsZero(node.Y) {
- continue
- }
-
- switch ins.Op {
- case token.AND:
- pass.Reportf(ins.Pos(), "x & 0 always equals 0")
- case token.OR, token.XOR:
- pass.Reportf(ins.Pos(), "x %s 0 always equals x", ins.Op)
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckNonOctalFileMode(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- call := node.(*ast.CallExpr)
- sig, ok := pass.TypesInfo.TypeOf(call.Fun).(*types.Signature)
- if !ok {
- return
- }
- n := sig.Params().Len()
- var args []int
- for i := 0; i < n; i++ {
- typ := sig.Params().At(i).Type()
- if IsType(typ, "os.FileMode") {
- args = append(args, i)
- }
- }
- for _, i := range args {
- lit, ok := call.Args[i].(*ast.BasicLit)
- if !ok {
- continue
- }
- if len(lit.Value) == 3 &&
- lit.Value[0] != '0' &&
- lit.Value[0] >= '0' && lit.Value[0] <= '7' &&
- lit.Value[1] >= '0' && lit.Value[1] <= '7' &&
- lit.Value[2] >= '0' && lit.Value[2] <= '7' {
-
- v, err := strconv.ParseInt(lit.Value, 10, 64)
- if err != nil {
- continue
- }
- ReportNodef(pass, call.Args[i], "file mode '%s' evaluates to %#o; did you mean '0%s'?", lit.Value, v, lit.Value)
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckPureFunctions(pass *analysis.Pass) (interface{}, error) {
- pure := pass.ResultOf[facts.Purity].(facts.PurityResult)
-
-fnLoop:
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- if IsInTest(pass, ssafn) {
- params := ssafn.Signature.Params()
- for i := 0; i < params.Len(); i++ {
- param := params.At(i)
- if IsType(param.Type(), "*testing.B") {
- // Ignore discarded pure functions in code related
- // to benchmarks. Instead of matching BenchmarkFoo
- // functions, we match any function accepting a
- // *testing.B. Benchmarks sometimes call generic
- // functions for doing the actual work, and
- // checking for the parameter is a lot easier and
- // faster than analyzing call trees.
- continue fnLoop
- }
- }
- }
-
- for _, b := range ssafn.Blocks {
- for _, ins := range b.Instrs {
- ins, ok := ins.(*ssa.Call)
- if !ok {
- continue
- }
- refs := ins.Referrers()
- if refs == nil || len(FilterDebug(*refs)) > 0 {
- continue
- }
- callee := ins.Common().StaticCallee()
- if callee == nil {
- continue
- }
- if callee.Object() == nil {
- // TODO(dh): support anonymous functions
- continue
- }
- if _, ok := pure[callee.Object().(*types.Func)]; ok {
- pass.Reportf(ins.Pos(), "%s is a pure function but its return value is ignored", callee.Name())
- continue
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckDeprecated(pass *analysis.Pass) (interface{}, error) {
- deprs := pass.ResultOf[facts.Deprecated].(facts.DeprecatedResult)
-
- // Selectors can appear outside of function literals, e.g. when
- // declaring package level variables.
-
- var tfn types.Object
- stack := 0
- fn := func(node ast.Node, push bool) bool {
- if !push {
- stack--
- return false
- }
- stack++
- if stack == 1 {
- tfn = nil
- }
- if fn, ok := node.(*ast.FuncDecl); ok {
- tfn = pass.TypesInfo.ObjectOf(fn.Name)
- }
- sel, ok := node.(*ast.SelectorExpr)
- if !ok {
- return true
- }
-
- obj := pass.TypesInfo.ObjectOf(sel.Sel)
- if obj.Pkg() == nil {
- return true
- }
- if pass.Pkg == obj.Pkg() || obj.Pkg().Path()+"_test" == pass.Pkg.Path() {
- // Don't flag stuff in our own package
- return true
- }
- if depr, ok := deprs.Objects[obj]; ok {
- // Look for the first available alternative, not the first
- // version something was deprecated in. If a function was
- // deprecated in Go 1.6, an alternative has been available
- // already in 1.0, and we're targeting 1.2, it still
- // makes sense to use the alternative from 1.0, to be
- // future-proof.
- minVersion := deprecated.Stdlib[SelectorName(pass, sel)].AlternativeAvailableSince
- if !IsGoVersion(pass, minVersion) {
- return true
- }
-
- if tfn != nil {
- if _, ok := deprs.Objects[tfn]; ok {
- // functions that are deprecated may use deprecated
- // symbols
- return true
- }
- }
- ReportNodef(pass, sel, "%s is deprecated: %s", Render(pass, sel), depr.Msg)
- return true
- }
- return true
- }
-
- imps := map[string]*types.Package{}
- for _, imp := range pass.Pkg.Imports() {
- imps[imp.Path()] = imp
- }
- fn2 := func(node ast.Node) {
- spec := node.(*ast.ImportSpec)
- p := spec.Path.Value
- path := p[1 : len(p)-1]
- imp := imps[path]
- if depr, ok := deprs.Packages[imp]; ok {
- ReportNodef(pass, spec, "Package %s is deprecated: %s", path, depr.Msg)
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Nodes(nil, fn)
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.ImportSpec)(nil)}, fn2)
- return nil, nil
-}
-
-func callChecker(rules map[string]CallCheck) func(pass *analysis.Pass) (interface{}, error) {
- return func(pass *analysis.Pass) (interface{}, error) {
- return checkCalls(pass, rules)
- }
-}
-
-func checkCalls(pass *analysis.Pass, rules map[string]CallCheck) (interface{}, error) {
- ranges := pass.ResultOf[valueRangesAnalyzer].(map[*ssa.Function]vrp.Ranges)
- fn := func(caller *ssa.Function, site ssa.CallInstruction, callee *ssa.Function) {
- obj, ok := callee.Object().(*types.Func)
- if !ok {
- return
- }
-
- r, ok := rules[lint.FuncName(obj)]
- if !ok {
- return
- }
- var args []*Argument
- ssaargs := site.Common().Args
- if callee.Signature.Recv() != nil {
- ssaargs = ssaargs[1:]
- }
- for _, arg := range ssaargs {
- if iarg, ok := arg.(*ssa.MakeInterface); ok {
- arg = iarg.X
- }
- vr := ranges[site.Parent()][arg]
- args = append(args, &Argument{Value: Value{arg, vr}})
- }
- call := &Call{
- Pass: pass,
- Instr: site,
- Args: args,
- Parent: site.Parent(),
- }
- r(call)
- for idx, arg := range call.Args {
- _ = idx
- for _, e := range arg.invalids {
- // path, _ := astutil.PathEnclosingInterval(f.File, edge.Site.Pos(), edge.Site.Pos())
- // if len(path) < 2 {
- // continue
- // }
- // astcall, ok := path[0].(*ast.CallExpr)
- // if !ok {
- // continue
- // }
- // pass.Reportf(astcall.Args[idx], "%s", e)
-
- pass.Reportf(site.Pos(), "%s", e)
- }
- }
- for _, e := range call.invalids {
- pass.Reportf(call.Instr.Common().Pos(), "%s", e)
- }
- }
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- eachCall(ssafn, fn)
- }
- return nil, nil
-}
-
-func shortCallName(call *ssa.CallCommon) string {
- if call.IsInvoke() {
- return ""
- }
- switch v := call.Value.(type) {
- case *ssa.Function:
- fn, ok := v.Object().(*types.Func)
- if !ok {
- return ""
- }
- return fn.Name()
- case *ssa.Builtin:
- return v.Name()
- }
- return ""
-}
-
-func CheckWriterBufferModified(pass *analysis.Pass) (interface{}, error) {
- // TODO(dh): this might be a good candidate for taint analysis.
- // Taint the argument as MUST_NOT_MODIFY, then propagate that
- // through functions like bytes.Split
-
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- sig := ssafn.Signature
- if ssafn.Name() != "Write" || sig.Recv() == nil || sig.Params().Len() != 1 || sig.Results().Len() != 2 {
- continue
- }
- tArg, ok := sig.Params().At(0).Type().(*types.Slice)
- if !ok {
- continue
- }
- if basic, ok := tArg.Elem().(*types.Basic); !ok || basic.Kind() != types.Byte {
- continue
- }
- if basic, ok := sig.Results().At(0).Type().(*types.Basic); !ok || basic.Kind() != types.Int {
- continue
- }
- if named, ok := sig.Results().At(1).Type().(*types.Named); !ok || !IsType(named, "error") {
- continue
- }
-
- for _, block := range ssafn.Blocks {
- for _, ins := range block.Instrs {
- switch ins := ins.(type) {
- case *ssa.Store:
- addr, ok := ins.Addr.(*ssa.IndexAddr)
- if !ok {
- continue
- }
- if addr.X != ssafn.Params[1] {
- continue
- }
- pass.Reportf(ins.Pos(), "io.Writer.Write must not modify the provided buffer, not even temporarily")
- case *ssa.Call:
- if !IsCallTo(ins.Common(), "append") {
- continue
- }
- if ins.Common().Args[0] != ssafn.Params[1] {
- continue
- }
- pass.Reportf(ins.Pos(), "io.Writer.Write must not modify the provided buffer, not even temporarily")
- }
- }
- }
- }
- return nil, nil
-}
-
-func loopedRegexp(name string) CallCheck {
- return func(call *Call) {
- if len(extractConsts(call.Args[0].Value.Value)) == 0 {
- return
- }
- if !isInLoop(call.Instr.Block()) {
- return
- }
- call.Invalid(fmt.Sprintf("calling %s in a loop has poor performance, consider using regexp.Compile", name))
- }
-}
-
-func CheckEmptyBranch(pass *analysis.Pass) (interface{}, error) {
- for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- if ssafn.Syntax() == nil {
- continue
- }
- if IsExample(ssafn) {
- continue
- }
- fn := func(node ast.Node) bool {
- ifstmt, ok := node.(*ast.IfStmt)
- if !ok {
- return true
- }
- if ifstmt.Else != nil {
- b, ok := ifstmt.Else.(*ast.BlockStmt)
- if !ok || len(b.List) != 0 {
- return true
- }
- ReportfFG(pass, ifstmt.Else.Pos(), "empty branch")
- }
- if len(ifstmt.Body.List) != 0 {
- return true
- }
- ReportfFG(pass, ifstmt.Pos(), "empty branch")
- return true
- }
- Inspect(ssafn.Syntax(), fn)
- }
- return nil, nil
-}
-
-func CheckMapBytesKey(pass *analysis.Pass) (interface{}, error) {
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, b := range fn.Blocks {
- insLoop:
- for _, ins := range b.Instrs {
- // find []byte -> string conversions
- conv, ok := ins.(*ssa.Convert)
- if !ok || conv.Type() != types.Universe.Lookup("string").Type() {
- continue
- }
- if s, ok := conv.X.Type().(*types.Slice); !ok || s.Elem() != types.Universe.Lookup("byte").Type() {
- continue
- }
- refs := conv.Referrers()
- // need at least two (DebugRef) references: the
- // conversion and the *ast.Ident
- if refs == nil || len(*refs) < 2 {
- continue
- }
- ident := false
- // skip first reference, that's the conversion itself
- for _, ref := range (*refs)[1:] {
- switch ref := ref.(type) {
- case *ssa.DebugRef:
- if _, ok := ref.Expr.(*ast.Ident); !ok {
- // the string seems to be used somewhere
- // unexpected; the default branch should
- // catch this already, but be safe
- continue insLoop
- } else {
- ident = true
- }
- case *ssa.Lookup:
- default:
- // the string is used somewhere else than a
- // map lookup
- continue insLoop
- }
- }
-
- // the result of the conversion wasn't assigned to an
- // identifier
- if !ident {
- continue
- }
- pass.Reportf(conv.Pos(), "m[string(key)] would be more efficient than k := string(key); m[k]")
- }
- }
- }
- return nil, nil
-}
-
-func CheckRangeStringRunes(pass *analysis.Pass) (interface{}, error) {
- return sharedcheck.CheckRangeStringRunes(pass)
-}
-
-func CheckSelfAssignment(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- assign := node.(*ast.AssignStmt)
- if assign.Tok != token.ASSIGN || len(assign.Lhs) != len(assign.Rhs) {
- return
- }
- for i, stmt := range assign.Lhs {
- rlh := Render(pass, stmt)
- rrh := Render(pass, assign.Rhs[i])
- if rlh == rrh {
- ReportfFG(pass, assign.Pos(), "self-assignment of %s to %s", rrh, rlh)
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.AssignStmt)(nil)}, fn)
- return nil, nil
-}
-
-func buildTagsIdentical(s1, s2 []string) bool {
- if len(s1) != len(s2) {
- return false
- }
- s1s := make([]string, len(s1))
- copy(s1s, s1)
- sort.Strings(s1s)
- s2s := make([]string, len(s2))
- copy(s2s, s2)
- sort.Strings(s2s)
- for i, s := range s1s {
- if s != s2s[i] {
- return false
- }
- }
- return true
-}
-
-func CheckDuplicateBuildConstraints(pass *analysis.Pass) (interface{}, error) {
- for _, f := range pass.Files {
- constraints := buildTags(f)
- for i, constraint1 := range constraints {
- for j, constraint2 := range constraints {
- if i >= j {
- continue
- }
- if buildTagsIdentical(constraint1, constraint2) {
- ReportfFG(pass, f.Pos(), "identical build constraints %q and %q",
- strings.Join(constraint1, " "),
- strings.Join(constraint2, " "))
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckSillyRegexp(pass *analysis.Pass) (interface{}, error) {
- // We could use the rule checking engine for this, but the
- // arguments aren't really invalid.
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, b := range fn.Blocks {
- for _, ins := range b.Instrs {
- call, ok := ins.(*ssa.Call)
- if !ok {
- continue
- }
- switch CallName(call.Common()) {
- case "regexp.MustCompile", "regexp.Compile", "regexp.Match", "regexp.MatchReader", "regexp.MatchString":
- default:
- continue
- }
- c, ok := call.Common().Args[0].(*ssa.Const)
- if !ok {
- continue
- }
- s := constant.StringVal(c.Value)
- re, err := syntax.Parse(s, 0)
- if err != nil {
- continue
- }
- if re.Op != syntax.OpLiteral && re.Op != syntax.OpEmptyMatch {
- continue
- }
- pass.Reportf(call.Pos(), "regular expression does not contain any meta characters")
- }
- }
- }
- return nil, nil
-}
-
-func CheckMissingEnumTypesInDeclaration(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- decl := node.(*ast.GenDecl)
- if !decl.Lparen.IsValid() {
- return
- }
- if decl.Tok != token.CONST {
- return
- }
-
- groups := GroupSpecs(pass.Fset, decl.Specs)
- groupLoop:
- for _, group := range groups {
- if len(group) < 2 {
- continue
- }
- if group[0].(*ast.ValueSpec).Type == nil {
- // first constant doesn't have a type
- continue groupLoop
- }
- for i, spec := range group {
- spec := spec.(*ast.ValueSpec)
- if len(spec.Names) != 1 || len(spec.Values) != 1 {
- continue groupLoop
- }
- switch v := spec.Values[0].(type) {
- case *ast.BasicLit:
- case *ast.UnaryExpr:
- if _, ok := v.X.(*ast.BasicLit); !ok {
- continue groupLoop
- }
- default:
- // if it's not a literal it might be typed, such as
- // time.Microsecond = 1000 * Nanosecond
- continue groupLoop
- }
- if i == 0 {
- continue
- }
- if spec.Type != nil {
- continue groupLoop
- }
- }
- ReportNodef(pass, group[0], "only the first constant in this group has an explicit type")
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.GenDecl)(nil)}, fn)
- return nil, nil
-}
-
-func CheckTimerResetReturnValue(pass *analysis.Pass) (interface{}, error) {
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- for _, block := range fn.Blocks {
- for _, ins := range block.Instrs {
- call, ok := ins.(*ssa.Call)
- if !ok {
- continue
- }
- if !IsCallTo(call.Common(), "(*time.Timer).Reset") {
- continue
- }
- refs := call.Referrers()
- if refs == nil {
- continue
- }
- for _, ref := range FilterDebug(*refs) {
- ifstmt, ok := ref.(*ssa.If)
- if !ok {
- continue
- }
-
- found := false
- for _, succ := range ifstmt.Block().Succs {
- if len(succ.Preds) != 1 {
- // Merge point, not a branch in the
- // syntactical sense.
-
- // FIXME(dh): this is broken for if
- // statements a la "if x || y"
- continue
- }
- ssautil.Walk(succ, func(b *ssa.BasicBlock) bool {
- if !succ.Dominates(b) {
- // We've reached the end of the branch
- return false
- }
- for _, ins := range b.Instrs {
- // TODO(dh): we should check that
- // we're receiving from the channel of
- // a time.Timer to further reduce
- // false positives. Not a key
- // priority, considering the rarity of
- // Reset and the tiny likeliness of a
- // false positive
- if ins, ok := ins.(*ssa.UnOp); ok && ins.Op == token.ARROW && IsType(ins.X.Type(), "<-chan time.Time") {
- found = true
- return false
- }
- }
- return true
- })
- }
-
- if found {
- pass.Reportf(call.Pos(), "it is not possible to use Reset's return value correctly, as there is a race condition between draining the channel and the new timer expiring")
- }
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckToLowerToUpperComparison(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- binExpr := node.(*ast.BinaryExpr)
-
- var negative bool
- switch binExpr.Op {
- case token.EQL:
- negative = false
- case token.NEQ:
- negative = true
- default:
- return
- }
-
- const (
- lo = "strings.ToLower"
- up = "strings.ToUpper"
- )
-
- var call string
- if IsCallToAST(pass, binExpr.X, lo) && IsCallToAST(pass, binExpr.Y, lo) {
- call = lo
- } else if IsCallToAST(pass, binExpr.X, up) && IsCallToAST(pass, binExpr.Y, up) {
- call = up
- } else {
- return
- }
-
- bang := ""
- if negative {
- bang = "!"
- }
-
- ReportNodef(pass, binExpr, "should use %sstrings.EqualFold(a, b) instead of %s(a) %s %s(b)", bang, call, binExpr.Op, call)
- }
-
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckUnreachableTypeCases(pass *analysis.Pass) (interface{}, error) {
- // Check if T subsumes V in a type switch. T subsumes V if T is an interface and T's method set is a subset of V's method set.
- subsumes := func(T, V types.Type) bool {
- tIface, ok := T.Underlying().(*types.Interface)
- if !ok {
- return false
- }
-
- return types.Implements(V, tIface)
- }
-
- subsumesAny := func(Ts, Vs []types.Type) (types.Type, types.Type, bool) {
- for _, T := range Ts {
- for _, V := range Vs {
- if subsumes(T, V) {
- return T, V, true
- }
- }
- }
-
- return nil, nil, false
- }
-
- fn := func(node ast.Node) {
- tsStmt := node.(*ast.TypeSwitchStmt)
-
- type ccAndTypes struct {
- cc *ast.CaseClause
- types []types.Type
- }
-
- // All asserted types in the order of case clauses.
- ccs := make([]ccAndTypes, 0, len(tsStmt.Body.List))
- for _, stmt := range tsStmt.Body.List {
- cc, _ := stmt.(*ast.CaseClause)
-
- // Exclude the 'default' case.
- if len(cc.List) == 0 {
- continue
- }
-
- Ts := make([]types.Type, len(cc.List))
- for i, expr := range cc.List {
- Ts[i] = pass.TypesInfo.TypeOf(expr)
- }
-
- ccs = append(ccs, ccAndTypes{cc: cc, types: Ts})
- }
-
- if len(ccs) <= 1 {
- // Zero or one case clauses, nothing to check.
- return
- }
-
- // Check if case clauses following cc have types that are subsumed by cc.
- for i, cc := range ccs[:len(ccs)-1] {
- for _, next := range ccs[i+1:] {
- if T, V, yes := subsumesAny(cc.types, next.types); yes {
- ReportNodef(pass, next.cc, "unreachable case clause: %s will always match before %s", T.String(), V.String())
- }
- }
- }
- }
-
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.TypeSwitchStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckSingleArgAppend(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- if !IsCallToAST(pass, node, "append") {
- return
- }
- call := node.(*ast.CallExpr)
- if len(call.Args) != 1 {
- return
- }
- ReportfFG(pass, call.Pos(), "x = append(y) is equivalent to x = y")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.CallExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckStructTags(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- for _, field := range node.(*ast.StructType).Fields.List {
- if field.Tag == nil {
- continue
- }
- tags, err := parseStructTag(field.Tag.Value[1 : len(field.Tag.Value)-1])
- if err != nil {
- ReportNodef(pass, field.Tag, "unparseable struct tag: %s", err)
- continue
- }
- for k, v := range tags {
- if len(v) > 1 {
- ReportNodef(pass, field.Tag, "duplicate struct tag %q", k)
- continue
- }
-
- switch k {
- case "json":
- checkJSONTag(pass, field, v[0])
- case "xml":
- checkXMLTag(pass, field, v[0])
- }
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.StructType)(nil)}, fn)
- return nil, nil
-}
-
-func checkJSONTag(pass *analysis.Pass, field *ast.Field, tag string) {
- //lint:ignore SA9003 TODO(dh): should we flag empty tags?
- if len(tag) == 0 {
- }
- fields := strings.Split(tag, ",")
- for _, r := range fields[0] {
- if !unicode.IsLetter(r) && !unicode.IsDigit(r) && !strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", r) {
- ReportNodef(pass, field.Tag, "invalid JSON field name %q", fields[0])
- }
- }
- var co, cs, ci int
- for _, s := range fields[1:] {
- switch s {
- case "omitempty":
- co++
- case "":
- // allow stuff like "-,"
- case "string":
- cs++
- // only for string, floating point, integer and bool
- T := Dereference(pass.TypesInfo.TypeOf(field.Type).Underlying()).Underlying()
- basic, ok := T.(*types.Basic)
- if !ok || (basic.Info()&(types.IsBoolean|types.IsInteger|types.IsFloat|types.IsString)) == 0 {
- ReportNodef(pass, field.Tag, "the JSON string option only applies to fields of type string, floating point, integer or bool, or pointers to those")
- }
- case "inline":
- ci++
- default:
- ReportNodef(pass, field.Tag, "unknown JSON option %q", s)
- }
- }
- if co > 1 {
- ReportNodef(pass, field.Tag, `duplicate JSON option "omitempty"`)
- }
- if cs > 1 {
- ReportNodef(pass, field.Tag, `duplicate JSON option "string"`)
- }
- if ci > 1 {
- ReportNodef(pass, field.Tag, `duplicate JSON option "inline"`)
- }
-}
-
-func checkXMLTag(pass *analysis.Pass, field *ast.Field, tag string) {
- //lint:ignore SA9003 TODO(dh): should we flag empty tags?
- if len(tag) == 0 {
- }
- fields := strings.Split(tag, ",")
- counts := map[string]int{}
- var exclusives []string
- for _, s := range fields[1:] {
- switch s {
- case "attr", "chardata", "cdata", "innerxml", "comment":
- counts[s]++
- if counts[s] == 1 {
- exclusives = append(exclusives, s)
- }
- case "omitempty", "any":
- counts[s]++
- case "":
- default:
- ReportNodef(pass, field.Tag, "unknown XML option %q", s)
- }
- }
- for k, v := range counts {
- if v > 1 {
- ReportNodef(pass, field.Tag, "duplicate XML option %q", k)
- }
- }
- if len(exclusives) > 1 {
- ReportNodef(pass, field.Tag, "XML options %s are mutually exclusive", strings.Join(exclusives, " and "))
- }
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/rules.go b/vendor/honnef.co/go/tools/staticcheck/rules.go
deleted file mode 100644
index 0152cac1a..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/rules.go
+++ /dev/null
@@ -1,321 +0,0 @@
-package staticcheck
-
-import (
- "fmt"
- "go/constant"
- "go/types"
- "net"
- "net/url"
- "regexp"
- "sort"
- "strconv"
- "strings"
- "time"
- "unicode/utf8"
-
- "golang.org/x/tools/go/analysis"
- . "honnef.co/go/tools/lint/lintdsl"
- "honnef.co/go/tools/ssa"
- "honnef.co/go/tools/staticcheck/vrp"
-)
-
-const (
- MsgInvalidHostPort = "invalid port or service name in host:port pair"
- MsgInvalidUTF8 = "argument is not a valid UTF-8 encoded string"
- MsgNonUniqueCutset = "cutset contains duplicate characters"
-)
-
-type Call struct {
- Pass *analysis.Pass
- Instr ssa.CallInstruction
- Args []*Argument
-
- Parent *ssa.Function
-
- invalids []string
-}
-
-func (c *Call) Invalid(msg string) {
- c.invalids = append(c.invalids, msg)
-}
-
-type Argument struct {
- Value Value
- invalids []string
-}
-
-func (arg *Argument) Invalid(msg string) {
- arg.invalids = append(arg.invalids, msg)
-}
-
-type Value struct {
- Value ssa.Value
- Range vrp.Range
-}
-
-type CallCheck func(call *Call)
-
-func extractConsts(v ssa.Value) []*ssa.Const {
- switch v := v.(type) {
- case *ssa.Const:
- return []*ssa.Const{v}
- case *ssa.MakeInterface:
- return extractConsts(v.X)
- default:
- return nil
- }
-}
-
-func ValidateRegexp(v Value) error {
- for _, c := range extractConsts(v.Value) {
- if c.Value == nil {
- continue
- }
- if c.Value.Kind() != constant.String {
- continue
- }
- s := constant.StringVal(c.Value)
- if _, err := regexp.Compile(s); err != nil {
- return err
- }
- }
- return nil
-}
-
-func ValidateTimeLayout(v Value) error {
- for _, c := range extractConsts(v.Value) {
- if c.Value == nil {
- continue
- }
- if c.Value.Kind() != constant.String {
- continue
- }
- s := constant.StringVal(c.Value)
- s = strings.Replace(s, "_", " ", -1)
- s = strings.Replace(s, "Z", "-", -1)
- _, err := time.Parse(s, s)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-func ValidateURL(v Value) error {
- for _, c := range extractConsts(v.Value) {
- if c.Value == nil {
- continue
- }
- if c.Value.Kind() != constant.String {
- continue
- }
- s := constant.StringVal(c.Value)
- _, err := url.Parse(s)
- if err != nil {
- return fmt.Errorf("%q is not a valid URL: %s", s, err)
- }
- }
- return nil
-}
-
-func IntValue(v Value, z vrp.Z) bool {
- r, ok := v.Range.(vrp.IntInterval)
- if !ok || !r.IsKnown() {
- return false
- }
- if r.Lower != r.Upper {
- return false
- }
- if r.Lower.Cmp(z) == 0 {
- return true
- }
- return false
-}
-
-func InvalidUTF8(v Value) bool {
- for _, c := range extractConsts(v.Value) {
- if c.Value == nil {
- continue
- }
- if c.Value.Kind() != constant.String {
- continue
- }
- s := constant.StringVal(c.Value)
- if !utf8.ValidString(s) {
- return true
- }
- }
- return false
-}
-
-func UnbufferedChannel(v Value) bool {
- r, ok := v.Range.(vrp.ChannelInterval)
- if !ok || !r.IsKnown() {
- return false
- }
- if r.Size.Lower.Cmp(vrp.NewZ(0)) == 0 &&
- r.Size.Upper.Cmp(vrp.NewZ(0)) == 0 {
- return true
- }
- return false
-}
-
-func Pointer(v Value) bool {
- switch v.Value.Type().Underlying().(type) {
- case *types.Pointer, *types.Interface:
- return true
- }
- return false
-}
-
-func ConvertedFromInt(v Value) bool {
- conv, ok := v.Value.(*ssa.Convert)
- if !ok {
- return false
- }
- b, ok := conv.X.Type().Underlying().(*types.Basic)
- if !ok {
- return false
- }
- if (b.Info() & types.IsInteger) == 0 {
- return false
- }
- return true
-}
-
-func validEncodingBinaryType(pass *analysis.Pass, typ types.Type) bool {
- typ = typ.Underlying()
- switch typ := typ.(type) {
- case *types.Basic:
- switch typ.Kind() {
- case types.Uint8, types.Uint16, types.Uint32, types.Uint64,
- types.Int8, types.Int16, types.Int32, types.Int64,
- types.Float32, types.Float64, types.Complex64, types.Complex128, types.Invalid:
- return true
- case types.Bool:
- return IsGoVersion(pass, 8)
- }
- return false
- case *types.Struct:
- n := typ.NumFields()
- for i := 0; i < n; i++ {
- if !validEncodingBinaryType(pass, typ.Field(i).Type()) {
- return false
- }
- }
- return true
- case *types.Array:
- return validEncodingBinaryType(pass, typ.Elem())
- case *types.Interface:
- // we can't determine if it's a valid type or not
- return true
- }
- return false
-}
-
-func CanBinaryMarshal(pass *analysis.Pass, v Value) bool {
- typ := v.Value.Type().Underlying()
- if ttyp, ok := typ.(*types.Pointer); ok {
- typ = ttyp.Elem().Underlying()
- }
- if ttyp, ok := typ.(interface {
- Elem() types.Type
- }); ok {
- if _, ok := ttyp.(*types.Pointer); !ok {
- typ = ttyp.Elem()
- }
- }
-
- return validEncodingBinaryType(pass, typ)
-}
-
-func RepeatZeroTimes(name string, arg int) CallCheck {
- return func(call *Call) {
- arg := call.Args[arg]
- if IntValue(arg.Value, vrp.NewZ(0)) {
- arg.Invalid(fmt.Sprintf("calling %s with n == 0 will return no results, did you mean -1?", name))
- }
- }
-}
-
-func validateServiceName(s string) bool {
- if len(s) < 1 || len(s) > 15 {
- return false
- }
- if s[0] == '-' || s[len(s)-1] == '-' {
- return false
- }
- if strings.Contains(s, "--") {
- return false
- }
- hasLetter := false
- for _, r := range s {
- if (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') {
- hasLetter = true
- continue
- }
- if r >= '0' && r <= '9' {
- continue
- }
- return false
- }
- return hasLetter
-}
-
-func validatePort(s string) bool {
- n, err := strconv.ParseInt(s, 10, 64)
- if err != nil {
- return validateServiceName(s)
- }
- return n >= 0 && n <= 65535
-}
-
-func ValidHostPort(v Value) bool {
- for _, k := range extractConsts(v.Value) {
- if k.Value == nil {
- continue
- }
- if k.Value.Kind() != constant.String {
- continue
- }
- s := constant.StringVal(k.Value)
- _, port, err := net.SplitHostPort(s)
- if err != nil {
- return false
- }
- // TODO(dh): check hostname
- if !validatePort(port) {
- return false
- }
- }
- return true
-}
-
-// ConvertedFrom reports whether value v was converted from type typ.
-func ConvertedFrom(v Value, typ string) bool {
- change, ok := v.Value.(*ssa.ChangeType)
- return ok && IsType(change.X.Type(), typ)
-}
-
-func UniqueStringCutset(v Value) bool {
- for _, c := range extractConsts(v.Value) {
- if c.Value == nil {
- continue
- }
- if c.Value.Kind() != constant.String {
- continue
- }
- s := constant.StringVal(c.Value)
- rs := runeSlice(s)
- if len(rs) < 2 {
- continue
- }
- sort.Sort(rs)
- for i, r := range rs[1:] {
- if rs[i] == r {
- return false
- }
- }
- }
- return true
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/structtag.go b/vendor/honnef.co/go/tools/staticcheck/structtag.go
deleted file mode 100644
index 38830a22c..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/structtag.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Copyright 2019 Dominik Honnef. All rights reserved.
-
-package staticcheck
-
-import "strconv"
-
-func parseStructTag(tag string) (map[string][]string, error) {
- // FIXME(dh): detect missing closing quote
- out := map[string][]string{}
-
- for tag != "" {
- // Skip leading space.
- i := 0
- for i < len(tag) && tag[i] == ' ' {
- i++
- }
- tag = tag[i:]
- if tag == "" {
- break
- }
-
- // Scan to colon. A space, a quote or a control character is a syntax error.
- // Strictly speaking, control chars include the range [0x7f, 0x9f], not just
- // [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
- // as it is simpler to inspect the tag's bytes than the tag's runes.
- i = 0
- for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
- i++
- }
- if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
- break
- }
- name := string(tag[:i])
- tag = tag[i+1:]
-
- // Scan quoted string to find value.
- i = 1
- for i < len(tag) && tag[i] != '"' {
- if tag[i] == '\\' {
- i++
- }
- i++
- }
- if i >= len(tag) {
- break
- }
- qvalue := string(tag[:i+1])
- tag = tag[i+1:]
-
- value, err := strconv.Unquote(qvalue)
- if err != nil {
- return nil, err
- }
- out[name] = append(out[name], value)
- }
- return out, nil
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/vrp/channel.go b/vendor/honnef.co/go/tools/staticcheck/vrp/channel.go
deleted file mode 100644
index 0ef73787b..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/vrp/channel.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package vrp
-
-import (
- "fmt"
-
- "honnef.co/go/tools/ssa"
-)
-
-type ChannelInterval struct {
- Size IntInterval
-}
-
-func (c ChannelInterval) Union(other Range) Range {
- i, ok := other.(ChannelInterval)
- if !ok {
- i = ChannelInterval{EmptyIntInterval}
- }
- if c.Size.Empty() || !c.Size.IsKnown() {
- return i
- }
- if i.Size.Empty() || !i.Size.IsKnown() {
- return c
- }
- return ChannelInterval{
- Size: c.Size.Union(i.Size).(IntInterval),
- }
-}
-
-func (c ChannelInterval) String() string {
- return c.Size.String()
-}
-
-func (c ChannelInterval) IsKnown() bool {
- return c.Size.IsKnown()
-}
-
-type MakeChannelConstraint struct {
- aConstraint
- Buffer ssa.Value
-}
-type ChannelChangeTypeConstraint struct {
- aConstraint
- X ssa.Value
-}
-
-func NewMakeChannelConstraint(buffer, y ssa.Value) Constraint {
- return &MakeChannelConstraint{NewConstraint(y), buffer}
-}
-func NewChannelChangeTypeConstraint(x, y ssa.Value) Constraint {
- return &ChannelChangeTypeConstraint{NewConstraint(y), x}
-}
-
-func (c *MakeChannelConstraint) Operands() []ssa.Value { return []ssa.Value{c.Buffer} }
-func (c *ChannelChangeTypeConstraint) Operands() []ssa.Value { return []ssa.Value{c.X} }
-
-func (c *MakeChannelConstraint) String() string {
- return fmt.Sprintf("%s = make(chan, %s)", c.Y().Name(), c.Buffer.Name())
-}
-func (c *ChannelChangeTypeConstraint) String() string {
- return fmt.Sprintf("%s = changetype(%s)", c.Y().Name(), c.X.Name())
-}
-
-func (c *MakeChannelConstraint) Eval(g *Graph) Range {
- i, ok := g.Range(c.Buffer).(IntInterval)
- if !ok {
- return ChannelInterval{NewIntInterval(NewZ(0), PInfinity)}
- }
- if i.Lower.Sign() == -1 {
- i.Lower = NewZ(0)
- }
- return ChannelInterval{i}
-}
-func (c *ChannelChangeTypeConstraint) Eval(g *Graph) Range { return g.Range(c.X) }
diff --git a/vendor/honnef.co/go/tools/staticcheck/vrp/int.go b/vendor/honnef.co/go/tools/staticcheck/vrp/int.go
deleted file mode 100644
index 926bb7af3..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/vrp/int.go
+++ /dev/null
@@ -1,476 +0,0 @@
-package vrp
-
-import (
- "fmt"
- "go/token"
- "go/types"
- "math/big"
-
- "honnef.co/go/tools/ssa"
-)
-
-type Zs []Z
-
-func (zs Zs) Len() int {
- return len(zs)
-}
-
-func (zs Zs) Less(i int, j int) bool {
- return zs[i].Cmp(zs[j]) == -1
-}
-
-func (zs Zs) Swap(i int, j int) {
- zs[i], zs[j] = zs[j], zs[i]
-}
-
-type Z struct {
- infinity int8
- integer *big.Int
-}
-
-func NewZ(n int64) Z {
- return NewBigZ(big.NewInt(n))
-}
-
-func NewBigZ(n *big.Int) Z {
- return Z{integer: n}
-}
-
-func (z1 Z) Infinite() bool {
- return z1.infinity != 0
-}
-
-func (z1 Z) Add(z2 Z) Z {
- if z2.Sign() == -1 {
- return z1.Sub(z2.Negate())
- }
- if z1 == NInfinity {
- return NInfinity
- }
- if z1 == PInfinity {
- return PInfinity
- }
- if z2 == PInfinity {
- return PInfinity
- }
-
- if !z1.Infinite() && !z2.Infinite() {
- n := &big.Int{}
- n.Add(z1.integer, z2.integer)
- return NewBigZ(n)
- }
-
- panic(fmt.Sprintf("%s + %s is not defined", z1, z2))
-}
-
-func (z1 Z) Sub(z2 Z) Z {
- if z2.Sign() == -1 {
- return z1.Add(z2.Negate())
- }
- if !z1.Infinite() && !z2.Infinite() {
- n := &big.Int{}
- n.Sub(z1.integer, z2.integer)
- return NewBigZ(n)
- }
-
- if z1 != PInfinity && z2 == PInfinity {
- return NInfinity
- }
- if z1.Infinite() && !z2.Infinite() {
- return Z{infinity: z1.infinity}
- }
- if z1 == PInfinity && z2 == PInfinity {
- return PInfinity
- }
- panic(fmt.Sprintf("%s - %s is not defined", z1, z2))
-}
-
-func (z1 Z) Mul(z2 Z) Z {
- if (z1.integer != nil && z1.integer.Sign() == 0) ||
- (z2.integer != nil && z2.integer.Sign() == 0) {
- return NewBigZ(&big.Int{})
- }
-
- if z1.infinity != 0 || z2.infinity != 0 {
- return Z{infinity: int8(z1.Sign() * z2.Sign())}
- }
-
- n := &big.Int{}
- n.Mul(z1.integer, z2.integer)
- return NewBigZ(n)
-}
-
-func (z1 Z) Negate() Z {
- if z1.infinity == 1 {
- return NInfinity
- }
- if z1.infinity == -1 {
- return PInfinity
- }
- n := &big.Int{}
- n.Neg(z1.integer)
- return NewBigZ(n)
-}
-
-func (z1 Z) Sign() int {
- if z1.infinity != 0 {
- return int(z1.infinity)
- }
- return z1.integer.Sign()
-}
-
-func (z1 Z) String() string {
- if z1 == NInfinity {
- return "-∞"
- }
- if z1 == PInfinity {
- return "∞"
- }
- return fmt.Sprintf("%d", z1.integer)
-}
-
-func (z1 Z) Cmp(z2 Z) int {
- if z1.infinity == z2.infinity && z1.infinity != 0 {
- return 0
- }
- if z1 == PInfinity {
- return 1
- }
- if z1 == NInfinity {
- return -1
- }
- if z2 == NInfinity {
- return 1
- }
- if z2 == PInfinity {
- return -1
- }
- return z1.integer.Cmp(z2.integer)
-}
-
-func MaxZ(zs ...Z) Z {
- if len(zs) == 0 {
- panic("Max called with no arguments")
- }
- if len(zs) == 1 {
- return zs[0]
- }
- ret := zs[0]
- for _, z := range zs[1:] {
- if z.Cmp(ret) == 1 {
- ret = z
- }
- }
- return ret
-}
-
-func MinZ(zs ...Z) Z {
- if len(zs) == 0 {
- panic("Min called with no arguments")
- }
- if len(zs) == 1 {
- return zs[0]
- }
- ret := zs[0]
- for _, z := range zs[1:] {
- if z.Cmp(ret) == -1 {
- ret = z
- }
- }
- return ret
-}
-
-var NInfinity = Z{infinity: -1}
-var PInfinity = Z{infinity: 1}
-var EmptyIntInterval = IntInterval{true, PInfinity, NInfinity}
-
-func InfinityFor(v ssa.Value) IntInterval {
- if b, ok := v.Type().Underlying().(*types.Basic); ok {
- if (b.Info() & types.IsUnsigned) != 0 {
- return NewIntInterval(NewZ(0), PInfinity)
- }
- }
- return NewIntInterval(NInfinity, PInfinity)
-}
-
-type IntInterval struct {
- known bool
- Lower Z
- Upper Z
-}
-
-func NewIntInterval(l, u Z) IntInterval {
- if u.Cmp(l) == -1 {
- return EmptyIntInterval
- }
- return IntInterval{known: true, Lower: l, Upper: u}
-}
-
-func (i IntInterval) IsKnown() bool {
- return i.known
-}
-
-func (i IntInterval) Empty() bool {
- return i.Lower == PInfinity && i.Upper == NInfinity
-}
-
-func (i IntInterval) IsMaxRange() bool {
- return i.Lower == NInfinity && i.Upper == PInfinity
-}
-
-func (i1 IntInterval) Intersection(i2 IntInterval) IntInterval {
- if !i1.IsKnown() {
- return i2
- }
- if !i2.IsKnown() {
- return i1
- }
- if i1.Empty() || i2.Empty() {
- return EmptyIntInterval
- }
- i3 := NewIntInterval(MaxZ(i1.Lower, i2.Lower), MinZ(i1.Upper, i2.Upper))
- if i3.Lower.Cmp(i3.Upper) == 1 {
- return EmptyIntInterval
- }
- return i3
-}
-
-func (i1 IntInterval) Union(other Range) Range {
- i2, ok := other.(IntInterval)
- if !ok {
- i2 = EmptyIntInterval
- }
- if i1.Empty() || !i1.IsKnown() {
- return i2
- }
- if i2.Empty() || !i2.IsKnown() {
- return i1
- }
- return NewIntInterval(MinZ(i1.Lower, i2.Lower), MaxZ(i1.Upper, i2.Upper))
-}
-
-func (i1 IntInterval) Add(i2 IntInterval) IntInterval {
- if i1.Empty() || i2.Empty() {
- return EmptyIntInterval
- }
- l1, u1, l2, u2 := i1.Lower, i1.Upper, i2.Lower, i2.Upper
- return NewIntInterval(l1.Add(l2), u1.Add(u2))
-}
-
-func (i1 IntInterval) Sub(i2 IntInterval) IntInterval {
- if i1.Empty() || i2.Empty() {
- return EmptyIntInterval
- }
- l1, u1, l2, u2 := i1.Lower, i1.Upper, i2.Lower, i2.Upper
- return NewIntInterval(l1.Sub(u2), u1.Sub(l2))
-}
-
-func (i1 IntInterval) Mul(i2 IntInterval) IntInterval {
- if i1.Empty() || i2.Empty() {
- return EmptyIntInterval
- }
- x1, x2 := i1.Lower, i1.Upper
- y1, y2 := i2.Lower, i2.Upper
- return NewIntInterval(
- MinZ(x1.Mul(y1), x1.Mul(y2), x2.Mul(y1), x2.Mul(y2)),
- MaxZ(x1.Mul(y1), x1.Mul(y2), x2.Mul(y1), x2.Mul(y2)),
- )
-}
-
-func (i1 IntInterval) String() string {
- if !i1.IsKnown() {
- return "[⊥, ⊥]"
- }
- if i1.Empty() {
- return "{}"
- }
- return fmt.Sprintf("[%s, %s]", i1.Lower, i1.Upper)
-}
-
-type IntArithmeticConstraint struct {
- aConstraint
- A ssa.Value
- B ssa.Value
- Op token.Token
- Fn func(IntInterval, IntInterval) IntInterval
-}
-
-type IntAddConstraint struct{ *IntArithmeticConstraint }
-type IntSubConstraint struct{ *IntArithmeticConstraint }
-type IntMulConstraint struct{ *IntArithmeticConstraint }
-
-type IntConversionConstraint struct {
- aConstraint
- X ssa.Value
-}
-
-type IntIntersectionConstraint struct {
- aConstraint
- ranges Ranges
- A ssa.Value
- B ssa.Value
- Op token.Token
- I IntInterval
- resolved bool
-}
-
-type IntIntervalConstraint struct {
- aConstraint
- I IntInterval
-}
-
-func NewIntArithmeticConstraint(a, b, y ssa.Value, op token.Token, fn func(IntInterval, IntInterval) IntInterval) *IntArithmeticConstraint {
- return &IntArithmeticConstraint{NewConstraint(y), a, b, op, fn}
-}
-func NewIntAddConstraint(a, b, y ssa.Value) Constraint {
- return &IntAddConstraint{NewIntArithmeticConstraint(a, b, y, token.ADD, IntInterval.Add)}
-}
-func NewIntSubConstraint(a, b, y ssa.Value) Constraint {
- return &IntSubConstraint{NewIntArithmeticConstraint(a, b, y, token.SUB, IntInterval.Sub)}
-}
-func NewIntMulConstraint(a, b, y ssa.Value) Constraint {
- return &IntMulConstraint{NewIntArithmeticConstraint(a, b, y, token.MUL, IntInterval.Mul)}
-}
-func NewIntConversionConstraint(x, y ssa.Value) Constraint {
- return &IntConversionConstraint{NewConstraint(y), x}
-}
-func NewIntIntersectionConstraint(a, b ssa.Value, op token.Token, ranges Ranges, y ssa.Value) Constraint {
- return &IntIntersectionConstraint{
- aConstraint: NewConstraint(y),
- ranges: ranges,
- A: a,
- B: b,
- Op: op,
- }
-}
-func NewIntIntervalConstraint(i IntInterval, y ssa.Value) Constraint {
- return &IntIntervalConstraint{NewConstraint(y), i}
-}
-
-func (c *IntArithmeticConstraint) Operands() []ssa.Value { return []ssa.Value{c.A, c.B} }
-func (c *IntConversionConstraint) Operands() []ssa.Value { return []ssa.Value{c.X} }
-func (c *IntIntersectionConstraint) Operands() []ssa.Value { return []ssa.Value{c.A} }
-func (s *IntIntervalConstraint) Operands() []ssa.Value { return nil }
-
-func (c *IntArithmeticConstraint) String() string {
- return fmt.Sprintf("%s = %s %s %s", c.Y().Name(), c.A.Name(), c.Op, c.B.Name())
-}
-func (c *IntConversionConstraint) String() string {
- return fmt.Sprintf("%s = %s(%s)", c.Y().Name(), c.Y().Type(), c.X.Name())
-}
-func (c *IntIntersectionConstraint) String() string {
- return fmt.Sprintf("%s = %s %s %s (%t branch)", c.Y().Name(), c.A.Name(), c.Op, c.B.Name(), c.Y().(*ssa.Sigma).Branch)
-}
-func (c *IntIntervalConstraint) String() string { return fmt.Sprintf("%s = %s", c.Y().Name(), c.I) }
-
-func (c *IntArithmeticConstraint) Eval(g *Graph) Range {
- i1, i2 := g.Range(c.A).(IntInterval), g.Range(c.B).(IntInterval)
- if !i1.IsKnown() || !i2.IsKnown() {
- return IntInterval{}
- }
- return c.Fn(i1, i2)
-}
-func (c *IntConversionConstraint) Eval(g *Graph) Range {
- s := &types.StdSizes{
- // XXX is it okay to assume the largest word size, or do we
- // need to be platform specific?
- WordSize: 8,
- MaxAlign: 1,
- }
- fromI := g.Range(c.X).(IntInterval)
- toI := g.Range(c.Y()).(IntInterval)
- fromT := c.X.Type().Underlying().(*types.Basic)
- toT := c.Y().Type().Underlying().(*types.Basic)
- fromB := s.Sizeof(c.X.Type())
- toB := s.Sizeof(c.Y().Type())
-
- if !fromI.IsKnown() {
- return toI
- }
- if !toI.IsKnown() {
- return fromI
- }
-
- // uint -> sint/uint, M > N: [max(0, l1), min(2**N-1, u2)]
- if (fromT.Info()&types.IsUnsigned != 0) &&
- toB > fromB {
-
- n := big.NewInt(1)
- n.Lsh(n, uint(fromB*8))
- n.Sub(n, big.NewInt(1))
- return NewIntInterval(
- MaxZ(NewZ(0), fromI.Lower),
- MinZ(NewBigZ(n), toI.Upper),
- )
- }
-
- // sint -> sint, M > N; [max(-∞, l1), min(2**N-1, u2)]
- if (fromT.Info()&types.IsUnsigned == 0) &&
- (toT.Info()&types.IsUnsigned == 0) &&
- toB > fromB {
-
- n := big.NewInt(1)
- n.Lsh(n, uint(fromB*8))
- n.Sub(n, big.NewInt(1))
- return NewIntInterval(
- MaxZ(NInfinity, fromI.Lower),
- MinZ(NewBigZ(n), toI.Upper),
- )
- }
-
- return fromI
-}
-func (c *IntIntersectionConstraint) Eval(g *Graph) Range {
- xi := g.Range(c.A).(IntInterval)
- if !xi.IsKnown() {
- return c.I
- }
- return xi.Intersection(c.I)
-}
-func (c *IntIntervalConstraint) Eval(*Graph) Range { return c.I }
-
-func (c *IntIntersectionConstraint) Futures() []ssa.Value {
- return []ssa.Value{c.B}
-}
-
-func (c *IntIntersectionConstraint) Resolve() {
- r, ok := c.ranges[c.B].(IntInterval)
- if !ok {
- c.I = InfinityFor(c.Y())
- return
- }
-
- switch c.Op {
- case token.EQL:
- c.I = r
- case token.GTR:
- c.I = NewIntInterval(r.Lower.Add(NewZ(1)), PInfinity)
- case token.GEQ:
- c.I = NewIntInterval(r.Lower, PInfinity)
- case token.LSS:
- // TODO(dh): do we need 0 instead of NInfinity for uints?
- c.I = NewIntInterval(NInfinity, r.Upper.Sub(NewZ(1)))
- case token.LEQ:
- c.I = NewIntInterval(NInfinity, r.Upper)
- case token.NEQ:
- c.I = InfinityFor(c.Y())
- default:
- panic("unsupported op " + c.Op.String())
- }
-}
-
-func (c *IntIntersectionConstraint) IsKnown() bool {
- return c.I.IsKnown()
-}
-
-func (c *IntIntersectionConstraint) MarkUnresolved() {
- c.resolved = false
-}
-
-func (c *IntIntersectionConstraint) MarkResolved() {
- c.resolved = true
-}
-
-func (c *IntIntersectionConstraint) IsResolved() bool {
- return c.resolved
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/vrp/slice.go b/vendor/honnef.co/go/tools/staticcheck/vrp/slice.go
deleted file mode 100644
index 40658dd8d..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/vrp/slice.go
+++ /dev/null
@@ -1,273 +0,0 @@
-package vrp
-
-// TODO(dh): most of the constraints have implementations identical to
-// that of strings. Consider reusing them.
-
-import (
- "fmt"
- "go/types"
-
- "honnef.co/go/tools/ssa"
-)
-
-type SliceInterval struct {
- Length IntInterval
-}
-
-func (s SliceInterval) Union(other Range) Range {
- i, ok := other.(SliceInterval)
- if !ok {
- i = SliceInterval{EmptyIntInterval}
- }
- if s.Length.Empty() || !s.Length.IsKnown() {
- return i
- }
- if i.Length.Empty() || !i.Length.IsKnown() {
- return s
- }
- return SliceInterval{
- Length: s.Length.Union(i.Length).(IntInterval),
- }
-}
-func (s SliceInterval) String() string { return s.Length.String() }
-func (s SliceInterval) IsKnown() bool { return s.Length.IsKnown() }
-
-type SliceAppendConstraint struct {
- aConstraint
- A ssa.Value
- B ssa.Value
-}
-
-type SliceSliceConstraint struct {
- aConstraint
- X ssa.Value
- Lower ssa.Value
- Upper ssa.Value
-}
-
-type ArraySliceConstraint struct {
- aConstraint
- X ssa.Value
- Lower ssa.Value
- Upper ssa.Value
-}
-
-type SliceIntersectionConstraint struct {
- aConstraint
- X ssa.Value
- I IntInterval
-}
-
-type SliceLengthConstraint struct {
- aConstraint
- X ssa.Value
-}
-
-type MakeSliceConstraint struct {
- aConstraint
- Size ssa.Value
-}
-
-type SliceIntervalConstraint struct {
- aConstraint
- I IntInterval
-}
-
-func NewSliceAppendConstraint(a, b, y ssa.Value) Constraint {
- return &SliceAppendConstraint{NewConstraint(y), a, b}
-}
-func NewSliceSliceConstraint(x, lower, upper, y ssa.Value) Constraint {
- return &SliceSliceConstraint{NewConstraint(y), x, lower, upper}
-}
-func NewArraySliceConstraint(x, lower, upper, y ssa.Value) Constraint {
- return &ArraySliceConstraint{NewConstraint(y), x, lower, upper}
-}
-func NewSliceIntersectionConstraint(x ssa.Value, i IntInterval, y ssa.Value) Constraint {
- return &SliceIntersectionConstraint{NewConstraint(y), x, i}
-}
-func NewSliceLengthConstraint(x, y ssa.Value) Constraint {
- return &SliceLengthConstraint{NewConstraint(y), x}
-}
-func NewMakeSliceConstraint(size, y ssa.Value) Constraint {
- return &MakeSliceConstraint{NewConstraint(y), size}
-}
-func NewSliceIntervalConstraint(i IntInterval, y ssa.Value) Constraint {
- return &SliceIntervalConstraint{NewConstraint(y), i}
-}
-
-func (c *SliceAppendConstraint) Operands() []ssa.Value { return []ssa.Value{c.A, c.B} }
-func (c *SliceSliceConstraint) Operands() []ssa.Value {
- ops := []ssa.Value{c.X}
- if c.Lower != nil {
- ops = append(ops, c.Lower)
- }
- if c.Upper != nil {
- ops = append(ops, c.Upper)
- }
- return ops
-}
-func (c *ArraySliceConstraint) Operands() []ssa.Value {
- ops := []ssa.Value{c.X}
- if c.Lower != nil {
- ops = append(ops, c.Lower)
- }
- if c.Upper != nil {
- ops = append(ops, c.Upper)
- }
- return ops
-}
-func (c *SliceIntersectionConstraint) Operands() []ssa.Value { return []ssa.Value{c.X} }
-func (c *SliceLengthConstraint) Operands() []ssa.Value { return []ssa.Value{c.X} }
-func (c *MakeSliceConstraint) Operands() []ssa.Value { return []ssa.Value{c.Size} }
-func (s *SliceIntervalConstraint) Operands() []ssa.Value { return nil }
-
-func (c *SliceAppendConstraint) String() string {
- return fmt.Sprintf("%s = append(%s, %s)", c.Y().Name(), c.A.Name(), c.B.Name())
-}
-func (c *SliceSliceConstraint) String() string {
- var lname, uname string
- if c.Lower != nil {
- lname = c.Lower.Name()
- }
- if c.Upper != nil {
- uname = c.Upper.Name()
- }
- return fmt.Sprintf("%s[%s:%s]", c.X.Name(), lname, uname)
-}
-func (c *ArraySliceConstraint) String() string {
- var lname, uname string
- if c.Lower != nil {
- lname = c.Lower.Name()
- }
- if c.Upper != nil {
- uname = c.Upper.Name()
- }
- return fmt.Sprintf("%s[%s:%s]", c.X.Name(), lname, uname)
-}
-func (c *SliceIntersectionConstraint) String() string {
- return fmt.Sprintf("%s = %s.%t ⊓ %s", c.Y().Name(), c.X.Name(), c.Y().(*ssa.Sigma).Branch, c.I)
-}
-func (c *SliceLengthConstraint) String() string {
- return fmt.Sprintf("%s = len(%s)", c.Y().Name(), c.X.Name())
-}
-func (c *MakeSliceConstraint) String() string {
- return fmt.Sprintf("%s = make(slice, %s)", c.Y().Name(), c.Size.Name())
-}
-func (c *SliceIntervalConstraint) String() string { return fmt.Sprintf("%s = %s", c.Y().Name(), c.I) }
-
-func (c *SliceAppendConstraint) Eval(g *Graph) Range {
- l1 := g.Range(c.A).(SliceInterval).Length
- var l2 IntInterval
- switch r := g.Range(c.B).(type) {
- case SliceInterval:
- l2 = r.Length
- case StringInterval:
- l2 = r.Length
- default:
- return SliceInterval{}
- }
- if !l1.IsKnown() || !l2.IsKnown() {
- return SliceInterval{}
- }
- return SliceInterval{
- Length: l1.Add(l2),
- }
-}
-func (c *SliceSliceConstraint) Eval(g *Graph) Range {
- lr := NewIntInterval(NewZ(0), NewZ(0))
- if c.Lower != nil {
- lr = g.Range(c.Lower).(IntInterval)
- }
- ur := g.Range(c.X).(SliceInterval).Length
- if c.Upper != nil {
- ur = g.Range(c.Upper).(IntInterval)
- }
- if !lr.IsKnown() || !ur.IsKnown() {
- return SliceInterval{}
- }
-
- ls := []Z{
- ur.Lower.Sub(lr.Lower),
- ur.Upper.Sub(lr.Lower),
- ur.Lower.Sub(lr.Upper),
- ur.Upper.Sub(lr.Upper),
- }
- // TODO(dh): if we don't truncate lengths to 0 we might be able to
- // easily detect slices with high < low. we'd need to treat -∞
- // specially, though.
- for i, l := range ls {
- if l.Sign() == -1 {
- ls[i] = NewZ(0)
- }
- }
-
- return SliceInterval{
- Length: NewIntInterval(MinZ(ls...), MaxZ(ls...)),
- }
-}
-func (c *ArraySliceConstraint) Eval(g *Graph) Range {
- lr := NewIntInterval(NewZ(0), NewZ(0))
- if c.Lower != nil {
- lr = g.Range(c.Lower).(IntInterval)
- }
- var l int64
- switch typ := c.X.Type().(type) {
- case *types.Array:
- l = typ.Len()
- case *types.Pointer:
- l = typ.Elem().(*types.Array).Len()
- }
- ur := NewIntInterval(NewZ(l), NewZ(l))
- if c.Upper != nil {
- ur = g.Range(c.Upper).(IntInterval)
- }
- if !lr.IsKnown() || !ur.IsKnown() {
- return SliceInterval{}
- }
-
- ls := []Z{
- ur.Lower.Sub(lr.Lower),
- ur.Upper.Sub(lr.Lower),
- ur.Lower.Sub(lr.Upper),
- ur.Upper.Sub(lr.Upper),
- }
- // TODO(dh): if we don't truncate lengths to 0 we might be able to
- // easily detect slices with high < low. we'd need to treat -∞
- // specially, though.
- for i, l := range ls {
- if l.Sign() == -1 {
- ls[i] = NewZ(0)
- }
- }
-
- return SliceInterval{
- Length: NewIntInterval(MinZ(ls...), MaxZ(ls...)),
- }
-}
-func (c *SliceIntersectionConstraint) Eval(g *Graph) Range {
- xi := g.Range(c.X).(SliceInterval)
- if !xi.IsKnown() {
- return c.I
- }
- return SliceInterval{
- Length: xi.Length.Intersection(c.I),
- }
-}
-func (c *SliceLengthConstraint) Eval(g *Graph) Range {
- i := g.Range(c.X).(SliceInterval).Length
- if !i.IsKnown() {
- return NewIntInterval(NewZ(0), PInfinity)
- }
- return i
-}
-func (c *MakeSliceConstraint) Eval(g *Graph) Range {
- i, ok := g.Range(c.Size).(IntInterval)
- if !ok {
- return SliceInterval{NewIntInterval(NewZ(0), PInfinity)}
- }
- if i.Lower.Sign() == -1 {
- i.Lower = NewZ(0)
- }
- return SliceInterval{i}
-}
-func (c *SliceIntervalConstraint) Eval(*Graph) Range { return SliceInterval{c.I} }
diff --git a/vendor/honnef.co/go/tools/staticcheck/vrp/string.go b/vendor/honnef.co/go/tools/staticcheck/vrp/string.go
deleted file mode 100644
index e05877f9f..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/vrp/string.go
+++ /dev/null
@@ -1,258 +0,0 @@
-package vrp
-
-import (
- "fmt"
- "go/token"
- "go/types"
-
- "honnef.co/go/tools/ssa"
-)
-
-type StringInterval struct {
- Length IntInterval
-}
-
-func (s StringInterval) Union(other Range) Range {
- i, ok := other.(StringInterval)
- if !ok {
- i = StringInterval{EmptyIntInterval}
- }
- if s.Length.Empty() || !s.Length.IsKnown() {
- return i
- }
- if i.Length.Empty() || !i.Length.IsKnown() {
- return s
- }
- return StringInterval{
- Length: s.Length.Union(i.Length).(IntInterval),
- }
-}
-
-func (s StringInterval) String() string {
- return s.Length.String()
-}
-
-func (s StringInterval) IsKnown() bool {
- return s.Length.IsKnown()
-}
-
-type StringSliceConstraint struct {
- aConstraint
- X ssa.Value
- Lower ssa.Value
- Upper ssa.Value
-}
-
-type StringIntersectionConstraint struct {
- aConstraint
- ranges Ranges
- A ssa.Value
- B ssa.Value
- Op token.Token
- I IntInterval
- resolved bool
-}
-
-type StringConcatConstraint struct {
- aConstraint
- A ssa.Value
- B ssa.Value
-}
-
-type StringLengthConstraint struct {
- aConstraint
- X ssa.Value
-}
-
-type StringIntervalConstraint struct {
- aConstraint
- I IntInterval
-}
-
-func NewStringSliceConstraint(x, lower, upper, y ssa.Value) Constraint {
- return &StringSliceConstraint{NewConstraint(y), x, lower, upper}
-}
-func NewStringIntersectionConstraint(a, b ssa.Value, op token.Token, ranges Ranges, y ssa.Value) Constraint {
- return &StringIntersectionConstraint{
- aConstraint: NewConstraint(y),
- ranges: ranges,
- A: a,
- B: b,
- Op: op,
- }
-}
-func NewStringConcatConstraint(a, b, y ssa.Value) Constraint {
- return &StringConcatConstraint{NewConstraint(y), a, b}
-}
-func NewStringLengthConstraint(x ssa.Value, y ssa.Value) Constraint {
- return &StringLengthConstraint{NewConstraint(y), x}
-}
-func NewStringIntervalConstraint(i IntInterval, y ssa.Value) Constraint {
- return &StringIntervalConstraint{NewConstraint(y), i}
-}
-
-func (c *StringSliceConstraint) Operands() []ssa.Value {
- vs := []ssa.Value{c.X}
- if c.Lower != nil {
- vs = append(vs, c.Lower)
- }
- if c.Upper != nil {
- vs = append(vs, c.Upper)
- }
- return vs
-}
-func (c *StringIntersectionConstraint) Operands() []ssa.Value { return []ssa.Value{c.A} }
-func (c StringConcatConstraint) Operands() []ssa.Value { return []ssa.Value{c.A, c.B} }
-func (c *StringLengthConstraint) Operands() []ssa.Value { return []ssa.Value{c.X} }
-func (s *StringIntervalConstraint) Operands() []ssa.Value { return nil }
-
-func (c *StringSliceConstraint) String() string {
- var lname, uname string
- if c.Lower != nil {
- lname = c.Lower.Name()
- }
- if c.Upper != nil {
- uname = c.Upper.Name()
- }
- return fmt.Sprintf("%s[%s:%s]", c.X.Name(), lname, uname)
-}
-func (c *StringIntersectionConstraint) String() string {
- return fmt.Sprintf("%s = %s %s %s (%t branch)", c.Y().Name(), c.A.Name(), c.Op, c.B.Name(), c.Y().(*ssa.Sigma).Branch)
-}
-func (c StringConcatConstraint) String() string {
- return fmt.Sprintf("%s = %s + %s", c.Y().Name(), c.A.Name(), c.B.Name())
-}
-func (c *StringLengthConstraint) String() string {
- return fmt.Sprintf("%s = len(%s)", c.Y().Name(), c.X.Name())
-}
-func (c *StringIntervalConstraint) String() string { return fmt.Sprintf("%s = %s", c.Y().Name(), c.I) }
-
-func (c *StringSliceConstraint) Eval(g *Graph) Range {
- lr := NewIntInterval(NewZ(0), NewZ(0))
- if c.Lower != nil {
- lr = g.Range(c.Lower).(IntInterval)
- }
- ur := g.Range(c.X).(StringInterval).Length
- if c.Upper != nil {
- ur = g.Range(c.Upper).(IntInterval)
- }
- if !lr.IsKnown() || !ur.IsKnown() {
- return StringInterval{}
- }
-
- ls := []Z{
- ur.Lower.Sub(lr.Lower),
- ur.Upper.Sub(lr.Lower),
- ur.Lower.Sub(lr.Upper),
- ur.Upper.Sub(lr.Upper),
- }
- // TODO(dh): if we don't truncate lengths to 0 we might be able to
- // easily detect slices with high < low. we'd need to treat -∞
- // specially, though.
- for i, l := range ls {
- if l.Sign() == -1 {
- ls[i] = NewZ(0)
- }
- }
-
- return StringInterval{
- Length: NewIntInterval(MinZ(ls...), MaxZ(ls...)),
- }
-}
-func (c *StringIntersectionConstraint) Eval(g *Graph) Range {
- var l IntInterval
- switch r := g.Range(c.A).(type) {
- case StringInterval:
- l = r.Length
- case IntInterval:
- l = r
- }
-
- if !l.IsKnown() {
- return StringInterval{c.I}
- }
- return StringInterval{
- Length: l.Intersection(c.I),
- }
-}
-func (c StringConcatConstraint) Eval(g *Graph) Range {
- i1, i2 := g.Range(c.A).(StringInterval), g.Range(c.B).(StringInterval)
- if !i1.Length.IsKnown() || !i2.Length.IsKnown() {
- return StringInterval{}
- }
- return StringInterval{
- Length: i1.Length.Add(i2.Length),
- }
-}
-func (c *StringLengthConstraint) Eval(g *Graph) Range {
- i := g.Range(c.X).(StringInterval).Length
- if !i.IsKnown() {
- return NewIntInterval(NewZ(0), PInfinity)
- }
- return i
-}
-func (c *StringIntervalConstraint) Eval(*Graph) Range { return StringInterval{c.I} }
-
-func (c *StringIntersectionConstraint) Futures() []ssa.Value {
- return []ssa.Value{c.B}
-}
-
-func (c *StringIntersectionConstraint) Resolve() {
- if (c.A.Type().Underlying().(*types.Basic).Info() & types.IsString) != 0 {
- // comparing two strings
- r, ok := c.ranges[c.B].(StringInterval)
- if !ok {
- c.I = NewIntInterval(NewZ(0), PInfinity)
- return
- }
- switch c.Op {
- case token.EQL:
- c.I = r.Length
- case token.GTR, token.GEQ:
- c.I = NewIntInterval(r.Length.Lower, PInfinity)
- case token.LSS, token.LEQ:
- c.I = NewIntInterval(NewZ(0), r.Length.Upper)
- case token.NEQ:
- default:
- panic("unsupported op " + c.Op.String())
- }
- } else {
- r, ok := c.ranges[c.B].(IntInterval)
- if !ok {
- c.I = NewIntInterval(NewZ(0), PInfinity)
- return
- }
- // comparing two lengths
- switch c.Op {
- case token.EQL:
- c.I = r
- case token.GTR:
- c.I = NewIntInterval(r.Lower.Add(NewZ(1)), PInfinity)
- case token.GEQ:
- c.I = NewIntInterval(r.Lower, PInfinity)
- case token.LSS:
- c.I = NewIntInterval(NInfinity, r.Upper.Sub(NewZ(1)))
- case token.LEQ:
- c.I = NewIntInterval(NInfinity, r.Upper)
- case token.NEQ:
- default:
- panic("unsupported op " + c.Op.String())
- }
- }
-}
-
-func (c *StringIntersectionConstraint) IsKnown() bool {
- return c.I.IsKnown()
-}
-
-func (c *StringIntersectionConstraint) MarkUnresolved() {
- c.resolved = false
-}
-
-func (c *StringIntersectionConstraint) MarkResolved() {
- c.resolved = true
-}
-
-func (c *StringIntersectionConstraint) IsResolved() bool {
- return c.resolved
-}
diff --git a/vendor/honnef.co/go/tools/staticcheck/vrp/vrp.go b/vendor/honnef.co/go/tools/staticcheck/vrp/vrp.go
deleted file mode 100644
index 3c138e512..000000000
--- a/vendor/honnef.co/go/tools/staticcheck/vrp/vrp.go
+++ /dev/null
@@ -1,1056 +0,0 @@
-package vrp
-
-// TODO(dh) widening and narrowing have a lot of code in common. Make
-// it reusable.
-
-import (
- "fmt"
- "go/constant"
- "go/token"
- "go/types"
- "math/big"
- "sort"
- "strings"
-
- "honnef.co/go/tools/lint"
- "honnef.co/go/tools/ssa"
-)
-
-type Future interface {
- Constraint
- Futures() []ssa.Value
- Resolve()
- IsKnown() bool
- MarkUnresolved()
- MarkResolved()
- IsResolved() bool
-}
-
-type Range interface {
- Union(other Range) Range
- IsKnown() bool
-}
-
-type Constraint interface {
- Y() ssa.Value
- isConstraint()
- String() string
- Eval(*Graph) Range
- Operands() []ssa.Value
-}
-
-type aConstraint struct {
- y ssa.Value
-}
-
-func NewConstraint(y ssa.Value) aConstraint {
- return aConstraint{y}
-}
-
-func (aConstraint) isConstraint() {}
-func (c aConstraint) Y() ssa.Value { return c.y }
-
-type PhiConstraint struct {
- aConstraint
- Vars []ssa.Value
-}
-
-func NewPhiConstraint(vars []ssa.Value, y ssa.Value) Constraint {
- uniqm := map[ssa.Value]struct{}{}
- for _, v := range vars {
- uniqm[v] = struct{}{}
- }
- var uniq []ssa.Value
- for v := range uniqm {
- uniq = append(uniq, v)
- }
- return &PhiConstraint{
- aConstraint: NewConstraint(y),
- Vars: uniq,
- }
-}
-
-func (c *PhiConstraint) Operands() []ssa.Value {
- return c.Vars
-}
-
-func (c *PhiConstraint) Eval(g *Graph) Range {
- i := Range(nil)
- for _, v := range c.Vars {
- i = g.Range(v).Union(i)
- }
- return i
-}
-
-func (c *PhiConstraint) String() string {
- names := make([]string, len(c.Vars))
- for i, v := range c.Vars {
- names[i] = v.Name()
- }
- return fmt.Sprintf("%s = φ(%s)", c.Y().Name(), strings.Join(names, ", "))
-}
-
-func isSupportedType(typ types.Type) bool {
- switch typ := typ.Underlying().(type) {
- case *types.Basic:
- switch typ.Kind() {
- case types.String, types.UntypedString:
- return true
- default:
- if (typ.Info() & types.IsInteger) == 0 {
- return false
- }
- }
- case *types.Chan:
- return true
- case *types.Slice:
- return true
- default:
- return false
- }
- return true
-}
-
-func ConstantToZ(c constant.Value) Z {
- s := constant.ToInt(c).ExactString()
- n := &big.Int{}
- n.SetString(s, 10)
- return NewBigZ(n)
-}
-
-func sigmaInteger(g *Graph, ins *ssa.Sigma, cond *ssa.BinOp, ops []*ssa.Value) Constraint {
- op := cond.Op
- if !ins.Branch {
- op = (invertToken(op))
- }
-
- switch op {
- case token.EQL, token.GTR, token.GEQ, token.LSS, token.LEQ:
- default:
- return nil
- }
- var a, b ssa.Value
- if (*ops[0]) == ins.X {
- a = *ops[0]
- b = *ops[1]
- } else {
- a = *ops[1]
- b = *ops[0]
- op = flipToken(op)
- }
- return NewIntIntersectionConstraint(a, b, op, g.ranges, ins)
-}
-
-func sigmaString(g *Graph, ins *ssa.Sigma, cond *ssa.BinOp, ops []*ssa.Value) Constraint {
- op := cond.Op
- if !ins.Branch {
- op = (invertToken(op))
- }
-
- switch op {
- case token.EQL, token.GTR, token.GEQ, token.LSS, token.LEQ:
- default:
- return nil
- }
-
- if ((*ops[0]).Type().Underlying().(*types.Basic).Info() & types.IsString) == 0 {
- var a, b ssa.Value
- call, ok := (*ops[0]).(*ssa.Call)
- if ok && call.Common().Args[0] == ins.X {
- a = *ops[0]
- b = *ops[1]
- } else {
- a = *ops[1]
- b = *ops[0]
- op = flipToken(op)
- }
- return NewStringIntersectionConstraint(a, b, op, g.ranges, ins)
- }
- var a, b ssa.Value
- if (*ops[0]) == ins.X {
- a = *ops[0]
- b = *ops[1]
- } else {
- a = *ops[1]
- b = *ops[0]
- op = flipToken(op)
- }
- return NewStringIntersectionConstraint(a, b, op, g.ranges, ins)
-}
-
-func sigmaSlice(g *Graph, ins *ssa.Sigma, cond *ssa.BinOp, ops []*ssa.Value) Constraint {
- // TODO(dh) sigmaSlice and sigmaString are a lot alike. Can they
- // be merged?
- //
- // XXX support futures
-
- op := cond.Op
- if !ins.Branch {
- op = (invertToken(op))
- }
-
- k, ok := (*ops[1]).(*ssa.Const)
- // XXX investigate in what cases this wouldn't be a Const
- //
- // XXX what if left and right are swapped?
- if !ok {
- return nil
- }
-
- call, ok := (*ops[0]).(*ssa.Call)
- if !ok {
- return nil
- }
- builtin, ok := call.Common().Value.(*ssa.Builtin)
- if !ok {
- return nil
- }
- if builtin.Name() != "len" {
- return nil
- }
- callops := call.Operands(nil)
-
- v := ConstantToZ(k.Value)
- c := NewSliceIntersectionConstraint(*callops[1], IntInterval{}, ins).(*SliceIntersectionConstraint)
- switch op {
- case token.EQL:
- c.I = NewIntInterval(v, v)
- case token.GTR, token.GEQ:
- off := int64(0)
- if cond.Op == token.GTR {
- off = 1
- }
- c.I = NewIntInterval(
- v.Add(NewZ(off)),
- PInfinity,
- )
- case token.LSS, token.LEQ:
- off := int64(0)
- if cond.Op == token.LSS {
- off = -1
- }
- c.I = NewIntInterval(
- NInfinity,
- v.Add(NewZ(off)),
- )
- default:
- return nil
- }
- return c
-}
-
-func BuildGraph(f *ssa.Function) *Graph {
- g := &Graph{
- Vertices: map[interface{}]*Vertex{},
- ranges: Ranges{},
- }
-
- var cs []Constraint
-
- ops := make([]*ssa.Value, 16)
- seen := map[ssa.Value]bool{}
- for _, block := range f.Blocks {
- for _, ins := range block.Instrs {
- ops = ins.Operands(ops[:0])
- for _, op := range ops {
- if c, ok := (*op).(*ssa.Const); ok {
- if seen[c] {
- continue
- }
- seen[c] = true
- if c.Value == nil {
- switch c.Type().Underlying().(type) {
- case *types.Slice:
- cs = append(cs, NewSliceIntervalConstraint(NewIntInterval(NewZ(0), NewZ(0)), c))
- }
- continue
- }
- switch c.Value.Kind() {
- case constant.Int:
- v := ConstantToZ(c.Value)
- cs = append(cs, NewIntIntervalConstraint(NewIntInterval(v, v), c))
- case constant.String:
- s := constant.StringVal(c.Value)
- n := NewZ(int64(len(s)))
- cs = append(cs, NewStringIntervalConstraint(NewIntInterval(n, n), c))
- }
- }
- }
- }
- }
- for _, block := range f.Blocks {
- for _, ins := range block.Instrs {
- switch ins := ins.(type) {
- case *ssa.Convert:
- switch v := ins.Type().Underlying().(type) {
- case *types.Basic:
- if (v.Info() & types.IsInteger) == 0 {
- continue
- }
- cs = append(cs, NewIntConversionConstraint(ins.X, ins))
- }
- case *ssa.Call:
- if static := ins.Common().StaticCallee(); static != nil {
- if fn, ok := static.Object().(*types.Func); ok {
- switch lint.FuncName(fn) {
- case "bytes.Index", "bytes.IndexAny", "bytes.IndexByte",
- "bytes.IndexFunc", "bytes.IndexRune", "bytes.LastIndex",
- "bytes.LastIndexAny", "bytes.LastIndexByte", "bytes.LastIndexFunc",
- "strings.Index", "strings.IndexAny", "strings.IndexByte",
- "strings.IndexFunc", "strings.IndexRune", "strings.LastIndex",
- "strings.LastIndexAny", "strings.LastIndexByte", "strings.LastIndexFunc":
- // TODO(dh): instead of limiting by +∞,
- // limit by the upper bound of the passed
- // string
- cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(-1), PInfinity), ins))
- case "bytes.Title", "bytes.ToLower", "bytes.ToTitle", "bytes.ToUpper",
- "strings.Title", "strings.ToLower", "strings.ToTitle", "strings.ToUpper":
- cs = append(cs, NewCopyConstraint(ins.Common().Args[0], ins))
- case "bytes.ToLowerSpecial", "bytes.ToTitleSpecial", "bytes.ToUpperSpecial",
- "strings.ToLowerSpecial", "strings.ToTitleSpecial", "strings.ToUpperSpecial":
- cs = append(cs, NewCopyConstraint(ins.Common().Args[1], ins))
- case "bytes.Compare", "strings.Compare":
- cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(-1), NewZ(1)), ins))
- case "bytes.Count", "strings.Count":
- // TODO(dh): instead of limiting by +∞,
- // limit by the upper bound of the passed
- // string.
- cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(0), PInfinity), ins))
- case "bytes.Map", "bytes.TrimFunc", "bytes.TrimLeft", "bytes.TrimLeftFunc",
- "bytes.TrimRight", "bytes.TrimRightFunc", "bytes.TrimSpace",
- "strings.Map", "strings.TrimFunc", "strings.TrimLeft", "strings.TrimLeftFunc",
- "strings.TrimRight", "strings.TrimRightFunc", "strings.TrimSpace":
- // TODO(dh): lower = 0, upper = upper of passed string
- case "bytes.TrimPrefix", "bytes.TrimSuffix",
- "strings.TrimPrefix", "strings.TrimSuffix":
- // TODO(dh) range between "unmodified" and len(cutset) removed
- case "(*bytes.Buffer).Cap", "(*bytes.Buffer).Len", "(*bytes.Reader).Len", "(*bytes.Reader).Size":
- cs = append(cs, NewIntIntervalConstraint(NewIntInterval(NewZ(0), PInfinity), ins))
- }
- }
- }
- builtin, ok := ins.Common().Value.(*ssa.Builtin)
- ops := ins.Operands(nil)
- if !ok {
- continue
- }
- switch builtin.Name() {
- case "len":
- switch op1 := (*ops[1]).Type().Underlying().(type) {
- case *types.Basic:
- if op1.Kind() == types.String || op1.Kind() == types.UntypedString {
- cs = append(cs, NewStringLengthConstraint(*ops[1], ins))
- }
- case *types.Slice:
- cs = append(cs, NewSliceLengthConstraint(*ops[1], ins))
- }
-
- case "append":
- cs = append(cs, NewSliceAppendConstraint(ins.Common().Args[0], ins.Common().Args[1], ins))
- }
- case *ssa.BinOp:
- ops := ins.Operands(nil)
- basic, ok := (*ops[0]).Type().Underlying().(*types.Basic)
- if !ok {
- continue
- }
- switch basic.Kind() {
- case types.Int, types.Int8, types.Int16, types.Int32, types.Int64,
- types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64, types.UntypedInt:
- fns := map[token.Token]func(ssa.Value, ssa.Value, ssa.Value) Constraint{
- token.ADD: NewIntAddConstraint,
- token.SUB: NewIntSubConstraint,
- token.MUL: NewIntMulConstraint,
- // XXX support QUO, REM, SHL, SHR
- }
- fn, ok := fns[ins.Op]
- if ok {
- cs = append(cs, fn(*ops[0], *ops[1], ins))
- }
- case types.String, types.UntypedString:
- if ins.Op == token.ADD {
- cs = append(cs, NewStringConcatConstraint(*ops[0], *ops[1], ins))
- }
- }
- case *ssa.Slice:
- typ := ins.X.Type().Underlying()
- switch typ := typ.(type) {
- case *types.Basic:
- cs = append(cs, NewStringSliceConstraint(ins.X, ins.Low, ins.High, ins))
- case *types.Slice:
- cs = append(cs, NewSliceSliceConstraint(ins.X, ins.Low, ins.High, ins))
- case *types.Array:
- cs = append(cs, NewArraySliceConstraint(ins.X, ins.Low, ins.High, ins))
- case *types.Pointer:
- if _, ok := typ.Elem().(*types.Array); !ok {
- continue
- }
- cs = append(cs, NewArraySliceConstraint(ins.X, ins.Low, ins.High, ins))
- }
- case *ssa.Phi:
- if !isSupportedType(ins.Type()) {
- continue
- }
- ops := ins.Operands(nil)
- dops := make([]ssa.Value, len(ops))
- for i, op := range ops {
- dops[i] = *op
- }
- cs = append(cs, NewPhiConstraint(dops, ins))
- case *ssa.Sigma:
- pred := ins.Block().Preds[0]
- instrs := pred.Instrs
- cond, ok := instrs[len(instrs)-1].(*ssa.If).Cond.(*ssa.BinOp)
- ops := cond.Operands(nil)
- if !ok {
- continue
- }
- switch typ := ins.Type().Underlying().(type) {
- case *types.Basic:
- var c Constraint
- switch typ.Kind() {
- case types.Int, types.Int8, types.Int16, types.Int32, types.Int64,
- types.Uint, types.Uint8, types.Uint16, types.Uint32, types.Uint64, types.UntypedInt:
- c = sigmaInteger(g, ins, cond, ops)
- case types.String, types.UntypedString:
- c = sigmaString(g, ins, cond, ops)
- }
- if c != nil {
- cs = append(cs, c)
- }
- case *types.Slice:
- c := sigmaSlice(g, ins, cond, ops)
- if c != nil {
- cs = append(cs, c)
- }
- default:
- //log.Printf("unsupported sigma type %T", typ) // XXX
- }
- case *ssa.MakeChan:
- cs = append(cs, NewMakeChannelConstraint(ins.Size, ins))
- case *ssa.MakeSlice:
- cs = append(cs, NewMakeSliceConstraint(ins.Len, ins))
- case *ssa.ChangeType:
- switch ins.X.Type().Underlying().(type) {
- case *types.Chan:
- cs = append(cs, NewChannelChangeTypeConstraint(ins.X, ins))
- }
- }
- }
- }
-
- for _, c := range cs {
- if c == nil {
- panic("nil constraint")
- }
- // If V is used in constraint C, then we create an edge V->C
- for _, op := range c.Operands() {
- g.AddEdge(op, c, false)
- }
- if c, ok := c.(Future); ok {
- for _, op := range c.Futures() {
- g.AddEdge(op, c, true)
- }
- }
- // If constraint C defines variable V, then we create an edge
- // C->V
- g.AddEdge(c, c.Y(), false)
- }
-
- g.FindSCCs()
- g.sccEdges = make([][]Edge, len(g.SCCs))
- g.futures = make([][]Future, len(g.SCCs))
- for _, e := range g.Edges {
- g.sccEdges[e.From.SCC] = append(g.sccEdges[e.From.SCC], e)
- if !e.control {
- continue
- }
- if c, ok := e.To.Value.(Future); ok {
- g.futures[e.From.SCC] = append(g.futures[e.From.SCC], c)
- }
- }
- return g
-}
-
-func (g *Graph) Solve() Ranges {
- var consts []Z
- off := NewZ(1)
- for _, n := range g.Vertices {
- if c, ok := n.Value.(*ssa.Const); ok {
- basic, ok := c.Type().Underlying().(*types.Basic)
- if !ok {
- continue
- }
- if (basic.Info() & types.IsInteger) != 0 {
- z := ConstantToZ(c.Value)
- consts = append(consts, z)
- consts = append(consts, z.Add(off))
- consts = append(consts, z.Sub(off))
- }
- }
-
- }
- sort.Sort(Zs(consts))
-
- for scc, vertices := range g.SCCs {
- n := 0
- n = len(vertices)
- if n == 1 {
- g.resolveFutures(scc)
- v := vertices[0]
- if v, ok := v.Value.(ssa.Value); ok {
- switch typ := v.Type().Underlying().(type) {
- case *types.Basic:
- switch typ.Kind() {
- case types.String, types.UntypedString:
- if !g.Range(v).(StringInterval).IsKnown() {
- g.SetRange(v, StringInterval{NewIntInterval(NewZ(0), PInfinity)})
- }
- default:
- if !g.Range(v).(IntInterval).IsKnown() {
- g.SetRange(v, InfinityFor(v))
- }
- }
- case *types.Chan:
- if !g.Range(v).(ChannelInterval).IsKnown() {
- g.SetRange(v, ChannelInterval{NewIntInterval(NewZ(0), PInfinity)})
- }
- case *types.Slice:
- if !g.Range(v).(SliceInterval).IsKnown() {
- g.SetRange(v, SliceInterval{NewIntInterval(NewZ(0), PInfinity)})
- }
- }
- }
- if c, ok := v.Value.(Constraint); ok {
- g.SetRange(c.Y(), c.Eval(g))
- }
- } else {
- uses := g.uses(scc)
- entries := g.entries(scc)
- for len(entries) > 0 {
- v := entries[len(entries)-1]
- entries = entries[:len(entries)-1]
- for _, use := range uses[v] {
- if g.widen(use, consts) {
- entries = append(entries, use.Y())
- }
- }
- }
-
- g.resolveFutures(scc)
-
- // XXX this seems to be necessary, but shouldn't be.
- // removing it leads to nil pointer derefs; investigate
- // where we're not setting values correctly.
- for _, n := range vertices {
- if v, ok := n.Value.(ssa.Value); ok {
- i, ok := g.Range(v).(IntInterval)
- if !ok {
- continue
- }
- if !i.IsKnown() {
- g.SetRange(v, InfinityFor(v))
- }
- }
- }
-
- actives := g.actives(scc)
- for len(actives) > 0 {
- v := actives[len(actives)-1]
- actives = actives[:len(actives)-1]
- for _, use := range uses[v] {
- if g.narrow(use) {
- actives = append(actives, use.Y())
- }
- }
- }
- }
- // propagate scc
- for _, edge := range g.sccEdges[scc] {
- if edge.control {
- continue
- }
- if edge.From.SCC == edge.To.SCC {
- continue
- }
- if c, ok := edge.To.Value.(Constraint); ok {
- g.SetRange(c.Y(), c.Eval(g))
- }
- if c, ok := edge.To.Value.(Future); ok {
- if !c.IsKnown() {
- c.MarkUnresolved()
- }
- }
- }
- }
-
- for v, r := range g.ranges {
- i, ok := r.(IntInterval)
- if !ok {
- continue
- }
- if (v.Type().Underlying().(*types.Basic).Info() & types.IsUnsigned) == 0 {
- if i.Upper != PInfinity {
- s := &types.StdSizes{
- // XXX is it okay to assume the largest word size, or do we
- // need to be platform specific?
- WordSize: 8,
- MaxAlign: 1,
- }
- bits := (s.Sizeof(v.Type()) * 8) - 1
- n := big.NewInt(1)
- n = n.Lsh(n, uint(bits))
- upper, lower := &big.Int{}, &big.Int{}
- upper.Sub(n, big.NewInt(1))
- lower.Neg(n)
-
- if i.Upper.Cmp(NewBigZ(upper)) == 1 {
- i = NewIntInterval(NInfinity, PInfinity)
- } else if i.Lower.Cmp(NewBigZ(lower)) == -1 {
- i = NewIntInterval(NInfinity, PInfinity)
- }
- }
- }
-
- g.ranges[v] = i
- }
-
- return g.ranges
-}
-
-func VertexString(v *Vertex) string {
- switch v := v.Value.(type) {
- case Constraint:
- return v.String()
- case ssa.Value:
- return v.Name()
- case nil:
- return "BUG: nil vertex value"
- default:
- panic(fmt.Sprintf("unexpected type %T", v))
- }
-}
-
-type Vertex struct {
- Value interface{} // one of Constraint or ssa.Value
- SCC int
- index int
- lowlink int
- stack bool
-
- Succs []Edge
-}
-
-type Ranges map[ssa.Value]Range
-
-func (r Ranges) Get(x ssa.Value) Range {
- if x == nil {
- return nil
- }
- i, ok := r[x]
- if !ok {
- switch x := x.Type().Underlying().(type) {
- case *types.Basic:
- switch x.Kind() {
- case types.String, types.UntypedString:
- return StringInterval{}
- default:
- return IntInterval{}
- }
- case *types.Chan:
- return ChannelInterval{}
- case *types.Slice:
- return SliceInterval{}
- }
- }
- return i
-}
-
-type Graph struct {
- Vertices map[interface{}]*Vertex
- Edges []Edge
- SCCs [][]*Vertex
- ranges Ranges
-
- // map SCCs to futures
- futures [][]Future
- // map SCCs to edges
- sccEdges [][]Edge
-}
-
-func (g Graph) Graphviz() string {
- var lines []string
- lines = append(lines, "digraph{")
- ids := map[interface{}]int{}
- i := 1
- for _, v := range g.Vertices {
- ids[v] = i
- shape := "box"
- if _, ok := v.Value.(ssa.Value); ok {
- shape = "oval"
- }
- lines = append(lines, fmt.Sprintf(`n%d [shape="%s", label=%q, colorscheme=spectral11, style="filled", fillcolor="%d"]`,
- i, shape, VertexString(v), (v.SCC%11)+1))
- i++
- }
- for _, e := range g.Edges {
- style := "solid"
- if e.control {
- style = "dashed"
- }
- lines = append(lines, fmt.Sprintf(`n%d -> n%d [style="%s"]`, ids[e.From], ids[e.To], style))
- }
- lines = append(lines, "}")
- return strings.Join(lines, "\n")
-}
-
-func (g *Graph) SetRange(x ssa.Value, r Range) {
- g.ranges[x] = r
-}
-
-func (g *Graph) Range(x ssa.Value) Range {
- return g.ranges.Get(x)
-}
-
-func (g *Graph) widen(c Constraint, consts []Z) bool {
- setRange := func(i Range) {
- g.SetRange(c.Y(), i)
- }
- widenIntInterval := func(oi, ni IntInterval) (IntInterval, bool) {
- if !ni.IsKnown() {
- return oi, false
- }
- nlc := NInfinity
- nuc := PInfinity
-
- // Don't get stuck widening for an absurd amount of time due
- // to an excess number of constants, as may be present in
- // table-based scanners.
- if len(consts) < 1000 {
- for _, co := range consts {
- if co.Cmp(ni.Lower) <= 0 {
- nlc = co
- break
- }
- }
- for _, co := range consts {
- if co.Cmp(ni.Upper) >= 0 {
- nuc = co
- break
- }
- }
- }
-
- if !oi.IsKnown() {
- return ni, true
- }
- if ni.Lower.Cmp(oi.Lower) == -1 && ni.Upper.Cmp(oi.Upper) == 1 {
- return NewIntInterval(nlc, nuc), true
- }
- if ni.Lower.Cmp(oi.Lower) == -1 {
- return NewIntInterval(nlc, oi.Upper), true
- }
- if ni.Upper.Cmp(oi.Upper) == 1 {
- return NewIntInterval(oi.Lower, nuc), true
- }
- return oi, false
- }
- switch oi := g.Range(c.Y()).(type) {
- case IntInterval:
- ni := c.Eval(g).(IntInterval)
- si, changed := widenIntInterval(oi, ni)
- if changed {
- setRange(si)
- return true
- }
- return false
- case StringInterval:
- ni := c.Eval(g).(StringInterval)
- si, changed := widenIntInterval(oi.Length, ni.Length)
- if changed {
- setRange(StringInterval{si})
- return true
- }
- return false
- case SliceInterval:
- ni := c.Eval(g).(SliceInterval)
- si, changed := widenIntInterval(oi.Length, ni.Length)
- if changed {
- setRange(SliceInterval{si})
- return true
- }
- return false
- default:
- return false
- }
-}
-
-func (g *Graph) narrow(c Constraint) bool {
- narrowIntInterval := func(oi, ni IntInterval) (IntInterval, bool) {
- oLower := oi.Lower
- oUpper := oi.Upper
- nLower := ni.Lower
- nUpper := ni.Upper
-
- if oLower == NInfinity && nLower != NInfinity {
- return NewIntInterval(nLower, oUpper), true
- }
- if oUpper == PInfinity && nUpper != PInfinity {
- return NewIntInterval(oLower, nUpper), true
- }
- if oLower.Cmp(nLower) == 1 {
- return NewIntInterval(nLower, oUpper), true
- }
- if oUpper.Cmp(nUpper) == -1 {
- return NewIntInterval(oLower, nUpper), true
- }
- return oi, false
- }
- switch oi := g.Range(c.Y()).(type) {
- case IntInterval:
- ni := c.Eval(g).(IntInterval)
- si, changed := narrowIntInterval(oi, ni)
- if changed {
- g.SetRange(c.Y(), si)
- return true
- }
- return false
- case StringInterval:
- ni := c.Eval(g).(StringInterval)
- si, changed := narrowIntInterval(oi.Length, ni.Length)
- if changed {
- g.SetRange(c.Y(), StringInterval{si})
- return true
- }
- return false
- case SliceInterval:
- ni := c.Eval(g).(SliceInterval)
- si, changed := narrowIntInterval(oi.Length, ni.Length)
- if changed {
- g.SetRange(c.Y(), SliceInterval{si})
- return true
- }
- return false
- default:
- return false
- }
-}
-
-func (g *Graph) resolveFutures(scc int) {
- for _, c := range g.futures[scc] {
- c.Resolve()
- }
-}
-
-func (g *Graph) entries(scc int) []ssa.Value {
- var entries []ssa.Value
- for _, n := range g.Vertices {
- if n.SCC != scc {
- continue
- }
- if v, ok := n.Value.(ssa.Value); ok {
- // XXX avoid quadratic runtime
- //
- // XXX I cannot think of any code where the future and its
- // variables aren't in the same SCC, in which case this
- // code isn't very useful (the variables won't be resolved
- // yet). Before we have a cross-SCC example, however, we
- // can't really verify that this code is working
- // correctly, or indeed doing anything useful.
- for _, on := range g.Vertices {
- if c, ok := on.Value.(Future); ok {
- if c.Y() == v {
- if !c.IsResolved() {
- g.SetRange(c.Y(), c.Eval(g))
- c.MarkResolved()
- }
- break
- }
- }
- }
- if g.Range(v).IsKnown() {
- entries = append(entries, v)
- }
- }
- }
- return entries
-}
-
-func (g *Graph) uses(scc int) map[ssa.Value][]Constraint {
- m := map[ssa.Value][]Constraint{}
- for _, e := range g.sccEdges[scc] {
- if e.control {
- continue
- }
- if v, ok := e.From.Value.(ssa.Value); ok {
- c := e.To.Value.(Constraint)
- sink := c.Y()
- if g.Vertices[sink].SCC == scc {
- m[v] = append(m[v], c)
- }
- }
- }
- return m
-}
-
-func (g *Graph) actives(scc int) []ssa.Value {
- var actives []ssa.Value
- for _, n := range g.Vertices {
- if n.SCC != scc {
- continue
- }
- if v, ok := n.Value.(ssa.Value); ok {
- if _, ok := v.(*ssa.Const); !ok {
- actives = append(actives, v)
- }
- }
- }
- return actives
-}
-
-func (g *Graph) AddEdge(from, to interface{}, ctrl bool) {
- vf, ok := g.Vertices[from]
- if !ok {
- vf = &Vertex{Value: from}
- g.Vertices[from] = vf
- }
- vt, ok := g.Vertices[to]
- if !ok {
- vt = &Vertex{Value: to}
- g.Vertices[to] = vt
- }
- e := Edge{From: vf, To: vt, control: ctrl}
- g.Edges = append(g.Edges, e)
- vf.Succs = append(vf.Succs, e)
-}
-
-type Edge struct {
- From, To *Vertex
- control bool
-}
-
-func (e Edge) String() string {
- return fmt.Sprintf("%s -> %s", VertexString(e.From), VertexString(e.To))
-}
-
-func (g *Graph) FindSCCs() {
- // use Tarjan to find the SCCs
-
- index := 1
- var s []*Vertex
-
- scc := 0
- var strongconnect func(v *Vertex)
- strongconnect = func(v *Vertex) {
- // set the depth index for v to the smallest unused index
- v.index = index
- v.lowlink = index
- index++
- s = append(s, v)
- v.stack = true
-
- for _, e := range v.Succs {
- w := e.To
- if w.index == 0 {
- // successor w has not yet been visited; recurse on it
- strongconnect(w)
- if w.lowlink < v.lowlink {
- v.lowlink = w.lowlink
- }
- } else if w.stack {
- // successor w is in stack s and hence in the current scc
- if w.index < v.lowlink {
- v.lowlink = w.index
- }
- }
- }
-
- if v.lowlink == v.index {
- for {
- w := s[len(s)-1]
- s = s[:len(s)-1]
- w.stack = false
- w.SCC = scc
- if w == v {
- break
- }
- }
- scc++
- }
- }
- for _, v := range g.Vertices {
- if v.index == 0 {
- strongconnect(v)
- }
- }
-
- g.SCCs = make([][]*Vertex, scc)
- for _, n := range g.Vertices {
- n.SCC = scc - n.SCC - 1
- g.SCCs[n.SCC] = append(g.SCCs[n.SCC], n)
- }
-}
-
-func invertToken(tok token.Token) token.Token {
- switch tok {
- case token.LSS:
- return token.GEQ
- case token.GTR:
- return token.LEQ
- case token.EQL:
- return token.NEQ
- case token.NEQ:
- return token.EQL
- case token.GEQ:
- return token.LSS
- case token.LEQ:
- return token.GTR
- default:
- panic(fmt.Sprintf("unsupported token %s", tok))
- }
-}
-
-func flipToken(tok token.Token) token.Token {
- switch tok {
- case token.LSS:
- return token.GTR
- case token.GTR:
- return token.LSS
- case token.EQL:
- return token.EQL
- case token.NEQ:
- return token.NEQ
- case token.GEQ:
- return token.LEQ
- case token.LEQ:
- return token.GEQ
- default:
- panic(fmt.Sprintf("unsupported token %s", tok))
- }
-}
-
-type CopyConstraint struct {
- aConstraint
- X ssa.Value
-}
-
-func (c *CopyConstraint) String() string {
- return fmt.Sprintf("%s = copy(%s)", c.Y().Name(), c.X.Name())
-}
-
-func (c *CopyConstraint) Eval(g *Graph) Range {
- return g.Range(c.X)
-}
-
-func (c *CopyConstraint) Operands() []ssa.Value {
- return []ssa.Value{c.X}
-}
-
-func NewCopyConstraint(x, y ssa.Value) Constraint {
- return &CopyConstraint{
- aConstraint: aConstraint{
- y: y,
- },
- X: x,
- }
-}
diff --git a/vendor/honnef.co/go/tools/stylecheck/analysis.go b/vendor/honnef.co/go/tools/stylecheck/analysis.go
deleted file mode 100644
index f252487f7..000000000
--- a/vendor/honnef.co/go/tools/stylecheck/analysis.go
+++ /dev/null
@@ -1,111 +0,0 @@
-package stylecheck
-
-import (
- "flag"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "honnef.co/go/tools/config"
- "honnef.co/go/tools/facts"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/lint/lintutil"
-)
-
-func newFlagSet() flag.FlagSet {
- fs := flag.NewFlagSet("", flag.PanicOnError)
- fs.Var(lintutil.NewVersionFlag(), "go", "Target Go version")
- return *fs
-}
-
-var Analyzers = map[string]*analysis.Analyzer{
- "ST1000": {
- Name: "ST1000",
- Run: CheckPackageComment,
- Doc: Docs["ST1000"].String(),
- Requires: []*analysis.Analyzer{},
- Flags: newFlagSet(),
- },
- "ST1001": {
- Name: "ST1001",
- Run: CheckDotImports,
- Doc: Docs["ST1001"].String(),
- Requires: []*analysis.Analyzer{facts.Generated, config.Analyzer},
- Flags: newFlagSet(),
- },
- "ST1003": {
- Name: "ST1003",
- Run: CheckNames,
- Doc: Docs["ST1003"].String(),
- Requires: []*analysis.Analyzer{facts.Generated, config.Analyzer},
- Flags: newFlagSet(),
- },
- "ST1005": {
- Name: "ST1005",
- Run: CheckErrorStrings,
- Doc: Docs["ST1005"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "ST1006": {
- Name: "ST1006",
- Run: CheckReceiverNames,
- Doc: Docs["ST1006"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer, facts.Generated},
- Flags: newFlagSet(),
- },
- "ST1008": {
- Name: "ST1008",
- Run: CheckErrorReturn,
- Doc: Docs["ST1008"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "ST1011": {
- Name: "ST1011",
- Run: CheckTimeNames,
- Doc: Docs["ST1011"].String(),
- Flags: newFlagSet(),
- },
- "ST1012": {
- Name: "ST1012",
- Run: CheckErrorVarNames,
- Doc: Docs["ST1012"].String(),
- Requires: []*analysis.Analyzer{config.Analyzer},
- Flags: newFlagSet(),
- },
- "ST1013": {
- Name: "ST1013",
- Run: CheckHTTPStatusCodes,
- Doc: Docs["ST1013"].String(),
- Requires: []*analysis.Analyzer{facts.Generated, facts.TokenFile, config.Analyzer},
- Flags: newFlagSet(),
- },
- "ST1015": {
- Name: "ST1015",
- Run: CheckDefaultCaseOrder,
- Doc: Docs["ST1015"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile},
- Flags: newFlagSet(),
- },
- "ST1016": {
- Name: "ST1016",
- Run: CheckReceiverNamesIdentical,
- Doc: Docs["ST1016"].String(),
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- Flags: newFlagSet(),
- },
- "ST1017": {
- Name: "ST1017",
- Run: CheckYodaConditions,
- Doc: Docs["ST1017"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer, facts.Generated, facts.TokenFile},
- Flags: newFlagSet(),
- },
- "ST1018": {
- Name: "ST1018",
- Run: CheckInvisibleCharacters,
- Doc: Docs["ST1018"].String(),
- Requires: []*analysis.Analyzer{inspect.Analyzer},
- Flags: newFlagSet(),
- },
-}
diff --git a/vendor/honnef.co/go/tools/stylecheck/doc.go b/vendor/honnef.co/go/tools/stylecheck/doc.go
deleted file mode 100644
index 9097214d9..000000000
--- a/vendor/honnef.co/go/tools/stylecheck/doc.go
+++ /dev/null
@@ -1,154 +0,0 @@
-package stylecheck
-
-import "honnef.co/go/tools/lint"
-
-var Docs = map[string]*lint.Documentation{
- "ST1000": &lint.Documentation{
- Title: `Incorrect or missing package comment`,
- Text: `Packages must have a package comment that is formatted according to
-the guidelines laid out in
-https://github.com/golang/go/wiki/CodeReviewComments#package-comments.`,
- Since: "2019.1",
- NonDefault: true,
- },
-
- "ST1001": &lint.Documentation{
- Title: `Dot imports are discouraged`,
- Text: `Dot imports that aren't in external test packages are discouraged.
-
-The dot_import_whitelist option can be used to whitelist certain
-imports.
-
-Quoting Go Code Review Comments:
-
- The import . form can be useful in tests that, due to circular
- dependencies, cannot be made part of the package being tested:
-
- package foo_test
-
- import (
- "bar/testutil" // also imports "foo"
- . "foo"
- )
-
- In this case, the test file cannot be in package foo because it
- uses bar/testutil, which imports foo. So we use the 'import .'
- form to let the file pretend to be part of package foo even though
- it is not. Except for this one case, do not use import . in your
- programs. It makes the programs much harder to read because it is
- unclear whether a name like Quux is a top-level identifier in the
- current package or in an imported package.`,
- Since: "2019.1",
- Options: []string{"dot_import_whitelist"},
- },
-
- "ST1003": &lint.Documentation{
- Title: `Poorly chosen identifier`,
- Text: `Identifiers, such as variable and package names, follow certain rules.
-
-See the following links for details:
-
-- https://golang.org/doc/effective_go.html#package-names
-- https://golang.org/doc/effective_go.html#mixed-caps
-- https://github.com/golang/go/wiki/CodeReviewComments#initialisms
-- https://github.com/golang/go/wiki/CodeReviewComments#variable-names`,
- Since: "2019.1",
- NonDefault: true,
- Options: []string{"initialisms"},
- },
-
- "ST1005": &lint.Documentation{
- Title: `Incorrectly formatted error string`,
- Text: `Error strings follow a set of guidelines to ensure uniformity and good
-composability.
-
-Quoting Go Code Review Comments:
-
- Error strings should not be capitalized (unless beginning with
- proper nouns or acronyms) or end with punctuation, since they are
- usually printed following other context. That is, use
- fmt.Errorf("something bad") not fmt.Errorf("Something bad"), so
- that log.Printf("Reading %s: %v", filename, err) formats without a
- spurious capital letter mid-message.`,
- Since: "2019.1",
- },
-
- "ST1006": &lint.Documentation{
- Title: `Poorly chosen receiver name`,
- Text: `Quoting Go Code Review Comments:
-
- The name of a method's receiver should be a reflection of its
- identity; often a one or two letter abbreviation of its type
- suffices (such as "c" or "cl" for "Client"). Don't use generic
- names such as "me", "this" or "self", identifiers typical of
- object-oriented languages that place more emphasis on methods as
- opposed to functions. The name need not be as descriptive as that
- of a method argument, as its role is obvious and serves no
- documentary purpose. It can be very short as it will appear on
- almost every line of every method of the type; familiarity admits
- brevity. Be consistent, too: if you call the receiver "c" in one
- method, don't call it "cl" in another.`,
- Since: "2019.1",
- },
-
- "ST1008": &lint.Documentation{
- Title: `A function's error value should be its last return value`,
- Text: `A function's error value should be its last return value.`,
- Since: `2019.1`,
- },
-
- "ST1011": &lint.Documentation{
- Title: `Poorly chosen name for variable of type time.Duration`,
- Text: `time.Duration values represent an amount of time, which is represented
-as a count of nanoseconds. An expression like 5 * time.Microsecond
-yields the value 5000. It is therefore not appropriate to suffix a
-variable of type time.Duration with any time unit, such as Msec or
-Milli.`,
- Since: `2019.1`,
- },
-
- "ST1012": &lint.Documentation{
- Title: `Poorly chosen name for error variable`,
- Text: `Error variables that are part of an API should be called errFoo or
-ErrFoo.`,
- Since: "2019.1",
- },
-
- "ST1013": &lint.Documentation{
- Title: `Should use constants for HTTP error codes, not magic numbers`,
- Text: `HTTP has a tremendous number of status codes. While some of those are
-well known (200, 400, 404, 500), most of them are not. The net/http
-package provides constants for all status codes that are part of the
-various specifications. It is recommended to use these constants
-instead of hard-coding magic numbers, to vastly improve the
-readability of your code.`,
- Since: "2019.1",
- Options: []string{"http_status_code_whitelist"},
- },
-
- "ST1015": &lint.Documentation{
- Title: `A switch's default case should be the first or last case`,
- Since: "2019.1",
- },
-
- "ST1016": &lint.Documentation{
- Title: `Use consistent method receiver names`,
- Since: "2019.1",
- NonDefault: true,
- },
-
- "ST1017": &lint.Documentation{
- Title: `Don't use Yoda conditions`,
- Text: `Yoda conditions are conditions of the kind 'if 42 == x', where the
-literal is on the left side of the comparison. These are a common
-idiom in languages in which assignment is an expression, to avoid bugs
-of the kind 'if (x = 42)'. In Go, which doesn't allow for this kind of
-bug, we prefer the more idiomatic 'if x == 42'.`,
- Since: "2019.2",
- },
-
- "ST1018": &lint.Documentation{
- Title: `Avoid zero-width and control characters in string literals`,
- Since: "2019.2",
- },
-}
diff --git a/vendor/honnef.co/go/tools/stylecheck/lint.go b/vendor/honnef.co/go/tools/stylecheck/lint.go
deleted file mode 100644
index 1699d5898..000000000
--- a/vendor/honnef.co/go/tools/stylecheck/lint.go
+++ /dev/null
@@ -1,629 +0,0 @@
-package stylecheck // import "honnef.co/go/tools/stylecheck"
-
-import (
- "fmt"
- "go/ast"
- "go/constant"
- "go/token"
- "go/types"
- "strconv"
- "strings"
- "unicode"
- "unicode/utf8"
-
- "honnef.co/go/tools/config"
- "honnef.co/go/tools/internal/passes/buildssa"
- . "honnef.co/go/tools/lint/lintdsl"
- "honnef.co/go/tools/ssa"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/inspector"
- "golang.org/x/tools/go/types/typeutil"
-)
-
-func CheckPackageComment(pass *analysis.Pass) (interface{}, error) {
- // - At least one file in a non-main package should have a package comment
- //
- // - The comment should be of the form
- // "Package x ...". This has a slight potential for false
- // positives, as multiple files can have package comments, in
- // which case they get appended. But that doesn't happen a lot in
- // the real world.
-
- if pass.Pkg.Name() == "main" {
- return nil, nil
- }
- hasDocs := false
- for _, f := range pass.Files {
- if IsInTest(pass, f) {
- continue
- }
- if f.Doc != nil && len(f.Doc.List) > 0 {
- hasDocs = true
- prefix := "Package " + f.Name.Name + " "
- if !strings.HasPrefix(strings.TrimSpace(f.Doc.Text()), prefix) {
- ReportNodef(pass, f.Doc, `package comment should be of the form "%s..."`, prefix)
- }
- f.Doc.Text()
- }
- }
-
- if !hasDocs {
- for _, f := range pass.Files {
- if IsInTest(pass, f) {
- continue
- }
- ReportNodef(pass, f, "at least one file in a package should have a package comment")
- }
- }
- return nil, nil
-}
-
-func CheckDotImports(pass *analysis.Pass) (interface{}, error) {
- for _, f := range pass.Files {
- imports:
- for _, imp := range f.Imports {
- path := imp.Path.Value
- path = path[1 : len(path)-1]
- for _, w := range config.For(pass).DotImportWhitelist {
- if w == path {
- continue imports
- }
- }
-
- if imp.Name != nil && imp.Name.Name == "." && !IsInTest(pass, f) {
- ReportNodefFG(pass, imp, "should not use dot imports")
- }
- }
- }
- return nil, nil
-}
-
-func CheckBlankImports(pass *analysis.Pass) (interface{}, error) {
- fset := pass.Fset
- for _, f := range pass.Files {
- if IsInMain(pass, f) || IsInTest(pass, f) {
- continue
- }
-
- // Collect imports of the form `import _ "foo"`, i.e. with no
- // parentheses, as their comment will be associated with the
- // (paren-free) GenDecl, not the import spec itself.
- //
- // We don't directly process the GenDecl so that we can
- // correctly handle the following:
- //
- // import _ "foo"
- // import _ "bar"
- //
- // where only the first import should get flagged.
- skip := map[ast.Spec]bool{}
- ast.Inspect(f, func(node ast.Node) bool {
- switch node := node.(type) {
- case *ast.File:
- return true
- case *ast.GenDecl:
- if node.Tok != token.IMPORT {
- return false
- }
- if node.Lparen == token.NoPos && node.Doc != nil {
- skip[node.Specs[0]] = true
- }
- return false
- }
- return false
- })
- for i, imp := range f.Imports {
- pos := fset.Position(imp.Pos())
-
- if !IsBlank(imp.Name) {
- continue
- }
- // Only flag the first blank import in a group of imports,
- // or don't flag any of them, if the first one is
- // commented
- if i > 0 {
- prev := f.Imports[i-1]
- prevPos := fset.Position(prev.Pos())
- if pos.Line-1 == prevPos.Line && IsBlank(prev.Name) {
- continue
- }
- }
-
- if imp.Doc == nil && imp.Comment == nil && !skip[imp] {
- ReportNodef(pass, imp, "a blank import should be only in a main or test package, or have a comment justifying it")
- }
- }
- }
- return nil, nil
-}
-
-func CheckIncDec(pass *analysis.Pass) (interface{}, error) {
- // TODO(dh): this can be noisy for function bodies that look like this:
- // x += 3
- // ...
- // x += 2
- // ...
- // x += 1
- fn := func(node ast.Node) {
- assign := node.(*ast.AssignStmt)
- if assign.Tok != token.ADD_ASSIGN && assign.Tok != token.SUB_ASSIGN {
- return
- }
- if (len(assign.Lhs) != 1 || len(assign.Rhs) != 1) ||
- !IsIntLiteral(assign.Rhs[0], "1") {
- return
- }
-
- suffix := ""
- switch assign.Tok {
- case token.ADD_ASSIGN:
- suffix = "++"
- case token.SUB_ASSIGN:
- suffix = "--"
- }
-
- ReportNodef(pass, assign, "should replace %s with %s%s", Render(pass, assign), Render(pass, assign.Lhs[0]), suffix)
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.AssignStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckErrorReturn(pass *analysis.Pass) (interface{}, error) {
-fnLoop:
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- sig := fn.Type().(*types.Signature)
- rets := sig.Results()
- if rets == nil || rets.Len() < 2 {
- continue
- }
-
- if rets.At(rets.Len()-1).Type() == types.Universe.Lookup("error").Type() {
- // Last return type is error. If the function also returns
- // errors in other positions, that's fine.
- continue
- }
- for i := rets.Len() - 2; i >= 0; i-- {
- if rets.At(i).Type() == types.Universe.Lookup("error").Type() {
- pass.Reportf(rets.At(i).Pos(), "error should be returned as the last argument")
- continue fnLoop
- }
- }
- }
- return nil, nil
-}
-
-// CheckUnexportedReturn checks that exported functions on exported
-// types do not return unexported types.
-func CheckUnexportedReturn(pass *analysis.Pass) (interface{}, error) {
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- if fn.Synthetic != "" || fn.Parent() != nil {
- continue
- }
- if !ast.IsExported(fn.Name()) || IsInMain(pass, fn) || IsInTest(pass, fn) {
- continue
- }
- sig := fn.Type().(*types.Signature)
- if sig.Recv() != nil && !ast.IsExported(Dereference(sig.Recv().Type()).(*types.Named).Obj().Name()) {
- continue
- }
- res := sig.Results()
- for i := 0; i < res.Len(); i++ {
- if named, ok := DereferenceR(res.At(i).Type()).(*types.Named); ok &&
- !ast.IsExported(named.Obj().Name()) &&
- named != types.Universe.Lookup("error").Type() {
- pass.Reportf(fn.Pos(), "should not return unexported type")
- }
- }
- }
- return nil, nil
-}
-
-func CheckReceiverNames(pass *analysis.Pass) (interface{}, error) {
- ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).Pkg
- for _, m := range ssapkg.Members {
- if T, ok := m.Object().(*types.TypeName); ok && !T.IsAlias() {
- ms := typeutil.IntuitiveMethodSet(T.Type(), nil)
- for _, sel := range ms {
- fn := sel.Obj().(*types.Func)
- recv := fn.Type().(*types.Signature).Recv()
- if Dereference(recv.Type()) != T.Type() {
- // skip embedded methods
- continue
- }
- if recv.Name() == "self" || recv.Name() == "this" {
- ReportfFG(pass, recv.Pos(), `receiver name should be a reflection of its identity; don't use generic names such as "this" or "self"`)
- }
- if recv.Name() == "_" {
- ReportfFG(pass, recv.Pos(), "receiver name should not be an underscore, omit the name if it is unused")
- }
- }
- }
- }
- return nil, nil
-}
-
-func CheckReceiverNamesIdentical(pass *analysis.Pass) (interface{}, error) {
- ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).Pkg
- for _, m := range ssapkg.Members {
- names := map[string]int{}
-
- var firstFn *types.Func
- if T, ok := m.Object().(*types.TypeName); ok && !T.IsAlias() {
- ms := typeutil.IntuitiveMethodSet(T.Type(), nil)
- for _, sel := range ms {
- fn := sel.Obj().(*types.Func)
- recv := fn.Type().(*types.Signature).Recv()
- if Dereference(recv.Type()) != T.Type() {
- // skip embedded methods
- continue
- }
- if firstFn == nil {
- firstFn = fn
- }
- if recv.Name() != "" && recv.Name() != "_" {
- names[recv.Name()]++
- }
- }
- }
-
- if len(names) > 1 {
- var seen []string
- for name, count := range names {
- seen = append(seen, fmt.Sprintf("%dx %q", count, name))
- }
-
- pass.Reportf(firstFn.Pos(), "methods on the same type should have the same receiver name (seen %s)", strings.Join(seen, ", "))
- }
- }
- return nil, nil
-}
-
-func CheckContextFirstArg(pass *analysis.Pass) (interface{}, error) {
- // TODO(dh): this check doesn't apply to test helpers. Example from the stdlib:
- // func helperCommandContext(t *testing.T, ctx context.Context, s ...string) (cmd *exec.Cmd) {
-fnLoop:
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- if fn.Synthetic != "" || fn.Parent() != nil {
- continue
- }
- params := fn.Signature.Params()
- if params.Len() < 2 {
- continue
- }
- if types.TypeString(params.At(0).Type(), nil) == "context.Context" {
- continue
- }
- for i := 1; i < params.Len(); i++ {
- param := params.At(i)
- if types.TypeString(param.Type(), nil) == "context.Context" {
- pass.Reportf(param.Pos(), "context.Context should be the first argument of a function")
- continue fnLoop
- }
- }
- }
- return nil, nil
-}
-
-func CheckErrorStrings(pass *analysis.Pass) (interface{}, error) {
- objNames := map[*ssa.Package]map[string]bool{}
- ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).Pkg
- objNames[ssapkg] = map[string]bool{}
- for _, m := range ssapkg.Members {
- if typ, ok := m.(*ssa.Type); ok {
- objNames[ssapkg][typ.Name()] = true
- }
- }
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- objNames[fn.Package()][fn.Name()] = true
- }
-
- for _, fn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
- if IsInTest(pass, fn) {
- // We don't care about malformed error messages in tests;
- // they're usually for direct human consumption, not part
- // of an API
- continue
- }
- for _, block := range fn.Blocks {
- instrLoop:
- for _, ins := range block.Instrs {
- call, ok := ins.(*ssa.Call)
- if !ok {
- continue
- }
- if !IsCallTo(call.Common(), "errors.New") && !IsCallTo(call.Common(), "fmt.Errorf") {
- continue
- }
-
- k, ok := call.Common().Args[0].(*ssa.Const)
- if !ok {
- continue
- }
-
- s := constant.StringVal(k.Value)
- if len(s) == 0 {
- continue
- }
- switch s[len(s)-1] {
- case '.', ':', '!', '\n':
- pass.Reportf(call.Pos(), "error strings should not end with punctuation or a newline")
- }
- idx := strings.IndexByte(s, ' ')
- if idx == -1 {
- // single word error message, probably not a real
- // error but something used in tests or during
- // debugging
- continue
- }
- word := s[:idx]
- first, n := utf8.DecodeRuneInString(word)
- if !unicode.IsUpper(first) {
- continue
- }
- for _, c := range word[n:] {
- if unicode.IsUpper(c) {
- // Word is probably an initialism or
- // multi-word function name
- continue instrLoop
- }
- }
-
- word = strings.TrimRightFunc(word, func(r rune) bool { return unicode.IsPunct(r) })
- if objNames[fn.Package()][word] {
- // Word is probably the name of a function or type in this package
- continue
- }
- // First word in error starts with a capital
- // letter, and the word doesn't contain any other
- // capitals, making it unlikely to be an
- // initialism or multi-word function name.
- //
- // It could still be a proper noun, though.
-
- pass.Reportf(call.Pos(), "error strings should not be capitalized")
- }
- }
- }
- return nil, nil
-}
-
-func CheckTimeNames(pass *analysis.Pass) (interface{}, error) {
- suffixes := []string{
- "Sec", "Secs", "Seconds",
- "Msec", "Msecs",
- "Milli", "Millis", "Milliseconds",
- "Usec", "Usecs", "Microseconds",
- "MS", "Ms",
- }
- fn := func(T types.Type, names []*ast.Ident) {
- if !IsType(T, "time.Duration") && !IsType(T, "*time.Duration") {
- return
- }
- for _, name := range names {
- for _, suffix := range suffixes {
- if strings.HasSuffix(name.Name, suffix) {
- ReportNodef(pass, name, "var %s is of type %v; don't use unit-specific suffix %q", name.Name, T, suffix)
- break
- }
- }
- }
- }
- for _, f := range pass.Files {
- ast.Inspect(f, func(node ast.Node) bool {
- switch node := node.(type) {
- case *ast.ValueSpec:
- T := pass.TypesInfo.TypeOf(node.Type)
- fn(T, node.Names)
- case *ast.FieldList:
- for _, field := range node.List {
- T := pass.TypesInfo.TypeOf(field.Type)
- fn(T, field.Names)
- }
- }
- return true
- })
- }
- return nil, nil
-}
-
-func CheckErrorVarNames(pass *analysis.Pass) (interface{}, error) {
- for _, f := range pass.Files {
- for _, decl := range f.Decls {
- gen, ok := decl.(*ast.GenDecl)
- if !ok || gen.Tok != token.VAR {
- continue
- }
- for _, spec := range gen.Specs {
- spec := spec.(*ast.ValueSpec)
- if len(spec.Names) != len(spec.Values) {
- continue
- }
-
- for i, name := range spec.Names {
- val := spec.Values[i]
- if !IsCallToAST(pass, val, "errors.New") && !IsCallToAST(pass, val, "fmt.Errorf") {
- continue
- }
-
- prefix := "err"
- if name.IsExported() {
- prefix = "Err"
- }
- if !strings.HasPrefix(name.Name, prefix) {
- ReportNodef(pass, name, "error var %s should have name of the form %sFoo", name.Name, prefix)
- }
- }
- }
- }
- }
- return nil, nil
-}
-
-var httpStatusCodes = map[int]string{
- 100: "StatusContinue",
- 101: "StatusSwitchingProtocols",
- 102: "StatusProcessing",
- 200: "StatusOK",
- 201: "StatusCreated",
- 202: "StatusAccepted",
- 203: "StatusNonAuthoritativeInfo",
- 204: "StatusNoContent",
- 205: "StatusResetContent",
- 206: "StatusPartialContent",
- 207: "StatusMultiStatus",
- 208: "StatusAlreadyReported",
- 226: "StatusIMUsed",
- 300: "StatusMultipleChoices",
- 301: "StatusMovedPermanently",
- 302: "StatusFound",
- 303: "StatusSeeOther",
- 304: "StatusNotModified",
- 305: "StatusUseProxy",
- 307: "StatusTemporaryRedirect",
- 308: "StatusPermanentRedirect",
- 400: "StatusBadRequest",
- 401: "StatusUnauthorized",
- 402: "StatusPaymentRequired",
- 403: "StatusForbidden",
- 404: "StatusNotFound",
- 405: "StatusMethodNotAllowed",
- 406: "StatusNotAcceptable",
- 407: "StatusProxyAuthRequired",
- 408: "StatusRequestTimeout",
- 409: "StatusConflict",
- 410: "StatusGone",
- 411: "StatusLengthRequired",
- 412: "StatusPreconditionFailed",
- 413: "StatusRequestEntityTooLarge",
- 414: "StatusRequestURITooLong",
- 415: "StatusUnsupportedMediaType",
- 416: "StatusRequestedRangeNotSatisfiable",
- 417: "StatusExpectationFailed",
- 418: "StatusTeapot",
- 422: "StatusUnprocessableEntity",
- 423: "StatusLocked",
- 424: "StatusFailedDependency",
- 426: "StatusUpgradeRequired",
- 428: "StatusPreconditionRequired",
- 429: "StatusTooManyRequests",
- 431: "StatusRequestHeaderFieldsTooLarge",
- 451: "StatusUnavailableForLegalReasons",
- 500: "StatusInternalServerError",
- 501: "StatusNotImplemented",
- 502: "StatusBadGateway",
- 503: "StatusServiceUnavailable",
- 504: "StatusGatewayTimeout",
- 505: "StatusHTTPVersionNotSupported",
- 506: "StatusVariantAlsoNegotiates",
- 507: "StatusInsufficientStorage",
- 508: "StatusLoopDetected",
- 510: "StatusNotExtended",
- 511: "StatusNetworkAuthenticationRequired",
-}
-
-func CheckHTTPStatusCodes(pass *analysis.Pass) (interface{}, error) {
- whitelist := map[string]bool{}
- for _, code := range config.For(pass).HTTPStatusCodeWhitelist {
- whitelist[code] = true
- }
- fn := func(node ast.Node) bool {
- if node == nil {
- return true
- }
- call, ok := node.(*ast.CallExpr)
- if !ok {
- return true
- }
-
- var arg int
- switch CallNameAST(pass, call) {
- case "net/http.Error":
- arg = 2
- case "net/http.Redirect":
- arg = 3
- case "net/http.StatusText":
- arg = 0
- case "net/http.RedirectHandler":
- arg = 1
- default:
- return true
- }
- lit, ok := call.Args[arg].(*ast.BasicLit)
- if !ok {
- return true
- }
- if whitelist[lit.Value] {
- return true
- }
-
- n, err := strconv.Atoi(lit.Value)
- if err != nil {
- return true
- }
- s, ok := httpStatusCodes[n]
- if !ok {
- return true
- }
- ReportNodefFG(pass, lit, "should use constant http.%s instead of numeric literal %d", s, n)
- return true
- }
- // OPT(dh): replace with inspector
- for _, f := range pass.Files {
- ast.Inspect(f, fn)
- }
- return nil, nil
-}
-
-func CheckDefaultCaseOrder(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- stmt := node.(*ast.SwitchStmt)
- list := stmt.Body.List
- for i, c := range list {
- if c.(*ast.CaseClause).List == nil && i != 0 && i != len(list)-1 {
- ReportNodefFG(pass, c, "default case should be first or last in switch statement")
- break
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.SwitchStmt)(nil)}, fn)
- return nil, nil
-}
-
-func CheckYodaConditions(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- cond := node.(*ast.BinaryExpr)
- if cond.Op != token.EQL && cond.Op != token.NEQ {
- return
- }
- if _, ok := cond.X.(*ast.BasicLit); !ok {
- return
- }
- if _, ok := cond.Y.(*ast.BasicLit); ok {
- // Don't flag lit == lit conditions, just in case
- return
- }
- ReportNodefFG(pass, cond, "don't use Yoda conditions")
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BinaryExpr)(nil)}, fn)
- return nil, nil
-}
-
-func CheckInvisibleCharacters(pass *analysis.Pass) (interface{}, error) {
- fn := func(node ast.Node) {
- lit := node.(*ast.BasicLit)
- if lit.Kind != token.STRING {
- return
- }
- for _, r := range lit.Value {
- if unicode.Is(unicode.Cf, r) {
- ReportNodef(pass, lit, "string literal contains the Unicode format character %U, consider using the %q escape sequence", r, r)
- } else if unicode.Is(unicode.Cc, r) && r != '\n' && r != '\t' && r != '\r' {
- ReportNodef(pass, lit, "string literal contains the Unicode control character %U, consider using the %q escape sequence", r, r)
- }
- }
- }
- pass.ResultOf[inspect.Analyzer].(*inspector.Inspector).Preorder([]ast.Node{(*ast.BasicLit)(nil)}, fn)
- return nil, nil
-}
diff --git a/vendor/honnef.co/go/tools/stylecheck/names.go b/vendor/honnef.co/go/tools/stylecheck/names.go
deleted file mode 100644
index 160f9d7ff..000000000
--- a/vendor/honnef.co/go/tools/stylecheck/names.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright (c) 2013 The Go Authors. All rights reserved.
-// Copyright (c) 2018 Dominik Honnef. All rights reserved.
-
-package stylecheck
-
-import (
- "go/ast"
- "go/token"
- "strings"
- "unicode"
-
- "golang.org/x/tools/go/analysis"
- "honnef.co/go/tools/config"
- . "honnef.co/go/tools/lint/lintdsl"
-)
-
-// knownNameExceptions is a set of names that are known to be exempt from naming checks.
-// This is usually because they are constrained by having to match names in the
-// standard library.
-var knownNameExceptions = map[string]bool{
- "LastInsertId": true, // must match database/sql
- "kWh": true,
-}
-
-func CheckNames(pass *analysis.Pass) (interface{}, error) {
- // A large part of this function is copied from
- // github.com/golang/lint, Copyright (c) 2013 The Go Authors,
- // licensed under the BSD 3-clause license.
-
- allCaps := func(s string) bool {
- for _, r := range s {
- if !((r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_') {
- return false
- }
- }
- return true
- }
-
- check := func(id *ast.Ident, thing string, initialisms map[string]bool) {
- if id.Name == "_" {
- return
- }
- if knownNameExceptions[id.Name] {
- return
- }
-
- // Handle two common styles from other languages that don't belong in Go.
- if len(id.Name) >= 5 && allCaps(id.Name) && strings.Contains(id.Name, "_") {
- ReportfFG(pass, id.Pos(), "should not use ALL_CAPS in Go names; use CamelCase instead")
- return
- }
-
- should := lintName(id.Name, initialisms)
- if id.Name == should {
- return
- }
-
- if len(id.Name) > 2 && strings.Contains(id.Name[1:len(id.Name)-1], "_") {
- ReportfFG(pass, id.Pos(), "should not use underscores in Go names; %s %s should be %s", thing, id.Name, should)
- return
- }
- ReportfFG(pass, id.Pos(), "%s %s should be %s", thing, id.Name, should)
- }
- checkList := func(fl *ast.FieldList, thing string, initialisms map[string]bool) {
- if fl == nil {
- return
- }
- for _, f := range fl.List {
- for _, id := range f.Names {
- check(id, thing, initialisms)
- }
- }
- }
-
- il := config.For(pass).Initialisms
- initialisms := make(map[string]bool, len(il))
- for _, word := range il {
- initialisms[word] = true
- }
- for _, f := range pass.Files {
- // Package names need slightly different handling than other names.
- if !strings.HasSuffix(f.Name.Name, "_test") && strings.Contains(f.Name.Name, "_") {
- ReportfFG(pass, f.Pos(), "should not use underscores in package names")
- }
- if strings.IndexFunc(f.Name.Name, unicode.IsUpper) != -1 {
- ReportfFG(pass, f.Pos(), "should not use MixedCaps in package name; %s should be %s", f.Name.Name, strings.ToLower(f.Name.Name))
- }
-
- ast.Inspect(f, func(node ast.Node) bool {
- switch v := node.(type) {
- case *ast.AssignStmt:
- if v.Tok != token.DEFINE {
- return true
- }
- for _, exp := range v.Lhs {
- if id, ok := exp.(*ast.Ident); ok {
- check(id, "var", initialisms)
- }
- }
- case *ast.FuncDecl:
- // Functions with no body are defined elsewhere (in
- // assembly, or via go:linkname). These are likely to
- // be something very low level (such as the runtime),
- // where our rules don't apply.
- if v.Body == nil {
- return true
- }
-
- if IsInTest(pass, v) && (strings.HasPrefix(v.Name.Name, "Example") || strings.HasPrefix(v.Name.Name, "Test") || strings.HasPrefix(v.Name.Name, "Benchmark")) {
- return true
- }
-
- thing := "func"
- if v.Recv != nil {
- thing = "method"
- }
-
- if !isTechnicallyExported(v) {
- check(v.Name, thing, initialisms)
- }
-
- checkList(v.Type.Params, thing+" parameter", initialisms)
- checkList(v.Type.Results, thing+" result", initialisms)
- case *ast.GenDecl:
- if v.Tok == token.IMPORT {
- return true
- }
- var thing string
- switch v.Tok {
- case token.CONST:
- thing = "const"
- case token.TYPE:
- thing = "type"
- case token.VAR:
- thing = "var"
- }
- for _, spec := range v.Specs {
- switch s := spec.(type) {
- case *ast.TypeSpec:
- check(s.Name, thing, initialisms)
- case *ast.ValueSpec:
- for _, id := range s.Names {
- check(id, thing, initialisms)
- }
- }
- }
- case *ast.InterfaceType:
- // Do not check interface method names.
- // They are often constrainted by the method names of concrete types.
- for _, x := range v.Methods.List {
- ft, ok := x.Type.(*ast.FuncType)
- if !ok { // might be an embedded interface name
- continue
- }
- checkList(ft.Params, "interface method parameter", initialisms)
- checkList(ft.Results, "interface method result", initialisms)
- }
- case *ast.RangeStmt:
- if v.Tok == token.ASSIGN {
- return true
- }
- if id, ok := v.Key.(*ast.Ident); ok {
- check(id, "range var", initialisms)
- }
- if id, ok := v.Value.(*ast.Ident); ok {
- check(id, "range var", initialisms)
- }
- case *ast.StructType:
- for _, f := range v.Fields.List {
- for _, id := range f.Names {
- check(id, "struct field", initialisms)
- }
- }
- }
- return true
- })
- }
- return nil, nil
-}
-
-// lintName returns a different name if it should be different.
-func lintName(name string, initialisms map[string]bool) (should string) {
- // A large part of this function is copied from
- // github.com/golang/lint, Copyright (c) 2013 The Go Authors,
- // licensed under the BSD 3-clause license.
-
- // Fast path for simple cases: "_" and all lowercase.
- if name == "_" {
- return name
- }
- if strings.IndexFunc(name, func(r rune) bool { return !unicode.IsLower(r) }) == -1 {
- return name
- }
-
- // Split camelCase at any lower->upper transition, and split on underscores.
- // Check each word for common initialisms.
- runes := []rune(name)
- w, i := 0, 0 // index of start of word, scan
- for i+1 <= len(runes) {
- eow := false // whether we hit the end of a word
- if i+1 == len(runes) {
- eow = true
- } else if runes[i+1] == '_' && i+1 != len(runes)-1 {
- // underscore; shift the remainder forward over any run of underscores
- eow = true
- n := 1
- for i+n+1 < len(runes) && runes[i+n+1] == '_' {
- n++
- }
-
- // Leave at most one underscore if the underscore is between two digits
- if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
- n--
- }
-
- copy(runes[i+1:], runes[i+n+1:])
- runes = runes[:len(runes)-n]
- } else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
- // lower->non-lower
- eow = true
- }
- i++
- if !eow {
- continue
- }
-
- // [w,i) is a word.
- word := string(runes[w:i])
- if u := strings.ToUpper(word); initialisms[u] {
- // Keep consistent case, which is lowercase only at the start.
- if w == 0 && unicode.IsLower(runes[w]) {
- u = strings.ToLower(u)
- }
- // All the common initialisms are ASCII,
- // so we can replace the bytes exactly.
- // TODO(dh): this won't be true once we allow custom initialisms
- copy(runes[w:], []rune(u))
- } else if w > 0 && strings.ToLower(word) == word {
- // already all lowercase, and not the first word, so uppercase the first character.
- runes[w] = unicode.ToUpper(runes[w])
- }
- w = i
- }
- return string(runes)
-}
-
-func isTechnicallyExported(f *ast.FuncDecl) bool {
- if f.Recv != nil || f.Doc == nil {
- return false
- }
-
- const export = "//export "
- const linkname = "//go:linkname "
- for _, c := range f.Doc.List {
- if strings.HasPrefix(c.Text, export) && len(c.Text) == len(export)+len(f.Name.Name) && c.Text[len(export):] == f.Name.Name {
- return true
- }
-
- if strings.HasPrefix(c.Text, linkname) {
- return true
- }
- }
- return false
-}
diff --git a/vendor/honnef.co/go/tools/unused/edge.go b/vendor/honnef.co/go/tools/unused/edge.go
deleted file mode 100644
index 02e0d09cf..000000000
--- a/vendor/honnef.co/go/tools/unused/edge.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package unused
-
-//go:generate stringer -type edgeKind
-type edgeKind uint64
-
-func (e edgeKind) is(o edgeKind) bool {
- return e&o != 0
-}
-
-const (
- edgeAlias edgeKind = 1 << iota
- edgeBlankField
- edgeAnonymousStruct
- edgeCgoExported
- edgeConstGroup
- edgeElementType
- edgeEmbeddedInterface
- edgeExportedConstant
- edgeExportedField
- edgeExportedFunction
- edgeExportedMethod
- edgeExportedType
- edgeExportedVariable
- edgeExtendsExportedFields
- edgeExtendsExportedMethodSet
- edgeFieldAccess
- edgeFunctionArgument
- edgeFunctionResult
- edgeFunctionSignature
- edgeImplements
- edgeInstructionOperand
- edgeInterfaceCall
- edgeInterfaceMethod
- edgeKeyType
- edgeLinkname
- edgeMainFunction
- edgeNamedType
- edgeNetRPCRegister
- edgeNoCopySentinel
- edgeProvidesMethod
- edgeReceiver
- edgeRuntimeFunction
- edgeSignature
- edgeStructConversion
- edgeTestSink
- edgeTupleElement
- edgeType
- edgeTypeName
- edgeUnderlyingType
- edgePointerType
- edgeUnsafeConversion
- edgeUsedConstant
- edgeVarDecl
-)
diff --git a/vendor/honnef.co/go/tools/unused/edgekind_string.go b/vendor/honnef.co/go/tools/unused/edgekind_string.go
deleted file mode 100644
index 7629636cf..000000000
--- a/vendor/honnef.co/go/tools/unused/edgekind_string.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Code generated by "stringer -type edgeKind"; DO NOT EDIT.
-
-package unused
-
-import "strconv"
-
-func _() {
- // An "invalid array index" compiler error signifies that the constant values have changed.
- // Re-run the stringer command to generate them again.
- var x [1]struct{}
- _ = x[edgeAlias-1]
- _ = x[edgeBlankField-2]
- _ = x[edgeAnonymousStruct-4]
- _ = x[edgeCgoExported-8]
- _ = x[edgeConstGroup-16]
- _ = x[edgeElementType-32]
- _ = x[edgeEmbeddedInterface-64]
- _ = x[edgeExportedConstant-128]
- _ = x[edgeExportedField-256]
- _ = x[edgeExportedFunction-512]
- _ = x[edgeExportedMethod-1024]
- _ = x[edgeExportedType-2048]
- _ = x[edgeExportedVariable-4096]
- _ = x[edgeExtendsExportedFields-8192]
- _ = x[edgeExtendsExportedMethodSet-16384]
- _ = x[edgeFieldAccess-32768]
- _ = x[edgeFunctionArgument-65536]
- _ = x[edgeFunctionResult-131072]
- _ = x[edgeFunctionSignature-262144]
- _ = x[edgeImplements-524288]
- _ = x[edgeInstructionOperand-1048576]
- _ = x[edgeInterfaceCall-2097152]
- _ = x[edgeInterfaceMethod-4194304]
- _ = x[edgeKeyType-8388608]
- _ = x[edgeLinkname-16777216]
- _ = x[edgeMainFunction-33554432]
- _ = x[edgeNamedType-67108864]
- _ = x[edgeNetRPCRegister-134217728]
- _ = x[edgeNoCopySentinel-268435456]
- _ = x[edgeProvidesMethod-536870912]
- _ = x[edgeReceiver-1073741824]
- _ = x[edgeRuntimeFunction-2147483648]
- _ = x[edgeSignature-4294967296]
- _ = x[edgeStructConversion-8589934592]
- _ = x[edgeTestSink-17179869184]
- _ = x[edgeTupleElement-34359738368]
- _ = x[edgeType-68719476736]
- _ = x[edgeTypeName-137438953472]
- _ = x[edgeUnderlyingType-274877906944]
- _ = x[edgePointerType-549755813888]
- _ = x[edgeUnsafeConversion-1099511627776]
- _ = x[edgeUsedConstant-2199023255552]
- _ = x[edgeVarDecl-4398046511104]
-}
-
-const _edgeKind_name = "edgeAliasedgeBlankFieldedgeAnonymousStructedgeCgoExportededgeConstGroupedgeElementTypeedgeEmbeddedInterfaceedgeExportedConstantedgeExportedFieldedgeExportedFunctionedgeExportedMethodedgeExportedTypeedgeExportedVariableedgeExtendsExportedFieldsedgeExtendsExportedMethodSetedgeFieldAccessedgeFunctionArgumentedgeFunctionResultedgeFunctionSignatureedgeImplementsedgeInstructionOperandedgeInterfaceCalledgeInterfaceMethodedgeKeyTypeedgeLinknameedgeMainFunctionedgeNamedTypeedgeNetRPCRegisteredgeNoCopySentineledgeProvidesMethodedgeReceiveredgeRuntimeFunctionedgeSignatureedgeStructConversionedgeTestSinkedgeTupleElementedgeTypeedgeTypeNameedgeUnderlyingTypeedgePointerTypeedgeUnsafeConversionedgeUsedConstantedgeVarDecl"
-
-var _edgeKind_map = map[edgeKind]string{
- 1: _edgeKind_name[0:9],
- 2: _edgeKind_name[9:23],
- 4: _edgeKind_name[23:42],
- 8: _edgeKind_name[42:57],
- 16: _edgeKind_name[57:71],
- 32: _edgeKind_name[71:86],
- 64: _edgeKind_name[86:107],
- 128: _edgeKind_name[107:127],
- 256: _edgeKind_name[127:144],
- 512: _edgeKind_name[144:164],
- 1024: _edgeKind_name[164:182],
- 2048: _edgeKind_name[182:198],
- 4096: _edgeKind_name[198:218],
- 8192: _edgeKind_name[218:243],
- 16384: _edgeKind_name[243:271],
- 32768: _edgeKind_name[271:286],
- 65536: _edgeKind_name[286:306],
- 131072: _edgeKind_name[306:324],
- 262144: _edgeKind_name[324:345],
- 524288: _edgeKind_name[345:359],
- 1048576: _edgeKind_name[359:381],
- 2097152: _edgeKind_name[381:398],
- 4194304: _edgeKind_name[398:417],
- 8388608: _edgeKind_name[417:428],
- 16777216: _edgeKind_name[428:440],
- 33554432: _edgeKind_name[440:456],
- 67108864: _edgeKind_name[456:469],
- 134217728: _edgeKind_name[469:487],
- 268435456: _edgeKind_name[487:505],
- 536870912: _edgeKind_name[505:523],
- 1073741824: _edgeKind_name[523:535],
- 2147483648: _edgeKind_name[535:554],
- 4294967296: _edgeKind_name[554:567],
- 8589934592: _edgeKind_name[567:587],
- 17179869184: _edgeKind_name[587:599],
- 34359738368: _edgeKind_name[599:615],
- 68719476736: _edgeKind_name[615:623],
- 137438953472: _edgeKind_name[623:635],
- 274877906944: _edgeKind_name[635:653],
- 549755813888: _edgeKind_name[653:668],
- 1099511627776: _edgeKind_name[668:688],
- 2199023255552: _edgeKind_name[688:704],
- 4398046511104: _edgeKind_name[704:715],
-}
-
-func (i edgeKind) String() string {
- if str, ok := _edgeKind_map[i]; ok {
- return str
- }
- return "edgeKind(" + strconv.FormatInt(int64(i), 10) + ")"
-}
diff --git a/vendor/honnef.co/go/tools/unused/implements.go b/vendor/honnef.co/go/tools/unused/implements.go
deleted file mode 100644
index 835baac69..000000000
--- a/vendor/honnef.co/go/tools/unused/implements.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package unused
-
-import "go/types"
-
-// lookupMethod returns the index of and method with matching package and name, or (-1, nil).
-func lookupMethod(T *types.Interface, pkg *types.Package, name string) (int, *types.Func) {
- if name != "_" {
- for i := 0; i < T.NumMethods(); i++ {
- m := T.Method(i)
- if sameId(m, pkg, name) {
- return i, m
- }
- }
- }
- return -1, nil
-}
-
-func sameId(obj types.Object, pkg *types.Package, name string) bool {
- // spec:
- // "Two identifiers are different if they are spelled differently,
- // or if they appear in different packages and are not exported.
- // Otherwise, they are the same."
- if name != obj.Name() {
- return false
- }
- // obj.Name == name
- if obj.Exported() {
- return true
- }
- // not exported, so packages must be the same (pkg == nil for
- // fields in Universe scope; this can only happen for types
- // introduced via Eval)
- if pkg == nil || obj.Pkg() == nil {
- return pkg == obj.Pkg()
- }
- // pkg != nil && obj.pkg != nil
- return pkg.Path() == obj.Pkg().Path()
-}
-
-func (g *Graph) implements(V types.Type, T *types.Interface, msV *types.MethodSet) ([]*types.Selection, bool) {
- // fast path for common case
- if T.Empty() {
- return nil, true
- }
-
- if ityp, _ := V.Underlying().(*types.Interface); ityp != nil {
- // TODO(dh): is this code reachable?
- for i := 0; i < T.NumMethods(); i++ {
- m := T.Method(i)
- _, obj := lookupMethod(ityp, m.Pkg(), m.Name())
- switch {
- case obj == nil:
- return nil, false
- case !types.Identical(obj.Type(), m.Type()):
- return nil, false
- }
- }
- return nil, true
- }
-
- // A concrete type implements T if it implements all methods of T.
- var sels []*types.Selection
- for i := 0; i < T.NumMethods(); i++ {
- m := T.Method(i)
- sel := msV.Lookup(m.Pkg(), m.Name())
- if sel == nil {
- return nil, false
- }
-
- f, _ := sel.Obj().(*types.Func)
- if f == nil {
- return nil, false
- }
-
- if !types.Identical(f.Type(), m.Type()) {
- return nil, false
- }
-
- sels = append(sels, sel)
- }
- return sels, true
-}
diff --git a/vendor/honnef.co/go/tools/unused/unused.go b/vendor/honnef.co/go/tools/unused/unused.go
deleted file mode 100644
index 152d3692d..000000000
--- a/vendor/honnef.co/go/tools/unused/unused.go
+++ /dev/null
@@ -1,1964 +0,0 @@
-package unused
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "go/types"
- "io"
- "strings"
- "sync"
- "sync/atomic"
-
- "golang.org/x/tools/go/analysis"
- "honnef.co/go/tools/go/types/typeutil"
- "honnef.co/go/tools/internal/passes/buildssa"
- "honnef.co/go/tools/lint"
- "honnef.co/go/tools/lint/lintdsl"
- "honnef.co/go/tools/ssa"
-)
-
-// The graph we construct omits nodes along a path that do not
-// contribute any new information to the solution. For example, the
-// full graph for a function with a receiver would be Func ->
-// Signature -> Var -> Type. However, since signatures cannot be
-// unused, and receivers are always considered used, we can compact
-// the graph down to Func -> Type. This makes the graph smaller, but
-// harder to debug.
-
-// TODO(dh): conversions between structs mark fields as used, but the
-// conversion itself isn't part of that subgraph. even if the function
-// containing the conversion is unused, the fields will be marked as
-// used.
-
-// TODO(dh): we cannot observe function calls in assembly files.
-
-/*
-
-- packages use:
- - (1.1) exported named types (unless in package main)
- - (1.2) exported functions (unless in package main)
- - (1.3) exported variables (unless in package main)
- - (1.4) exported constants (unless in package main)
- - (1.5) init functions
- - (1.6) functions exported to cgo
- - (1.7) the main function iff in the main package
- - (1.8) symbols linked via go:linkname
-
-- named types use:
- - (2.1) exported methods
- - (2.2) the type they're based on
- - (2.3) all their aliases. we can't easily track uses of aliases
- because go/types turns them into uses of the aliased types. assume
- that if a type is used, so are all of its aliases.
- - (2.4) the pointer type. this aids with eagerly implementing
- interfaces. if a method that implements an interface is defined on
- a pointer receiver, and the pointer type is never used, but the
- named type is, then we still want to mark the method as used.
-
-- variables and constants use:
- - their types
-
-- functions use:
- - (4.1) all their arguments, return parameters and receivers
- - (4.2) anonymous functions defined beneath them
- - (4.3) closures and bound methods.
- this implements a simplified model where a function is used merely by being referenced, even if it is never called.
- that way we don't have to keep track of closures escaping functions.
- - (4.4) functions they return. we assume that someone else will call the returned function
- - (4.5) functions/interface methods they call
- - types they instantiate or convert to
- - (4.7) fields they access
- - (4.8) types of all instructions
- - (4.9) package-level variables they assign to iff in tests (sinks for benchmarks)
-
-- conversions use:
- - (5.1) when converting between two equivalent structs, the fields in
- either struct use each other. the fields are relevant for the
- conversion, but only if the fields are also accessed outside the
- conversion.
- - (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
-
-- structs use:
- - (6.1) fields of type NoCopy sentinel
- - (6.2) exported fields
- - (6.3) embedded fields that help implement interfaces (either fully implements it, or contributes required methods) (recursively)
- - (6.4) embedded fields that have exported methods (recursively)
- - (6.5) embedded structs that have exported fields (recursively)
-
-- (7.1) field accesses use fields
-- (7.2) fields use their types
-
-- (8.0) How we handle interfaces:
- - (8.1) We do not technically care about interfaces that only consist of
- exported methods. Exported methods on concrete types are always
- marked as used.
- - Any concrete type implements all known interfaces. Even if it isn't
- assigned to any interfaces in our code, the user may receive a value
- of the type and expect to pass it back to us through an interface.
-
- Concrete types use their methods that implement interfaces. If the
- type is used, it uses those methods. Otherwise, it doesn't. This
- way, types aren't incorrectly marked reachable through the edge
- from method to type.
-
- - (8.3) All interface methods are marked as used, even if they never get
- called. This is to accomodate sum types (unexported interface
- method that must exist but never gets called.)
-
- - (8.4) All embedded interfaces are marked as used. This is an
- extension of 8.3, but we have to explicitly track embedded
- interfaces because in a chain C->B->A, B wouldn't be marked as
- used by 8.3 just because it contributes A's methods to C.
-
-- Inherent uses:
- - thunks and other generated wrappers call the real function
- - (9.2) variables use their types
- - (9.3) types use their underlying and element types
- - (9.4) conversions use the type they convert to
- - (9.5) instructions use their operands
- - (9.6) instructions use their operands' types
- - (9.7) variable _reads_ use variables, writes do not, except in tests
- - (9.8) runtime functions that may be called from user code via the compiler
-
-
-- const groups:
- (10.1) if one constant out of a block of constants is used, mark all
- of them used. a lot of the time, unused constants exist for the sake
- of completeness. See also
- https://github.com/dominikh/go-tools/issues/365
-
-
-- (11.1) anonymous struct types use all their fields. we cannot
- deduplicate struct types, as that leads to order-dependent
- reportings. we can't not deduplicate struct types while still
- tracking fields, because then each instance of the unnamed type in
- the data flow chain will get its own fields, causing false
- positives. Thus, we only accurately track fields of named struct
- types, and assume that unnamed struct types use all their fields.
-
-
-- Differences in whole program mode:
- - (e2) types aim to implement all exported interfaces from all packages
- - (e3) exported identifiers aren't automatically used. for fields and
- methods this poses extra issues due to reflection. We assume
- that all exported fields are used. We also maintain a list of
- known reflection-based method callers.
-
-*/
-
-func assert(b bool) {
- if !b {
- panic("failed assertion")
- }
-}
-
-func typString(obj types.Object) string {
- switch obj := obj.(type) {
- case *types.Func:
- return "func"
- case *types.Var:
- if obj.IsField() {
- return "field"
- }
- return "var"
- case *types.Const:
- return "const"
- case *types.TypeName:
- return "type"
- default:
- return "identifier"
- }
-}
-
-// /usr/lib/go/src/runtime/proc.go:433:6: func badmorestackg0 is unused (U1000)
-
-// Functions defined in the Go runtime that may be called through
-// compiler magic or via assembly.
-var runtimeFuncs = map[string]bool{
- // The first part of the list is copied from
- // cmd/compile/internal/gc/builtin.go, var runtimeDecls
- "newobject": true,
- "panicindex": true,
- "panicslice": true,
- "panicdivide": true,
- "panicmakeslicelen": true,
- "throwinit": true,
- "panicwrap": true,
- "gopanic": true,
- "gorecover": true,
- "goschedguarded": true,
- "printbool": true,
- "printfloat": true,
- "printint": true,
- "printhex": true,
- "printuint": true,
- "printcomplex": true,
- "printstring": true,
- "printpointer": true,
- "printiface": true,
- "printeface": true,
- "printslice": true,
- "printnl": true,
- "printsp": true,
- "printlock": true,
- "printunlock": true,
- "concatstring2": true,
- "concatstring3": true,
- "concatstring4": true,
- "concatstring5": true,
- "concatstrings": true,
- "cmpstring": true,
- "intstring": true,
- "slicebytetostring": true,
- "slicebytetostringtmp": true,
- "slicerunetostring": true,
- "stringtoslicebyte": true,
- "stringtoslicerune": true,
- "slicecopy": true,
- "slicestringcopy": true,
- "decoderune": true,
- "countrunes": true,
- "convI2I": true,
- "convT16": true,
- "convT32": true,
- "convT64": true,
- "convTstring": true,
- "convTslice": true,
- "convT2E": true,
- "convT2Enoptr": true,
- "convT2I": true,
- "convT2Inoptr": true,
- "assertE2I": true,
- "assertE2I2": true,
- "assertI2I": true,
- "assertI2I2": true,
- "panicdottypeE": true,
- "panicdottypeI": true,
- "panicnildottype": true,
- "ifaceeq": true,
- "efaceeq": true,
- "fastrand": true,
- "makemap64": true,
- "makemap": true,
- "makemap_small": true,
- "mapaccess1": true,
- "mapaccess1_fast32": true,
- "mapaccess1_fast64": true,
- "mapaccess1_faststr": true,
- "mapaccess1_fat": true,
- "mapaccess2": true,
- "mapaccess2_fast32": true,
- "mapaccess2_fast64": true,
- "mapaccess2_faststr": true,
- "mapaccess2_fat": true,
- "mapassign": true,
- "mapassign_fast32": true,
- "mapassign_fast32ptr": true,
- "mapassign_fast64": true,
- "mapassign_fast64ptr": true,
- "mapassign_faststr": true,
- "mapiterinit": true,
- "mapdelete": true,
- "mapdelete_fast32": true,
- "mapdelete_fast64": true,
- "mapdelete_faststr": true,
- "mapiternext": true,
- "mapclear": true,
- "makechan64": true,
- "makechan": true,
- "chanrecv1": true,
- "chanrecv2": true,
- "chansend1": true,
- "closechan": true,
- "writeBarrier": true,
- "typedmemmove": true,
- "typedmemclr": true,
- "typedslicecopy": true,
- "selectnbsend": true,
- "selectnbrecv": true,
- "selectnbrecv2": true,
- "selectsetpc": true,
- "selectgo": true,
- "block": true,
- "makeslice": true,
- "makeslice64": true,
- "growslice": true,
- "memmove": true,
- "memclrNoHeapPointers": true,
- "memclrHasPointers": true,
- "memequal": true,
- "memequal8": true,
- "memequal16": true,
- "memequal32": true,
- "memequal64": true,
- "memequal128": true,
- "int64div": true,
- "uint64div": true,
- "int64mod": true,
- "uint64mod": true,
- "float64toint64": true,
- "float64touint64": true,
- "float64touint32": true,
- "int64tofloat64": true,
- "uint64tofloat64": true,
- "uint32tofloat64": true,
- "complex128div": true,
- "racefuncenter": true,
- "racefuncenterfp": true,
- "racefuncexit": true,
- "raceread": true,
- "racewrite": true,
- "racereadrange": true,
- "racewriterange": true,
- "msanread": true,
- "msanwrite": true,
- "x86HasPOPCNT": true,
- "x86HasSSE41": true,
- "arm64HasATOMICS": true,
-
- // The second part of the list is extracted from assembly code in
- // the standard library, with the exception of the runtime package itself
- "abort": true,
- "aeshashbody": true,
- "args": true,
- "asminit": true,
- "badctxt": true,
- "badmcall2": true,
- "badmcall": true,
- "badmorestackg0": true,
- "badmorestackgsignal": true,
- "badsignal2": true,
- "callbackasm1": true,
- "callCfunction": true,
- "cgocallback_gofunc": true,
- "cgocallbackg": true,
- "checkgoarm": true,
- "check": true,
- "debugCallCheck": true,
- "debugCallWrap": true,
- "emptyfunc": true,
- "entersyscall": true,
- "exit": true,
- "exits": true,
- "exitsyscall": true,
- "externalthreadhandler": true,
- "findnull": true,
- "goexit1": true,
- "gostring": true,
- "i386_set_ldt": true,
- "_initcgo": true,
- "init_thread_tls": true,
- "ldt0setup": true,
- "libpreinit": true,
- "load_g": true,
- "morestack": true,
- "mstart": true,
- "nacl_sysinfo": true,
- "nanotimeQPC": true,
- "nanotime": true,
- "newosproc0": true,
- "newproc": true,
- "newstack": true,
- "noted": true,
- "nowQPC": true,
- "osinit": true,
- "printf": true,
- "racecallback": true,
- "reflectcallmove": true,
- "reginit": true,
- "rt0_go": true,
- "save_g": true,
- "schedinit": true,
- "setldt": true,
- "settls": true,
- "sighandler": true,
- "sigprofNonGo": true,
- "sigtrampgo": true,
- "_sigtramp": true,
- "sigtramp": true,
- "stackcheck": true,
- "syscall_chdir": true,
- "syscall_chroot": true,
- "syscall_close": true,
- "syscall_dup2": true,
- "syscall_execve": true,
- "syscall_exit": true,
- "syscall_fcntl": true,
- "syscall_forkx": true,
- "syscall_gethostname": true,
- "syscall_getpid": true,
- "syscall_ioctl": true,
- "syscall_pipe": true,
- "syscall_rawsyscall6": true,
- "syscall_rawSyscall6": true,
- "syscall_rawsyscall": true,
- "syscall_RawSyscall": true,
- "syscall_rawsysvicall6": true,
- "syscall_setgid": true,
- "syscall_setgroups": true,
- "syscall_setpgid": true,
- "syscall_setsid": true,
- "syscall_setuid": true,
- "syscall_syscall6": true,
- "syscall_syscall": true,
- "syscall_Syscall": true,
- "syscall_sysvicall6": true,
- "syscall_wait4": true,
- "syscall_write": true,
- "traceback": true,
- "tstart": true,
- "usplitR0": true,
- "wbBufFlush": true,
- "write": true,
-}
-
-type pkg struct {
- Fset *token.FileSet
- Files []*ast.File
- Pkg *types.Package
- TypesInfo *types.Info
- TypesSizes types.Sizes
- SSA *ssa.Package
- SrcFuncs []*ssa.Function
-}
-
-type Checker struct {
- WholeProgram bool
- Debug io.Writer
-
- mu sync.Mutex
- initialPackages map[*types.Package]struct{}
- allPackages map[*types.Package]struct{}
- graph *Graph
-}
-
-func NewChecker(wholeProgram bool) *Checker {
- return &Checker{
- initialPackages: map[*types.Package]struct{}{},
- allPackages: map[*types.Package]struct{}{},
- WholeProgram: wholeProgram,
- }
-}
-
-func (c *Checker) Analyzer() *analysis.Analyzer {
- name := "U1000"
- if c.WholeProgram {
- name = "U1001"
- }
- return &analysis.Analyzer{
- Name: name,
- Doc: "Unused code",
- Run: c.Run,
- Requires: []*analysis.Analyzer{buildssa.Analyzer},
- }
-}
-
-func (c *Checker) Run(pass *analysis.Pass) (interface{}, error) {
- c.mu.Lock()
- if c.graph == nil {
- c.graph = NewGraph()
- c.graph.wholeProgram = c.WholeProgram
- c.graph.fset = pass.Fset
- }
-
- var visit func(pkg *types.Package)
- visit = func(pkg *types.Package) {
- if _, ok := c.allPackages[pkg]; ok {
- return
- }
- c.allPackages[pkg] = struct{}{}
- for _, imp := range pkg.Imports() {
- visit(imp)
- }
- }
- visit(pass.Pkg)
-
- c.initialPackages[pass.Pkg] = struct{}{}
- c.mu.Unlock()
-
- ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
- pkg := &pkg{
- Fset: pass.Fset,
- Files: pass.Files,
- Pkg: pass.Pkg,
- TypesInfo: pass.TypesInfo,
- TypesSizes: pass.TypesSizes,
- SSA: ssapkg.Pkg,
- SrcFuncs: ssapkg.SrcFuncs,
- }
-
- c.processPkg(c.graph, pkg)
-
- return nil, nil
-}
-
-func (c *Checker) ProblemObject(fset *token.FileSet, obj types.Object) lint.Problem {
- name := obj.Name()
- if sig, ok := obj.Type().(*types.Signature); ok && sig.Recv() != nil {
- switch sig.Recv().Type().(type) {
- case *types.Named, *types.Pointer:
- typ := types.TypeString(sig.Recv().Type(), func(*types.Package) string { return "" })
- if len(typ) > 0 && typ[0] == '*' {
- name = fmt.Sprintf("(%s).%s", typ, obj.Name())
- } else if len(typ) > 0 {
- name = fmt.Sprintf("%s.%s", typ, obj.Name())
- }
- }
- }
-
- checkName := "U1000"
- if c.WholeProgram {
- checkName = "U1001"
- }
- return lint.Problem{
- Pos: lint.DisplayPosition(fset, obj.Pos()),
- Message: fmt.Sprintf("%s %s is unused", typString(obj), name),
- Check: checkName,
- }
-}
-
-func (c *Checker) Result() []types.Object {
- out := c.results()
-
- out2 := make([]types.Object, 0, len(out))
- for _, v := range out {
- if _, ok := c.initialPackages[v.Pkg()]; !ok {
- continue
- }
- out2 = append(out2, v)
- }
-
- return out2
-}
-
-func (c *Checker) debugf(f string, v ...interface{}) {
- if c.Debug != nil {
- fmt.Fprintf(c.Debug, f, v...)
- }
-}
-
-func (graph *Graph) quieten(node *Node) {
- if node.seen {
- return
- }
- switch obj := node.obj.(type) {
- case *types.Named:
- for i := 0; i < obj.NumMethods(); i++ {
- m := obj.Method(i)
- if node, ok := graph.nodeMaybe(m); ok {
- node.quiet = true
- }
- }
- case *types.Struct:
- for i := 0; i < obj.NumFields(); i++ {
- if node, ok := graph.nodeMaybe(obj.Field(i)); ok {
- node.quiet = true
- }
- }
- case *types.Interface:
- for i := 0; i < obj.NumExplicitMethods(); i++ {
- m := obj.ExplicitMethod(i)
- if node, ok := graph.nodeMaybe(m); ok {
- node.quiet = true
- }
- }
- }
-}
-
-func (c *Checker) results() []types.Object {
- if c.graph == nil {
- // We never analyzed any packages
- return nil
- }
-
- var out []types.Object
-
- if c.WholeProgram {
- var ifaces []*types.Interface
- var notIfaces []types.Type
-
- // implement as many interfaces as possible
- c.graph.seenTypes.Iterate(func(t types.Type, _ interface{}) {
- switch t := t.(type) {
- case *types.Interface:
- if t.NumMethods() > 0 {
- ifaces = append(ifaces, t)
- }
- default:
- if _, ok := t.Underlying().(*types.Interface); !ok {
- notIfaces = append(notIfaces, t)
- }
- }
- })
-
- for pkg := range c.allPackages {
- for _, iface := range interfacesFromExportData(pkg) {
- if iface.NumMethods() > 0 {
- ifaces = append(ifaces, iface)
- }
- }
- }
-
- ctx := &context{
- g: c.graph,
- seenTypes: &c.graph.seenTypes,
- }
- // (8.0) handle interfaces
- // (e2) types aim to implement all exported interfaces from all packages
- for _, t := range notIfaces {
- // OPT(dh): it is unfortunate that we do not have access
- // to a populated method set at this point.
- ms := types.NewMethodSet(t)
- for _, iface := range ifaces {
- if sels, ok := c.graph.implements(t, iface, ms); ok {
- for _, sel := range sels {
- c.graph.useMethod(ctx, t, sel, t, edgeImplements)
- }
- }
- }
- }
- }
-
- if c.Debug != nil {
- debugNode := func(node *Node) {
- if node.obj == nil {
- c.debugf("n%d [label=\"Root\"];\n", node.id)
- } else {
- c.debugf("n%d [label=%q];\n", node.id, fmt.Sprintf("(%T) %s", node.obj, node.obj))
- }
- for _, e := range node.used {
- for i := edgeKind(1); i < 64; i++ {
- if e.kind.is(1 << i) {
- c.debugf("n%d -> n%d [label=%q];\n", node.id, e.node.id, edgeKind(1< 1 {
- cg := &ConstGroup{}
- ctx.see(cg)
- for _, spec := range specs {
- for _, name := range spec.(*ast.ValueSpec).Names {
- obj := pkg.TypesInfo.ObjectOf(name)
- // (10.1) const groups
- ctx.seeAndUse(obj, cg, edgeConstGroup)
- ctx.use(cg, obj, edgeConstGroup)
- }
- }
- }
- }
- case token.VAR:
- for _, spec := range n.Specs {
- v := spec.(*ast.ValueSpec)
- for _, name := range v.Names {
- T := pkg.TypesInfo.TypeOf(name)
- if fn != nil {
- ctx.seeAndUse(T, fn, edgeVarDecl)
- } else {
- // TODO(dh): we likely want to make
- // the type used by the variable, not
- // the package containing the
- // variable. But then we have to take
- // special care of blank identifiers.
- ctx.seeAndUse(T, nil, edgeVarDecl)
- }
- g.typ(ctx, T, nil)
- }
- }
- case token.TYPE:
- for _, spec := range n.Specs {
- // go/types doesn't provide a way to go from a
- // types.Named to the named type it was based on
- // (the t1 in type t2 t1). Therefore we walk the
- // AST and process GenDecls.
- //
- // (2.2) named types use the type they're based on
- v := spec.(*ast.TypeSpec)
- T := pkg.TypesInfo.TypeOf(v.Type)
- obj := pkg.TypesInfo.ObjectOf(v.Name)
- ctx.see(obj)
- ctx.see(T)
- ctx.use(T, obj, edgeType)
- g.typ(ctx, obj.Type(), nil)
- g.typ(ctx, T, nil)
-
- if v.Assign != 0 {
- aliasFor := obj.(*types.TypeName).Type()
- // (2.3) named types use all their aliases. we can't easily track uses of aliases
- if isIrrelevant(aliasFor) {
- // We do not track the type this is an
- // alias for (for example builtins), so
- // just mark the alias used.
- //
- // FIXME(dh): what about aliases declared inside functions?
- ctx.use(obj, nil, edgeAlias)
- } else {
- ctx.see(aliasFor)
- ctx.seeAndUse(obj, aliasFor, edgeAlias)
- }
- }
- }
- }
- }
- return true
- })
- }
-
- for _, m := range pkg.SSA.Members {
- switch m := m.(type) {
- case *ssa.NamedConst:
- // nothing to do, we collect all constants from Defs
- case *ssa.Global:
- if m.Object() != nil {
- ctx.see(m.Object())
- if g.trackExportedIdentifier(ctx, m.Object()) {
- // (1.3) packages use exported variables (unless in package main)
- ctx.use(m.Object(), nil, edgeExportedVariable)
- }
- }
- case *ssa.Function:
- mObj := owningObject(m)
- if mObj != nil {
- ctx.see(mObj)
- }
- //lint:ignore SA9003 handled implicitly
- if m.Name() == "init" {
- // (1.5) packages use init functions
- //
- // This is handled implicitly. The generated init
- // function has no object, thus everything in it will
- // be owned by the package.
- }
- // This branch catches top-level functions, not methods.
- if m.Object() != nil && g.trackExportedIdentifier(ctx, m.Object()) {
- // (1.2) packages use exported functions (unless in package main)
- ctx.use(mObj, nil, edgeExportedFunction)
- }
- if m.Name() == "main" && pkg.Pkg.Name() == "main" {
- // (1.7) packages use the main function iff in the main package
- ctx.use(mObj, nil, edgeMainFunction)
- }
- if pkg.Pkg.Path() == "runtime" && runtimeFuncs[m.Name()] {
- // (9.8) runtime functions that may be called from user code via the compiler
- ctx.use(mObj, nil, edgeRuntimeFunction)
- }
- if m.Syntax() != nil {
- doc := m.Syntax().(*ast.FuncDecl).Doc
- if doc != nil {
- for _, cmt := range doc.List {
- if strings.HasPrefix(cmt.Text, "//go:cgo_export_") {
- // (1.6) packages use functions exported to cgo
- ctx.use(mObj, nil, edgeCgoExported)
- }
- }
- }
- }
- g.function(ctx, m)
- case *ssa.Type:
- if m.Object() != nil {
- ctx.see(m.Object())
- if g.trackExportedIdentifier(ctx, m.Object()) {
- // (1.1) packages use exported named types (unless in package main)
- ctx.use(m.Object(), nil, edgeExportedType)
- }
- }
- g.typ(ctx, m.Type(), nil)
- default:
- panic(fmt.Sprintf("unreachable: %T", m))
- }
- }
-
- if !g.wholeProgram {
- // When not in whole program mode we reset seenTypes after each package,
- // which means g.seenTypes only contains types of
- // interest to us. In whole program mode, we're better off
- // processing all interfaces at once, globally, both for
- // performance reasons and because in whole program mode we
- // actually care about all interfaces, not just the subset
- // that has unexported methods.
-
- var ifaces []*types.Interface
- var notIfaces []types.Type
-
- ctx.seenTypes.Iterate(func(t types.Type, _ interface{}) {
- switch t := t.(type) {
- case *types.Interface:
- // OPT(dh): (8.1) we only need interfaces that have unexported methods
- ifaces = append(ifaces, t)
- default:
- if _, ok := t.Underlying().(*types.Interface); !ok {
- notIfaces = append(notIfaces, t)
- }
- }
- })
-
- // (8.0) handle interfaces
- for _, t := range notIfaces {
- ms := pkg.SSA.Prog.MethodSets.MethodSet(t)
- for _, iface := range ifaces {
- if sels, ok := g.implements(t, iface, ms); ok {
- for _, sel := range sels {
- g.useMethod(ctx, t, sel, t, edgeImplements)
- }
- }
- }
- }
- }
-}
-
-func (g *Graph) useMethod(ctx *context, t types.Type, sel *types.Selection, by interface{}, kind edgeKind) {
- obj := sel.Obj()
- path := sel.Index()
- assert(obj != nil)
- if len(path) > 1 {
- base := lintdsl.Dereference(t).Underlying().(*types.Struct)
- for _, idx := range path[:len(path)-1] {
- next := base.Field(idx)
- // (6.3) structs use embedded fields that help implement interfaces
- ctx.see(base)
- ctx.seeAndUse(next, base, edgeProvidesMethod)
- base, _ = lintdsl.Dereference(next.Type()).Underlying().(*types.Struct)
- }
- }
- ctx.seeAndUse(obj, by, kind)
-}
-
-func owningObject(fn *ssa.Function) types.Object {
- if fn.Object() != nil {
- return fn.Object()
- }
- if fn.Parent() != nil {
- return owningObject(fn.Parent())
- }
- return nil
-}
-
-func (g *Graph) function(ctx *context, fn *ssa.Function) {
- if fn.Package() != nil && fn.Package() != ctx.pkg.SSA {
- return
- }
-
- name := fn.RelString(nil)
- if _, ok := ctx.seenFns[name]; ok {
- return
- }
- ctx.seenFns[name] = struct{}{}
-
- // (4.1) functions use all their arguments, return parameters and receivers
- g.signature(ctx, fn.Signature, owningObject(fn))
- g.instructions(ctx, fn)
- for _, anon := range fn.AnonFuncs {
- // (4.2) functions use anonymous functions defined beneath them
- //
- // This fact is expressed implicitly. Anonymous functions have
- // no types.Object, so their owner is the surrounding
- // function.
- g.function(ctx, anon)
- }
-}
-
-func (g *Graph) typ(ctx *context, t types.Type, parent types.Type) {
- if g.wholeProgram {
- g.mu.Lock()
- }
- if ctx.seenTypes.At(t) != nil {
- if g.wholeProgram {
- g.mu.Unlock()
- }
- return
- }
- if g.wholeProgram {
- g.mu.Unlock()
- }
- if t, ok := t.(*types.Named); ok && t.Obj().Pkg() != nil {
- if t.Obj().Pkg() != ctx.pkg.Pkg {
- return
- }
- }
-
- if g.wholeProgram {
- g.mu.Lock()
- }
- ctx.seenTypes.Set(t, struct{}{})
- if g.wholeProgram {
- g.mu.Unlock()
- }
- if isIrrelevant(t) {
- return
- }
-
- ctx.see(t)
- switch t := t.(type) {
- case *types.Struct:
- for i := 0; i < t.NumFields(); i++ {
- ctx.see(t.Field(i))
- if t.Field(i).Exported() {
- // (6.2) structs use exported fields
- ctx.use(t.Field(i), t, edgeExportedField)
- } else if t.Field(i).Name() == "_" {
- ctx.use(t.Field(i), t, edgeBlankField)
- } else if isNoCopyType(t.Field(i).Type()) {
- // (6.1) structs use fields of type NoCopy sentinel
- ctx.use(t.Field(i), t, edgeNoCopySentinel)
- } else if parent == nil {
- // (11.1) anonymous struct types use all their fields.
- ctx.use(t.Field(i), t, edgeAnonymousStruct)
- }
- if t.Field(i).Anonymous() {
- // (e3) exported identifiers aren't automatically used.
- if !g.wholeProgram {
- // does the embedded field contribute exported methods to the method set?
- T := t.Field(i).Type()
- if _, ok := T.Underlying().(*types.Pointer); !ok {
- // An embedded field is addressable, so check
- // the pointer type to get the full method set
- T = types.NewPointer(T)
- }
- ms := ctx.pkg.SSA.Prog.MethodSets.MethodSet(T)
- for j := 0; j < ms.Len(); j++ {
- if ms.At(j).Obj().Exported() {
- // (6.4) structs use embedded fields that have exported methods (recursively)
- ctx.use(t.Field(i), t, edgeExtendsExportedMethodSet)
- break
- }
- }
- }
-
- seen := map[*types.Struct]struct{}{}
- var hasExportedField func(t types.Type) bool
- hasExportedField = func(T types.Type) bool {
- t, ok := lintdsl.Dereference(T).Underlying().(*types.Struct)
- if !ok {
- return false
- }
- if _, ok := seen[t]; ok {
- return false
- }
- seen[t] = struct{}{}
- for i := 0; i < t.NumFields(); i++ {
- field := t.Field(i)
- if field.Exported() {
- return true
- }
- if field.Embedded() && hasExportedField(field.Type()) {
- return true
- }
- }
- return false
- }
- // does the embedded field contribute exported fields?
- if hasExportedField(t.Field(i).Type()) {
- // (6.5) structs use embedded structs that have exported fields (recursively)
- ctx.use(t.Field(i), t, edgeExtendsExportedFields)
- }
-
- }
- g.variable(ctx, t.Field(i))
- }
- case *types.Basic:
- // Nothing to do
- case *types.Named:
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.Underlying(), t, edgeUnderlyingType)
- ctx.seeAndUse(t.Obj(), t, edgeTypeName)
- ctx.seeAndUse(t, t.Obj(), edgeNamedType)
-
- // (2.4) named types use the pointer type
- if _, ok := t.Underlying().(*types.Interface); !ok && t.NumMethods() > 0 {
- ctx.seeAndUse(types.NewPointer(t), t, edgePointerType)
- }
-
- for i := 0; i < t.NumMethods(); i++ {
- ctx.see(t.Method(i))
- // don't use trackExportedIdentifier here, we care about
- // all exported methods, even in package main or in tests.
- if t.Method(i).Exported() && !g.wholeProgram {
- // (2.1) named types use exported methods
- ctx.use(t.Method(i), t, edgeExportedMethod)
- }
- g.function(ctx, ctx.pkg.SSA.Prog.FuncValue(t.Method(i)))
- }
-
- g.typ(ctx, t.Underlying(), t)
- case *types.Slice:
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.Elem(), t, edgeElementType)
- g.typ(ctx, t.Elem(), nil)
- case *types.Map:
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.Elem(), t, edgeElementType)
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.Key(), t, edgeKeyType)
- g.typ(ctx, t.Elem(), nil)
- g.typ(ctx, t.Key(), nil)
- case *types.Signature:
- g.signature(ctx, t, nil)
- case *types.Interface:
- for i := 0; i < t.NumMethods(); i++ {
- m := t.Method(i)
- // (8.3) All interface methods are marked as used
- ctx.seeAndUse(m, t, edgeInterfaceMethod)
- ctx.seeAndUse(m.Type().(*types.Signature), m, edgeSignature)
- g.signature(ctx, m.Type().(*types.Signature), nil)
- }
- for i := 0; i < t.NumEmbeddeds(); i++ {
- tt := t.EmbeddedType(i)
- // (8.4) All embedded interfaces are marked as used
- ctx.seeAndUse(tt, t, edgeEmbeddedInterface)
- }
- case *types.Array:
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.Elem(), t, edgeElementType)
- g.typ(ctx, t.Elem(), nil)
- case *types.Pointer:
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.Elem(), t, edgeElementType)
- g.typ(ctx, t.Elem(), nil)
- case *types.Chan:
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.Elem(), t, edgeElementType)
- g.typ(ctx, t.Elem(), nil)
- case *types.Tuple:
- for i := 0; i < t.Len(); i++ {
- // (9.3) types use their underlying and element types
- ctx.seeAndUse(t.At(i).Type(), t, edgeTupleElement|edgeType)
- g.typ(ctx, t.At(i).Type(), nil)
- }
- default:
- panic(fmt.Sprintf("unreachable: %T", t))
- }
-}
-
-func (g *Graph) variable(ctx *context, v *types.Var) {
- // (9.2) variables use their types
- ctx.seeAndUse(v.Type(), v, edgeType)
- g.typ(ctx, v.Type(), nil)
-}
-
-func (g *Graph) signature(ctx *context, sig *types.Signature, fn types.Object) {
- var user interface{} = fn
- if fn == nil {
- user = sig
- ctx.see(sig)
- }
- if sig.Recv() != nil {
- ctx.seeAndUse(sig.Recv().Type(), user, edgeReceiver|edgeType)
- g.typ(ctx, sig.Recv().Type(), nil)
- }
- for i := 0; i < sig.Params().Len(); i++ {
- param := sig.Params().At(i)
- ctx.seeAndUse(param.Type(), user, edgeFunctionArgument|edgeType)
- g.typ(ctx, param.Type(), nil)
- }
- for i := 0; i < sig.Results().Len(); i++ {
- param := sig.Results().At(i)
- ctx.seeAndUse(param.Type(), user, edgeFunctionResult|edgeType)
- g.typ(ctx, param.Type(), nil)
- }
-}
-
-func (g *Graph) instructions(ctx *context, fn *ssa.Function) {
- fnObj := owningObject(fn)
- for _, b := range fn.Blocks {
- for _, instr := range b.Instrs {
- ops := instr.Operands(nil)
- switch instr.(type) {
- case *ssa.Store:
- // (9.7) variable _reads_ use variables, writes do not
- ops = ops[1:]
- case *ssa.DebugRef:
- ops = nil
- }
- for _, arg := range ops {
- walkPhi(*arg, func(v ssa.Value) {
- switch v := v.(type) {
- case *ssa.Function:
- // (4.3) functions use closures and bound methods.
- // (4.5) functions use functions they call
- // (9.5) instructions use their operands
- // (4.4) functions use functions they return. we assume that someone else will call the returned function
- if owningObject(v) != nil {
- ctx.seeAndUse(owningObject(v), fnObj, edgeInstructionOperand)
- }
- g.function(ctx, v)
- case *ssa.Const:
- // (9.6) instructions use their operands' types
- ctx.seeAndUse(v.Type(), fnObj, edgeType)
- g.typ(ctx, v.Type(), nil)
- case *ssa.Global:
- if v.Object() != nil {
- // (9.5) instructions use their operands
- ctx.seeAndUse(v.Object(), fnObj, edgeInstructionOperand)
- }
- }
- })
- }
- if v, ok := instr.(ssa.Value); ok {
- if _, ok := v.(*ssa.Range); !ok {
- // See https://github.com/golang/go/issues/19670
-
- // (4.8) instructions use their types
- // (9.4) conversions use the type they convert to
- ctx.seeAndUse(v.Type(), fnObj, edgeType)
- g.typ(ctx, v.Type(), nil)
- }
- }
- switch instr := instr.(type) {
- case *ssa.Field:
- st := instr.X.Type().Underlying().(*types.Struct)
- field := st.Field(instr.Field)
- // (4.7) functions use fields they access
- ctx.seeAndUse(field, fnObj, edgeFieldAccess)
- case *ssa.FieldAddr:
- st := lintdsl.Dereference(instr.X.Type()).Underlying().(*types.Struct)
- field := st.Field(instr.Field)
- // (4.7) functions use fields they access
- ctx.seeAndUse(field, fnObj, edgeFieldAccess)
- case *ssa.Store:
- // nothing to do, handled generically by operands
- case *ssa.Call:
- c := instr.Common()
- if !c.IsInvoke() {
- // handled generically as an instruction operand
-
- if g.wholeProgram {
- // (e3) special case known reflection-based method callers
- switch lintdsl.CallName(c) {
- case "net/rpc.Register", "net/rpc.RegisterName", "(*net/rpc.Server).Register", "(*net/rpc.Server).RegisterName":
- var arg ssa.Value
- switch lintdsl.CallName(c) {
- case "net/rpc.Register":
- arg = c.Args[0]
- case "net/rpc.RegisterName":
- arg = c.Args[1]
- case "(*net/rpc.Server).Register":
- arg = c.Args[1]
- case "(*net/rpc.Server).RegisterName":
- arg = c.Args[2]
- }
- walkPhi(arg, func(v ssa.Value) {
- if v, ok := v.(*ssa.MakeInterface); ok {
- walkPhi(v.X, func(vv ssa.Value) {
- ms := ctx.pkg.SSA.Prog.MethodSets.MethodSet(vv.Type())
- for i := 0; i < ms.Len(); i++ {
- if ms.At(i).Obj().Exported() {
- g.useMethod(ctx, vv.Type(), ms.At(i), fnObj, edgeNetRPCRegister)
- }
- }
- })
- }
- })
- }
- }
- } else {
- // (4.5) functions use functions/interface methods they call
- ctx.seeAndUse(c.Method, fnObj, edgeInterfaceCall)
- }
- case *ssa.Return:
- // nothing to do, handled generically by operands
- case *ssa.ChangeType:
- // conversion type handled generically
-
- s1, ok1 := lintdsl.Dereference(instr.Type()).Underlying().(*types.Struct)
- s2, ok2 := lintdsl.Dereference(instr.X.Type()).Underlying().(*types.Struct)
- if ok1 && ok2 {
- // Converting between two structs. The fields are
- // relevant for the conversion, but only if the
- // fields are also used outside of the conversion.
- // Mark fields as used by each other.
-
- assert(s1.NumFields() == s2.NumFields())
- for i := 0; i < s1.NumFields(); i++ {
- ctx.see(s1.Field(i))
- ctx.see(s2.Field(i))
- // (5.1) when converting between two equivalent structs, the fields in
- // either struct use each other. the fields are relevant for the
- // conversion, but only if the fields are also accessed outside the
- // conversion.
- ctx.seeAndUse(s1.Field(i), s2.Field(i), edgeStructConversion)
- ctx.seeAndUse(s2.Field(i), s1.Field(i), edgeStructConversion)
- }
- }
- case *ssa.MakeInterface:
- // nothing to do, handled generically by operands
- case *ssa.Slice:
- // nothing to do, handled generically by operands
- case *ssa.RunDefers:
- // nothing to do, the deferred functions are already marked use by defering them.
- case *ssa.Convert:
- // to unsafe.Pointer
- if typ, ok := instr.Type().(*types.Basic); ok && typ.Kind() == types.UnsafePointer {
- if ptr, ok := instr.X.Type().Underlying().(*types.Pointer); ok {
- if st, ok := ptr.Elem().Underlying().(*types.Struct); ok {
- for i := 0; i < st.NumFields(); i++ {
- // (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
- ctx.seeAndUse(st.Field(i), fnObj, edgeUnsafeConversion)
- }
- }
- }
- }
- // from unsafe.Pointer
- if typ, ok := instr.X.Type().(*types.Basic); ok && typ.Kind() == types.UnsafePointer {
- if ptr, ok := instr.Type().Underlying().(*types.Pointer); ok {
- if st, ok := ptr.Elem().Underlying().(*types.Struct); ok {
- for i := 0; i < st.NumFields(); i++ {
- // (5.2) when converting to or from unsafe.Pointer, mark all fields as used.
- ctx.seeAndUse(st.Field(i), fnObj, edgeUnsafeConversion)
- }
- }
- }
- }
- case *ssa.TypeAssert:
- // nothing to do, handled generically by instruction
- // type (possibly a tuple, which contains the asserted
- // to type). redundantly handled by the type of
- // ssa.Extract, too
- case *ssa.MakeClosure:
- // nothing to do, handled generically by operands
- case *ssa.Alloc:
- // nothing to do
- case *ssa.UnOp:
- // nothing to do
- case *ssa.BinOp:
- // nothing to do
- case *ssa.If:
- // nothing to do
- case *ssa.Jump:
- // nothing to do
- case *ssa.IndexAddr:
- // nothing to do
- case *ssa.Extract:
- // nothing to do
- case *ssa.Panic:
- // nothing to do
- case *ssa.DebugRef:
- // nothing to do
- case *ssa.BlankStore:
- // nothing to do
- case *ssa.Phi:
- // nothing to do
- case *ssa.MakeMap:
- // nothing to do
- case *ssa.MapUpdate:
- // nothing to do
- case *ssa.Lookup:
- // nothing to do
- case *ssa.MakeSlice:
- // nothing to do
- case *ssa.Send:
- // nothing to do
- case *ssa.MakeChan:
- // nothing to do
- case *ssa.Range:
- // nothing to do
- case *ssa.Next:
- // nothing to do
- case *ssa.Index:
- // nothing to do
- case *ssa.Select:
- // nothing to do
- case *ssa.ChangeInterface:
- // nothing to do
- case *ssa.Go:
- // nothing to do, handled generically by operands
- case *ssa.Defer:
- // nothing to do, handled generically by operands
- default:
- panic(fmt.Sprintf("unreachable: %T", instr))
- }
- }
- }
-}
-
-// isNoCopyType reports whether a type represents the NoCopy sentinel
-// type. The NoCopy type is a named struct with no fields and exactly
-// one method `func Lock()` that is empty.
-//
-// FIXME(dh): currently we're not checking that the function body is
-// empty.
-func isNoCopyType(typ types.Type) bool {
- st, ok := typ.Underlying().(*types.Struct)
- if !ok {
- return false
- }
- if st.NumFields() != 0 {
- return false
- }
-
- named, ok := typ.(*types.Named)
- if !ok {
- return false
- }
- if named.NumMethods() != 1 {
- return false
- }
- meth := named.Method(0)
- if meth.Name() != "Lock" {
- return false
- }
- sig := meth.Type().(*types.Signature)
- if sig.Params().Len() != 0 || sig.Results().Len() != 0 {
- return false
- }
- return true
-}
-
-func walkPhi(v ssa.Value, fn func(v ssa.Value)) {
- phi, ok := v.(*ssa.Phi)
- if !ok {
- fn(v)
- return
- }
-
- seen := map[ssa.Value]struct{}{}
- var impl func(v *ssa.Phi)
- impl = func(v *ssa.Phi) {
- if _, ok := seen[v]; ok {
- return
- }
- seen[v] = struct{}{}
- for _, e := range v.Edges {
- if ev, ok := e.(*ssa.Phi); ok {
- impl(ev)
- } else {
- fn(e)
- }
- }
- }
- impl(phi)
-}
-
-func interfacesFromExportData(pkg *types.Package) []*types.Interface {
- var out []*types.Interface
- scope := pkg.Scope()
- for _, name := range scope.Names() {
- obj := scope.Lookup(name)
- out = append(out, interfacesFromObject(obj)...)
- }
- return out
-}
-
-func interfacesFromObject(obj types.Object) []*types.Interface {
- var out []*types.Interface
- switch obj := obj.(type) {
- case *types.Func:
- sig := obj.Type().(*types.Signature)
- for i := 0; i < sig.Results().Len(); i++ {
- out = append(out, interfacesFromObject(sig.Results().At(i))...)
- }
- for i := 0; i < sig.Params().Len(); i++ {
- out = append(out, interfacesFromObject(sig.Params().At(i))...)
- }
- case *types.TypeName:
- if named, ok := obj.Type().(*types.Named); ok {
- for i := 0; i < named.NumMethods(); i++ {
- out = append(out, interfacesFromObject(named.Method(i))...)
- }
-
- if iface, ok := named.Underlying().(*types.Interface); ok {
- out = append(out, iface)
- }
- }
- case *types.Var:
- // No call to Underlying here. We want unnamed interfaces
- // only. Named interfaces are gotten directly from the
- // package's scope.
- if iface, ok := obj.Type().(*types.Interface); ok {
- out = append(out, iface)
- }
- case *types.Const:
- case *types.Builtin:
- default:
- panic(fmt.Sprintf("unhandled type: %T", obj))
- }
- return out
-}
diff --git a/vendor/honnef.co/go/tools/version/buildinfo.go b/vendor/honnef.co/go/tools/version/buildinfo.go
deleted file mode 100644
index b6034bb7d..000000000
--- a/vendor/honnef.co/go/tools/version/buildinfo.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// +build go1.12
-
-package version
-
-import (
- "fmt"
- "runtime/debug"
-)
-
-func printBuildInfo() {
- if info, ok := debug.ReadBuildInfo(); ok {
- fmt.Println("Main module:")
- printModule(&info.Main)
- fmt.Println("Dependencies:")
- for _, dep := range info.Deps {
- printModule(dep)
- }
- } else {
- fmt.Println("Built without Go modules")
- }
-}
-
-func buildInfoVersion() (string, bool) {
- info, ok := debug.ReadBuildInfo()
- if !ok {
- return "", false
- }
- if info.Main.Version == "(devel)" {
- return "", false
- }
- return info.Main.Version, true
-}
-
-func printModule(m *debug.Module) {
- fmt.Printf("\t%s", m.Path)
- if m.Version != "(devel)" {
- fmt.Printf("@%s", m.Version)
- }
- if m.Sum != "" {
- fmt.Printf(" (sum: %s)", m.Sum)
- }
- if m.Replace != nil {
- fmt.Printf(" (replace: %s)", m.Replace.Path)
- }
- fmt.Println()
-}
diff --git a/vendor/honnef.co/go/tools/version/buildinfo111.go b/vendor/honnef.co/go/tools/version/buildinfo111.go
deleted file mode 100644
index 06aae1e65..000000000
--- a/vendor/honnef.co/go/tools/version/buildinfo111.go
+++ /dev/null
@@ -1,6 +0,0 @@
-// +build !go1.12
-
-package version
-
-func printBuildInfo() {}
-func buildInfoVersion() (string, bool) { return "", false }
diff --git a/vendor/honnef.co/go/tools/version/version.go b/vendor/honnef.co/go/tools/version/version.go
deleted file mode 100644
index 468e8efd6..000000000
--- a/vendor/honnef.co/go/tools/version/version.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package version
-
-import (
- "fmt"
- "os"
- "path/filepath"
- "runtime"
-)
-
-const Version = "2019.2.3"
-
-// version returns a version descriptor and reports whether the
-// version is a known release.
-func version() (string, bool) {
- if Version != "devel" {
- return Version, true
- }
- v, ok := buildInfoVersion()
- if ok {
- return v, false
- }
- return "devel", false
-}
-
-func Print() {
- v, release := version()
-
- if release {
- fmt.Printf("%s %s\n", filepath.Base(os.Args[0]), v)
- } else if v == "devel" {
- fmt.Printf("%s (no version)\n", filepath.Base(os.Args[0]))
- } else {
- fmt.Printf("%s (devel, %s)\n", filepath.Base(os.Args[0]), v)
- }
-}
-
-func Verbose() {
- Print()
- fmt.Println()
- fmt.Println("Compiled with Go version:", runtime.Version())
- printBuildInfo()
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c765d7081..377adee8f 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,9 +1,9 @@
-# cloud.google.com/go v0.56.0 => cloud.google.com/go v0.49.0
+# cloud.google.com/go v0.46.3 => cloud.google.com/go v0.49.0
cloud.google.com/go/compute/metadata
-# github.com/Azure/go-autorest/autorest v0.10.2 => github.com/Azure/go-autorest/autorest v0.9.0
+# github.com/Azure/go-autorest/autorest v0.9.0 => github.com/Azure/go-autorest/autorest v0.9.0
github.com/Azure/go-autorest/autorest
github.com/Azure/go-autorest/autorest/azure
-# github.com/Azure/go-autorest/autorest/adal v0.8.3 => github.com/Azure/go-autorest/autorest/adal v0.5.0
+# github.com/Azure/go-autorest/autorest/adal v0.5.0 => github.com/Azure/go-autorest/autorest/adal v0.5.0
github.com/Azure/go-autorest/autorest/adal
# github.com/Azure/go-autorest/autorest/date v0.1.0 => github.com/Azure/go-autorest/autorest/date v0.1.0
github.com/Azure/go-autorest/autorest/date
@@ -11,9 +11,7 @@ github.com/Azure/go-autorest/autorest/date
github.com/Azure/go-autorest/logger
# github.com/Azure/go-autorest/tracing v0.5.0 => github.com/Azure/go-autorest/tracing v0.5.0
github.com/Azure/go-autorest/tracing
-# github.com/BurntSushi/toml v0.3.1
-github.com/BurntSushi/toml
-# github.com/NYTimes/gziphandler v1.1.1
+# github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46
github.com/NYTimes/gziphandler
# github.com/PuerkitoBio/purell v1.1.1
github.com/PuerkitoBio/purell
@@ -35,7 +33,7 @@ github.com/appscode/go/version
github.com/armon/circbuf
# github.com/beorn7/perks v1.0.1
github.com/beorn7/perks/quantile
-# github.com/blang/semver v3.5.1+incompatible
+# github.com/blang/semver v3.5.0+incompatible
github.com/blang/semver
# github.com/cespare/xxhash/v2 v2.1.1
github.com/cespare/xxhash/v2
@@ -65,7 +63,7 @@ github.com/go-openapi/jsonpointer
github.com/go-openapi/jsonreference
# github.com/go-openapi/spec v0.19.8
github.com/go-openapi/spec
-# github.com/go-openapi/swag v0.19.9
+# github.com/go-openapi/swag v0.19.5
github.com/go-openapi/swag
# github.com/gogo/protobuf v1.3.1 => github.com/gogo/protobuf v1.3.1
github.com/gogo/protobuf/gogoproto
@@ -74,7 +72,7 @@ github.com/gogo/protobuf/protoc-gen-gogo/descriptor
github.com/gogo/protobuf/sortkeys
# github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/glog
-# github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7
+# github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef
github.com/golang/groupcache/lru
# github.com/golang/protobuf v1.4.2 => github.com/golang/protobuf v1.3.2
github.com/golang/protobuf/jsonpb
@@ -94,23 +92,21 @@ github.com/google/go-cmp/cmp/internal/value
github.com/google/gofuzz
# github.com/google/uuid v1.1.1
github.com/google/uuid
-# github.com/googleapis/gnostic v0.4.0 => github.com/googleapis/gnostic v0.3.1
+# github.com/googleapis/gnostic v0.3.1 => github.com/googleapis/gnostic v0.3.1
github.com/googleapis/gnostic/OpenAPIv2
github.com/googleapis/gnostic/compiler
github.com/googleapis/gnostic/extensions
-# github.com/gophercloud/gophercloud v0.11.0
+# github.com/gophercloud/gophercloud v0.1.0
github.com/gophercloud/gophercloud
github.com/gophercloud/gophercloud/openstack
github.com/gophercloud/gophercloud/openstack/identity/v2/tenants
github.com/gophercloud/gophercloud/openstack/identity/v2/tokens
-github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/ec2tokens
-github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/oauth1
github.com/gophercloud/gophercloud/openstack/identity/v3/tokens
github.com/gophercloud/gophercloud/openstack/utils
github.com/gophercloud/gophercloud/pagination
# github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/grpc-ecosystem/go-grpc-prometheus
-# github.com/hashicorp/golang-lru v0.5.4
+# github.com/hashicorp/golang-lru v0.5.1
github.com/hashicorp/golang-lru
github.com/hashicorp/golang-lru/simplelru
# github.com/imdario/mergo v0.3.6 => github.com/imdario/mergo v0.3.5
@@ -121,13 +117,13 @@ github.com/inconshreveable/mousetrap
github.com/jpillora/go-ogle-analytics
# github.com/json-iterator/go v1.1.10
github.com/json-iterator/go
-# github.com/mailru/easyjson v0.7.1
+# github.com/mailru/easyjson v0.7.0
github.com/mailru/easyjson/buffer
github.com/mailru/easyjson/jlexer
github.com/mailru/easyjson/jwriter
# github.com/matttproud/golang_protobuf_extensions v1.0.1
github.com/matttproud/golang_protobuf_extensions/pbutil
-# github.com/mitchellh/mapstructure v1.2.2
+# github.com/mitchellh/mapstructure v1.1.2
github.com/mitchellh/mapstructure
# github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
github.com/modern-go/concurrent
@@ -137,7 +133,7 @@ github.com/modern-go/reflect2
github.com/munnerz/goautoneg
# github.com/pkg/errors v0.9.1
github.com/pkg/errors
-# github.com/prometheus/client_golang v1.7.1 => github.com/prometheus/client_golang v1.7.1
+# github.com/prometheus/client_golang v1.0.0 => github.com/prometheus/client_golang v1.7.1
github.com/prometheus/client_golang/prometheus
github.com/prometheus/client_golang/prometheus/internal
github.com/prometheus/client_golang/prometheus/promhttp
@@ -195,13 +191,11 @@ go.etcd.io/etcd/raft/confchange
go.etcd.io/etcd/raft/quorum
go.etcd.io/etcd/raft/raftpb
go.etcd.io/etcd/raft/tracker
-# go.uber.org/atomic v1.6.0
+# go.uber.org/atomic v1.4.0
go.uber.org/atomic
-# go.uber.org/multierr v1.3.0
+# go.uber.org/multierr v1.1.0
go.uber.org/multierr
-# go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee
-go.uber.org/tools/update-license
-# go.uber.org/zap v1.13.0
+# go.uber.org/zap v1.10.0
go.uber.org/zap
go.uber.org/zap/buffer
go.uber.org/zap/internal/bufferpool
@@ -216,9 +210,6 @@ golang.org/x/crypto/nacl/secretbox
golang.org/x/crypto/poly1305
golang.org/x/crypto/salsa20/salsa
golang.org/x/crypto/ssh/terminal
-# golang.org/x/lint v0.0.0-20200302205851-738671d3881b
-golang.org/x/lint
-golang.org/x/lint/golint
# golang.org/x/net v0.0.0-20200625001655-4c5254603344
golang.org/x/net/context
golang.org/x/net/context/ctxhttp
@@ -229,13 +220,13 @@ golang.org/x/net/idna
golang.org/x/net/internal/timeseries
golang.org/x/net/trace
golang.org/x/net/websocket
-# golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
+# golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/oauth2
golang.org/x/oauth2/google
golang.org/x/oauth2/internal
golang.org/x/oauth2/jws
golang.org/x/oauth2/jwt
-# golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a
+# golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sync/singleflight
# golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1
golang.org/x/sys/cpu
@@ -248,37 +239,15 @@ golang.org/x/text/transform
golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm
golang.org/x/text/width
-# golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1
+# golang.org/x/time v0.0.0-20190308202827-9d24e82272b4
golang.org/x/time/rate
-# golang.org/x/tools v0.0.0-20200603131246-cc40288be839
-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
-golang.org/x/tools/go/buildutil
-golang.org/x/tools/go/gcexportdata
-golang.org/x/tools/go/internal/gcimporter
-golang.org/x/tools/go/internal/packagesdriver
-golang.org/x/tools/go/packages
-golang.org/x/tools/go/types/objectpath
-golang.org/x/tools/go/types/typeutil
-golang.org/x/tools/internal/analysisinternal
-golang.org/x/tools/internal/event
-golang.org/x/tools/internal/event/core
-golang.org/x/tools/internal/event/keys
-golang.org/x/tools/internal/event/label
-golang.org/x/tools/internal/gocommand
-golang.org/x/tools/internal/packagesinternal
-# golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
-golang.org/x/xerrors
-golang.org/x/xerrors/internal
# gomodules.xyz/jsonpatch/v2 v2.1.0
gomodules.xyz/jsonpatch/v2
# gomodules.xyz/sets v0.0.0-20200817084356-ae6e5e14ce3d
gomodules.xyz/sets
# gomodules.xyz/version v0.1.0
gomodules.xyz/version
-# google.golang.org/appengine v1.6.6
+# google.golang.org/appengine v1.6.1
google.golang.org/appengine
google.golang.org/appengine/internal
google.golang.org/appengine/internal/app_identity
@@ -289,9 +258,9 @@ google.golang.org/appengine/internal/modules
google.golang.org/appengine/internal/remote_api
google.golang.org/appengine/internal/urlfetch
google.golang.org/appengine/urlfetch
-# google.golang.org/genproto v0.0.0-20200603110839-e855014d5736 => google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9
+# google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9 => google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9
google.golang.org/genproto/googleapis/rpc/status
-# google.golang.org/grpc v1.29.1 => google.golang.org/grpc v1.26.0
+# google.golang.org/grpc v1.26.0 => google.golang.org/grpc v1.26.0
google.golang.org/grpc
google.golang.org/grpc/attributes
google.golang.org/grpc/backoff
@@ -334,34 +303,8 @@ google.golang.org/grpc/tap
gopkg.in/inf.v0
# gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/natefinch/lumberjack.v2
-# gopkg.in/yaml.v2 v2.3.0
+# gopkg.in/yaml.v2 v2.2.8
gopkg.in/yaml.v2
-# honnef.co/go/tools v0.0.1-2019.2.3
-honnef.co/go/tools/arg
-honnef.co/go/tools/cmd/staticcheck
-honnef.co/go/tools/config
-honnef.co/go/tools/deprecated
-honnef.co/go/tools/facts
-honnef.co/go/tools/functions
-honnef.co/go/tools/go/types/typeutil
-honnef.co/go/tools/internal/cache
-honnef.co/go/tools/internal/passes/buildssa
-honnef.co/go/tools/internal/renameio
-honnef.co/go/tools/internal/sharedcheck
-honnef.co/go/tools/lint
-honnef.co/go/tools/lint/lintdsl
-honnef.co/go/tools/lint/lintutil
-honnef.co/go/tools/lint/lintutil/format
-honnef.co/go/tools/loader
-honnef.co/go/tools/printf
-honnef.co/go/tools/simple
-honnef.co/go/tools/ssa
-honnef.co/go/tools/ssautil
-honnef.co/go/tools/staticcheck
-honnef.co/go/tools/staticcheck/vrp
-honnef.co/go/tools/stylecheck
-honnef.co/go/tools/unused
-honnef.co/go/tools/version
# k8s.io/api v0.18.9 => github.com/kmodules/api v0.18.10-0.20200922195318-d60fe725dea0
k8s.io/api/admission/v1
k8s.io/api/admission/v1beta1
@@ -836,7 +779,7 @@ k8s.io/kube-openapi/pkg/util
k8s.io/kube-openapi/pkg/util/proto
# k8s.io/kubernetes v1.18.9 => github.com/kmodules/kubernetes v1.19.0-alpha.0.0.20200922200158-8b13196d8dc4
k8s.io/kubernetes/pkg/util/hash
-# k8s.io/utils v0.0.0-20200414100711-2df71ebbae66 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
+# k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 => k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89
k8s.io/utils/buffer
k8s.io/utils/integer
k8s.io/utils/net
@@ -884,7 +827,7 @@ sigs.k8s.io/structured-merge-diff/v3/typed
sigs.k8s.io/structured-merge-diff/v3/value
# sigs.k8s.io/yaml v1.2.0
sigs.k8s.io/yaml
-# stash.appscode.dev/apimachinery v0.11.3-0.20201012035827-8f31689080d6
+# stash.appscode.dev/apimachinery v0.11.3
stash.appscode.dev/apimachinery/apis
stash.appscode.dev/apimachinery/apis/repositories
stash.appscode.dev/apimachinery/apis/repositories/v1alpha1