diff --git a/go.mod b/go.mod index 8804d3119..149871261 100644 --- a/go.mod +++ b/go.mod @@ -4,20 +4,20 @@ go 1.18 require ( github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 - github.com/caddyserver/certmagic v0.16.1 + github.com/caddyserver/certmagic v0.16.2 github.com/chzyer/readline v1.5.1 github.com/ddliu/go-httpclient v0.6.9 github.com/denisenkom/go-mssqldb v0.12.2 github.com/didip/tollbooth v4.0.2+incompatible github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 - github.com/evanw/esbuild v0.14.49 + github.com/evanw/esbuild v0.14.53 github.com/go-gcfg/gcfg v1.2.3 github.com/lib/pq v1.10.6 - github.com/lucas-clemente/quic-go v0.28.0 + github.com/lucas-clemente/quic-go v0.28.1 github.com/mitchellh/go-homedir v1.1.0 github.com/natefinch/pie v0.0.0-20170715172608-9a0d72014007 github.com/russross/blackfriday/v2 v2.1.0 - github.com/sirupsen/logrus v1.8.1 + github.com/sirupsen/logrus v1.9.0 github.com/tylerb/graceful v1.2.15 github.com/wellington/sass v0.0.0-20160911051022-cab90b3986d6 github.com/xyproto/ask v1.0.1-0.20190918171905-3782b6dc3afd @@ -44,13 +44,13 @@ require ( github.com/xyproto/tinysvg v1.1.0 github.com/xyproto/unzip v0.0.0-20150601123358-823950573952 github.com/yosssi/gcss v0.1.0 - golang.org/x/net v0.0.0-20220708220712-1185a9018129 + golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b ) require ( github.com/alecthomas/chroma v0.10.0 // indirect github.com/cheekybits/genny v1.0.0 // indirect - github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect + github.com/dlclark/regexp2 v1.7.0 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect @@ -65,12 +65,12 @@ require ( github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 // indirect + github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect github.com/mattetti/filebuffer v1.0.1 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/mholt/acmez v1.0.3 // indirect + github.com/mholt/acmez v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/nxadm/tail v1.4.8 // indirect @@ -85,17 +85,17 @@ require ( github.com/xyproto/simplehstore v1.8.1 // indirect github.com/xyproto/simplemaria v0.0.0-20190613092611-fe65bee4fd92 // indirect github.com/xyproto/symwalk v1.1.1 // indirect - github.com/xyproto/vt100 v1.11.0 // indirect + github.com/xyproto/vt100 v1.11.1 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.21.0 // indirect - golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect + golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect + golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect - golang.org/x/tools v0.1.11 // indirect + golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect + golang.org/x/tools v0.1.12 // indirect gopkg.in/gcfg.v1 v1.2.3 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index 7243ccc1c..1e9231041 100644 --- a/go.sum +++ b/go.sum @@ -21,8 +21,8 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4Yn github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/caddyserver/certmagic v0.16.1 h1:rdSnjcUVJojmL4M0efJ+yHXErrrijS4YYg3FuwRdJkI= -github.com/caddyserver/certmagic v0.16.1/go.mod h1:jKQ5n+ViHAr6DbPwEGLTSM2vDwTO6EvCKBblBRUvvuQ= +github.com/caddyserver/certmagic v0.16.2 h1:k2n3LkkUG3aMUK/kckMuF9/0VFo+0FtMX3drPYESbmQ= +github.com/caddyserver/certmagic v0.16.2/go.mod h1:PgLIr/dSJa+WA7t7z6Je5xuS/e5A/GFCPHRuZ1QP+MQ= github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -49,14 +49,14 @@ github.com/denisenkom/go-mssqldb v0.12.2/go.mod h1:lnIw1mZukFRZDJYQ0Pb833QS2IaC3 github.com/didip/tollbooth v4.0.2+incompatible h1:fVSa33JzSz0hoh2NxpwZtksAzAgd7zjmGO20HCZtF4M= github.com/didip/tollbooth v4.0.2+incompatible/go.mod h1:A9b0665CE6l1KmzpDws2++elm/CsuWBMa5Jv4WY0PEY= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E= -github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= +github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/evanw/esbuild v0.14.49 h1:jpZ/ut75socKiFF2XWSzjTAVAQP7IkRvrkLFaIb/Ueg= -github.com/evanw/esbuild v0.14.49/go.mod h1:GG+zjdi59yh3ehDn4ZWfPcATxjPDUH53iU4ZJbp7dkY= +github.com/evanw/esbuild v0.14.53 h1:9uU73SZUmP1jRQhaC6hPm9aoqFGYlPwfk7OrhG6AhpQ= +github.com/evanw/esbuild v0.14.53/go.mod h1:iINY06rn799hi48UqEnaQvVfZWe6W9bET78LbvN8VWk= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -164,8 +164,8 @@ github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis= github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40= -github.com/lucas-clemente/quic-go v0.28.0 h1:9eXVRgIkMQQyiyorz/dAaOYIx3TFzXsIFkNFz4cxuJM= -github.com/lucas-clemente/quic-go v0.28.0/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= +github.com/lucas-clemente/quic-go v0.28.1 h1:Uo0lvVxWg5la9gflIF9lwa39ONq85Xq2D91YNEIslzU= +github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= @@ -176,8 +176,9 @@ github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 h1:7m/WlWcSROrcK5NxuXaxYD32BZqe/LEEnBrWcH/cOqQ= github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= +github.com/marten-seemann/qtls-go1-19 v0.1.0 h1:rLFKD/9mp/uq1SYGYuVZhm83wkmU95pK5df3GufyYYU= +github.com/marten-seemann/qtls-go1-19 v0.1.0/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= github.com/mattetti/filebuffer v1.0.0/go.mod h1:X6nyAIge2JGVmuJt2MFCqmHrb/5IHiphfHtot0s5cnI= github.com/mattetti/filebuffer v1.0.1 h1:gG7pyfnSIZCxdoKq+cPa8T0hhYtD9NxCdI4D7PTjRLM= github.com/mattetti/filebuffer v1.0.1/go.mod h1:YdMURNDOttIiruleeVr6f56OrMc+MydEnTcXwtkxNVs= @@ -192,8 +193,8 @@ github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpe github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/mholt/acmez v1.0.3 h1:mDgRxGYk6TKlfydYNMfX0HXXJh9i73YL+swPjYCADU8= -github.com/mholt/acmez v1.0.3/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY= +github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80= +github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= @@ -276,8 +277,8 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -371,8 +372,8 @@ github.com/xyproto/tinysvg v1.1.0/go.mod h1:DKgmaYuFIvJab9ug4nH4ZG356VtUaKXG2mUU github.com/xyproto/unzip v0.0.0-20150601123358-823950573952 h1:pCgYs8AOzRpEmdM55hrSnd+TZOr+1/m9Y9KkFIZPwiU= github.com/xyproto/unzip v0.0.0-20150601123358-823950573952/go.mod h1:ygEdojOpwX5uG71ECHji5sod2rpZ+9hqNeAZD50S84Q= github.com/xyproto/vt100 v1.10.4/go.mod h1:GTrdAbDl0c1TYMjR2EoehGn3QyVwACjhSlAS2wdH45k= -github.com/xyproto/vt100 v1.11.0 h1:g8jyvSrAgAlxhxcUsAjTY9IDE5WHv4MjQQmSLESCx5g= -github.com/xyproto/vt100 v1.11.0/go.mod h1:GTrdAbDl0c1TYMjR2EoehGn3QyVwACjhSlAS2wdH45k= +github.com/xyproto/vt100 v1.11.1 h1:+yspG/agkzgBCPChyhV2ScqCe/4H8VUAIceeWxSYCOY= +github.com/xyproto/vt100 v1.11.1/go.mod h1:oOV0IZJ/+d6kUWnyq7r/lIPhkFvmqMuw1hoaoONUA0s= github.com/yosssi/gcss v0.1.0 h1:jRuino7qq7kqntBIhT+0xSUI5/sBgCA/zCQ1Tuzd6Gg= github.com/yosssi/gcss v0.1.0/go.mod h1:M3mTPOWZWjVROkXKZ2AiDzOBOXu2MqQeDXF/nKO44sI= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -408,8 +409,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -444,8 +445,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0= -golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b h1:3ogNYyK4oIQdIKzTu68hQrr4iuVxF3AxKl9Aj/eDrw0= +golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -457,8 +458,8 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -473,7 +474,6 @@ golang.org/x/sys v0.0.0-20190618155005-516e3c20635f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -492,7 +492,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -500,8 +499,10 @@ golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 h1:Y7NOhdqIOU8kYI7BxsgL38d0ot0raxvcW+EMQU2QrT4= +golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -513,8 +514,8 @@ golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -529,8 +530,8 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/vendor/github.com/caddyserver/certmagic/README.md b/vendor/github.com/caddyserver/certmagic/README.md index 2e0e37abc..6fb9a5f6f 100644 --- a/vendor/github.com/caddyserver/certmagic/README.md +++ b/vendor/github.com/caddyserver/certmagic/README.md @@ -445,7 +445,7 @@ By default, CertMagic stores assets on the local file system in `$HOME/.local/sh The notion of a "cluster" or "fleet" of instances that may be serving the same site and sharing certificates, etc, is tied to storage. Simply, any instances that use the same storage facilities are considered part of the cluster. So if you deploy 100 instances of CertMagic behind a load balancer, they are all part of the same cluster if they share the same storage configuration. Sharing storage could be mounting a shared folder, or implementing some other distributed storage system such as a database server or KV store. -The easiest way to change the storage being used is to set `certmagic.DefaultStorage` to a value that satisfies the [Storage interface](https://pkg.go.dev/github.com/caddyserver/certmagic?tab=doc#Storage). Keep in mind that a valid `Storage` must be able to implement some operations atomically in order to provide locking and synchronization. +The easiest way to change the storage being used is to set `certmagic.Default.Storage` to a value that satisfies the [Storage interface](https://pkg.go.dev/github.com/caddyserver/certmagic?tab=doc#Storage). Keep in mind that a valid `Storage` must be able to implement some operations atomically in order to provide locking and synchronization. If you write a Storage implementation, please add it to the [project wiki](https://github.com/caddyserver/certmagic/wiki/Storage-Implementations) so people can find it! @@ -454,7 +454,7 @@ If you write a Storage implementation, please add it to the [project wiki](https All of the certificates in use are de-duplicated and cached in memory for optimal performance at handshake-time. This cache must be backed by persistent storage as described above. -Most applications will not need to interact with certificate caches directly. Usually, the closest you will come is to set the package-wide `certmagic.DefaultStorage` variable (before attempting to create any Configs). However, if your use case requires using different storage facilities for different Configs (that's highly unlikely and NOT recommended! Even Caddy doesn't get that crazy), you will need to call `certmagic.NewCache()` and pass in the storage you want to use, then get new `Config` structs with `certmagic.NewWithCache()` and pass in the cache. +Most applications will not need to interact with certificate caches directly. Usually, the closest you will come is to set the package-wide `certmagic.Default.Storage` variable (before attempting to create any Configs) which defines how the cache is persisted. However, if your use case requires using different storage facilities for different Configs (that's highly unlikely and NOT recommended! Even Caddy doesn't get that crazy), you will need to call `certmagic.NewCache()` and pass in the storage you want to use, then get new `Config` structs with `certmagic.NewWithCache()` and pass in the cache. Again, if you're needing to do this, you've probably over-complicated your application design. diff --git a/vendor/github.com/caddyserver/certmagic/account.go b/vendor/github.com/caddyserver/certmagic/account.go index 484cce0a0..f3cb755a0 100644 --- a/vendor/github.com/caddyserver/certmagic/account.go +++ b/vendor/github.com/caddyserver/certmagic/account.go @@ -171,14 +171,14 @@ func (am *ACMEIssuer) saveAccount(ctx context.Context, ca string, account acme.A return storeTx(ctx, am.config.Storage, all) } -// getEmail does everything it can to obtain an email address +// setEmail does everything it can to obtain an email address // from the user within the scope of memory and storage to use // for ACME TLS. If it cannot get an email address, it does nothing // (If user is prompted, it will warn the user of // the consequences of an empty email.) This function MAY prompt // the user for input. If allowPrompts is false, the user // will NOT be prompted and an empty email may be returned. -func (am *ACMEIssuer) getEmail(ctx context.Context, allowPrompts bool) error { +func (am *ACMEIssuer) setEmail(ctx context.Context, allowPrompts bool) error { leEmail := am.Email // First try package default email, or a discovered email address @@ -206,10 +206,12 @@ func (am *ACMEIssuer) getEmail(ctx context.Context, allowPrompts bool) error { } // User might have just signified their agreement - am.Agreed = DefaultACME.Agreed + am.mu.Lock() + am.agreed = DefaultACME.Agreed + am.mu.Unlock() } - // save the email for later and ensure it is consistent + // Save the email for later and ensure it is consistent // for repeated use; then update cfg with the email leEmail = strings.TrimSpace(strings.ToLower(leEmail)) discoveredEmailMu.Lock() @@ -217,7 +219,12 @@ func (am *ACMEIssuer) getEmail(ctx context.Context, allowPrompts bool) error { discoveredEmail = leEmail } discoveredEmailMu.Unlock() - am.Email = leEmail + + // The unexported email field is the one we use + // because we have thread-safe control over it + am.mu.Lock() + am.email = leEmail + am.mu.Unlock() return nil } diff --git a/vendor/github.com/caddyserver/certmagic/acmeclient.go b/vendor/github.com/caddyserver/certmagic/acmeclient.go index f93b34d02..90a06ba18 100644 --- a/vendor/github.com/caddyserver/certmagic/acmeclient.go +++ b/vendor/github.com/caddyserver/certmagic/acmeclient.go @@ -16,12 +16,10 @@ package certmagic import ( "context" - "crypto/tls" "crypto/x509" "fmt" weakrand "math/rand" "net" - "net/http" "net/url" "strconv" "strings" @@ -61,7 +59,7 @@ func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, useTestCA, if iss.AccountKeyPEM != "" { account, err = iss.GetAccount(ctx, []byte(iss.AccountKeyPEM)) } else { - account, err = iss.getAccount(ctx, client.Directory, iss.Email) + account, err = iss.getAccount(ctx, client.Directory, iss.getEmail()) } if err != nil { return nil, fmt.Errorf("getting ACME account: %v", err) @@ -78,7 +76,7 @@ func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, useTestCA, // agree to terms if interactive { - if !iss.Agreed { + if !iss.isAgreed() { var termsURL string dir, err := client.GetDirectory(ctx) if err != nil { @@ -88,18 +86,23 @@ func (iss *ACMEIssuer) newACMEClientWithAccount(ctx context.Context, useTestCA, termsURL = dir.Meta.TermsOfService } if termsURL != "" { - iss.Agreed = iss.askUserAgreement(termsURL) - if !iss.Agreed { + agreed := iss.askUserAgreement(termsURL) + if !agreed { return nil, fmt.Errorf("user must agree to CA terms") } + iss.mu.Lock() + iss.agreed = agreed + iss.mu.Unlock() } } } else { // can't prompt a user who isn't there; they should // have reviewed the terms beforehand - iss.Agreed = true + iss.mu.Lock() + iss.agreed = true + iss.mu.Unlock() } - account.TermsOfServiceAgreed = iss.Agreed + account.TermsOfServiceAgreed = iss.isAgreed() // associate account with external binding, if configured if iss.ExternalAccount != nil { @@ -163,59 +166,17 @@ func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, error) { return nil, fmt.Errorf("%s: insecure CA URL (HTTPS required)", caURL) } - // set up the dialers and resolver for the ACME client's HTTP client - dialer := &net.Dialer{ - Timeout: 30 * time.Second, - KeepAlive: 2 * time.Minute, - } - if iss.Resolver != "" { - dialer.Resolver = &net.Resolver{ - PreferGo: true, - Dial: func(ctx context.Context, network, _ string) (net.Conn, error) { - return (&net.Dialer{ - Timeout: 15 * time.Second, - }).DialContext(ctx, network, iss.Resolver) - }, - } - } - - // TODO: we could potentially reuse the HTTP transport and client - hc := iss.httpClient // TODO: is this racey? - if iss.httpClient == nil { - transport := &http.Transport{ - Proxy: http.ProxyFromEnvironment, - DialContext: dialer.DialContext, - TLSHandshakeTimeout: 30 * time.Second, // increase to 30s requested in #175 - ResponseHeaderTimeout: 30 * time.Second, // increase to 30s requested in #175 - ExpectContinueTimeout: 2 * time.Second, - ForceAttemptHTTP2: true, - } - if iss.TrustedRoots != nil { - transport.TLSClientConfig = &tls.Config{ - RootCAs: iss.TrustedRoots, - } - } - - hc = &http.Client{ - Transport: transport, - Timeout: HTTPTimeout, - } - - iss.httpClient = hc - } - client := &acmez.Client{ Client: &acme.Client{ Directory: caURL, PollTimeout: certObtainTimeout, UserAgent: buildUAString(), - HTTPClient: hc, + HTTPClient: iss.httpClient, }, ChallengeSolvers: make(map[string]acmez.Solver), } if iss.Logger != nil { - l := iss.Logger.Named("acme_client") - client.Client.Logger, client.Logger = l, l + client.Logger = iss.Logger.Named("acme_client") } // configure challenges (most of the time, DNS challenge is @@ -287,8 +248,10 @@ func (iss *ACMEIssuer) newACMEClient(useTestCA bool) (*acmez.Client, error) { } func (c *acmeClient) throttle(ctx context.Context, names []string) error { + email := c.iss.getEmail() + // throttling is scoped to CA + account email - rateLimiterKey := c.acmeClient.Directory + "," + c.iss.Email + rateLimiterKey := c.acmeClient.Directory + "," + email rateLimitersMu.Lock() rl, ok := rateLimiters[rateLimiterKey] if !ok { @@ -301,7 +264,7 @@ func (c *acmeClient) throttle(ctx context.Context, names []string) error { c.iss.Logger.Info("waiting on internal rate limiter", zap.Strings("identifiers", names), zap.String("ca", c.acmeClient.Directory), - zap.String("account", c.iss.Email), + zap.String("account", email), ) } err := rl.Wait(ctx) @@ -312,7 +275,7 @@ func (c *acmeClient) throttle(ctx context.Context, names []string) error { c.iss.Logger.Info("done waiting on internal rate limiter", zap.Strings("identifiers", names), zap.String("ca", c.acmeClient.Directory), - zap.String("account", c.iss.Email), + zap.String("account", email), ) } return nil diff --git a/vendor/github.com/caddyserver/certmagic/acmeissuer.go b/vendor/github.com/caddyserver/certmagic/acmeissuer.go index 94dfc2c71..4b49b1fa9 100644 --- a/vendor/github.com/caddyserver/certmagic/acmeissuer.go +++ b/vendor/github.com/caddyserver/certmagic/acmeissuer.go @@ -2,13 +2,16 @@ package certmagic import ( "context" + "crypto/tls" "crypto/x509" "errors" "fmt" + "net" "net/http" "net/url" "sort" "strings" + "sync" "time" "github.com/mholt/acmez" @@ -112,6 +115,18 @@ type ACMEIssuer struct { config *Config httpClient *http.Client + + // Some fields are changed on-the-fly during + // certificate management. For example, the + // email might be implicitly discovered if not + // explicitly configured, and agreement might + // happen during the flow. Changing the exported + // fields field is racey (issue #195) so we + // control unexported fields that we can + // synchronize properly. + email string + agreed bool + mu *sync.Mutex // protects the above grouped fields } // NewACMEIssuer constructs a valid ACMEIssuer based on a template @@ -181,7 +196,43 @@ func NewACMEIssuer(cfg *Config, template ACMEIssuer) *ACMEIssuer { if template.Logger == nil { template.Logger = DefaultACME.Logger } + template.config = cfg + template.mu = new(sync.Mutex) + + // set up the dialer and transport / HTTP client + dialer := &net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 2 * time.Minute, + } + if template.Resolver != "" { + dialer.Resolver = &net.Resolver{ + PreferGo: true, + Dial: func(ctx context.Context, network, _ string) (net.Conn, error) { + return (&net.Dialer{ + Timeout: 15 * time.Second, + }).DialContext(ctx, network, template.Resolver) + }, + } + } + transport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: dialer.DialContext, + TLSHandshakeTimeout: 30 * time.Second, // increase to 30s requested in #175 + ResponseHeaderTimeout: 30 * time.Second, // increase to 30s requested in #175 + ExpectContinueTimeout: 2 * time.Second, + ForceAttemptHTTP2: true, + } + if template.TrustedRoots != nil { + transport.TLSClientConfig = &tls.Config{ + RootCAs: template.TrustedRoots, + } + } + template.httpClient = &http.Client{ + Transport: transport, + Timeout: HTTPTimeout, + } + return &template } @@ -213,6 +264,18 @@ func (*ACMEIssuer) issuerKey(ca string) string { return key } +func (iss *ACMEIssuer) getEmail() string { + iss.mu.Lock() + defer iss.mu.Unlock() + return iss.email +} + +func (iss *ACMEIssuer) isAgreed() bool { + iss.mu.Lock() + defer iss.mu.Unlock() + return iss.agreed +} + // PreCheck performs a few simple checks before obtaining or // renewing a certificate with ACME, and returns whether this // batch is eligible for certificates if using Let's Encrypt. @@ -226,7 +289,7 @@ func (am *ACMEIssuer) PreCheck(ctx context.Context, names []string, interactive } } } - return am.getEmail(ctx, interactive) + return am.setEmail(ctx, interactive) } // Issue implements the Issuer interface. It obtains a certificate for the given csr using diff --git a/vendor/github.com/caddyserver/certmagic/certificates.go b/vendor/github.com/caddyserver/certmagic/certificates.go index 47bcd71df..707331f01 100644 --- a/vendor/github.com/caddyserver/certmagic/certificates.go +++ b/vendor/github.com/caddyserver/certmagic/certificates.go @@ -341,7 +341,7 @@ func (cfg *Config) reloadManagedCertificate(ctx context.Context, oldCert Certifi // as a quick sanity check, looks like it could be the subject // of a certificate. Requirements are: // - must not be empty -// - must not start or end with a dot (RFC 1034) +// - must not start or end with a dot (RFC 1034; RFC 6066 section 3) // - must not contain common accidental special characters func SubjectQualifiesForCert(subj string) bool { // must not be empty diff --git a/vendor/github.com/caddyserver/certmagic/dnsutil.go b/vendor/github.com/caddyserver/certmagic/dnsutil.go index 2eb064e34..0d7ba74fd 100644 --- a/vendor/github.com/caddyserver/certmagic/dnsutil.go +++ b/vendor/github.com/caddyserver/certmagic/dnsutil.go @@ -133,7 +133,9 @@ func dnsQuery(fqdn string, rtype uint16, nameservers []string, recursive bool) ( func createDNSMsg(fqdn string, rtype uint16, recursive bool) *dns.Msg { m := new(dns.Msg) m.SetQuestion(fqdn, rtype) - m.SetEdns0(4096, false) + + // See: https://caddy.community/t/hard-time-getting-a-response-on-a-dns-01-challenge/15721/16 + m.SetEdns0(1232, false) if !recursive { m.RecursionDesired = false } diff --git a/vendor/github.com/caddyserver/certmagic/solvers.go b/vendor/github.com/caddyserver/certmagic/solvers.go index 01087dba6..dcde352db 100644 --- a/vendor/github.com/caddyserver/certmagic/solvers.go +++ b/vendor/github.com/caddyserver/certmagic/solvers.go @@ -238,9 +238,18 @@ func (s *tlsALPNSolver) CleanUp(ctx context.Context, chal acme.Challenge) error return nil } -// DNS01Solver is a type that makes libdns providers usable -// as ACME dns-01 challenge solvers. -// See https://github.com/libdns/libdns +// DNS01Solver is a type that makes libdns providers usable as ACME dns-01 +// challenge solvers. See https://github.com/libdns/libdns +// +// Note that challenges may be solved concurrently by some clients (such as +// acmez, which CertMagic uses), meaning that multiple TXT records may be +// created in a DNS zone simultaneously, and in some cases distinct TXT records +// may have the same name. For example, solving challenges for both example.com +// and *.example.com create a TXT record named _acme_challenge.example.com, +// but with different tokens as their values. This solver distinguishes +// between different records with the same name by looking at their values. +// DNS provider APIs and implementations of the libdns interfaces must also +// support multiple same-named TXT records. type DNS01Solver struct { // The implementation that interacts with the DNS // provider to set or delete records. (REQUIRED) @@ -266,7 +275,18 @@ type DNS01Solver struct { // that the solver doesn't follow CNAME/NS record. OverrideDomain string - txtRecords map[string]dnsPresentMemory // keyed by domain name + // Remember DNS records while challenges are active; i.e. + // records we have presented and not yet cleaned up. + // This lets us clean them up quickly and efficiently. + // Keyed by domain name (specifically the ACME DNS name). + // The map value is a slice because there can be multiple + // concurrent challenges for different domains that have + // the same ACME DNS name, for example: example.com and + // *.example.com. We distinguish individual memories by + // the value of their TXT records, which should contain + // unique challenge tokens. + // See https://github.com/caddyserver/caddy/issues/3474. + txtRecords map[string][]dnsPresentMemory txtRecordsMu sync.Mutex } @@ -278,13 +298,6 @@ func (s *DNS01Solver) Present(ctx context.Context, challenge acme.Challenge) err } keyAuth := challenge.DNS01KeyAuthorization() - // multiple identifiers can have the same ACME challenge - // domain (e.g. example.com and *.example.com) so we need - // to ensure that we don't solve those concurrently and - // step on each challenges' metaphorical toes; see - // https://github.com/caddyserver/caddy/issues/3474 - activeDNSChallenges.Lock(dnsName) - zone, err := findZoneByFQDN(dnsName, recursiveNameservers(s.Resolvers)) if err != nil { return fmt.Errorf("could not determine zone for domain %q: %v", dnsName, err) @@ -299,19 +312,18 @@ func (s *DNS01Solver) Present(ctx context.Context, challenge acme.Challenge) err results, err := s.DNSProvider.AppendRecords(ctx, zone, []libdns.Record{rec}) if err != nil { - return fmt.Errorf("adding temporary record for zone %s: %w", zone, err) + return fmt.Errorf("adding temporary record for zone %q: %w", zone, err) } if len(results) != 1 { return fmt.Errorf("expected one record, got %d: %v", len(results), results) } // remember the record and zone we got so we can clean up more efficiently - s.txtRecordsMu.Lock() - if s.txtRecords == nil { - s.txtRecords = make(map[string]dnsPresentMemory) - } - s.txtRecords[dnsName] = dnsPresentMemory{dnsZone: zone, rec: results[0]} - s.txtRecordsMu.Unlock() + s.saveDNSPresentMemory(dnsPresentMemory{ + dnsZone: zone, + dnsName: dnsName, + rec: results[0], + }) return nil } @@ -363,7 +375,7 @@ func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error var ready bool ready, err = checkDNSPropagation(dnsName, keyAuth, resolvers) if err != nil { - return fmt.Errorf("checking DNS propagation of %s: %w", dnsName, err) + return fmt.Errorf("checking DNS propagation of %q: %w", dnsName, err) } if ready { return nil @@ -376,30 +388,24 @@ func (s *DNS01Solver) Wait(ctx context.Context, challenge acme.Challenge) error // CleanUp deletes the DNS TXT record created in Present(). func (s *DNS01Solver) CleanUp(ctx context.Context, challenge acme.Challenge) error { dnsName := challenge.DNS01TXTRecordName() + if s.OverrideDomain != "" { + dnsName = s.OverrideDomain + } + keyAuth := challenge.DNS01KeyAuthorization() - defer func() { - // always forget about it so we don't leak memory - s.txtRecordsMu.Lock() - delete(s.txtRecords, dnsName) - s.txtRecordsMu.Unlock() - - // always do this last - but always do it! - activeDNSChallenges.Unlock(dnsName) - }() + // always forget about the record so we don't leak memory + defer s.deleteDNSPresentMemory(dnsName, keyAuth) // recall the record we created and zone we looked up - s.txtRecordsMu.Lock() - memory, ok := s.txtRecords[dnsName] - if !ok { - s.txtRecordsMu.Unlock() - return fmt.Errorf("no memory of presenting a DNS record for %s (probably OK if presenting failed)", challenge.Identifier.Value) + memory, err := s.getDNSPresentMemory(dnsName, keyAuth) + if err != nil { + return err } - s.txtRecordsMu.Unlock() // clean up the record - _, err := s.DNSProvider.DeleteRecords(ctx, memory.dnsZone, []libdns.Record{memory.rec}) + _, err = s.DNSProvider.DeleteRecords(ctx, memory.dnsZone, []libdns.Record{memory.rec}) if err != nil { - return fmt.Errorf("deleting temporary record for zone %s: %w", memory.dnsZone, err) + return fmt.Errorf("deleting temporary record for name %q in zone %q: %w", memory.dnsName, memory.dnsZone, err) } return nil @@ -407,58 +413,58 @@ func (s *DNS01Solver) CleanUp(ctx context.Context, challenge acme.Challenge) err type dnsPresentMemory struct { dnsZone string + dnsName string rec libdns.Record } -// ACMEDNSProvider defines the set of operations required for -// ACME challenges. A DNS provider must be able to append and -// delete records in order to solve ACME challenges. Find one -// you can use at https://github.com/libdns. If your provider -// isn't implemented yet, feel free to contribute! -type ACMEDNSProvider interface { - libdns.RecordAppender - libdns.RecordDeleter +func (s *DNS01Solver) saveDNSPresentMemory(mem dnsPresentMemory) { + s.txtRecordsMu.Lock() + if s.txtRecords == nil { + s.txtRecords = make(map[string][]dnsPresentMemory) + } + s.txtRecords[mem.dnsName] = append(s.txtRecords[mem.dnsName], mem) + s.txtRecordsMu.Unlock() } -// activeDNSChallenges synchronizes DNS challenges for -// names to ensure that challenges for the same ACME -// DNS name do not overlap; for example, the TXT record -// to make for both example.com and *.example.com are -// the same; thus we cannot solve them concurrently. -var activeDNSChallenges = newMapMutex() - -// mapMutex implements named mutexes. -type mapMutex struct { - cond *sync.Cond - set map[interface{}]struct{} -} +func (s *DNS01Solver) getDNSPresentMemory(dnsName, keyAuth string) (dnsPresentMemory, error) { + s.txtRecordsMu.Lock() + defer s.txtRecordsMu.Unlock() -func newMapMutex() *mapMutex { - return &mapMutex{ - cond: sync.NewCond(new(sync.Mutex)), - set: make(map[interface{}]struct{}), + var memory dnsPresentMemory + for _, mem := range s.txtRecords[dnsName] { + if mem.rec.Value == keyAuth { + memory = mem + break + } } -} -func (mmu *mapMutex) Lock(key interface{}) { - mmu.cond.L.Lock() - defer mmu.cond.L.Unlock() - for mmu.locked(key) { - mmu.cond.Wait() + if memory.rec.Name == "" { + return dnsPresentMemory{}, fmt.Errorf("no memory of presenting a DNS record for %q (usually OK if presenting also failed)", dnsName) } - mmu.set[key] = struct{}{} + + return memory, nil } -func (mmu *mapMutex) Unlock(key interface{}) { - mmu.cond.L.Lock() - defer mmu.cond.L.Unlock() - delete(mmu.set, key) - mmu.cond.Broadcast() +func (s *DNS01Solver) deleteDNSPresentMemory(dnsName, keyAuth string) { + s.txtRecordsMu.Lock() + defer s.txtRecordsMu.Unlock() + + for i, mem := range s.txtRecords[dnsName] { + if mem.rec.Value == keyAuth { + s.txtRecords[dnsName] = append(s.txtRecords[dnsName][:i], s.txtRecords[dnsName][i+1:]...) + return + } + } } -func (mmu *mapMutex) locked(key interface{}) (ok bool) { - _, ok = mmu.set[key] - return +// ACMEDNSProvider defines the set of operations required for +// ACME challenges. A DNS provider must be able to append and +// delete records in order to solve ACME challenges. Find one +// you can use at https://github.com/libdns. If your provider +// isn't implemented yet, feel free to contribute! +type ACMEDNSProvider interface { + libdns.RecordAppender + libdns.RecordDeleter } // distributedSolver allows the ACME HTTP-01 and TLS-ALPN challenges diff --git a/vendor/github.com/dlclark/regexp2/README.md b/vendor/github.com/dlclark/regexp2/README.md index f92f8b10b..b404471cb 100644 --- a/vendor/github.com/dlclark/regexp2/README.md +++ b/vendor/github.com/dlclark/regexp2/README.md @@ -80,6 +80,8 @@ The default behavior of `regexp2` is to match the .NET regexp engine, however th * add support for named ascii character classes (e.g. `[[:foo:]]`) * add support for python-style capture groups (e.g. `(Pre)`) * change singleline behavior for `$` to only match end of string (like RE2) (see [#24](https://github.com/dlclark/regexp2/issues/24)) +* change the character classes `\d` `\s` and `\w` to match the same characters as RE2. NOTE: if you also use the `ECMAScript` option then this will change the `\s` character class to match ECMAScript instead of RE2. ECMAScript allows more whitespace characters in `\s` than RE2 (but still fewer than the the default behavior). +* allow character escape sequences to have defaults. For example, by default `\_` isn't a known character escape and will fail to compile, but in RE2 mode it will match the literal character `_` ```go re := regexp2.MustCompile(`Your RE2-compatible pattern`, regexp2.RE2) @@ -90,6 +92,10 @@ if isMatch, _ := re.MatchString(`Something to match`); isMatch { This feature is a work in progress and I'm open to ideas for more things to put here (maybe more relaxed character escaping rules?). +## ECMAScript compatibility mode +In this mode the engine provides compatibility with the [regex engine](https://tc39.es/ecma262/multipage/text-processing.html#sec-regexp-regular-expression-objects) described in the ECMAScript specification. + +Additionally a Unicode mode is provided which allows parsing of `\u{CodePoint}` syntax that is only when both are provided. ## Library features that I'm still working on - Regex split diff --git a/vendor/github.com/dlclark/regexp2/regexp.go b/vendor/github.com/dlclark/regexp2/regexp.go index 7c7b01d87..818c7663b 100644 --- a/vendor/github.com/dlclark/regexp2/regexp.go +++ b/vendor/github.com/dlclark/regexp2/regexp.go @@ -121,6 +121,7 @@ const ( Debug = 0x0080 // "d" ECMAScript = 0x0100 // "e" RE2 = 0x0200 // RE2 (regexp package) compatibility mode + Unicode = 0x0400 // "u" ) func (re *Regexp) RightToLeft() bool { diff --git a/vendor/github.com/dlclark/regexp2/syntax/charclass.go b/vendor/github.com/dlclark/regexp2/syntax/charclass.go index 53974d101..6881a0e29 100644 --- a/vendor/github.com/dlclark/regexp2/syntax/charclass.go +++ b/vendor/github.com/dlclark/regexp2/syntax/charclass.go @@ -37,6 +37,8 @@ var ( ecmaSpace = []rune{0x0009, 0x000e, 0x0020, 0x0021, 0x00a0, 0x00a1, 0x1680, 0x1681, 0x2000, 0x200b, 0x2028, 0x202a, 0x202f, 0x2030, 0x205f, 0x2060, 0x3000, 0x3001, 0xfeff, 0xff00} ecmaWord = []rune{0x0030, 0x003a, 0x0041, 0x005b, 0x005f, 0x0060, 0x0061, 0x007b} ecmaDigit = []rune{0x0030, 0x003a} + + re2Space = []rune{0x0009, 0x000b, 0x000c, 0x000e, 0x0020, 0x0021} ) var ( @@ -56,6 +58,9 @@ var ( NotSpaceClass = getCharSetFromCategoryString(true, false, spaceCategoryText) DigitClass = getCharSetFromCategoryString(false, false, "Nd") NotDigitClass = getCharSetFromCategoryString(false, true, "Nd") + + RE2SpaceClass = getCharSetFromOldString(re2Space, false) + NotRE2SpaceClass = getCharSetFromOldString(re2Space, true) ) var unicodeCategories = func() map[string]*unicode.RangeTable { @@ -401,13 +406,19 @@ func (c *CharSet) addChar(ch rune) { c.addRange(ch, ch) } -func (c *CharSet) addSpace(ecma, negate bool) { +func (c *CharSet) addSpace(ecma, re2, negate bool) { if ecma { if negate { c.addRanges(NotECMASpaceClass().ranges) } else { c.addRanges(ECMASpaceClass().ranges) } + } else if re2 { + if negate { + c.addRanges(NotRE2SpaceClass().ranges) + } else { + c.addRanges(RE2SpaceClass().ranges) + } } else { c.addCategories(category{cat: spaceCategoryText, negate: negate}) } @@ -563,7 +574,7 @@ func (c *CharSet) addNamedASCII(name string, negate bool) bool { case "punct": //[!-/:-@[-`{-~] rs = []singleRange{singleRange{'!', '/'}, singleRange{':', '@'}, singleRange{'[', '`'}, singleRange{'{', '~'}} case "space": - c.addSpace(true, negate) + c.addSpace(true, false, negate) case "upper": rs = []singleRange{singleRange{'A', 'Z'}} case "word": diff --git a/vendor/github.com/dlclark/regexp2/syntax/parser.go b/vendor/github.com/dlclark/regexp2/syntax/parser.go index d86f33282..9dc6e3130 100644 --- a/vendor/github.com/dlclark/regexp2/syntax/parser.go +++ b/vendor/github.com/dlclark/regexp2/syntax/parser.go @@ -22,6 +22,7 @@ const ( Debug = 0x0080 // "d" ECMAScript = 0x0100 // "e" RE2 = 0x0200 // RE2 compat mode + Unicode = 0x0400 // "u" ) func optionFromCode(ch rune) RegexOptions { @@ -43,6 +44,8 @@ func optionFromCode(ch rune) RegexOptions { return Debug case 'e', 'E': return ECMAScript + case 'u', 'U': + return Unicode default: return 0 } @@ -104,7 +107,7 @@ const ( ErrBadClassInCharRange = "cannot include class \\%v in character range" ErrUnterminatedBracket = "unterminated [] set" ErrSubtractionMustBeLast = "a subtraction must be the last element in a character class" - ErrReversedCharRange = "[x-y] range in reverse order" + ErrReversedCharRange = "[%c-%c] range in reverse order" ) func (e ErrorCode) String() string { @@ -1121,14 +1124,14 @@ func (p *parser) scanBackslash(scanOnly bool) (*regexNode, error) { case 'w': p.moveRight(1) - if p.useOptionE() { + if p.useOptionE() || p.useRE2() { return newRegexNodeSet(ntSet, p.options, ECMAWordClass()), nil } return newRegexNodeSet(ntSet, p.options, WordClass()), nil case 'W': p.moveRight(1) - if p.useOptionE() { + if p.useOptionE() || p.useRE2() { return newRegexNodeSet(ntSet, p.options, NotECMAWordClass()), nil } return newRegexNodeSet(ntSet, p.options, NotWordClass()), nil @@ -1137,6 +1140,8 @@ func (p *parser) scanBackslash(scanOnly bool) (*regexNode, error) { p.moveRight(1) if p.useOptionE() { return newRegexNodeSet(ntSet, p.options, ECMASpaceClass()), nil + } else if p.useRE2() { + return newRegexNodeSet(ntSet, p.options, RE2SpaceClass()), nil } return newRegexNodeSet(ntSet, p.options, SpaceClass()), nil @@ -1144,19 +1149,21 @@ func (p *parser) scanBackslash(scanOnly bool) (*regexNode, error) { p.moveRight(1) if p.useOptionE() { return newRegexNodeSet(ntSet, p.options, NotECMASpaceClass()), nil + } else if p.useRE2() { + return newRegexNodeSet(ntSet, p.options, NotRE2SpaceClass()), nil } return newRegexNodeSet(ntSet, p.options, NotSpaceClass()), nil case 'd': p.moveRight(1) - if p.useOptionE() { + if p.useOptionE() || p.useRE2() { return newRegexNodeSet(ntSet, p.options, ECMADigitClass()), nil } return newRegexNodeSet(ntSet, p.options, DigitClass()), nil case 'D': p.moveRight(1) - if p.useOptionE() { + if p.useOptionE() || p.useRE2() { return newRegexNodeSet(ntSet, p.options, NotECMADigitClass()), nil } return newRegexNodeSet(ntSet, p.options, NotDigitClass()), nil @@ -1462,7 +1469,7 @@ func (p *parser) scanCharSet(caseInsensitive, scanOnly bool) (*CharSet, error) { if inRange { return nil, p.getErr(ErrBadClassInCharRange, ch) } - cc.addDigit(p.useOptionE(), ch == 'D', p.patternRaw) + cc.addDigit(p.useOptionE() || p.useRE2(), ch == 'D', p.patternRaw) } continue @@ -1471,7 +1478,7 @@ func (p *parser) scanCharSet(caseInsensitive, scanOnly bool) (*CharSet, error) { if inRange { return nil, p.getErr(ErrBadClassInCharRange, ch) } - cc.addSpace(p.useOptionE(), ch == 'S') + cc.addSpace(p.useOptionE(), p.useRE2(), ch == 'S') } continue @@ -1481,7 +1488,7 @@ func (p *parser) scanCharSet(caseInsensitive, scanOnly bool) (*CharSet, error) { return nil, p.getErr(ErrBadClassInCharRange, ch) } - cc.addWord(p.useOptionE(), ch == 'W') + cc.addWord(p.useOptionE() || p.useRE2(), ch == 'W') } continue @@ -1567,7 +1574,7 @@ func (p *parser) scanCharSet(caseInsensitive, scanOnly bool) (*CharSet, error) { } else { // a regular range, like a-z if chPrev > ch { - return nil, p.getErr(ErrReversedCharRange) + return nil, p.getErr(ErrReversedCharRange, chPrev, ch) } cc.addRange(chPrev, ch) } @@ -1691,7 +1698,13 @@ func (p *parser) scanCharEscape() (r rune, err error) { r, err = p.scanHex(2) } case 'u': - r, err = p.scanHex(4) + // ECMAscript suppot \u{HEX} only if `u` is also set + if p.useOptionE() && p.useOptionU() && p.charsRight() > 0 && p.rightChar(0) == '{' { + p.moveRight(1) + return p.scanHexUntilBrace() + } else { + r, err = p.scanHex(4) + } case 'a': return '\u0007', nil case 'b': @@ -1711,7 +1724,7 @@ func (p *parser) scanCharEscape() (r rune, err error) { case 'c': r, err = p.scanControl() default: - if !p.useOptionE() && IsWordChar(ch) { + if !p.useOptionE() && !p.useRE2() && IsWordChar(ch) { return 0, p.getErr(ErrUnrecognizedEscape, string(ch)) } return ch, nil @@ -1968,6 +1981,11 @@ func (p *parser) useRE2() bool { return (p.options & RE2) != 0 } +// True if U option enabling ECMAScript's Unicode behavior on. +func (p *parser) useOptionU() bool { + return (p.options & Unicode) != 0 +} + // True if options stack is empty. func (p *parser) emptyOptionsStack() bool { return len(p.optionsStack) == 0 @@ -2063,7 +2081,8 @@ func (p *parser) addToConcatenate(pos, cch int, isReplacement bool) { } if cch > 1 { - str := p.pattern[pos : pos+cch] + str := make([]rune, cch) + copy(str, p.pattern[pos:pos+cch]) if p.useOptionI() && !isReplacement { // We do the ToLower character by character for consistency. With surrogate chars, doing diff --git a/vendor/github.com/evanw/esbuild/internal/bundler/bundler.go b/vendor/github.com/evanw/esbuild/internal/bundler/bundler.go index 274cd73de..4c3c2c61c 100644 --- a/vendor/github.com/evanw/esbuild/internal/bundler/bundler.go +++ b/vendor/github.com/evanw/esbuild/internal/bundler/bundler.go @@ -26,7 +26,6 @@ import ( "github.com/evanw/esbuild/internal/js_ast" "github.com/evanw/esbuild/internal/js_lexer" "github.com/evanw/esbuild/internal/js_parser" - "github.com/evanw/esbuild/internal/js_printer" "github.com/evanw/esbuild/internal/logger" "github.com/evanw/esbuild/internal/resolver" "github.com/evanw/esbuild/internal/runtime" @@ -505,7 +504,7 @@ func ResolveFailureErrorTextSuggestionNotes( hint = fmt.Sprintf("Use the relative path %q to reference the file %q. "+ "Without the leading \"./\", the path %q is being interpreted as a package path instead.", "./"+path, res.PrettyPath(query.PathPair.Primary), path) - suggestion = string(js_printer.QuoteForJSON("./"+path, false)) + suggestion = string(helpers.QuoteForJSON("./"+path, false)) } } } @@ -1195,6 +1194,12 @@ func (s *scanner) maybeParseFile( if len(resolveResult.JSXFragment) > 0 { optionsClone.JSX.Fragment = config.DefineExpr{Parts: resolveResult.JSXFragment} } + if resolveResult.JSX != config.TSJSXNone { + optionsClone.JSX.SetOptionsFromTSJSX(resolveResult.JSX) + } + if resolveResult.JSXImportSource != "" { + optionsClone.JSX.ImportSource = resolveResult.JSXImportSource + } if resolveResult.UseDefineForClassFieldsTS != config.Unspecified { optionsClone.UseDefineForClassFields = resolveResult.UseDefineForClassFieldsTS } @@ -1723,7 +1728,7 @@ func (s *scanner) processScannedFiles(entryPointMeta []graph.EntryPoint) []scann // Begin the metadata chunk if s.options.NeedsMetafile { - sb.Write(js_printer.QuoteForJSON(result.file.inputFile.Source.PrettyPath, s.options.ASCIIOnly)) + sb.Write(helpers.QuoteForJSON(result.file.inputFile.Source.PrettyPath, s.options.ASCIIOnly)) sb.WriteString(fmt.Sprintf(": {\n \"bytes\": %d,\n \"imports\": [", len(result.file.inputFile.Source.Contents))) } @@ -1770,8 +1775,8 @@ func (s *scanner) processScannedFiles(entryPointMeta []graph.EntryPoint) []scann sb.WriteString(",\n ") } sb.WriteString(fmt.Sprintf("{\n \"path\": %s,\n \"kind\": %s\n }", - js_printer.QuoteForJSON(otherFile.inputFile.Source.PrettyPath, s.options.ASCIIOnly), - js_printer.QuoteForJSON(record.Kind.StringForMetafile(), s.options.ASCIIOnly))) + helpers.QuoteForJSON(otherFile.inputFile.Source.PrettyPath, s.options.ASCIIOnly), + helpers.QuoteForJSON(record.Kind.StringForMetafile(), s.options.ASCIIOnly))) } switch record.Kind { @@ -1948,7 +1953,7 @@ func (s *scanner) processScannedFiles(entryPointMeta []graph.EntryPoint) []scann var jsonMetadataChunk string if s.options.NeedsMetafile { inputs := fmt.Sprintf("{\n %s: {\n \"bytesInOutput\": %d\n }\n }", - js_printer.QuoteForJSON(result.file.inputFile.Source.PrettyPath, s.options.ASCIIOnly), + helpers.QuoteForJSON(result.file.inputFile.Source.PrettyPath, s.options.ASCIIOnly), len(bytes), ) jsonMetadataChunk = fmt.Sprintf( @@ -2349,7 +2354,7 @@ func (b *Bundle) computeDataForSourceMapsInParallel(options *config.Options, rea if !options.ExcludeSourcesContent { if sm == nil { // Simple case: no nested source map - result.quotedContents = [][]byte{js_printer.QuoteForJSON(f.inputFile.Source.Contents, options.ASCIIOnly)} + result.quotedContents = [][]byte{helpers.QuoteForJSON(f.inputFile.Source.Contents, options.ASCIIOnly)} } else { // Complex case: nested source map result.quotedContents = make([][]byte, len(sm.Sources)) @@ -2361,7 +2366,7 @@ func (b *Bundle) computeDataForSourceMapsInParallel(options *config.Options, rea if value := sm.SourcesContent[i]; value.Quoted != "" { if options.ASCIIOnly && !isASCIIOnly(value.Quoted) { // Re-quote non-ASCII values if output is ASCII-only - quotedContents = js_printer.QuoteForJSON(helpers.UTF16ToString(value.Value), options.ASCIIOnly) + quotedContents = helpers.QuoteForJSON(helpers.UTF16ToString(value.Value), options.ASCIIOnly) } else { // Otherwise just use the value directly from the input file quotedContents = []byte(value.Quoted) @@ -2423,7 +2428,7 @@ func (b *Bundle) generateMetadataJSON(results []graph.OutputFile, allReachableFi sb.WriteString(",\n ") } paths[path] = true - sb.WriteString(fmt.Sprintf("%s: ", js_printer.QuoteForJSON(path, asciiOnly))) + sb.WriteString(fmt.Sprintf("%s: ", helpers.QuoteForJSON(path, asciiOnly))) sb.WriteString(result.JSONMetadataChunk) } } diff --git a/vendor/github.com/evanw/esbuild/internal/bundler/debug.go b/vendor/github.com/evanw/esbuild/internal/bundler/debug.go index 731a34fc4..094f0b97b 100644 --- a/vendor/github.com/evanw/esbuild/internal/bundler/debug.go +++ b/vendor/github.com/evanw/esbuild/internal/bundler/debug.go @@ -6,8 +6,8 @@ import ( "github.com/evanw/esbuild/internal/ast" "github.com/evanw/esbuild/internal/graph" + "github.com/evanw/esbuild/internal/helpers" "github.com/evanw/esbuild/internal/js_ast" - "github.com/evanw/esbuild/internal/js_printer" ) // Set this to true and then load the resulting metafile in "graph-debugger.html" @@ -29,7 +29,7 @@ func (c *linkerContext) generateExtraDataForFileJS(sourceIndex uint32) string { quoteSym := func(ref js_ast.Ref) string { name := fmt.Sprintf("%d:%d [%s]", ref.SourceIndex, ref.InnerIndex, c.graph.Symbols.Get(ref).OriginalName) - return string(js_printer.QuoteForJSON(name, c.options.ASCIIOnly)) + return string(helpers.QuoteForJSON(name, c.options.ASCIIOnly)) } sb.WriteString(`,"parts":[`) @@ -74,7 +74,7 @@ func (c *linkerContext) generateExtraDataForFileJS(sourceIndex uint32) string { sb.WriteByte(',') } path := c.graph.Files[record.SourceIndex.GetIndex()].InputFile.Source.PrettyPath - sb.WriteString(fmt.Sprintf(`{"source":%s}`, js_printer.QuoteForJSON(path, c.options.ASCIIOnly))) + sb.WriteString(fmt.Sprintf(`{"source":%s}`, helpers.QuoteForJSON(path, c.options.ASCIIOnly))) } sb.WriteByte(']') @@ -114,7 +114,7 @@ func (c *linkerContext) generateExtraDataForFileJS(sourceIndex uint32) string { sb.WriteByte(',') } sb.WriteString(fmt.Sprintf(`{"source":%s,"partIndex":%d}`, - js_printer.QuoteForJSON(c.graph.Files[dep.SourceIndex].InputFile.Source.PrettyPath, c.options.ASCIIOnly), + helpers.QuoteForJSON(c.graph.Files[dep.SourceIndex].InputFile.Source.PrettyPath, c.options.ASCIIOnly), dep.PartIndex, )) } @@ -122,7 +122,7 @@ func (c *linkerContext) generateExtraDataForFileJS(sourceIndex uint32) string { // code sb.WriteString(`,"code":`) - sb.Write(js_printer.QuoteForJSON(strings.TrimRight(code, "\n"), c.options.ASCIIOnly)) + sb.Write(helpers.QuoteForJSON(strings.TrimRight(code, "\n"), c.options.ASCIIOnly)) sb.WriteByte('}') } diff --git a/vendor/github.com/evanw/esbuild/internal/bundler/linker.go b/vendor/github.com/evanw/esbuild/internal/bundler/linker.go index ec6b691fa..96f97effa 100644 --- a/vendor/github.com/evanw/esbuild/internal/bundler/linker.go +++ b/vendor/github.com/evanw/esbuild/internal/bundler/linker.go @@ -50,6 +50,9 @@ type linkerContext struct { uniqueKeyPrefix string uniqueKeyPrefixBytes []byte // This is just "uniqueKeyPrefix" in byte form + // Property mangling results go here + mangledProps map[js_ast.Ref]string + // We may need to refer to the CommonJS "module" symbol for exports unboundModuleRef js_ast.Ref @@ -330,6 +333,9 @@ func (c *linkerContext) mangleProps(mangleCache map[string]interface{}) { c.timer.Begin("Mangle props") defer c.timer.End("Mangle props") + mangledProps := make(map[js_ast.Ref]string) + c.mangledProps = mangledProps + // Reserve all JS keywords reservedProps := make(map[string]bool) for keyword := range js_lexer.Keywords { @@ -347,7 +353,7 @@ func (c *linkerContext) mangleProps(mangleCache map[string]interface{}) { // Merge all mangled property symbols together freq := js_ast.CharFreq{} - mangledProps := make(map[string]js_ast.Ref) + mergedProps := make(map[string]js_ast.Ref) for _, sourceIndex := range c.graph.ReachableFiles { // Don't mangle anything in the runtime code if sourceIndex == runtime.SourceIndex { @@ -363,10 +369,10 @@ func (c *linkerContext) mangleProps(mangleCache map[string]interface{}) { // Merge each mangled property with other ones of the same name for name, ref := range repr.AST.MangledProps { - if existing, ok := mangledProps[name]; ok { + if existing, ok := mergedProps[name]; ok { js_ast.MergeSymbols(c.graph.Symbols, ref, existing) } else { - mangledProps[name] = ref + mergedProps[name] = ref } } @@ -378,9 +384,9 @@ func (c *linkerContext) mangleProps(mangleCache map[string]interface{}) { } // Sort by use count (note: does not currently account for live vs. dead code) - sorted := make(renamer.StableSymbolCountArray, 0, len(mangledProps)) + sorted := make(renamer.StableSymbolCountArray, 0, len(mergedProps)) stableSourceIndices := c.graph.StableSourceIndices - for _, ref := range mangledProps { + for _, ref := range mergedProps { sorted = append(sorted, renamer.StableSymbolCount{ StableSourceIndex: stableSourceIndices[ref.SourceIndex], Ref: ref, @@ -398,7 +404,7 @@ func (c *linkerContext) mangleProps(mangleCache map[string]interface{}) { // Don't change existing mappings if existing, ok := mangleCache[symbol.OriginalName]; ok { if existing != false { - symbol.OriginalName = existing.(string) + mangledProps[symbolCount.Ref] = existing.(string) } continue } @@ -417,7 +423,7 @@ func (c *linkerContext) mangleProps(mangleCache map[string]interface{}) { if mangleCache != nil { mangleCache[symbol.OriginalName] = name } - symbol.OriginalName = name + mangledProps[symbolCount.Ref] = name } } @@ -2968,11 +2974,11 @@ func sanitizeFilePathForVirtualModulePath(path string) string { // order that JavaScript modules were evaluated in before the top-level await // feature was introduced. // -// A -// / \ -// B C -// \ / -// D +// A +// / \ +// B C +// \ / +// D // // If A imports B and then C, B imports D, and C imports D, then the JavaScript // traversal order is D B C A. @@ -2983,10 +2989,10 @@ func sanitizeFilePathForVirtualModulePath(path string) string { // In this case we just pick an arbitrary but consistent order. func (c *linkerContext) findImportedCSSFilesInJSOrder(entryPoint uint32) (order []uint32) { visited := make(map[uint32]bool) - var visit func(uint32, ast.Index32) + var visit func(uint32) // Include this file and all files it imports - visit = func(sourceIndex uint32, importerIndex ast.Index32) { + visit = func(sourceIndex uint32) { if visited[sourceIndex] { return } @@ -3013,7 +3019,7 @@ func (c *linkerContext) findImportedCSSFilesInJSOrder(entryPoint uint32) (order // this is the only way to do it. for _, importRecordIndex := range part.ImportRecordIndices { if record := &repr.AST.ImportRecords[importRecordIndex]; record.SourceIndex.IsValid() { - visit(record.SourceIndex.GetIndex(), ast.MakeIndex32(sourceIndex)) + visit(record.SourceIndex.GetIndex()) } } } @@ -3025,7 +3031,7 @@ func (c *linkerContext) findImportedCSSFilesInJSOrder(entryPoint uint32) (order } // Include all files reachable from the entry point - visit(entryPoint, ast.Index32{}) + visit(entryPoint) return } @@ -3036,11 +3042,11 @@ func (c *linkerContext) findImportedCSSFilesInJSOrder(entryPoint uint32) (order // CSS file multiple times is equivalent to evaluating it once at the last // location. So we drop all but the last evaluation in the order. // -// A -// / \ -// B C -// \ / -// D +// A +// / \ +// B C +// \ / +// D // // If A imports B and then C, B imports D, and C imports D, then the CSS // traversal order is B D C A. @@ -3052,10 +3058,10 @@ func (c *linkerContext) findImportedFilesInCSSOrder(entryPoints []uint32) (exter visited := make(map[uint32]bool) externals := make(map[logger.Path]externalImportsCSS) - var visit func(uint32, ast.Index32) + var visit func(uint32) // Include this file and all files it imports - visit = func(sourceIndex uint32, importerIndex ast.Index32) { + visit = func(sourceIndex uint32) { if !visited[sourceIndex] { visited[sourceIndex] = true repr := c.graph.Files[sourceIndex].InputFile.Repr.(*graph.CSSRepr) @@ -3070,7 +3076,7 @@ func (c *linkerContext) findImportedFilesInCSSOrder(entryPoints []uint32) (exter if atImport, ok := topLevelRules[i].Data.(*css_ast.RAtImport); ok { if record := &repr.AST.ImportRecords[atImport.ImportRecordIndex]; record.SourceIndex.IsValid() { // Follow internal dependencies - visit(record.SourceIndex.GetIndex(), ast.MakeIndex32(sourceIndex)) + visit(record.SourceIndex.GetIndex()) } else { // Record external dependencies external := externals[record.Path] @@ -3114,7 +3120,7 @@ func (c *linkerContext) findImportedFilesInCSSOrder(entryPoints []uint32) (exter // Include all files reachable from any entry point for i := len(entryPoints) - 1; i >= 0; i-- { - visit(entryPoints[i], ast.Index32{}) + visit(entryPoints[i]) } // Reverse the order afterward when traversing in CSS order @@ -4185,6 +4191,7 @@ func (c *linkerContext) generateCodeForFileInChunkJS( InputSourceMap: inputSourceMap, LineOffsetTables: lineOffsetTables, RequireOrImportMetaForSource: c.requireOrImportMetaForSource, + MangledProps: c.mangledProps, } tree := repr.AST tree.Directive = "" // This is handled elsewhere @@ -4500,6 +4507,7 @@ func (c *linkerContext) generateEntryPointTailJS( LegalComments: c.options.LegalComments, UnsupportedFeatures: c.options.UnsupportedJSFeatures, RequireOrImportMetaForSource: c.requireOrImportMetaForSource, + MangledProps: c.mangledProps, } result.PrintResult = js_printer.Print(tree, c.graph.Symbols, r, printOptions) return @@ -4874,7 +4882,7 @@ func (c *linkerContext) generateChunkJS(chunks []chunkInfo, chunkIndex int, chun // Add the top-level directive if present (but omit "use strict" in ES // modules because all ES modules are automatically in strict mode) if repr.AST.Directive != "" && (repr.AST.Directive != "use strict" || c.options.OutputFormat != config.FormatESModule) { - quoted := string(js_printer.QuoteForJSON(repr.AST.Directive, c.options.ASCIIOnly)) + ";" + newline + quoted := string(helpers.QuoteForJSON(repr.AST.Directive, c.options.ASCIIOnly)) + ";" + newline prevOffset.AdvanceString(quoted) j.AddString(quoted) newlineBeforeComment = true @@ -4925,8 +4933,8 @@ func (c *linkerContext) generateChunkJS(chunks []chunkInfo, chunkIndex int, chun jMeta.AddString(",") } jMeta.AddString(fmt.Sprintf("\n {\n \"path\": %s,\n \"kind\": %s\n }", - js_printer.QuoteForJSON(c.res.PrettyPath(logger.Path{Text: chunks[chunkImport.chunkIndex].uniqueKey, Namespace: "file"}), c.options.ASCIIOnly), - js_printer.QuoteForJSON(chunkImport.importKind.StringForMetafile(), c.options.ASCIIOnly))) + helpers.QuoteForJSON(c.res.PrettyPath(logger.Path{Text: chunks[chunkImport.chunkIndex].uniqueKey, Namespace: "file"}), c.options.ASCIIOnly), + helpers.QuoteForJSON(chunkImport.importKind.StringForMetafile(), c.options.ASCIIOnly))) } if !isFirstMeta { jMeta.AddString("\n ") @@ -4962,14 +4970,14 @@ func (c *linkerContext) generateChunkJS(chunks []chunkInfo, chunkIndex int, chun jMeta.AddString(",") } jMeta.AddString(fmt.Sprintf("\n %s", - js_printer.QuoteForJSON(alias, c.options.ASCIIOnly))) + helpers.QuoteForJSON(alias, c.options.ASCIIOnly))) } if !isFirstMeta { jMeta.AddString("\n ") } if chunk.isEntryPoint { entryPoint := c.graph.Files[chunk.sourceIndex].InputFile.Source.PrettyPath - jMeta.AddString(fmt.Sprintf("],\n \"entryPoint\": %s,\n \"inputs\": {", js_printer.QuoteForJSON(entryPoint, c.options.ASCIIOnly))) + jMeta.AddString(fmt.Sprintf("],\n \"entryPoint\": %s,\n \"inputs\": {", helpers.QuoteForJSON(entryPoint, c.options.ASCIIOnly))) } else { jMeta.AddString("],\n \"inputs\": {") } @@ -5115,7 +5123,7 @@ func (c *linkerContext) generateChunkJS(chunks []chunkInfo, chunkIndex int, chun path := c.graph.Files[sourceIndex].InputFile.Source.PrettyPath extra := c.generateExtraDataForFileJS(sourceIndex) jMeta.AddString(fmt.Sprintf("\n %s: {\n \"bytesInOutput\": %d\n %s}", - js_printer.QuoteForJSON(path, c.options.ASCIIOnly), metaByteCount[path], extra)) + helpers.QuoteForJSON(path, c.options.ASCIIOnly), metaByteCount[path], extra)) } if !isFirstMeta { jMeta.AddString("\n ") @@ -5150,7 +5158,7 @@ func (c *linkerContext) generateGlobalNamePrefix() string { } text = fmt.Sprintf("var %s%s", prefix, join) } else { - prefix = fmt.Sprintf("this[%s]", js_printer.QuoteForJSON(prefix, c.options.ASCIIOnly)) + prefix = fmt.Sprintf("this[%s]", helpers.QuoteForJSON(prefix, c.options.ASCIIOnly)) } for _, name := range globalName[1:] { var dotOrIndex string @@ -5160,7 +5168,7 @@ func (c *linkerContext) generateGlobalNamePrefix() string { } dotOrIndex = fmt.Sprintf(".%s", name) } else { - dotOrIndex = fmt.Sprintf("[%s]", js_printer.QuoteForJSON(name, c.options.ASCIIOnly)) + dotOrIndex = fmt.Sprintf("[%s]", helpers.QuoteForJSON(name, c.options.ASCIIOnly)) } prefix = fmt.Sprintf("(%s%s||=%s{})%s", prefix, space, space, dotOrIndex) } @@ -5173,7 +5181,7 @@ func (c *linkerContext) generateGlobalNamePrefix() string { } text = fmt.Sprintf("var %s%s=%s", prefix, space, space) } else { - prefix = fmt.Sprintf("this[%s]", js_printer.QuoteForJSON(prefix, c.options.ASCIIOnly)) + prefix = fmt.Sprintf("this[%s]", helpers.QuoteForJSON(prefix, c.options.ASCIIOnly)) text = fmt.Sprintf("%s%s=%s", prefix, space, space) } @@ -5185,7 +5193,7 @@ func (c *linkerContext) generateGlobalNamePrefix() string { } prefix = fmt.Sprintf("%s.%s", prefix, name) } else { - prefix = fmt.Sprintf("%s[%s]", prefix, js_printer.QuoteForJSON(name, c.options.ASCIIOnly)) + prefix = fmt.Sprintf("%s[%s]", prefix, helpers.QuoteForJSON(name, c.options.ASCIIOnly)) } text += fmt.Sprintf("%s%s||%s{}%s%s%s=%s", oldPrefix, space, space, join, prefix, space, space) } @@ -5351,8 +5359,8 @@ func (c *linkerContext) generateChunkCSS(chunks []chunkInfo, chunkIndex int, chu jMeta.AddString(",") } jMeta.AddString(fmt.Sprintf("\n {\n \"path\": %s,\n \"kind\": %s\n }", - js_printer.QuoteForJSON(c.res.PrettyPath(logger.Path{Text: chunks[chunkImport.chunkIndex].uniqueKey, Namespace: "file"}), c.options.ASCIIOnly), - js_printer.QuoteForJSON(chunkImport.importKind.StringForMetafile(), c.options.ASCIIOnly))) + helpers.QuoteForJSON(c.res.PrettyPath(logger.Path{Text: chunks[chunkImport.chunkIndex].uniqueKey, Namespace: "file"}), c.options.ASCIIOnly), + helpers.QuoteForJSON(chunkImport.importKind.StringForMetafile(), c.options.ASCIIOnly))) } if !isFirstMeta { jMeta.AddString("\n ") @@ -5365,7 +5373,7 @@ func (c *linkerContext) generateChunkCSS(chunks []chunkInfo, chunkIndex int, chu // and there is already an output file for the JavaScript entry point. if _, ok := file.InputFile.Repr.(*graph.CSSRepr); ok { jMeta.AddString(fmt.Sprintf("],\n \"entryPoint\": %s,\n \"inputs\": {", - js_printer.QuoteForJSON(file.InputFile.Source.PrettyPath, c.options.ASCIIOnly))) + helpers.QuoteForJSON(file.InputFile.Source.PrettyPath, c.options.ASCIIOnly))) } else { jMeta.AddString("],\n \"inputs\": {") } @@ -5428,7 +5436,7 @@ func (c *linkerContext) generateChunkCSS(chunks []chunkInfo, chunkIndex int, chu jMeta.AddString(",") } jMeta.AddString(fmt.Sprintf("\n %s: {\n \"bytesInOutput\": %d\n }", - js_printer.QuoteForJSON(c.graph.Files[compileResult.sourceIndex].InputFile.Source.PrettyPath, c.options.ASCIIOnly), + helpers.QuoteForJSON(c.graph.Files[compileResult.sourceIndex].InputFile.Source.PrettyPath, c.options.ASCIIOnly), len(compileResult.CSS))) } } @@ -5673,6 +5681,15 @@ func (c *linkerContext) generateIsolatedHash(chunk *chunkInfo, channel chan []by hashWriteLengthPrefixed(hash, []byte(part.Data)) } + // Also hash the public path. If provided, this is used whenever files + // reference each other such as cross-chunk imports, asset file references, + // and source map comments. We always include the hash in all chunks instead + // of trying to figure out which chunks will include the public path for + // simplicity and for robustness to code changes in the future. + if c.options.PublicPath != "" { + hashWriteLengthPrefixed(hash, []byte(c.options.PublicPath)) + } + // Include the generated output content in the hash. This excludes the // randomly-generated import paths (the unique keys) and only includes the // data in the spans between them. @@ -5906,13 +5923,13 @@ func (c *linkerContext) generateSourceMapForChunk( } } - j.AddBytes(js_printer.QuoteForJSON(item.prettyPath, c.options.ASCIIOnly)) + j.AddBytes(helpers.QuoteForJSON(item.prettyPath, c.options.ASCIIOnly)) } j.AddString("]") if c.options.SourceRoot != "" { j.AddString(",\n \"sourceRoot\": ") - j.AddBytes(js_printer.QuoteForJSON(c.options.SourceRoot, c.options.ASCIIOnly)) + j.AddBytes(helpers.QuoteForJSON(c.options.SourceRoot, c.options.ASCIIOnly)) } // Write the sourcesContent @@ -5933,6 +5950,7 @@ func (c *linkerContext) generateSourceMapForChunk( mappingsStart := j.Length() prevEndState := sourcemap.SourceMapState{} prevColumnOffset := 0 + totalQuotedNameLen := 0 for _, result := range results { chunk := result.sourceMapChunk offset := result.generatedOffset @@ -5954,6 +5972,7 @@ func (c *linkerContext) generateSourceMapForChunk( SourceIndex: sourcesIndex, GeneratedLine: offset.Lines, GeneratedColumn: offset.Columns, + OriginalName: totalQuotedNameLen, } if offset.Lines == 0 { startState.GeneratedColumn += prevColumnOffset @@ -5963,9 +5982,24 @@ func (c *linkerContext) generateSourceMapForChunk( sourcemap.AppendSourceMapChunk(&j, prevEndState, startState, chunk.Buffer) // Generate the relative offset to start from next time + prevOriginalName := prevEndState.OriginalName prevEndState = chunk.EndState prevEndState.SourceIndex += sourcesIndex + if chunk.Buffer.FirstNameOffset.IsValid() { + prevEndState.OriginalName += totalQuotedNameLen + } else { + // It's possible for a chunk to have mappings but for none of those + // mappings to have an associated name. The name is optional and is + // omitted when the mapping is for a non-name token or if the final + // and original names are the same. In that case we need to restore + // the previous original name end state since it wasn't modified after + // all. If we don't do this, then files after this will adjust their + // name offsets assuming that the previous generated mapping has this + // file's offset, which is wrong. + prevEndState.OriginalName = prevOriginalName + } prevColumnOffset = chunk.FinalGeneratedColumn + totalQuotedNameLen += len(chunk.QuotedNames) // If this was all one line, include the column offset from the start if prevEndState.GeneratedLine == 0 { @@ -5975,8 +6009,23 @@ func (c *linkerContext) generateSourceMapForChunk( } mappingsEnd := j.Length() + // Write the names + isFirstName := true + j.AddString("\",\n \"names\": [") + for _, result := range results { + for _, quotedName := range result.sourceMapChunk.QuotedNames { + if isFirstName { + isFirstName = false + } else { + j.AddString(", ") + } + j.AddBytes(quotedName) + } + } + j.AddString("]") + // Finish the source map - j.AddString("\",\n \"names\": []\n}\n") + j.AddString("\n}\n") bytes := j.Done() if !canHaveShifts { diff --git a/vendor/github.com/evanw/esbuild/internal/cache/cache.go b/vendor/github.com/evanw/esbuild/internal/cache/cache.go index 000af6be2..7eacea39a 100644 --- a/vendor/github.com/evanw/esbuild/internal/cache/cache.go +++ b/vendor/github.com/evanw/esbuild/internal/cache/cache.go @@ -11,26 +11,25 @@ import ( // able to reuse the results of parsing between builds and make subsequent // builds faster by avoiding redundant parsing work. This only works if: // -// * The AST information in the cache must be considered immutable. There is -// no way to enforce this in Go, but please be disciplined about this. The -// ASTs are shared in between builds. Any information that must be mutated -// in the AST during a build must be done on a shallow clone of the data if -// the mutation happens after parsing (i.e. a clone that clones everything -// that will be mutated and shares only the parts that won't be mutated). +// - The AST information in the cache must be considered immutable. There is +// no way to enforce this in Go, but please be disciplined about this. The +// ASTs are shared in between builds. Any information that must be mutated +// in the AST during a build must be done on a shallow clone of the data if +// the mutation happens after parsing (i.e. a clone that clones everything +// that will be mutated and shares only the parts that won't be mutated). // -// * The information in the cache must not depend at all on the contents of -// any file other than the file being cached. Invalidating an entry in the -// cache does not also invalidate any entries that depend on that file, so -// caching information that depends on other files can result in incorrect -// results due to reusing stale data. For example, do not "bake in" some -// value imported from another file. -// -// * Cached ASTs must only be reused if the parsing options are identical -// between builds. For example, it would be bad if the AST parser depended -// on options inherited from a nearby "package.json" file but those options -// were not part of the cache key. Then the cached AST could incorrectly be -// reused even if the contents of that "package.json" file have changed. +// - The information in the cache must not depend at all on the contents of +// any file other than the file being cached. Invalidating an entry in the +// cache does not also invalidate any entries that depend on that file, so +// caching information that depends on other files can result in incorrect +// results due to reusing stale data. For example, do not "bake in" some +// value imported from another file. // +// - Cached ASTs must only be reused if the parsing options are identical +// between builds. For example, it would be bad if the AST parser depended +// on options inherited from a nearby "package.json" file but those options +// were not part of the cache key. Then the cached AST could incorrectly be +// reused even if the contents of that "package.json" file have changed. type CacheSet struct { FSCache FSCache CSSCache CSSCache diff --git a/vendor/github.com/evanw/esbuild/internal/config/config.go b/vendor/github.com/evanw/esbuild/internal/config/config.go index 28d7fe5ac..49e29653d 100644 --- a/vendor/github.com/evanw/esbuild/internal/config/config.go +++ b/vendor/github.com/evanw/esbuild/internal/config/config.go @@ -13,10 +13,39 @@ import ( ) type JSXOptions struct { - Factory DefineExpr - Fragment DefineExpr - Parse bool - Preserve bool + Factory DefineExpr + Fragment DefineExpr + Parse bool + Preserve bool + AutomaticRuntime bool + ImportSource string + Development bool +} + +type TSJSX uint8 + +const ( + TSJSXNone TSJSX = iota + TSJSXPreserve + TSJSXReact + TSJSXReactJSX + TSJSXReactJSXDev +) + +func (jsxOptions *JSXOptions) SetOptionsFromTSJSX(tsx TSJSX) { + switch tsx { + case TSJSXPreserve: + jsxOptions.Preserve = true + case TSJSXReact: + jsxOptions.AutomaticRuntime = false + jsxOptions.Development = false + case TSJSXReactJSX: + jsxOptions.AutomaticRuntime = true + // Don't set Development = false implicitly + case TSJSXReactJSXDev: + jsxOptions.AutomaticRuntime = true + jsxOptions.Development = true + } } type TSOptions struct { @@ -276,6 +305,7 @@ type Options struct { WriteToStdout bool OmitRuntimeForTests bool + OmitJSXRuntimeForTests bool UnusedImportFlagsTS UnusedImportFlagsTS UseDefineForClassFields MaybeBool ASCIIOnly bool @@ -309,32 +339,31 @@ type UnusedImportFlagsTS uint8 // With !UnusedImportKeepStmt && !UnusedImportKeepValues: // -// "import 'foo'" => "import 'foo'" -// "import * as unused from 'foo'" => "" -// "import { unused } from 'foo'" => "" -// "import { type unused } from 'foo'" => "" +// "import 'foo'" => "import 'foo'" +// "import * as unused from 'foo'" => "" +// "import { unused } from 'foo'" => "" +// "import { type unused } from 'foo'" => "" // // With UnusedImportKeepStmt && !UnusedImportKeepValues: // -// "import 'foo'" => "import 'foo'" -// "import * as unused from 'foo'" => "import 'foo'" -// "import { unused } from 'foo'" => "import 'foo'" -// "import { type unused } from 'foo'" => "import 'foo'" +// "import 'foo'" => "import 'foo'" +// "import * as unused from 'foo'" => "import 'foo'" +// "import { unused } from 'foo'" => "import 'foo'" +// "import { type unused } from 'foo'" => "import 'foo'" // // With !UnusedImportKeepStmt && UnusedImportKeepValues: // -// "import 'foo'" => "import 'foo'" -// "import * as unused from 'foo'" => "import * as unused from 'foo'" -// "import { unused } from 'foo'" => "import { unused } from 'foo'" -// "import { type unused } from 'foo'" => "" +// "import 'foo'" => "import 'foo'" +// "import * as unused from 'foo'" => "import * as unused from 'foo'" +// "import { unused } from 'foo'" => "import { unused } from 'foo'" +// "import { type unused } from 'foo'" => "" // // With UnusedImportKeepStmt && UnusedImportKeepValues: // -// "import 'foo'" => "import 'foo'" -// "import * as unused from 'foo'" => "import * as unused from 'foo'" -// "import { unused } from 'foo'" => "import { unused } from 'foo'" -// "import { type unused } from 'foo'" => "import {} from 'foo'" -// +// "import 'foo'" => "import 'foo'" +// "import * as unused from 'foo'" => "import * as unused from 'foo'" +// "import { unused } from 'foo'" => "import { unused } from 'foo'" +// "import { type unused } from 'foo'" => "import {} from 'foo'" const ( UnusedImportKeepStmt UnusedImportFlagsTS = 1 << iota // "importsNotUsedAsValues" != "remove" UnusedImportKeepValues // "preserveValueImports" == true diff --git a/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls_box.go b/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls_box.go index 52587fdff..75f7afa74 100644 --- a/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls_box.go +++ b/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls_box.go @@ -40,15 +40,14 @@ const ( // We want to avoid a situation where the browser treats some of the original // rules as valid and others as invalid. // -// Safe: -// top: 1px; left: 0; bottom: 1px; right: 0; -// top: 1Q; left: 2Q; bottom: 3Q; right: 4Q; -// -// Unsafe: -// top: 1vh; left: 2vw; bottom: 3vh; right: 4vw; -// top: 1Q; left: 2Q; bottom: 3Q; right: 0; -// inset: 1Q 0 0 0; top: 0; +// Safe: +// top: 1px; left: 0; bottom: 1px; right: 0; +// top: 1Q; left: 2Q; bottom: 3Q; right: 4Q; // +// Unsafe: +// top: 1vh; left: 2vw; bottom: 3vh; right: 4vw; +// top: 1Q; left: 2Q; bottom: 3Q; right: 0; +// inset: 1Q 0 0 0; top: 0; type unitSafetyTracker struct { unit string status unitSafetyStatus diff --git a/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go b/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go index 6a560770d..40016efa4 100644 --- a/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go +++ b/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go @@ -521,17 +521,17 @@ var nonDeprecatedElementsSupportedByIE7 = map[string]bool{ // if any of the selectors are unsafe, since then browsers which don't support // that particular feature would ignore the entire merged qualified rule: // -// Input: -// a { color: red } -// b { color: red } -// input::-moz-placeholder { color: red } +// Input: +// a { color: red } +// b { color: red } +// input::-moz-placeholder { color: red } // -// Valid output: -// a, b { color: red } -// input::-moz-placeholder { color: red } +// Valid output: +// a, b { color: red } +// input::-moz-placeholder { color: red } // -// Invalid output: -// a, b, input::-moz-placeholder { color: red } +// Invalid output: +// a, b, input::-moz-placeholder { color: red } // // This considers IE 7 and above to be a browser that a user could possibly use. // Versions of IE less than 6 are not considered. diff --git a/vendor/github.com/evanw/esbuild/internal/css_printer/css_printer.go b/vendor/github.com/evanw/esbuild/internal/css_printer/css_printer.go index 79530a688..6479200dd 100644 --- a/vendor/github.com/evanw/esbuild/internal/css_printer/css_printer.go +++ b/vendor/github.com/evanw/esbuild/internal/css_printer/css_printer.go @@ -48,7 +48,7 @@ func Print(tree css_ast.AST, options Options) PrintResult { p := printer{ options: options, importRecords: tree.ImportRecords, - builder: sourcemap.MakeChunkBuilder(options.InputSourceMap, options.LineOffsetTables), + builder: sourcemap.MakeChunkBuilder(options.InputSourceMap, options.LineOffsetTables, options.ASCIIOnly), } for _, rule := range tree.Rules { p.printRule(rule, 0, false) @@ -78,7 +78,7 @@ func (p *printer) printRule(rule css_ast.Rule, indent int32, omitTrailingSemicol } if p.options.AddSourceMappings { - p.builder.AddSourceMapping(rule.Loc, p.css) + p.builder.AddSourceMapping(rule.Loc, "", p.css) } if !p.options.MinifyWhitespace { diff --git a/vendor/github.com/evanw/esbuild/internal/fs/filepath.go b/vendor/github.com/evanw/esbuild/internal/fs/filepath.go index ae65991b4..edab22c22 100644 --- a/vendor/github.com/evanw/esbuild/internal/fs/filepath.go +++ b/vendor/github.com/evanw/esbuild/internal/fs/filepath.go @@ -343,13 +343,13 @@ func (fp goFilepath) fromSlash(path string) string { // by purely lexical processing. It applies the following rules // iteratively until no further processing can be done: // -// 1. Replace multiple Separator elements with a single one. -// 2. Eliminate each . path name element (the current directory). -// 3. Eliminate each inner .. path name element (the parent directory) -// along with the non-.. element that precedes it. -// 4. Eliminate .. elements that begin a rooted path: -// that is, replace "/.." by "/" at the beginning of a path, -// assuming Separator is '/'. +// 1. Replace multiple Separator elements with a single one. +// 2. Eliminate each . path name element (the current directory). +// 3. Eliminate each inner .. path name element (the parent directory) +// along with the non-.. element that precedes it. +// 4. Eliminate .. elements that begin a rooted path: +// that is, replace "/.." by "/" at the beginning of a path, +// assuming Separator is '/'. // // The returned path ends in a slash only if it represents a root directory, // such as "/" on Unix or `C:\` on Windows. @@ -359,8 +359,8 @@ func (fp goFilepath) fromSlash(path string) string { // If the result of this process is an empty string, Clean // returns the string ".". // -// See also Rob Pike, ``Lexical File Names in Plan 9 or -// Getting Dot-Dot Right,'' +// See also Rob Pike, "Lexical File Names in Plan 9 or +// Getting Dot-Dot Right," // https://9p.io/sys/doc/lexnames.html func (fp goFilepath) clean(path string) string { originalPath := path diff --git a/vendor/github.com/evanw/esbuild/internal/fs/fs_real.go b/vendor/github.com/evanw/esbuild/internal/fs/fs_real.go index 366921738..aea425171 100644 --- a/vendor/github.com/evanw/esbuild/internal/fs/fs_real.go +++ b/vendor/github.com/evanw/esbuild/internal/fs/fs_real.go @@ -485,13 +485,13 @@ func (fs *realFS) WatchData() WatchData { } } else { // Check individual entries - isPresent := make(map[string]bool, len(names)) + lookup := make(map[string]string, len(names)) for _, name := range names { - isPresent[strings.ToLower(name)] = true + lookup[strings.ToLower(name)] = name } for name, wasPresent := range data.accessedEntries.wasPresent { - if wasPresent != isPresent[name] { - return fs.Join(path, name) + if originalName, isPresent := lookup[name]; wasPresent != isPresent { + return fs.Join(path, originalName) } } } diff --git a/vendor/github.com/evanw/esbuild/internal/helpers/mime.go b/vendor/github.com/evanw/esbuild/internal/helpers/mime.go index 9897b373d..4273bd312 100644 --- a/vendor/github.com/evanw/esbuild/internal/helpers/mime.go +++ b/vendor/github.com/evanw/esbuild/internal/helpers/mime.go @@ -13,6 +13,7 @@ var builtinTypesLower = map[string]string{ ".xml": "text/xml; charset=utf-8", // Images + ".avif": "image/avif", ".gif": "image/gif", ".jpeg": "image/jpeg", ".jpg": "image/jpeg", diff --git a/vendor/github.com/evanw/esbuild/internal/helpers/quote.go b/vendor/github.com/evanw/esbuild/internal/helpers/quote.go new file mode 100644 index 000000000..704982acf --- /dev/null +++ b/vendor/github.com/evanw/esbuild/internal/helpers/quote.go @@ -0,0 +1,114 @@ +package helpers + +import "unicode/utf8" + +const hexChars = "0123456789ABCDEF" +const firstASCII = 0x20 +const lastASCII = 0x7E +const firstHighSurrogate = 0xD800 +const firstLowSurrogate = 0xDC00 +const lastLowSurrogate = 0xDFFF + +func canPrintWithoutEscape(c rune, asciiOnly bool) bool { + if c <= lastASCII { + return c >= firstASCII && c != '\\' && c != '"' + } else { + return !asciiOnly && c != '\uFEFF' && (c < firstHighSurrogate || c > lastLowSurrogate) + } +} + +func QuoteForJSON(text string, asciiOnly bool) []byte { + // Estimate the required length + lenEstimate := 2 + for _, c := range text { + if canPrintWithoutEscape(c, asciiOnly) { + lenEstimate += utf8.RuneLen(c) + } else { + switch c { + case '\b', '\f', '\n', '\r', '\t', '\\', '"': + lenEstimate += 2 + default: + if c <= 0xFFFF { + lenEstimate += 6 + } else { + lenEstimate += 12 + } + } + } + } + + // Preallocate the array + bytes := make([]byte, 0, lenEstimate) + i := 0 + n := len(text) + bytes = append(bytes, '"') + + for i < n { + c, width := DecodeWTF8Rune(text[i:]) + + // Fast path: a run of characters that don't need escaping + if canPrintWithoutEscape(c, asciiOnly) { + start := i + i += width + for i < n { + c, width = DecodeWTF8Rune(text[i:]) + if !canPrintWithoutEscape(c, asciiOnly) { + break + } + i += width + } + bytes = append(bytes, text[start:i]...) + continue + } + + switch c { + case '\b': + bytes = append(bytes, "\\b"...) + i++ + + case '\f': + bytes = append(bytes, "\\f"...) + i++ + + case '\n': + bytes = append(bytes, "\\n"...) + i++ + + case '\r': + bytes = append(bytes, "\\r"...) + i++ + + case '\t': + bytes = append(bytes, "\\t"...) + i++ + + case '\\': + bytes = append(bytes, "\\\\"...) + i++ + + case '"': + bytes = append(bytes, "\\\""...) + i++ + + default: + i += width + if c <= 0xFFFF { + bytes = append( + bytes, + '\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15], + ) + } else { + c -= 0x10000 + lo := firstHighSurrogate + ((c >> 10) & 0x3FF) + hi := firstLowSurrogate + (c & 0x3FF) + bytes = append( + bytes, + '\\', 'u', hexChars[lo>>12], hexChars[(lo>>8)&15], hexChars[(lo>>4)&15], hexChars[lo&15], + '\\', 'u', hexChars[hi>>12], hexChars[(hi>>8)&15], hexChars[(hi>>4)&15], hexChars[hi&15], + ) + } + } + } + + return append(bytes, '"') +} diff --git a/vendor/github.com/evanw/esbuild/internal/js_ast/js_ast.go b/vendor/github.com/evanw/esbuild/internal/js_ast/js_ast.go index b5e13840b..b9ede5c66 100644 --- a/vendor/github.com/evanw/esbuild/internal/js_ast/js_ast.go +++ b/vendor/github.com/evanw/esbuild/internal/js_ast/js_ast.go @@ -382,14 +382,16 @@ type BMissing struct{} type BIdentifier struct{ Ref Ref } type BArray struct { - Items []ArrayBinding - HasSpread bool - IsSingleLine bool + Items []ArrayBinding + CloseBracketLoc logger.Loc + HasSpread bool + IsSingleLine bool } type BObject struct { - Properties []PropertyBinding - IsSingleLine bool + Properties []PropertyBinding + CloseBraceLoc logger.Loc + IsSingleLine bool } type Expr struct { @@ -493,6 +495,7 @@ type ENew struct { Target Expr Args []Expr CloseParenLoc logger.Loc + IsMultiLine bool // True if there is a comment containing "@__PURE__" or "#__PURE__" preceding // this call expression. See the comment inside ECall for more details. @@ -519,6 +522,7 @@ type ECall struct { CloseParenLoc logger.Loc OptionalChain OptionalChain IsDirectEval bool + IsMultiLine bool // True if there is a comment containing "@__PURE__" or "#__PURE__" preceding // this call expression. This is an annotation used for tree shaking, and @@ -978,11 +982,11 @@ type SSwitch struct { // This object represents all of these types of import statements: // -// import 'path' -// import {item1, item2} from 'path' -// import * as ns from 'path' -// import defaultItem, {item1, item2} from 'path' -// import defaultItem, * as ns from 'path' +// import 'path' +// import {item1, item2} from 'path' +// import * as ns from 'path' +// import defaultItem, {item1, item2} from 'path' +// import defaultItem, * as ns from 'path' // // Many parts are optional and can be combined in different ways. The only // restriction is that you cannot have both a clause and a star namespace. @@ -1521,6 +1525,7 @@ const ( ImplicitStrictModeClass ImplicitStrictModeESM ImplicitStrictModeTSAlwaysStrict + ImplicitStrictModeJSXAutomaticRuntime ) func (s *Scope) RecursiveSetStrictMode(kind StrictModeKind) { @@ -1537,27 +1542,27 @@ func (s *Scope) RecursiveSetStrictMode(kind StrictModeKind) { // block are merged into a single namespace while the non-exported code is // still scoped to just within that block: // -// let x = 1; -// namespace Foo { -// let x = 2; -// export let y = 3; -// } -// namespace Foo { -// console.log(x); // 1 -// console.log(y); // 3 -// } +// let x = 1; +// namespace Foo { +// let x = 2; +// export let y = 3; +// } +// namespace Foo { +// console.log(x); // 1 +// console.log(y); // 3 +// } // // Doing this also works inside an enum: // -// enum Foo { -// A = 3, -// B = A + 1, -// } -// enum Foo { -// C = A + 2, -// } -// console.log(Foo.B) // 4 -// console.log(Foo.C) // 5 +// enum Foo { +// A = 3, +// B = A + 1, +// } +// enum Foo { +// C = A + 2, +// } +// console.log(Foo.B) // 4 +// console.log(Foo.C) // 5 // // This is a form of identifier lookup that works differently than the // hierarchical scope-based identifier lookup in JavaScript. Lookup now needs diff --git a/vendor/github.com/evanw/esbuild/internal/js_lexer/js_lexer.go b/vendor/github.com/evanw/esbuild/internal/js_lexer/js_lexer.go index f86fe0fd9..b25189b3b 100644 --- a/vendor/github.com/evanw/esbuild/internal/js_lexer/js_lexer.go +++ b/vendor/github.com/evanw/esbuild/internal/js_lexer/js_lexer.go @@ -245,14 +245,17 @@ type MaybeSubstring struct { } type Lexer struct { - CommentsToPreserveBefore []js_ast.Comment - AllOriginalComments []js_ast.Comment - Identifier MaybeSubstring - log logger.Log - source logger.Source - JSXFactoryPragmaComment logger.Span - JSXFragmentPragmaComment logger.Span - SourceMappingURL logger.Span + CommentsToPreserveBefore []js_ast.Comment + AllOriginalComments []js_ast.Comment + Identifier MaybeSubstring + log logger.Log + source logger.Source + JSXFactoryPragmaComment logger.Span + JSXFragmentPragmaComment logger.Span + JSXRuntimePragmaComment logger.Span + JSXImportSourcePragmaComment logger.Span + SourceMappingURL logger.Span + BadArrowInTSXSuggestion string // Escape sequences in string literals are decoded lazily because they are // not interpreted inside tagged templates, and tagged templates can contain @@ -270,6 +273,8 @@ type Lexer struct { start int end int ApproximateNewlineCount int + CouldBeBadArrowInTSX int + BadArrowInTSXRange logger.Range LegacyOctalLoc logger.Loc AwaitKeywordLoc logger.Loc FnOrArrowStartLoc logger.Loc @@ -945,23 +950,36 @@ func (lexer *Lexer) NextJSXElementChild() { } else { replacement = "{'>'}" } - msg := logger.Msg{Kind: logger.Error, Data: lexer.tracker.MsgData(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}, Len: 1}, - fmt.Sprintf("The character \"%c\" is not valid inside a JSX element", lexer.codePoint)), - Notes: []logger.MsgData{{Text: fmt.Sprintf("Did you mean to escape it as %q instead?", replacement)}}} - msg.Data.Location.Suggestion = replacement - if !lexer.ts.Parse { - // TypeScript treats this as an error but Babel doesn't treat this - // as an error yet, so allow this in JS for now. Babel version 8 - // was supposed to be released in 2021 but was never released. If - // it's released in the future, this can be changed to an error too. - // - // More context: - // * TypeScript change: https://github.com/microsoft/TypeScript/issues/36341 - // * Babel 8 change: https://github.com/babel/babel/issues/11042 - // * Babel 8 release: https://github.com/babel/babel/issues/10746 - // - msg.Kind = logger.Warning + msg := logger.Msg{ + Kind: logger.Error, + Data: lexer.tracker.MsgData(logger.Range{Loc: logger.Loc{Start: int32(lexer.end)}, Len: 1}, + fmt.Sprintf("The character \"%c\" is not valid inside a JSX element", lexer.codePoint)), } + + // Attempt to provide a better error message if this looks like an arrow function + if lexer.CouldBeBadArrowInTSX > 0 && lexer.codePoint == '>' && lexer.source.Contents[lexer.end-1] == '=' { + msg.Notes = []logger.MsgData{lexer.tracker.MsgData(lexer.BadArrowInTSXRange, + "TypeScript's TSX syntax interprets arrow functions with a single generic type parameter as an opening JSX element. "+ + "If you want it to be interpreted as an arrow function instead, you need to add a trailing comma after the type parameter to disambiguate:")} + msg.Notes[0].Location.Suggestion = lexer.BadArrowInTSXSuggestion + } else { + msg.Notes = []logger.MsgData{{Text: fmt.Sprintf("Did you mean to escape it as %q instead?", replacement)}} + msg.Data.Location.Suggestion = replacement + if !lexer.ts.Parse { + // TypeScript treats this as an error but Babel doesn't treat this + // as an error yet, so allow this in JS for now. Babel version 8 + // was supposed to be released in 2021 but was never released. If + // it's released in the future, this can be changed to an error too. + // + // More context: + // * TypeScript change: https://github.com/microsoft/TypeScript/issues/36341 + // * Babel 8 change: https://github.com/babel/babel/issues/11042 + // * Babel 8 release: https://github.com/babel/babel/issues/10746 + // + msg.Kind = logger.Warning + } + } + lexer.log.AddMsg(msg) lexer.step() @@ -2770,6 +2788,14 @@ func (lexer *Lexer) scanCommentText() { if arg, ok := scanForPragmaArg(pragmaSkipSpaceFirst, lexer.start+i+1, "jsxFrag", rest); ok { lexer.JSXFragmentPragmaComment = arg } + } else if hasPrefixWithWordBoundary(rest, "jsxRuntime") { + if arg, ok := scanForPragmaArg(pragmaSkipSpaceFirst, lexer.start+i+1, "jsxRuntime", rest); ok { + lexer.JSXRuntimePragmaComment = arg + } + } else if hasPrefixWithWordBoundary(rest, "jsxImportSource") { + if arg, ok := scanForPragmaArg(pragmaSkipSpaceFirst, lexer.start+i+1, "jsxImportSource", rest); ok { + lexer.JSXImportSourcePragmaComment = arg + } } else if i == 2 && strings.HasPrefix(rest, " sourceMappingURL=") { if arg, ok := scanForPragmaArg(pragmaNoSpaceFirst, lexer.start+i+1, " sourceMappingURL=", rest); ok { lexer.SourceMappingURL = arg diff --git a/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser.go b/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser.go index 11e57bfe1..9edcdee57 100644 --- a/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser.go +++ b/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser.go @@ -24,10 +24,10 @@ import ( // // 1. Parse the source into an AST, create the scope tree, and declare symbols. // -// 2. Visit each node in the AST, bind identifiers to declared symbols, do -// constant folding, substitute compile-time variable definitions, and -// lower certain syntactic constructs as appropriate given the language -// target. +// 2. Visit each node in the AST, bind identifiers to declared symbols, do +// constant folding, substitute compile-time variable definitions, and +// lower certain syntactic constructs as appropriate given the language +// target. // // So many things have been put in so few passes because we want to minimize // the number of full-tree passes to improve performance. However, we need @@ -194,6 +194,11 @@ type parser struct { tempRefCount int topLevelTempRefCount int + // We need to scan over the source contents to recover the line and column offsets + jsxSourceLoc int + jsxSourceLine int + jsxSourceColumn int + exportsRef js_ast.Ref requireRef js_ast.Ref moduleRef js_ast.Ref @@ -204,6 +209,11 @@ type parser struct { superCtorRef js_ast.Ref jsxDevRef js_ast.Ref + // Imports from "react/jsx-runtime" and "react", respectively. + // (Or whatever was specified in the "importSource" option) + jsxRuntimeImports map[string]js_ast.Ref + jsxLegacyImports map[string]js_ast.Ref + // For lowering private methods weakMapRef js_ast.Ref weakSetRef js_ast.Ref @@ -216,6 +226,7 @@ type parser struct { latestArrowArgLoc logger.Loc forbidSuffixAfterAsLoc logger.Loc + firstJSXElementLoc logger.Loc fnOrArrowDataVisit fnOrArrowDataVisit @@ -396,6 +407,7 @@ type optionsThatSupportStructuralEquality struct { minifySyntax bool minifyIdentifiers bool omitRuntimeForTests bool + omitJSXRuntimeForTests bool ignoreDCEAnnotations bool treeShaking bool dropDebugger bool @@ -430,6 +442,7 @@ func OptionsFromConfig(options *config.Options) Options { minifySyntax: options.MinifySyntax, minifyIdentifiers: options.MinifyIdentifiers, omitRuntimeForTests: options.OmitRuntimeForTests, + omitJSXRuntimeForTests: options.OmitJSXRuntimeForTests, ignoreDCEAnnotations: options.IgnoreDCEAnnotations, treeShaking: options.TreeShaking, dropDebugger: options.DropDebugger, @@ -1515,6 +1528,55 @@ func (p *parser) callRuntime(loc logger.Loc, name string, args []js_ast.Expr) js }} } +type JSXImport uint8 + +const ( + JSXImportJSX JSXImport = iota + JSXImportJSXS + JSXImportFragment + JSXImportCreateElement +) + +func (p *parser) importJSXSymbol(loc logger.Loc, jsx JSXImport) js_ast.Expr { + var symbols map[string]js_ast.Ref + var name string + + switch jsx { + case JSXImportJSX: + symbols = p.jsxRuntimeImports + if p.options.jsx.Development { + name = "jsxDEV" + } else { + name = "jsx" + } + case JSXImportJSXS: + symbols = p.jsxRuntimeImports + if p.options.jsx.Development { + name = "jsxDEV" + } else { + name = "jsxs" + } + case JSXImportFragment: + symbols = p.jsxRuntimeImports + name = "Fragment" + case JSXImportCreateElement: + symbols = p.jsxLegacyImports + name = "createElement" + } + + ref, ok := symbols[name] + if !ok { + ref = p.newSymbol(js_ast.SymbolOther, name) + p.moduleScope.Generated = append(p.moduleScope.Generated, ref) + p.isImportItem[ref] = true + symbols[name] = ref + } + p.recordUsage(ref) + return p.handleIdentifier(loc, &js_ast.EIdentifier{Ref: ref}, identifierOpts{ + wasOriginallyIdentifier: true, + }) +} + func (p *parser) valueToSubstituteForRequire(loc logger.Loc) js_ast.Expr { if p.source.Index != runtime.SourceIndex && config.ShouldCallRuntimeRequire(p.options.mode, p.options.outputFormat) { @@ -1645,20 +1707,19 @@ func (p *parser) logDeferredArrowArgErrors(errors *deferredErrors) { // // Specifically, for await: // -// // This is ok -// async function foo() { (x = await y) } +// // This is ok +// async function foo() { (x = await y) } // -// // This is an error -// async function foo() { (x = await y) => {} } +// // This is an error +// async function foo() { (x = await y) => {} } // // And for yield: // -// // This is ok -// function* foo() { (x = yield y) } -// -// // This is an error -// function* foo() { (x = yield y) => {} } +// // This is ok +// function* foo() { (x = yield y) } // +// // This is an error +// function* foo() { (x = yield y) => {} } type deferredArrowArgErrors struct { invalidExprAwait logger.Range invalidExprYield logger.Range @@ -2821,9 +2882,10 @@ func (p *parser) convertExprToBinding(expr js_ast.Expr, invalidLog invalidLog) ( items = append(items, js_ast.ArrayBinding{Binding: binding, DefaultValueOrNil: initializerOrNil}) } return js_ast.Binding{Loc: expr.Loc, Data: &js_ast.BArray{ - Items: items, - HasSpread: isSpread, - IsSingleLine: e.IsSingleLine, + Items: items, + HasSpread: isSpread, + IsSingleLine: e.IsSingleLine, + CloseBracketLoc: e.CloseBracketLoc, }}, invalidLog case *js_ast.EObject: @@ -2852,8 +2914,9 @@ func (p *parser) convertExprToBinding(expr js_ast.Expr, invalidLog invalidLog) ( }) } return js_ast.Binding{Loc: expr.Loc, Data: &js_ast.BObject{ - Properties: properties, - IsSingleLine: e.IsSingleLine, + Properties: properties, + IsSingleLine: e.IsSingleLine, + CloseBraceLoc: e.CloseBraceLoc, }}, invalidLog default: @@ -3208,12 +3271,18 @@ func (p *parser) parsePrefix(level js_ast.L, errors *deferredErrors, flags exprF target := p.parseExprWithFlags(js_ast.LMember, flags) args := []js_ast.Expr{} var closeParenLoc logger.Loc + var isMultiLine bool if p.lexer.Token == js_lexer.TOpenParen { - args, closeParenLoc = p.parseCallArgs() + args, closeParenLoc, isMultiLine = p.parseCallArgs() } - return js_ast.Expr{Loc: loc, Data: &js_ast.ENew{Target: target, Args: args, CloseParenLoc: closeParenLoc}} + return js_ast.Expr{Loc: loc, Data: &js_ast.ENew{ + Target: target, + Args: args, + CloseParenLoc: closeParenLoc, + IsMultiLine: isMultiLine, + }} case js_lexer.TOpenBracket: p.lexer.Next() @@ -3697,12 +3766,13 @@ func (p *parser) parseSuffix(left js_ast.Expr, level js_ast.L, errors *deferredE if level >= js_ast.LCall { return left } - args, closeParenLoc := p.parseCallArgs() + args, closeParenLoc, isMultiLine := p.parseCallArgs() left = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ECall{ Target: left, Args: args, CloseParenLoc: closeParenLoc, OptionalChain: optionalStart, + IsMultiLine: isMultiLine, }} case js_lexer.TLessThan, js_lexer.TLessThanLessThan: @@ -3718,12 +3788,13 @@ func (p *parser) parseSuffix(left js_ast.Expr, level js_ast.L, errors *deferredE if level >= js_ast.LCall { return left } - args, closeParenLoc := p.parseCallArgs() + args, closeParenLoc, isMultiLine := p.parseCallArgs() left = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ECall{ Target: left, Args: args, CloseParenLoc: closeParenLoc, OptionalChain: optionalStart, + IsMultiLine: isMultiLine, }} default: @@ -3819,12 +3890,13 @@ func (p *parser) parseSuffix(left js_ast.Expr, level js_ast.L, errors *deferredE if level >= js_ast.LCall { return left } - args, closeParenLoc := p.parseCallArgs() + args, closeParenLoc, isMultiLine := p.parseCallArgs() left = js_ast.Expr{Loc: left.Loc, Data: &js_ast.ECall{ Target: left, Args: args, CloseParenLoc: closeParenLoc, OptionalChain: oldOptionalChain, + IsMultiLine: isMultiLine, }} optionalChain = oldOptionalChain @@ -4329,7 +4401,7 @@ func (p *parser) parseExprOrLetStmt(opts parseStmtOpts) (js_ast.Expr, js_ast.Stm return p.parseSuffix(expr, js_ast.LLowest, nil, 0), js_ast.Stmt{}, nil } -func (p *parser) parseCallArgs() (args []js_ast.Expr, closeParenLoc logger.Loc) { +func (p *parser) parseCallArgs() (args []js_ast.Expr, closeParenLoc logger.Loc, isMultiLine bool) { // Allow "in" inside call arguments oldAllowIn := p.allowIn p.allowIn = true @@ -4337,6 +4409,9 @@ func (p *parser) parseCallArgs() (args []js_ast.Expr, closeParenLoc logger.Loc) p.lexer.Expect(js_lexer.TOpenParen) for p.lexer.Token != js_lexer.TCloseParen { + if p.lexer.HasNewlineBefore { + isMultiLine = true + } loc := p.lexer.Loc() isSpread := p.lexer.Token == js_lexer.TDotDotDot if isSpread { @@ -4351,9 +4426,15 @@ func (p *parser) parseCallArgs() (args []js_ast.Expr, closeParenLoc logger.Loc) if p.lexer.Token != js_lexer.TComma { break } + if p.lexer.HasNewlineBefore { + isMultiLine = true + } p.lexer.Next() } + if p.lexer.HasNewlineBefore { + isMultiLine = true + } closeParenLoc = p.lexer.Loc() p.lexer.Expect(js_lexer.TCloseParen) p.allowIn = oldAllowIn @@ -4435,6 +4516,11 @@ func (p *parser) parseJSXTag() (logger.Range, string, js_ast.Expr) { } func (p *parser) parseJSXElement(loc logger.Loc) js_ast.Expr { + // Keep track of the location of the first JSX element for error messages + if p.firstJSXElementLoc.Start == -1 { + p.firstJSXElementLoc = loc + } + // Parse the tag startRange, startText, startTagOrNil := p.parseJSXTag() @@ -4516,6 +4602,26 @@ func (p *parser) parseJSXElement(loc logger.Loc) js_ast.Expr { break parseAttributes } } + + // Check for and warn about duplicate attributes + if len(properties) > 1 && !p.suppressWarningsAboutWeirdCode { + keys := make(map[string]logger.Loc) + for _, property := range properties { + if property.Kind != js_ast.PropertySpread { + if str, ok := property.Key.Data.(*js_ast.EString); ok { + key := helpers.UTF16ToString(str.Value) + if prevLoc, ok := keys[key]; ok { + r := js_lexer.RangeOfIdentifier(p.source, property.Key.Loc) + p.log.AddIDWithNotes(logger.MsgID_JS_DuplicateObjectKey, logger.Warning, &p.tracker, r, + fmt.Sprintf("Duplicate %q attribute in JSX element", key), + []logger.MsgData{p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, prevLoc), + fmt.Sprintf("The original %q attribute is here:", key))}) + } + keys[key] = property.Key.Loc + } + } + } + } } // People sometimes try to use the output of "JSON.stringify()" as a JSX @@ -4577,6 +4683,24 @@ func (p *parser) parseJSXElement(loc logger.Loc) js_ast.Expr { }} } + // Attempt to provide a better error message for people incorrectly trying to + // use arrow functions in TSX (which doesn't work because they are JSX elements) + if p.options.ts.Parse && len(properties) == 0 && startText != "" && p.lexer.Token == js_lexer.TGreaterThan && + strings.HasPrefix(p.source.Contents[p.lexer.Loc().Start:], ">(") { + badArrowInTSXRange := p.lexer.BadArrowInTSXRange + badArrowInTSXSuggestion := p.lexer.BadArrowInTSXSuggestion + + p.lexer.CouldBeBadArrowInTSX++ + p.lexer.BadArrowInTSXRange = logger.Range{Loc: loc, Len: p.lexer.Range().End() - loc.Start} + p.lexer.BadArrowInTSXSuggestion = fmt.Sprintf("<%s,>", startText) + + defer func() { + p.lexer.CouldBeBadArrowInTSX-- + p.lexer.BadArrowInTSXRange = badArrowInTSXRange + p.lexer.BadArrowInTSXSuggestion = badArrowInTSXSuggestion + }() + } + // Use ExpectJSXElementChild() so we parse child strings p.lexer.ExpectJSXElementChild(js_lexer.TGreaterThan) @@ -5131,11 +5255,13 @@ func (p *parser) parseBinding() js_ast.Binding { if p.lexer.HasNewlineBefore { isSingleLine = false } + closeBracketLoc := p.lexer.Loc() p.lexer.Expect(js_lexer.TCloseBracket) return js_ast.Binding{Loc: loc, Data: &js_ast.BArray{ - Items: items, - HasSpread: hasSpread, - IsSingleLine: isSingleLine, + Items: items, + HasSpread: hasSpread, + IsSingleLine: isSingleLine, + CloseBracketLoc: closeBracketLoc, }} case js_lexer.TOpenBrace: @@ -5175,10 +5301,12 @@ func (p *parser) parseBinding() js_ast.Binding { if p.lexer.HasNewlineBefore { isSingleLine = false } + closeBraceLoc := p.lexer.Loc() p.lexer.Expect(js_lexer.TCloseBrace) return js_ast.Binding{Loc: loc, Data: &js_ast.BObject{ - Properties: properties, - IsSingleLine: isSingleLine, + Properties: properties, + IsSingleLine: isSingleLine, + CloseBraceLoc: closeBraceLoc, }} } @@ -7326,10 +7454,10 @@ func findIdentifiers(binding js_ast.Binding, identifiers []js_ast.Decl) []js_ast // can. Everything can be trimmed except for hoisted declarations ("var" and // "function"), which affect the parent scope. For example: // -// function foo() { -// if (false) { var x; } -// x = 1; -// } +// function foo() { +// if (false) { var x; } +// x = 1; +// } // // We can't trim the entire branch as dead or calling foo() will incorrectly // assign to a global variable instead. @@ -9977,22 +10105,21 @@ func isUnsightlyPrimitive(data js_ast.E) bool { // a constant declared later on, then we need to end the const local prefix. // We want to avoid situations like this: // -// const x = y; // This is supposed to throw due to TDZ -// const y = 1; +// const x = y; // This is supposed to throw due to TDZ +// const y = 1; // // or this: // -// const x = 1; -// const y = foo(); // This is supposed to throw due to TDZ -// const z = 2; -// const foo = () => z; +// const x = 1; +// const y = foo(); // This is supposed to throw due to TDZ +// const z = 2; +// const foo = () => z; // // But a situation like this is ok: // -// const x = 1; -// const y = [() => z]; -// const z = 2; -// +// const x = 1; +// const y = [() => z]; +// const z = 2; func isSafeForConstLocalPrefix(expr js_ast.Expr) bool { switch e := expr.Data.(type) { case *js_ast.EMissing, *js_ast.EString, *js_ast.ERegExp, *js_ast.EBigInt, *js_ast.EFunction, *js_ast.EArrow: @@ -10125,14 +10252,14 @@ const ( // // Example usage: // -// // "value" => "value + value" -// // "value()" => "(_a = value(), _a + _a)" -// valueFunc, wrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, value) -// return wrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{ -// Op: js_ast.BinOpAdd, -// Left: valueFunc(), -// Right: valueFunc(), -// }}) +// // "value" => "value + value" +// // "value()" => "(_a = value(), _a + _a)" +// valueFunc, wrapFunc := p.captureValueWithPossibleSideEffects(loc, 2, value) +// return wrapFunc(js_ast.Expr{Loc: loc, Data: &js_ast.EBinary{ +// Op: js_ast.BinOpAdd, +// Left: valueFunc(), +// Right: valueFunc(), +// }}) // // This returns a function for generating references instead of a raw reference // because AST nodes are supposed to be unique in memory, not aliases of other @@ -10730,20 +10857,25 @@ func (p *parser) instantiateDefineExpr(loc logger.Loc, expr config.DefineExpr, o } // Check both user-specified defines and known globals - if defines, ok := p.options.defines.DotDefines[parts[len(parts)-1]]; ok { - next: - for _, define := range defines { - if len(define.Parts) == len(parts) { - for i := range parts { - if parts[i] != define.Parts[i] { - continue next + if opts.matchAgainstDefines { + // Make sure define resolution is not recursive + opts.matchAgainstDefines = false + + if defines, ok := p.options.defines.DotDefines[parts[len(parts)-1]]; ok { + next: + for _, define := range defines { + if len(define.Parts) == len(parts) { + for i := range parts { + if parts[i] != define.Parts[i] { + continue next + } } - } - } - // Substitute user-specified defines - if define.Data.DefineExpr != nil { - return p.instantiateDefineExpr(loc, *define.Data.DefineExpr, opts) + // Substitute user-specified defines + if define.Data.DefineExpr != nil { + return p.instantiateDefineExpr(loc, *define.Data.DefineExpr, opts) + } + } } } } @@ -11991,6 +12123,38 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO case *js_ast.EJSXElement: propsLoc := expr.Loc + + // Resolving the location index to a specific line and column in + // development mode is not too expensive because we seek from the + // previous JSX element. It amounts to at most a single additional + // scan over the source code. Note that this has to happen before + // we visit anything about this JSX element to make sure that we + // only ever need to scan forward, not backward. + var jsxSourceLine int + var jsxSourceColumn int + if p.options.jsx.Development && p.options.jsx.AutomaticRuntime { + for p.jsxSourceLoc < int(propsLoc.Start) { + r, size := utf8.DecodeRuneInString(p.source.Contents[p.jsxSourceLoc:]) + p.jsxSourceLoc += size + if r == '\n' || r == '\r' || r == '\u2028' || r == '\u2029' { + if r == '\r' && p.jsxSourceLoc < len(p.source.Contents) && p.source.Contents[p.jsxSourceLoc] == '\n' { + p.jsxSourceLoc++ // Handle Windows-style CRLF newlines + } + p.jsxSourceLine++ + p.jsxSourceColumn = 0 + } else { + // Babel and TypeScript count columns in UTF-16 code units + if r < 0xFFFF { + p.jsxSourceColumn++ + } else { + p.jsxSourceColumn += 2 + } + } + } + jsxSourceLine = p.jsxSourceLine + jsxSourceColumn = p.jsxSourceColumn + } + if e.TagOrNil.Data != nil { propsLoc = e.TagOrNil.Loc e.TagOrNil = p.visitExpr(e.TagOrNil) @@ -12034,37 +12198,195 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO } else { // A missing tag is a fragment if e.TagOrNil.Data == nil { - e.TagOrNil = p.instantiateDefineExpr(expr.Loc, p.options.jsx.Fragment, identifierOpts{ - wasOriginallyIdentifier: true, - }) + if p.options.jsx.AutomaticRuntime { + e.TagOrNil = p.importJSXSymbol(expr.Loc, JSXImportFragment) + } else { + e.TagOrNil = p.instantiateDefineExpr(expr.Loc, p.options.jsx.Fragment, identifierOpts{ + wasOriginallyIdentifier: true, + matchAgainstDefines: true, // Allow defines to rewrite the JSX fragment factory + }) + } + } + + shouldUseCreateElement := !p.options.jsx.AutomaticRuntime + if !shouldUseCreateElement { + // Even for runtime="automatic",
is special cased to createElement + // See https://github.com/babel/babel/blob/e482c763466ba3f44cb9e3467583b78b7f030b4a/packages/babel-plugin-transform-react-jsx/src/create-plugin.ts#L352 + seenPropsSpread := false + for _, property := range e.Properties { + if seenPropsSpread && property.Kind == js_ast.PropertyNormal { + if str, ok := property.Key.Data.(*js_ast.EString); ok && helpers.UTF16EqualsString(str.Value, "key") { + shouldUseCreateElement = true + break + } + } else if property.Kind == js_ast.PropertySpread { + seenPropsSpread = true + } + } } - // Arguments to createElement() - args := []js_ast.Expr{e.TagOrNil} - if len(e.Properties) > 0 { + if shouldUseCreateElement { + // Arguments to createElement() + args := []js_ast.Expr{e.TagOrNil} + if len(e.Properties) > 0 { + args = append(args, p.lowerObjectSpread(propsLoc, &js_ast.EObject{ + Properties: e.Properties, + })) + } else { + args = append(args, js_ast.Expr{Loc: propsLoc, Data: js_ast.ENullShared}) + } + if len(e.Children) > 0 { + args = append(args, e.Children...) + } + + // Call createElement() + var target js_ast.Expr + if p.options.jsx.AutomaticRuntime { + target = p.importJSXSymbol(expr.Loc, JSXImportCreateElement) + } else { + target = p.instantiateDefineExpr(expr.Loc, p.options.jsx.Factory, identifierOpts{ + wasOriginallyIdentifier: true, + matchAgainstDefines: true, // Allow defines to rewrite the JSX factory + }) + p.warnAboutImportNamespaceCall(target, exprKindCall) + } + return js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{ + Target: target, + Args: args, + CloseParenLoc: e.CloseLoc, + + // Enable tree shaking + CanBeUnwrappedIfUnused: !p.options.ignoreDCEAnnotations, + }}, exprOut{} + } else { + // Arguments to jsx() + args := []js_ast.Expr{e.TagOrNil} + + // Props argument + properties := make([]js_ast.Property, 0, len(e.Properties)+1) + + // For jsx(), "key" is passed in as a separate argument, so filter it out + // from the props here. Also, check for __source and __self, which might have + // been added by some upstream plugin. Their presence here would represent a + // configuration error. + hasKey := false + keyProperty := js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared} + for _, property := range e.Properties { + if str, ok := property.Key.Data.(*js_ast.EString); ok { + propName := helpers.UTF16ToString(str.Value) + switch propName { + case "key": + if property.Flags.Has(js_ast.PropertyWasShorthand) { + r := js_lexer.RangeOfIdentifier(p.source, property.Loc) + msg := logger.Msg{ + Kind: logger.Error, + Data: p.tracker.MsgData(r, "Please provide an explicit value for \"key\":"), + Notes: []logger.MsgData{{Text: "Using \"key\" as a shorthand for \"key={true}\" is not allowed when using React's \"automatic\" JSX transform."}}, + } + msg.Data.Location.Suggestion = "key={true}" + p.log.AddMsg(msg) + } else { + keyProperty = property.ValueOrNil + hasKey = true + } + continue + + case "__source", "__self": + r := js_lexer.RangeOfIdentifier(p.source, property.Loc) + p.log.AddErrorWithNotes(&p.tracker, r, + fmt.Sprintf("Duplicate \"%s\" prop found:", propName), + []logger.MsgData{{Text: "Both \"__source\" and \"__self\" are set automatically by esbuild when using React's \"automatic\" JSX transform. " + + "This duplicate prop may have come from a plugin."}}) + continue + } + } + properties = append(properties, property) + } + + isStaticChildren := len(e.Children) > 1 + + // Children are passed in as an explicit prop + if len(e.Children) > 0 { + childrenValue := e.Children[0] + + if len(e.Children) > 1 { + childrenValue.Data = &js_ast.EArray{Items: e.Children} + } else if _, ok := childrenValue.Data.(*js_ast.ESpread); ok { + // TypeScript considers spread children to be static, but Babel considers + // it to be an error ("Spread children are not supported in React."). + // We'll follow TypeScript's behavior here because spread children may be + // valid with non-React source runtimes. + childrenValue.Data = &js_ast.EArray{Items: []js_ast.Expr{childrenValue}} + isStaticChildren = true + } + + properties = append(properties, js_ast.Property{ + Key: js_ast.Expr{ + Data: &js_ast.EString{Value: helpers.StringToUTF16("children")}, + Loc: childrenValue.Loc, + }, + ValueOrNil: childrenValue, + Kind: js_ast.PropertyNormal, + Loc: childrenValue.Loc, + }) + } + args = append(args, p.lowerObjectSpread(propsLoc, &js_ast.EObject{ - Properties: e.Properties, + Properties: properties, })) - } else { - args = append(args, js_ast.Expr{Loc: propsLoc, Data: js_ast.ENullShared}) - } - if len(e.Children) > 0 { - args = append(args, e.Children...) - } - // Call createElement() - target := p.instantiateDefineExpr(expr.Loc, p.options.jsx.Factory, identifierOpts{ - wasOriginallyIdentifier: true, - }) - p.warnAboutImportNamespaceCall(target, exprKindCall) - return js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{ - Target: target, - Args: args, - CloseParenLoc: e.CloseLoc, + // "key" + if hasKey || p.options.jsx.Development { + args = append(args, keyProperty) + } + + if p.options.jsx.Development { + // "isStaticChildren" + args = append(args, js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EBoolean{Value: isStaticChildren}}) + + // "__source" + args = append(args, js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EObject{ + Properties: []js_ast.Property{ + { + Kind: js_ast.PropertyNormal, + Key: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16("fileName")}}, + ValueOrNil: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16(p.source.PrettyPath)}}, + }, + { + Kind: js_ast.PropertyNormal, + Key: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16("lineNumber")}}, + ValueOrNil: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: float64(jsxSourceLine + 1)}}, // 1-based lines + }, + { + Kind: js_ast.PropertyNormal, + Key: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.EString{Value: helpers.StringToUTF16("columnNumber")}}, + ValueOrNil: js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ENumber{Value: float64(jsxSourceColumn + 1)}}, // 1-based columns + }, + }, + }}) + + // "__self" + if p.fnOrArrowDataParse.isThisDisallowed { + args = append(args, js_ast.Expr{Loc: expr.Loc, Data: js_ast.EUndefinedShared}) + } else { + args = append(args, js_ast.Expr{Loc: expr.Loc, Data: js_ast.EThisShared}) + } + } - // Enable tree shaking - CanBeUnwrappedIfUnused: !p.options.ignoreDCEAnnotations, - }}, exprOut{} + jsx := JSXImportJSX + if isStaticChildren { + jsx = JSXImportJSXS + } + + return js_ast.Expr{Loc: expr.Loc, Data: &js_ast.ECall{ + Target: p.importJSXSymbol(expr.Loc, jsx), + Args: args, + CloseParenLoc: e.CloseLoc, + + // Enable tree shaking + CanBeUnwrappedIfUnused: !p.options.ignoreDCEAnnotations, + }}, exprOut{} + } } case *js_ast.ETemplate: @@ -14256,6 +14578,7 @@ type identifierOpts struct { isDeleteTarget bool preferQuotedKey bool wasOriginallyIdentifier bool + matchAgainstDefines bool } func (p *parser) handleIdentifier(loc logger.Loc, e *js_ast.EIdentifier, opts identifierOpts) js_ast.Expr { @@ -15290,6 +15613,7 @@ func newParser(log logger.Log, source logger.Source, lexer js_lexer.Lexer, optio promiseRef: js_ast.InvalidRef, regExpRef: js_ast.InvalidRef, afterArrowBodyLoc: logger.Loc{Start: -1}, + firstJSXElementLoc: logger.Loc{Start: -1}, importMetaRef: js_ast.InvalidRef, runtimePublicFieldImport: js_ast.InvalidRef, superCtorRef: js_ast.InvalidRef, @@ -15313,6 +15637,10 @@ func newParser(log logger.Log, source logger.Source, lexer js_lexer.Lexer, optio namedImports: make(map[js_ast.Ref]js_ast.NamedImport), namedExports: make(map[string]js_ast.NamedExport), + // For JSX runtime imports + jsxRuntimeImports: make(map[string]js_ast.Ref), + jsxLegacyImports: make(map[string]js_ast.Ref), + suppressWarningsAboutWeirdCode: helpers.IsInsideNodeModules(source.KeyPath.Text), } @@ -15328,6 +15656,8 @@ func newParser(log logger.Log, source logger.Source, lexer js_lexer.Lexer, optio var defaultJSXFactory = []string{"React", "createElement"} var defaultJSXFragment = []string{"React", "Fragment"} +const defaultJSXImportSource = "react" + func Parse(log logger.Log, source logger.Source, options Options) (result js_ast.AST, ok bool) { ok = true defer func() { @@ -15346,6 +15676,9 @@ func Parse(log logger.Log, source logger.Source, options Options) (result js_ast if len(options.jsx.Fragment.Parts) == 0 && options.jsx.Fragment.Constant == nil { options.jsx.Fragment = config.DefineExpr{Parts: defaultJSXFragment} } + if len(options.jsx.ImportSource) == 0 { + options.jsx.ImportSource = defaultJSXImportSource + } if !options.ts.Parse { // Non-TypeScript files always get the real JavaScript class field behavior @@ -15461,7 +15794,7 @@ func Parse(log logger.Log, source logger.Source, options Options) (result js_ast } } } - before = p.generateImportStmt(file.Source.KeyPath.Text, exportsNoConflict, file.Source.Index, before, symbols) + before = p.generateImportStmt(file.Source.KeyPath.Text, exportsNoConflict, &file.Source.Index, before, symbols) } // Bind symbols in a second pass over the AST. I started off doing this in a @@ -15536,8 +15869,7 @@ func Parse(log logger.Log, source logger.Source, options Options) (result js_ast // Pop the module scope to apply the "ContainsDirectEval" rules p.popScope() - parts = append(append(before, parts...), after...) - result = p.toAST(parts, hashbang, directive) + result = p.toAST(before, parts, after, hashbang, directive) result.SourceMapComment = p.lexer.SourceMappingURL return } @@ -15568,18 +15900,11 @@ func LazyExportAST(log logger.Log, source logger.Source, options Options, expr j } p.symbolUses = nil - ast := p.toAST([]js_ast.Part{nsExportPart, part}, "", "") + ast := p.toAST(nil, []js_ast.Part{nsExportPart, part}, nil, "", "") ast.HasLazyExport = true return ast } -type JSXExprKind uint8 - -const ( - JSXFactory JSXExprKind = iota - JSXFragment -) - func ParseDefineExprOrJSON(text string) (config.DefineExpr, js_ast.E) { if text == "" { return config.DefineExpr{}, nil @@ -15715,22 +16040,60 @@ func (p *parser) prepareForVisitPass() { // Handle "@jsx" and "@jsxFrag" pragmas now that lexing is done if p.options.jsx.Parse { + if jsxRuntime := p.lexer.JSXRuntimePragmaComment; jsxRuntime.Text != "" { + if jsxRuntime.Text == "automatic" { + p.options.jsx.AutomaticRuntime = true + } else if jsxRuntime.Text == "classic" { + p.options.jsx.AutomaticRuntime = false + } else { + p.log.AddIDWithNotes(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxRuntime.Range, + fmt.Sprintf("Invalid JSX runtime: %q", jsxRuntime.Text), + []logger.MsgData{{Text: "The JSX runtime can only be set to either \"classic\" or \"automatic\"."}}) + } + } + if jsxFactory := p.lexer.JSXFactoryPragmaComment; jsxFactory.Text != "" { - if expr, _ := ParseDefineExprOrJSON(jsxFactory.Text); len(expr.Parts) > 0 { + if p.options.jsx.AutomaticRuntime { + p.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFactory.Range, + "The JSX factory cannot be set when using React's \"automatic\" JSX transform") + } else if expr, _ := ParseDefineExprOrJSON(jsxFactory.Text); len(expr.Parts) > 0 { p.options.jsx.Factory = expr } else { p.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFactory.Range, fmt.Sprintf("Invalid JSX factory: %s", jsxFactory.Text)) } } + if jsxFragment := p.lexer.JSXFragmentPragmaComment; jsxFragment.Text != "" { - if expr, _ := ParseDefineExprOrJSON(jsxFragment.Text); len(expr.Parts) > 0 || expr.Constant != nil { + if p.options.jsx.AutomaticRuntime { + p.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFragment.Range, + "The JSX fragment cannot be set when using React's \"automatic\" JSX transform") + } else if expr, _ := ParseDefineExprOrJSON(jsxFragment.Text); len(expr.Parts) > 0 || expr.Constant != nil { p.options.jsx.Fragment = expr } else { p.log.AddID(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxFragment.Range, fmt.Sprintf("Invalid JSX fragment: %s", jsxFragment.Text)) } } + + if jsxImportSource := p.lexer.JSXImportSourcePragmaComment; jsxImportSource.Text != "" { + if !p.options.jsx.AutomaticRuntime { + p.log.AddIDWithNotes(logger.MsgID_JS_UnsupportedJSXComment, logger.Warning, &p.tracker, jsxImportSource.Range, + fmt.Sprintf("The JSX import source cannot be set without also enabling React's \"automatic\" JSX transform"), + []logger.MsgData{{Text: "You can enable React's \"automatic\" JSX transform for this file by using a \"@jsxRuntime automatic\" comment."}}) + } else { + p.options.jsx.ImportSource = jsxImportSource.Text + } + } + } + + // Force-enable strict mode if the JSX "automatic" runtime is enabled and + // there is at least one JSX element. This is because the automatically- + // generated import statement turns the file into an ES module. This behavior + // matches TypeScript which also does this. See this PR for more information: + // https://github.com/microsoft/TypeScript/pull/39199 + if p.currentScope.StrictMode == js_ast.SloppyMode && p.options.jsx.AutomaticRuntime && p.firstJSXElementLoc.Start != -1 { + p.currentScope.StrictMode = js_ast.ImplicitStrictModeJSXAutomaticRuntime } } @@ -15837,7 +16200,7 @@ func (p *parser) computeCharacterFrequency() *js_ast.CharFreq { func (p *parser) generateImportStmt( path string, imports []string, - sourceIndex uint32, + sourceIndex *uint32, parts []js_ast.Part, symbols map[string]js_ast.Ref, ) []js_ast.Part { @@ -15846,7 +16209,9 @@ func (p *parser) generateImportStmt( declaredSymbols := make([]js_ast.DeclaredSymbol, len(imports)) clauseItems := make([]js_ast.ClauseItem, len(imports)) importRecordIndex := p.addImportRecord(ast.ImportStmt, logger.Loc{}, path, nil) - p.importRecords[importRecordIndex].SourceIndex = ast.MakeIndex32(sourceIndex) + if sourceIndex != nil { + p.importRecords[importRecordIndex].SourceIndex = ast.MakeIndex32(*sourceIndex) + } // Create per-import information for i, alias := range imports { @@ -15870,21 +16235,66 @@ func (p *parser) generateImportStmt( NamespaceRef: namespaceRef, Items: &clauseItems, ImportRecordIndex: importRecordIndex, + IsSingleLine: true, }}}, }) } -func (p *parser) toAST(parts []js_ast.Part, hashbang string, directive string) js_ast.AST { +// Sort the keys for determinism +func sortedKeysOfMapStringRef(in map[string]js_ast.Ref) []string { + keys := make([]string, 0, len(in)) + for key := range in { + keys = append(keys, key) + } + sort.Strings(keys) + return keys +} + +func (p *parser) toAST(before, parts, after []js_ast.Part, hashbang string, directive string) js_ast.AST { // Insert an import statement for any runtime imports we generated if len(p.runtimeImports) > 0 && !p.options.omitRuntimeForTests { - // Sort the imports for determinism - keys := make([]string, 0, len(p.runtimeImports)) - for key := range p.runtimeImports { - keys = append(keys, key) + keys := sortedKeysOfMapStringRef(p.runtimeImports) + sourceIndex := runtime.SourceIndex + before = p.generateImportStmt("", keys, &sourceIndex, before, p.runtimeImports) + } + + // Insert an import statement for any jsx runtime imports we generated + if len(p.jsxRuntimeImports) > 0 && !p.options.omitJSXRuntimeForTests { + keys := sortedKeysOfMapStringRef(p.jsxRuntimeImports) + + // Determine the runtime source and whether it's prod or dev + path := p.options.jsx.ImportSource + if p.options.jsx.Development { + path = path + "/jsx-dev-runtime" + } else { + path = path + "/jsx-runtime" } - sort.Strings(keys) - parts = p.generateImportStmt("", keys, runtime.SourceIndex, parts, p.runtimeImports) + + before = p.generateImportStmt(path, keys, nil, before, p.jsxRuntimeImports) + } + + // Insert an import statement for any legacy jsx imports we generated (i.e., createElement) + if len(p.jsxLegacyImports) > 0 && !p.options.omitJSXRuntimeForTests { + keys := sortedKeysOfMapStringRef(p.jsxLegacyImports) + path := p.options.jsx.ImportSource + before = p.generateImportStmt(path, keys, nil, before, p.jsxLegacyImports) + } + + // Generated imports are inserted before other code instead of appending them + // to the end of the file. Appending them should work fine because JavaScript + // import statements are "hoisted" to run before the importing file. However, + // some buggy JavaScript toolchains such as the TypeScript compiler convert + // ESM into CommonJS by replacing "import" statements inline without doing + // any hoisting, which is incorrect. See the following issue for more info: + // https://github.com/microsoft/TypeScript/issues/16166. Since JSX-related + // imports are present in the generated code when bundling is disabled, and + // could therefore be processed by these buggy tools, it's more robust to put + // them at the top even though it means potentially reallocating almost the + // entire array of parts. + if len(before) > 0 { + parts = append(before, parts...) } + parts = append(parts, after...) // Handle import paths after the whole file has been visited because we need // symbol usage counts to be able to remove unused type-only imports in diff --git a/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go b/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go index e3ea2d341..fa2e0ceda 100644 --- a/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go +++ b/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go @@ -220,6 +220,13 @@ func (p *parser) markStrictModeFeature(feature strictModeFeature, r logger.Range notes = []logger.MsgData{t.MsgData(tsAlwaysStrict.Range, fmt.Sprintf( "TypeScript's %q setting was enabled here:", tsAlwaysStrict.Name))} + case js_ast.ImplicitStrictModeJSXAutomaticRuntime: + notes = []logger.MsgData{p.tracker.MsgData(logger.Range{Loc: p.firstJSXElementLoc, Len: 1}, + "This file is implicitly in strict mode due to the JSX element here:"), + {Text: "When React's \"automatic\" JSX transform is enabled, using a JSX element automatically inserts " + + "an \"import\" statement at the top of the file for the corresponding the JSX helper function. " + + "This means the file is considered an ECMAScript module, and all ECMAScript modules use strict mode."}} + case js_ast.ExplicitStrictMode: notes = []logger.MsgData{p.tracker.MsgData(p.source.RangeOfString(p.currentScope.UseStrictLoc), "Strict mode is triggered by the \"use strict\" directive here:")} @@ -709,6 +716,7 @@ flatten: }}, Args: append([]js_ast.Expr{thisArg}, e.Args...), CanBeUnwrappedIfUnused: e.CanBeUnwrappedIfUnused, + IsMultiLine: e.IsMultiLine, }} break } @@ -726,6 +734,7 @@ flatten: }}, Args: append([]js_ast.Expr{privateThisFunc()}, e.Args...), CanBeUnwrappedIfUnused: e.CanBeUnwrappedIfUnused, + IsMultiLine: e.IsMultiLine, }}) privateThisFunc = nil break @@ -735,6 +744,7 @@ flatten: Target: result, Args: e.Args, CanBeUnwrappedIfUnused: e.CanBeUnwrappedIfUnused, + IsMultiLine: e.IsMultiLine, }} case *js_ast.EUnary: @@ -784,7 +794,8 @@ func (p *parser) lowerParenthesizedOptionalChain(loc logger.Loc, e *js_ast.ECall Name: "call", NameLoc: loc, }}, - Args: append(append(make([]js_ast.Expr, 0, len(e.Args)+1), childOut.thisArgFunc()), e.Args...), + Args: append(append(make([]js_ast.Expr, 0, len(e.Args)+1), childOut.thisArgFunc()), e.Args...), + IsMultiLine: e.IsMultiLine, }}) } @@ -937,26 +948,26 @@ func (p *parser) lowerNullishCoalescing(loc logger.Loc, left js_ast.Expr, right // properties are grouped into object literals and then passed to the // "__spreadValues" and "__spreadProps" functions like this: // -// "{a, b, ...c, d, e}" => "__spreadProps(__spreadValues(__spreadProps({a, b}, c), {d, e})" +// "{a, b, ...c, d, e}" => "__spreadProps(__spreadValues(__spreadProps({a, b}, c), {d, e})" // // If the object literal starts with a spread, then we pass an empty object // literal to "__spreadValues" to make sure we clone the object: // -// "{...a, b}" => "__spreadProps(__spreadValues({}, a), {b})" +// "{...a, b}" => "__spreadProps(__spreadValues({}, a), {b})" // // It's not immediately obvious why we don't compile everything to a single // call to a function that takes any number of arguments, since that would be // shorter. The reason is to preserve the order of side effects. Consider // this code: // -// let a = { -// get x() { -// b = {y: 2} -// return 1 -// } -// } -// let b = {} -// let c = {...a, ...b} +// let a = { +// get x() { +// b = {y: 2} +// return 1 +// } +// } +// let b = {} +// let c = {...a, ...b} // // Converting the above code to "let c = __spreadFn({}, a, null, b)" means "c" // becomes "{x: 1}" which is incorrect. Converting the above code instead to diff --git a/vendor/github.com/evanw/esbuild/internal/js_parser/sourcemap_parser.go b/vendor/github.com/evanw/esbuild/internal/js_parser/sourcemap_parser.go index 9a14988ec..e0ecbb9a0 100644 --- a/vendor/github.com/evanw/esbuild/internal/js_parser/sourcemap_parser.go +++ b/vendor/github.com/evanw/esbuild/internal/js_parser/sourcemap_parser.go @@ -4,6 +4,7 @@ import ( "fmt" "sort" + "github.com/evanw/esbuild/internal/ast" "github.com/evanw/esbuild/internal/helpers" "github.com/evanw/esbuild/internal/js_ast" "github.com/evanw/esbuild/internal/logger" @@ -26,6 +27,7 @@ func ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap { var sources []string var sourcesContent []sourcemap.SourceContent + var names []string var mappingsRaw []uint16 var mappingsStart int32 hasVersion := false @@ -75,6 +77,18 @@ func ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap { } } } + + case "names": + if value, ok := prop.ValueOrNil.Data.(*js_ast.EArray); ok { + names = nil + for _, item := range value.Items { + if element, ok := item.Data.(*js_ast.EString); ok { + names = append(names, helpers.UTF16ToString(element.Value)) + } else { + names = append(names, "") + } + } + } } } @@ -91,11 +105,13 @@ func ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap { var mappings mappingArray mappingsLen := len(mappingsRaw) sourcesLen := len(sources) - generatedLine := 0 - generatedColumn := 0 - sourceIndex := 0 - originalLine := 0 - originalColumn := 0 + namesLen := len(names) + var generatedLine int32 + var generatedColumn int32 + var sourceIndex int32 + var originalLine int32 + var originalColumn int32 + var originalName int32 current := 0 errorText := "" errorLen := 0 @@ -153,7 +169,7 @@ func ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap { break } sourceIndex += sourceIndexDelta - if sourceIndex < 0 || sourceIndex >= sourcesLen { + if sourceIndex < 0 || sourceIndex >= int32(sourcesLen) { errorText = fmt.Sprintf("Invalid source index value: %d", sourceIndex) errorLen = i break @@ -190,8 +206,16 @@ func ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap { } current += i - // Ignore the optional name index - if _, i, ok := sourcemap.DecodeVLQUTF16(mappingsRaw[current:]); ok { + // Read the original name + var optionalName ast.Index32 + if originalNameDelta, i, ok := sourcemap.DecodeVLQUTF16(mappingsRaw[current:]); ok { + originalName += originalNameDelta + if originalName < 0 || originalName >= int32(namesLen) { + errorText = fmt.Sprintf("Invalid name index value: %d", originalName) + errorLen = i + break + } + optionalName = ast.MakeIndex32(uint32(originalName)) current += i } @@ -208,11 +232,12 @@ func ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap { } mappings = append(mappings, sourcemap.Mapping{ - GeneratedLine: int32(generatedLine), - GeneratedColumn: int32(generatedColumn), - SourceIndex: int32(sourceIndex), - OriginalLine: int32(originalLine), - OriginalColumn: int32(originalColumn), + GeneratedLine: generatedLine, + GeneratedColumn: generatedColumn, + SourceIndex: sourceIndex, + OriginalLine: originalLine, + OriginalColumn: originalColumn, + OriginalName: optionalName, }) } @@ -235,6 +260,7 @@ func ParseSourceMap(log logger.Log, source logger.Source) *sourcemap.SourceMap { Sources: sources, SourcesContent: sourcesContent, Mappings: mappings, + Names: names, } } diff --git a/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go b/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go index 811d1a3b5..ff2b45427 100644 --- a/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go +++ b/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go @@ -130,18 +130,17 @@ func (p *parser) skipTypeScriptFnArgs() { // This is a spot where the TypeScript grammar is highly ambiguous. Here are // some cases that are valid: // -// let x = (y: any): (() => {}) => { }; -// let x = (y: any): () => {} => { }; -// let x = (y: any): (y) => {} => { }; -// let x = (y: any): (y[]) => {}; -// let x = (y: any): (a | b) => {}; +// let x = (y: any): (() => {}) => { }; +// let x = (y: any): () => {} => { }; +// let x = (y: any): (y) => {} => { }; +// let x = (y: any): (y[]) => {}; +// let x = (y: any): (a | b) => {}; // // Here are some cases that aren't valid: // -// let x = (y: any): (y) => {}; -// let x = (y: any): (y) => {return 0}; -// let x = (y: any): asserts y is (y) => {}; -// +// let x = (y: any): (y) => {}; +// let x = (y: any): (y) => {return 0}; +// let x = (y: any): asserts y is (y) => {}; func (p *parser) skipTypeScriptParenOrFnType() { if p.trySkipTypeScriptArrowArgsWithBacktracking() { p.skipTypeScriptReturnType() @@ -863,7 +862,7 @@ func (p *parser) isTSArrowFnJSX() (isTSArrowFn bool) { // Look ahead to see if this should be an arrow function instead if p.lexer.Token == js_lexer.TIdentifier { p.lexer.Next() - if p.lexer.Token == js_lexer.TComma { + if p.lexer.Token == js_lexer.TComma || p.lexer.Token == js_lexer.TEquals { isTSArrowFn = true } else if p.lexer.Token == js_lexer.TExtends { p.lexer.Next() diff --git a/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go b/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go index e0f779923..336fb31e2 100644 --- a/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go +++ b/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go @@ -30,110 +30,6 @@ const lastHighSurrogate = 0xDBFF const firstLowSurrogate = 0xDC00 const lastLowSurrogate = 0xDFFF -func canPrintWithoutEscape(c rune, asciiOnly bool) bool { - if c <= lastASCII { - return c >= firstASCII && c != '\\' && c != '"' - } else { - return !asciiOnly && c != '\uFEFF' && (c < firstHighSurrogate || c > lastLowSurrogate) - } -} - -func QuoteForJSON(text string, asciiOnly bool) []byte { - // Estimate the required length - lenEstimate := 2 - for _, c := range text { - if canPrintWithoutEscape(c, asciiOnly) { - lenEstimate += utf8.RuneLen(c) - } else { - switch c { - case '\b', '\f', '\n', '\r', '\t', '\\', '"': - lenEstimate += 2 - default: - if c <= 0xFFFF { - lenEstimate += 6 - } else { - lenEstimate += 12 - } - } - } - } - - // Preallocate the array - bytes := make([]byte, 0, lenEstimate) - i := 0 - n := len(text) - bytes = append(bytes, '"') - - for i < n { - c, width := helpers.DecodeWTF8Rune(text[i:]) - - // Fast path: a run of characters that don't need escaping - if canPrintWithoutEscape(c, asciiOnly) { - start := i - i += width - for i < n { - c, width = helpers.DecodeWTF8Rune(text[i:]) - if !canPrintWithoutEscape(c, asciiOnly) { - break - } - i += width - } - bytes = append(bytes, text[start:i]...) - continue - } - - switch c { - case '\b': - bytes = append(bytes, "\\b"...) - i++ - - case '\f': - bytes = append(bytes, "\\f"...) - i++ - - case '\n': - bytes = append(bytes, "\\n"...) - i++ - - case '\r': - bytes = append(bytes, "\\r"...) - i++ - - case '\t': - bytes = append(bytes, "\\t"...) - i++ - - case '\\': - bytes = append(bytes, "\\\\"...) - i++ - - case '"': - bytes = append(bytes, "\\\""...) - i++ - - default: - i += width - if c <= 0xFFFF { - bytes = append( - bytes, - '\\', 'u', hexChars[c>>12], hexChars[(c>>8)&15], hexChars[(c>>4)&15], hexChars[c&15], - ) - } else { - c -= 0x10000 - lo := firstHighSurrogate + ((c >> 10) & 0x3FF) - hi := firstLowSurrogate + (c & 0x3FF) - bytes = append( - bytes, - '\\', 'u', hexChars[lo>>12], hexChars[(lo>>8)&15], hexChars[(lo>>4)&15], hexChars[lo&15], - '\\', 'u', hexChars[hi>>12], hexChars[(hi>>8)&15], hexChars[(hi>>4)&15], hexChars[hi&15], - ) - } - } - } - - return append(bytes, '"') -} - func QuoteIdentifier(js []byte, name string, unsupportedFeatures compat.JSFeature) []byte { isASCII := false asciiStart := 0 @@ -417,7 +313,7 @@ func (p *printer) printJSXTag(tagOrNil js_ast.Expr) { case *js_ast.EIdentifier: name := p.renamer.NameForSymbol(e.Ref) - p.addSourceMapping(tagOrNil.Loc) + p.addSourceMappingForName(tagOrNil.Loc, name, e.Ref) p.print(name) case *js_ast.EDot: @@ -472,7 +368,17 @@ func (p *printer) printQuotedUTF8(text string, allowBacktick bool) { func (p *printer) addSourceMapping(loc logger.Loc) { if p.options.AddSourceMappings { - p.builder.AddSourceMapping(loc, p.js) + p.builder.AddSourceMapping(loc, "", p.js) + } +} + +func (p *printer) addSourceMappingForName(loc logger.Loc, name string, ref js_ast.Ref) { + if p.options.AddSourceMappings { + if originalName := p.symbols.Get(js_ast.FollowSymbols(p.symbols, ref)).OriginalName; originalName != name { + p.builder.AddSourceMapping(loc, originalName, p.js) + } else { + p.builder.AddSourceMapping(loc, "", p.js) + } } } @@ -484,15 +390,12 @@ func (p *printer) printIndent() { } } -func (p *printer) printSymbol(ref js_ast.Ref) { - name := p.renamer.NameForSymbol(ref) - - // Minify "return #foo in bar" to "return#foo in bar" - if !strings.HasPrefix(name, "#") { - p.printSpaceBeforeIdentifier() +func (p *printer) mangledPropName(ref js_ast.Ref) string { + ref = js_ast.FollowSymbols(p.symbols, ref) + if name, ok := p.options.MangledProps[ref]; ok { + return name } - - p.printIdentifier(name) + return p.renamer.NameForSymbol(ref) } func (p *printer) printClauseAlias(alias string) { @@ -628,15 +531,18 @@ func (p *printer) printNumber(value float64, level js_ast.L) { } func (p *printer) printBinding(binding js_ast.Binding) { - p.addSourceMapping(binding.Loc) - switch b := binding.Data.(type) { case *js_ast.BMissing: + p.addSourceMapping(binding.Loc) case *js_ast.BIdentifier: - p.printSymbol(b.Ref) + name := p.renamer.NameForSymbol(b.Ref) + p.printSpaceBeforeIdentifier() + p.addSourceMappingForName(binding.Loc, name, b.Ref) + p.printIdentifier(name) case *js_ast.BArray: + p.addSourceMapping(binding.Loc) p.print("[") if len(b.Items) > 0 { if !b.IsSingleLine { @@ -678,9 +584,11 @@ func (p *printer) printBinding(binding js_ast.Binding) { p.printIndent() } } + p.addSourceMapping(b.CloseBracketLoc) p.print("]") case *js_ast.BObject: + p.addSourceMapping(binding.Loc) p.print("{") if len(b.Properties) > 0 { if !b.IsSingleLine { @@ -718,11 +626,12 @@ func (p *printer) printBinding(binding js_ast.Binding) { } if str, ok := property.Key.Data.(*js_ast.EString); ok && !property.PreferQuotedKey && p.canPrintIdentifierUTF16(str.Value) { - p.addSourceMapping(property.Key.Loc) - p.printIdentifierUTF16(str.Value) - // Use a shorthand property if the names are the same if id, ok := property.Value.Data.(*js_ast.BIdentifier); ok && helpers.UTF16EqualsString(str.Value, p.renamer.NameForSymbol(id.Ref)) { + if p.options.AddSourceMappings { + p.addSourceMappingForName(property.Key.Loc, helpers.UTF16ToString(str.Value), id.Ref) + } + p.printIdentifierUTF16(str.Value) if property.DefaultValueOrNil.Data != nil { p.printSpace() p.print("=") @@ -731,9 +640,12 @@ func (p *printer) printBinding(binding js_ast.Binding) { } continue } - } else if mangled, ok := property.Key.Data.(*js_ast.EMangledProp); ok { + p.addSourceMapping(property.Key.Loc) - if name := p.renamer.NameForSymbol(mangled.Ref); p.canPrintIdentifier(name) { + p.printIdentifierUTF16(str.Value) + } else if mangled, ok := property.Key.Data.(*js_ast.EMangledProp); ok { + if name := p.mangledPropName(mangled.Ref); p.canPrintIdentifier(name) { + p.addSourceMappingForName(property.Key.Loc, name, mangled.Ref) p.printIdentifier(name) // Use a shorthand property if the names are the same @@ -747,6 +659,7 @@ func (p *printer) printBinding(binding js_ast.Binding) { continue } } else { + p.addSourceMapping(property.Key.Loc) p.printQuotedUTF8(name, false /* allowBacktick */) } } else { @@ -775,6 +688,7 @@ func (p *printer) printBinding(binding js_ast.Binding) { p.printSpace() } } + p.addSourceMapping(b.CloseBraceLoc) p.print("}") default: @@ -837,17 +751,27 @@ func (p *printer) printSpaceBeforeIdentifier() { } } -func (p *printer) printFnArgs(args []js_ast.Arg, hasRestArg bool, isArrow bool) { +type fnArgsOpts struct { + openParenLoc logger.Loc + addMappingForOpenParenLoc bool + hasRestArg bool + isArrow bool +} + +func (p *printer) printFnArgs(args []js_ast.Arg, opts fnArgsOpts) { wrap := true // Minify "(a) => {}" as "a=>{}" - if p.options.MinifyWhitespace && !hasRestArg && isArrow && len(args) == 1 { + if p.options.MinifyWhitespace && !opts.hasRestArg && opts.isArrow && len(args) == 1 { if _, ok := args[0].Binding.Data.(*js_ast.BIdentifier); ok && args[0].DefaultOrNil.Data == nil { wrap = false } } if wrap { + if opts.addMappingForOpenParenLoc { + p.addSourceMapping(opts.openParenLoc) + } p.print("(") } @@ -856,7 +780,7 @@ func (p *printer) printFnArgs(args []js_ast.Arg, hasRestArg bool, isArrow bool) p.print(",") p.printSpace() } - if hasRestArg && i+1 == len(args) { + if opts.hasRestArg && i+1 == len(args) { p.print("...") } p.printBinding(arg.Binding) @@ -875,7 +799,7 @@ func (p *printer) printFnArgs(args []js_ast.Arg, hasRestArg bool, isArrow bool) } func (p *printer) printFn(fn js_ast.Fn) { - p.printFnArgs(fn.Args, fn.HasRestArg, false /* isArrow */) + p.printFnArgs(fn.Args, fnArgsOpts{hasRestArg: fn.HasRestArg}) p.printSpace() p.printBlock(fn.Body.Loc, fn.Body.Block) } @@ -926,15 +850,15 @@ func (p *printer) printClass(class js_ast.Class) { } func (p *printer) printProperty(item js_ast.Property) { - p.addSourceMapping(item.Loc) - if item.Kind == js_ast.PropertySpread { + p.addSourceMapping(item.Loc) p.print("...") p.printExpr(item.ValueOrNil, js_ast.LComma, 0) return } if item.Flags.Has(js_ast.PropertyIsStatic) { + p.addSourceMapping(item.Loc) p.print("static") p.printSpace() } @@ -942,11 +866,13 @@ func (p *printer) printProperty(item js_ast.Property) { switch item.Kind { case js_ast.PropertyGet: p.printSpaceBeforeIdentifier() + p.addSourceMapping(item.Loc) p.print("get") p.printSpace() case js_ast.PropertySet: p.printSpaceBeforeIdentifier() + p.addSourceMapping(item.Loc) p.print("set") p.printSpace() } @@ -954,15 +880,18 @@ func (p *printer) printProperty(item js_ast.Property) { if fn, ok := item.ValueOrNil.Data.(*js_ast.EFunction); item.Flags.Has(js_ast.PropertyIsMethod) && ok { if fn.Fn.IsAsync { p.printSpaceBeforeIdentifier() + p.addSourceMapping(item.Loc) p.print("async") p.printSpace() } if fn.Fn.IsGenerator { + p.addSourceMapping(item.Loc) p.print("*") } } if item.Flags.Has(js_ast.PropertyIsComputed) { + p.addSourceMapping(item.Loc) p.print("[") p.printExpr(item.Key, js_ast.LComma, 0) p.print("]") @@ -989,13 +918,14 @@ func (p *printer) printProperty(item js_ast.Property) { switch key := item.Key.Data.(type) { case *js_ast.EPrivateIdentifier: - p.addSourceMapping(item.Key.Loc) - p.printSymbol(key.Ref) + name := p.renamer.NameForSymbol(key.Ref) + p.addSourceMappingForName(item.Key.Loc, name, key.Ref) + p.printIdentifier(name) case *js_ast.EMangledProp: - p.addSourceMapping(item.Key.Loc) - if name := p.renamer.NameForSymbol(key.Ref); p.canPrintIdentifier(name) { + if name := p.mangledPropName(key.Ref); p.canPrintIdentifier(name) { p.printSpaceBeforeIdentifier() + p.addSourceMappingForName(item.Key.Loc, name, key.Ref) p.printIdentifier(name) // Use a shorthand property if the names are the same @@ -1028,20 +958,23 @@ func (p *printer) printProperty(item js_ast.Property) { } } } else { + p.addSourceMapping(item.Key.Loc) p.printQuotedUTF8(name, false /* allowBacktick */) } case *js_ast.EString: - p.addSourceMapping(item.Key.Loc) if !item.Flags.Has(js_ast.PropertyPreferQuotedKey) && p.canPrintIdentifierUTF16(key.Value) { p.printSpaceBeforeIdentifier() - p.printIdentifierUTF16(key.Value) // Use a shorthand property if the names are the same if !p.options.UnsupportedFeatures.Has(compat.ObjectExtensions) && item.ValueOrNil.Data != nil { switch e := item.ValueOrNil.Data.(type) { case *js_ast.EIdentifier: if helpers.UTF16EqualsString(key.Value, p.renamer.NameForSymbol(e.Ref)) { + if p.options.AddSourceMappings { + p.addSourceMappingForName(item.Key.Loc, helpers.UTF16ToString(key.Value), e.Ref) + } + p.printIdentifierUTF16(key.Value) if item.InitializerOrNil.Data != nil { p.printSpace() p.print("=") @@ -1056,6 +989,10 @@ func (p *printer) printProperty(item js_ast.Property) { ref := js_ast.FollowSymbols(p.symbols, e.Ref) if symbol := p.symbols.Get(ref); symbol.NamespaceAlias == nil && helpers.UTF16EqualsString(key.Value, p.renamer.NameForSymbol(ref)) && p.options.ConstValues[ref].Kind == js_ast.ConstValueNone { + if p.options.AddSourceMappings { + p.addSourceMappingForName(item.Key.Loc, helpers.UTF16ToString(key.Value), ref) + } + p.printIdentifierUTF16(key.Value) if item.InitializerOrNil.Data != nil { p.printSpace() p.print("=") @@ -1066,7 +1003,11 @@ func (p *printer) printProperty(item js_ast.Property) { } } } + + p.addSourceMapping(item.Key.Loc) + p.printIdentifierUTF16(key.Value) } else { + p.addSourceMapping(item.Key.Loc) p.printQuotedUTF16(key.Value, false /* allowBacktick */) } @@ -1167,15 +1108,16 @@ func (p *printer) printRequireOrImportExpr( // Wrap this with a call to "__toESM()" if this is a CommonJS file wrapWithToESM := record.Flags.Has(ast.WrapWithToESM) if wrapWithToESM { - p.printSymbol(p.options.ToESMRef) + p.printSpaceBeforeIdentifier() + p.printIdentifier(p.renamer.NameForSymbol(p.options.ToESMRef)) p.print("(") } // Potentially substitute our own "__require" stub for "require" + p.printSpaceBeforeIdentifier() if record.Flags.Has(ast.CallRuntimeRequire) { - p.printSymbol(p.options.RuntimeRequireRef) + p.printIdentifier(p.renamer.NameForSymbol(p.options.RuntimeRequireRef)) } else { - p.printSpaceBeforeIdentifier() p.print("require") } @@ -1209,7 +1151,8 @@ func (p *printer) printRequireOrImportExpr( // Wrap this with a call to "__toESM()" if this is a CommonJS file if record.Flags.Has(ast.WrapWithToESM) { - p.printSymbol(p.options.ToESMRef) + p.printSpaceBeforeIdentifier() + p.printIdentifier(p.renamer.NameForSymbol(p.options.ToESMRef)) p.print("(") defer func() { if p.moduleType.IsESM() { @@ -1222,10 +1165,10 @@ func (p *printer) printRequireOrImportExpr( } // Potentially substitute our own "__require" stub for "require" + p.printSpaceBeforeIdentifier() if record.Flags.Has(ast.CallRuntimeRequire) { - p.printSymbol(p.options.RuntimeRequireRef) + p.printIdentifier(p.renamer.NameForSymbol(p.options.RuntimeRequireRef)) } else { - p.printSpaceBeforeIdentifier() p.print("require") } @@ -1262,11 +1205,13 @@ func (p *printer) printRequireOrImportExpr( // Internal "import()" of async ESM if record.Kind == ast.ImportDynamic && meta.IsWrapperAsync { - p.printSymbol(meta.WrapperRef) + p.printSpaceBeforeIdentifier() + p.printIdentifier(p.renamer.NameForSymbol(meta.WrapperRef)) p.print("()") if meta.ExportsRef != js_ast.InvalidRef { p.printDotThenPrefix() - p.printSymbol(meta.ExportsRef) + p.printSpaceBeforeIdentifier() + p.printIdentifier(p.renamer.NameForSymbol(meta.ExportsRef)) p.printDotThenSuffix() } return @@ -1289,12 +1234,14 @@ func (p *printer) printRequireOrImportExpr( // Wrap this with a call to "__toESM()" if this is a CommonJS file wrapWithToESM := record.Flags.Has(ast.WrapWithToESM) if wrapWithToESM { - p.printSymbol(p.options.ToESMRef) + p.printSpaceBeforeIdentifier() + p.printIdentifier(p.renamer.NameForSymbol(p.options.ToESMRef)) p.print("(") } // Call the wrapper - p.printSymbol(meta.WrapperRef) + p.printSpaceBeforeIdentifier() + p.printIdentifier(p.renamer.NameForSymbol(meta.WrapperRef)) p.print("()") // Return the namespace object if this is an ESM file @@ -1305,10 +1252,10 @@ func (p *printer) printRequireOrImportExpr( // Wrap this with a call to "__toCommonJS()" if this is an ESM file wrapWithTpCJS := record.Flags.Has(ast.WrapWithToCJS) if wrapWithTpCJS { - p.printSymbol(p.options.ToCommonJSRef) + p.printIdentifier(p.renamer.NameForSymbol(p.options.ToCommonJSRef)) p.print("(") } - p.printSymbol(meta.ExportsRef) + p.printIdentifier(p.renamer.NameForSymbol(meta.ExportsRef)) if wrapWithTpCJS { p.print(")") } @@ -1359,11 +1306,13 @@ func (p *printer) printDotThenSuffix() { } } -func (p *printer) printUndefined(level js_ast.L) { +func (p *printer) printUndefined(loc logger.Loc, level js_ast.L) { if level >= js_ast.LPrefix { + p.addSourceMapping(loc) p.print("(void 0)") } else { p.printSpaceBeforeIdentifier() + p.addSourceMapping(loc) p.print("void 0") p.prevNumEnd = len(p.js) } @@ -1592,43 +1541,51 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } } - p.addSourceMapping(expr.Loc) - switch e := expr.Data.(type) { case *js_ast.EMissing: + p.addSourceMapping(expr.Loc) case *js_ast.EUndefined: - p.printUndefined(level) + p.printUndefined(expr.Loc, level) case *js_ast.ESuper: p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("super") case *js_ast.ENull: p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("null") case *js_ast.EThis: p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("this") case *js_ast.ESpread: + p.addSourceMapping(expr.Loc) p.print("...") p.printExpr(e.Value, js_ast.LComma, 0) case *js_ast.ENewTarget: p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("new.target") case *js_ast.EImportMeta: p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("import.meta") case *js_ast.EMangledProp: - p.printQuotedUTF8(p.renamer.NameForSymbol(e.Ref), true) + name := p.mangledPropName(e.Ref) + p.addSourceMappingForName(expr.Loc, name, e.Ref) + p.printQuotedUTF8(name, true) case *js_ast.EJSXElement: // Start the opening tag + p.addSourceMapping(expr.Loc) p.print("<") p.printJSXTag(e.TagOrNil) @@ -1644,10 +1601,12 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } p.printSpaceBeforeIdentifier() - p.addSourceMapping(property.Key.Loc) if mangled, ok := property.Key.Data.(*js_ast.EMangledProp); ok { - p.printSymbol(mangled.Ref) + name := p.mangledPropName(mangled.Ref) + p.addSourceMappingForName(property.Key.Loc, name, mangled.Ref) + p.printIdentifier(name) } else { + p.addSourceMapping(property.Key.Loc) p.print(helpers.UTF16ToString(property.Key.Data.(*js_ast.EString).Value)) } @@ -1738,24 +1697,41 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } if hasPureComment { + p.addSourceMapping(expr.Loc) p.print("/* @__PURE__ */ ") } p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("new") p.printSpace() p.printExpr(e.Target, js_ast.LNew, forbidCall) // Omit the "()" when minifying, but only when safe to do so if !p.options.MinifyWhitespace || len(e.Args) > 0 || level >= js_ast.LPostfix { + isMultiLine := e.IsMultiLine && len(e.Args) > 0 && !p.options.MinifyWhitespace p.print("(") + if isMultiLine { + p.options.Indent++ + } for i, arg := range e.Args { - if i != 0 { + if isMultiLine { + if i != 0 { + p.print(",") + } + p.printNewline() + p.printIndent() + } else if i != 0 { p.print(",") p.printSpace() } p.printExpr(arg, js_ast.LComma, 0) } + if isMultiLine { + p.options.Indent-- + p.printNewline() + p.printIndent() + } if e.CloseParenLoc.Start > expr.Loc.Start { p.addSourceMapping(e.CloseParenLoc) } @@ -1821,6 +1797,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla if hasPureComment { wasStmtStart := p.stmtStart == len(p.js) wasExportDefaultStart := p.exportDefaultStart == len(p.js) + p.addSourceMapping(expr.Loc) p.print("/* @__PURE__ */ ") if wasStmtStart { p.stmtStart = len(p.js) @@ -1847,23 +1824,41 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla if e.OptionalChain == js_ast.OptionalChainStart { p.print("?.") } + + isMultiLine := e.IsMultiLine && len(e.Args) > 0 && !p.options.MinifyWhitespace p.print("(") + if isMultiLine { + p.options.Indent++ + } for i, arg := range e.Args { - if i != 0 { + if isMultiLine { + if i != 0 { + p.print(",") + } + p.printNewline() + p.printIndent() + } else if i != 0 { p.print(",") p.printSpace() } p.printExpr(arg, js_ast.LComma, 0) } + if isMultiLine { + p.options.Indent-- + p.printNewline() + p.printIndent() + } if e.CloseParenLoc.Start > expr.Loc.Start { p.addSourceMapping(e.CloseParenLoc) } p.print(")") + if wrap { p.print(")") } case *js_ast.ERequireString: + p.addSourceMapping(expr.Loc) p.printRequireOrImportExpr(e.ImportRecordIndex, nil, level, flags) case *js_ast.ERequireResolveString: @@ -1872,6 +1867,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla p.print("(") } p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("require.resolve(") p.printQuotedUTF8(p.importRecords[e.ImportRecordIndex].Path.Text, true /* allowBacktick */) p.print(")") @@ -1884,6 +1880,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla if !p.options.MinifyWhitespace { leadingInteriorComments = e.LeadingInteriorComments } + p.addSourceMapping(expr.Loc) p.printRequireOrImportExpr(e.ImportRecordIndex, leadingInteriorComments, level, flags) case *js_ast.EImportCall: @@ -1896,6 +1893,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla p.print("(") } p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("import(") if len(leadingInteriorComments) > 0 { p.printNewline() @@ -2029,17 +2027,20 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla if e.OptionalChain != js_ast.OptionalChainStart { p.print(".") } - p.addSourceMapping(e.Index.Loc) - p.printSymbol(index.Ref) + name := p.renamer.NameForSymbol(index.Ref) + p.addSourceMappingForName(e.Index.Loc, name, index.Ref) + p.printIdentifier(name) case *js_ast.EMangledProp: - if name := p.renamer.NameForSymbol(index.Ref); p.canPrintIdentifier(name) { + if name := p.mangledPropName(index.Ref); p.canPrintIdentifier(name) { if e.OptionalChain != js_ast.OptionalChainStart { p.print(".") } + p.addSourceMappingForName(e.Index.Loc, name, index.Ref) p.printIdentifier(name) } else { p.print("[") + p.addSourceMapping(e.Index.Loc) p.printQuotedUTF8(name, true /* allowBacktick */) p.print("]") } @@ -2080,12 +2081,18 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla p.print("(") } if e.IsAsync { + p.addSourceMapping(expr.Loc) p.printSpaceBeforeIdentifier() p.print("async") p.printSpace() } - p.printFnArgs(e.Args, e.HasRestArg, true /* isArrow */) + p.printFnArgs(e.Args, fnArgsOpts{ + openParenLoc: expr.Loc, + addMappingForOpenParenLoc: !e.IsAsync, + hasRestArg: e.HasRestArg, + isArrow: true, + }) p.printSpace() p.print("=>") p.printSpace() @@ -2112,6 +2119,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla p.print("(") } p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) if e.Fn.IsAsync { p.print("async ") } @@ -2121,7 +2129,10 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla p.printSpace() } if e.Fn.Name != nil { - p.printSymbol(e.Fn.Name.Ref) + p.printSpaceBeforeIdentifier() + name := p.renamer.NameForSymbol(e.Fn.Name.Ref) + p.addSourceMappingForName(e.Fn.Name.Loc, name, e.Fn.Name.Ref) + p.printIdentifier(name) } p.printFn(e.Fn) if wrap { @@ -2135,11 +2146,13 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla p.print("(") } p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("class") if e.Class.Name != nil { p.print(" ") - p.addSourceMapping(e.Class.Name.Loc) - p.printSymbol(e.Class.Name.Ref) + name := p.renamer.NameForSymbol(e.Class.Name.Ref) + p.addSourceMappingForName(e.Class.Name.Loc, name, e.Class.Name.Ref) + p.printIdentifier(name) } p.printClass(e.Class) if wrap { @@ -2147,6 +2160,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } case *js_ast.EArray: + p.addSourceMapping(expr.Loc) p.print("[") if len(e.Items) > 0 { if !e.IsSingleLine { @@ -2190,6 +2204,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla if wrap { p.print("(") } + p.addSourceMapping(expr.Loc) p.print("{") if len(e.Properties) != 0 { if !e.IsSingleLine { @@ -2226,6 +2241,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } case *js_ast.EBoolean: + p.addSourceMapping(expr.Loc) if p.options.MinifySyntax { if level >= js_ast.LPrefix { if e.Value { @@ -2250,6 +2266,8 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } case *js_ast.EString: + p.addSourceMapping(expr.Loc) + // If this was originally a template literal, print it as one as long as we're not minifying if e.PreferTemplate && !p.options.MinifySyntax && !p.options.UnsupportedFeatures.Has(compat.TemplateLiteral) { p.print("`") @@ -2263,6 +2281,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla case *js_ast.ETemplate: // Convert no-substitution template literals into strings if it's smaller if p.options.MinifySyntax && e.TagOrNil.Data == nil && len(e.Parts) == 0 { + p.addSourceMapping(expr.Loc) p.printQuotedUTF16(e.HeadCooked, true /* allowBacktick */) return } @@ -2276,6 +2295,8 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } else { p.printExpr(e.TagOrNil, js_ast.LPostfix, isCallTargetOrTemplateTag) } + } else { + p.addSourceMapping(expr.Loc) } p.print("`") if e.TagOrNil.Data != nil { @@ -2299,12 +2320,14 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla buffer := p.js n := len(buffer) + // Avoid forming a single-line comment or " 0 { - // Avoid forming a single-line comment or "= 7 && strings.EqualFold(e.Value[:7], "/script")) { p.print(" ") } } + + p.addSourceMapping(expr.Loc) p.print(e.Value) // Need a space before the next identifier to avoid it turning into flags @@ -2321,10 +2344,12 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla case *js_ast.EBigInt: p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print(e.Value) p.print("n") case *js_ast.ENumber: + p.addSourceMapping(expr.Loc) p.printNumber(e.Value, level) case *js_ast.EIdentifier: @@ -2337,6 +2362,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } p.printSpaceBeforeIdentifier() + p.addSourceMappingForName(expr.Loc, name, e.Ref) p.printIdentifier(name) if wrap { @@ -2349,7 +2375,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla symbol := p.symbols.Get(ref) if symbol.ImportItemStatus == js_ast.ImportItemMissing { - p.printUndefined(level) + p.printUndefined(expr.Loc, level) } else if symbol.NamespaceAlias != nil { wrap := p.callTarget == e && e.WasOriginallyIdentifier if wrap { @@ -2359,13 +2385,17 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla p.print("(0, ") } } - p.printSymbol(symbol.NamespaceAlias.NamespaceRef) + p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) + p.printIdentifier(p.renamer.NameForSymbol(symbol.NamespaceAlias.NamespaceRef)) alias := symbol.NamespaceAlias.Alias if !e.PreferQuotedKey && p.canPrintIdentifier(alias) { p.print(".") + p.addSourceMappingForName(expr.Loc, alias, ref) p.printIdentifier(alias) } else { p.print("[") + p.addSourceMappingForName(expr.Loc, alias, ref) p.printQuotedUTF8(alias, true /* allowBacktick */) p.print("]") } @@ -2376,7 +2406,10 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla // Handle inlined constants p.printExpr(js_ast.ConstValueToExpr(expr.Loc, value), level, flags) } else { - p.printSymbol(e.Ref) + p.printSpaceBeforeIdentifier() + name := p.renamer.NameForSymbol(ref) + p.addSourceMappingForName(expr.Loc, name, ref) + p.printIdentifier(name) } case *js_ast.EAwait: @@ -2387,6 +2420,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("await") p.printSpace() p.printExpr(e.Value, js_ast.LPrefix-1, 0) @@ -2403,6 +2437,7 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla } p.printSpaceBeforeIdentifier() + p.addSourceMapping(expr.Loc) p.print("yield") if e.ValueOrNil.Data != nil { @@ -2431,10 +2466,16 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla if entry.IsKeyword { p.printSpaceBeforeIdentifier() + if e.Op.IsPrefix() { + p.addSourceMapping(expr.Loc) + } p.print(entry.Text) p.printSpace() } else { p.printSpaceBeforeOperator(e.Op) + if e.Op.IsPrefix() { + p.addSourceMapping(expr.Loc) + } p.print(entry.Text) p.prevOp = e.Op p.prevOpEnd = len(p.js) @@ -2531,8 +2572,9 @@ func (p *printer) printExpr(expr js_ast.Expr, level js_ast.L, flags printExprFla // Special-case "#foo in bar" if private, ok := e.Left.Data.(*js_ast.EPrivateIdentifier); ok && e.Op == js_ast.BinOpIn { - p.addSourceMapping(e.Left.Loc) - p.printSymbol(private.Ref) + name := p.renamer.NameForSymbol(private.Ref) + p.addSourceMappingForName(e.Left.Loc, name, private.Ref) + p.printIdentifier(name) } else if e.Op == js_ast.BinOpComma { // The result of the left operand of the comma operator is unused p.printExpr(e.Left, leftLevel, (flags&forbidIn)|exprResultIsUnused|parentWasUnaryOrBinary) @@ -2743,8 +2785,15 @@ func (p *printer) printNonNegativeFloat(absValue float64) { } } - // Numbers in this range can potentially be printed with one fewer byte as hex - if p.options.MinifyWhitespace && absValue >= 1_000_000_000_000 && absValue <= 0xFFFF_FFFF_FFFF_FFFF { + // Numbers in this range can potentially be printed with one fewer byte as + // hex. This compares against 0xFFFF_FFFF_FFFF_F800 instead of comparing + // against 0xFFFF_FFFF_FFFF_FFFF because 0xFFFF_FFFF_FFFF_FFFF when converted + // to float64 rounds up to 0x1_0000_0000_0000_0180, which can no longer fit + // into uint64. In Go, the result of converting float64 to uint64 outside of + // the uint64 range is implementation-dependent and is different on amd64 vs. + // arm64. The float64 value 0xFFFF_FFFF_FFFF_F800 is the biggest value that + // is below the float64 value 0x1_0000_0000_0000_0180, so we use that instead. + if p.options.MinifyWhitespace && absValue >= 1_000_000_000_000 && absValue <= 0xFFFF_FFFF_FFFF_F800 { if asInt := uint64(absValue); absValue == float64(asInt) { if hex := strconv.FormatUint(asInt, 16); 2+len(hex) < len(result) { result = append(append(result[:0], '0', 'x'), hex...) @@ -2973,6 +3022,7 @@ func (p *printer) printIndentedComment(text string) { func (p *printer) printPath(importRecordIndex uint32) { record := p.importRecords[importRecordIndex] + p.addSourceMapping(record.Range.Loc) p.printQuotedUTF8(record.Path.Text, false /* allowBacktick */) // Just omit import assertions if they aren't supported @@ -3044,8 +3094,6 @@ const ( ) func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { - p.addSourceMapping(stmt.Loc) - switch s := stmt.Data.(type) { case *js_ast.SComment: text := s.Text @@ -3066,9 +3114,11 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { } } + p.addSourceMapping(stmt.Loc) p.printIndentedComment(text) case *js_ast.SFunction: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() if s.IsExport { @@ -3082,28 +3132,35 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.print("*") p.printSpace() } - p.printSymbol(s.Fn.Name.Ref) + p.printSpaceBeforeIdentifier() + name := p.renamer.NameForSymbol(s.Fn.Name.Ref) + p.addSourceMappingForName(s.Fn.Name.Loc, name, s.Fn.Name.Ref) + p.printIdentifier(name) p.printFn(s.Fn) p.printNewline() case *js_ast.SClass: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() if s.IsExport { p.print("export ") } p.print("class ") - p.addSourceMapping(s.Class.Name.Loc) - p.printSymbol(s.Class.Name.Ref) + name := p.renamer.NameForSymbol(s.Class.Name.Ref) + p.addSourceMappingForName(s.Class.Name.Loc, name, s.Class.Name.Ref) + p.printIdentifier(name) p.printClass(s.Class) p.printNewline() case *js_ast.SEmpty: + p.addSourceMapping(stmt.Loc) p.printIndent() p.print(";") p.printNewline() case *js_ast.SExportDefault: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("export default") @@ -3129,7 +3186,10 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printSpace() } if s2.Fn.Name != nil { - p.printSymbol(s2.Fn.Name.Ref) + p.printSpaceBeforeIdentifier() + name := p.renamer.NameForSymbol(s2.Fn.Name.Ref) + p.addSourceMappingForName(s2.Fn.Name.Loc, name, s2.Fn.Name.Ref) + p.printIdentifier(name) } p.printFn(s2.Fn) p.printNewline() @@ -3139,8 +3199,9 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.print("class") if s2.Class.Name != nil { p.print(" ") - p.addSourceMapping(s2.Class.Name.Loc) - p.printSymbol(s2.Class.Name.Ref) + name := p.renamer.NameForSymbol(s2.Class.Name.Ref) + p.addSourceMappingForName(s2.Class.Name.Loc, name, s2.Class.Name.Ref) + p.printIdentifier(name) } p.printClass(s2.Class) p.printNewline() @@ -3150,6 +3211,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { } case *js_ast.SExportStar: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("export") @@ -3169,6 +3231,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printSemicolonAfterStatement() case *js_ast.SExportClause: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("export") @@ -3192,10 +3255,12 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { } name := p.renamer.NameForSymbol(item.Name.Ref) + p.addSourceMappingForName(item.Name.Loc, name, item.Name.Ref) p.printIdentifier(name) if name != item.Alias { p.print(" as") p.printSpace() + p.addSourceMapping(item.AliasLoc) p.printClauseAlias(item.Alias) } } @@ -3212,6 +3277,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printSemicolonAfterStatement() case *js_ast.SExportFrom: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("export") @@ -3260,6 +3326,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printSemicolonAfterStatement() case *js_ast.SLocal: + p.addSourceMapping(stmt.Loc) switch s.Kind { case js_ast.LocalConst: p.printDeclStmt(s.IsExport, "const", s.Decls) @@ -3270,10 +3337,12 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { } case *js_ast.SIf: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printIf(s) case *js_ast.SDoWhile: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("do") @@ -3297,6 +3366,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printSemicolonAfterStatement() case *js_ast.SForIn: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("for") @@ -3312,6 +3382,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printBody(s.Body) case *js_ast.SForOf: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("for") @@ -3335,6 +3406,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printBody(s.Body) case *js_ast.SWhile: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("while") @@ -3345,6 +3417,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printBody(s.Body) case *js_ast.SWith: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("with") @@ -3355,12 +3428,21 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printBody(s.Body) case *js_ast.SLabel: - p.printIndent() - p.printSymbol(s.Name.Ref) + // Avoid printing a source mapping that masks the one from the label + if !p.options.MinifyWhitespace && p.options.Indent > 0 { + p.addSourceMapping(stmt.Loc) + p.printIndent() + } + + p.printSpaceBeforeIdentifier() + name := p.renamer.NameForSymbol(s.Name.Ref) + p.addSourceMappingForName(s.Name.Loc, name, s.Name.Ref) + p.printIdentifier(name) p.print(":") p.printBody(s.Stmt) case *js_ast.STry: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("try") @@ -3407,6 +3489,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { } } + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("for") @@ -3429,6 +3512,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printBody(s.Body) case *js_ast.SSwitch: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("switch") @@ -3481,13 +3565,17 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { case *js_ast.SImport: itemCount := 0 + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("import") p.printSpace() if s.DefaultName != nil { - p.printSymbol(s.DefaultName.Ref) + p.printSpaceBeforeIdentifier() + name := p.renamer.NameForSymbol(s.DefaultName.Ref) + p.addSourceMappingForName(s.DefaultName.Loc, name, s.DefaultName.Ref) + p.printIdentifier(name) itemCount++ } @@ -3514,12 +3602,15 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printIndent() } + p.addSourceMapping(item.AliasLoc) p.printClauseAlias(item.Alias) + name := p.renamer.NameForSymbol(item.Name.Ref) if name != item.Alias { p.printSpace() p.printSpaceBeforeIdentifier() p.print("as ") + p.addSourceMappingForName(item.Name.Loc, name, item.Name.Ref) p.printIdentifier(name) } } @@ -3545,7 +3636,9 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.print("*") p.printSpace() p.print("as ") - p.printSymbol(s.NamespaceRef) + name := p.renamer.NameForSymbol(s.NamespaceRef) + p.addSourceMappingForName(*s.StarNameLoc, name, s.NamespaceRef) + p.printIdentifier(name) itemCount++ } @@ -3560,43 +3653,53 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printSemicolonAfterStatement() case *js_ast.SBlock: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printBlock(stmt.Loc, *s) p.printNewline() case *js_ast.SDebugger: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("debugger") p.printSemicolonAfterStatement() case *js_ast.SDirective: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.printQuotedUTF16(s.Value, false /* allowBacktick */) p.printSemicolonAfterStatement() case *js_ast.SBreak: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("break") if s.Label != nil { p.print(" ") - p.printSymbol(s.Label.Ref) + name := p.renamer.NameForSymbol(s.Label.Ref) + p.addSourceMappingForName(s.Label.Loc, name, s.Label.Ref) + p.printIdentifier(name) } p.printSemicolonAfterStatement() case *js_ast.SContinue: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("continue") if s.Label != nil { p.print(" ") - p.printSymbol(s.Label.Ref) + name := p.renamer.NameForSymbol(s.Label.Ref) + p.addSourceMappingForName(s.Label.Loc, name, s.Label.Ref) + p.printIdentifier(name) } p.printSemicolonAfterStatement() case *js_ast.SReturn: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("return") @@ -3607,6 +3710,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { p.printSemicolonAfterStatement() case *js_ast.SThrow: + p.addSourceMapping(stmt.Loc) p.printIndent() p.printSpaceBeforeIdentifier() p.print("throw") @@ -3624,6 +3728,7 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { // If this statement is not in a block, then we still need to emit something if (flags & canOmitStatement) == 0 { // "if (x) empty();" => "if (x) ;" + p.addSourceMapping(stmt.Loc) p.printIndent() p.print(";") p.printNewline() @@ -3634,7 +3739,13 @@ func (p *printer) printStmt(stmt js_ast.Stmt, flags printStmtFlags) { } } - p.printIndent() + // Avoid printing a source mapping when the expression would print one in + // the same spot. We don't want to accidentally mask the mapping it emits. + if !p.options.MinifyWhitespace && p.options.Indent > 0 { + p.addSourceMapping(stmt.Loc) + p.printIndent() + } + p.stmtStart = len(p.js) p.printExpr(value, js_ast.LLowest, exprResultIsUnused) p.printSemicolonAfterStatement() @@ -3653,6 +3764,9 @@ type Options struct { // Cross-module inlining of detected inlinable constants is also done during printing ConstValues map[js_ast.Ref]js_ast.ConstValue + // Property mangling results go here + MangledProps map[js_ast.Ref]string + // This will be present if the input file had a source map. In that case we // want to map all the way back to the original input file(s). InputSourceMap *sourcemap.SourceMap @@ -3708,7 +3822,7 @@ func Print(tree js_ast.AST, symbols js_ast.SymbolMap, r renamer.Renamer, options prevOpEnd: -1, prevNumEnd: -1, prevRegExpEnd: -1, - builder: sourcemap.MakeChunkBuilder(options.InputSourceMap, options.LineOffsetTables), + builder: sourcemap.MakeChunkBuilder(options.InputSourceMap, options.LineOffsetTables, options.ASCIIOnly), } p.isUnbound = func(ref js_ast.Ref) bool { diff --git a/vendor/github.com/evanw/esbuild/internal/logger/logger.go b/vendor/github.com/evanw/esbuild/internal/logger/logger.go index 92d86fe9b..2b2d8edf5 100644 --- a/vendor/github.com/evanw/esbuild/internal/logger/logger.go +++ b/vendor/github.com/evanw/esbuild/internal/logger/logger.go @@ -388,6 +388,20 @@ func (s *Source) RangeOfString(loc Loc) Range { } } + if quote == '`' { + // Search for the matching quote character + for i := 1; i < len(text); i++ { + c := text[i] + if c == quote { + return Range{Loc: loc, Len: int32(i + 1)} + } else if c == '\\' { + i += 1 + } else if c == '$' && i+1 < len(text) && text[i+1] == '{' { + break // Only return the range for no-substitution template literals + } + } + } + return Range{Loc: loc, Len: 0} } diff --git a/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go b/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go index cfbf9490f..3d0ed42e1 100644 --- a/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go +++ b/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go @@ -16,7 +16,6 @@ import ( "github.com/evanw/esbuild/internal/fs" "github.com/evanw/esbuild/internal/helpers" "github.com/evanw/esbuild/internal/js_ast" - "github.com/evanw/esbuild/internal/js_printer" "github.com/evanw/esbuild/internal/logger" ) @@ -102,8 +101,10 @@ type ResolveResult struct { PluginData interface{} // If not empty, these should override the default values - JSXFactory []string // Default if empty: "React.createElement" - JSXFragment []string // Default if empty: "React.Fragment" + JSXFactory []string // Default if empty: "React.createElement" + JSXFragment []string // Default if empty: "React.Fragment" + JSXImportSource string // Default if empty: "react" + JSX config.TSJSX DifferentCase *fs.DifferentCase @@ -627,6 +628,8 @@ func (r resolverQuery) finalizeResolve(result *ResolveResult) { } else { result.JSXFactory = dirInfo.enclosingTSConfigJSON.JSXFactory result.JSXFragment = dirInfo.enclosingTSConfigJSON.JSXFragmentFactory + result.JSX = dirInfo.enclosingTSConfigJSON.JSX + result.JSXImportSource = dirInfo.enclosingTSConfigJSON.JSXImportSource result.UseDefineForClassFieldsTS = dirInfo.enclosingTSConfigJSON.UseDefineForClassFields result.UnusedImportFlagsTS = config.UnusedImportFlagsFromTsconfigValues( dirInfo.enclosingTSConfigJSON.PreserveImportsNotUsedAsValues, @@ -934,6 +937,16 @@ func (r resolverQuery) parseTSConfig(file string, visited map[string]bool) (*TSC filesToCheck := []string{r.fs.Join(join, "tsconfig.json"), join, join + ".json"} for _, fileToCheck := range filesToCheck { base, err := r.parseTSConfig(fileToCheck, visited) + + // Explicitly ignore matches if they are directories instead of files + if err != nil && err != syscall.ENOENT { + if entries, _, dirErr := r.fs.ReadDirectory(r.fs.Dir(fileToCheck)); dirErr == nil { + if entry, _ := entries.Get(r.fs.Base(fileToCheck)); entry != nil && entry.Kind(r.fs) == fs.DirEntry { + continue + } + } + } + if err == nil { return base } else if err == syscall.ENOENT { @@ -963,19 +976,34 @@ func (r resolverQuery) parseTSConfig(file string, visited map[string]bool) (*TSC if !r.fs.IsAbs(extends) { extendsFile = r.fs.Join(fileDir, extends) } - for _, fileToCheck := range []string{extendsFile, extendsFile + ".json"} { - base, err := r.parseTSConfig(fileToCheck, visited) - if err == nil { - return base - } else if err == syscall.ENOENT { - continue - } else if err == errParseErrorImportCycle { + base, err := r.parseTSConfig(extendsFile, visited) + + // TypeScript's handling of "extends" has some specific edge cases. We + // must only try adding ".json" if it's not already present, which is + // unlike how node path resolution works. We also need to explicitly + // ignore matches if they are directories instead of files. Some users + // name directories the same name as their config files. + if err != nil && !strings.HasSuffix(extendsFile, ".json") { + if entries, _, dirErr := r.fs.ReadDirectory(r.fs.Dir(extendsFile)); dirErr == nil { + extendsBase := r.fs.Base(extendsFile) + if entry, _ := entries.Get(extendsBase); entry == nil || entry.Kind(r.fs) != fs.FileEntry { + if entry, _ := entries.Get(extendsBase + ".json"); entry != nil && entry.Kind(r.fs) == fs.FileEntry { + base, err = r.parseTSConfig(extendsFile+".json", visited) + } + } + } + } + + if err == nil { + return base + } else if err != syscall.ENOENT { + if err == errParseErrorImportCycle { r.log.AddID(logger.MsgID_TsconfigJSON_Cycle, logger.Warning, &tracker, extendsRange, fmt.Sprintf("Base config file %q forms cycle", extends)) } else if err != errParseErrorAlreadyLogged { r.log.AddError(&tracker, extendsRange, fmt.Sprintf("Cannot read file %q: %s", - r.PrettyPath(logger.Path{Text: fileToCheck, Namespace: "file"}), err.Error())) + r.PrettyPath(logger.Path{Text: extendsFile, Namespace: "file"}), err.Error())) } return nil } @@ -1151,9 +1179,9 @@ func (r resolverQuery) dirInfoUncached(path string) *dirInfo { return info } -// https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#resolution-customization-with-modulesuffixes -// "Note that the empty string '' in moduleSuffixes is necessary for TypeScript to -// also look-up ./foo.ts. In a sense, the default value for moduleSuffixes is ['']." +// From: https://devblogs.microsoft.com/typescript/announcing-typescript-4-7-beta/#resolution-customization-with-modulesuffixes +// Note that the empty string "" in moduleSuffixes is necessary for TypeScript to +// also look-up ./foo.ts. In a sense, the default value for moduleSuffixes is [""]. var defaultModuleSuffixes = []string{""} var rewrittenFileExtensions = map[string][]string{ @@ -2028,7 +2056,7 @@ func (r resolverQuery) finalizeImportsExportsResult( // Provide an inline suggestion message with the correct import path actualImportPath := path.Join(esmPackageName, subpath) - r.debugMeta.suggestionText = string(js_printer.QuoteForJSON(actualImportPath, false)) + r.debugMeta.suggestionText = string(helpers.QuoteForJSON(actualImportPath, false)) r.debugMeta.suggestionMessage = fmt.Sprintf("Import from %q to get the file %q:", actualImportPath, r.PrettyPath(absolute.Primary)) } @@ -2118,7 +2146,7 @@ func IsPackagePath(path string) bool { // This list can be obtained with the following command: // -// node --experimental-wasi-unstable-preview1 -p "[...require('module').builtinModules].join('\n')" +// node --experimental-wasi-unstable-preview1 -p "[...require('module').builtinModules].join('\n')" // // Be sure to use the *LATEST* version of node when updating this list! var BuiltInNodeModules = map[string]bool{ diff --git a/vendor/github.com/evanw/esbuild/internal/resolver/tsconfig_json.go b/vendor/github.com/evanw/esbuild/internal/resolver/tsconfig_json.go index ff2292b0f..a47eadb1e 100644 --- a/vendor/github.com/evanw/esbuild/internal/resolver/tsconfig_json.go +++ b/vendor/github.com/evanw/esbuild/internal/resolver/tsconfig_json.go @@ -38,8 +38,10 @@ type TSConfigJSON struct { TSTarget *config.TSTarget TSStrict *config.TSAlwaysStrict TSAlwaysStrict *config.TSAlwaysStrict + JSX config.TSJSX JSXFactory []string JSXFragmentFactory []string + JSXImportSource string ModuleSuffixes []string UseDefineForClassFields config.MaybeBool PreserveImportsNotUsedAsValues bool @@ -105,6 +107,24 @@ func ParseTSConfigJSON( } } + // Parse "jsx" + if valueJSON, _, ok := getProperty(compilerOptionsJSON, "jsx"); ok { + if value, ok := getString(valueJSON); ok { + switch strings.ToLower(value) { + case "none": + result.JSX = config.TSJSXNone + case "preserve", "react-native": + result.JSX = config.TSJSXPreserve + case "react": + result.JSX = config.TSJSXReact + case "react-jsx": + result.JSX = config.TSJSXReactJSX + case "react-jsxdev": + result.JSX = config.TSJSXReactJSXDev + } + } + } + // Parse "jsxFactory" if valueJSON, _, ok := getProperty(compilerOptionsJSON, "jsxFactory"); ok { if value, ok := getString(valueJSON); ok { @@ -119,6 +139,13 @@ func ParseTSConfigJSON( } } + // Parse "jsxImportSource" + if valueJSON, _, ok := getProperty(compilerOptionsJSON, "jsxImportSource"); ok { + if value, ok := getString(valueJSON); ok { + result.JSXImportSource = value + } + } + // Parse "moduleSuffixes" if valueJSON, _, ok := getProperty(compilerOptionsJSON, "moduleSuffixes"); ok { if value, ok := valueJSON.Data.(*js_ast.EArray); ok { diff --git a/vendor/github.com/evanw/esbuild/internal/sourcemap/sourcemap.go b/vendor/github.com/evanw/esbuild/internal/sourcemap/sourcemap.go index d0c3f8ace..93effc210 100644 --- a/vendor/github.com/evanw/esbuild/internal/sourcemap/sourcemap.go +++ b/vendor/github.com/evanw/esbuild/internal/sourcemap/sourcemap.go @@ -4,6 +4,7 @@ import ( "bytes" "unicode/utf8" + "github.com/evanw/esbuild/internal/ast" "github.com/evanw/esbuild/internal/helpers" "github.com/evanw/esbuild/internal/logger" ) @@ -12,15 +13,17 @@ type Mapping struct { GeneratedLine int32 // 0-based GeneratedColumn int32 // 0-based count of UTF-16 code units - SourceIndex int32 // 0-based - OriginalLine int32 // 0-based - OriginalColumn int32 // 0-based count of UTF-16 code units + SourceIndex int32 // 0-based + OriginalLine int32 // 0-based + OriginalColumn int32 // 0-based count of UTF-16 code units + OriginalName ast.Index32 // 0-based, optional } type SourceMap struct { Sources []string SourcesContent []SourceContent Mappings []Mapping + Names []string } type SourceContent struct { @@ -73,13 +76,12 @@ var base64 = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456 // bit. The continuation bit tells us whether there are more digits in this // value following this digit. // -// Continuation -// | Sign -// | | -// V V -// 101011 -// -func EncodeVLQ(value int) []byte { +// Continuation +// | Sign +// | | +// V V +// 101011 +func encodeVLQ(encoded []byte, value int) []byte { var vlq int if value < 0 { vlq = ((-value) << 1) | 1 @@ -87,13 +89,13 @@ func EncodeVLQ(value int) []byte { vlq = value << 1 } - // Handle the common case up front without allocations + // Handle the common case if (vlq >> 5) == 0 { digit := vlq & 31 - return base64[digit : digit+1] + encoded = append(encoded, base64[digit]) + return encoded } - encoded := []byte{} for { digit := vlq & 31 vlq >>= 5 @@ -144,7 +146,7 @@ func DecodeVLQ(encoded []byte, start int) (int, int) { return value, start } -func DecodeVLQUTF16(encoded []uint16) (int, int, bool) { +func DecodeVLQUTF16(encoded []uint16) (int32, int, bool) { n := len(encoded) if n == 0 { return 0, 0, false @@ -153,12 +155,12 @@ func DecodeVLQUTF16(encoded []uint16) (int, int, bool) { // Scan over the input current := 0 shift := 0 - vlq := 0 + var vlq int32 for { if current >= n { return 0, 0, false } - index := bytes.IndexByte(base64, byte(encoded[current])) + index := int32(bytes.IndexByte(base64, byte(encoded[current]))) if index < 0 { return 0, 0, false } @@ -318,6 +320,13 @@ func (pieces SourceMapPieces) Finalize(shifts []SourceMapShift) []byte { _, current = DecodeVLQ(pieces.Mappings, current) // The original line _, current = DecodeVLQ(pieces.Mappings, current) // The original column + // Skip over the original name + if current < len(pieces.Mappings) { + if c := pieces.Mappings[current]; c != ',' && c != ';' { + _, current = DecodeVLQ(pieces.Mappings, current) + } + } + // Skip a trailing comma if current < len(pieces.Mappings) && pieces.Mappings[current] == ',' { current++ @@ -351,7 +360,7 @@ func (pieces SourceMapPieces) Finalize(shifts []SourceMapShift) []byte { panic("Unexpected line change when shifting source maps") } shiftColumnDelta := shift.After.Columns - shift.Before.Columns - j.AddBytes(EncodeVLQ(generatedColumnDelta + shiftColumnDelta - prevShiftColumnDelta)) + j.AddBytes(encodeVLQ(nil, generatedColumnDelta+shiftColumnDelta-prevShiftColumnDelta)) prevShiftColumnDelta = shiftColumnDelta // Finally, start the next run after the end of this generated column offset @@ -378,6 +387,8 @@ type SourceMapState struct { SourceIndex int OriginalLine int OriginalColumn int + OriginalName int + HasOriginalName bool } // Source map chunks are computed in parallel for speed. Each chunk is relative @@ -388,7 +399,7 @@ type SourceMapState struct { // After all chunks are computed, they are joined together in a second pass. // This rewrites the first mapping in each chunk to be relative to the end // state of the previous chunk. -func AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startState SourceMapState, sourceMap []byte) { +func AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startState SourceMapState, buffer MappingsBuffer) { // Handle line breaks in between this mapping and the previous one if startState.GeneratedLine != 0 { j.AddBytes(bytes.Repeat([]byte{';'}, startState.GeneratedLine)) @@ -397,12 +408,11 @@ func AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startS // Skip past any leading semicolons, which indicate line breaks semicolons := 0 - for sourceMap[semicolons] == ';' { + for buffer.Data[semicolons] == ';' { semicolons++ } if semicolons > 0 { - j.AddBytes(sourceMap[:semicolons]) - sourceMap = sourceMap[semicolons:] + j.AddBytes(buffer.Data[:semicolons]) prevEndState.GeneratedColumn = 0 startState.GeneratedColumn = 0 } @@ -410,11 +420,16 @@ func AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startS // Strip off the first mapping from the buffer. The first mapping should be // for the start of the original file (the printer always generates one for // the start of the file). - generatedColumn, i := DecodeVLQ(sourceMap, 0) - sourceIndex, i := DecodeVLQ(sourceMap, i) - originalLine, i := DecodeVLQ(sourceMap, i) - originalColumn, i := DecodeVLQ(sourceMap, i) - sourceMap = sourceMap[i:] + // + // Note that we do not want to strip off the original name, even though it + // could be a part of the first mapping. This will be handled using a special + // case below instead. Original names are optional and are often omitted, so + // we handle it uniformly by saving an index to the first original name, + // which may or may not be a part of the first mapping. + generatedColumn, i := DecodeVLQ(buffer.Data, semicolons) + sourceIndex, i := DecodeVLQ(buffer.Data, i) + originalLine, i := DecodeVLQ(buffer.Data, i) + originalColumn, i := DecodeVLQ(buffer.Data, i) // Rewrite the first mapping to be relative to the end state of the previous // chunk. We now know what the end state is because we're in the second pass @@ -423,35 +438,46 @@ func AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startS startState.GeneratedColumn += generatedColumn startState.OriginalLine += originalLine startState.OriginalColumn += originalColumn - j.AddBytes(appendMappingToBuffer(nil, j.LastByte(), prevEndState, startState)) + prevEndState.HasOriginalName = false // This is handled separately below + rewritten, _ := appendMappingToBuffer(nil, j.LastByte(), prevEndState, startState) + j.AddBytes(rewritten) + + // Next, if there's an original name, we need to rewrite that as well to be + // relative to that of the previous chunk. + if buffer.FirstNameOffset.IsValid() { + before := int(buffer.FirstNameOffset.GetIndex()) + originalName, after := DecodeVLQ(buffer.Data, before) + originalName += startState.OriginalName - prevEndState.OriginalName + j.AddBytes(buffer.Data[i:before]) + j.AddBytes(encodeVLQ(nil, originalName)) + j.AddBytes(buffer.Data[after:]) + return + } - // Then append everything after that without modification. - j.AddBytes(sourceMap) + // Otherwise, just append everything after that without modification + j.AddBytes(buffer.Data[i:]) } -func appendMappingToBuffer(buffer []byte, lastByte byte, prevState SourceMapState, currentState SourceMapState) []byte { +func appendMappingToBuffer(buffer []byte, lastByte byte, prevState SourceMapState, currentState SourceMapState) ([]byte, ast.Index32) { // Put commas in between mappings if lastByte != 0 && lastByte != ';' && lastByte != '"' { buffer = append(buffer, ',') } - // Record the generated column (the line is recorded using ';' elsewhere) - buffer = append(buffer, EncodeVLQ(currentState.GeneratedColumn-prevState.GeneratedColumn)...) - prevState.GeneratedColumn = currentState.GeneratedColumn - - // Record the generated source - buffer = append(buffer, EncodeVLQ(currentState.SourceIndex-prevState.SourceIndex)...) - prevState.SourceIndex = currentState.SourceIndex - - // Record the original line - buffer = append(buffer, EncodeVLQ(currentState.OriginalLine-prevState.OriginalLine)...) - prevState.OriginalLine = currentState.OriginalLine + // Record the mapping (note that the generated line is recorded using ';' elsewhere) + buffer = encodeVLQ(buffer, currentState.GeneratedColumn-prevState.GeneratedColumn) + buffer = encodeVLQ(buffer, currentState.SourceIndex-prevState.SourceIndex) + buffer = encodeVLQ(buffer, currentState.OriginalLine-prevState.OriginalLine) + buffer = encodeVLQ(buffer, currentState.OriginalColumn-prevState.OriginalColumn) - // Record the original column - buffer = append(buffer, EncodeVLQ(currentState.OriginalColumn-prevState.OriginalColumn)...) - prevState.OriginalColumn = currentState.OriginalColumn + // Record the optional original name + var nameOffset ast.Index32 + if currentState.HasOriginalName { + nameOffset = ast.MakeIndex32(uint32(len(buffer))) + buffer = encodeVLQ(buffer, currentState.OriginalName-prevState.OriginalName) + } - return buffer + return buffer, nameOffset } type LineOffsetTable struct { @@ -549,8 +575,14 @@ func GenerateLineOffsetTables(contents string, approximateLineCount int32) []Lin return lineOffsetTables } +type MappingsBuffer struct { + Data []byte + FirstNameOffset ast.Index32 +} + type Chunk struct { - Buffer []byte + Buffer MappingsBuffer + QuotedNames [][]byte // This end state will be used to rewrite the start of the following source // map chunk so that the delta-encoded VLQ numbers are preserved. @@ -567,12 +599,18 @@ type Chunk struct { type ChunkBuilder struct { inputSourceMap *SourceMap sourceMap []byte + quotedNames [][]byte + namesMap map[string]uint32 lineOffsetTables []LineOffsetTable + prevOriginalName string prevState SourceMapState lastGeneratedUpdate int generatedColumn int - prevLoc logger.Loc + prevGeneratedLen int + prevOriginalLoc logger.Loc + firstNameOffset ast.Index32 hasPrevState bool + asciiOnly bool // This is a workaround for a bug in the popular "source-map" library: // https://github.com/mozilla/source-map/issues/261. The library will @@ -586,11 +624,13 @@ type ChunkBuilder struct { coverLinesWithoutMappings bool } -func MakeChunkBuilder(inputSourceMap *SourceMap, lineOffsetTables []LineOffsetTable) ChunkBuilder { +func MakeChunkBuilder(inputSourceMap *SourceMap, lineOffsetTables []LineOffsetTable, asciiOnly bool) ChunkBuilder { return ChunkBuilder{ inputSourceMap: inputSourceMap, - prevLoc: logger.Loc{Start: -1}, + prevOriginalLoc: logger.Loc{Start: -1}, lineOffsetTables: lineOffsetTables, + asciiOnly: asciiOnly, + namesMap: make(map[string]uint32), // We automatically repeat the previous source mapping if we ever generate // a line that doesn't start with a mapping. This helps give files more @@ -607,11 +647,15 @@ func MakeChunkBuilder(inputSourceMap *SourceMap, lineOffsetTables []LineOffsetTa } } -func (b *ChunkBuilder) AddSourceMapping(loc logger.Loc, output []byte) { - if loc == b.prevLoc { +func (b *ChunkBuilder) AddSourceMapping(originalLoc logger.Loc, originalName string, output []byte) { + // Avoid generating duplicate mappings + if originalLoc == b.prevOriginalLoc && (b.prevGeneratedLen == len(output) || b.prevOriginalName == originalName) { return } - b.prevLoc = loc + + b.prevOriginalLoc = originalLoc + b.prevGeneratedLen = len(output) + b.prevOriginalName = originalName // Binary search to find the line lineOffsetTables := b.lineOffsetTables @@ -620,7 +664,7 @@ func (b *ChunkBuilder) AddSourceMapping(loc logger.Loc, output []byte) { for count > 0 { step := count / 2 i := originalLine + step - if lineOffsetTables[i].byteOffsetToStartOfLine <= loc.Start { + if lineOffsetTables[i].byteOffsetToStartOfLine <= originalLoc.Start { originalLine = i + 1 count = count - step - 1 } else { @@ -631,7 +675,7 @@ func (b *ChunkBuilder) AddSourceMapping(loc logger.Loc, output []byte) { // Use the line to compute the column line := &lineOffsetTables[originalLine] - originalColumn := int(loc.Start - line.byteOffsetToStartOfLine) + originalColumn := int(originalLoc.Start - line.byteOffsetToStartOfLine) if line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) { originalColumn = int(line.columnsForNonASCII[originalColumn-int(line.byteOffsetToFirstNonASCII)]) } @@ -650,7 +694,7 @@ func (b *ChunkBuilder) AddSourceMapping(loc logger.Loc, output []byte) { }) } - b.appendMapping(SourceMapState{ + b.appendMapping(originalName, SourceMapState{ GeneratedLine: b.prevState.GeneratedLine, GeneratedColumn: b.generatedColumn, OriginalLine: originalLine, @@ -671,7 +715,11 @@ func (b *ChunkBuilder) GenerateChunk(output []byte) Chunk { } } return Chunk{ - Buffer: b.sourceMap, + Buffer: MappingsBuffer{ + Data: b.sourceMap, + FirstNameOffset: b.firstNameOffset, + }, + QuotedNames: b.quotedNames, EndState: b.prevState, FinalGeneratedColumn: b.generatedColumn, ShouldIgnore: shouldIgnore, @@ -725,7 +773,7 @@ func (b *ChunkBuilder) updateGeneratedLineAndColumn(output []byte) { b.lastGeneratedUpdate = len(output) } -func (b *ChunkBuilder) appendMapping(currentState SourceMapState) { +func (b *ChunkBuilder) appendMapping(originalName string, currentState SourceMapState) { // If the input file had a source map, map all the way back to the original if b.inputSourceMap != nil { mapping := b.inputSourceMap.Find( @@ -740,6 +788,26 @@ func (b *ChunkBuilder) appendMapping(currentState SourceMapState) { currentState.SourceIndex = int(mapping.SourceIndex) currentState.OriginalLine = int(mapping.OriginalLine) currentState.OriginalColumn = int(mapping.OriginalColumn) + + // Map all the way back to the original name if present. Otherwise, keep + // the original name from esbuild, which corresponds to the name in the + // intermediate source code. This is important for tools that only emit + // a name mapping when the name is different than the original name. + if mapping.OriginalName.IsValid() { + originalName = b.inputSourceMap.Names[mapping.OriginalName.GetIndex()] + } + } + + // Optionally reference the original name + if originalName != "" { + i, ok := b.namesMap[originalName] + if !ok { + i = uint32(len(b.quotedNames)) + b.quotedNames = append(b.quotedNames, helpers.QuoteForJSON(originalName, b.asciiOnly)) + b.namesMap[originalName] = i + } + currentState.OriginalName = int(i) + currentState.HasOriginalName = true } b.appendMappingWithoutRemapping(currentState) @@ -751,7 +819,16 @@ func (b *ChunkBuilder) appendMappingWithoutRemapping(currentState SourceMapState lastByte = b.sourceMap[len(b.sourceMap)-1] } - b.sourceMap = appendMappingToBuffer(b.sourceMap, lastByte, b.prevState, currentState) + var nameOffset ast.Index32 + b.sourceMap, nameOffset = appendMappingToBuffer(b.sourceMap, lastByte, b.prevState, currentState) + prevOriginalName := b.prevState.OriginalName b.prevState = currentState + if !currentState.HasOriginalName { + // Revert the original name change if it's invalid + b.prevState.OriginalName = prevOriginalName + } else if !b.firstNameOffset.IsValid() { + // Keep track of the first name offset so we can jump right to it later + b.firstNameOffset = nameOffset + } b.hasPrevState = true } diff --git a/vendor/github.com/evanw/esbuild/pkg/api/api.go b/vendor/github.com/evanw/esbuild/pkg/api/api.go index fec8a2c41..5a7af90b3 100644 --- a/vendor/github.com/evanw/esbuild/pkg/api/api.go +++ b/vendor/github.com/evanw/esbuild/pkg/api/api.go @@ -5,7 +5,7 @@ // creating a child process, there is also an API for the command-line // interface itself: https://godoc.org/github.com/evanw/esbuild/pkg/cli. // -// Build API +// # Build API // // This function runs an end-to-end build operation. It takes an array of file // paths as entry points, parses them and all of their dependencies, and @@ -14,29 +14,29 @@ // // Example usage: // -// package main +// package main // -// import ( -// "os" +// import ( +// "os" // -// "github.com/evanw/esbuild/pkg/api" -// ) +// "github.com/evanw/esbuild/pkg/api" +// ) // -// func main() { -// result := api.Build(api.BuildOptions{ -// EntryPoints: []string{"input.js"}, -// Outfile: "output.js", -// Bundle: true, -// Write: true, -// LogLevel: api.LogLevelInfo, -// }) +// func main() { +// result := api.Build(api.BuildOptions{ +// EntryPoints: []string{"input.js"}, +// Outfile: "output.js", +// Bundle: true, +// Write: true, +// LogLevel: api.LogLevelInfo, +// }) // -// if len(result.Errors) > 0 { -// os.Exit(1) -// } -// } +// if len(result.Errors) > 0 { +// os.Exit(1) +// } +// } // -// Transform API +// # Transform API // // This function transforms a string of source code into JavaScript. It can be // used to minify JavaScript, convert TypeScript/JSX to JavaScript, or convert @@ -45,36 +45,35 @@ // // Example usage: // -// package main -// -// import ( -// "fmt" -// "os" +// package main // -// "github.com/evanw/esbuild/pkg/api" -// ) +// import ( +// "fmt" +// "os" // -// func main() { -// jsx := ` -// import * as React from 'react' -// import * as ReactDOM from 'react-dom' +// "github.com/evanw/esbuild/pkg/api" +// ) // -// ReactDOM.render( -//

Hello, world!

, -// document.getElementById('root') -// ); -// ` +// func main() { +// jsx := ` +// import * as React from 'react' +// import * as ReactDOM from 'react-dom' // -// result := api.Transform(jsx, api.TransformOptions{ -// Loader: api.LoaderJSX, -// }) +// ReactDOM.render( +//

Hello, world!

, +// document.getElementById('root') +// ); +// ` // -// fmt.Printf("%d errors and %d warnings\n", -// len(result.Errors), len(result.Warnings)) +// result := api.Transform(jsx, api.TransformOptions{ +// Loader: api.LoaderJSX, +// }) // -// os.Stdout.Write(result.Code) -// } +// fmt.Printf("%d errors and %d warnings\n", +// len(result.Errors), len(result.Warnings)) // +// os.Stdout.Write(result.Code) +// } package api type SourceMap uint8 @@ -110,6 +109,7 @@ type JSXMode uint8 const ( JSXModeTransform JSXMode = iota JSXModePreserve + JSXModeAutomatic ) type Target uint8 @@ -150,7 +150,8 @@ const ( type Platform uint8 const ( - PlatformBrowser Platform = iota + PlatformDefault Platform = iota + PlatformBrowser PlatformNode PlatformNeutral ) @@ -275,9 +276,11 @@ type BuildOptions struct { IgnoreAnnotations bool // Documentation: https://esbuild.github.io/api/#ignore-annotations LegalComments LegalComments // Documentation: https://esbuild.github.io/api/#legal-comments - JSXMode JSXMode // Documentation: https://esbuild.github.io/api/#jsx-mode - JSXFactory string // Documentation: https://esbuild.github.io/api/#jsx-factory - JSXFragment string // Documentation: https://esbuild.github.io/api/#jsx-fragment + JSXMode JSXMode // Documentation: https://esbuild.github.io/api/#jsx-mode + JSXFactory string // Documentation: https://esbuild.github.io/api/#jsx-factory + JSXFragment string // Documentation: https://esbuild.github.io/api/#jsx-fragment + JSXImportSource string // Documentation: https://esbuild.github.io/api/#jsx-import-source + JSXDev bool // Documentation: https://esbuild.github.io/api/#jsx-dev Define map[string]string // Documentation: https://esbuild.github.io/api/#define Pure []string // Documentation: https://esbuild.github.io/api/#pure @@ -378,8 +381,9 @@ type TransformOptions struct { Engines []Engine // Documentation: https://esbuild.github.io/api/#target Supported map[string]bool // Documentation: https://esbuild.github.io/api/#supported - Format Format // Documentation: https://esbuild.github.io/api/#format - GlobalName string // Documentation: https://esbuild.github.io/api/#global-name + Platform Platform // Documentation: https://esbuild.github.io/api/#platform + Format Format // Documentation: https://esbuild.github.io/api/#format + GlobalName string // Documentation: https://esbuild.github.io/api/#global-name MangleProps string // Documentation: https://esbuild.github.io/api/#mangle-props ReserveProps string // Documentation: https://esbuild.github.io/api/#mangle-props @@ -394,9 +398,11 @@ type TransformOptions struct { IgnoreAnnotations bool // Documentation: https://esbuild.github.io/api/#ignore-annotations LegalComments LegalComments // Documentation: https://esbuild.github.io/api/#legal-comments - JSXMode JSXMode // Documentation: https://esbuild.github.io/api/#jsx - JSXFactory string // Documentation: https://esbuild.github.io/api/#jsx-factory - JSXFragment string // Documentation: https://esbuild.github.io/api/#jsx-fragment + JSXMode JSXMode // Documentation: https://esbuild.github.io/api/#jsx + JSXFactory string // Documentation: https://esbuild.github.io/api/#jsx-factory + JSXFragment string // Documentation: https://esbuild.github.io/api/#jsx-fragment + JSXImportSource string // Documentation: https://esbuild.github.io/api/#jsx-import-source + JSXDev bool // Documentation: https://esbuild.github.io/api/#jsx-dev TsconfigRaw string // Documentation: https://esbuild.github.io/api/#tsconfig-raw Banner string // Documentation: https://esbuild.github.io/api/#banner diff --git a/vendor/github.com/evanw/esbuild/pkg/api/api_impl.go b/vendor/github.com/evanw/esbuild/pkg/api/api_impl.go index 8b361610f..12fdc23c3 100644 --- a/vendor/github.com/evanw/esbuild/pkg/api/api_impl.go +++ b/vendor/github.com/evanw/esbuild/pkg/api/api_impl.go @@ -97,8 +97,10 @@ func validatePathTemplate(template string) []config.PathTemplate { return parts } -func validatePlatform(value Platform) config.Platform { +func validatePlatform(value Platform, defaultPlatform config.Platform) config.Platform { switch value { + case PlatformDefault: + return defaultPlatform case PlatformBrowser: return config.PlatformBrowser case PlatformNode: @@ -487,7 +489,7 @@ func validateDefines( log logger.Log, defines map[string]string, pureFns []string, - platform Platform, + platform config.Platform, minify bool, drop Drop, ) (*config.ProcessedDefines, []config.InjectedDefine) { @@ -553,7 +555,7 @@ func validateDefines( // that must be handled to avoid all React code crashing instantly. This // is only done if it's not already defined so that you can override it if // necessary. - if platform == PlatformBrowser { + if platform == config.PlatformBrowser { if _, process := rawDefines["process"]; !process { if _, processEnv := rawDefines["process.env"]; !processEnv { if _, processEnvNodeEnv := rawDefines["process.env.NODE_ENV"]; !processEnvNodeEnv { @@ -882,7 +884,8 @@ func rebuildImpl( bannerJS, bannerCSS := validateBannerOrFooter(log, "banner", buildOpts.Banner) footerJS, footerCSS := validateBannerOrFooter(log, "footer", buildOpts.Footer) minify := buildOpts.MinifyWhitespace && buildOpts.MinifyIdentifiers && buildOpts.MinifySyntax - defines, injectedDefines := validateDefines(log, buildOpts.Define, buildOpts.Pure, buildOpts.Platform, minify, buildOpts.Drop) + platform := validatePlatform(buildOpts.Platform, config.PlatformBrowser) + defines, injectedDefines := validateDefines(log, buildOpts.Define, buildOpts.Pure, platform, minify, buildOpts.Drop) mangleCache := cloneMangleCache(log, buildOpts.MangleCache) options := config.Options{ TargetFromAPI: targetFromAPI, @@ -894,13 +897,16 @@ func rebuildImpl( UnsupportedCSSFeatureOverridesMask: cssMask, OriginalTargetEnv: targetEnv, JSX: config.JSXOptions{ - Preserve: buildOpts.JSXMode == JSXModePreserve, - Factory: validateJSXExpr(log, buildOpts.JSXFactory, "factory"), - Fragment: validateJSXExpr(log, buildOpts.JSXFragment, "fragment"), + Preserve: buildOpts.JSXMode == JSXModePreserve, + AutomaticRuntime: buildOpts.JSXMode == JSXModeAutomatic, + Factory: validateJSXExpr(log, buildOpts.JSXFactory, "factory"), + Fragment: validateJSXExpr(log, buildOpts.JSXFragment, "fragment"), + Development: buildOpts.JSXDev, + ImportSource: buildOpts.JSXImportSource, }, Defines: defines, InjectedDefines: injectedDefines, - Platform: validatePlatform(buildOpts.Platform), + Platform: platform, SourceMap: validateSourceMap(buildOpts.Sourcemap), LegalComments: validateLegalComments(buildOpts.LegalComments, buildOpts.Bundle), SourceRoot: buildOpts.SourceRoot, @@ -1353,9 +1359,12 @@ func transformImpl(input string, transformOpts TransformOptions) TransformResult var unusedImportFlagsTS config.UnusedImportFlagsTS useDefineForClassFieldsTS := config.Unspecified jsx := config.JSXOptions{ - Preserve: transformOpts.JSXMode == JSXModePreserve, - Factory: validateJSXExpr(log, transformOpts.JSXFactory, "factory"), - Fragment: validateJSXExpr(log, transformOpts.JSXFragment, "fragment"), + Preserve: transformOpts.JSXMode == JSXModePreserve, + AutomaticRuntime: transformOpts.JSXMode == JSXModeAutomatic, + Factory: validateJSXExpr(log, transformOpts.JSXFactory, "factory"), + Fragment: validateJSXExpr(log, transformOpts.JSXFragment, "fragment"), + Development: transformOpts.JSXDev, + ImportSource: transformOpts.JSXImportSource, } // Settings from "tsconfig.json" override those @@ -1369,12 +1378,18 @@ func transformImpl(input string, transformOpts TransformOptions) TransformResult Contents: transformOpts.TsconfigRaw, } if result := resolver.ParseTSConfigJSON(log, source, &caches.JSONCache, nil); result != nil { + if result.JSX != config.TSJSXNone { + jsx.SetOptionsFromTSJSX(result.JSX) + } if len(result.JSXFactory) > 0 { jsx.Factory = config.DefineExpr{Parts: result.JSXFactory} } if len(result.JSXFragmentFactory) > 0 { jsx.Fragment = config.DefineExpr{Parts: result.JSXFragmentFactory} } + if len(result.JSXImportSource) > 0 { + jsx.ImportSource = result.JSXImportSource + } if result.UseDefineForClassFields != config.Unspecified { useDefineForClassFieldsTS = result.UseDefineForClassFields } @@ -1398,7 +1413,8 @@ func transformImpl(input string, transformOpts TransformOptions) TransformResult // Convert and validate the transformOpts targetFromAPI, jsFeatures, cssFeatures, targetEnv := validateFeatures(log, transformOpts.Target, transformOpts.Engines) jsOverrides, jsMask, cssOverrides, cssMask := validateSupported(log, transformOpts.Supported) - defines, injectedDefines := validateDefines(log, transformOpts.Define, transformOpts.Pure, PlatformNeutral, false /* minify */, transformOpts.Drop) + platform := validatePlatform(transformOpts.Platform, config.PlatformNeutral) + defines, injectedDefines := validateDefines(log, transformOpts.Define, transformOpts.Pure, platform, false /* minify */, transformOpts.Drop) mangleCache := cloneMangleCache(log, transformOpts.MangleCache) options := config.Options{ TargetFromAPI: targetFromAPI, @@ -1414,6 +1430,7 @@ func transformImpl(input string, transformOpts TransformOptions) TransformResult JSX: jsx, Defines: defines, InjectedDefines: injectedDefines, + Platform: platform, SourceMap: validateSourceMap(transformOpts.Sourcemap), LegalComments: validateLegalComments(transformOpts.LegalComments, false /* bundle */), SourceRoot: transformOpts.SourceRoot, diff --git a/vendor/github.com/lucas-clemente/quic-go/README.md b/vendor/github.com/lucas-clemente/quic-go/README.md index f284174c2..fc25e0b48 100644 --- a/vendor/github.com/lucas-clemente/quic-go/README.md +++ b/vendor/github.com/lucas-clemente/quic-go/README.md @@ -5,9 +5,9 @@ [![PkgGoDev](https://pkg.go.dev/badge/github.com/lucas-clemente/quic-go)](https://pkg.go.dev/github.com/lucas-clemente/quic-go) [![Code Coverage](https://img.shields.io/codecov/c/github/lucas-clemente/quic-go/master.svg?style=flat-square)](https://codecov.io/gh/lucas-clemente/quic-go/) -quic-go is an implementation of the [QUIC protocol, RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000) protocol in Go, including the [Unreliable Datagram Extension, RFC 9221](https://datatracker.ietf.org/doc/html/rfc9221). +quic-go is an implementation of the QUIC protocol ([RFC 9000](https://datatracker.ietf.org/doc/html/rfc9000), [RFC 9001](https://datatracker.ietf.org/doc/html/rfc9001), [RFC 9002](https://datatracker.ietf.org/doc/html/rfc9002)) in Go, including the [Unreliable Datagram Extension, RFC 9221](https://datatracker.ietf.org/doc/html/rfc9221). It has support for HTTP/3 [RFC 9114](https://datatracker.ietf.org/doc/html/rfc9114). -In addition to RFC 9000, it currently implements the [IETF QUIC draft-29](https://tools.ietf.org/html/draft-ietf-quic-transport-29). Support for draft-29 will eventually be dropped, as it is phased out of the ecosystem. +In addition the RFCs listed above, it currently implements the [IETF QUIC draft-29](https://tools.ietf.org/html/draft-ietf-quic-transport-29). Support for draft-29 will eventually be dropped, as it is phased out of the ecosystem. ## Guides diff --git a/vendor/github.com/lucas-clemente/quic-go/http3/body.go b/vendor/github.com/lucas-clemente/quic-go/http3/body.go index b3d1afd7b..d6e704ebc 100644 --- a/vendor/github.com/lucas-clemente/quic-go/http3/body.go +++ b/vendor/github.com/lucas-clemente/quic-go/http3/body.go @@ -110,7 +110,9 @@ func (r *hijackableBody) requestDone() { if r.reqDoneClosed || r.reqDone == nil { return } - close(r.reqDone) + if r.reqDone != nil { + close(r.reqDone) + } r.reqDoneClosed = true } diff --git a/vendor/github.com/lucas-clemente/quic-go/http3/client.go b/vendor/github.com/lucas-clemente/quic-go/http3/client.go index e4c51688a..90115e4b1 100644 --- a/vendor/github.com/lucas-clemente/quic-go/http3/client.go +++ b/vendor/github.com/lucas-clemente/quic-go/http3/client.go @@ -273,7 +273,9 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon // This go routine keeps running even after RoundTripOpt() returns. // It is shut down when the application is done processing the body. reqDone := make(chan struct{}) + done := make(chan struct{}) go func() { + defer close(done) select { case <-req.Context().Done(): str.CancelWrite(quic.StreamErrorCode(errorRequestCanceled)) @@ -282,9 +284,14 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon } }() - rsp, rerr := c.doRequest(req, str, opt, reqDone) + doneChan := reqDone + if opt.DontCloseRequestStream { + doneChan = nil + } + rsp, rerr := c.doRequest(req, str, opt, doneChan) if rerr.err != nil { // if any error occurred close(reqDone) + <-done if rerr.streamErr != 0 { // if it was a stream error str.CancelWrite(quic.StreamErrorCode(rerr.streamErr)) } @@ -296,6 +303,10 @@ func (c *client) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Respon c.conn.CloseWithError(quic.ApplicationErrorCode(rerr.connErr), reason) } } + if opt.DontCloseRequestStream { + close(reqDone) + <-done + } return rsp, rerr.err } @@ -326,7 +337,7 @@ func (c *client) sendRequestBody(str Stream, body io.ReadCloser) error { return nil } -func (c *client) doRequest(req *http.Request, str quic.Stream, opt RoundTripOpt, reqDone chan struct{}) (*http.Response, requestError) { +func (c *client) doRequest(req *http.Request, str quic.Stream, opt RoundTripOpt, reqDone chan<- struct{}) (*http.Response, requestError) { var requestGzip bool if !c.opts.DisableCompression && req.Method != "HEAD" && req.Header.Get("Accept-Encoding") == "" && req.Header.Get("Range") == "" { requestGzip = true diff --git a/vendor/github.com/lucas-clemente/quic-go/http3/roundtrip.go b/vendor/github.com/lucas-clemente/quic-go/http3/roundtrip.go index a4d0a312c..5cde95a62 100644 --- a/vendor/github.com/lucas-clemente/quic-go/http3/roundtrip.go +++ b/vendor/github.com/lucas-clemente/quic-go/http3/roundtrip.go @@ -84,6 +84,7 @@ type RoundTripOpt struct { // If set true and no cached connection is available, RoundTripOpt will return ErrNoCachedConn. OnlyCachedConn bool // DontCloseRequestStream controls whether the request stream is closed after sending the request. + // If set, context cancellations have no effect after the response headers are received. DontCloseRequestStream bool } diff --git a/vendor/github.com/mholt/acmez/README.md b/vendor/github.com/mholt/acmez/README.md index c9c28aaad..89e8e1ed9 100644 --- a/vendor/github.com/mholt/acmez/README.md +++ b/vendor/github.com/mholt/acmez/README.md @@ -32,14 +32,33 @@ In other words, the `acmez` package is **porcelain** while the `acme` package is - Utility functions for solving challenges - Helpers for RFC 8737 (tls-alpn-01 challenge) -The `acmez` package is "bring-your-own-solver." It provides helper utilities for http-01, dns-01, and tls-alpn-01 challenges, but does not actually solve them for you. You must write an implementation of `acmez.Solver` in order to get certificates. How this is done depends on the environment in which you're using this code. -This is not a command line utility either. The goal is to not add more external tooling to already-complex infrastructure: ACME and TLS should be built-in to servers rather than tacked on as an afterthought. +## Examples +See the [`examples` folder](https://github.com/mholt/acmez/tree/master/examples) for tutorials on how to use either package. **Most users should follow the [porcelain guide](https://github.com/mholt/acmez/blob/master/examples/porcelain/main.go).** -## Examples -See the `examples` folder for tutorials on how to use either package. +## Challenge solvers + +The `acmez` package is "bring-your-own-solver." It provides helper utilities for http-01, dns-01, and tls-alpn-01 challenges, but does not actually solve them for you. You must write or use an implementation of [`acmez.Solver`](https://pkg.go.dev/github.com/mholt/acmez#Solver) in order to get certificates. How this is done depends on your environment/situation. + +However, you can find [a general-purpose dns-01 solver in CertMagic](https://pkg.go.dev/github.com/caddyserver/certmagic#DNS01Solver), which uses [libdns](https://github.com/libdns) packages to integrate with numerous DNS providers. You can use it like this: + +```go +// minimal example using Cloudflare +solver := &certmagic.DNS01Solver{ + DNSProvider: &cloudflare.Provider{APIToken: "topsecret"}, +} +client := acmez.Client{ + ChallengeSolvers: map[string]acmez.Solver{ + acme.ChallengeTypeDNS01: solver, + }, + // ... +} +``` + +If you're implementing a tls-alpn-01 solver, the `acmez` package can help. It has the constant [`ACMETLS1Protocol`](https://pkg.go.dev/github.com/mholt/acmez#pkg-constants) which you can use to identify challenge handshakes by inspecting the ClientHello's ALPN extension. Simply complete the handshake using a certificate from the [`acmez.TLSALPN01ChallengeCert()`](https://pkg.go.dev/github.com/mholt/acmez#TLSALPN01ChallengeCert) function to solve the challenge. + ## History diff --git a/vendor/github.com/mholt/acmez/client.go b/vendor/github.com/mholt/acmez/client.go index c39038c90..4a55fb031 100644 --- a/vendor/github.com/mholt/acmez/client.go +++ b/vendor/github.com/mholt/acmez/client.go @@ -21,9 +21,9 @@ // implementing solvers and using the certificates. It DOES NOT manage // certificates, it only gets them from the ACME server. // -// NOTE: This package's main function is to get a certificate, not manage it. -// Most users will want to *manage* certificates over the lifetime of a -// long-running program such as a HTTPS or TLS server, and should use CertMagic +// NOTE: This package's primary purpose is to get a certificate, not manage it. +// Most users actually want to *manage* certificates over the lifetime of +// long-running programs such as HTTPS or TLS servers, and should use CertMagic // instead: https://github.com/caddyserver/certmagic. package acmez @@ -60,9 +60,6 @@ type Client struct { // Map of solvers keyed by name of the challenge type. ChallengeSolvers map[string]Solver - - // An optional logger. Default: no logs - Logger *zap.Logger } // ObtainCertificateUsingCSR obtains all resulting certificate chains using the given CSR, which @@ -71,7 +68,7 @@ type Client struct { // x509.ParseCertificateRequest on the output). The Subject CommonName is NOT considered. // // It implements every single part of the ACME flow described in RFC 8555 §7.1 with the exception -// of "Create account" because this method signature does not have a way to return the udpated +// of "Create account" because this method signature does not have a way to return the updated // account object. The account's status MUST be "valid" in order to succeed. // // As far as SANs go, this method currently only supports DNSNames and IPAddresses on the csr. @@ -407,6 +404,11 @@ func (c *Client) presentForNextChallenge(ctx context.Context, authz *authzState) func (c *Client) initiateCurrentChallenge(ctx context.Context, authz *authzState) error { if authz.Status != acme.StatusPending { + if c.Logger != nil { + c.Logger.Debug("skipping challenge initiation because authorization is not pending", + zap.String("identifier", authz.IdentifierValue()), + zap.String("authz_status", authz.Status)) + } return nil } @@ -416,7 +418,17 @@ func (c *Client) initiateCurrentChallenge(ctx context.Context, authz *authzState // that's probably OK, since we can't finalize the order until the slow // challenges are done too) if waiter, ok := authz.currentSolver.(Waiter); ok { + if c.Logger != nil { + c.Logger.Debug("waiting for solver before continuing", + zap.String("identifier", authz.IdentifierValue()), + zap.String("challenge_type", authz.currentChallenge.Type)) + } err := waiter.Wait(ctx, authz.currentChallenge) + if c.Logger != nil { + c.Logger.Debug("done waiting for solver", + zap.String("identifier", authz.IdentifierValue()), + zap.String("challenge_type", authz.currentChallenge.Type)) + } if err != nil { return fmt.Errorf("waiting for solver %T to be ready: %w", authz.currentSolver, err) } @@ -531,6 +543,13 @@ func (c *Client) pollAuthorization(ctx context.Context, account acme.Account, au } return fmt.Errorf("[%s] %w", authz.Authorization.IdentifierValue(), err) } + + if c.Logger != nil { + c.Logger.Info("authorization finalized", + zap.String("identifier", authz.IdentifierValue()), + zap.String("authz_status", authz.Status)) + } + return nil } diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md index 5152b6aa4..b042c896f 100644 --- a/vendor/github.com/sirupsen/logrus/README.md +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -1,4 +1,4 @@ -# Logrus :walrus: [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus) +# Logrus :walrus: [![Build Status](https://github.com/sirupsen/logrus/workflows/CI/badge.svg)](https://github.com/sirupsen/logrus/actions?query=workflow%3ACI) [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![Go Reference](https://pkg.go.dev/badge/github.com/sirupsen/logrus.svg)](https://pkg.go.dev/github.com/sirupsen/logrus) Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger. @@ -341,7 +341,7 @@ import ( log "github.com/sirupsen/logrus" ) -init() { +func init() { // do something here to set environment depending on an environment variable // or command-line flag if Environment == "production" { diff --git a/vendor/github.com/sirupsen/logrus/buffer_pool.go b/vendor/github.com/sirupsen/logrus/buffer_pool.go index 4545dec07..c7787f77c 100644 --- a/vendor/github.com/sirupsen/logrus/buffer_pool.go +++ b/vendor/github.com/sirupsen/logrus/buffer_pool.go @@ -26,15 +26,6 @@ func (p *defaultPool) Get() *bytes.Buffer { return p.pool.Get().(*bytes.Buffer) } -func getBuffer() *bytes.Buffer { - return bufferPool.Get() -} - -func putBuffer(buf *bytes.Buffer) { - buf.Reset() - bufferPool.Put(buf) -} - // SetBufferPool allows to replace the default logrus buffer pool // to better meets the specific needs of an application. func SetBufferPool(bp BufferPool) { diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go index 07a1e5fa7..71cdbbc35 100644 --- a/vendor/github.com/sirupsen/logrus/entry.go +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -232,6 +232,7 @@ func (entry *Entry) log(level Level, msg string) { newEntry.Logger.mu.Lock() reportCaller := newEntry.Logger.ReportCaller + bufPool := newEntry.getBufferPool() newEntry.Logger.mu.Unlock() if reportCaller { @@ -239,11 +240,11 @@ func (entry *Entry) log(level Level, msg string) { } newEntry.fireHooks() - - buffer = getBuffer() + buffer = bufPool.Get() defer func() { newEntry.Buffer = nil - putBuffer(buffer) + buffer.Reset() + bufPool.Put(buffer) }() buffer.Reset() newEntry.Buffer = buffer @@ -260,6 +261,13 @@ func (entry *Entry) log(level Level, msg string) { } } +func (entry *Entry) getBufferPool() (pool BufferPool) { + if entry.Logger.BufferPool != nil { + return entry.Logger.BufferPool + } + return bufferPool +} + func (entry *Entry) fireHooks() { var tmpHooks LevelHooks entry.Logger.mu.Lock() @@ -276,18 +284,21 @@ func (entry *Entry) fireHooks() { } func (entry *Entry) write() { + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() serialized, err := entry.Logger.Formatter.Format(entry) if err != nil { fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) return } - entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() if _, err := entry.Logger.Out.Write(serialized); err != nil { fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) } } +// Log will log a message at the level given as parameter. +// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. +// For this behaviour Entry.Panic or Entry.Fatal should be used instead. func (entry *Entry) Log(level Level, args ...interface{}) { if entry.Logger.IsLevelEnabled(level) { entry.log(level, fmt.Sprint(args...)) diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go index 337704457..5ff0aef6d 100644 --- a/vendor/github.com/sirupsen/logrus/logger.go +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -44,6 +44,9 @@ type Logger struct { entryPool sync.Pool // Function to exit the application, defaults to `os.Exit()` ExitFunc exitFunc + // The buffer pool used to format the log. If it is nil, the default global + // buffer pool will be used. + BufferPool BufferPool } type exitFunc func(int) @@ -192,6 +195,9 @@ func (logger *Logger) Panicf(format string, args ...interface{}) { logger.Logf(PanicLevel, format, args...) } +// Log will log a message at the level given as parameter. +// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. +// For this behaviour Logger.Panic or Logger.Fatal should be used instead. func (logger *Logger) Log(level Level, args ...interface{}) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() @@ -402,3 +408,10 @@ func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks { logger.mu.Unlock() return oldHooks } + +// SetBufferPool sets the logger buffer pool. +func (logger *Logger) SetBufferPool(pool BufferPool) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.BufferPool = pool +} diff --git a/vendor/github.com/xyproto/vt100/README.md b/vendor/github.com/xyproto/vt100/README.md index 240488d77..758a3a8cb 100644 --- a/vendor/github.com/xyproto/vt100/README.md +++ b/vendor/github.com/xyproto/vt100/README.md @@ -78,6 +78,6 @@ Quick installation: ### General info -* Version: 1.11.0 +* Version: 1.11.1 * Licence: BSD-3 * Author: Alexander F. Rødseth <xyproto@archlinux.org> diff --git a/vendor/github.com/xyproto/vt100/canvas.go b/vendor/github.com/xyproto/vt100/canvas.go index 417f4644c..c9209e0db 100644 --- a/vendor/github.com/xyproto/vt100/canvas.go +++ b/vendor/github.com/xyproto/vt100/canvas.go @@ -7,7 +7,6 @@ import ( "strconv" "strings" "sync" - "unicode" ) type ColorRune struct { @@ -276,34 +275,48 @@ func (c *Canvas) Draw() { c.mut.RLock() firstRun := len(c.oldchars) == 0 skipAll := !firstRun // true by default, except for the first run - size := uint(c.w * c.h) - for index := uint(0); index < (size - 1); index++ { - cr = (*c).chars[index] - if !firstRun { + if firstRun { + for index := uint(0); index < (c.w*c.h - 1); index++ { + cr = (*c).chars[index] + // Only output a color code if it's different from the last character, or it's the first one + if (index == 0) || !lastfg.Equal(cr.fg) || !lastbg.Equal(cr.bg) { + // Write to the string builder + sb.WriteString(cr.fg.Combine(cr.bg).String()) + } + // Write the character + if cr.r != 0 { + sb.WriteRune(cr.r) + } else { + sb.WriteRune(' ') + } + lastfg = cr.fg + lastbg = cr.bg + } + } else { + for index := uint(0); index < (c.w*c.h - 1); index++ { + cr = (*c).chars[index] oldcr = (*c).oldchars[index] if cr.fg.Equal(lastfg) && cr.fg.Equal(oldcr.fg) && cr.bg.Equal(lastbg) && cr.bg.Equal(oldcr.bg) && cr.r == oldcr.r { // One is not skippable, can not skip all skipAll = false } + // Only output a color code if it's different from the last character, or it's the first one + if (index == 0) || !lastfg.Equal(cr.fg) || !lastbg.Equal(cr.bg) { + // Write to the string builder + sb.WriteString(cr.fg.Combine(cr.bg).String()) + } + // Write the character + if cr.r != 0 { + sb.WriteRune(cr.r) + } else { + sb.WriteRune(' ') + } + lastfg = cr.fg + lastbg = cr.bg } - - // Only output a color code if it's different from the last character, or it's the first one - if (index == 0) || !lastfg.Equal(cr.fg) || !lastbg.Equal(cr.bg) { - // Write to the string builder - sb.WriteString(cr.fg.Combine(cr.bg).String()) - } - - // Write the character - if unicode.IsPrint(cr.r) { - sb.WriteRune(cr.r) - } else { - sb.WriteRune(' ') - } - - lastfg = cr.fg - lastbg = cr.bg } + c.mut.RUnlock() // The screenfull so far is correct (sb.String()) diff --git a/vendor/golang.org/x/crypto/AUTHORS b/vendor/golang.org/x/crypto/AUTHORS deleted file mode 100644 index 2b00ddba0..000000000 --- a/vendor/golang.org/x/crypto/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at https://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/crypto/CONTRIBUTORS b/vendor/golang.org/x/crypto/CONTRIBUTORS deleted file mode 100644 index 1fbd3e976..000000000 --- a/vendor/golang.org/x/crypto/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at https://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/net/AUTHORS b/vendor/golang.org/x/net/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/golang.org/x/net/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/net/CONTRIBUTORS b/vendor/golang.org/x/net/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/golang.org/x/net/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go index 0178647ee..184ac45fe 100644 --- a/vendor/golang.org/x/net/http2/frame.go +++ b/vendor/golang.org/x/net/http2/frame.go @@ -23,7 +23,7 @@ const frameHeaderLen = 9 var padZeros = make([]byte, 255) // zeros for padding // A FrameType is a registered frame type as defined in -// http://http2.github.io/http2-spec/#rfc.section.11.2 +// https://httpwg.org/specs/rfc7540.html#rfc.section.11.2 type FrameType uint8 const ( @@ -146,7 +146,7 @@ func typeFrameParser(t FrameType) frameParser { // A FrameHeader is the 9 byte header of all HTTP/2 frames. // -// See http://http2.github.io/http2-spec/#FrameHeader +// See https://httpwg.org/specs/rfc7540.html#FrameHeader type FrameHeader struct { valid bool // caller can access []byte fields in the Frame @@ -575,7 +575,7 @@ func (fr *Framer) checkFrameOrder(f Frame) error { // A DataFrame conveys arbitrary, variable-length sequences of octets // associated with a stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.1 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.1 type DataFrame struct { FrameHeader data []byte @@ -698,7 +698,7 @@ func (f *Framer) WriteDataPadded(streamID uint32, endStream bool, data, pad []by // endpoints communicate, such as preferences and constraints on peer // behavior. // -// See http://http2.github.io/http2-spec/#SETTINGS +// See https://httpwg.org/specs/rfc7540.html#SETTINGS type SettingsFrame struct { FrameHeader p []byte @@ -837,7 +837,7 @@ func (f *Framer) WriteSettingsAck() error { // A PingFrame is a mechanism for measuring a minimal round trip time // from the sender, as well as determining whether an idle connection // is still functional. -// See http://http2.github.io/http2-spec/#rfc.section.6.7 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.7 type PingFrame struct { FrameHeader Data [8]byte @@ -870,7 +870,7 @@ func (f *Framer) WritePing(ack bool, data [8]byte) error { } // A GoAwayFrame informs the remote peer to stop creating streams on this connection. -// See http://http2.github.io/http2-spec/#rfc.section.6.8 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.8 type GoAwayFrame struct { FrameHeader LastStreamID uint32 @@ -934,7 +934,7 @@ func parseUnknownFrame(_ *frameCache, fh FrameHeader, countError func(string), p } // A WindowUpdateFrame is used to implement flow control. -// See http://http2.github.io/http2-spec/#rfc.section.6.9 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.9 type WindowUpdateFrame struct { FrameHeader Increment uint32 // never read with high bit set @@ -1123,7 +1123,7 @@ func (f *Framer) WriteHeaders(p HeadersFrameParam) error { } // A PriorityFrame specifies the sender-advised priority of a stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.3 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.3 type PriorityFrame struct { FrameHeader PriorityParam @@ -1193,7 +1193,7 @@ func (f *Framer) WritePriority(streamID uint32, p PriorityParam) error { } // A RSTStreamFrame allows for abnormal termination of a stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.4 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.4 type RSTStreamFrame struct { FrameHeader ErrCode ErrCode @@ -1225,7 +1225,7 @@ func (f *Framer) WriteRSTStream(streamID uint32, code ErrCode) error { } // A ContinuationFrame is used to continue a sequence of header block fragments. -// See http://http2.github.io/http2-spec/#rfc.section.6.10 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.10 type ContinuationFrame struct { FrameHeader headerFragBuf []byte @@ -1266,7 +1266,7 @@ func (f *Framer) WriteContinuation(streamID uint32, endHeaders bool, headerBlock } // A PushPromiseFrame is used to initiate a server stream. -// See http://http2.github.io/http2-spec/#rfc.section.6.6 +// See https://httpwg.org/specs/rfc7540.html#rfc.section.6.6 type PushPromiseFrame struct { FrameHeader PromiseID uint32 diff --git a/vendor/golang.org/x/net/http2/hpack/encode.go b/vendor/golang.org/x/net/http2/hpack/encode.go index 97f17831f..6886dc163 100644 --- a/vendor/golang.org/x/net/http2/hpack/encode.go +++ b/vendor/golang.org/x/net/http2/hpack/encode.go @@ -191,7 +191,7 @@ func appendTableSize(dst []byte, v uint32) []byte { // bit prefix, to dst and returns the extended buffer. // // See -// http://http2.github.io/http2-spec/compression.html#integer.representation +// https://httpwg.org/specs/rfc7541.html#integer.representation func appendVarInt(dst []byte, n byte, i uint64) []byte { k := uint64((1 << n) - 1) if i < k { diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go index 85f18a2b0..ebdfbee96 100644 --- a/vendor/golang.org/x/net/http2/hpack/hpack.go +++ b/vendor/golang.org/x/net/http2/hpack/hpack.go @@ -59,7 +59,7 @@ func (hf HeaderField) String() string { // Size returns the size of an entry per RFC 7541 section 4.1. func (hf HeaderField) Size() uint32 { - // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 + // https://httpwg.org/specs/rfc7541.html#rfc.section.4.1 // "The size of the dynamic table is the sum of the size of // its entries. The size of an entry is the sum of its name's // length in octets (as defined in Section 5.2), its value's @@ -158,7 +158,7 @@ func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { } type dynamicTable struct { - // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2 + // https://httpwg.org/specs/rfc7541.html#rfc.section.2.3.2 table headerFieldTable size uint32 // in bytes maxSize uint32 // current maxSize @@ -307,27 +307,27 @@ func (d *Decoder) parseHeaderFieldRepr() error { case b&128 != 0: // Indexed representation. // High bit set? - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.1 return d.parseFieldIndexed() case b&192 == 64: // 6.2.1 Literal Header Field with Incremental Indexing // 0b10xxxxxx: top two bits are 10 - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1 return d.parseFieldLiteral(6, indexedTrue) case b&240 == 0: // 6.2.2 Literal Header Field without Indexing // 0b0000xxxx: top four bits are 0000 - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2 return d.parseFieldLiteral(4, indexedFalse) case b&240 == 16: // 6.2.3 Literal Header Field never Indexed // 0b0001xxxx: top four bits are 0001 - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3 return d.parseFieldLiteral(4, indexedNever) case b&224 == 32: // 6.3 Dynamic Table Size Update // Top three bits are '001'. - // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3 + // https://httpwg.org/specs/rfc7541.html#rfc.section.6.3 return d.parseDynamicTableSizeUpdate() } @@ -420,7 +420,7 @@ var errVarintOverflow = DecodingError{errors.New("varint integer overflow")} // readVarInt reads an unsigned variable length integer off the // beginning of p. n is the parameter as described in -// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1. +// https://httpwg.org/specs/rfc7541.html#rfc.section.5.1. // // n must always be between 1 and 8. // diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go index 479ba4b2b..6f2df2818 100644 --- a/vendor/golang.org/x/net/http2/http2.go +++ b/vendor/golang.org/x/net/http2/http2.go @@ -55,14 +55,14 @@ const ( ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" // SETTINGS_MAX_FRAME_SIZE default - // http://http2.github.io/http2-spec/#rfc.section.6.5.2 + // https://httpwg.org/specs/rfc7540.html#rfc.section.6.5.2 initialMaxFrameSize = 16384 // NextProtoTLS is the NPN/ALPN protocol negotiated during // HTTP/2's TLS setup. NextProtoTLS = "h2" - // http://http2.github.io/http2-spec/#SettingValues + // https://httpwg.org/specs/rfc7540.html#SettingValues initialHeaderTableSize = 4096 initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size @@ -111,7 +111,7 @@ func (st streamState) String() string { // Setting is a setting parameter: which setting it is, and its value. type Setting struct { // ID is which setting is being set. - // See http://http2.github.io/http2-spec/#SettingValues + // See https://httpwg.org/specs/rfc7540.html#SettingFormat ID SettingID // Val is the value. @@ -143,7 +143,7 @@ func (s Setting) Valid() error { } // A SettingID is an HTTP/2 setting as defined in -// http://http2.github.io/http2-spec/#iana-settings +// https://httpwg.org/specs/rfc7540.html#iana-settings type SettingID uint16 const ( diff --git a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go index ba53f564b..f7d0b0d2b 100644 --- a/vendor/golang.org/x/net/internal/socket/rawconn_msg.go +++ b/vendor/golang.org/x/net/internal/socket/rawconn_msg.go @@ -8,22 +8,21 @@ package socket import ( + "net" "os" ) func (c *Conn) recvMsg(m *Message, flags int) error { m.raceWrite() - var h msghdr - vs := make([]iovec, len(m.Buffers)) - var sa []byte - if c.network != "tcp" { - sa = make([]byte, sizeofSockaddrInet6) - } - h.pack(vs, m.Buffers, m.OOB, sa) - var operr error - var n int + var ( + operr error + n int + oobn int + recvflags int + from net.Addr + ) fn := func(s uintptr) bool { - n, operr = recvmsg(s, &h, flags) + n, oobn, recvflags, from, operr = recvmsg(s, m.Buffers, m.OOB, flags, c.network) return ioComplete(flags, operr) } if err := c.c.Read(fn); err != nil { @@ -32,34 +31,21 @@ func (c *Conn) recvMsg(m *Message, flags int) error { if operr != nil { return os.NewSyscallError("recvmsg", operr) } - if c.network != "tcp" { - var err error - m.Addr, err = parseInetAddr(sa[:], c.network) - if err != nil { - return err - } - } + m.Addr = from m.N = n - m.NN = h.controllen() - m.Flags = h.flags() + m.NN = oobn + m.Flags = recvflags return nil } func (c *Conn) sendMsg(m *Message, flags int) error { m.raceRead() - var h msghdr - vs := make([]iovec, len(m.Buffers)) - var sa []byte - if m.Addr != nil { - var a [sizeofSockaddrInet6]byte - n := marshalInetAddr(m.Addr, a[:]) - sa = a[:n] - } - h.pack(vs, m.Buffers, m.OOB, sa) - var operr error - var n int + var ( + operr error + n int + ) fn := func(s uintptr) bool { - n, operr = sendmsg(s, &h, flags) + n, operr = sendmsg(s, m.Buffers, m.OOB, m.Addr, flags) return ioComplete(flags, operr) } if err := c.c.Write(fn); err != nil { diff --git a/vendor/golang.org/x/net/internal/socket/sys_stub.go b/vendor/golang.org/x/net/internal/socket/sys_stub.go index 381e45e16..7cfb349c0 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_stub.go +++ b/vendor/golang.org/x/net/internal/socket/sys_stub.go @@ -36,11 +36,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return errNotImplemented } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errNotImplemented +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + return 0, 0, 0, nil, errNotImplemented } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/sys_unix.go b/vendor/golang.org/x/net/internal/socket/sys_unix.go index d203e2984..de823932b 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_unix.go +++ b/vendor/golang.org/x/net/internal/socket/sys_unix.go @@ -8,8 +8,10 @@ package socket import ( - "syscall" + "net" "unsafe" + + "golang.org/x/sys/unix" ) //go:linkname syscall_getsockopt syscall.getsockopt @@ -18,12 +20,6 @@ func syscall_getsockopt(s, level, name int, val unsafe.Pointer, vallen *uint32) //go:linkname syscall_setsockopt syscall.setsockopt func syscall_setsockopt(s, level, name int, val unsafe.Pointer, vallen uintptr) error -//go:linkname syscall_recvmsg syscall.recvmsg -func syscall_recvmsg(s int, msg *syscall.Msghdr, flags int) (int, error) - -//go:linkname syscall_sendmsg syscall.sendmsg -func syscall_sendmsg(s int, msg *syscall.Msghdr, flags int) (int, error) - func getsockopt(s uintptr, level, name int, b []byte) (int, error) { l := uint32(len(b)) err := syscall_getsockopt(int(s), level, name, unsafe.Pointer(&b[0]), &l) @@ -34,10 +30,93 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return syscall_setsockopt(int(s), level, name, unsafe.Pointer(&b[0]), uintptr(len(b))) } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return syscall_recvmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + var unixFrom unix.Sockaddr + n, oobn, recvflags, unixFrom, err = unix.RecvmsgBuffers(int(s), buffers, oob, flags) + if unixFrom != nil { + from = sockaddrToAddr(unixFrom, network) + } + return } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - return syscall_sendmsg(int(s), (*syscall.Msghdr)(unsafe.Pointer(h)), flags) +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { + var unixTo unix.Sockaddr + if to != nil { + unixTo = addrToSockaddr(to) + } + return unix.SendmsgBuffers(int(s), buffers, oob, unixTo, flags) +} + +// addrToSockaddr converts a net.Addr to a unix.Sockaddr. +func addrToSockaddr(a net.Addr) unix.Sockaddr { + var ( + ip net.IP + port int + zone string + ) + switch a := a.(type) { + case *net.TCPAddr: + ip = a.IP + port = a.Port + zone = a.Zone + case *net.UDPAddr: + ip = a.IP + port = a.Port + zone = a.Zone + case *net.IPAddr: + ip = a.IP + zone = a.Zone + default: + return nil + } + + if ip4 := ip.To4(); ip4 != nil { + sa := unix.SockaddrInet4{Port: port} + copy(sa.Addr[:], ip4) + return &sa + } + + if ip6 := ip.To16(); ip6 != nil && ip.To4() == nil { + sa := unix.SockaddrInet6{Port: port} + copy(sa.Addr[:], ip6) + if zone != "" { + sa.ZoneId = uint32(zoneCache.index(zone)) + } + return &sa + } + + return nil +} + +// sockaddrToAddr converts a unix.Sockaddr to a net.Addr. +func sockaddrToAddr(sa unix.Sockaddr, network string) net.Addr { + var ( + ip net.IP + port int + zone string + ) + switch sa := sa.(type) { + case *unix.SockaddrInet4: + ip = make(net.IP, net.IPv4len) + copy(ip, sa.Addr[:]) + port = sa.Port + case *unix.SockaddrInet6: + ip = make(net.IP, net.IPv6len) + copy(ip, sa.Addr[:]) + port = sa.Port + if sa.ZoneId > 0 { + zone = zoneCache.name(int(sa.ZoneId)) + } + default: + return nil + } + + switch network { + case "tcp", "tcp4", "tcp6": + return &net.TCPAddr{IP: ip, Port: port, Zone: zone} + case "udp", "udp4", "udp6": + return &net.UDPAddr{IP: ip, Port: port, Zone: zone} + default: + return &net.IPAddr{IP: ip, Zone: zone} + } } diff --git a/vendor/golang.org/x/net/internal/socket/sys_windows.go b/vendor/golang.org/x/net/internal/socket/sys_windows.go index 2de0d68c6..b738b89dd 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_windows.go +++ b/vendor/golang.org/x/net/internal/socket/sys_windows.go @@ -5,6 +5,7 @@ package socket import ( + "net" "syscall" "unsafe" @@ -37,11 +38,11 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return syscall.Setsockopt(syscall.Handle(s), int32(level), int32(name), (*byte)(unsafe.Pointer(&b[0])), int32(len(b))) } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - return 0, errNotImplemented +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + return 0, 0, 0, nil, errNotImplemented } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { return 0, errNotImplemented } diff --git a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go index 1e38b9223..fc65e62fa 100644 --- a/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go +++ b/vendor/golang.org/x/net/internal/socket/sys_zos_s390x.go @@ -27,12 +27,39 @@ func setsockopt(s uintptr, level, name int, b []byte) error { return errnoErr(errno) } -func recvmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) - return int(n), errnoErr(errno) +func recvmsg(s uintptr, buffers [][]byte, oob []byte, flags int, network string) (n, oobn int, recvflags int, from net.Addr, err error) { + var h msghdr + vs := make([]iovec, len(buffers)) + var sa []byte + if network != "tcp" { + sa = make([]byte, sizeofSockaddrInet6) + } + h.pack(vs, buffers, oob, sa) + sn, _, errno := syscall_syscall(syscall.SYS___RECVMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags)) + n = int(sn) + oobn = h.controllen() + recvflags = h.flags() + err = errnoErr(errno) + if network != "tcp" { + var err2 error + from, err2 = parseInetAddr(sa, network) + if err2 != nil && err == nil { + err = err2 + } + } + return } -func sendmsg(s uintptr, h *msghdr, flags int) (int, error) { - n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(h)), uintptr(flags)) +func sendmsg(s uintptr, buffers [][]byte, oob []byte, to net.Addr, flags int) (int, error) { + var h msghdr + vs := make([]iovec, len(buffers)) + var sa []byte + if to != nil { + var a [sizeofSockaddrInet6]byte + n := marshalInetAddr(to, a[:]) + sa = a[:n] + } + h.pack(vs, buffers, oob, sa) + n, _, errno := syscall_syscall(syscall.SYS___SENDMSG_A, s, uintptr(unsafe.Pointer(&h)), uintptr(flags)) return int(n), errnoErr(errno) } diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go deleted file mode 100644 index 5acf6db6e..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_386.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_darwin.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go b/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go deleted file mode 100644 index 5acf6db6e..000000000 --- a/vendor/golang.org/x/net/internal/socket/zsys_darwin_arm.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by cmd/cgo -godefs; DO NOT EDIT. -// cgo -godefs defs_darwin.go - -package socket - -type iovec struct { - Base *byte - Len uint32 -} - -type msghdr struct { - Name *byte - Namelen uint32 - Iov *iovec - Iovlen int32 - Control *byte - Controllen uint32 - Flags int32 -} - -type cmsghdr struct { - Len uint32 - Level int32 - Type int32 -} - -const ( - sizeofIovec = 0x8 - sizeofMsghdr = 0x1c -) diff --git a/vendor/golang.org/x/sys/AUTHORS b/vendor/golang.org/x/sys/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/golang.org/x/sys/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/sys/CONTRIBUTORS b/vendor/golang.org/x/sys/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/golang.org/x/sys/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index ca50e4e14..2ab44aa65 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -297,6 +297,10 @@ struct ltchars { #define SOL_NETLINK 270 #endif +#ifndef SOL_SMC +#define SOL_SMC 286 +#endif + #ifdef SOL_BLUETOOTH // SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h // but it is already in bluetooth_linux.go diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index ac579c60f..2db1b51e9 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -218,13 +218,62 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) { } func recvmsgRaw(fd int, iov []Iovec, oob []byte, flags int, rsa *RawSockaddrAny) (n, oobn int, recvflags int, err error) { - // Recvmsg not implemented on AIX - return -1, -1, -1, ENOSYS + var msg Msghdr + msg.Name = (*byte)(unsafe.Pointer(rsa)) + msg.Namelen = uint32(SizeofSockaddrAny) + var dummy byte + if len(oob) > 0 { + // receive at least one normal byte + if emptyIovecs(iov) { + var iova [1]Iovec + iova[0].Base = &dummy + iova[0].SetLen(1) + iov = iova[:] + } + msg.Control = (*byte)(unsafe.Pointer(&oob[0])) + msg.SetControllen(len(oob)) + } + if len(iov) > 0 { + msg.Iov = &iov[0] + msg.SetIovlen(len(iov)) + } + if n, err = recvmsg(fd, &msg, flags); n == -1 { + return + } + oobn = int(msg.Controllen) + recvflags = int(msg.Flags) + return } func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Socklen, flags int) (n int, err error) { - // SendmsgN not implemented on AIX - return -1, ENOSYS + var msg Msghdr + msg.Name = (*byte)(unsafe.Pointer(ptr)) + msg.Namelen = uint32(salen) + var dummy byte + var empty bool + if len(oob) > 0 { + // send at least one normal byte + empty = emptyIovecs(iov) + if empty { + var iova [1]Iovec + iova[0].Base = &dummy + iova[0].SetLen(1) + iov = iova[:] + } + msg.Control = (*byte)(unsafe.Pointer(&oob[0])) + msg.SetControllen(len(oob)) + } + if len(iov) > 0 { + msg.Iov = &iov[0] + msg.SetIovlen(len(iov)) + } + if n, err = sendmsg(fd, &msg, flags); err != nil { + return 0, err + } + if len(oob) > 0 && empty { + n = 0 + } + return n, nil } func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { diff --git a/vendor/golang.org/x/sys/unix/syscall_bsd.go b/vendor/golang.org/x/sys/unix/syscall_bsd.go index c437fc5d7..eda42671f 100644 --- a/vendor/golang.org/x/sys/unix/syscall_bsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_bsd.go @@ -363,7 +363,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle var empty bool if len(oob) > 0 { // send at least one normal byte - empty := emptyIovecs(iov) + empty = emptyIovecs(iov) if empty { var iova [1]Iovec iova[0].Base = &dummy diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 5e4a94f73..ecb0f27fb 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1541,7 +1541,7 @@ func sendmsgN(fd int, iov []Iovec, oob []byte, ptr unsafe.Pointer, salen _Sockle var dummy byte var empty bool if len(oob) > 0 { - empty := emptyIovecs(iov) + empty = emptyIovecs(iov) if empty { var sockType int sockType, err = GetsockoptInt(fd, SOL_SOCKET, SO_TYPE) diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index b0d6c2738..785d693eb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2940,6 +2940,7 @@ const ( SOL_RAW = 0xff SOL_RDS = 0x114 SOL_RXRPC = 0x110 + SOL_SMC = 0x11e SOL_TCP = 0x6 SOL_TIPC = 0x10f SOL_TLS = 0x11a diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 869847987..f6de1eedb 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -945,6 +945,9 @@ type PerfEventAttr struct { Aux_watermark uint32 Sample_max_stack uint16 _ uint16 + Aux_sample_size uint32 + _ uint32 + Sig_data uint64 } type PerfEventMmapPage struct { diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index be3ec2bd4..e27913817 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -417,6 +417,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb uint32) (err error) = psapi.GetModuleInformation //sys GetModuleFileNameEx(process Handle, module Handle, filename *uint16, size uint32) (err error) = psapi.GetModuleFileNameExW //sys GetModuleBaseName(process Handle, module Handle, baseName *uint16, size uint32) (err error) = psapi.GetModuleBaseNameW +//sys QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) = psapi.QueryWorkingSetEx // NT Native APIs //sys rtlNtStatusToDosErrorNoTeb(ntstatus NTStatus) (ret syscall.Errno) = ntdll.RtlNtStatusToDosErrorNoTeb @@ -971,6 +972,32 @@ func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) { return unsafe.Pointer(&sa.raw), sl, nil } +type RawSockaddrBth struct { + AddressFamily [2]byte + BtAddr [8]byte + ServiceClassId [16]byte + Port [4]byte +} + +type SockaddrBth struct { + BtAddr uint64 + ServiceClassId GUID + Port uint32 + + raw RawSockaddrBth +} + +func (sa *SockaddrBth) sockaddr() (unsafe.Pointer, int32, error) { + family := AF_BTH + sa.raw = RawSockaddrBth{ + AddressFamily: *(*[2]byte)(unsafe.Pointer(&family)), + BtAddr: *(*[8]byte)(unsafe.Pointer(&sa.BtAddr)), + Port: *(*[4]byte)(unsafe.Pointer(&sa.Port)), + ServiceClassId: *(*[16]byte)(unsafe.Pointer(&sa.ServiceClassId)), + } + return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil +} + func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) { switch rsa.Addr.Family { case AF_UNIX: @@ -1707,3 +1734,71 @@ func LoadResourceData(module, resInfo Handle) (data []byte, err error) { h.Cap = int(size) return } + +// PSAPI_WORKING_SET_EX_BLOCK contains extended working set information for a page. +type PSAPI_WORKING_SET_EX_BLOCK uint64 + +// Valid returns the validity of this page. +// If this bit is 1, the subsequent members are valid; otherwise they should be ignored. +func (b PSAPI_WORKING_SET_EX_BLOCK) Valid() bool { + return (b & 1) == 1 +} + +// ShareCount is the number of processes that share this page. The maximum value of this member is 7. +func (b PSAPI_WORKING_SET_EX_BLOCK) ShareCount() uint64 { + return b.intField(1, 3) +} + +// Win32Protection is the memory protection attributes of the page. For a list of values, see +// https://docs.microsoft.com/en-us/windows/win32/memory/memory-protection-constants +func (b PSAPI_WORKING_SET_EX_BLOCK) Win32Protection() uint64 { + return b.intField(4, 11) +} + +// Shared returns the shared status of this page. +// If this bit is 1, the page can be shared. +func (b PSAPI_WORKING_SET_EX_BLOCK) Shared() bool { + return (b & (1 << 15)) == 1 +} + +// Node is the NUMA node. The maximum value of this member is 63. +func (b PSAPI_WORKING_SET_EX_BLOCK) Node() uint64 { + return b.intField(16, 6) +} + +// Locked returns the locked status of this page. +// If this bit is 1, the virtual page is locked in physical memory. +func (b PSAPI_WORKING_SET_EX_BLOCK) Locked() bool { + return (b & (1 << 22)) == 1 +} + +// LargePage returns the large page status of this page. +// If this bit is 1, the page is a large page. +func (b PSAPI_WORKING_SET_EX_BLOCK) LargePage() bool { + return (b & (1 << 23)) == 1 +} + +// Bad returns the bad status of this page. +// If this bit is 1, the page is has been reported as bad. +func (b PSAPI_WORKING_SET_EX_BLOCK) Bad() bool { + return (b & (1 << 31)) == 1 +} + +// intField extracts an integer field in the PSAPI_WORKING_SET_EX_BLOCK union. +func (b PSAPI_WORKING_SET_EX_BLOCK) intField(start, length int) uint64 { + var mask PSAPI_WORKING_SET_EX_BLOCK + for pos := start; pos < start+length; pos++ { + mask |= (1 << pos) + } + + masked := b & mask + return uint64(masked >> start) +} + +// PSAPI_WORKING_SET_EX_INFORMATION contains extended working set information for a process. +type PSAPI_WORKING_SET_EX_INFORMATION struct { + // The virtual address. + VirtualAddress Pointer + // A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress. + VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK +} diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 678262cda..52d4742cb 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -408,6 +408,7 @@ var ( procGetModuleBaseNameW = modpsapi.NewProc("GetModuleBaseNameW") procGetModuleFileNameExW = modpsapi.NewProc("GetModuleFileNameExW") procGetModuleInformation = modpsapi.NewProc("GetModuleInformation") + procQueryWorkingSetEx = modpsapi.NewProc("QueryWorkingSetEx") procSubscribeServiceChangeNotifications = modsechost.NewProc("SubscribeServiceChangeNotifications") procUnsubscribeServiceChangeNotifications = modsechost.NewProc("UnsubscribeServiceChangeNotifications") procGetUserNameExW = modsecur32.NewProc("GetUserNameExW") @@ -3504,6 +3505,14 @@ func GetModuleInformation(process Handle, module Handle, modinfo *ModuleInfo, cb return } +func QueryWorkingSetEx(process Handle, pv uintptr, cb uint32) (err error) { + r1, _, e1 := syscall.Syscall(procQueryWorkingSetEx.Addr(), 3, uintptr(process), uintptr(pv), uintptr(cb)) + if r1 == 0 { + err = errnoErr(e1) + } + return +} + func SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) { ret = procSubscribeServiceChangeNotifications.Find() if ret != nil { diff --git a/vendor/golang.org/x/time/AUTHORS b/vendor/golang.org/x/time/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/golang.org/x/time/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/time/CONTRIBUTORS b/vendor/golang.org/x/time/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/golang.org/x/time/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/tools/AUTHORS b/vendor/golang.org/x/tools/AUTHORS deleted file mode 100644 index 15167cd74..000000000 --- a/vendor/golang.org/x/tools/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code refers to The Go Authors for copyright purposes. -# The master list of authors is in the main Go distribution, -# visible at http://tip.golang.org/AUTHORS. diff --git a/vendor/golang.org/x/tools/CONTRIBUTORS b/vendor/golang.org/x/tools/CONTRIBUTORS deleted file mode 100644 index 1c4577e96..000000000 --- a/vendor/golang.org/x/tools/CONTRIBUTORS +++ /dev/null @@ -1,3 +0,0 @@ -# This source code was written by the Go contributors. -# The master list of contributors is in the main Go distribution, -# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go index d50826dbf..2ed25a750 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go @@ -22,26 +22,42 @@ package gcexportdata // import "golang.org/x/tools/go/gcexportdata" import ( "bufio" "bytes" + "encoding/json" "fmt" "go/token" "go/types" "io" "io/ioutil" + "os/exec" "golang.org/x/tools/go/internal/gcimporter" ) // Find returns the name of an object (.o) or archive (.a) file // containing type information for the specified import path, -// using the workspace layout conventions of go/build. +// using the go command. // If no file was found, an empty filename is returned. // // A relative srcDir is interpreted relative to the current working directory. // // Find also returns the package's resolved (canonical) import path, // reflecting the effects of srcDir and vendoring on importPath. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. func Find(importPath, srcDir string) (filename, path string) { - return gcimporter.FindPkg(importPath, srcDir) + cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) + cmd.Dir = srcDir + out, err := cmd.CombinedOutput() + if err != nil { + return "", "" + } + var data struct { + ImportPath string + Export string + } + json.Unmarshal(out, &data) + return data.Export, data.ImportPath } // NewReader returns a reader for the export data section of an object @@ -100,13 +116,29 @@ func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, // The indexed export format starts with an 'i'; the older // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. - if len(data) > 0 && data[0] == 'i' { - _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) - return pkg, err - } + if len(data) > 0 { + switch data[0] { + case 'i': + _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) + return pkg, err + + case 'v', 'c', 'd': + _, pkg, err := gcimporter.BImportData(fset, imports, data, path) + return pkg, err - _, pkg, err := gcimporter.BImportData(fset, imports, data, path) - return pkg, err + case 'u': + _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) + } + } + return nil, fmt.Errorf("empty export data for %s", path) } // Write writes encoded type information for the specified package to out. diff --git a/vendor/golang.org/x/tools/go/gcexportdata/importer.go b/vendor/golang.org/x/tools/go/gcexportdata/importer.go index fe6ed9321..37a7247e2 100644 --- a/vendor/golang.org/x/tools/go/gcexportdata/importer.go +++ b/vendor/golang.org/x/tools/go/gcexportdata/importer.go @@ -22,6 +22,9 @@ import ( // version-skew problems described in the documentation of this package, // or to control the FileSet or access the imports map populated during // package loading. +// +// Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, +// which is more efficient. func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { return importer{fset, imports} } diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go index 493bfa03b..e96c39600 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/gcimporter.go @@ -181,8 +181,9 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func defer rc.Close() var hdr string + var size int64 buf := bufio.NewReader(rc) - if hdr, _, err = FindExportData(buf); err != nil { + if hdr, size, err = FindExportData(buf); err != nil { return } @@ -210,10 +211,27 @@ func Import(packages map[string]*types.Package, path, srcDir string, lookup func // The indexed export format starts with an 'i'; the older // binary export format starts with a 'c', 'd', or 'v' // (from "version"). Select appropriate importer. - if len(data) > 0 && data[0] == 'i' { - _, pkg, err = IImportData(fset, packages, data[1:], id) - } else { - _, pkg, err = BImportData(fset, packages, data, id) + if len(data) > 0 { + switch data[0] { + case 'i': + _, pkg, err := IImportData(fset, packages, data[1:], id) + return pkg, err + + case 'v', 'c', 'd': + _, pkg, err := BImportData(fset, packages, data, id) + return pkg, err + + case 'u': + _, pkg, err := UImportData(fset, packages, data[1:size], id) + return pkg, err + + default: + l := len(data) + if l > 10 { + l = 10 + } + return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id) + } } default: diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go index 28b91b865..4caa0f55d 100644 --- a/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go @@ -17,6 +17,7 @@ import ( "go/token" "go/types" "io" + "math/big" "sort" "strings" @@ -512,7 +513,9 @@ func (r *importReader) value() (typ types.Type, val constant.Value) { val = constant.MakeString(r.string()) case types.IsInteger: - val = r.mpint(b) + var x big.Int + r.mpint(&x, b) + val = constant.Make(&x) case types.IsFloat: val = r.mpfloat(b) @@ -561,8 +564,8 @@ func intSize(b *types.Basic) (signed bool, maxBytes uint) { return } -func (r *importReader) mpint(b *types.Basic) constant.Value { - signed, maxBytes := intSize(b) +func (r *importReader) mpint(x *big.Int, typ *types.Basic) { + signed, maxBytes := intSize(typ) maxSmall := 256 - maxBytes if signed { @@ -581,7 +584,8 @@ func (r *importReader) mpint(b *types.Basic) constant.Value { v = ^v } } - return constant.MakeInt64(v) + x.SetInt64(v) + return } v := -n @@ -591,47 +595,23 @@ func (r *importReader) mpint(b *types.Basic) constant.Value { if v < 1 || uint(v) > maxBytes { errorf("weird decoding: %v, %v => %v", n, signed, v) } - - buf := make([]byte, v) - io.ReadFull(&r.declReader, buf) - - // convert to little endian - // TODO(gri) go/constant should have a more direct conversion function - // (e.g., once it supports a big.Float based implementation) - for i, j := 0, len(buf)-1; i < j; i, j = i+1, j-1 { - buf[i], buf[j] = buf[j], buf[i] - } - - x := constant.MakeFromBytes(buf) + b := make([]byte, v) + io.ReadFull(&r.declReader, b) + x.SetBytes(b) if signed && n&1 != 0 { - x = constant.UnaryOp(token.SUB, x, 0) + x.Neg(x) } - return x } -func (r *importReader) mpfloat(b *types.Basic) constant.Value { - x := r.mpint(b) - if constant.Sign(x) == 0 { - return x - } - - exp := r.int64() - switch { - case exp > 0: - x = constant.Shift(x, token.SHL, uint(exp)) - // Ensure that the imported Kind is Float, else this constant may run into - // bitsize limits on overlarge integers. Eventually we can instead adopt - // the approach of CL 288632, but that CL relies on go/constant APIs that - // were introduced in go1.13. - // - // TODO(rFindley): sync the logic here with tip Go once we no longer - // support go1.12. - x = constant.ToFloat(x) - case exp < 0: - d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp)) - x = constant.BinaryOp(x, token.QUO, d) +func (r *importReader) mpfloat(typ *types.Basic) constant.Value { + var mant big.Int + r.mpint(&mant, typ) + var f big.Float + f.SetInt(&mant) + if f.Sign() != 0 { + f.SetMantExp(&f, int(r.int64())) } - return x + return constant.Make(&f) } func (r *importReader) ident() string { diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go new file mode 100644 index 000000000..286bf4454 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_no.go @@ -0,0 +1,10 @@ +// Copyright 2022 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. + +//go:build !(go1.18 && goexperiment.unified) +// +build !go1.18 !goexperiment.unified + +package gcimporter + +const unifiedIR = false diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go new file mode 100644 index 000000000..b5d69ffbe --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/unified_yes.go @@ -0,0 +1,10 @@ +// Copyright 2022 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. + +//go:build go1.18 && goexperiment.unified +// +build go1.18,goexperiment.unified + +package gcimporter + +const unifiedIR = true diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go new file mode 100644 index 000000000..8eb20729c --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_no.go @@ -0,0 +1,19 @@ +// Copyright 2022 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. + +//go:build !go1.18 +// +build !go1.18 + +package gcimporter + +import ( + "fmt" + "go/token" + "go/types" +) + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data") + return +} diff --git a/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go new file mode 100644 index 000000000..3c1a43754 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/gcimporter/ureader_yes.go @@ -0,0 +1,612 @@ +// Copyright 2021 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. + +// Derived from go/internal/gcimporter/ureader.go + +//go:build go1.18 +// +build go1.18 + +package gcimporter + +import ( + "go/token" + "go/types" + "strings" + + "golang.org/x/tools/go/internal/pkgbits" +) + +// A pkgReader holds the shared state for reading a unified IR package +// description. +type pkgReader struct { + pkgbits.PkgDecoder + + fake fakeFileSet + + ctxt *types.Context + imports map[string]*types.Package // previously imported packages, indexed by path + + // lazily initialized arrays corresponding to the unified IR + // PosBase, Pkg, and Type sections, respectively. + posBases []string // position bases (i.e., file names) + pkgs []*types.Package + typs []types.Type + + // laterFns holds functions that need to be invoked at the end of + // import reading. + laterFns []func() +} + +// later adds a function to be invoked at the end of import reading. +func (pr *pkgReader) later(fn func()) { + pr.laterFns = append(pr.laterFns, fn) +} + +// See cmd/compile/internal/noder.derivedInfo. +type derivedInfo struct { + idx pkgbits.Index + needed bool +} + +// See cmd/compile/internal/noder.typeInfo. +type typeInfo struct { + idx pkgbits.Index + derived bool +} + +func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { + s := string(data) + s = s[:strings.LastIndex(s, "\n$$\n")] + input := pkgbits.NewPkgDecoder(path, s) + pkg = readUnifiedPackage(fset, nil, imports, input) + return +} + +// readUnifiedPackage reads a package description from the given +// unified IR export data decoder. +func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { + pr := pkgReader{ + PkgDecoder: input, + + fake: fakeFileSet{ + fset: fset, + files: make(map[string]*fileInfo), + }, + + ctxt: ctxt, + imports: imports, + + posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), + pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), + typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), + } + defer pr.fake.setLines() + + r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) + pkg := r.pkg() + r.Bool() // has init + + for i, n := 0, r.Len(); i < n; i++ { + // As if r.obj(), but avoiding the Scope.Lookup call, + // to avoid eager loading of imports. + r.Sync(pkgbits.SyncObject) + assert(!r.Bool()) + r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + assert(r.Len() == 0) + } + + r.Sync(pkgbits.SyncEOF) + + for _, fn := range pr.laterFns { + fn() + } + + pkg.MarkComplete() + return pkg +} + +// A reader holds the state for reading a single unified IR element +// within a package. +type reader struct { + pkgbits.Decoder + + p *pkgReader + + dict *readerDict +} + +// A readerDict holds the state for type parameters that parameterize +// the current unified IR element. +type readerDict struct { + // bounds is a slice of typeInfos corresponding to the underlying + // bounds of the element's type parameters. + bounds []typeInfo + + // tparams is a slice of the constructed TypeParams for the element. + tparams []*types.TypeParam + + // devived is a slice of types derived from tparams, which may be + // instantiated while reading the current element. + derived []derivedInfo + derivedTypes []types.Type // lazily instantiated from derived +} + +func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { + return &reader{ + Decoder: pr.NewDecoder(k, idx, marker), + p: pr, + } +} + +// @@@ Positions + +func (r *reader) pos() token.Pos { + r.Sync(pkgbits.SyncPos) + if !r.Bool() { + return token.NoPos + } + + // TODO(mdempsky): Delta encoding. + posBase := r.posBase() + line := r.Uint() + col := r.Uint() + return r.p.fake.pos(posBase, int(line), int(col)) +} + +func (r *reader) posBase() string { + return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) +} + +func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { + if b := pr.posBases[idx]; b != "" { + return b + } + + r := pr.newReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) + + // Within types2, position bases have a lot more details (e.g., + // keeping track of where //line directives appeared exactly). + // + // For go/types, we just track the file name. + + filename := r.String() + + if r.Bool() { // file base + // Was: "b = token.NewTrimmedFileBase(filename, true)" + } else { // line base + pos := r.pos() + line := r.Uint() + col := r.Uint() + + // Was: "b = token.NewLineBase(pos, filename, true, line, col)" + _, _, _ = pos, line, col + } + + b := filename + pr.posBases[idx] = b + return b +} + +// @@@ Packages + +func (r *reader) pkg() *types.Package { + r.Sync(pkgbits.SyncPkg) + return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) +} + +func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { + // TODO(mdempsky): Consider using some non-nil pointer to indicate + // the universe scope, so we don't need to keep re-reading it. + if pkg := pr.pkgs[idx]; pkg != nil { + return pkg + } + + pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() + pr.pkgs[idx] = pkg + return pkg +} + +func (r *reader) doPkg() *types.Package { + path := r.String() + switch path { + case "": + path = r.p.PkgPath() + case "builtin": + return nil // universe + case "unsafe": + return types.Unsafe + } + + if pkg := r.p.imports[path]; pkg != nil { + return pkg + } + + name := r.String() + + 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(imports) + + return pkg +} + +// @@@ Types + +func (r *reader) typ() types.Type { + return r.p.typIdx(r.typInfo(), r.dict) +} + +func (r *reader) typInfo() typeInfo { + r.Sync(pkgbits.SyncType) + if r.Bool() { + return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} + } + return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} +} + +func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { + idx := info.idx + var where *types.Type + if info.derived { + where = &dict.derivedTypes[idx] + idx = dict.derived[idx].idx + } else { + where = &pr.typs[idx] + } + + if typ := *where; typ != nil { + return typ + } + + r := pr.newReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) + r.dict = dict + + typ := r.doTyp() + assert(typ != nil) + + // See comment in pkgReader.typIdx explaining how this happens. + if prev := *where; prev != nil { + return prev + } + + *where = typ + return typ +} + +func (r *reader) doTyp() (res types.Type) { + switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { + default: + errorf("unhandled type tag: %v", tag) + panic("unreachable") + + case pkgbits.TypeBasic: + return types.Typ[r.Len()] + + case pkgbits.TypeNamed: + obj, targs := r.obj() + name := obj.(*types.TypeName) + if len(targs) != 0 { + t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) + return t + } + return name.Type() + + case pkgbits.TypeTypeParam: + return r.dict.tparams[r.Len()] + + case pkgbits.TypeArray: + len := int64(r.Uint64()) + return types.NewArray(r.typ(), len) + case pkgbits.TypeChan: + dir := types.ChanDir(r.Len()) + return types.NewChan(dir, r.typ()) + case pkgbits.TypeMap: + return types.NewMap(r.typ(), r.typ()) + case pkgbits.TypePointer: + return types.NewPointer(r.typ()) + case pkgbits.TypeSignature: + return r.signature(nil, nil, nil) + case pkgbits.TypeSlice: + return types.NewSlice(r.typ()) + case pkgbits.TypeStruct: + return r.structType() + case pkgbits.TypeInterface: + return r.interfaceType() + case pkgbits.TypeUnion: + return r.unionType() + } +} + +func (r *reader) structType() *types.Struct { + fields := make([]*types.Var, r.Len()) + var tags []string + for i := range fields { + pos := r.pos() + pkg, name := r.selector() + ftyp := r.typ() + tag := r.String() + embedded := r.Bool() + + fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) + if tag != "" { + for len(tags) < i { + tags = append(tags, "") + } + tags = append(tags, tag) + } + } + return types.NewStruct(fields, tags) +} + +func (r *reader) unionType() *types.Union { + terms := make([]*types.Term, r.Len()) + for i := range terms { + terms[i] = types.NewTerm(r.Bool(), r.typ()) + } + return types.NewUnion(terms) +} + +func (r *reader) interfaceType() *types.Interface { + methods := make([]*types.Func, r.Len()) + embeddeds := make([]types.Type, r.Len()) + implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() + + for i := range methods { + pos := r.pos() + pkg, name := r.selector() + mtyp := r.signature(nil, nil, nil) + methods[i] = types.NewFunc(pos, pkg, name, mtyp) + } + + for i := range embeddeds { + embeddeds[i] = r.typ() + } + + iface := types.NewInterfaceType(methods, embeddeds) + if implicit { + iface.MarkImplicit() + } + return iface +} + +func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { + r.Sync(pkgbits.SyncSignature) + + params := r.params() + results := r.params() + variadic := r.Bool() + + return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) +} + +func (r *reader) params() *types.Tuple { + r.Sync(pkgbits.SyncParams) + + params := make([]*types.Var, r.Len()) + for i := range params { + params[i] = r.param() + } + + return types.NewTuple(params...) +} + +func (r *reader) param() *types.Var { + r.Sync(pkgbits.SyncParam) + + pos := r.pos() + pkg, name := r.localIdent() + typ := r.typ() + + return types.NewParam(pos, pkg, name, typ) +} + +// @@@ Objects + +func (r *reader) obj() (types.Object, []types.Type) { + r.Sync(pkgbits.SyncObject) + + assert(!r.Bool()) + + pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) + obj := pkgScope(pkg).Lookup(name) + + targs := make([]types.Type, r.Len()) + for i := range targs { + targs[i] = r.typ() + } + + return obj, targs +} + +func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { + rname := pr.newReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) + + objPkg, objName := rname.qualifiedIdent() + assert(objName != "") + + tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) + + if tag == pkgbits.ObjStub { + assert(objPkg == nil || objPkg == types.Unsafe) + return objPkg, objName + } + + if objPkg.Scope().Lookup(objName) == nil { + dict := pr.objDictIdx(idx) + + r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) + r.dict = dict + + declare := func(obj types.Object) { + objPkg.Scope().Insert(obj) + } + + switch tag { + default: + panic("weird") + + case pkgbits.ObjAlias: + pos := r.pos() + typ := r.typ() + declare(types.NewTypeName(pos, objPkg, objName, typ)) + + case pkgbits.ObjConst: + pos := r.pos() + typ := r.typ() + val := r.Value() + declare(types.NewConst(pos, objPkg, objName, typ, val)) + + case pkgbits.ObjFunc: + pos := r.pos() + tparams := r.typeParamNames() + sig := r.signature(nil, nil, tparams) + declare(types.NewFunc(pos, objPkg, objName, sig)) + + case pkgbits.ObjType: + pos := r.pos() + + obj := types.NewTypeName(pos, objPkg, objName, nil) + named := types.NewNamed(obj, nil, nil) + declare(obj) + + named.SetTypeParams(r.typeParamNames()) + + // TODO(mdempsky): Rewrite receiver types to underlying is an + // Interface? The go/types importer does this (I think because + // unit tests expected that), but cmd/compile doesn't care + // about it, so maybe we can avoid worrying about that here. + rhs := r.typ() + r.p.later(func() { + underlying := rhs.Underlying() + named.SetUnderlying(underlying) + }) + + for i, n := 0, r.Len(); i < n; i++ { + named.AddMethod(r.method()) + } + + case pkgbits.ObjVar: + pos := r.pos() + typ := r.typ() + declare(types.NewVar(pos, objPkg, objName, typ)) + } + } + + return objPkg, objName +} + +func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { + r := pr.newReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) + + var dict readerDict + + if implicits := r.Len(); implicits != 0 { + errorf("unexpected object with %v implicit type parameter(s)", implicits) + } + + dict.bounds = make([]typeInfo, r.Len()) + for i := range dict.bounds { + dict.bounds[i] = r.typInfo() + } + + dict.derived = make([]derivedInfo, r.Len()) + dict.derivedTypes = make([]types.Type, len(dict.derived)) + for i := range dict.derived { + dict.derived[i] = derivedInfo{r.Reloc(pkgbits.RelocType), r.Bool()} + } + + // function references follow, but reader doesn't need those + + return &dict +} + +func (r *reader) typeParamNames() []*types.TypeParam { + r.Sync(pkgbits.SyncTypeParamNames) + + // Note: This code assumes it only processes objects without + // implement type parameters. This is currently fine, because + // reader is only used to read in exported declarations, which are + // always package scoped. + + if len(r.dict.bounds) == 0 { + return nil + } + + // Careful: Type parameter lists may have cycles. To allow for this, + // we construct the type parameter list in two passes: first we + // create all the TypeNames and TypeParams, then we construct and + // set the bound type. + + r.dict.tparams = make([]*types.TypeParam, len(r.dict.bounds)) + for i := range r.dict.bounds { + pos := r.pos() + pkg, name := r.localIdent() + + tname := types.NewTypeName(pos, pkg, name, nil) + r.dict.tparams[i] = types.NewTypeParam(tname, nil) + } + + typs := make([]types.Type, len(r.dict.bounds)) + for i, bound := range r.dict.bounds { + typs[i] = r.p.typIdx(bound, r.dict) + } + + // TODO(mdempsky): This is subtle, elaborate further. + // + // We have to save tparams outside of the closure, because + // typeParamNames() can be called multiple times with the same + // dictionary instance. + // + // Also, this needs to happen later to make sure SetUnderlying has + // been called. + // + // TODO(mdempsky): Is it safe to have a single "later" slice or do + // we need to have multiple passes? See comments on CL 386002 and + // go.dev/issue/52104. + tparams := r.dict.tparams + r.p.later(func() { + for i, typ := range typs { + tparams[i].SetConstraint(typ) + } + }) + + return r.dict.tparams +} + +func (r *reader) method() *types.Func { + r.Sync(pkgbits.SyncMethod) + pos := r.pos() + pkg, name := r.selector() + + rparams := r.typeParamNames() + sig := r.signature(r.param(), rparams, nil) + + _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. + return types.NewFunc(pos, pkg, name, sig) +} + +func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } +func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } +func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } + +func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { + r.Sync(marker) + return r.pkg(), r.String() +} + +// pkgScope returns pkg.Scope(). +// If pkg is nil, it returns types.Universe instead. +// +// TODO(mdempsky): Remove after x/tools can depend on Go 1.19. +func pkgScope(pkg *types.Package) *types.Scope { + if pkg != nil { + return pkg.Scope() + } + return types.Universe +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go b/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go new file mode 100644 index 000000000..f0cabde96 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/codes.go @@ -0,0 +1,77 @@ +// Copyright 2021 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 pkgbits + +// A Code is an enum value that can be encoded into bitstreams. +// +// Code types are preferable for enum types, because they allow +// Decoder to detect desyncs. +type Code interface { + // Marker returns the SyncMarker for the Code's dynamic type. + Marker() SyncMarker + + // Value returns the Code's ordinal value. + Value() int +} + +// A CodeVal distinguishes among go/constant.Value encodings. +type CodeVal int + +func (c CodeVal) Marker() SyncMarker { return SyncVal } +func (c CodeVal) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ValBool CodeVal = iota + ValString + ValInt64 + ValBigInt + ValBigRat + ValBigFloat +) + +// A CodeType distinguishes among go/types.Type encodings. +type CodeType int + +func (c CodeType) Marker() SyncMarker { return SyncType } +func (c CodeType) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + TypeBasic CodeType = iota + TypeNamed + TypePointer + TypeSlice + TypeArray + TypeChan + TypeMap + TypeSignature + TypeStruct + TypeInterface + TypeUnion + TypeTypeParam +) + +// A CodeObj distinguishes among go/types.Object encodings. +type CodeObj int + +func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } +func (c CodeObj) Value() int { return int(c) } + +// Note: These values are public and cannot be changed without +// updating the go/types importers. + +const ( + ObjAlias CodeObj = iota + ObjConst + ObjType + ObjFunc + ObjVar + ObjStub +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go b/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go new file mode 100644 index 000000000..2bc793668 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/decoder.go @@ -0,0 +1,433 @@ +// Copyright 2021 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 pkgbits + +import ( + "encoding/binary" + "fmt" + "go/constant" + "go/token" + "math/big" + "os" + "runtime" + "strings" +) + +// A PkgDecoder provides methods for decoding a package's Unified IR +// export data. +type PkgDecoder struct { + // version is the file format version. + version uint32 + + // sync indicates whether the file uses sync markers. + sync bool + + // pkgPath is the package path for the package to be decoded. + // + // TODO(mdempsky): Remove; unneeded since CL 391014. + pkgPath string + + // elemData is the full data payload of the encoded package. + // Elements are densely and contiguously packed together. + // + // The last 8 bytes of elemData are the package fingerprint. + elemData string + + // elemEnds stores the byte-offset end positions of element + // bitstreams within elemData. + // + // For example, element I's bitstream data starts at elemEnds[I-1] + // (or 0, if I==0) and ends at elemEnds[I]. + // + // Note: elemEnds is indexed by absolute indices, not + // section-relative indices. + elemEnds []uint32 + + // elemEndsEnds stores the index-offset end positions of relocation + // sections within elemEnds. + // + // For example, section K's end positions start at elemEndsEnds[K-1] + // (or 0, if K==0) and end at elemEndsEnds[K]. + elemEndsEnds [numRelocs]uint32 +} + +// PkgPath returns the package path for the package +// +// TODO(mdempsky): Remove; unneeded since CL 391014. +func (pr *PkgDecoder) PkgPath() string { return pr.pkgPath } + +// SyncMarkers reports whether pr uses sync markers. +func (pr *PkgDecoder) SyncMarkers() bool { return pr.sync } + +// NewPkgDecoder returns a PkgDecoder initialized to read the Unified +// IR export data from input. pkgPath is the package path for the +// compilation unit that produced the export data. +// +// TODO(mdempsky): Remove pkgPath parameter; unneeded since CL 391014. +func NewPkgDecoder(pkgPath, input string) PkgDecoder { + pr := PkgDecoder{ + pkgPath: pkgPath, + } + + // TODO(mdempsky): Implement direct indexing of input string to + // avoid copying the position information. + + r := strings.NewReader(input) + + assert(binary.Read(r, binary.LittleEndian, &pr.version) == nil) + + switch pr.version { + default: + panic(fmt.Errorf("unsupported version: %v", pr.version)) + case 0: + // no flags + case 1: + var flags uint32 + assert(binary.Read(r, binary.LittleEndian, &flags) == nil) + pr.sync = flags&flagSyncMarkers != 0 + } + + assert(binary.Read(r, binary.LittleEndian, pr.elemEndsEnds[:]) == nil) + + pr.elemEnds = make([]uint32, pr.elemEndsEnds[len(pr.elemEndsEnds)-1]) + assert(binary.Read(r, binary.LittleEndian, pr.elemEnds[:]) == nil) + + pos, err := r.Seek(0, os.SEEK_CUR) + assert(err == nil) + + pr.elemData = input[pos:] + assert(len(pr.elemData)-8 == int(pr.elemEnds[len(pr.elemEnds)-1])) + + return pr +} + +// NumElems returns the number of elements in section k. +func (pr *PkgDecoder) NumElems(k RelocKind) int { + count := int(pr.elemEndsEnds[k]) + if k > 0 { + count -= int(pr.elemEndsEnds[k-1]) + } + return count +} + +// TotalElems returns the total number of elements across all sections. +func (pr *PkgDecoder) TotalElems() int { + return len(pr.elemEnds) +} + +// Fingerprint returns the package fingerprint. +func (pr *PkgDecoder) Fingerprint() [8]byte { + var fp [8]byte + copy(fp[:], pr.elemData[len(pr.elemData)-8:]) + return fp +} + +// AbsIdx returns the absolute index for the given (section, index) +// pair. +func (pr *PkgDecoder) AbsIdx(k RelocKind, idx Index) int { + absIdx := int(idx) + if k > 0 { + absIdx += int(pr.elemEndsEnds[k-1]) + } + if absIdx >= int(pr.elemEndsEnds[k]) { + errorf("%v:%v is out of bounds; %v", k, idx, pr.elemEndsEnds) + } + return absIdx +} + +// DataIdx returns the raw element bitstream for the given (section, +// index) pair. +func (pr *PkgDecoder) DataIdx(k RelocKind, idx Index) string { + absIdx := pr.AbsIdx(k, idx) + + var start uint32 + if absIdx > 0 { + start = pr.elemEnds[absIdx-1] + } + end := pr.elemEnds[absIdx] + + return pr.elemData[start:end] +} + +// StringIdx returns the string value for the given string index. +func (pr *PkgDecoder) StringIdx(idx Index) string { + return pr.DataIdx(RelocString, idx) +} + +// NewDecoder returns a Decoder for the given (section, index) pair, +// and decodes the given SyncMarker from the element bitstream. +func (pr *PkgDecoder) NewDecoder(k RelocKind, idx Index, marker SyncMarker) Decoder { + r := pr.NewDecoderRaw(k, idx) + r.Sync(marker) + return r +} + +// NewDecoderRaw returns a Decoder for the given (section, index) pair. +// +// Most callers should use NewDecoder instead. +func (pr *PkgDecoder) NewDecoderRaw(k RelocKind, idx Index) Decoder { + r := Decoder{ + common: pr, + k: k, + Idx: idx, + } + + // TODO(mdempsky) r.data.Reset(...) after #44505 is resolved. + r.Data = *strings.NewReader(pr.DataIdx(k, idx)) + + r.Sync(SyncRelocs) + r.Relocs = make([]RelocEnt, r.Len()) + for i := range r.Relocs { + r.Sync(SyncReloc) + r.Relocs[i] = RelocEnt{RelocKind(r.Len()), Index(r.Len())} + } + + return r +} + +// A Decoder provides methods for decoding an individual element's +// bitstream data. +type Decoder struct { + common *PkgDecoder + + Relocs []RelocEnt + Data strings.Reader + + k RelocKind + Idx Index +} + +func (r *Decoder) checkErr(err error) { + if err != nil { + errorf("unexpected decoding error: %w", err) + } +} + +func (r *Decoder) rawUvarint() uint64 { + x, err := binary.ReadUvarint(&r.Data) + r.checkErr(err) + return x +} + +func (r *Decoder) rawVarint() int64 { + ux := r.rawUvarint() + + // Zig-zag decode. + x := int64(ux >> 1) + if ux&1 != 0 { + x = ^x + } + return x +} + +func (r *Decoder) rawReloc(k RelocKind, idx int) Index { + e := r.Relocs[idx] + assert(e.Kind == k) + return e.Idx +} + +// Sync decodes a sync marker from the element bitstream and asserts +// that it matches the expected marker. +// +// If r.common.sync is false, then Sync is a no-op. +func (r *Decoder) Sync(mWant SyncMarker) { + if !r.common.sync { + return + } + + pos, _ := r.Data.Seek(0, os.SEEK_CUR) // TODO(mdempsky): io.SeekCurrent after #44505 is resolved + mHave := SyncMarker(r.rawUvarint()) + writerPCs := make([]int, r.rawUvarint()) + for i := range writerPCs { + writerPCs[i] = int(r.rawUvarint()) + } + + if mHave == mWant { + return + } + + // There's some tension here between printing: + // + // (1) full file paths that tools can recognize (e.g., so emacs + // hyperlinks the "file:line" text for easy navigation), or + // + // (2) short file paths that are easier for humans to read (e.g., by + // omitting redundant or irrelevant details, so it's easier to + // focus on the useful bits that remain). + // + // The current formatting favors the former, as it seems more + // helpful in practice. But perhaps the formatting could be improved + // to better address both concerns. For example, use relative file + // paths if they would be shorter, or rewrite file paths to contain + // "$GOROOT" (like objabi.AbsFile does) if tools can be taught how + // to reliably expand that again. + + fmt.Printf("export data desync: package %q, section %v, index %v, offset %v\n", r.common.pkgPath, r.k, r.Idx, pos) + + fmt.Printf("\nfound %v, written at:\n", mHave) + if len(writerPCs) == 0 { + fmt.Printf("\t[stack trace unavailable; recompile package %q with -d=syncframes]\n", r.common.pkgPath) + } + for _, pc := range writerPCs { + fmt.Printf("\t%s\n", r.common.StringIdx(r.rawReloc(RelocString, pc))) + } + + fmt.Printf("\nexpected %v, reading at:\n", mWant) + var readerPCs [32]uintptr // TODO(mdempsky): Dynamically size? + n := runtime.Callers(2, readerPCs[:]) + for _, pc := range fmtFrames(readerPCs[:n]...) { + fmt.Printf("\t%s\n", pc) + } + + // We already printed a stack trace for the reader, so now we can + // simply exit. Printing a second one with panic or base.Fatalf + // would just be noise. + os.Exit(1) +} + +// Bool decodes and returns a bool value from the element bitstream. +func (r *Decoder) Bool() bool { + r.Sync(SyncBool) + x, err := r.Data.ReadByte() + r.checkErr(err) + assert(x < 2) + return x != 0 +} + +// Int64 decodes and returns an int64 value from the element bitstream. +func (r *Decoder) Int64() int64 { + r.Sync(SyncInt64) + return r.rawVarint() +} + +// Int64 decodes and returns a uint64 value from the element bitstream. +func (r *Decoder) Uint64() uint64 { + r.Sync(SyncUint64) + return r.rawUvarint() +} + +// Len decodes and returns a non-negative int value from the element bitstream. +func (r *Decoder) Len() int { x := r.Uint64(); v := int(x); assert(uint64(v) == x); return v } + +// Int decodes and returns an int value from the element bitstream. +func (r *Decoder) Int() int { x := r.Int64(); v := int(x); assert(int64(v) == x); return v } + +// Uint decodes and returns a uint value from the element bitstream. +func (r *Decoder) Uint() uint { x := r.Uint64(); v := uint(x); assert(uint64(v) == x); return v } + +// Code decodes a Code value from the element bitstream and returns +// its ordinal value. It's the caller's responsibility to convert the +// result to an appropriate Code type. +// +// TODO(mdempsky): Ideally this method would have signature "Code[T +// Code] T" instead, but we don't allow generic methods and the +// compiler can't depend on generics yet anyway. +func (r *Decoder) Code(mark SyncMarker) int { + r.Sync(mark) + return r.Len() +} + +// Reloc decodes a relocation of expected section k from the element +// bitstream and returns an index to the referenced element. +func (r *Decoder) Reloc(k RelocKind) Index { + r.Sync(SyncUseReloc) + return r.rawReloc(k, r.Len()) +} + +// String decodes and returns a string value from the element +// bitstream. +func (r *Decoder) String() string { + r.Sync(SyncString) + return r.common.StringIdx(r.Reloc(RelocString)) +} + +// Strings decodes and returns a variable-length slice of strings from +// the element bitstream. +func (r *Decoder) Strings() []string { + res := make([]string, r.Len()) + for i := range res { + res[i] = r.String() + } + return res +} + +// Value decodes and returns a constant.Value from the element +// bitstream. +func (r *Decoder) Value() constant.Value { + r.Sync(SyncValue) + isComplex := r.Bool() + val := r.scalar() + if isComplex { + val = constant.BinaryOp(val, token.ADD, constant.MakeImag(r.scalar())) + } + return val +} + +func (r *Decoder) scalar() constant.Value { + switch tag := CodeVal(r.Code(SyncVal)); tag { + default: + panic(fmt.Errorf("unexpected scalar tag: %v", tag)) + + case ValBool: + return constant.MakeBool(r.Bool()) + case ValString: + return constant.MakeString(r.String()) + case ValInt64: + return constant.MakeInt64(r.Int64()) + case ValBigInt: + return constant.Make(r.bigInt()) + case ValBigRat: + num := r.bigInt() + denom := r.bigInt() + return constant.Make(new(big.Rat).SetFrac(num, denom)) + case ValBigFloat: + return constant.Make(r.bigFloat()) + } +} + +func (r *Decoder) bigInt() *big.Int { + v := new(big.Int).SetBytes([]byte(r.String())) + if r.Bool() { + v.Neg(v) + } + return v +} + +func (r *Decoder) bigFloat() *big.Float { + v := new(big.Float).SetPrec(512) + assert(v.UnmarshalText([]byte(r.String())) == nil) + return v +} + +// @@@ Helpers + +// TODO(mdempsky): These should probably be removed. I think they're a +// smell that the export data format is not yet quite right. + +// PeekPkgPath returns the package path for the specified package +// index. +func (pr *PkgDecoder) PeekPkgPath(idx Index) string { + r := pr.NewDecoder(RelocPkg, idx, SyncPkgDef) + path := r.String() + if path == "" { + path = pr.pkgPath + } + return path +} + +// PeekObj returns the package path, object name, and CodeObj for the +// specified object index. +func (pr *PkgDecoder) PeekObj(idx Index) (string, string, CodeObj) { + r := pr.NewDecoder(RelocName, idx, SyncObject1) + r.Sync(SyncSym) + r.Sync(SyncPkg) + path := pr.PeekPkgPath(r.Reloc(RelocPkg)) + name := r.String() + assert(name != "") + + tag := CodeObj(r.Code(SyncCodeObj)) + + return path, name, tag +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go b/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go new file mode 100644 index 000000000..c8a2796b5 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/doc.go @@ -0,0 +1,32 @@ +// Copyright 2022 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 pkgbits implements low-level coding abstractions for +// Unified IR's export data format. +// +// At a low-level, a package is a collection of bitstream elements. +// Each element has a "kind" and a dense, non-negative index. +// Elements can be randomly accessed given their kind and index. +// +// Individual elements are sequences of variable-length values (e.g., +// integers, booleans, strings, go/constant values, cross-references +// to other elements). Package pkgbits provides APIs for encoding and +// decoding these low-level values, but the details of mapping +// higher-level Go constructs into elements is left to higher-level +// abstractions. +// +// Elements may cross-reference each other with "relocations." For +// example, an element representing a pointer type has a relocation +// referring to the element type. +// +// Go constructs may be composed as a constellation of multiple +// elements. For example, a declared function may have one element to +// describe the object (e.g., its name, type, position), and a +// separate element to describe its function body. This allows readers +// some flexibility in efficiently seeking or re-reading data (e.g., +// inlining requires re-reading the function body for each inlined +// call, without needing to re-read the object-level details). +// +// This is a copy of internal/pkgbits in the Go implementation. +package pkgbits diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go b/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go new file mode 100644 index 000000000..c50c838ca --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/encoder.go @@ -0,0 +1,379 @@ +// Copyright 2021 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 pkgbits + +import ( + "bytes" + "crypto/md5" + "encoding/binary" + "go/constant" + "io" + "math/big" + "runtime" +) + +// currentVersion is the current version number. +// +// - v0: initial prototype +// +// - v1: adds the flags uint32 word +const currentVersion uint32 = 1 + +// A PkgEncoder provides methods for encoding a package's Unified IR +// export data. +type PkgEncoder struct { + // elems holds the bitstream for previously encoded elements. + elems [numRelocs][]string + + // stringsIdx maps previously encoded strings to their index within + // the RelocString section, to allow deduplication. That is, + // elems[RelocString][stringsIdx[s]] == s (if present). + stringsIdx map[string]Index + + // syncFrames is the number of frames to write at each sync + // marker. A negative value means sync markers are omitted. + syncFrames int +} + +// SyncMarkers reports whether pw uses sync markers. +func (pw *PkgEncoder) SyncMarkers() bool { return pw.syncFrames >= 0 } + +// NewPkgEncoder returns an initialized PkgEncoder. +// +// syncFrames is the number of caller frames that should be serialized +// at Sync points. Serializing additional frames results in larger +// export data files, but can help diagnosing desync errors in +// higher-level Unified IR reader/writer code. If syncFrames is +// negative, then sync markers are omitted entirely. +func NewPkgEncoder(syncFrames int) PkgEncoder { + return PkgEncoder{ + stringsIdx: make(map[string]Index), + syncFrames: syncFrames, + } +} + +// DumpTo writes the package's encoded data to out0 and returns the +// package fingerprint. +func (pw *PkgEncoder) DumpTo(out0 io.Writer) (fingerprint [8]byte) { + h := md5.New() + out := io.MultiWriter(out0, h) + + writeUint32 := func(x uint32) { + assert(binary.Write(out, binary.LittleEndian, x) == nil) + } + + writeUint32(currentVersion) + + var flags uint32 + if pw.SyncMarkers() { + flags |= flagSyncMarkers + } + writeUint32(flags) + + // Write elemEndsEnds. + var sum uint32 + for _, elems := range &pw.elems { + sum += uint32(len(elems)) + writeUint32(sum) + } + + // Write elemEnds. + sum = 0 + for _, elems := range &pw.elems { + for _, elem := range elems { + sum += uint32(len(elem)) + writeUint32(sum) + } + } + + // Write elemData. + for _, elems := range &pw.elems { + for _, elem := range elems { + _, err := io.WriteString(out, elem) + assert(err == nil) + } + } + + // Write fingerprint. + copy(fingerprint[:], h.Sum(nil)) + _, err := out0.Write(fingerprint[:]) + assert(err == nil) + + return +} + +// StringIdx adds a string value to the strings section, if not +// already present, and returns its index. +func (pw *PkgEncoder) StringIdx(s string) Index { + if idx, ok := pw.stringsIdx[s]; ok { + assert(pw.elems[RelocString][idx] == s) + return idx + } + + idx := Index(len(pw.elems[RelocString])) + pw.elems[RelocString] = append(pw.elems[RelocString], s) + pw.stringsIdx[s] = idx + return idx +} + +// NewEncoder returns an Encoder for a new element within the given +// section, and encodes the given SyncMarker as the start of the +// element bitstream. +func (pw *PkgEncoder) NewEncoder(k RelocKind, marker SyncMarker) Encoder { + e := pw.NewEncoderRaw(k) + e.Sync(marker) + return e +} + +// NewEncoderRaw returns an Encoder for a new element within the given +// section. +// +// Most callers should use NewEncoder instead. +func (pw *PkgEncoder) NewEncoderRaw(k RelocKind) Encoder { + idx := Index(len(pw.elems[k])) + pw.elems[k] = append(pw.elems[k], "") // placeholder + + return Encoder{ + p: pw, + k: k, + Idx: idx, + } +} + +// An Encoder provides methods for encoding an individual element's +// bitstream data. +type Encoder struct { + p *PkgEncoder + + Relocs []RelocEnt + Data bytes.Buffer // accumulated element bitstream data + + encodingRelocHeader bool + + k RelocKind + Idx Index // index within relocation section +} + +// Flush finalizes the element's bitstream and returns its Index. +func (w *Encoder) Flush() Index { + var sb bytes.Buffer // TODO(mdempsky): strings.Builder after #44505 is resolved + + // Backup the data so we write the relocations at the front. + var tmp bytes.Buffer + io.Copy(&tmp, &w.Data) + + // TODO(mdempsky): Consider writing these out separately so they're + // easier to strip, along with function bodies, so that we can prune + // down to just the data that's relevant to go/types. + if w.encodingRelocHeader { + panic("encodingRelocHeader already true; recursive flush?") + } + w.encodingRelocHeader = true + w.Sync(SyncRelocs) + w.Len(len(w.Relocs)) + for _, rEnt := range w.Relocs { + w.Sync(SyncReloc) + w.Len(int(rEnt.Kind)) + w.Len(int(rEnt.Idx)) + } + + io.Copy(&sb, &w.Data) + io.Copy(&sb, &tmp) + w.p.elems[w.k][w.Idx] = sb.String() + + return w.Idx +} + +func (w *Encoder) checkErr(err error) { + if err != nil { + errorf("unexpected encoding error: %v", err) + } +} + +func (w *Encoder) rawUvarint(x uint64) { + var buf [binary.MaxVarintLen64]byte + n := binary.PutUvarint(buf[:], x) + _, err := w.Data.Write(buf[:n]) + w.checkErr(err) +} + +func (w *Encoder) rawVarint(x int64) { + // Zig-zag encode. + ux := uint64(x) << 1 + if x < 0 { + ux = ^ux + } + + w.rawUvarint(ux) +} + +func (w *Encoder) rawReloc(r RelocKind, idx Index) int { + // TODO(mdempsky): Use map for lookup; this takes quadratic time. + for i, rEnt := range w.Relocs { + if rEnt.Kind == r && rEnt.Idx == idx { + return i + } + } + + i := len(w.Relocs) + w.Relocs = append(w.Relocs, RelocEnt{r, idx}) + return i +} + +func (w *Encoder) Sync(m SyncMarker) { + if !w.p.SyncMarkers() { + return + } + + // Writing out stack frame string references requires working + // relocations, but writing out the relocations themselves involves + // sync markers. To prevent infinite recursion, we simply trim the + // stack frame for sync markers within the relocation header. + var frames []string + if !w.encodingRelocHeader && w.p.syncFrames > 0 { + pcs := make([]uintptr, w.p.syncFrames) + n := runtime.Callers(2, pcs) + frames = fmtFrames(pcs[:n]...) + } + + // TODO(mdempsky): Save space by writing out stack frames as a + // linked list so we can share common stack frames. + w.rawUvarint(uint64(m)) + w.rawUvarint(uint64(len(frames))) + for _, frame := range frames { + w.rawUvarint(uint64(w.rawReloc(RelocString, w.p.StringIdx(frame)))) + } +} + +// Bool encodes and writes a bool value into the element bitstream, +// and then returns the bool value. +// +// For simple, 2-alternative encodings, the idiomatic way to call Bool +// is something like: +// +// if w.Bool(x != 0) { +// // alternative #1 +// } else { +// // alternative #2 +// } +// +// For multi-alternative encodings, use Code instead. +func (w *Encoder) Bool(b bool) bool { + w.Sync(SyncBool) + var x byte + if b { + x = 1 + } + err := w.Data.WriteByte(x) + w.checkErr(err) + return b +} + +// Int64 encodes and writes an int64 value into the element bitstream. +func (w *Encoder) Int64(x int64) { + w.Sync(SyncInt64) + w.rawVarint(x) +} + +// Uint64 encodes and writes a uint64 value into the element bitstream. +func (w *Encoder) Uint64(x uint64) { + w.Sync(SyncUint64) + w.rawUvarint(x) +} + +// Len encodes and writes a non-negative int value into the element bitstream. +func (w *Encoder) Len(x int) { assert(x >= 0); w.Uint64(uint64(x)) } + +// Int encodes and writes an int value into the element bitstream. +func (w *Encoder) Int(x int) { w.Int64(int64(x)) } + +// Len encodes and writes a uint value into the element bitstream. +func (w *Encoder) Uint(x uint) { w.Uint64(uint64(x)) } + +// Reloc encodes and writes a relocation for the given (section, +// index) pair into the element bitstream. +// +// Note: Only the index is formally written into the element +// bitstream, so bitstream decoders must know from context which +// section an encoded relocation refers to. +func (w *Encoder) Reloc(r RelocKind, idx Index) { + w.Sync(SyncUseReloc) + w.Len(w.rawReloc(r, idx)) +} + +// Code encodes and writes a Code value into the element bitstream. +func (w *Encoder) Code(c Code) { + w.Sync(c.Marker()) + w.Len(c.Value()) +} + +// String encodes and writes a string value into the element +// bitstream. +// +// Internally, strings are deduplicated by adding them to the strings +// section (if not already present), and then writing a relocation +// into the element bitstream. +func (w *Encoder) String(s string) { + w.Sync(SyncString) + w.Reloc(RelocString, w.p.StringIdx(s)) +} + +// Strings encodes and writes a variable-length slice of strings into +// the element bitstream. +func (w *Encoder) Strings(ss []string) { + w.Len(len(ss)) + for _, s := range ss { + w.String(s) + } +} + +// Value encodes and writes a constant.Value into the element +// bitstream. +func (w *Encoder) Value(val constant.Value) { + w.Sync(SyncValue) + if w.Bool(val.Kind() == constant.Complex) { + w.scalar(constant.Real(val)) + w.scalar(constant.Imag(val)) + } else { + w.scalar(val) + } +} + +func (w *Encoder) scalar(val constant.Value) { + switch v := constant.Val(val).(type) { + default: + errorf("unhandled %v (%v)", val, val.Kind()) + case bool: + w.Code(ValBool) + w.Bool(v) + case string: + w.Code(ValString) + w.String(v) + case int64: + w.Code(ValInt64) + w.Int64(v) + case *big.Int: + w.Code(ValBigInt) + w.bigInt(v) + case *big.Rat: + w.Code(ValBigRat) + w.bigInt(v.Num()) + w.bigInt(v.Denom()) + case *big.Float: + w.Code(ValBigFloat) + w.bigFloat(v) + } +} + +func (w *Encoder) bigInt(v *big.Int) { + b := v.Bytes() + w.String(string(b)) // TODO: More efficient encoding. + w.Bool(v.Sign() < 0) +} + +func (w *Encoder) bigFloat(v *big.Float) { + b := v.Append(nil, 'p', -1) + w.String(string(b)) // TODO: More efficient encoding. +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go b/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go new file mode 100644 index 000000000..654222745 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/flags.go @@ -0,0 +1,9 @@ +// Copyright 2022 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 pkgbits + +const ( + flagSyncMarkers = 1 << iota // file format contains sync markers +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go new file mode 100644 index 000000000..5294f6a63 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go1.go @@ -0,0 +1,21 @@ +// Copyright 2021 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. + +//go:build !go1.7 +// +build !go1.7 + +// TODO(mdempsky): Remove after #44505 is resolved + +package pkgbits + +import "runtime" + +func walkFrames(pcs []uintptr, visit frameVisitor) { + for _, pc := range pcs { + fn := runtime.FuncForPC(pc) + file, line := fn.FileLine(pc) + + visit(file, line, fn.Name(), pc-fn.Entry()) + } +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go new file mode 100644 index 000000000..2324ae7ad --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/frames_go17.go @@ -0,0 +1,28 @@ +// Copyright 2021 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. + +//go:build go1.7 +// +build go1.7 + +package pkgbits + +import "runtime" + +// walkFrames calls visit for each call frame represented by pcs. +// +// pcs should be a slice of PCs, as returned by runtime.Callers. +func walkFrames(pcs []uintptr, visit frameVisitor) { + if len(pcs) == 0 { + return + } + + frames := runtime.CallersFrames(pcs) + for { + frame, more := frames.Next() + visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) + if !more { + return + } + } +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go b/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go new file mode 100644 index 000000000..7a8f04ab3 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/reloc.go @@ -0,0 +1,42 @@ +// Copyright 2021 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 pkgbits + +// A RelocKind indicates a particular section within a unified IR export. +type RelocKind int + +// An Index represents a bitstream element index within a particular +// section. +type Index int + +// A relocEnt (relocation entry) is an entry in an element's local +// reference table. +// +// TODO(mdempsky): Rename this too. +type RelocEnt struct { + Kind RelocKind + Idx Index +} + +// Reserved indices within the meta relocation section. +const ( + PublicRootIdx Index = 0 + PrivateRootIdx Index = 1 +) + +const ( + RelocString RelocKind = iota + RelocMeta + RelocPosBase + RelocPkg + RelocName + RelocType + RelocObj + RelocObjExt + RelocObjDict + RelocBody + + numRelocs = iota +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/support.go b/vendor/golang.org/x/tools/go/internal/pkgbits/support.go new file mode 100644 index 000000000..ad26d3b28 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/support.go @@ -0,0 +1,17 @@ +// Copyright 2022 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 pkgbits + +import "fmt" + +func assert(b bool) { + if !b { + panic("assertion failed") + } +} + +func errorf(format string, args ...interface{}) { + panic(fmt.Errorf(format, args...)) +} diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go b/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go new file mode 100644 index 000000000..5bd51ef71 --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/sync.go @@ -0,0 +1,113 @@ +// Copyright 2021 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 pkgbits + +import ( + "fmt" + "strings" +) + +// fmtFrames formats a backtrace for reporting reader/writer desyncs. +func fmtFrames(pcs ...uintptr) []string { + res := make([]string, 0, len(pcs)) + walkFrames(pcs, func(file string, line int, name string, offset uintptr) { + // Trim package from function name. It's just redundant noise. + name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") + + res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) + }) + return res +} + +type frameVisitor func(file string, line int, name string, offset uintptr) + +// SyncMarker is an enum type that represents markers that may be +// written to export data to ensure the reader and writer stay +// synchronized. +type SyncMarker int + +//go:generate stringer -type=SyncMarker -trimprefix=Sync + +const ( + _ SyncMarker = iota + + // Public markers (known to go/types importers). + + // Low-level coding markers. + SyncEOF + SyncBool + SyncInt64 + SyncUint64 + SyncString + SyncValue + SyncVal + SyncRelocs + SyncReloc + SyncUseReloc + + // Higher-level object and type markers. + SyncPublic + SyncPos + SyncPosBase + SyncObject + SyncObject1 + SyncPkg + SyncPkgDef + SyncMethod + SyncType + SyncTypeIdx + SyncTypeParamNames + SyncSignature + SyncParams + SyncParam + SyncCodeObj + SyncSym + SyncLocalIdent + SyncSelector + + // Private markers (only known to cmd/compile). + SyncPrivate + + SyncFuncExt + SyncVarExt + SyncTypeExt + SyncPragma + + SyncExprList + SyncExprs + SyncExpr + SyncExprType + SyncAssign + SyncOp + SyncFuncLit + SyncCompLit + + SyncDecl + SyncFuncBody + SyncOpenScope + SyncCloseScope + SyncCloseAnotherScope + SyncDeclNames + SyncDeclName + + SyncStmts + SyncBlockStmt + SyncIfStmt + SyncForStmt + SyncSwitchStmt + SyncRangeStmt + SyncCaseClause + SyncCommClause + SyncSelectStmt + SyncDecls + SyncLabeledStmt + SyncUseObjLocal + SyncAddLocal + SyncLinkname + SyncStmt1 + SyncStmtsEnd + SyncLabel + SyncOptLabel +) diff --git a/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go b/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go new file mode 100644 index 000000000..4a5b0ca5f --- /dev/null +++ b/vendor/golang.org/x/tools/go/internal/pkgbits/syncmarker_string.go @@ -0,0 +1,89 @@ +// Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. + +package pkgbits + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[SyncEOF-1] + _ = x[SyncBool-2] + _ = x[SyncInt64-3] + _ = x[SyncUint64-4] + _ = x[SyncString-5] + _ = x[SyncValue-6] + _ = x[SyncVal-7] + _ = x[SyncRelocs-8] + _ = x[SyncReloc-9] + _ = x[SyncUseReloc-10] + _ = x[SyncPublic-11] + _ = x[SyncPos-12] + _ = x[SyncPosBase-13] + _ = x[SyncObject-14] + _ = x[SyncObject1-15] + _ = x[SyncPkg-16] + _ = x[SyncPkgDef-17] + _ = x[SyncMethod-18] + _ = x[SyncType-19] + _ = x[SyncTypeIdx-20] + _ = x[SyncTypeParamNames-21] + _ = x[SyncSignature-22] + _ = x[SyncParams-23] + _ = x[SyncParam-24] + _ = x[SyncCodeObj-25] + _ = x[SyncSym-26] + _ = x[SyncLocalIdent-27] + _ = x[SyncSelector-28] + _ = x[SyncPrivate-29] + _ = x[SyncFuncExt-30] + _ = x[SyncVarExt-31] + _ = x[SyncTypeExt-32] + _ = x[SyncPragma-33] + _ = x[SyncExprList-34] + _ = x[SyncExprs-35] + _ = x[SyncExpr-36] + _ = x[SyncExprType-37] + _ = x[SyncAssign-38] + _ = x[SyncOp-39] + _ = x[SyncFuncLit-40] + _ = x[SyncCompLit-41] + _ = x[SyncDecl-42] + _ = x[SyncFuncBody-43] + _ = x[SyncOpenScope-44] + _ = x[SyncCloseScope-45] + _ = x[SyncCloseAnotherScope-46] + _ = x[SyncDeclNames-47] + _ = x[SyncDeclName-48] + _ = x[SyncStmts-49] + _ = x[SyncBlockStmt-50] + _ = x[SyncIfStmt-51] + _ = x[SyncForStmt-52] + _ = x[SyncSwitchStmt-53] + _ = x[SyncRangeStmt-54] + _ = x[SyncCaseClause-55] + _ = x[SyncCommClause-56] + _ = x[SyncSelectStmt-57] + _ = x[SyncDecls-58] + _ = x[SyncLabeledStmt-59] + _ = x[SyncUseObjLocal-60] + _ = x[SyncAddLocal-61] + _ = x[SyncLinkname-62] + _ = x[SyncStmt1-63] + _ = x[SyncStmtsEnd-64] + _ = x[SyncLabel-65] + _ = x[SyncOptLabel-66] +} + +const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel" + +var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458} + +func (i SyncMarker) String() string { + i -= 1 + if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { + return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" + } + return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] +} diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go index 50533995a..de881562d 100644 --- a/vendor/golang.org/x/tools/go/packages/golist.go +++ b/vendor/golang.org/x/tools/go/packages/golist.go @@ -302,11 +302,12 @@ func (state *golistState) runContainsQueries(response *responseDeduper, queries } dirResponse, err := state.createDriverResponse(pattern) - // If there was an error loading the package, or the package is returned - // with errors, try to load the file as an ad-hoc package. + // If there was an error loading the package, or no packages are returned, + // or the package is returned with errors, try to load the file as an + // ad-hoc package. // Usually the error will appear in a returned package, but may not if we're // in module mode and the ad-hoc is located outside a module. - if err != nil || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && + if err != nil || len(dirResponse.Packages) == 0 || len(dirResponse.Packages) == 1 && len(dirResponse.Packages[0].GoFiles) == 0 && len(dirResponse.Packages[0].Errors) == 1 { var queryErr error if dirResponse, queryErr = state.adhocPackage(pattern, query); queryErr != nil { diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go index d859617b7..9e373d64e 100644 --- a/vendor/golang.org/x/tools/internal/imports/fix.go +++ b/vendor/golang.org/x/tools/internal/imports/fix.go @@ -796,7 +796,7 @@ func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchP return getCandidatePkgs(ctx, callback, filename, filePkg, env) } -var RequiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB"} +var RequiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB", "GOWORK"} // ProcessEnv contains environment variables and settings that affect the use of // the go command, the go/build package, etc. @@ -906,7 +906,7 @@ func (e *ProcessEnv) GetResolver() (Resolver, error) { if err := e.init(); err != nil { return nil, err } - if len(e.Env["GOMOD"]) == 0 { + if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 { e.resolver = newGopathResolver(e) return e.resolver, nil } diff --git a/vendor/golang.org/x/tools/internal/imports/mod.go b/vendor/golang.org/x/tools/internal/imports/mod.go index 2bcf41f5f..46693f243 100644 --- a/vendor/golang.org/x/tools/internal/imports/mod.go +++ b/vendor/golang.org/x/tools/internal/imports/mod.go @@ -70,9 +70,17 @@ func (r *ModuleResolver) init() error { Logf: r.env.Logf, WorkingDir: r.env.WorkingDir, } - vendorEnabled, mainModVendor, err := gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) - if err != nil { - return err + + vendorEnabled := false + var mainModVendor *gocommand.ModuleJSON + + // Module vendor directories are ignored in workspace mode: + // https://go.googlesource.com/proposal/+/master/design/45713-workspace.md + if len(r.env.Env["GOWORK"]) == 0 { + vendorEnabled, mainModVendor, err = gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner) + if err != nil { + return err + } } if mainModVendor != nil && vendorEnabled { diff --git a/vendor/modules.txt b/vendor/modules.txt index b92444b8a..2e85e791a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -34,7 +34,7 @@ github.com/alecthomas/chroma/styles # github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 ## explicit github.com/bmizerany/assert -# github.com/caddyserver/certmagic v0.16.1 +# github.com/caddyserver/certmagic v0.16.2 ## explicit; go 1.17 github.com/caddyserver/certmagic # github.com/cheekybits/genny v1.0.0 @@ -62,15 +62,15 @@ github.com/didip/tollbooth github.com/didip/tollbooth/errors github.com/didip/tollbooth/libstring github.com/didip/tollbooth/limiter -# github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 -## explicit +# github.com/dlclark/regexp2 v1.7.0 +## explicit; go 1.13 github.com/dlclark/regexp2 github.com/dlclark/regexp2/syntax # github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 ## explicit github.com/eknkc/amber github.com/eknkc/amber/parser -# github.com/evanw/esbuild v0.14.49 +# github.com/evanw/esbuild v0.14.53 ## explicit; go 1.13 github.com/evanw/esbuild/internal/api_helpers github.com/evanw/esbuild/internal/ast @@ -134,7 +134,7 @@ github.com/lib/pq/scram # github.com/libdns/libdns v0.2.1 ## explicit; go 1.14 github.com/libdns/libdns -# github.com/lucas-clemente/quic-go v0.28.0 +# github.com/lucas-clemente/quic-go v0.28.1 ## explicit; go 1.16 github.com/lucas-clemente/quic-go github.com/lucas-clemente/quic-go/http3 @@ -162,7 +162,7 @@ github.com/marten-seemann/qtls-go1-17 # github.com/marten-seemann/qtls-go1-18 v0.1.2 ## explicit; go 1.18 github.com/marten-seemann/qtls-go1-18 -# github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 +# github.com/marten-seemann/qtls-go1-19 v0.1.0 ## explicit; go 1.19 github.com/marten-seemann/qtls-go1-19 # github.com/mattetti/filebuffer v1.0.1 @@ -177,7 +177,7 @@ github.com/mattn/go-isatty # github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d ## explicit github.com/mgutz/ansi -# github.com/mholt/acmez v1.0.3 +# github.com/mholt/acmez v1.0.4 ## explicit; go 1.14 github.com/mholt/acmez github.com/mholt/acmez/acme @@ -243,7 +243,7 @@ github.com/russross/blackfriday/v2 # github.com/shopspring/decimal v1.3.1 ## explicit; go 1.13 github.com/shopspring/decimal -# github.com/sirupsen/logrus v1.8.1 +# github.com/sirupsen/logrus v1.9.0 ## explicit; go 1.13 github.com/sirupsen/logrus # github.com/tylerb/graceful v1.2.15 @@ -352,7 +352,7 @@ github.com/xyproto/tinysvg # github.com/xyproto/unzip v0.0.0-20150601123358-823950573952 ## explicit github.com/xyproto/unzip -# github.com/xyproto/vt100 v1.11.0 +# github.com/xyproto/vt100 v1.11.1 ## explicit; go 1.10 github.com/xyproto/vt100 # github.com/yosssi/gcss v0.1.0 @@ -375,7 +375,7 @@ go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore -# golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d +# golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa ## explicit; go 1.17 golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish @@ -395,7 +395,7 @@ golang.org/x/crypto/ocsp golang.org/x/mod/internal/lazyregexp golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.0.0-20220708220712-1185a9018129 +# golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b ## explicit; go 1.17 golang.org/x/net/bpf golang.org/x/net/http/httpguts @@ -406,7 +406,7 @@ golang.org/x/net/internal/iana golang.org/x/net/internal/socket golang.org/x/net/ipv4 golang.org/x/net/ipv6 -# golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 +# golang.org/x/sys v0.0.0-20220803195053-6e608f9ce704 ## explicit; go 1.17 golang.org/x/sys/cpu golang.org/x/sys/execabs @@ -419,16 +419,17 @@ golang.org/x/text/secure/bidirule golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm -# golang.org/x/time v0.0.0-20220609170525-579cf78fd858 +# golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 ## explicit golang.org/x/time/rate -# golang.org/x/tools v0.1.11 -## explicit; go 1.17 +# golang.org/x/tools v0.1.12 +## explicit; go 1.18 golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/ast/inspector golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/internal/gcimporter golang.org/x/tools/go/internal/packagesdriver +golang.org/x/tools/go/internal/pkgbits golang.org/x/tools/go/packages golang.org/x/tools/imports golang.org/x/tools/internal/event