mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 19:49:57 +00:00
TUN-8006: Update quic-go to latest upstream
This commit is contained in:
221
vendor/golang.org/x/exp/rand/exp.go
generated
vendored
Normal file
221
vendor/golang.org/x/exp/rand/exp.go
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
// Copyright 2009 The Go 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 rand
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
* Exponential distribution
|
||||
*
|
||||
* See "The Ziggurat Method for Generating Random Variables"
|
||||
* (Marsaglia & Tsang, 2000)
|
||||
* http://www.jstatsoft.org/v05/i08/paper [pdf]
|
||||
*/
|
||||
|
||||
const (
|
||||
re = 7.69711747013104972
|
||||
)
|
||||
|
||||
// ExpFloat64 returns an exponentially distributed float64 in the range
|
||||
// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
|
||||
// (lambda) is 1 and whose mean is 1/lambda (1).
|
||||
// To produce a distribution with a different rate parameter,
|
||||
// callers can adjust the output using:
|
||||
//
|
||||
// sample = ExpFloat64() / desiredRateParameter
|
||||
func (r *Rand) ExpFloat64() float64 {
|
||||
for {
|
||||
j := r.Uint32()
|
||||
i := j & 0xFF
|
||||
x := float64(j) * float64(we[i])
|
||||
if j < ke[i] {
|
||||
return x
|
||||
}
|
||||
if i == 0 {
|
||||
return re - math.Log(r.Float64())
|
||||
}
|
||||
if fe[i]+float32(r.Float64())*(fe[i-1]-fe[i]) < float32(math.Exp(-x)) {
|
||||
return x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ke = [256]uint32{
|
||||
0xe290a139, 0x0, 0x9beadebc, 0xc377ac71, 0xd4ddb990,
|
||||
0xde893fb8, 0xe4a8e87c, 0xe8dff16a, 0xebf2deab, 0xee49a6e8,
|
||||
0xf0204efd, 0xf19bdb8e, 0xf2d458bb, 0xf3da104b, 0xf4b86d78,
|
||||
0xf577ad8a, 0xf61de83d, 0xf6afb784, 0xf730a573, 0xf7a37651,
|
||||
0xf80a5bb6, 0xf867189d, 0xf8bb1b4f, 0xf9079062, 0xf94d70ca,
|
||||
0xf98d8c7d, 0xf9c8928a, 0xf9ff175b, 0xfa319996, 0xfa6085f8,
|
||||
0xfa8c3a62, 0xfab5084e, 0xfadb36c8, 0xfaff0410, 0xfb20a6ea,
|
||||
0xfb404fb4, 0xfb5e2951, 0xfb7a59e9, 0xfb95038c, 0xfbae44ba,
|
||||
0xfbc638d8, 0xfbdcf892, 0xfbf29a30, 0xfc0731df, 0xfc1ad1ed,
|
||||
0xfc2d8b02, 0xfc3f6c4d, 0xfc5083ac, 0xfc60ddd1, 0xfc708662,
|
||||
0xfc7f8810, 0xfc8decb4, 0xfc9bbd62, 0xfca9027c, 0xfcb5c3c3,
|
||||
0xfcc20864, 0xfccdd70a, 0xfcd935e3, 0xfce42ab0, 0xfceebace,
|
||||
0xfcf8eb3b, 0xfd02c0a0, 0xfd0c3f59, 0xfd156b7b, 0xfd1e48d6,
|
||||
0xfd26daff, 0xfd2f2552, 0xfd372af7, 0xfd3eeee5, 0xfd4673e7,
|
||||
0xfd4dbc9e, 0xfd54cb85, 0xfd5ba2f2, 0xfd62451b, 0xfd68b415,
|
||||
0xfd6ef1da, 0xfd750047, 0xfd7ae120, 0xfd809612, 0xfd8620b4,
|
||||
0xfd8b8285, 0xfd90bcf5, 0xfd95d15e, 0xfd9ac10b, 0xfd9f8d36,
|
||||
0xfda43708, 0xfda8bf9e, 0xfdad2806, 0xfdb17141, 0xfdb59c46,
|
||||
0xfdb9a9fd, 0xfdbd9b46, 0xfdc170f6, 0xfdc52bd8, 0xfdc8ccac,
|
||||
0xfdcc542d, 0xfdcfc30b, 0xfdd319ef, 0xfdd6597a, 0xfdd98245,
|
||||
0xfddc94e5, 0xfddf91e6, 0xfde279ce, 0xfde54d1f, 0xfde80c52,
|
||||
0xfdeab7de, 0xfded5034, 0xfdefd5be, 0xfdf248e3, 0xfdf4aa06,
|
||||
0xfdf6f984, 0xfdf937b6, 0xfdfb64f4, 0xfdfd818d, 0xfdff8dd0,
|
||||
0xfe018a08, 0xfe03767a, 0xfe05536c, 0xfe07211c, 0xfe08dfc9,
|
||||
0xfe0a8fab, 0xfe0c30fb, 0xfe0dc3ec, 0xfe0f48b1, 0xfe10bf76,
|
||||
0xfe122869, 0xfe1383b4, 0xfe14d17c, 0xfe1611e7, 0xfe174516,
|
||||
0xfe186b2a, 0xfe19843e, 0xfe1a9070, 0xfe1b8fd6, 0xfe1c8289,
|
||||
0xfe1d689b, 0xfe1e4220, 0xfe1f0f26, 0xfe1fcfbc, 0xfe2083ed,
|
||||
0xfe212bc3, 0xfe21c745, 0xfe225678, 0xfe22d95f, 0xfe234ffb,
|
||||
0xfe23ba4a, 0xfe241849, 0xfe2469f2, 0xfe24af3c, 0xfe24e81e,
|
||||
0xfe25148b, 0xfe253474, 0xfe2547c7, 0xfe254e70, 0xfe25485a,
|
||||
0xfe25356a, 0xfe251586, 0xfe24e88f, 0xfe24ae64, 0xfe2466e1,
|
||||
0xfe2411df, 0xfe23af34, 0xfe233eb4, 0xfe22c02c, 0xfe22336b,
|
||||
0xfe219838, 0xfe20ee58, 0xfe20358c, 0xfe1f6d92, 0xfe1e9621,
|
||||
0xfe1daef0, 0xfe1cb7ac, 0xfe1bb002, 0xfe1a9798, 0xfe196e0d,
|
||||
0xfe1832fd, 0xfe16e5fe, 0xfe15869d, 0xfe141464, 0xfe128ed3,
|
||||
0xfe10f565, 0xfe0f478c, 0xfe0d84b1, 0xfe0bac36, 0xfe09bd73,
|
||||
0xfe07b7b5, 0xfe059a40, 0xfe03644c, 0xfe011504, 0xfdfeab88,
|
||||
0xfdfc26e9, 0xfdf98629, 0xfdf6c83b, 0xfdf3ec01, 0xfdf0f04a,
|
||||
0xfdedd3d1, 0xfdea953d, 0xfde7331e, 0xfde3abe9, 0xfddffdfb,
|
||||
0xfddc2791, 0xfdd826cd, 0xfdd3f9a8, 0xfdcf9dfc, 0xfdcb1176,
|
||||
0xfdc65198, 0xfdc15bb3, 0xfdbc2ce2, 0xfdb6c206, 0xfdb117be,
|
||||
0xfdab2a63, 0xfda4f5fd, 0xfd9e7640, 0xfd97a67a, 0xfd908192,
|
||||
0xfd8901f2, 0xfd812182, 0xfd78d98e, 0xfd7022bb, 0xfd66f4ed,
|
||||
0xfd5d4732, 0xfd530f9c, 0xfd48432b, 0xfd3cd59a, 0xfd30b936,
|
||||
0xfd23dea4, 0xfd16349e, 0xfd07a7a3, 0xfcf8219b, 0xfce7895b,
|
||||
0xfcd5c220, 0xfcc2aadb, 0xfcae1d5e, 0xfc97ed4e, 0xfc7fe6d4,
|
||||
0xfc65ccf3, 0xfc495762, 0xfc2a2fc8, 0xfc07ee19, 0xfbe213c1,
|
||||
0xfbb8051a, 0xfb890078, 0xfb5411a5, 0xfb180005, 0xfad33482,
|
||||
0xfa839276, 0xfa263b32, 0xf9b72d1c, 0xf930a1a2, 0xf889f023,
|
||||
0xf7b577d2, 0xf69c650c, 0xf51530f0, 0xf2cb0e3c, 0xeeefb15d,
|
||||
0xe6da6ecf,
|
||||
}
|
||||
var we = [256]float32{
|
||||
2.0249555e-09, 1.486674e-11, 2.4409617e-11, 3.1968806e-11,
|
||||
3.844677e-11, 4.4228204e-11, 4.9516443e-11, 5.443359e-11,
|
||||
5.905944e-11, 6.344942e-11, 6.7643814e-11, 7.1672945e-11,
|
||||
7.556032e-11, 7.932458e-11, 8.298079e-11, 8.654132e-11,
|
||||
9.0016515e-11, 9.3415074e-11, 9.674443e-11, 1.0001099e-10,
|
||||
1.03220314e-10, 1.06377254e-10, 1.09486115e-10, 1.1255068e-10,
|
||||
1.1557435e-10, 1.1856015e-10, 1.2151083e-10, 1.2442886e-10,
|
||||
1.2731648e-10, 1.3017575e-10, 1.3300853e-10, 1.3581657e-10,
|
||||
1.3860142e-10, 1.4136457e-10, 1.4410738e-10, 1.4683108e-10,
|
||||
1.4953687e-10, 1.5222583e-10, 1.54899e-10, 1.5755733e-10,
|
||||
1.6020171e-10, 1.6283301e-10, 1.6545203e-10, 1.6805951e-10,
|
||||
1.7065617e-10, 1.732427e-10, 1.7581973e-10, 1.7838787e-10,
|
||||
1.8094774e-10, 1.8349985e-10, 1.8604476e-10, 1.8858298e-10,
|
||||
1.9111498e-10, 1.9364126e-10, 1.9616223e-10, 1.9867835e-10,
|
||||
2.0119004e-10, 2.0369768e-10, 2.0620168e-10, 2.087024e-10,
|
||||
2.1120022e-10, 2.136955e-10, 2.1618855e-10, 2.1867974e-10,
|
||||
2.2116936e-10, 2.2365775e-10, 2.261452e-10, 2.2863202e-10,
|
||||
2.311185e-10, 2.3360494e-10, 2.360916e-10, 2.3857874e-10,
|
||||
2.4106667e-10, 2.4355562e-10, 2.4604588e-10, 2.485377e-10,
|
||||
2.5103128e-10, 2.5352695e-10, 2.560249e-10, 2.585254e-10,
|
||||
2.6102867e-10, 2.6353494e-10, 2.6604446e-10, 2.6855745e-10,
|
||||
2.7107416e-10, 2.7359479e-10, 2.761196e-10, 2.7864877e-10,
|
||||
2.8118255e-10, 2.8372119e-10, 2.8626485e-10, 2.888138e-10,
|
||||
2.9136826e-10, 2.939284e-10, 2.9649452e-10, 2.9906677e-10,
|
||||
3.016454e-10, 3.0423064e-10, 3.0682268e-10, 3.0942177e-10,
|
||||
3.1202813e-10, 3.1464195e-10, 3.1726352e-10, 3.19893e-10,
|
||||
3.2253064e-10, 3.251767e-10, 3.2783135e-10, 3.3049485e-10,
|
||||
3.3316744e-10, 3.3584938e-10, 3.3854083e-10, 3.4124212e-10,
|
||||
3.4395342e-10, 3.46675e-10, 3.4940711e-10, 3.5215003e-10,
|
||||
3.5490397e-10, 3.5766917e-10, 3.6044595e-10, 3.6323455e-10,
|
||||
3.660352e-10, 3.6884823e-10, 3.7167386e-10, 3.745124e-10,
|
||||
3.773641e-10, 3.802293e-10, 3.8310827e-10, 3.860013e-10,
|
||||
3.8890866e-10, 3.918307e-10, 3.9476775e-10, 3.9772008e-10,
|
||||
4.0068804e-10, 4.0367196e-10, 4.0667217e-10, 4.09689e-10,
|
||||
4.1272286e-10, 4.1577405e-10, 4.1884296e-10, 4.2192994e-10,
|
||||
4.250354e-10, 4.281597e-10, 4.313033e-10, 4.3446652e-10,
|
||||
4.3764986e-10, 4.408537e-10, 4.4407847e-10, 4.4732465e-10,
|
||||
4.5059267e-10, 4.5388301e-10, 4.571962e-10, 4.6053267e-10,
|
||||
4.6389292e-10, 4.6727755e-10, 4.70687e-10, 4.741219e-10,
|
||||
4.7758275e-10, 4.810702e-10, 4.845848e-10, 4.8812715e-10,
|
||||
4.9169796e-10, 4.9529775e-10, 4.989273e-10, 5.0258725e-10,
|
||||
5.0627835e-10, 5.100013e-10, 5.1375687e-10, 5.1754584e-10,
|
||||
5.21369e-10, 5.2522725e-10, 5.2912136e-10, 5.330522e-10,
|
||||
5.370208e-10, 5.4102806e-10, 5.45075e-10, 5.491625e-10,
|
||||
5.532918e-10, 5.5746385e-10, 5.616799e-10, 5.6594107e-10,
|
||||
5.7024857e-10, 5.746037e-10, 5.7900773e-10, 5.834621e-10,
|
||||
5.8796823e-10, 5.925276e-10, 5.971417e-10, 6.018122e-10,
|
||||
6.065408e-10, 6.113292e-10, 6.1617933e-10, 6.2109295e-10,
|
||||
6.260722e-10, 6.3111916e-10, 6.3623595e-10, 6.4142497e-10,
|
||||
6.4668854e-10, 6.5202926e-10, 6.5744976e-10, 6.6295286e-10,
|
||||
6.6854156e-10, 6.742188e-10, 6.79988e-10, 6.858526e-10,
|
||||
6.9181616e-10, 6.978826e-10, 7.04056e-10, 7.103407e-10,
|
||||
7.167412e-10, 7.2326256e-10, 7.2990985e-10, 7.366886e-10,
|
||||
7.4360473e-10, 7.5066453e-10, 7.5787476e-10, 7.6524265e-10,
|
||||
7.7277595e-10, 7.80483e-10, 7.883728e-10, 7.9645507e-10,
|
||||
8.047402e-10, 8.1323964e-10, 8.219657e-10, 8.309319e-10,
|
||||
8.401528e-10, 8.496445e-10, 8.594247e-10, 8.6951274e-10,
|
||||
8.799301e-10, 8.9070046e-10, 9.018503e-10, 9.134092e-10,
|
||||
9.254101e-10, 9.378904e-10, 9.508923e-10, 9.644638e-10,
|
||||
9.786603e-10, 9.935448e-10, 1.0091913e-09, 1.025686e-09,
|
||||
1.0431306e-09, 1.0616465e-09, 1.08138e-09, 1.1025096e-09,
|
||||
1.1252564e-09, 1.1498986e-09, 1.1767932e-09, 1.206409e-09,
|
||||
1.2393786e-09, 1.276585e-09, 1.3193139e-09, 1.3695435e-09,
|
||||
1.4305498e-09, 1.508365e-09, 1.6160854e-09, 1.7921248e-09,
|
||||
}
|
||||
var fe = [256]float32{
|
||||
1, 0.9381437, 0.90046996, 0.87170434, 0.8477855, 0.8269933,
|
||||
0.8084217, 0.7915276, 0.77595687, 0.7614634, 0.7478686,
|
||||
0.7350381, 0.72286767, 0.71127474, 0.70019263, 0.6895665,
|
||||
0.67935055, 0.6695063, 0.66000086, 0.65080583, 0.6418967,
|
||||
0.63325197, 0.6248527, 0.6166822, 0.60872537, 0.60096896,
|
||||
0.5934009, 0.58601034, 0.5787874, 0.57172304, 0.5648092,
|
||||
0.5580383, 0.5514034, 0.5448982, 0.5385169, 0.53225386,
|
||||
0.5261042, 0.52006316, 0.5141264, 0.50828975, 0.5025495,
|
||||
0.496902, 0.49134386, 0.485872, 0.48048335, 0.4751752,
|
||||
0.46994483, 0.46478975, 0.45970762, 0.45469615, 0.44975325,
|
||||
0.44487688, 0.44006512, 0.43531612, 0.43062815, 0.42599955,
|
||||
0.42142874, 0.4169142, 0.41245446, 0.40804818, 0.403694,
|
||||
0.3993907, 0.39513698, 0.39093173, 0.38677382, 0.38266218,
|
||||
0.37859577, 0.37457356, 0.37059465, 0.3666581, 0.362763,
|
||||
0.35890847, 0.35509375, 0.351318, 0.3475805, 0.34388044,
|
||||
0.34021714, 0.3365899, 0.33299807, 0.32944095, 0.32591796,
|
||||
0.3224285, 0.3189719, 0.31554767, 0.31215525, 0.30879408,
|
||||
0.3054636, 0.3021634, 0.29889292, 0.2956517, 0.29243928,
|
||||
0.28925523, 0.28609908, 0.28297043, 0.27986884, 0.27679393,
|
||||
0.2737453, 0.2707226, 0.2677254, 0.26475343, 0.26180625,
|
||||
0.25888354, 0.25598502, 0.2531103, 0.25025907, 0.24743107,
|
||||
0.24462597, 0.24184346, 0.23908329, 0.23634516, 0.23362878,
|
||||
0.23093392, 0.2282603, 0.22560766, 0.22297576, 0.22036438,
|
||||
0.21777324, 0.21520215, 0.21265087, 0.21011916, 0.20760682,
|
||||
0.20511365, 0.20263945, 0.20018397, 0.19774707, 0.19532852,
|
||||
0.19292815, 0.19054577, 0.1881812, 0.18583426, 0.18350479,
|
||||
0.1811926, 0.17889754, 0.17661946, 0.17435817, 0.17211354,
|
||||
0.1698854, 0.16767362, 0.16547804, 0.16329853, 0.16113494,
|
||||
0.15898713, 0.15685499, 0.15473837, 0.15263714, 0.15055119,
|
||||
0.14848037, 0.14642459, 0.14438373, 0.14235765, 0.14034624,
|
||||
0.13834943, 0.13636707, 0.13439907, 0.13244532, 0.13050574,
|
||||
0.1285802, 0.12666863, 0.12477092, 0.12288698, 0.12101672,
|
||||
0.119160056, 0.1173169, 0.115487166, 0.11367077, 0.11186763,
|
||||
0.11007768, 0.10830083, 0.10653701, 0.10478614, 0.10304816,
|
||||
0.101323, 0.09961058, 0.09791085, 0.09622374, 0.09454919,
|
||||
0.09288713, 0.091237515, 0.08960028, 0.087975375, 0.08636274,
|
||||
0.08476233, 0.083174095, 0.081597984, 0.08003395, 0.07848195,
|
||||
0.076941945, 0.07541389, 0.07389775, 0.072393484, 0.07090106,
|
||||
0.069420435, 0.06795159, 0.066494495, 0.06504912, 0.063615434,
|
||||
0.062193416, 0.060783047, 0.059384305, 0.057997175,
|
||||
0.05662164, 0.05525769, 0.053905312, 0.052564494, 0.051235236,
|
||||
0.049917534, 0.048611384, 0.047316793, 0.046033762, 0.0447623,
|
||||
0.043502413, 0.042254124, 0.041017443, 0.039792392,
|
||||
0.038578995, 0.037377283, 0.036187284, 0.035009038,
|
||||
0.033842582, 0.032687962, 0.031545233, 0.030414443, 0.02929566,
|
||||
0.02818895, 0.027094385, 0.026012046, 0.024942026, 0.023884421,
|
||||
0.022839336, 0.021806888, 0.020787204, 0.019780423, 0.0187867,
|
||||
0.0178062, 0.016839107, 0.015885621, 0.014945968, 0.014020392,
|
||||
0.013109165, 0.012212592, 0.011331013, 0.01046481, 0.009614414,
|
||||
0.008780315, 0.007963077, 0.0071633533, 0.006381906,
|
||||
0.0056196423, 0.0048776558, 0.004157295, 0.0034602648,
|
||||
0.0027887989, 0.0021459677, 0.0015362998, 0.0009672693,
|
||||
0.00045413437,
|
||||
}
|
156
vendor/golang.org/x/exp/rand/normal.go
generated
vendored
Normal file
156
vendor/golang.org/x/exp/rand/normal.go
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright 2009 The Go 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 rand
|
||||
|
||||
import (
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
* Normal distribution
|
||||
*
|
||||
* See "The Ziggurat Method for Generating Random Variables"
|
||||
* (Marsaglia & Tsang, 2000)
|
||||
* http://www.jstatsoft.org/v05/i08/paper [pdf]
|
||||
*/
|
||||
|
||||
const (
|
||||
rn = 3.442619855899
|
||||
)
|
||||
|
||||
func absInt32(i int32) uint32 {
|
||||
if i < 0 {
|
||||
return uint32(-i)
|
||||
}
|
||||
return uint32(i)
|
||||
}
|
||||
|
||||
// NormFloat64 returns a normally distributed float64 in the range
|
||||
// [-math.MaxFloat64, +math.MaxFloat64] with
|
||||
// standard normal distribution (mean = 0, stddev = 1).
|
||||
// To produce a different normal distribution, callers can
|
||||
// adjust the output using:
|
||||
//
|
||||
// sample = NormFloat64() * desiredStdDev + desiredMean
|
||||
func (r *Rand) NormFloat64() float64 {
|
||||
for {
|
||||
j := int32(r.Uint32()) // Possibly negative
|
||||
i := j & 0x7F
|
||||
x := float64(j) * float64(wn[i])
|
||||
if absInt32(j) < kn[i] {
|
||||
// This case should be hit better than 99% of the time.
|
||||
return x
|
||||
}
|
||||
|
||||
if i == 0 {
|
||||
// This extra work is only required for the base strip.
|
||||
for {
|
||||
x = -math.Log(r.Float64()) * (1.0 / rn)
|
||||
y := -math.Log(r.Float64())
|
||||
if y+y >= x*x {
|
||||
break
|
||||
}
|
||||
}
|
||||
if j > 0 {
|
||||
return rn + x
|
||||
}
|
||||
return -rn - x
|
||||
}
|
||||
if fn[i]+float32(r.Float64())*(fn[i-1]-fn[i]) < float32(math.Exp(-.5*x*x)) {
|
||||
return x
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var kn = [128]uint32{
|
||||
0x76ad2212, 0x0, 0x600f1b53, 0x6ce447a6, 0x725b46a2,
|
||||
0x7560051d, 0x774921eb, 0x789a25bd, 0x799045c3, 0x7a4bce5d,
|
||||
0x7adf629f, 0x7b5682a6, 0x7bb8a8c6, 0x7c0ae722, 0x7c50cce7,
|
||||
0x7c8cec5b, 0x7cc12cd6, 0x7ceefed2, 0x7d177e0b, 0x7d3b8883,
|
||||
0x7d5bce6c, 0x7d78dd64, 0x7d932886, 0x7dab0e57, 0x7dc0dd30,
|
||||
0x7dd4d688, 0x7de73185, 0x7df81cea, 0x7e07c0a3, 0x7e163efa,
|
||||
0x7e23b587, 0x7e303dfd, 0x7e3beec2, 0x7e46db77, 0x7e51155d,
|
||||
0x7e5aabb3, 0x7e63abf7, 0x7e6c222c, 0x7e741906, 0x7e7b9a18,
|
||||
0x7e82adfa, 0x7e895c63, 0x7e8fac4b, 0x7e95a3fb, 0x7e9b4924,
|
||||
0x7ea0a0ef, 0x7ea5b00d, 0x7eaa7ac3, 0x7eaf04f3, 0x7eb3522a,
|
||||
0x7eb765a5, 0x7ebb4259, 0x7ebeeafd, 0x7ec2620a, 0x7ec5a9c4,
|
||||
0x7ec8c441, 0x7ecbb365, 0x7ece78ed, 0x7ed11671, 0x7ed38d62,
|
||||
0x7ed5df12, 0x7ed80cb4, 0x7eda175c, 0x7edc0005, 0x7eddc78e,
|
||||
0x7edf6ebf, 0x7ee0f647, 0x7ee25ebe, 0x7ee3a8a9, 0x7ee4d473,
|
||||
0x7ee5e276, 0x7ee6d2f5, 0x7ee7a620, 0x7ee85c10, 0x7ee8f4cd,
|
||||
0x7ee97047, 0x7ee9ce59, 0x7eea0eca, 0x7eea3147, 0x7eea3568,
|
||||
0x7eea1aab, 0x7ee9e071, 0x7ee98602, 0x7ee90a88, 0x7ee86d08,
|
||||
0x7ee7ac6a, 0x7ee6c769, 0x7ee5bc9c, 0x7ee48a67, 0x7ee32efc,
|
||||
0x7ee1a857, 0x7edff42f, 0x7ede0ffa, 0x7edbf8d9, 0x7ed9ab94,
|
||||
0x7ed7248d, 0x7ed45fae, 0x7ed1585c, 0x7ece095f, 0x7eca6ccb,
|
||||
0x7ec67be2, 0x7ec22eee, 0x7ebd7d1a, 0x7eb85c35, 0x7eb2c075,
|
||||
0x7eac9c20, 0x7ea5df27, 0x7e9e769f, 0x7e964c16, 0x7e8d44ba,
|
||||
0x7e834033, 0x7e781728, 0x7e6b9933, 0x7e5d8a1a, 0x7e4d9ded,
|
||||
0x7e3b737a, 0x7e268c2f, 0x7e0e3ff5, 0x7df1aa5d, 0x7dcf8c72,
|
||||
0x7da61a1e, 0x7d72a0fb, 0x7d30e097, 0x7cd9b4ab, 0x7c600f1a,
|
||||
0x7ba90bdc, 0x7a722176, 0x77d664e5,
|
||||
}
|
||||
var wn = [128]float32{
|
||||
1.7290405e-09, 1.2680929e-10, 1.6897518e-10, 1.9862688e-10,
|
||||
2.2232431e-10, 2.4244937e-10, 2.601613e-10, 2.7611988e-10,
|
||||
2.9073963e-10, 3.042997e-10, 3.1699796e-10, 3.289802e-10,
|
||||
3.4035738e-10, 3.5121603e-10, 3.616251e-10, 3.7164058e-10,
|
||||
3.8130857e-10, 3.9066758e-10, 3.9975012e-10, 4.08584e-10,
|
||||
4.1719309e-10, 4.2559822e-10, 4.338176e-10, 4.418672e-10,
|
||||
4.497613e-10, 4.5751258e-10, 4.651324e-10, 4.7263105e-10,
|
||||
4.8001775e-10, 4.87301e-10, 4.944885e-10, 5.015873e-10,
|
||||
5.0860405e-10, 5.155446e-10, 5.2241467e-10, 5.2921934e-10,
|
||||
5.359635e-10, 5.426517e-10, 5.4928817e-10, 5.5587696e-10,
|
||||
5.624219e-10, 5.6892646e-10, 5.753941e-10, 5.818282e-10,
|
||||
5.882317e-10, 5.946077e-10, 6.00959e-10, 6.072884e-10,
|
||||
6.135985e-10, 6.19892e-10, 6.2617134e-10, 6.3243905e-10,
|
||||
6.386974e-10, 6.449488e-10, 6.511956e-10, 6.5744005e-10,
|
||||
6.6368433e-10, 6.699307e-10, 6.7618144e-10, 6.824387e-10,
|
||||
6.8870465e-10, 6.949815e-10, 7.012715e-10, 7.075768e-10,
|
||||
7.1389966e-10, 7.202424e-10, 7.266073e-10, 7.329966e-10,
|
||||
7.394128e-10, 7.4585826e-10, 7.5233547e-10, 7.58847e-10,
|
||||
7.653954e-10, 7.719835e-10, 7.7861395e-10, 7.852897e-10,
|
||||
7.920138e-10, 7.987892e-10, 8.0561924e-10, 8.125073e-10,
|
||||
8.194569e-10, 8.2647167e-10, 8.3355556e-10, 8.407127e-10,
|
||||
8.479473e-10, 8.55264e-10, 8.6266755e-10, 8.7016316e-10,
|
||||
8.777562e-10, 8.8545243e-10, 8.932582e-10, 9.0117996e-10,
|
||||
9.09225e-10, 9.174008e-10, 9.2571584e-10, 9.341788e-10,
|
||||
9.427997e-10, 9.515889e-10, 9.605579e-10, 9.697193e-10,
|
||||
9.790869e-10, 9.88676e-10, 9.985036e-10, 1.0085882e-09,
|
||||
1.0189509e-09, 1.0296151e-09, 1.0406069e-09, 1.0519566e-09,
|
||||
1.063698e-09, 1.0758702e-09, 1.0885183e-09, 1.1016947e-09,
|
||||
1.1154611e-09, 1.1298902e-09, 1.1450696e-09, 1.1611052e-09,
|
||||
1.1781276e-09, 1.1962995e-09, 1.2158287e-09, 1.2369856e-09,
|
||||
1.2601323e-09, 1.2857697e-09, 1.3146202e-09, 1.347784e-09,
|
||||
1.3870636e-09, 1.4357403e-09, 1.5008659e-09, 1.6030948e-09,
|
||||
}
|
||||
var fn = [128]float32{
|
||||
1, 0.9635997, 0.9362827, 0.9130436, 0.89228165, 0.87324303,
|
||||
0.8555006, 0.8387836, 0.8229072, 0.8077383, 0.793177,
|
||||
0.7791461, 0.7655842, 0.7524416, 0.73967725, 0.7272569,
|
||||
0.7151515, 0.7033361, 0.69178915, 0.68049186, 0.6694277,
|
||||
0.658582, 0.6479418, 0.63749546, 0.6272325, 0.6171434,
|
||||
0.6072195, 0.5974532, 0.58783704, 0.5783647, 0.56903,
|
||||
0.5598274, 0.5507518, 0.54179835, 0.5329627, 0.52424055,
|
||||
0.5156282, 0.50712204, 0.49871865, 0.49041483, 0.48220766,
|
||||
0.4740943, 0.46607214, 0.4581387, 0.45029163, 0.44252872,
|
||||
0.43484783, 0.427247, 0.41972435, 0.41227803, 0.40490642,
|
||||
0.39760786, 0.3903808, 0.3832238, 0.37613547, 0.36911446,
|
||||
0.3621595, 0.35526937, 0.34844297, 0.34167916, 0.33497685,
|
||||
0.3283351, 0.3217529, 0.3152294, 0.30876362, 0.30235484,
|
||||
0.29600215, 0.28970486, 0.2834622, 0.2772735, 0.27113807,
|
||||
0.2650553, 0.25902456, 0.2530453, 0.24711695, 0.241239,
|
||||
0.23541094, 0.22963232, 0.2239027, 0.21822165, 0.21258877,
|
||||
0.20700371, 0.20146611, 0.19597565, 0.19053204, 0.18513499,
|
||||
0.17978427, 0.17447963, 0.1692209, 0.16400786, 0.15884037,
|
||||
0.15371831, 0.14864157, 0.14361008, 0.13862377, 0.13368265,
|
||||
0.12878671, 0.12393598, 0.119130544, 0.11437051, 0.10965602,
|
||||
0.104987256, 0.10036444, 0.095787846, 0.0912578, 0.08677467,
|
||||
0.0823389, 0.077950984, 0.073611505, 0.06932112, 0.06508058,
|
||||
0.06089077, 0.056752663, 0.0526674, 0.048636295, 0.044660863,
|
||||
0.040742867, 0.03688439, 0.033087887, 0.029356318,
|
||||
0.025693292, 0.022103304, 0.018592102, 0.015167298,
|
||||
0.011839478, 0.008624485, 0.005548995, 0.0026696292,
|
||||
}
|
372
vendor/golang.org/x/exp/rand/rand.go
generated
vendored
Normal file
372
vendor/golang.org/x/exp/rand/rand.go
generated
vendored
Normal file
@@ -0,0 +1,372 @@
|
||||
// Copyright 2009 The Go 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 rand implements pseudo-random number generators.
|
||||
//
|
||||
// Random numbers are generated by a Source. Top-level functions, such as
|
||||
// Float64 and Int, use a default shared Source that produces a deterministic
|
||||
// sequence of values each time a program is run. Use the Seed function to
|
||||
// initialize the default Source if different behavior is required for each run.
|
||||
// The default Source, a LockedSource, is safe for concurrent use by multiple
|
||||
// goroutines, but Sources created by NewSource are not. However, Sources are small
|
||||
// and it is reasonable to have a separate Source for each goroutine, seeded
|
||||
// differently, to avoid locking.
|
||||
//
|
||||
// For random numbers suitable for security-sensitive work, see the crypto/rand
|
||||
// package.
|
||||
package rand
|
||||
|
||||
import "sync"
|
||||
|
||||
// A Source represents a source of uniformly-distributed
|
||||
// pseudo-random int64 values in the range [0, 1<<64).
|
||||
type Source interface {
|
||||
Uint64() uint64
|
||||
Seed(seed uint64)
|
||||
}
|
||||
|
||||
// NewSource returns a new pseudo-random Source seeded with the given value.
|
||||
func NewSource(seed uint64) Source {
|
||||
var rng PCGSource
|
||||
rng.Seed(seed)
|
||||
return &rng
|
||||
}
|
||||
|
||||
// A Rand is a source of random numbers.
|
||||
type Rand struct {
|
||||
src Source
|
||||
|
||||
// readVal contains remainder of 64-bit integer used for bytes
|
||||
// generation during most recent Read call.
|
||||
// It is saved so next Read call can start where the previous
|
||||
// one finished.
|
||||
readVal uint64
|
||||
// readPos indicates the number of low-order bytes of readVal
|
||||
// that are still valid.
|
||||
readPos int8
|
||||
}
|
||||
|
||||
// New returns a new Rand that uses random values from src
|
||||
// to generate other random values.
|
||||
func New(src Source) *Rand {
|
||||
return &Rand{src: src}
|
||||
}
|
||||
|
||||
// Seed uses the provided seed value to initialize the generator to a deterministic state.
|
||||
// Seed should not be called concurrently with any other Rand method.
|
||||
func (r *Rand) Seed(seed uint64) {
|
||||
if lk, ok := r.src.(*LockedSource); ok {
|
||||
lk.seedPos(seed, &r.readPos)
|
||||
return
|
||||
}
|
||||
|
||||
r.src.Seed(seed)
|
||||
r.readPos = 0
|
||||
}
|
||||
|
||||
// Uint64 returns a pseudo-random 64-bit integer as a uint64.
|
||||
func (r *Rand) Uint64() uint64 { return r.src.Uint64() }
|
||||
|
||||
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64.
|
||||
func (r *Rand) Int63() int64 { return int64(r.src.Uint64() &^ (1 << 63)) }
|
||||
|
||||
// Uint32 returns a pseudo-random 32-bit value as a uint32.
|
||||
func (r *Rand) Uint32() uint32 { return uint32(r.Uint64() >> 32) }
|
||||
|
||||
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32.
|
||||
func (r *Rand) Int31() int32 { return int32(r.Uint64() >> 33) }
|
||||
|
||||
// Int returns a non-negative pseudo-random int.
|
||||
func (r *Rand) Int() int {
|
||||
u := uint(r.Uint64())
|
||||
return int(u << 1 >> 1) // clear sign bit.
|
||||
}
|
||||
|
||||
const maxUint64 = (1 << 64) - 1
|
||||
|
||||
// Uint64n returns, as a uint64, a pseudo-random number in [0,n).
|
||||
// It is guaranteed more uniform than taking a Source value mod n
|
||||
// for any n that is not a power of 2.
|
||||
func (r *Rand) Uint64n(n uint64) uint64 {
|
||||
if n&(n-1) == 0 { // n is power of two, can mask
|
||||
if n == 0 {
|
||||
panic("invalid argument to Uint64n")
|
||||
}
|
||||
return r.Uint64() & (n - 1)
|
||||
}
|
||||
// If n does not divide v, to avoid bias we must not use
|
||||
// a v that is within maxUint64%n of the top of the range.
|
||||
v := r.Uint64()
|
||||
if v > maxUint64-n { // Fast check.
|
||||
ceiling := maxUint64 - maxUint64%n
|
||||
for v >= ceiling {
|
||||
v = r.Uint64()
|
||||
}
|
||||
}
|
||||
|
||||
return v % n
|
||||
}
|
||||
|
||||
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n).
|
||||
// It panics if n <= 0.
|
||||
func (r *Rand) Int63n(n int64) int64 {
|
||||
if n <= 0 {
|
||||
panic("invalid argument to Int63n")
|
||||
}
|
||||
return int64(r.Uint64n(uint64(n)))
|
||||
}
|
||||
|
||||
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n).
|
||||
// It panics if n <= 0.
|
||||
func (r *Rand) Int31n(n int32) int32 {
|
||||
if n <= 0 {
|
||||
panic("invalid argument to Int31n")
|
||||
}
|
||||
// TODO: Avoid some 64-bit ops to make it more efficient on 32-bit machines.
|
||||
return int32(r.Uint64n(uint64(n)))
|
||||
}
|
||||
|
||||
// Intn returns, as an int, a non-negative pseudo-random number in [0,n).
|
||||
// It panics if n <= 0.
|
||||
func (r *Rand) Intn(n int) int {
|
||||
if n <= 0 {
|
||||
panic("invalid argument to Intn")
|
||||
}
|
||||
// TODO: Avoid some 64-bit ops to make it more efficient on 32-bit machines.
|
||||
return int(r.Uint64n(uint64(n)))
|
||||
}
|
||||
|
||||
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0).
|
||||
func (r *Rand) Float64() float64 {
|
||||
// There is one bug in the value stream: r.Int63() may be so close
|
||||
// to 1<<63 that the division rounds up to 1.0, and we've guaranteed
|
||||
// that the result is always less than 1.0.
|
||||
//
|
||||
// We tried to fix this by mapping 1.0 back to 0.0, but since float64
|
||||
// values near 0 are much denser than near 1, mapping 1 to 0 caused
|
||||
// a theoretically significant overshoot in the probability of returning 0.
|
||||
// Instead of that, if we round up to 1, just try again.
|
||||
// Getting 1 only happens 1/2⁵³ of the time, so most clients
|
||||
// will not observe it anyway.
|
||||
again:
|
||||
f := float64(r.Uint64n(1<<53)) / (1 << 53)
|
||||
if f == 1.0 {
|
||||
goto again // resample; this branch is taken O(never)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0).
|
||||
func (r *Rand) Float32() float32 {
|
||||
// We do not want to return 1.0.
|
||||
// This only happens 1/2²⁴ of the time (plus the 1/2⁵³ of the time in Float64).
|
||||
again:
|
||||
f := float32(r.Float64())
|
||||
if f == 1 {
|
||||
goto again // resample; this branch is taken O(very rarely)
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n).
|
||||
func (r *Rand) Perm(n int) []int {
|
||||
m := make([]int, n)
|
||||
// In the following loop, the iteration when i=0 always swaps m[0] with m[0].
|
||||
// A change to remove this useless iteration is to assign 1 to i in the init
|
||||
// statement. But Perm also effects r. Making this change will affect
|
||||
// the final state of r. So this change can't be made for compatibility
|
||||
// reasons for Go 1.
|
||||
for i := 0; i < n; i++ {
|
||||
j := r.Intn(i + 1)
|
||||
m[i] = m[j]
|
||||
m[j] = i
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// Shuffle pseudo-randomizes the order of elements.
|
||||
// n is the number of elements. Shuffle panics if n < 0.
|
||||
// swap swaps the elements with indexes i and j.
|
||||
func (r *Rand) Shuffle(n int, swap func(i, j int)) {
|
||||
if n < 0 {
|
||||
panic("invalid argument to Shuffle")
|
||||
}
|
||||
|
||||
// Fisher-Yates shuffle: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
|
||||
// Shuffle really ought not be called with n that doesn't fit in 32 bits.
|
||||
// Not only will it take a very long time, but with 2³¹! possible permutations,
|
||||
// there's no way that any PRNG can have a big enough internal state to
|
||||
// generate even a minuscule percentage of the possible permutations.
|
||||
// Nevertheless, the right API signature accepts an int n, so handle it as best we can.
|
||||
i := n - 1
|
||||
for ; i > 1<<31-1-1; i-- {
|
||||
j := int(r.Int63n(int64(i + 1)))
|
||||
swap(i, j)
|
||||
}
|
||||
for ; i > 0; i-- {
|
||||
j := int(r.Int31n(int32(i + 1)))
|
||||
swap(i, j)
|
||||
}
|
||||
}
|
||||
|
||||
// Read generates len(p) random bytes and writes them into p. It
|
||||
// always returns len(p) and a nil error.
|
||||
// Read should not be called concurrently with any other Rand method unless
|
||||
// the underlying source is a LockedSource.
|
||||
func (r *Rand) Read(p []byte) (n int, err error) {
|
||||
if lk, ok := r.src.(*LockedSource); ok {
|
||||
return lk.Read(p, &r.readVal, &r.readPos)
|
||||
}
|
||||
return read(p, r.src, &r.readVal, &r.readPos)
|
||||
}
|
||||
|
||||
func read(p []byte, src Source, readVal *uint64, readPos *int8) (n int, err error) {
|
||||
pos := *readPos
|
||||
val := *readVal
|
||||
rng, _ := src.(*PCGSource)
|
||||
for n = 0; n < len(p); n++ {
|
||||
if pos == 0 {
|
||||
if rng != nil {
|
||||
val = rng.Uint64()
|
||||
} else {
|
||||
val = src.Uint64()
|
||||
}
|
||||
pos = 8
|
||||
}
|
||||
p[n] = byte(val)
|
||||
val >>= 8
|
||||
pos--
|
||||
}
|
||||
*readPos = pos
|
||||
*readVal = val
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
* Top-level convenience functions
|
||||
*/
|
||||
|
||||
var globalRand = New(&LockedSource{src: *NewSource(1).(*PCGSource)})
|
||||
|
||||
// Type assert that globalRand's source is a LockedSource whose src is a PCGSource.
|
||||
var _ PCGSource = globalRand.src.(*LockedSource).src
|
||||
|
||||
// Seed uses the provided seed value to initialize the default Source to a
|
||||
// deterministic state. If Seed is not called, the generator behaves as
|
||||
// if seeded by Seed(1).
|
||||
// Seed, unlike the Rand.Seed method, is safe for concurrent use.
|
||||
func Seed(seed uint64) { globalRand.Seed(seed) }
|
||||
|
||||
// Int63 returns a non-negative pseudo-random 63-bit integer as an int64
|
||||
// from the default Source.
|
||||
func Int63() int64 { return globalRand.Int63() }
|
||||
|
||||
// Uint32 returns a pseudo-random 32-bit value as a uint32
|
||||
// from the default Source.
|
||||
func Uint32() uint32 { return globalRand.Uint32() }
|
||||
|
||||
// Uint64 returns a pseudo-random 64-bit value as a uint64
|
||||
// from the default Source.
|
||||
func Uint64() uint64 { return globalRand.Uint64() }
|
||||
|
||||
// Int31 returns a non-negative pseudo-random 31-bit integer as an int32
|
||||
// from the default Source.
|
||||
func Int31() int32 { return globalRand.Int31() }
|
||||
|
||||
// Int returns a non-negative pseudo-random int from the default Source.
|
||||
func Int() int { return globalRand.Int() }
|
||||
|
||||
// Int63n returns, as an int64, a non-negative pseudo-random number in [0,n)
|
||||
// from the default Source.
|
||||
// It panics if n <= 0.
|
||||
func Int63n(n int64) int64 { return globalRand.Int63n(n) }
|
||||
|
||||
// Int31n returns, as an int32, a non-negative pseudo-random number in [0,n)
|
||||
// from the default Source.
|
||||
// It panics if n <= 0.
|
||||
func Int31n(n int32) int32 { return globalRand.Int31n(n) }
|
||||
|
||||
// Intn returns, as an int, a non-negative pseudo-random number in [0,n)
|
||||
// from the default Source.
|
||||
// It panics if n <= 0.
|
||||
func Intn(n int) int { return globalRand.Intn(n) }
|
||||
|
||||
// Float64 returns, as a float64, a pseudo-random number in [0.0,1.0)
|
||||
// from the default Source.
|
||||
func Float64() float64 { return globalRand.Float64() }
|
||||
|
||||
// Float32 returns, as a float32, a pseudo-random number in [0.0,1.0)
|
||||
// from the default Source.
|
||||
func Float32() float32 { return globalRand.Float32() }
|
||||
|
||||
// Perm returns, as a slice of n ints, a pseudo-random permutation of the integers [0,n)
|
||||
// from the default Source.
|
||||
func Perm(n int) []int { return globalRand.Perm(n) }
|
||||
|
||||
// Shuffle pseudo-randomizes the order of elements using the default Source.
|
||||
// n is the number of elements. Shuffle panics if n < 0.
|
||||
// swap swaps the elements with indexes i and j.
|
||||
func Shuffle(n int, swap func(i, j int)) { globalRand.Shuffle(n, swap) }
|
||||
|
||||
// Read generates len(p) random bytes from the default Source and
|
||||
// writes them into p. It always returns len(p) and a nil error.
|
||||
// Read, unlike the Rand.Read method, is safe for concurrent use.
|
||||
func Read(p []byte) (n int, err error) { return globalRand.Read(p) }
|
||||
|
||||
// NormFloat64 returns a normally distributed float64 in the range
|
||||
// [-math.MaxFloat64, +math.MaxFloat64] with
|
||||
// standard normal distribution (mean = 0, stddev = 1)
|
||||
// from the default Source.
|
||||
// To produce a different normal distribution, callers can
|
||||
// adjust the output using:
|
||||
//
|
||||
// sample = NormFloat64() * desiredStdDev + desiredMean
|
||||
func NormFloat64() float64 { return globalRand.NormFloat64() }
|
||||
|
||||
// ExpFloat64 returns an exponentially distributed float64 in the range
|
||||
// (0, +math.MaxFloat64] with an exponential distribution whose rate parameter
|
||||
// (lambda) is 1 and whose mean is 1/lambda (1) from the default Source.
|
||||
// To produce a distribution with a different rate parameter,
|
||||
// callers can adjust the output using:
|
||||
//
|
||||
// sample = ExpFloat64() / desiredRateParameter
|
||||
func ExpFloat64() float64 { return globalRand.ExpFloat64() }
|
||||
|
||||
// LockedSource is an implementation of Source that is concurrency-safe.
|
||||
// A Rand using a LockedSource is safe for concurrent use.
|
||||
//
|
||||
// The zero value of LockedSource is valid, but should be seeded before use.
|
||||
type LockedSource struct {
|
||||
lk sync.Mutex
|
||||
src PCGSource
|
||||
}
|
||||
|
||||
func (s *LockedSource) Uint64() (n uint64) {
|
||||
s.lk.Lock()
|
||||
n = s.src.Uint64()
|
||||
s.lk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (s *LockedSource) Seed(seed uint64) {
|
||||
s.lk.Lock()
|
||||
s.src.Seed(seed)
|
||||
s.lk.Unlock()
|
||||
}
|
||||
|
||||
// seedPos implements Seed for a LockedSource without a race condiiton.
|
||||
func (s *LockedSource) seedPos(seed uint64, readPos *int8) {
|
||||
s.lk.Lock()
|
||||
s.src.Seed(seed)
|
||||
*readPos = 0
|
||||
s.lk.Unlock()
|
||||
}
|
||||
|
||||
// Read implements Read for a LockedSource.
|
||||
func (s *LockedSource) Read(p []byte, readVal *uint64, readPos *int8) (n int, err error) {
|
||||
s.lk.Lock()
|
||||
n, err = read(p, &s.src, readVal, readPos)
|
||||
s.lk.Unlock()
|
||||
return
|
||||
}
|
91
vendor/golang.org/x/exp/rand/rng.go
generated
vendored
Normal file
91
vendor/golang.org/x/exp/rand/rng.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// 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 rand
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
// PCGSource is an implementation of a 64-bit permuted congruential
|
||||
// generator as defined in
|
||||
//
|
||||
// PCG: A Family of Simple Fast Space-Efficient Statistically Good
|
||||
// Algorithms for Random Number Generation
|
||||
// Melissa E. O’Neill, Harvey Mudd College
|
||||
// http://www.pcg-random.org/pdf/toms-oneill-pcg-family-v1.02.pdf
|
||||
//
|
||||
// The generator here is the congruential generator PCG XSL RR 128/64 (LCG)
|
||||
// as found in the software available at http://www.pcg-random.org/.
|
||||
// It has period 2^128 with 128 bits of state, producing 64-bit values.
|
||||
// Is state is represented by two uint64 words.
|
||||
type PCGSource struct {
|
||||
low uint64
|
||||
high uint64
|
||||
}
|
||||
|
||||
const (
|
||||
maxUint32 = (1 << 32) - 1
|
||||
|
||||
multiplier = 47026247687942121848144207491837523525
|
||||
mulHigh = multiplier >> 64
|
||||
mulLow = multiplier & maxUint64
|
||||
|
||||
increment = 117397592171526113268558934119004209487
|
||||
incHigh = increment >> 64
|
||||
incLow = increment & maxUint64
|
||||
|
||||
// TODO: Use these?
|
||||
initializer = 245720598905631564143578724636268694099
|
||||
initHigh = initializer >> 64
|
||||
initLow = initializer & maxUint64
|
||||
)
|
||||
|
||||
// Seed uses the provided seed value to initialize the generator to a deterministic state.
|
||||
func (pcg *PCGSource) Seed(seed uint64) {
|
||||
pcg.low = seed
|
||||
pcg.high = seed // TODO: What is right?
|
||||
}
|
||||
|
||||
// Uint64 returns a pseudo-random 64-bit unsigned integer as a uint64.
|
||||
func (pcg *PCGSource) Uint64() uint64 {
|
||||
pcg.multiply()
|
||||
pcg.add()
|
||||
// XOR high and low 64 bits together and rotate right by high 6 bits of state.
|
||||
return bits.RotateLeft64(pcg.high^pcg.low, -int(pcg.high>>58))
|
||||
}
|
||||
|
||||
func (pcg *PCGSource) add() {
|
||||
var carry uint64
|
||||
pcg.low, carry = bits.Add64(pcg.low, incLow, 0)
|
||||
pcg.high, _ = bits.Add64(pcg.high, incHigh, carry)
|
||||
}
|
||||
|
||||
func (pcg *PCGSource) multiply() {
|
||||
hi, lo := bits.Mul64(pcg.low, mulLow)
|
||||
hi += pcg.high * mulLow
|
||||
hi += pcg.low * mulHigh
|
||||
pcg.low = lo
|
||||
pcg.high = hi
|
||||
}
|
||||
|
||||
// MarshalBinary returns the binary representation of the current state of the generator.
|
||||
func (pcg *PCGSource) MarshalBinary() ([]byte, error) {
|
||||
var buf [16]byte
|
||||
binary.BigEndian.PutUint64(buf[:8], pcg.high)
|
||||
binary.BigEndian.PutUint64(buf[8:], pcg.low)
|
||||
return buf[:], nil
|
||||
}
|
||||
|
||||
// UnmarshalBinary sets the state of the generator to the state represented in data.
|
||||
func (pcg *PCGSource) UnmarshalBinary(data []byte) error {
|
||||
if len(data) < 16 {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
pcg.low = binary.BigEndian.Uint64(data[8:])
|
||||
pcg.high = binary.BigEndian.Uint64(data[:8])
|
||||
return nil
|
||||
}
|
77
vendor/golang.org/x/exp/rand/zipf.go
generated
vendored
Normal file
77
vendor/golang.org/x/exp/rand/zipf.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// W.Hormann, G.Derflinger:
|
||||
// "Rejection-Inversion to Generate Variates
|
||||
// from Monotone Discrete Distributions"
|
||||
// http://eeyore.wu-wien.ac.at/papers/96-04-04.wh-der.ps.gz
|
||||
|
||||
package rand
|
||||
|
||||
import "math"
|
||||
|
||||
// A Zipf generates Zipf distributed variates.
|
||||
type Zipf struct {
|
||||
r *Rand
|
||||
imax float64
|
||||
v float64
|
||||
q float64
|
||||
s float64
|
||||
oneminusQ float64
|
||||
oneminusQinv float64
|
||||
hxm float64
|
||||
hx0minusHxm float64
|
||||
}
|
||||
|
||||
func (z *Zipf) h(x float64) float64 {
|
||||
return math.Exp(z.oneminusQ*math.Log(z.v+x)) * z.oneminusQinv
|
||||
}
|
||||
|
||||
func (z *Zipf) hinv(x float64) float64 {
|
||||
return math.Exp(z.oneminusQinv*math.Log(z.oneminusQ*x)) - z.v
|
||||
}
|
||||
|
||||
// NewZipf returns a Zipf variate generator.
|
||||
// The generator generates values k ∈ [0, imax]
|
||||
// such that P(k) is proportional to (v + k) ** (-s).
|
||||
// Requirements: s > 1 and v >= 1.
|
||||
func NewZipf(r *Rand, s float64, v float64, imax uint64) *Zipf {
|
||||
z := new(Zipf)
|
||||
if s <= 1.0 || v < 1 {
|
||||
return nil
|
||||
}
|
||||
z.r = r
|
||||
z.imax = float64(imax)
|
||||
z.v = v
|
||||
z.q = s
|
||||
z.oneminusQ = 1.0 - z.q
|
||||
z.oneminusQinv = 1.0 / z.oneminusQ
|
||||
z.hxm = z.h(z.imax + 0.5)
|
||||
z.hx0minusHxm = z.h(0.5) - math.Exp(math.Log(z.v)*(-z.q)) - z.hxm
|
||||
z.s = 1 - z.hinv(z.h(1.5)-math.Exp(-z.q*math.Log(z.v+1.0)))
|
||||
return z
|
||||
}
|
||||
|
||||
// Uint64 returns a value drawn from the Zipf distribution described
|
||||
// by the Zipf object.
|
||||
func (z *Zipf) Uint64() uint64 {
|
||||
if z == nil {
|
||||
panic("rand: nil Zipf")
|
||||
}
|
||||
k := 0.0
|
||||
|
||||
for {
|
||||
r := z.r.Float64() // r on [0,1]
|
||||
ur := z.hxm + r*z.hx0minusHxm
|
||||
x := z.hinv(ur)
|
||||
k = math.Floor(x + 0.5)
|
||||
if k-x <= z.s {
|
||||
break
|
||||
}
|
||||
if ur >= z.h(k+0.5)-math.Exp(-math.Log(k+z.v)*z.q) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return uint64(k)
|
||||
}
|
14
vendor/golang.org/x/mod/modfile/print.go
generated
vendored
14
vendor/golang.org/x/mod/modfile/print.go
generated
vendored
@@ -16,7 +16,13 @@ import (
|
||||
func Format(f *FileSyntax) []byte {
|
||||
pr := &printer{}
|
||||
pr.file(f)
|
||||
return pr.Bytes()
|
||||
|
||||
// remove trailing blank lines
|
||||
b := pr.Bytes()
|
||||
for len(b) > 0 && b[len(b)-1] == '\n' && (len(b) == 1 || b[len(b)-2] == '\n') {
|
||||
b = b[:len(b)-1]
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// A printer collects the state during printing of a file or expression.
|
||||
@@ -59,7 +65,11 @@ func (p *printer) newline() {
|
||||
}
|
||||
|
||||
p.trim()
|
||||
p.printf("\n")
|
||||
if b := p.Bytes(); len(b) == 0 || (len(b) >= 2 && b[len(b)-1] == '\n' && b[len(b)-2] == '\n') {
|
||||
// skip the blank line at top of file or after a blank line
|
||||
} else {
|
||||
p.printf("\n")
|
||||
}
|
||||
for i := 0; i < p.margin; i++ {
|
||||
p.printf("\t")
|
||||
}
|
||||
|
122
vendor/golang.org/x/mod/modfile/rule.go
generated
vendored
122
vendor/golang.org/x/mod/modfile/rule.go
generated
vendored
@@ -35,12 +35,13 @@ import (
|
||||
|
||||
// A File is the parsed, interpreted form of a go.mod file.
|
||||
type File struct {
|
||||
Module *Module
|
||||
Go *Go
|
||||
Require []*Require
|
||||
Exclude []*Exclude
|
||||
Replace []*Replace
|
||||
Retract []*Retract
|
||||
Module *Module
|
||||
Go *Go
|
||||
Toolchain *Toolchain
|
||||
Require []*Require
|
||||
Exclude []*Exclude
|
||||
Replace []*Replace
|
||||
Retract []*Retract
|
||||
|
||||
Syntax *FileSyntax
|
||||
}
|
||||
@@ -58,6 +59,12 @@ type Go struct {
|
||||
Syntax *Line
|
||||
}
|
||||
|
||||
// A Toolchain is the toolchain statement.
|
||||
type Toolchain struct {
|
||||
Name string // "go1.21rc1"
|
||||
Syntax *Line
|
||||
}
|
||||
|
||||
// An Exclude is a single exclude statement.
|
||||
type Exclude struct {
|
||||
Mod module.Version
|
||||
@@ -296,9 +303,13 @@ func parseToFile(file string, data []byte, fix VersionFixer, strict bool) (parse
|
||||
return f, nil
|
||||
}
|
||||
|
||||
var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)$`)
|
||||
var GoVersionRE = lazyregexp.New(`^([1-9][0-9]*)\.(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))?([a-z]+[0-9]+)?$`)
|
||||
var laxGoVersionRE = lazyregexp.New(`^v?(([1-9][0-9]*)\.(0|[1-9][0-9]*))([^0-9].*)$`)
|
||||
|
||||
// Toolchains must be named beginning with `go1`,
|
||||
// like "go1.20.3" or "go1.20.3-gccgo". As a special case, "default" is also permitted.
|
||||
var ToolchainRE = lazyregexp.New(`^default$|^go1($|\.)`)
|
||||
|
||||
func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, args []string, fix VersionFixer, strict bool) {
|
||||
// If strict is false, this module is a dependency.
|
||||
// We ignore all unknown directives as well as main-module-only
|
||||
@@ -364,6 +375,21 @@ func (f *File) add(errs *ErrorList, block *LineBlock, line *Line, verb string, a
|
||||
f.Go = &Go{Syntax: line}
|
||||
f.Go.Version = args[0]
|
||||
|
||||
case "toolchain":
|
||||
if f.Toolchain != nil {
|
||||
errorf("repeated toolchain statement")
|
||||
return
|
||||
}
|
||||
if len(args) != 1 {
|
||||
errorf("toolchain directive expects exactly one argument")
|
||||
return
|
||||
} else if strict && !ToolchainRE.MatchString(args[0]) {
|
||||
errorf("invalid toolchain version '%s': must match format go1.23 or local", args[0])
|
||||
return
|
||||
}
|
||||
f.Toolchain = &Toolchain{Syntax: line}
|
||||
f.Toolchain.Name = args[0]
|
||||
|
||||
case "module":
|
||||
if f.Module != nil {
|
||||
errorf("repeated module statement")
|
||||
@@ -612,6 +638,22 @@ func (f *WorkFile) add(errs *ErrorList, line *Line, verb string, args []string,
|
||||
f.Go = &Go{Syntax: line}
|
||||
f.Go.Version = args[0]
|
||||
|
||||
case "toolchain":
|
||||
if f.Toolchain != nil {
|
||||
errorf("repeated toolchain statement")
|
||||
return
|
||||
}
|
||||
if len(args) != 1 {
|
||||
errorf("toolchain directive expects exactly one argument")
|
||||
return
|
||||
} else if !ToolchainRE.MatchString(args[0]) {
|
||||
errorf("invalid toolchain version '%s': must match format go1.23 or local", args[0])
|
||||
return
|
||||
}
|
||||
|
||||
f.Toolchain = &Toolchain{Syntax: line}
|
||||
f.Toolchain.Name = args[0]
|
||||
|
||||
case "use":
|
||||
if len(args) != 1 {
|
||||
errorf("usage: %s local/dir", verb)
|
||||
@@ -926,7 +968,7 @@ func (f *File) Cleanup() {
|
||||
|
||||
func (f *File) AddGoStmt(version string) error {
|
||||
if !GoVersionRE.MatchString(version) {
|
||||
return fmt.Errorf("invalid language version string %q", version)
|
||||
return fmt.Errorf("invalid language version %q", version)
|
||||
}
|
||||
if f.Go == nil {
|
||||
var hint Expr
|
||||
@@ -944,6 +986,44 @@ func (f *File) AddGoStmt(version string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DropGoStmt deletes the go statement from the file.
|
||||
func (f *File) DropGoStmt() {
|
||||
if f.Go != nil {
|
||||
f.Go.Syntax.markRemoved()
|
||||
f.Go = nil
|
||||
}
|
||||
}
|
||||
|
||||
// DropToolchainStmt deletes the toolchain statement from the file.
|
||||
func (f *File) DropToolchainStmt() {
|
||||
if f.Toolchain != nil {
|
||||
f.Toolchain.Syntax.markRemoved()
|
||||
f.Toolchain = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (f *File) AddToolchainStmt(name string) error {
|
||||
if !ToolchainRE.MatchString(name) {
|
||||
return fmt.Errorf("invalid toolchain name %q", name)
|
||||
}
|
||||
if f.Toolchain == nil {
|
||||
var hint Expr
|
||||
if f.Go != nil && f.Go.Syntax != nil {
|
||||
hint = f.Go.Syntax
|
||||
} else if f.Module != nil && f.Module.Syntax != nil {
|
||||
hint = f.Module.Syntax
|
||||
}
|
||||
f.Toolchain = &Toolchain{
|
||||
Name: name,
|
||||
Syntax: f.Syntax.addLine(hint, "toolchain", name),
|
||||
}
|
||||
} else {
|
||||
f.Toolchain.Name = name
|
||||
f.Syntax.updateLine(f.Toolchain.Syntax, "toolchain", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddRequire sets the first require line for path to version vers,
|
||||
// preserving any existing comments for that line and removing all
|
||||
// other lines for path.
|
||||
@@ -1387,13 +1467,21 @@ func (f *File) DropRetract(vi VersionInterval) error {
|
||||
func (f *File) SortBlocks() {
|
||||
f.removeDups() // otherwise sorting is unsafe
|
||||
|
||||
// semanticSortForExcludeVersionV is the Go version (plus leading "v") at which
|
||||
// lines in exclude blocks start to use semantic sort instead of lexicographic sort.
|
||||
// See go.dev/issue/60028.
|
||||
const semanticSortForExcludeVersionV = "v1.21"
|
||||
useSemanticSortForExclude := f.Go != nil && semver.Compare("v"+f.Go.Version, semanticSortForExcludeVersionV) >= 0
|
||||
|
||||
for _, stmt := range f.Syntax.Stmt {
|
||||
block, ok := stmt.(*LineBlock)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
less := lineLess
|
||||
if block.Token[0] == "retract" {
|
||||
if block.Token[0] == "exclude" && useSemanticSortForExclude {
|
||||
less = lineExcludeLess
|
||||
} else if block.Token[0] == "retract" {
|
||||
less = lineRetractLess
|
||||
}
|
||||
sort.SliceStable(block.Line, func(i, j int) bool {
|
||||
@@ -1496,6 +1584,22 @@ func lineLess(li, lj *Line) bool {
|
||||
return len(li.Token) < len(lj.Token)
|
||||
}
|
||||
|
||||
// lineExcludeLess reports whether li should be sorted before lj for lines in
|
||||
// an "exclude" block.
|
||||
func lineExcludeLess(li, lj *Line) bool {
|
||||
if len(li.Token) != 2 || len(lj.Token) != 2 {
|
||||
// Not a known exclude specification.
|
||||
// Fall back to sorting lexicographically.
|
||||
return lineLess(li, lj)
|
||||
}
|
||||
// An exclude specification has two tokens: ModulePath and Version.
|
||||
// Compare module path by string order and version by semver rules.
|
||||
if pi, pj := li.Token[0], lj.Token[0]; pi != pj {
|
||||
return pi < pj
|
||||
}
|
||||
return semver.Compare(li.Token[1], lj.Token[1]) < 0
|
||||
}
|
||||
|
||||
// lineRetractLess returns whether li should be sorted before lj for lines in
|
||||
// a "retract" block. It treats each line as a version interval. Single versions
|
||||
// are compared as if they were intervals with the same low and high version.
|
||||
|
61
vendor/golang.org/x/mod/modfile/work.go
generated
vendored
61
vendor/golang.org/x/mod/modfile/work.go
generated
vendored
@@ -12,9 +12,10 @@ import (
|
||||
|
||||
// A WorkFile is the parsed, interpreted form of a go.work file.
|
||||
type WorkFile struct {
|
||||
Go *Go
|
||||
Use []*Use
|
||||
Replace []*Replace
|
||||
Go *Go
|
||||
Toolchain *Toolchain
|
||||
Use []*Use
|
||||
Replace []*Replace
|
||||
|
||||
Syntax *FileSyntax
|
||||
}
|
||||
@@ -109,7 +110,7 @@ func (f *WorkFile) Cleanup() {
|
||||
|
||||
func (f *WorkFile) AddGoStmt(version string) error {
|
||||
if !GoVersionRE.MatchString(version) {
|
||||
return fmt.Errorf("invalid language version string %q", version)
|
||||
return fmt.Errorf("invalid language version %q", version)
|
||||
}
|
||||
if f.Go == nil {
|
||||
stmt := &Line{Token: []string{"go", version}}
|
||||
@@ -117,7 +118,7 @@ func (f *WorkFile) AddGoStmt(version string) error {
|
||||
Version: version,
|
||||
Syntax: stmt,
|
||||
}
|
||||
// Find the first non-comment-only block that's and add
|
||||
// Find the first non-comment-only block and add
|
||||
// the go statement before it. That will keep file comments at the top.
|
||||
i := 0
|
||||
for i = 0; i < len(f.Syntax.Stmt); i++ {
|
||||
@@ -133,6 +134,56 @@ func (f *WorkFile) AddGoStmt(version string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *WorkFile) AddToolchainStmt(name string) error {
|
||||
if !ToolchainRE.MatchString(name) {
|
||||
return fmt.Errorf("invalid toolchain name %q", name)
|
||||
}
|
||||
if f.Toolchain == nil {
|
||||
stmt := &Line{Token: []string{"toolchain", name}}
|
||||
f.Toolchain = &Toolchain{
|
||||
Name: name,
|
||||
Syntax: stmt,
|
||||
}
|
||||
// Find the go line and add the toolchain line after it.
|
||||
// Or else find the first non-comment-only block and add
|
||||
// the toolchain line before it. That will keep file comments at the top.
|
||||
i := 0
|
||||
for i = 0; i < len(f.Syntax.Stmt); i++ {
|
||||
if line, ok := f.Syntax.Stmt[i].(*Line); ok && len(line.Token) > 0 && line.Token[0] == "go" {
|
||||
i++
|
||||
goto Found
|
||||
}
|
||||
}
|
||||
for i = 0; i < len(f.Syntax.Stmt); i++ {
|
||||
if _, ok := f.Syntax.Stmt[i].(*CommentBlock); !ok {
|
||||
break
|
||||
}
|
||||
}
|
||||
Found:
|
||||
f.Syntax.Stmt = append(append(f.Syntax.Stmt[:i:i], stmt), f.Syntax.Stmt[i:]...)
|
||||
} else {
|
||||
f.Toolchain.Name = name
|
||||
f.Syntax.updateLine(f.Toolchain.Syntax, "toolchain", name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DropGoStmt deletes the go statement from the file.
|
||||
func (f *WorkFile) DropGoStmt() {
|
||||
if f.Go != nil {
|
||||
f.Go.Syntax.markRemoved()
|
||||
f.Go = nil
|
||||
}
|
||||
}
|
||||
|
||||
// DropToolchainStmt deletes the toolchain statement from the file.
|
||||
func (f *WorkFile) DropToolchainStmt() {
|
||||
if f.Toolchain != nil {
|
||||
f.Toolchain.Syntax.markRemoved()
|
||||
f.Toolchain = nil
|
||||
}
|
||||
}
|
||||
|
||||
func (f *WorkFile) AddUse(diskPath, modulePath string) error {
|
||||
need := true
|
||||
for _, d := range f.Use {
|
||||
|
764
vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
generated
vendored
Normal file
764
vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
generated
vendored
Normal file
@@ -0,0 +1,764 @@
|
||||
// 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"
|
||||
"go/types"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
|
||||
_ "unsafe" // for go:linkname
|
||||
)
|
||||
|
||||
// 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 [EKPRUTC];
|
||||
// one of these (TypeParam) requires an integer operand,
|
||||
// which is encoded as a string of decimal digits.
|
||||
// - The TO 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.
|
||||
// The indices used are implementation specific and may not correspond to
|
||||
// the argument to the go/types function.
|
||||
//
|
||||
// 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)
|
||||
opTypeParam = 'T' // .TypeParams.At(i) (Named, Signature)
|
||||
opConstraint = 'C' // .Constraint() (TypeParam)
|
||||
|
||||
// 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, TypeParam)
|
||||
)
|
||||
|
||||
// For is equivalent to new(Encoder).For(obj).
|
||||
//
|
||||
// It may be more efficient to reuse a single Encoder across several calls.
|
||||
func For(obj types.Object) (Path, error) {
|
||||
return new(Encoder).For(obj)
|
||||
}
|
||||
|
||||
// An Encoder amortizes the cost of encoding the paths of multiple objects.
|
||||
// The zero value of an Encoder is ready to use.
|
||||
type Encoder struct {
|
||||
scopeNamesMemo map[*types.Scope][]string // memoization of Scope.Names()
|
||||
namedMethodsMemo map[*types.Named][]*types.Func // memoization of namedMethods()
|
||||
}
|
||||
|
||||
// For 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 (enc *Encoder) 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.TypeName:
|
||||
if _, ok := obj.Type().(*typeparams.TypeParam); !ok {
|
||||
// With the exception of type parameters, only package-level type names
|
||||
// have a path.
|
||||
return "", fmt.Errorf("no path for %v", obj)
|
||||
}
|
||||
case *types.Const, // Only package-level constants 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)
|
||||
}
|
||||
|
||||
if path, ok := enc.concreteMethod(obj); ok {
|
||||
// Fast path for concrete methods that avoids looping over scope.
|
||||
return path, nil
|
||||
}
|
||||
|
||||
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 := enc.scopeNames(scope)
|
||||
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, nil); r != nil {
|
||||
return Path(r), nil
|
||||
}
|
||||
} else {
|
||||
if named, _ := T.(*types.Named); named != nil {
|
||||
if r := findTypeParam(obj, typeparams.ForNamed(named), path, nil); r != nil {
|
||||
// generic named type
|
||||
return Path(r), nil
|
||||
}
|
||||
}
|
||||
// defined (named) type
|
||||
if r := find(obj, T.Underlying(), append(path, opUnderlying), nil); 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), nil); 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)
|
||||
// Note that method index here is always with respect
|
||||
// to canonical ordering of methods, regardless of how
|
||||
// they appear in the underlying type.
|
||||
for i, m := range enc.namedMethods(T) {
|
||||
path2 := appendOpArg(path, opMethod, i)
|
||||
if m == obj {
|
||||
return Path(path2), nil // found declared method
|
||||
}
|
||||
if r := find(obj, m.Type(), append(path2, opType), nil); 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
|
||||
}
|
||||
|
||||
// concreteMethod returns the path for meth, which must have a non-nil receiver.
|
||||
// The second return value indicates success and may be false if the method is
|
||||
// an interface method or if it is an instantiated method.
|
||||
//
|
||||
// This function is just an optimization that avoids the general scope walking
|
||||
// approach. You are expected to fall back to the general approach if this
|
||||
// function fails.
|
||||
func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
||||
// Concrete methods can only be declared on package-scoped named types. For
|
||||
// that reason we can skip the expensive walk over the package scope: the
|
||||
// path will always be package -> named type -> method. We can trivially get
|
||||
// the type name from the receiver, and only have to look over the type's
|
||||
// methods to find the method index.
|
||||
//
|
||||
// Methods on generic types require special consideration, however. Consider
|
||||
// the following package:
|
||||
//
|
||||
// L1: type S[T any] struct{}
|
||||
// L2: func (recv S[A]) Foo() { recv.Bar() }
|
||||
// L3: func (recv S[B]) Bar() { }
|
||||
// L4: type Alias = S[int]
|
||||
// L5: func _[T any]() { var s S[int]; s.Foo() }
|
||||
//
|
||||
// The receivers of methods on generic types are instantiations. L2 and L3
|
||||
// instantiate S with the type-parameters A and B, which are scoped to the
|
||||
// respective methods. L4 and L5 each instantiate S with int. Each of these
|
||||
// instantiations has its own method set, full of methods (and thus objects)
|
||||
// with receivers whose types are the respective instantiations. In other
|
||||
// words, we have
|
||||
//
|
||||
// S[A].Foo, S[A].Bar
|
||||
// S[B].Foo, S[B].Bar
|
||||
// S[int].Foo, S[int].Bar
|
||||
//
|
||||
// We may thus be trying to produce object paths for any of these objects.
|
||||
//
|
||||
// S[A].Foo and S[B].Bar are the origin methods, and their paths are S.Foo
|
||||
// and S.Bar, which are the paths that this function naturally produces.
|
||||
//
|
||||
// S[A].Bar, S[B].Foo, and both methods on S[int] are instantiations that
|
||||
// don't correspond to the origin methods. For S[int], this is significant.
|
||||
// The most precise object path for S[int].Foo, for example, is Alias.Foo,
|
||||
// not S.Foo. Our function, however, would produce S.Foo, which would
|
||||
// resolve to a different object.
|
||||
//
|
||||
// For S[A].Bar and S[B].Foo it could be argued that S.Bar and S.Foo are
|
||||
// still the correct paths, since only the origin methods have meaningful
|
||||
// paths. But this is likely only true for trivial cases and has edge cases.
|
||||
// Since this function is only an optimization, we err on the side of giving
|
||||
// up, deferring to the slower but definitely correct algorithm. Most users
|
||||
// of objectpath will only be giving us origin methods, anyway, as referring
|
||||
// to instantiated methods is usually not useful.
|
||||
|
||||
if typeparams.OriginMethod(meth) != meth {
|
||||
return "", false
|
||||
}
|
||||
|
||||
recvT := meth.Type().(*types.Signature).Recv().Type()
|
||||
if ptr, ok := recvT.(*types.Pointer); ok {
|
||||
recvT = ptr.Elem()
|
||||
}
|
||||
|
||||
named, ok := recvT.(*types.Named)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if types.IsInterface(named) {
|
||||
// Named interfaces don't have to be package-scoped
|
||||
//
|
||||
// TODO(dominikh): opt: if scope.Lookup(name) == named, then we can apply this optimization to interface
|
||||
// methods, too, I think.
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Preallocate space for the name, opType, opMethod, and some digits.
|
||||
name := named.Obj().Name()
|
||||
path := make([]byte, 0, len(name)+8)
|
||||
path = append(path, name...)
|
||||
path = append(path, opType)
|
||||
for i, m := range enc.namedMethods(named) {
|
||||
if m == meth {
|
||||
path = appendOpArg(path, opMethod, i)
|
||||
return Path(path), true
|
||||
}
|
||||
}
|
||||
|
||||
// Due to golang/go#59944, go/types fails to associate the receiver with
|
||||
// certain methods on cgo types.
|
||||
//
|
||||
// TODO(rfindley): replace this panic once golang/go#59944 is fixed in all Go
|
||||
// versions gopls supports.
|
||||
return "", false
|
||||
// panic(fmt.Sprintf("couldn't find method %s on type %s; methods: %#v", meth, named, enc.namedMethods(named)))
|
||||
}
|
||||
|
||||
// find finds obj within type T, returning the path to it, or nil if not found.
|
||||
//
|
||||
// The seen map is used to short circuit cycles through type parameters. If
|
||||
// nil, it will be allocated as necessary.
|
||||
func find(obj types.Object, T types.Type, path []byte, seen map[*types.TypeName]bool) []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), seen)
|
||||
case *types.Slice:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Array:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Chan:
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Map:
|
||||
if r := find(obj, T.Key(), append(path, opKey), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
return find(obj, T.Elem(), append(path, opElem), seen)
|
||||
case *types.Signature:
|
||||
if r := findTypeParam(obj, typeparams.ForSignature(T), path, seen); r != nil {
|
||||
return r
|
||||
}
|
||||
if r := find(obj, T.Params(), append(path, opParams), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
return find(obj, T.Results(), append(path, opResults), seen)
|
||||
case *types.Struct:
|
||||
for i := 0; i < T.NumFields(); i++ {
|
||||
fld := T.Field(i)
|
||||
path2 := appendOpArg(path, opField, i)
|
||||
if fld == obj {
|
||||
return path2 // found field var
|
||||
}
|
||||
if r := find(obj, fld.Type(), append(path2, opType), seen); 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), seen); 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), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
case *typeparams.TypeParam:
|
||||
name := T.Obj()
|
||||
if name == obj {
|
||||
return append(path, opObj)
|
||||
}
|
||||
if seen[name] {
|
||||
return nil
|
||||
}
|
||||
if seen == nil {
|
||||
seen = make(map[*types.TypeName]bool)
|
||||
}
|
||||
seen[name] = true
|
||||
if r := find(obj, T.Constraint(), append(path, opConstraint), seen); r != nil {
|
||||
return r
|
||||
}
|
||||
return nil
|
||||
}
|
||||
panic(T)
|
||||
}
|
||||
|
||||
func findTypeParam(obj types.Object, list *typeparams.TypeParamList, path []byte, seen map[*types.TypeName]bool) []byte {
|
||||
for i := 0; i < list.Len(); i++ {
|
||||
tparam := list.At(i)
|
||||
path2 := appendOpArg(path, opTypeParam, i)
|
||||
if r := find(obj, tparam, path2, seen); r != nil {
|
||||
return r
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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.{Named,Signature}
|
||||
type hasTypeParams interface {
|
||||
TypeParams() *typeparams.TypeParamList
|
||||
}
|
||||
// abstraction of *types.{Named,TypeParam}
|
||||
type hasObj interface {
|
||||
Obj() *types.TypeName
|
||||
}
|
||||
|
||||
// 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, opTypeParam:
|
||||
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 %T, want named)", code, t, t)
|
||||
}
|
||||
t = named.Underlying()
|
||||
|
||||
case opTypeParam:
|
||||
hasTypeParams, ok := t.(hasTypeParams) // Named, Signature
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or signature)", code, t, t)
|
||||
}
|
||||
tparams := hasTypeParams.TypeParams()
|
||||
if n := tparams.Len(); index >= n {
|
||||
return nil, fmt.Errorf("tuple index %d out of range [0-%d)", index, n)
|
||||
}
|
||||
t = tparams.At(index)
|
||||
|
||||
case opConstraint:
|
||||
tparam, ok := t.(*typeparams.TypeParam)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want type parameter)", code, t, t)
|
||||
}
|
||||
t = tparam.Constraint()
|
||||
|
||||
case opAt:
|
||||
tuple, ok := t.(*types.Tuple)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, 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:
|
||||
switch t := t.(type) {
|
||||
case *types.Interface:
|
||||
if index >= t.NumMethods() {
|
||||
return nil, fmt.Errorf("method index %d out of range [0-%d)", index, t.NumMethods())
|
||||
}
|
||||
obj = t.Method(index) // Id-ordered
|
||||
|
||||
case *types.Named:
|
||||
methods := namedMethods(t) // (unmemoized)
|
||||
if index >= len(methods) {
|
||||
return nil, fmt.Errorf("method index %d out of range [0-%d)", index, len(methods))
|
||||
}
|
||||
obj = methods[index] // Id-ordered
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want interface or named)", code, t, t)
|
||||
}
|
||||
t = nil
|
||||
|
||||
case opObj:
|
||||
hasObj, ok := t.(hasObj)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot apply %q to %s (got %T, want named or type param)", code, t, t)
|
||||
}
|
||||
obj = hasObj.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
|
||||
}
|
||||
|
||||
// namedMethods returns the methods of a Named type in ascending Id order.
|
||||
func namedMethods(named *types.Named) []*types.Func {
|
||||
methods := make([]*types.Func, named.NumMethods())
|
||||
for i := range methods {
|
||||
methods[i] = named.Method(i)
|
||||
}
|
||||
sort.Slice(methods, func(i, j int) bool {
|
||||
return methods[i].Id() < methods[j].Id()
|
||||
})
|
||||
return methods
|
||||
}
|
||||
|
||||
// namedMethods is a memoization of the namedMethods function. Callers must not modify the result.
|
||||
func (enc *Encoder) namedMethods(named *types.Named) []*types.Func {
|
||||
m := enc.namedMethodsMemo
|
||||
if m == nil {
|
||||
m = make(map[*types.Named][]*types.Func)
|
||||
enc.namedMethodsMemo = m
|
||||
}
|
||||
methods, ok := m[named]
|
||||
if !ok {
|
||||
methods = namedMethods(named) // allocates and sorts
|
||||
m[named] = methods
|
||||
}
|
||||
return methods
|
||||
}
|
||||
|
||||
// scopeNames is a memoization of scope.Names. Callers must not modify the result.
|
||||
func (enc *Encoder) scopeNames(scope *types.Scope) []string {
|
||||
m := enc.scopeNamesMemo
|
||||
if m == nil {
|
||||
m = make(map[*types.Scope][]string)
|
||||
enc.scopeNamesMemo = m
|
||||
}
|
||||
names, ok := m[scope]
|
||||
if !ok {
|
||||
names = scope.Names() // allocates and sorts
|
||||
m[scope] = names
|
||||
}
|
||||
return names
|
||||
}
|
12
vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
generated
vendored
12
vendor/golang.org/x/tools/internal/gcimporter/gcimporter.go
generated
vendored
@@ -7,6 +7,18 @@
|
||||
// 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.
|
||||
//
|
||||
// The encoding is deterministic: if the encoder is applied twice to
|
||||
// the same types.Package data structure, both encodings are equal.
|
||||
// This property may be important to avoid spurious changes in
|
||||
// applications such as build systems.
|
||||
//
|
||||
// However, the encoder is not necessarily idempotent. Importing an
|
||||
// exported package may yield a types.Package that, while it
|
||||
// represents the same set of Go types as the original, may differ in
|
||||
// the details of its internal representation. Because of these
|
||||
// differences, re-encoding the imported package may yield a
|
||||
// different, but equally valid, encoding of the package.
|
||||
package gcimporter // import "golang.org/x/tools/internal/gcimporter"
|
||||
|
||||
import (
|
||||
|
8
vendor/golang.org/x/tools/internal/gcimporter/iexport.go
generated
vendored
8
vendor/golang.org/x/tools/internal/gcimporter/iexport.go
generated
vendored
@@ -44,12 +44,12 @@ func IExportShallow(fset *token.FileSet, pkg *types.Package) ([]byte, error) {
|
||||
return out.Bytes(), err
|
||||
}
|
||||
|
||||
// IImportShallow decodes "shallow" types.Package data encoded by IExportShallow
|
||||
// in the same executable. This function cannot import data from
|
||||
// IImportShallow decodes "shallow" types.Package data encoded by
|
||||
// IExportShallow in the same executable. This function cannot import data from
|
||||
// cmd/compile or gcexportdata.Write.
|
||||
func IImportShallow(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string, insert InsertType) (*types.Package, error) {
|
||||
func IImportShallow(fset *token.FileSet, getPackage GetPackageFunc, data []byte, path string, insert InsertType) (*types.Package, error) {
|
||||
const bundle = false
|
||||
pkgs, err := iimportCommon(fset, imports, data, bundle, path, insert)
|
||||
pkgs, err := iimportCommon(fset, getPackage, data, bundle, path, insert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
34
vendor/golang.org/x/tools/internal/gcimporter/iimport.go
generated
vendored
34
vendor/golang.org/x/tools/internal/gcimporter/iimport.go
generated
vendored
@@ -85,7 +85,7 @@ const (
|
||||
// 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, *types.Package, error) {
|
||||
pkgs, err := iimportCommon(fset, imports, data, false, path, nil)
|
||||
pkgs, err := iimportCommon(fset, GetPackageFromMap(imports), data, false, path, nil)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
@@ -94,10 +94,33 @@ func IImportData(fset *token.FileSet, imports map[string]*types.Package, data []
|
||||
|
||||
// IImportBundle imports a set of packages from the serialized package bundle.
|
||||
func IImportBundle(fset *token.FileSet, imports map[string]*types.Package, data []byte) ([]*types.Package, error) {
|
||||
return iimportCommon(fset, imports, data, true, "", nil)
|
||||
return iimportCommon(fset, GetPackageFromMap(imports), data, true, "", nil)
|
||||
}
|
||||
|
||||
func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data []byte, bundle bool, path string, insert InsertType) (pkgs []*types.Package, err error) {
|
||||
// A GetPackageFunc is a function that gets the package with the given path
|
||||
// from the importer state, creating it (with the specified name) if necessary.
|
||||
// It is an abstraction of the map historically used to memoize package creation.
|
||||
//
|
||||
// Two calls with the same path must return the same package.
|
||||
//
|
||||
// If the given getPackage func returns nil, the import will fail.
|
||||
type GetPackageFunc = func(path, name string) *types.Package
|
||||
|
||||
// GetPackageFromMap returns a GetPackageFunc that retrieves packages from the
|
||||
// given map of package path -> package.
|
||||
//
|
||||
// The resulting func may mutate m: if a requested package is not found, a new
|
||||
// package will be inserted into m.
|
||||
func GetPackageFromMap(m map[string]*types.Package) GetPackageFunc {
|
||||
return func(path, name string) *types.Package {
|
||||
if _, ok := m[path]; !ok {
|
||||
m[path] = types.NewPackage(path, name)
|
||||
}
|
||||
return m[path]
|
||||
}
|
||||
}
|
||||
|
||||
func iimportCommon(fset *token.FileSet, getPackage GetPackageFunc, data []byte, bundle bool, path string, insert InsertType) (pkgs []*types.Package, err error) {
|
||||
const currentVersion = iexportVersionCurrent
|
||||
version := int64(-1)
|
||||
if !debug {
|
||||
@@ -195,10 +218,9 @@ func iimportCommon(fset *token.FileSet, imports map[string]*types.Package, data
|
||||
if pkgPath == "" {
|
||||
pkgPath = path
|
||||
}
|
||||
pkg := imports[pkgPath]
|
||||
pkg := getPackage(pkgPath, pkgName)
|
||||
if pkg == nil {
|
||||
pkg = types.NewPackage(pkgPath, pkgName)
|
||||
imports[pkgPath] = pkg
|
||||
errorf("internal error: getPackage returned nil package for %s", pkgPath)
|
||||
} else if pkg.Name() != pkgName {
|
||||
errorf("conflicting names %s and %s for package %q", pkg.Name(), pkgName, path)
|
||||
}
|
||||
|
41
vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
generated
vendored
41
vendor/golang.org/x/tools/internal/gcimporter/ureader_yes.go
generated
vendored
@@ -12,6 +12,7 @@ package gcimporter
|
||||
import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/pkgbits"
|
||||
@@ -121,6 +122,16 @@ func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[st
|
||||
iface.Complete()
|
||||
}
|
||||
|
||||
// Imports() of pkg are all of the transitive packages that were loaded.
|
||||
var imps []*types.Package
|
||||
for _, imp := range pr.pkgs {
|
||||
if imp != nil && imp != pkg {
|
||||
imps = append(imps, imp)
|
||||
}
|
||||
}
|
||||
sort.Sort(byPath(imps))
|
||||
pkg.SetImports(imps)
|
||||
|
||||
pkg.MarkComplete()
|
||||
return pkg
|
||||
}
|
||||
@@ -260,39 +271,9 @@ func (r *reader) doPkg() *types.Package {
|
||||
pkg := types.NewPackage(path, name)
|
||||
r.p.imports[path] = pkg
|
||||
|
||||
imports := make([]*types.Package, r.Len())
|
||||
for i := range imports {
|
||||
imports[i] = r.pkg()
|
||||
}
|
||||
pkg.SetImports(flattenImports(imports))
|
||||
|
||||
return pkg
|
||||
}
|
||||
|
||||
// flattenImports returns the transitive closure of all imported
|
||||
// packages rooted from pkgs.
|
||||
func flattenImports(pkgs []*types.Package) []*types.Package {
|
||||
var res []*types.Package
|
||||
seen := make(map[*types.Package]struct{})
|
||||
for _, pkg := range pkgs {
|
||||
if _, ok := seen[pkg]; ok {
|
||||
continue
|
||||
}
|
||||
seen[pkg] = struct{}{}
|
||||
res = append(res, pkg)
|
||||
|
||||
// pkg.Imports() is already flattened.
|
||||
for _, pkg := range pkg.Imports() {
|
||||
if _, ok := seen[pkg]; ok {
|
||||
continue
|
||||
}
|
||||
seen[pkg] = struct{}{}
|
||||
res = append(res, pkg)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
// @@@ Types
|
||||
|
||||
func (r *reader) typ() types.Type {
|
||||
|
128
vendor/golang.org/x/tools/internal/gocommand/invoke.go
generated
vendored
128
vendor/golang.org/x/tools/internal/gocommand/invoke.go
generated
vendored
@@ -8,10 +8,12 @@ package gocommand
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
@@ -215,6 +217,18 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
|
||||
cmd := exec.Command("go", goArgs...)
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
|
||||
// cmd.WaitDelay was added only in go1.20 (see #50436).
|
||||
if waitDelay := reflect.ValueOf(cmd).Elem().FieldByName("WaitDelay"); waitDelay.IsValid() {
|
||||
// https://go.dev/issue/59541: don't wait forever copying stderr
|
||||
// after the command has exited.
|
||||
// After CL 484741 we copy stdout manually, so we we'll stop reading that as
|
||||
// soon as ctx is done. However, we also don't want to wait around forever
|
||||
// for stderr. Give a much-longer-than-reasonable delay and then assume that
|
||||
// something has wedged in the kernel or runtime.
|
||||
waitDelay.Set(reflect.ValueOf(30 * time.Second))
|
||||
}
|
||||
|
||||
// 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.
|
||||
@@ -229,6 +243,7 @@ func (i *Invocation) run(ctx context.Context, stdout, stderr io.Writer) error {
|
||||
cmd.Env = append(cmd.Env, "PWD="+i.WorkingDir)
|
||||
cmd.Dir = i.WorkingDir
|
||||
}
|
||||
|
||||
defer func(start time.Time) { log("%s for %v", time.Since(start), cmdDebugStr(cmd)) }(time.Now())
|
||||
|
||||
return runCmdContext(ctx, cmd)
|
||||
@@ -242,10 +257,85 @@ var DebugHangingGoCommands = false
|
||||
|
||||
// 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 {
|
||||
func runCmdContext(ctx context.Context, cmd *exec.Cmd) (err error) {
|
||||
// If cmd.Stdout is not an *os.File, the exec package will create a pipe and
|
||||
// copy it to the Writer in a goroutine until the process has finished and
|
||||
// either the pipe reaches EOF or command's WaitDelay expires.
|
||||
//
|
||||
// However, the output from 'go list' can be quite large, and we don't want to
|
||||
// keep reading (and allocating buffers) if we've already decided we don't
|
||||
// care about the output. We don't want to wait for the process to finish, and
|
||||
// we don't wait to wait for the WaitDelay to expire either.
|
||||
//
|
||||
// Instead, if cmd.Stdout requires a copying goroutine we explicitly replace
|
||||
// it with a pipe (which is an *os.File), which we can close in order to stop
|
||||
// copying output as soon as we realize we don't care about it.
|
||||
var stdoutW *os.File
|
||||
if cmd.Stdout != nil {
|
||||
if _, ok := cmd.Stdout.(*os.File); !ok {
|
||||
var stdoutR *os.File
|
||||
stdoutR, stdoutW, err = os.Pipe()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prevStdout := cmd.Stdout
|
||||
cmd.Stdout = stdoutW
|
||||
|
||||
stdoutErr := make(chan error, 1)
|
||||
go func() {
|
||||
_, err := io.Copy(prevStdout, stdoutR)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("copying stdout: %w", err)
|
||||
}
|
||||
stdoutErr <- err
|
||||
}()
|
||||
defer func() {
|
||||
// We started a goroutine to copy a stdout pipe.
|
||||
// Wait for it to finish, or terminate it if need be.
|
||||
var err2 error
|
||||
select {
|
||||
case err2 = <-stdoutErr:
|
||||
stdoutR.Close()
|
||||
case <-ctx.Done():
|
||||
stdoutR.Close()
|
||||
// Per https://pkg.go.dev/os#File.Close, the call to stdoutR.Close
|
||||
// should cause the Read call in io.Copy to unblock and return
|
||||
// immediately, but we still need to receive from stdoutErr to confirm
|
||||
// that that has happened.
|
||||
<-stdoutErr
|
||||
err2 = ctx.Err()
|
||||
}
|
||||
if err == nil {
|
||||
err = err2
|
||||
}
|
||||
}()
|
||||
|
||||
// Per https://pkg.go.dev/os/exec#Cmd, “If Stdout and Stderr are the
|
||||
// same writer, and have a type that can be compared with ==, at most
|
||||
// one goroutine at a time will call Write.”
|
||||
//
|
||||
// Since we're starting a goroutine that writes to cmd.Stdout, we must
|
||||
// also update cmd.Stderr so that that still holds.
|
||||
func() {
|
||||
defer func() { recover() }()
|
||||
if cmd.Stderr == prevStdout {
|
||||
cmd.Stderr = cmd.Stdout
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
err = cmd.Start()
|
||||
if stdoutW != nil {
|
||||
// The child process has inherited the pipe file,
|
||||
// so close the copy held in this process.
|
||||
stdoutW.Close()
|
||||
stdoutW = nil
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resChan := make(chan error, 1)
|
||||
go func() {
|
||||
resChan <- cmd.Wait()
|
||||
@@ -253,11 +343,14 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
|
||||
|
||||
// If we're interested in debugging hanging Go commands, stop waiting after a
|
||||
// minute and panic with interesting information.
|
||||
if DebugHangingGoCommands {
|
||||
debug := DebugHangingGoCommands
|
||||
if debug {
|
||||
timer := time.NewTimer(1 * time.Minute)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case err := <-resChan:
|
||||
return err
|
||||
case <-time.After(1 * time.Minute):
|
||||
case <-timer.C:
|
||||
HandleHangingGoCommand(cmd.Process)
|
||||
case <-ctx.Done():
|
||||
}
|
||||
@@ -270,30 +363,25 @@ func runCmdContext(ctx context.Context, cmd *exec.Cmd) error {
|
||||
}
|
||||
|
||||
// Cancelled. Interrupt and see if it ends voluntarily.
|
||||
cmd.Process.Signal(os.Interrupt)
|
||||
select {
|
||||
case err := <-resChan:
|
||||
return err
|
||||
case <-time.After(time.Second):
|
||||
if err := cmd.Process.Signal(os.Interrupt); err == nil {
|
||||
// (We used to wait only 1s but this proved
|
||||
// fragile on loaded builder machines.)
|
||||
timer := time.NewTimer(5 * time.Second)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case err := <-resChan:
|
||||
return err
|
||||
case <-timer.C:
|
||||
}
|
||||
}
|
||||
|
||||
// Didn't shut down in response to interrupt. Kill it hard.
|
||||
// TODO(rfindley): per advice from bcmills@, it may be better to send SIGQUIT
|
||||
// on certain platforms, such as unix.
|
||||
if err := cmd.Process.Kill(); err != nil && DebugHangingGoCommands {
|
||||
// Don't panic here as this reliably fails on windows with EINVAL.
|
||||
if err := cmd.Process.Kill(); err != nil && !errors.Is(err, os.ErrProcessDone) && debug {
|
||||
log.Printf("error killing the Go command: %v", err)
|
||||
}
|
||||
|
||||
// See above: don't wait indefinitely if we're debugging hanging Go commands.
|
||||
if DebugHangingGoCommands {
|
||||
select {
|
||||
case err := <-resChan:
|
||||
return err
|
||||
case <-time.After(10 * time.Second): // a shorter wait as resChan should return quickly following Kill
|
||||
HandleHangingGoCommand(cmd.Process)
|
||||
}
|
||||
}
|
||||
return <-resChan
|
||||
}
|
||||
|
||||
|
18
vendor/golang.org/x/tools/internal/gocommand/version.go
generated
vendored
18
vendor/golang.org/x/tools/internal/gocommand/version.go
generated
vendored
@@ -23,21 +23,11 @@ import (
|
||||
func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) {
|
||||
inv.Verb = "list"
|
||||
inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`}
|
||||
inv.Env = append(append([]string{}, inv.Env...), "GO111MODULE=off")
|
||||
// Unset any unneeded flags, and remove them from BuildFlags, if they're
|
||||
// present.
|
||||
inv.ModFile = ""
|
||||
inv.BuildFlags = nil // This is not a build command.
|
||||
inv.ModFlag = ""
|
||||
var buildFlags []string
|
||||
for _, flag := range inv.BuildFlags {
|
||||
// Flags can be prefixed by one or two dashes.
|
||||
f := strings.TrimPrefix(strings.TrimPrefix(flag, "-"), "-")
|
||||
if strings.HasPrefix(f, "mod=") || strings.HasPrefix(f, "modfile=") {
|
||||
continue
|
||||
}
|
||||
buildFlags = append(buildFlags, flag)
|
||||
}
|
||||
inv.BuildFlags = buildFlags
|
||||
inv.ModFile = ""
|
||||
inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off")
|
||||
|
||||
stdoutBytes, err := r.Run(ctx, inv)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
28
vendor/golang.org/x/tools/internal/imports/fix.go
generated
vendored
28
vendor/golang.org/x/tools/internal/imports/fix.go
generated
vendored
@@ -414,9 +414,16 @@ func (p *pass) fix() ([]*ImportFix, bool) {
|
||||
})
|
||||
}
|
||||
}
|
||||
// Collecting fixes involved map iteration, so sort for stability. See
|
||||
// golang/go#59976.
|
||||
sortFixes(fixes)
|
||||
|
||||
// collect selected fixes in a separate slice, so that it can be sorted
|
||||
// separately. Note that these fixes must occur after fixes to existing
|
||||
// imports. TODO(rfindley): figure out why.
|
||||
var selectedFixes []*ImportFix
|
||||
for _, imp := range selected {
|
||||
fixes = append(fixes, &ImportFix{
|
||||
selectedFixes = append(selectedFixes, &ImportFix{
|
||||
StmtInfo: ImportInfo{
|
||||
Name: p.importSpecName(imp),
|
||||
ImportPath: imp.ImportPath,
|
||||
@@ -425,8 +432,25 @@ func (p *pass) fix() ([]*ImportFix, bool) {
|
||||
FixType: AddImport,
|
||||
})
|
||||
}
|
||||
sortFixes(selectedFixes)
|
||||
|
||||
return fixes, true
|
||||
return append(fixes, selectedFixes...), true
|
||||
}
|
||||
|
||||
func sortFixes(fixes []*ImportFix) {
|
||||
sort.Slice(fixes, func(i, j int) bool {
|
||||
fi, fj := fixes[i], fixes[j]
|
||||
if fi.StmtInfo.ImportPath != fj.StmtInfo.ImportPath {
|
||||
return fi.StmtInfo.ImportPath < fj.StmtInfo.ImportPath
|
||||
}
|
||||
if fi.StmtInfo.Name != fj.StmtInfo.Name {
|
||||
return fi.StmtInfo.Name < fj.StmtInfo.Name
|
||||
}
|
||||
if fi.IdentName != fj.IdentName {
|
||||
return fi.IdentName < fj.IdentName
|
||||
}
|
||||
return fi.FixType < fj.FixType
|
||||
})
|
||||
}
|
||||
|
||||
// importSpecName gets the import name of imp in the import spec.
|
||||
|
92
vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go
generated
vendored
92
vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go
generated
vendored
@@ -7,7 +7,9 @@
|
||||
package tokeninternal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"sort"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
@@ -57,3 +59,93 @@ func GetLines(file *token.File) []int {
|
||||
panic("unexpected token.File size")
|
||||
}
|
||||
}
|
||||
|
||||
// AddExistingFiles adds the specified files to the FileSet if they
|
||||
// are not already present. It panics if any pair of files in the
|
||||
// resulting FileSet would overlap.
|
||||
func AddExistingFiles(fset *token.FileSet, files []*token.File) {
|
||||
// Punch through the FileSet encapsulation.
|
||||
type tokenFileSet struct {
|
||||
// This type remained essentially consistent from go1.16 to go1.21.
|
||||
mutex sync.RWMutex
|
||||
base int
|
||||
files []*token.File
|
||||
_ *token.File // changed to atomic.Pointer[token.File] in go1.19
|
||||
}
|
||||
|
||||
// If the size of token.FileSet changes, this will fail to compile.
|
||||
const delta = int64(unsafe.Sizeof(tokenFileSet{})) - int64(unsafe.Sizeof(token.FileSet{}))
|
||||
var _ [-delta * delta]int
|
||||
|
||||
type uP = unsafe.Pointer
|
||||
var ptr *tokenFileSet
|
||||
*(*uP)(uP(&ptr)) = uP(fset)
|
||||
ptr.mutex.Lock()
|
||||
defer ptr.mutex.Unlock()
|
||||
|
||||
// Merge and sort.
|
||||
newFiles := append(ptr.files, files...)
|
||||
sort.Slice(newFiles, func(i, j int) bool {
|
||||
return newFiles[i].Base() < newFiles[j].Base()
|
||||
})
|
||||
|
||||
// Reject overlapping files.
|
||||
// Discard adjacent identical files.
|
||||
out := newFiles[:0]
|
||||
for i, file := range newFiles {
|
||||
if i > 0 {
|
||||
prev := newFiles[i-1]
|
||||
if file == prev {
|
||||
continue
|
||||
}
|
||||
if prev.Base()+prev.Size()+1 > file.Base() {
|
||||
panic(fmt.Sprintf("file %s (%d-%d) overlaps with file %s (%d-%d)",
|
||||
prev.Name(), prev.Base(), prev.Base()+prev.Size(),
|
||||
file.Name(), file.Base(), file.Base()+file.Size()))
|
||||
}
|
||||
}
|
||||
out = append(out, file)
|
||||
}
|
||||
newFiles = out
|
||||
|
||||
ptr.files = newFiles
|
||||
|
||||
// Advance FileSet.Base().
|
||||
if len(newFiles) > 0 {
|
||||
last := newFiles[len(newFiles)-1]
|
||||
newBase := last.Base() + last.Size() + 1
|
||||
if ptr.base < newBase {
|
||||
ptr.base = newBase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FileSetFor returns a new FileSet containing a sequence of new Files with
|
||||
// the same base, size, and line as the input files, for use in APIs that
|
||||
// require a FileSet.
|
||||
//
|
||||
// Precondition: the input files must be non-overlapping, and sorted in order
|
||||
// of their Base.
|
||||
func FileSetFor(files ...*token.File) *token.FileSet {
|
||||
fset := token.NewFileSet()
|
||||
for _, f := range files {
|
||||
f2 := fset.AddFile(f.Name(), f.Base(), f.Size())
|
||||
lines := GetLines(f)
|
||||
f2.SetLines(lines)
|
||||
}
|
||||
return fset
|
||||
}
|
||||
|
||||
// CloneFileSet creates a new FileSet holding all files in fset. It does not
|
||||
// create copies of the token.Files in fset: they are added to the resulting
|
||||
// FileSet unmodified.
|
||||
func CloneFileSet(fset *token.FileSet) *token.FileSet {
|
||||
var files []*token.File
|
||||
fset.Iterate(func(f *token.File) bool {
|
||||
files = append(files, f)
|
||||
return true
|
||||
})
|
||||
newFileSet := token.NewFileSet()
|
||||
AddExistingFiles(newFileSet, files)
|
||||
return newFileSet
|
||||
}
|
||||
|
1
vendor/golang.org/x/tools/internal/typeparams/common.go
generated
vendored
1
vendor/golang.org/x/tools/internal/typeparams/common.go
generated
vendored
@@ -87,7 +87,6 @@ func IsTypeParam(t types.Type) bool {
|
||||
func OriginMethod(fn *types.Func) *types.Func {
|
||||
recv := fn.Type().(*types.Signature).Recv()
|
||||
if recv == nil {
|
||||
|
||||
return fn
|
||||
}
|
||||
base := recv.Type()
|
||||
|
9
vendor/golang.org/x/tools/internal/typesinternal/types.go
generated
vendored
9
vendor/golang.org/x/tools/internal/typesinternal/types.go
generated
vendored
@@ -11,6 +11,8 @@ import (
|
||||
"go/types"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/tools/go/types/objectpath"
|
||||
)
|
||||
|
||||
func SetUsesCgo(conf *types.Config) bool {
|
||||
@@ -50,3 +52,10 @@ func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos,
|
||||
}
|
||||
|
||||
var SetGoVersion = func(conf *types.Config, version string) bool { return false }
|
||||
|
||||
// NewObjectpathEncoder returns a function closure equivalent to
|
||||
// objectpath.For but amortized for multiple (sequential) calls.
|
||||
// It is a temporary workaround, pending the approval of proposal 58668.
|
||||
//
|
||||
//go:linkname NewObjectpathFunc golang.org/x/tools/go/types/objectpath.newEncoderFor
|
||||
func NewObjectpathFunc() func(types.Object) (objectpath.Path, error)
|
||||
|
Reference in New Issue
Block a user