From 7ea9ee1e9c84e7c3f7fcbcad2775343a0a1a5a5e Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Aug 2026 02:41:37 -0700 Subject: [PATCH 01/10] Update to Go 1.27 --- .github/actions/setup-go/action.yml | 2 +- CONTRIBUTING.md | 2 +- go.work | 2 +- tools/customlint/testdata/go.mod | 2 +- tools/go.mod | 2 +- tsc/go.mod | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/actions/setup-go/action.yml b/.github/actions/setup-go/action.yml index f847a1bd61384..05019e9c57be7 100644 --- a/.github/actions/setup-go/action.yml +++ b/.github/actions/setup-go/action.yml @@ -4,7 +4,7 @@ description: Setup Go inputs: go-version: description: Go version to set up - default: '1.26' + default: '1.27' runs: using: composite diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 813aa73df80c5..6c6d1776bffde 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -75,7 +75,7 @@ In general, things we find useful when reviewing suggestions are: ## Prerequisites -- Go 1.26 +- Go 1.27 - Node.js 24 - npm (the version declared by `packageManager` in `package.json`) - Git diff --git a/go.work b/go.work index e2b190498e8bd..4bfd12b16859f 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.26 +go 1.27 use ( ./tools diff --git a/tools/customlint/testdata/go.mod b/tools/customlint/testdata/go.mod index 66d975102e455..b2466ae844a46 100644 --- a/tools/customlint/testdata/go.mod +++ b/tools/customlint/testdata/go.mod @@ -1,3 +1,3 @@ module testdata -go 1.26 +go 1.27 diff --git a/tools/go.mod b/tools/go.mod index 0dca5d35ea01f..80b2c1124162b 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -1,6 +1,6 @@ module github.com/microsoft/TypeScript/tools -go 1.26 +go 1.27 require ( github.com/anchore/quill v0.7.1 diff --git a/tsc/go.mod b/tsc/go.mod index 5de91445f175b..bb492f73630c4 100644 --- a/tsc/go.mod +++ b/tsc/go.mod @@ -1,6 +1,6 @@ module github.com/microsoft/TypeScript/tsc -go 1.26 +go 1.27 require ( github.com/Microsoft/go-winio v0.6.2 From 14d1881c8c45ab5b03651bb223806aee539c258f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Aug 2026 02:42:36 -0700 Subject: [PATCH 02/10] Use encoding/json/v2 --- .golangci.yml | 2 +- NOTICE.txt | 31 ------------------------------- tsc/go.mod | 1 - tsc/go.sum | 2 -- tsc/internal/json/json.go | 5 ++--- 5 files changed, 3 insertions(+), 38 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b520c5ce2c330..1309650b71452 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -75,7 +75,7 @@ linters: deny: - pkg: 'encoding/json$' desc: 'Use "github.com/microsoft/TypeScript/tsc/internal/json" instead.' - - pkg: 'github.com/go-json-experiment/json' + - pkg: 'encoding/json/v2' desc: 'Use "github.com/microsoft/TypeScript/tsc/internal/json" instead.' forbidigo: diff --git a/NOTICE.txt b/NOTICE.txt index 0c40b1e6165ff..5b005463661cb 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -221,36 +221,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND --------------------------------------------------------- -github.com/go-json-experiment/json v0.0.0-20260623181947-01eb4420fa68 - BSD-3-Clause - - -Copyright 2010 The Go Authors -Copyright 2011 The Go Authors -Copyright 2016 The Go Authors -Copyright 2018 The Go Authors -Copyright 2020 The Go Authors -Copyright 2021 The Go Authors -Copyright 2022 The Go Authors -Copyright 2023 The Go Authors -Copyright 2024 The Go Authors -Copyright (c) 2020 The Go Authors - -Copyright (c) . All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---------------------------------------------------------- - ---------------------------------------------------------- - golang.org/x/sync v0.21.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang @@ -433,4 +403,3 @@ SOFTWARE. --------------------------------------------------------- - diff --git a/tsc/go.mod b/tsc/go.mod index bb492f73630c4..f52266708156d 100644 --- a/tsc/go.mod +++ b/tsc/go.mod @@ -4,7 +4,6 @@ go 1.27 require ( github.com/Microsoft/go-winio v0.6.2 - github.com/go-json-experiment/json v0.0.0-20260623181947-01eb4420fa68 github.com/google/go-cmp v0.7.0 github.com/klauspost/compress v1.19.0 github.com/mackerelio/go-osstat v0.2.7 diff --git a/tsc/go.sum b/tsc/go.sum index 2b6d00df64280..2a8d3cfeb2c7c 100644 --- a/tsc/go.sum +++ b/tsc/go.sum @@ -1,7 +1,5 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/go-json-experiment/json v0.0.0-20260623181947-01eb4420fa68 h1:KZaTBSyshWX3MP5jukJcNSuXDQTO+rNpt0J564dX/eg= -github.com/go-json-experiment/json v0.0.0-20260623181947-01eb4420fa68/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ= diff --git a/tsc/internal/json/json.go b/tsc/internal/json/json.go index 53e0169116325..ddacc5b16451a 100644 --- a/tsc/internal/json/json.go +++ b/tsc/internal/json/json.go @@ -2,11 +2,10 @@ package json import ( + "encoding/json/jsontext" + "encoding/json/v2" "io" "slices" - - "github.com/go-json-experiment/json" - "github.com/go-json-experiment/json/jsontext" ) var allowInvalid []json.Options = slices.Clip([]json.Options{jsontext.AllowInvalidUTF8(true)}) From e6a7493c7f5227e6cdc1462462ce48085d2dd730 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Aug 2026 02:48:32 -0700 Subject: [PATCH 03/10] Update Go dependencies --- NOTICE.txt | 10 +++++----- tools/go.mod | 8 ++++---- tools/go.sum | 24 ++++++++++++------------ tsc/go.mod | 14 +++++++------- tsc/go.sum | 28 ++++++++++++++-------------- 5 files changed, 42 insertions(+), 42 deletions(-) diff --git a/NOTICE.txt b/NOTICE.txt index 5b005463661cb..46d8787f9b90a 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -221,7 +221,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND --------------------------------------------------------- -golang.org/x/sync v0.21.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang +golang.org/x/sync v0.22.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang Copyright 2009 The Go Authors @@ -236,7 +236,7 @@ BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang --------------------------------------------------------- -golang.org/x/sys v0.46.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang +golang.org/x/sys v0.47.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang Copyright 2009 The Go Authors @@ -264,7 +264,7 @@ BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang --------------------------------------------------------- -golang.org/x/term v0.44.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang +golang.org/x/term v0.45.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang Copyright 2009 The Go Authors @@ -279,7 +279,7 @@ BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang --------------------------------------------------------- -golang.org/x/text v0.38.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang +golang.org/x/text v0.41.0 - BSD-3-Clause AND LicenseRef-scancode-google-patent-license-golang (c) AeHa (c) @@ -351,7 +351,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI --------------------------------------------------------- -github.com/mackerelio/go-osstat v0.2.7 - Apache-2.0 +github.com/mackerelio/go-osstat v0.2.8 - Apache-2.0 Copyright 2017-2019 Hatena Co., Ltd. diff --git a/tools/go.mod b/tools/go.mod index 80b2c1124162b..3b74c6d967b2b 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -6,8 +6,8 @@ require ( github.com/anchore/quill v0.7.1 github.com/blacktop/go-macho v1.1.263 github.com/golangci/plugin-module-register v0.1.2 - golang.org/x/mod v0.37.0 - golang.org/x/tools v0.47.0 + golang.org/x/mod v0.40.0 + golang.org/x/tools v0.49.0 gotest.tools/v3 v3.5.2 ) @@ -21,7 +21,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e // indirect - golang.org/x/crypto v0.53.0 // indirect - golang.org/x/sync v0.21.0 // indirect + golang.org/x/crypto v0.55.0 // indirect + golang.org/x/sync v0.22.0 // indirect software.sslmate.com/src/go-pkcs12 v0.7.2 // indirect ) diff --git a/tools/go.sum b/tools/go.sum index 67c702b4dbcb9..2074dbe221e69 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -51,22 +51,22 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= -golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= -golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= -golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= +golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= -golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= -golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= -golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= +golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= +golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tsc/go.mod b/tsc/go.mod index f52266708156d..80fd41fd3f0e3 100644 --- a/tsc/go.mod +++ b/tsc/go.mod @@ -6,13 +6,13 @@ require ( github.com/Microsoft/go-winio v0.6.2 github.com/google/go-cmp v0.7.0 github.com/klauspost/compress v1.19.0 - github.com/mackerelio/go-osstat v0.2.7 + github.com/mackerelio/go-osstat v0.2.8 github.com/peter-evans/patience v0.3.0 github.com/zeebo/xxh3 v1.1.0 - golang.org/x/sync v0.21.0 - golang.org/x/sys v0.46.0 - golang.org/x/term v0.44.0 - golang.org/x/text v0.38.0 + golang.org/x/sync v0.22.0 + golang.org/x/sys v0.47.0 + golang.org/x/term v0.45.0 + golang.org/x/text v0.41.0 gotest.tools/v3 v3.5.2 ) @@ -20,8 +20,8 @@ require ( github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/matryer/moq v0.7.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - golang.org/x/mod v0.37.0 // indirect - golang.org/x/tools v0.47.0 // indirect + golang.org/x/mod v0.40.0 // indirect + golang.org/x/tools v0.49.0 // indirect ) tool ( diff --git a/tsc/go.sum b/tsc/go.sum index 2a8d3cfeb2c7c..bb33ccdc30a2a 100644 --- a/tsc/go.sum +++ b/tsc/go.sum @@ -6,8 +6,8 @@ github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2o github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= -github.com/mackerelio/go-osstat v0.2.7 h1:TCavZi10wF49bT6iQZ9eT2keGZQpC69MTDfdJej5e94= -github.com/mackerelio/go-osstat v0.2.7/go.mod h1:dwpYh5pIPmvk+IEwBKNIWRFMB92mrC08CmXOhDC7nQk= +github.com/mackerelio/go-osstat v0.2.8 h1:I2duicTaCGWoM53XwAwA9OIe1inu0xnVs8/pqOWWVr4= +github.com/mackerelio/go-osstat v0.2.8/go.mod h1:SyS3XxKdoSKJnTGTkN5Yrh6VUQVuAURACfE6y+2DN4k= github.com/matryer/moq v0.7.1 h1:/QaXqMAdOrLqlshW2z7SMS21jDi7aVrbW0wJrR+hhJk= github.com/matryer/moq v0.7.1/go.mod h1:IabIiFkaKCyHxej25INgFR+fnOxSZFMv2LYrU+ioyDs= github.com/peter-evans/patience v0.3.0 h1:rX0JdJeepqdQl1Sk9c9uvorjYYzL2TfgLX1adqYm9cA= @@ -18,17 +18,17 @@ github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= -golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= -golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= -golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM= -golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= -golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc= -golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y= -golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE= -golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4= -golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= -golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= +golang.org/x/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs= +golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE= +golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= +golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= +golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= +golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= +golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI= +golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= From b28405221d11dc092727ed21e16f554b3b8acd9d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Aug 2026 02:54:38 -0700 Subject: [PATCH 04/10] Update golangci-lint to 2.13.0 --- .custom-gcl.yml | 2 +- .golangci.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.custom-gcl.yml b/.custom-gcl.yml index ab1990e91cb3d..83d7fbe027f5d 100644 --- a/.custom-gcl.yml +++ b/.custom-gcl.yml @@ -1,6 +1,6 @@ # yaml-language-server: $schema=https://golangci-lint.run/jsonschema/custom-gcl.jsonschema.json -version: v2.12.2 +version: v2.13.0 destination: ./tools diff --git a/.golangci.yml b/.golangci.yml index 1309650b71452..6b1309bfa69f3 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -67,6 +67,8 @@ linters: modernize: disable: + - embedlit + - slicesclip - slicesbackward # https://github.com/golang/go/issues/78829 depguard: From 5e6544f2a0c45900b815aa81fb5da12a95d040ea Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Aug 2026 02:55:28 -0700 Subject: [PATCH 05/10] Apply Go 1.27 modernizers --- .golangci.yml | 2 - tsc/internal/compiler/contentmapper_test.go | 2 +- tsc/internal/contentmapper/host_test.go | 138 +++++++------- tsc/internal/contentmapper/transform_test.go | 6 +- .../buildinfo_contentmapper_test.go | 22 +-- tsc/internal/execute/tsc/diagnostics.go | 11 +- tsc/internal/format/api_test.go | 32 ++-- tsc/internal/format/comment_test.go | 176 ++++++++---------- tsc/internal/format/format_test.go | 14 +- tsc/internal/fourslash/test_parser.go | 10 +- tsc/internal/ls/autoimport/extract.go | 6 +- tsc/internal/ls/autoimport/registry_test.go | 58 +++--- tsc/internal/ls/findallreferences.go | 6 +- tsc/internal/ls/lsconv/converters.go | 12 +- tsc/internal/ls/lsutil/formatcodeoptions.go | 24 ++- tsc/internal/lsp/server.go | 16 +- .../modulespecifiers/specifiers_test.go | 6 +- tsc/internal/printer/changetrackerwriter.go | 2 +- tsc/internal/project/api.go | 4 +- tsc/internal/project/contentmapper_test.go | 12 +- tsc/internal/project/dirty/map.go | 27 ++- tsc/internal/project/dirty/syncmap.go | 53 +++--- tsc/internal/project/logging/logcollector.go | 8 +- tsc/internal/project/overlayfs.go | 28 ++- tsc/internal/project/refcountcache_test.go | 8 +- tsc/internal/project/session.go | 24 +-- tsc/internal/project/snapshotfs.go | 2 +- .../testutil/autoimporttestutil/fixtures.go | 2 +- .../testutil/contentmappertest/component.go | 2 +- .../testutil/contentmappertest/duplicate.go | 10 +- .../testutil/contentmappertest/editing.go | 14 +- .../testutil/contentmappertest/lisp.go | 4 +- .../testutil/contentmappertest/mapper_test.go | 16 +- .../contentmappertest/supplemental.go | 2 +- .../supplemental_diagnostics.go | 4 +- .../contentmappertest/supplemental_globals.go | 4 +- .../contentmappertest/supplemental_module.go | 4 +- .../contentmappertest/synthesizing.go | 4 +- .../contentmappertest/transforming.go | 4 +- .../estransforms/taggedtemplate.go | 3 +- tsc/internal/tsoptions/contentmappers_test.go | 8 +- .../tsoptions/tsconfigparsing_test.go | 16 +- 42 files changed, 353 insertions(+), 453 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 6b1309bfa69f3..1309650b71452 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -67,8 +67,6 @@ linters: modernize: disable: - - embedlit - - slicesclip - slicesbackward # https://github.com/golang/go/issues/78829 depguard: diff --git a/tsc/internal/compiler/contentmapper_test.go b/tsc/internal/compiler/contentmapper_test.go index 197914d47aaee..6977d87a1ac4c 100644 --- a/tsc/internal/compiler/contentmapper_test.go +++ b/tsc/internal/compiler/contentmapper_test.go @@ -59,7 +59,7 @@ func newContentMapperProgramWithOptions(t *testing.T, contentMapperProject conte ParsedConfig: &tsoptions.ParsedOptions{ FileNames: rootFiles, CompilerOptions: options, - ContentMappers: []*contentmapper.Mapper{{Definition: contentmapper.Definition{Package: "vue", Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "vue-mapper", Version: "1.0.0"}}}, + ContentMappers: []*contentmapper.Mapper{{Package: "vue", Extensions: []string{".vue"}, Name: "vue-mapper", Version: "1.0.0"}}, }, } return compiler.NewProgram(compiler.ProgramOptions{ diff --git a/tsc/internal/contentmapper/host_test.go b/tsc/internal/contentmapper/host_test.go index b5a8a807f2c6b..8a4ee52b26129 100644 --- a/tsc/internal/contentmapper/host_test.go +++ b/tsc/internal/contentmapper/host_test.go @@ -68,7 +68,7 @@ func (fakeMapper) HandleRequest(ctx context.Context, method string, params json. return nil, err } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: p.Content, Extension: ".ts", Mappings: json.Value(mappings)}, + Text: p.Content, Extension: ".ts", Mappings: json.Value(mappings), Diagnostics: []contentmapper.Diagnostic{{ MessageText: "boom", Start: 0, @@ -121,7 +121,7 @@ func (m unicodeMapper) HandleRequest(ctx context.Context, method string, params case contentmapper.PositionEncodingUTF16: emojiLength, textLength = 1, 2 default: - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: p.Content, Extension: ".ts"}}, nil + return contentmapper.TransformResult{Text: p.Content, Extension: ".ts"}, nil } mappings, err := json.Marshal([][5]int{ {0, emojiLength, 0, emojiLength, int(spanmap.KindVerbatim)}, @@ -131,18 +131,16 @@ func (m unicodeMapper) HandleRequest(ctx context.Context, method string, params return nil, err } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{ - Text: p.Content, - Extension: ".ts", - Mappings: mappings, - DiagnosticDirectives: protocolDiagnosticDirectives([]contentmapper.MappedDiagnosticDirective{{ - OriginalStart: emojiLength, - OriginalLength: textLength - emojiLength, - VirtualStart: emojiLength, - VirtualEnd: textLength, - Policy: contentmapper.DiagnosticDirectivePolicyIgnore, - }}), - }, + Text: p.Content, + Extension: ".ts", + Mappings: mappings, + DiagnosticDirectives: protocolDiagnosticDirectives([]contentmapper.MappedDiagnosticDirective{{ + OriginalStart: emojiLength, + OriginalLength: textLength - emojiLength, + VirtualStart: emojiLength, + VirtualEnd: textLength, + Policy: contentmapper.DiagnosticDirectivePolicyIgnore, + }}), Diagnostics: []contentmapper.Diagnostic{{ MessageText: "after non-ASCII character", Start: emojiLength, @@ -169,7 +167,7 @@ func (m invalidDiagnosticMapper) HandleRequest(ctx context.Context, method strin return contentmapper.InitializeResult{PositionEncoding: m.encoding, DiagnosticSource: "mapper"}, nil case contentmapper.MethodTransform: return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Extension: ".ts"}, + Extension: ".ts", Diagnostics: []contentmapper.Diagnostic{{ MessageText: "invalid boundary", Start: 1, @@ -240,7 +238,7 @@ func TestRunnerTransform(t *testing.T) { r := contentmapper.NewHost(t.Context(), &fakeSpawner{}, locale.Default) defer r.Close() - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}, Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}} result, err := r.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: "export const x = 1;"}) assert.NilError(t, err) assert.Equal(t, result.Text, "export const x = 1;") @@ -267,8 +265,8 @@ func TestHostLogging(t *testing.T) { host := contentmapper.NewHostWithOptions(t.Context(), spawner, locale.Default, contentmapper.HostOptions{Logger: logger}) defer host.Close() mapper := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "configured", Extensions: []string{".vue"}}, - Manifest: contentmapper.Manifest{Name: "resolved", Version: "1.0.0", Exec: []string{"mapper"}}, + Package: "configured", Extensions: []string{".vue"}, + Name: "resolved", Version: "1.0.0", Exec: []string{"mapper"}, } _, err := host.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: "export const x = 1;"}) assert.NilError(t, err) @@ -290,8 +288,8 @@ func TestHostDiscardsStderrWithoutLogging(t *testing.T) { host := contentmapper.NewHost(t.Context(), spawner, locale.Default) defer host.Close() mapper := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "configured", Extensions: []string{".vue"}}, - Manifest: contentmapper.Manifest{Name: "resolved", Version: "1.0.0", Exec: []string{"mapper"}}, + Package: "configured", Extensions: []string{".vue"}, + Name: "resolved", Version: "1.0.0", Exec: []string{"mapper"}, } _, err := host.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: "export const x = 1;"}) assert.NilError(t, err) @@ -303,8 +301,8 @@ func TestMapperDiagnosticName(t *testing.T) { mapper *contentmapper.Mapper want string }{ - {mapper: &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "configured"}, Manifest: contentmapper.Manifest{Name: "resolved"}, ContributionID: "contributed"}, want: "resolved"}, - {mapper: &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "configured"}, ContributionID: "contributed"}, want: "configured"}, + {mapper: &contentmapper.Mapper{Package: "configured", Name: "resolved", ContributionID: "contributed"}, want: "resolved"}, + {mapper: &contentmapper.Mapper{Package: "configured", ContributionID: "contributed"}, want: "configured"}, {mapper: &contentmapper.Mapper{ContributionID: "contributed"}, want: "contributed"}, } for _, test := range tests { @@ -315,7 +313,7 @@ func TestMapperDiagnosticName(t *testing.T) { func TestRunnerTransformResponseValidation(t *testing.T) { t.Parallel() request := contentmapper.Request{FileName: "/a.vue", Content: "a"} - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}, Name: "mapper", Exec: []string{"mapper"}} t.Run("malformed result fails the request", func(t *testing.T) { t.Parallel() @@ -350,7 +348,7 @@ func TestHostClosesProcessWhenReadLoopFails(t *testing.T) { }) host := contentmapper.NewHost(t.Context(), spawner, locale.Default) defer host.Close() - mapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Name: "mapper", Exec: []string{"mapper"}} _, err := host.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: ""}) assert.Assert(t, err != nil) processClosed := false @@ -376,7 +374,7 @@ func TestHostReportsInitializationTimeoutBeforeClosingProcess(t *testing.T) { }) host := contentmapper.NewHost(t.Context(), spawner, locale.Default) defer host.Close() - mapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Name: "mapper", Exec: []string{"mapper"}} _, err := host.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: ""}) initializeError, ok := errors.AsType[*contentmapper.InitializeError](err) assert.Assert(t, ok, "expected InitializeError, got %v", err) @@ -392,7 +390,7 @@ func TestHostReportsProcessExitBeforeInitialization(t *testing.T) { }) host := contentmapper.NewHost(t.Context(), spawner, locale.Default) defer host.Close() - mapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Name: "mapper", Exec: []string{"mapper"}} _, err := host.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: ""}) initializeError, ok := errors.AsType[*contentmapper.InitializeError](err) assert.Assert(t, ok, "expected InitializeError, got %v", err) @@ -438,7 +436,7 @@ func (c *closeSignalReadWriteCloser) Close() error { func TestRunnerTransformDiagnosticDirectives(t *testing.T) { t.Parallel() request := contentmapper.Request{FileName: "/a.vue", Content: "directive\nsource"} - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}, Name: "mapper", Exec: []string{"mapper"}} transform := func(output contentmapper.MappedOutput) (contentmapper.Result, error) { host := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: responseMapper{response: func(p contentmapper.TransformParams) any { return contentmapper.TransformResult{MappedOutput: output} @@ -649,21 +647,21 @@ func TestRunnerTransformSupplementalOutputs(t *testing.T) { t.Parallel() host := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: responseMapper{response: func(p contentmapper.TransformParams) any { return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: "export default 1;", Extension: ".ts"}, + Text: "export default 1;", Extension: ".ts", Supplemental: []contentmapper.SupplementalOutput{ - {MappedOutput: contentmapper.MappedOutput{ + { Text: "declare const first: string;", Extension: ".ts", DiagnosticDirectives: protocolDiagnosticDirectives([]contentmapper.MappedDiagnosticDirective{{ VirtualEnd: 7, Policy: contentmapper.DiagnosticDirectivePolicyIgnore, }}), - }}, - {MappedOutput: contentmapper.MappedOutput{Text: "declare const second: number;", Extension: ".mjs"}}, + }, + {Text: "declare const second: number;", Extension: ".mjs"}, }, } }}}, locale.Default) defer host.Close() - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}, Name: "mapper", Exec: []string{"mapper"}} result, err := host.Transform(mapper, contentmapper.Request{FileName: "/component.vue", Content: "component"}) assert.NilError(t, err) assert.Equal(t, len(result.Supplemental), 2) @@ -680,22 +678,20 @@ func TestRunnerTransformInvalidSupplementalDiagnosticDirective(t *testing.T) { t.Parallel() host := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: responseMapper{response: func(p contentmapper.TransformParams) any { return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: "export {};", Extension: ".ts"}, + Text: "export {};", Extension: ".ts", Supplemental: []contentmapper.SupplementalOutput{ - {MappedOutput: contentmapper.MappedOutput{Text: "export {};", Extension: ".ts"}}, + {Text: "export {};", Extension: ".ts"}, { - MappedOutput: contentmapper.MappedOutput{ - Text: "export {};", Extension: ".ts", - DiagnosticDirectives: protocolDiagnosticDirectives([]contentmapper.MappedDiagnosticDirective{{ - Policy: contentmapper.DiagnosticDirectivePolicyExpect, - }}), - }, + Text: "export {};", Extension: ".ts", + DiagnosticDirectives: protocolDiagnosticDirectives([]contentmapper.MappedDiagnosticDirective{{ + Policy: contentmapper.DiagnosticDirectivePolicyExpect, + }}), }, }, } }}}, locale.Default) defer host.Close() - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}, Name: "mapper", Exec: []string{"mapper"}} _, err := host.Transform(mapper, contentmapper.Request{FileName: "/component.vue", Content: "component"}) directiveError, ok := errors.AsType[*contentmapper.DiagnosticDirectiveError](err) assert.Assert(t, ok) @@ -715,15 +711,15 @@ func TestRunnerRejectsInvalidVirtualExtension(t *testing.T) { var supplementalOutputs []contentmapper.SupplementalOutput if supplemental { canonicalExtension = ".ts" - supplementalOutputs = []contentmapper.SupplementalOutput{{MappedOutput: contentmapper.MappedOutput{Text: "export {};", Extension: extension}}} + supplementalOutputs = []contentmapper.SupplementalOutput{{Text: "export {};", Extension: extension}} } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: "export {};", Extension: canonicalExtension}, + Text: "export {};", Extension: canonicalExtension, Supplemental: supplementalOutputs, } }}}, locale.Default) defer host.Close() - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "mapper", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}, Name: "mapper", Exec: []string{"mapper"}} _, err := host.Transform(mapper, contentmapper.Request{FileName: "/component.vue", Content: "component"}) assert.ErrorContains(t, err, "invalid virtual extension") }) @@ -741,7 +737,7 @@ func TestRunnerPositionEncodings(t *testing.T) { t.Parallel() r := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: unicodeMapper{encoding: encoding}}, locale.Default) defer r.Close() - mapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: string(encoding), Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Name: string(encoding), Exec: []string{"mapper"}} result, err := r.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: "éx"}) assert.NilError(t, err) segments := result.Mappings.Segments() @@ -770,7 +766,7 @@ func TestRunnerRejectsUnsupportedPositionEncoding(t *testing.T) { t.Parallel() r := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: unicodeMapper{encoding: "utf-32"}}, locale.Default) defer r.Close() - mapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "invalid", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Name: "invalid", Exec: []string{"mapper"}} _, err := r.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: "x"}) assert.ErrorContains(t, err, "unsupported position encoding") } @@ -783,7 +779,7 @@ func TestRunnerRejectsInvalidDiagnosticSource(t *testing.T) { handler := unicodeMapper{encoding: contentmapper.PositionEncodingUTF8, source: &source} r := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: handler}, locale.Default) defer r.Close() - mapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "invalid", Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Name: "invalid", Exec: []string{"mapper"}} _, err := r.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: "x"}) if strings.TrimSpace(source) == "" { assert.ErrorContains(t, err, "diagnostic source must not be empty") @@ -807,7 +803,7 @@ func TestRunnerRejectsPositionsInsideUnicodeCharacters(t *testing.T) { t.Parallel() r := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: invalidDiagnosticMapper{encoding: test.encoding}}, locale.Default) defer r.Close() - mapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: string(test.encoding), Exec: []string{"mapper"}}} + mapper := &contentmapper.Mapper{Name: string(test.encoding), Exec: []string{"mapper"}} _, err := r.Transform(mapper, contentmapper.Request{FileName: "/a.vue", Content: test.content}) assert.ErrorContains(t, err, "splits a Unicode code point") }) @@ -821,9 +817,9 @@ func TestRunnerConsolidatesByIdentity(t *testing.T) { defer r.Close() // Two logically-separate mappers with the same identity share one process. - vueA := &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "a"}, Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}}} - vueB := &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "b"}, Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}}} - svelte := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "svelte", Version: "2.0.0", Exec: []string{"svelte-mapper"}}} + vueA := &contentmapper.Mapper{Package: "a", Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}} + vueB := &contentmapper.Mapper{Package: "b", Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}} + svelte := &contentmapper.Mapper{Name: "svelte", Version: "2.0.0", Exec: []string{"svelte-mapper"}} project := r.Project(contentmapper.ProjectSpec{Mappers: []*contentmapper.Mapper{vueA, vueB, svelte}, CompilerOptions: &core.CompilerOptions{}}) defer project.Close() @@ -840,9 +836,9 @@ func TestRunnerLeaseLifecycle(t *testing.T) { r := contentmapper.NewHost(t.Context(), &spawner, locale.Default) defer r.Close() - vueA := &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "a"}, Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}}} - vueB := &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "b"}, Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}}} - svelte := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "svelte", Version: "2.0.0", Exec: []string{"svelte-mapper"}}} + vueA := &contentmapper.Mapper{Package: "a", Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}} + vueB := &contentmapper.Mapper{Package: "b", Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}} + svelte := &contentmapper.Mapper{Name: "svelte", Version: "2.0.0", Exec: []string{"svelte-mapper"}} releaseVueA := r.Acquire([]*contentmapper.Mapper{vueA, vueA}) releaseVueB := r.Acquire([]*contentmapper.Mapper{vueB}) @@ -966,7 +962,7 @@ func (m *recordingMapper) HandleRequest(ctx context.Context, method string, para m.transformHandle = p.ProjectHandle m.transformParams = string(params) m.mu.Unlock() - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: p.Content, Extension: ".ts"}}, nil + return contentmapper.TransformResult{Text: p.Content, Extension: ".ts"}, nil default: return nil, fmt.Errorf("unexpected method %s", method) } @@ -980,8 +976,8 @@ func TestProjectLifecycle(t *testing.T) { defer host.Close() staticMapper := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Options: []byte(`{"mode":"static"}`)}, - Manifest: contentmapper.Manifest{Name: "static", Version: "1.0.0", Exec: []string{"mapper"}}, + Options: []byte(`{"mode":"static"}`), + Name: "static", Version: "1.0.0", Exec: []string{"mapper"}, } staticProject := host.Project(contentmapper.ProjectSpec{ ConfigFileName: "/repo/tsconfig.json", @@ -995,12 +991,12 @@ func TestProjectLifecycle(t *testing.T) { assert.NilError(t, staticProject.Close()) dynamicA := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Options: []byte(`{"mode":"a"}`)}, - Manifest: contentmapper.Manifest{Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, CompilerOptions: []string{"jsx"}, DynamicConfig: true}, + Options: []byte(`{"mode":"a"}`), + Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, CompilerOptions: []string{"jsx"}, DynamicConfig: true, } dynamicB := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Options: []byte(`{"mode":"b"}`)}, - Manifest: contentmapper.Manifest{Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true}, + Options: []byte(`{"mode":"b"}`), + Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true, } dynamicAOptions := &core.CompilerOptions{} projectA := host.Project(contentmapper.ProjectSpec{ @@ -1080,7 +1076,7 @@ func TestProjectMethodsAfterHostClose(t *testing.T) { mapperProcess := &recordingMapper{dynamicConfig: true} host := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: mapperProcess}, locale.Default) mapper := &contentmapper.Mapper{ - Manifest: contentmapper.Manifest{Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true}, + Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true, } project := host.Project(contentmapper.ProjectSpec{ ConfigFileName: "/repo/tsconfig.json", @@ -1120,8 +1116,8 @@ func TestProjectRejectsRelativeWatchedFiles(t *testing.T) { defer host.Close() projectMapper := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "dynamic"}, - Manifest: contentmapper.Manifest{Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true}, + Package: "dynamic", + Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true, } project := host.Project(contentmapper.ProjectSpec{ ConfigFileName: "/repo/tsconfig.json", @@ -1144,8 +1140,8 @@ func TestDynamicProjectRequiresConfigIdentity(t *testing.T) { defer host.Close() projectMapper := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "dynamic"}, - Manifest: contentmapper.Manifest{Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true}, + Package: "dynamic", + Name: "dynamic", Version: "1.0.0", Exec: []string{"mapper"}, DynamicConfig: true, } project := host.Project(contentmapper.ProjectSpec{ ConfigFileName: "/repo/tsconfig.json", @@ -1175,7 +1171,7 @@ func TestStaticMapperRejectsDynamicProjectResponseFields(t *testing.T) { t.Parallel() host := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: test.mapper}, locale.Default) defer host.Close() - projectMapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "static", Version: "1.0.0", Exec: []string{"mapper"}}} + projectMapper := &contentmapper.Mapper{Name: "static", Version: "1.0.0", Exec: []string{"mapper"}} project := host.Project(contentmapper.ProjectSpec{ ConfigFileName: "/repo/tsconfig.json", Mappers: []*contentmapper.Mapper{projectMapper}, @@ -1201,7 +1197,7 @@ func TestProjectRejectsInvalidOptionDiagnosticPath(t *testing.T) { }}} host := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: mapperProcess}, locale.Default) defer host.Close() - projectMapper := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "mapper", Version: "1.0.0", Exec: []string{"mapper"}}} + projectMapper := &contentmapper.Mapper{Name: "mapper", Version: "1.0.0", Exec: []string{"mapper"}} project := host.Project(contentmapper.ProjectSpec{Mappers: []*contentmapper.Mapper{projectMapper}, CompilerOptions: &core.CompilerOptions{}}) defer project.Close() _, err := project.Transform(projectMapper, contentmapper.Request{FileName: "/repo/file.ext", Content: "x"}) @@ -1224,7 +1220,7 @@ func TestRunnerForwardsProjectOptions(t *testing.T) { r := contentmapper.NewHost(t.Context(), &fakeSpawner{handler: mapper}, diagnosticLocale) defer r.Close() - mapperDefinition := &contentmapper.Mapper{Definition: contentmapper.Definition{Options: []byte(`{"strictTemplates":true}`)}, Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}, CompilerOptions: []string{"target", "jsx"}}} + mapperDefinition := &contentmapper.Mapper{Options: []byte(`{"strictTemplates":true}`), Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}, CompilerOptions: []string{"target", "jsx"}} compilerOptions := &core.CompilerOptions{Target: core.ScriptTargetES2020, Strict: core.TSTrue} project := r.Project(contentmapper.ProjectSpec{Mappers: []*contentmapper.Mapper{mapperDefinition}, CompilerOptions: compilerOptions}) defer project.Close() @@ -1255,7 +1251,7 @@ func TestHostSetLocaleRestartsMapper(t *testing.T) { r := contentmapper.NewHost(t.Context(), spawner, locale.Default) defer r.Close() - definition := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}}} + definition := &contentmapper.Mapper{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}} release := r.Acquire([]*contentmapper.Mapper{definition}) defer release() @@ -1282,7 +1278,7 @@ func TestHostSetLocaleWaitsForTransform(t *testing.T) { spawner := &fakeSpawner{handler: mapper} r := contentmapper.NewHost(t.Context(), spawner, locale.Default) defer r.Close() - definition := &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}}} + definition := &contentmapper.Mapper{Name: "vue", Version: "1.0.0", Exec: []string{"vue-mapper"}} transformDone := make(chan error) go func() { diff --git a/tsc/internal/contentmapper/transform_test.go b/tsc/internal/contentmapper/transform_test.go index e902cfb112bc6..a961cf70d7229 100644 --- a/tsc/internal/contentmapper/transform_test.go +++ b/tsc/internal/contentmapper/transform_test.go @@ -30,7 +30,7 @@ func TestParseResultSupplementalFileExtensions(t *testing.T) { files, err := contentmapper.ParseResult( ast.SourceFileParseOptions{FileName: "/component.astro", Path: "/component.astro"}, "", - &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".astro"}}, Manifest: contentmapper.Manifest{Name: "mapper"}}, + &contentmapper.Mapper{Extensions: []string{".astro"}, Name: "mapper"}, "transform-identity", result, ) @@ -68,7 +68,7 @@ func TestParseResultAllowsSupplementalModules(t *testing.T) { files, err := contentmapper.ParseResult( ast.SourceFileParseOptions{FileName: "/component.astro", Path: "/component.astro"}, "", - &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".astro"}}, Manifest: contentmapper.Manifest{Name: "mapper"}}, + &contentmapper.Mapper{Extensions: []string{".astro"}, Name: "mapper"}, "", contentmapper.Result{ Text: "export {};", @@ -91,7 +91,7 @@ func TestParseResultDoesNotLeakCanonicalModuleForcingToSupplementals(t *testing. files, err := contentmapper.ParseResult( ast.SourceFileParseOptions{FileName: "/component.astro", Path: "/component.astro"}, "", - &contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "mapper"}}, + &contentmapper.Mapper{Name: "mapper"}, "", contentmapper.Result{ Text: "const canonical = 1;", diff --git a/tsc/internal/execute/incremental/buildinfo_contentmapper_test.go b/tsc/internal/execute/incremental/buildinfo_contentmapper_test.go index bd2ae47240384..9a7229041aefd 100644 --- a/tsc/internal/execute/incremental/buildinfo_contentmapper_test.go +++ b/tsc/internal/execute/incremental/buildinfo_contentmapper_test.go @@ -25,24 +25,24 @@ func configWithMappers(mappers ...*contentmapper.Mapper) *tsoptions.ParsedComman func TestStaticContentMapperTransformIdentity(t *testing.T) { t.Parallel() - assert.Equal(t, (&contentmapper.Mapper{Manifest: contentmapper.Manifest{Name: "vue", Version: "2.0.0"}}).Identity(), "vue@2.0.0") - assert.Equal(t, (&contentmapper.Mapper{Definition: contentmapper.Definition{Package: "anon"}}).Identity(), "") + assert.Equal(t, (&contentmapper.Mapper{Name: "vue", Version: "2.0.0"}).Identity(), "vue@2.0.0") + assert.Equal(t, (&contentmapper.Mapper{Package: "anon"}).Identity(), "") jsxMapper := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "jsx"}, - Manifest: contentmapper.Manifest{Name: "jsx", Version: "1.0.0", CompilerOptions: []string{"jsx"}}, + Package: "jsx", + Name: "jsx", Version: "1.0.0", CompilerOptions: []string{"jsx"}, } jsxPreserveIdentity := jsxMapper.TransformIdentity(&core.CompilerOptions{Jsx: core.JsxEmitPreserve}) jsxReactIdentity := jsxMapper.TransformIdentity(&core.CompilerOptions{Jsx: core.JsxEmitReact}) assert.Assert(t, jsxPreserveIdentity != jsxReactIdentity) optionsA := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "vue", Options: []byte(`{"mode":"a"}`)}, - Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0"}, + Package: "vue", Options: []byte(`{"mode":"a"}`), + Name: "vue", Version: "1.0.0", } optionsB := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "vue", Options: []byte(`{"mode":"b"}`)}, - Manifest: contentmapper.Manifest{Name: "vue", Version: "1.0.0"}, + Package: "vue", Options: []byte(`{"mode":"b"}`), + Name: "vue", Version: "1.0.0", } assert.Assert(t, optionsA.TransformIdentity(&core.CompilerOptions{}) != optionsB.TransformIdentity(&core.CompilerOptions{})) } @@ -78,8 +78,8 @@ func (p fakeContentMapperProject) Close() error { return nil } func TestDynamicContentMapperIdentities(t *testing.T) { t.Parallel() config := configWithMappers(&contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: "dynamic"}, - Manifest: contentmapper.Manifest{Name: "dynamic", Version: "1.0.0", DynamicConfig: true}, + Package: "dynamic", + Name: "dynamic", Version: "1.0.0", DynamicConfig: true, }) project := fakeContentMapperProject{identities: []string{"dynamic@1.0.0:opaque"}} identities, err := incremental.ContentMapperIdentities(project) @@ -114,7 +114,7 @@ func TestReadBuildInfoProgramContentMapperIdentityMismatch(t *testing.T) { FileNames: []string{"/src/a.ts"}, ContentMapperIdentities: []string{"vue@1.0.0"}, } - config := configWithMappers(&contentmapper.Mapper{Definition: contentmapper.Definition{Package: "vue", Extensions: []string{".vue"}}, Manifest: contentmapper.Manifest{Name: "vue", Version: "2.0.0"}}) + config := configWithMappers(&contentmapper.Mapper{Package: "vue", Extensions: []string{".vue"}, Name: "vue", Version: "2.0.0"}) project := fakeContentMapperProject{identities: []string{"vue@2.0.0:current"}} host := compiler.NewCompilerHost("/", vfstest.FromMap[any](nil, true), "", nil, nil, project) diff --git a/tsc/internal/execute/tsc/diagnostics.go b/tsc/internal/execute/tsc/diagnostics.go index c4fa7b5ba6f41..f9f5033723439 100644 --- a/tsc/internal/execute/tsc/diagnostics.go +++ b/tsc/internal/execute/tsc/diagnostics.go @@ -9,17 +9,14 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/diagnosticwriter" "github.com/microsoft/TypeScript/tsc/internal/locale" - "github.com/microsoft/TypeScript/tsc/internal/tspath" ) func getFormatOptsOfSys(sys System, locale locale.Locale) *diagnosticwriter.FormattingOptions { return &diagnosticwriter.FormattingOptions{ - NewLine: "\n", - ComparePathsOptions: tspath.ComparePathsOptions{ - CurrentDirectory: sys.GetCurrentDirectory(), - UseCaseSensitiveFileNames: sys.FS().UseCaseSensitiveFileNames(), - }, - Locale: locale, + NewLine: "\n", + CurrentDirectory: sys.GetCurrentDirectory(), + UseCaseSensitiveFileNames: sys.FS().UseCaseSensitiveFileNames(), + Locale: locale, } } diff --git a/tsc/internal/format/api_test.go b/tsc/internal/format/api_test.go index d42df56296710..d393f28961ff6 100644 --- a/tsc/internal/format/api_test.go +++ b/tsc/internal/format/api_test.go @@ -40,15 +40,13 @@ func TestFormat(t *testing.T) { t.Run("format checker.ts", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 4, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 4, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") filePath := filepath.Join(repo.TestDataPath(), "fixtures/compiler/checker.ts") @@ -68,15 +66,13 @@ func TestFormat(t *testing.T) { func BenchmarkFormat(b *testing.B) { ctx := format.WithFormatCodeSettings(b.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 4, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 4, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") filePath := filepath.Join(repo.TestDataPath(), "fixtures/compiler/checker.ts") diff --git a/tsc/internal/format/comment_test.go b/tsc/internal/format/comment_test.go index b8162975f298d..33cbce0a4f059 100644 --- a/tsc/internal/format/comment_test.go +++ b/tsc/internal/format/comment_test.go @@ -18,15 +18,13 @@ func TestCommentFormatting(t *testing.T) { t.Run("format comment issue reproduction", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 4, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 4, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") @@ -69,15 +67,13 @@ func TestCommentFormatting(t *testing.T) { t.Run("format JSDoc with tab indentation", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSFalse, // Use tabs - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSFalse, // Use tabs + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") @@ -106,15 +102,13 @@ func TestCommentFormatting(t *testing.T) { t.Run("format comment inside multi-line argument list", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSFalse, // Use tabs - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSFalse, // Use tabs + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") @@ -139,15 +133,13 @@ func TestCommentFormatting(t *testing.T) { t.Run("format comment in chained method calls", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSFalse, // Use tabs - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSFalse, // Use tabs + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") @@ -173,15 +165,13 @@ func TestCommentFormatting(t *testing.T) { t.Run("format chained method call with comment (issue #1928)", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSFalse, // Use tabs - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSFalse, // Use tabs + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") @@ -206,15 +196,13 @@ func TestCommentFormatting(t *testing.T) { t.Run("multiline comment inside block that opens on first line (issue #2649)", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSFalse, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSFalse, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, }, "\n") originalText := `document.addEventListener('DOMContentLoaded', () => { @@ -235,15 +223,13 @@ func TestCommentFormatting(t *testing.T) { t.Run("single-line comment inside block that opens on first line (issue #2649)", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSFalse, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSFalse, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, }, "\n") originalText := `document.addEventListener('DOMContentLoaded', () => { @@ -268,15 +254,13 @@ func TestFormatSelectionPreservesComments(t *testing.T) { t.Run("format selection should not delete block comment when selection ends inside comment", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, }, "\n") // Reproduce: const test/* comment */=5; @@ -303,15 +287,13 @@ func TestFormatSelectionPreservesComments(t *testing.T) { t.Run("format selection should not delete block comment when selection starts inside comment", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, }, "\n") originalText := `const test/* comment */=5;` @@ -335,15 +317,13 @@ func TestFormatSelectionPreservesComments(t *testing.T) { t.Run("full document format should preserve block comment and add spaces", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 0, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 0, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeAndAfterBinaryOperators: core.TSTrue, }, "\n") @@ -368,15 +348,13 @@ func TestSliceBoundsPanic(t *testing.T) { t.Run("format code with trailing semicolon should not panic", func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - BaseIndentSize: 4, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + BaseIndentSize: 4, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, InsertSpaceBeforeTypeAnnotation: core.TSTrue, }, "\n") diff --git a/tsc/internal/format/format_test.go b/tsc/internal/format/format_test.go index 2ee70877255c7..6d8532010d8d6 100644 --- a/tsc/internal/format/format_test.go +++ b/tsc/internal/format/format_test.go @@ -33,14 +33,12 @@ func TestFormatNoTrailingSpace(t *testing.T) { t.Run(tc.name, func(t *testing.T) { t.Parallel() ctx := format.WithFormatCodeSettings(t.Context(), lsutil.FormatCodeSettings{ - EditorSettings: lsutil.EditorSettings{ - TabSize: 4, - IndentSize: 4, - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: lsutil.IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, + TabSize: 4, + IndentSize: 4, + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: lsutil.IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, }, "\n") sourceFile := parser.ParseSourceFile(ast.SourceFileParseOptions{ FileName: "/test.ts", diff --git a/tsc/internal/fourslash/test_parser.go b/tsc/internal/fourslash/test_parser.go index 18e59049781dd..4acc853bf01cf 100644 --- a/tsc/internal/fourslash/test_parser.go +++ b/tsc/internal/fourslash/test_parser.go @@ -285,12 +285,10 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st if previousCharacter == '[' && currentCharacter == '|' { // found a range start openRanges = append(openRanges, rangeLocationInformation{ - locationInformation: locationInformation{ - position: (i - 1) - difference, - sourcePosition: i - 1, - sourceLine: line, - sourceColumn: column, - }, + position: (i - 1) - difference, + sourcePosition: i - 1, + sourceLine: line, + sourceColumn: column, }) // copy all text up to marker position flush(i - 1) diff --git a/tsc/internal/ls/autoimport/extract.go b/tsc/internal/ls/autoimport/extract.go index 31ba6a2c7be07..c1a57f1af1749 100644 --- a/tsc/internal/ls/autoimport/extract.go +++ b/tsc/internal/ls/autoimport/extract.go @@ -264,10 +264,8 @@ func (e *symbolExtractor) createExport(symbol *ast.Symbol, moduleID ModuleID, mo } export := &Export{ - ExportID: ExportID{ - ExportName: symbol.Name, - ModuleID: moduleID, - }, + ExportName: symbol.Name, + ModuleID: moduleID, ModuleFileName: moduleFileName, Syntax: syntax, Flags: symbol.CombinedLocalAndExportSymbolFlags(), diff --git a/tsc/internal/ls/autoimport/registry_test.go b/tsc/internal/ls/autoimport/registry_test.go index a9b5b1349fd48..54b7af4102ac1 100644 --- a/tsc/internal/ls/autoimport/registry_test.go +++ b/tsc/internal/ls/autoimport/registry_test.go @@ -189,14 +189,12 @@ export const bar = 2;`, t.Run("node_modules buckets get deleted when no open files can reference them", func(t *testing.T) { t.Parallel() fixture := autoimporttestutil.SetupMonorepoLifecycleSession(t, autoimporttestutil.MonorepoSetupConfig{ - Root: monorepoProjectRoot, - MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{ - Name: "monorepo", - NodeModuleNames: []string{"pkg-root"}, - }, + Root: monorepoProjectRoot, + Name: "monorepo", + NodeModuleNames: []string{"pkg-root"}, Packages: []autoimporttestutil.MonorepoPackageConfig{ - {FileCount: 1, MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{Name: "package-a", NodeModuleNames: []string{"pkg-a"}}}, - {FileCount: 1, MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{Name: "package-b", NodeModuleNames: []string{"pkg-b"}}}, + {FileCount: 1, Name: "package-a", NodeModuleNames: []string{"pkg-a"}}, + {FileCount: 1, Name: "package-b", NodeModuleNames: []string{"pkg-b"}}, }, }) session := fixture.Session() @@ -358,19 +356,15 @@ export const bar = 2;`, packageAIndex := tspath.CombinePaths(packageADir, "index.js") fixture := autoimporttestutil.SetupMonorepoLifecycleSession(t, autoimporttestutil.MonorepoSetupConfig{ - Root: monorepoRoot, - MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{ - Name: "monorepo", - NodeModuleNames: []string{"pkg1", "pkg2", "pkg3"}, - DependencyNames: []string{"pkg1"}, - }, + Root: monorepoRoot, + Name: "monorepo", + NodeModuleNames: []string{"pkg1", "pkg2", "pkg3"}, + DependencyNames: []string{"pkg1"}, Packages: []autoimporttestutil.MonorepoPackageConfig{ { - FileCount: 0, - MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{ - Name: "a", - DependencyNames: []string{"pkg1", "pkg2"}, - }, + FileCount: 0, + Name: "a", + DependencyNames: []string{"pkg1", "pkg2"}, }, }, ExtraFiles: []autoimporttestutil.TextFileSpec{ @@ -434,29 +428,23 @@ export const bar = 2;`, fixture := autoimporttestutil.SetupMonorepoLifecycleSession(t, autoimporttestutil.MonorepoSetupConfig{ Root: monorepoRoot, - MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{ - Name: "monorepo", - // Both pkg-listed and pkg-unlisted exist in node_modules - NodeModuleNames: []string{"pkg-listed", "pkg-unlisted"}, - // But only pkg-listed is in the root package.json dependencies - DependencyNames: []string{"pkg-listed"}, - }, + Name: "monorepo", + // Both pkg-listed and pkg-unlisted exist in node_modules + NodeModuleNames: []string{"pkg-listed", "pkg-unlisted"}, + // But only pkg-listed is in the root package.json dependencies + DependencyNames: []string{"pkg-listed"}, Packages: []autoimporttestutil.MonorepoPackageConfig{ { FileCount: 0, - MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{ - Name: "a", - // package-a only lists pkg-listed in its package.json - DependencyNames: []string{"pkg-listed"}, - }, + Name: "a", + // package-a only lists pkg-listed in its package.json + DependencyNames: []string{"pkg-listed"}, }, { FileCount: 0, - MonorepoPackageTemplate: autoimporttestutil.MonorepoPackageTemplate{ - Name: "b", - // package-b also only lists pkg-listed in its package.json - DependencyNames: []string{"pkg-listed"}, - }, + Name: "b", + // package-b also only lists pkg-listed in its package.json + DependencyNames: []string{"pkg-listed"}, }, }, ExtraFiles: []autoimporttestutil.TextFileSpec{ diff --git a/tsc/internal/ls/findallreferences.go b/tsc/internal/ls/findallreferences.go index 84f20ad34f922..f893b61de8a4e 100644 --- a/tsc/internal/ls/findallreferences.go +++ b/tsc/internal/ls/findallreferences.go @@ -520,10 +520,8 @@ func (l *LanguageService) getNonLocalDefinition(ctx context.Context, entry *Symb continue } return &nonLocalDefinition{ - position: position{ - uri: lsconv.FileNameToDocumentURI(fileName), - pos: lspPosition, - }, + uri: lsconv.FileNameToDocumentURI(fileName), + pos: lspPosition, GetSourcePosition: sync.OnceValue(func() lsproto.HasTextDocumentPosition { mapped := l.tryGetSourcePosition(fileName, startPos) if mapped != nil { diff --git a/tsc/internal/ls/lsconv/converters.go b/tsc/internal/ls/lsconv/converters.go index 23eb9036206ee..bdb724f7667a4 100644 --- a/tsc/internal/ls/lsconv/converters.go +++ b/tsc/internal/ls/lsconv/converters.go @@ -154,13 +154,11 @@ func FromLSPRangeIntersectingForSourceFile(c *Converters, file *ast.SourceFile, if spans == nil { result = append(result, MappedSpan[*ast.SourceFile]{ Script: script, - MappedSpan: spanmap.MappedSpan{ - Span: core.NewTextRange( - int(c.lineAndCharacterToPosition(script, textRange.Start)), - int(c.lineAndCharacterToPosition(script, textRange.End)), - ), - Fidelity: spanmap.FidelityExact, - }, + Span: core.NewTextRange( + int(c.lineAndCharacterToPosition(script, textRange.Start)), + int(c.lineAndCharacterToPosition(script, textRange.End)), + ), + Fidelity: spanmap.FidelityExact, }) continue } diff --git a/tsc/internal/ls/lsutil/formatcodeoptions.go b/tsc/internal/ls/lsutil/formatcodeoptions.go index d63d3b489af41..73c8a899a63a1 100644 --- a/tsc/internal/ls/lsutil/formatcodeoptions.go +++ b/tsc/internal/ls/lsutil/formatcodeoptions.go @@ -113,19 +113,17 @@ func (settings FormatCodeSettings) ToLSFormatOptions() *lsproto.FormattingOption func GetDefaultFormatCodeSettings() FormatCodeSettings { return FormatCodeSettings{ - EditorSettings: EditorSettings{ - IndentSize: printer.GetDefaultIndentSize(), - TabSize: printer.GetDefaultIndentSize(), - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - }, - InsertSpaceAfterConstructor: core.TSFalse, - InsertSpaceAfterCommaDelimiter: core.TSTrue, - InsertSpaceAfterSemicolonInForStatements: core.TSTrue, - InsertSpaceBeforeAndAfterBinaryOperators: core.TSTrue, - InsertSpaceAfterKeywordsInControlFlowStatements: core.TSTrue, + IndentSize: printer.GetDefaultIndentSize(), + TabSize: printer.GetDefaultIndentSize(), + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, + InsertSpaceAfterConstructor: core.TSFalse, + InsertSpaceAfterCommaDelimiter: core.TSTrue, + InsertSpaceAfterSemicolonInForStatements: core.TSTrue, + InsertSpaceBeforeAndAfterBinaryOperators: core.TSTrue, + InsertSpaceAfterKeywordsInControlFlowStatements: core.TSTrue, InsertSpaceAfterFunctionKeywordForAnonymousFunctions: core.TSFalse, InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: core.TSFalse, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: core.TSFalse, diff --git a/tsc/internal/lsp/server.go b/tsc/internal/lsp/server.go index 9b3a4fccc7ae3..928f6e516c02d 100644 --- a/tsc/internal/lsp/server.go +++ b/tsc/internal/lsp/server.go @@ -2504,15 +2504,13 @@ func parseContentMapperContributions(values []*lsproto.ContentMapperContribution } } mapper := &contentmapper.Mapper{ - Definition: contentmapper.Definition{Package: identity, Extensions: validExtensions, Options: options}, - Manifest: contentmapper.Manifest{ - Name: manifest.Name, - Version: valueOrZero(manifest.Version), - Exec: slices.Clone(manifest.Exec), - CompilerOptions: slices.Clone(valueOrZero(manifest.CompilerOptions)), - DynamicConfig: valueOrZero(manifest.DynamicConfig), - }, - ContributionID: identity, + Package: identity, Extensions: validExtensions, Options: options, + Name: manifest.Name, + Version: valueOrZero(manifest.Version), + Exec: slices.Clone(manifest.Exec), + CompilerOptions: slices.Clone(valueOrZero(manifest.CompilerOptions)), + DynamicConfig: valueOrZero(manifest.DynamicConfig), + ContributionID: identity, } if manifest.Cwd != nil { if !tspath.PathIsAbsolute(*manifest.Cwd) { diff --git a/tsc/internal/modulespecifiers/specifiers_test.go b/tsc/internal/modulespecifiers/specifiers_test.go index 35269a9df76c9..4905febfa31af 100644 --- a/tsc/internal/modulespecifiers/specifiers_test.go +++ b/tsc/internal/modulespecifiers/specifiers_test.go @@ -328,10 +328,8 @@ func TestTryGetModuleNameFromExportsOrImports(t *testing.T) { "/pkg", "./src/things/*", packagejson.ExportsOrImports{ - JSONValue: packagejson.JSONValue{ - Type: packagejson.JSONValueTypeString, - Value: "./src/things/*/index.js", - }, + Type: packagejson.JSONValueTypeString, + Value: "./src/things/*/index.js", }, []string{}, MatchingModePattern, diff --git a/tsc/internal/printer/changetrackerwriter.go b/tsc/internal/printer/changetrackerwriter.go index aebc68c95a04e..9e508f9631337 100644 --- a/tsc/internal/printer/changetrackerwriter.go +++ b/tsc/internal/printer/changetrackerwriter.go @@ -27,7 +27,7 @@ func NewChangeTrackerWriter(newline string, indentSize int) *ChangeTrackerWriter indentSize = defaultIndentSize } ctw := &ChangeTrackerWriter{ - textWriter: textWriter{newLine: newline, indentSize: indentSize}, + newLine: newline, indentSize: indentSize, lastNonTriviaPosition: 0, pos: map[triviaPositionKey]int{}, end: map[triviaPositionKey]int{}, diff --git a/tsc/internal/project/api.go b/tsc/internal/project/api.go index 284897f29c147..182b65ef6a9c7 100644 --- a/tsc/internal/project/api.go +++ b/tsc/internal/project/api.go @@ -61,9 +61,7 @@ func (s *Session) APIUpdateTemporary(ctx context.Context, baseSnapshot *Snapshot newSnapshot := baseSnapshot.Clone(ctx, SnapshotChange{ fileChanges: fileChanges, - ResourceRequest: ResourceRequest{ - Documents: []lsproto.DocumentUri{uri}, - }, + Documents: []lsproto.DocumentUri{uri}, }, overlays, s) return newSnapshot, nil } diff --git a/tsc/internal/project/contentmapper_test.go b/tsc/internal/project/contentmapper_test.go index feda9d756dcd4..a37f1438b45a7 100644 --- a/tsc/internal/project/contentmapper_test.go +++ b/tsc/internal/project/contentmapper_test.go @@ -662,8 +662,8 @@ func TestContentMapperOpenFileExcludedByConfigChange(t *testing.T) { boxURI := lsproto.DocumentUri("file:///home/project/src/app.box") session.SetContentMapperContributions(ctx, project.ContentMapperContributions{ Mappers: []*contentmapper.Mapper{{ - Definition: contentmapper.Definition{Package: "test.extension", Extensions: []string{".box"}}, - Manifest: contentmapper.Manifest{Name: "mapper", Version: "1.0.0", Exec: []string{contentmappertest.TransformingMapper}, CompilerOptions: contentmappertest.DeclaredOptions}, + Package: "test.extension", Extensions: []string{".box"}, + Name: "mapper", Version: "1.0.0", Exec: []string{contentmappertest.TransformingMapper}, CompilerOptions: contentmappertest.DeclaredOptions, PackageDirectory: "/home/project", ContributionID: "test.extension[0]", }}, @@ -851,8 +851,8 @@ func TestContentMapperInferredProjectUsesExtensionContributions(t *testing.T) { assert.ErrorContains(t, err, "no project found", "configured mapper must not leak into inferred projects") session.SetContentMapperContributions(ctx, project.ContentMapperContributions{ Mappers: []*contentmapper.Mapper{{ - Definition: contentmapper.Definition{Package: "test.extension", Extensions: []string{".box"}}, - Manifest: contentmapper.Manifest{Name: "mapper", Version: "1.0.0", Exec: []string{contentmappertest.TransformingMapper}, CompilerOptions: contentmappertest.DeclaredOptions}, + Package: "test.extension", Extensions: []string{".box"}, + Name: "mapper", Version: "1.0.0", Exec: []string{contentmappertest.TransformingMapper}, CompilerOptions: contentmappertest.DeclaredOptions, PackageDirectory: "/home", ContributionID: "test.extension[0]", }}, @@ -905,8 +905,8 @@ func TestContentMapperInferredProjectSurvivesTypingsInstall(t *testing.T) { ctx := context.Background() session.SetContentMapperContributions(ctx, project.ContentMapperContributions{ Mappers: []*contentmapper.Mapper{{ - Definition: contentmapper.Definition{Package: "test.extension", Extensions: []string{".box"}}, - Manifest: contentmapper.Manifest{Name: "mapper", Version: "1.0.0", Exec: []string{contentmappertest.TransformingMapper}, CompilerOptions: contentmappertest.DeclaredOptions}, + Package: "test.extension", Extensions: []string{".box"}, + Name: "mapper", Version: "1.0.0", Exec: []string{contentmappertest.TransformingMapper}, CompilerOptions: contentmappertest.DeclaredOptions, PackageDirectory: "/home", ContributionID: "test.extension[0]", }}, diff --git a/tsc/internal/project/dirty/map.go b/tsc/internal/project/dirty/map.go index e90d8b7130cb2..cc74ee62833b8 100644 --- a/tsc/internal/project/dirty/map.go +++ b/tsc/internal/project/dirty/map.go @@ -73,13 +73,11 @@ func (m *Map[K, V]) Get(key K) (*MapEntry[K, V], bool) { return nil, false } return &MapEntry[K, V]{ - m: m, - mapEntry: mapEntry[K, V]{ - key: key, - original: value, - value: value, - dirty: false, - }, + m: m, + key: key, + original: value, + value: value, + dirty: false, }, true } @@ -90,12 +88,10 @@ func (m *Map[K, V]) Get(key K) (*MapEntry[K, V], bool) { // exist in the base map, use `Change` instead. func (m *Map[K, V]) Add(key K, value V) { m.dirty[key] = &MapEntry[K, V]{ - m: m, - mapEntry: mapEntry[K, V]{ - key: key, - value: value, - dirty: true, - }, + m: m, + key: key, + value: value, + dirty: true, } } @@ -133,12 +129,13 @@ func (m *Map[K, V]) Range(fn func(*MapEntry[K, V]) bool) { if _, ok := seenInDirty[key]; ok { continue // already processed in dirty entries } - if !fn(&MapEntry[K, V]{m: m, mapEntry: mapEntry[K, V]{ + if !fn(&MapEntry[K, V]{ + m: m, key: key, original: value, value: value, dirty: false, - }}) { + }) { break } } diff --git a/tsc/internal/project/dirty/syncmap.go b/tsc/internal/project/dirty/syncmap.go index c57b17dafd05b..6d75259d935f6 100644 --- a/tsc/internal/project/dirty/syncmap.go +++ b/tsc/internal/project/dirty/syncmap.go @@ -212,14 +212,12 @@ func (m *SyncMap[K, V]) Load(key K) (*SyncMapEntry[K, V], bool) { } if val, ok := m.base[key]; ok { return &SyncMapEntry[K, V]{ - m: m, - mapEntry: mapEntry[K, V]{ - key: key, - original: val, - value: val, - dirty: false, - delete: false, - }, + m: m, + key: key, + original: val, + value: val, + dirty: false, + delete: false, }, true } return nil, false @@ -237,23 +235,19 @@ func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (*SyncMapEntry[K, V], bool) return dirty, true } return &SyncMapEntry[K, V]{ - m: m, - mapEntry: mapEntry[K, V]{ - key: key, - original: baseValue, - value: baseValue, - dirty: false, - delete: false, - }, + m: m, + key: key, + original: baseValue, + value: baseValue, + dirty: false, + delete: false, }, true } entry, loaded := m.dirty.LoadOrStore(key, &SyncMapEntry[K, V]{ - m: m, - mapEntry: mapEntry[K, V]{ - key: key, - value: value, - dirty: true, - }, + m: m, + key: key, + value: value, + dirty: true, }) if loaded { entry.mu.Lock() @@ -267,12 +261,10 @@ func (m *SyncMap[K, V]) LoadOrStore(key K, value V) (*SyncMapEntry[K, V], bool) func (m *SyncMap[K, V]) Delete(key K) { entry, loaded := m.dirty.LoadOrStore(key, &SyncMapEntry[K, V]{ - m: m, - mapEntry: mapEntry[K, V]{ - key: key, - original: m.base[key], - delete: true, - }, + m: m, + key: key, + original: m.base[key], + delete: true, }) if loaded { entry.Delete() @@ -295,12 +287,13 @@ func (m *SyncMap[K, V]) Range(fn func(*SyncMapEntry[K, V]) bool) { if _, ok := seenInDirty[key]; ok { continue // already processed in dirty entries } - if !fn(&SyncMapEntry[K, V]{m: m, mapEntry: mapEntry[K, V]{ + if !fn(&SyncMapEntry[K, V]{ + m: m, key: key, original: value, value: value, dirty: false, - }}) { + }) { break } } diff --git a/tsc/internal/project/logging/logcollector.go b/tsc/internal/project/logging/logcollector.go index 0870c4e1f81e3..eebbe93ae0794 100644 --- a/tsc/internal/project/logging/logcollector.go +++ b/tsc/internal/project/logging/logcollector.go @@ -23,11 +23,9 @@ func (lc *logCollector) String() string { func NewTestLogger() LogCollector { var builder strings.Builder return &logCollector{ - logger: logger{ - writer: &builder, - prefix: func() string { - return formatTime(time.Unix(1349085672, 0)) - }, + writer: &builder, + prefix: func() string { + return formatTime(time.Unix(1349085672, 0)) }, builder: &builder, } diff --git a/tsc/internal/project/overlayfs.go b/tsc/internal/project/overlayfs.go index 476008cda21d3..e1da6edd1fb94 100644 --- a/tsc/internal/project/overlayfs.go +++ b/tsc/internal/project/overlayfs.go @@ -78,11 +78,9 @@ type diskFile struct { func newDiskFile(fileName string, content string) *diskFile { return &diskFile{ - fileBase: fileBase{ - fileName: fileName, - content: content, - hash: xxh3.HashString128(content), - }, + fileName: fileName, + content: content, + hash: xxh3.HashString128(content), } } @@ -107,11 +105,9 @@ func (f *diskFile) Kind() core.ScriptKind { func (f *diskFile) Clone() *diskFile { return &diskFile{ realpathPath: f.realpathPath, - fileBase: fileBase{ - fileName: f.fileName, - content: f.content, - hash: f.hash, - }, + fileName: f.fileName, + content: f.content, + hash: f.hash, } } @@ -126,13 +122,11 @@ type Overlay struct { func newOverlay(fileName string, content string, version int32, kind core.ScriptKind) *Overlay { return &Overlay{ - fileBase: fileBase{ - fileName: fileName, - content: content, - hash: xxh3.HashString128(content), - }, - version: version, - kind: kind, + fileName: fileName, + content: content, + hash: xxh3.HashString128(content), + version: version, + kind: kind, } } diff --git a/tsc/internal/project/refcountcache_test.go b/tsc/internal/project/refcountcache_test.go index 99e94063975b9..3026cca3493f2 100644 --- a/tsc/internal/project/refcountcache_test.go +++ b/tsc/internal/project/refcountcache_test.go @@ -21,7 +21,7 @@ import ( func TestContentMappedParseCacheBundleLifetime(t *testing.T) { t.Parallel() cache := NewContentMappedParseCache(RefCountCacheOptions{}) - key := ContentMappedParseCacheKey{SourceFileParseOptions: ast.SourceFileParseOptions{FileName: "/component.vue", Path: "/component.vue"}} + key := ContentMappedParseCacheKey{FileName: "/component.vue", Path: "/component.vue"} canonical := &ast.SourceFile{} supplemental := &ast.SourceFile{} produced := contentmapper.SourceFiles{Canonical: canonical, Supplemental: []*ast.SourceFile{supplemental}} @@ -463,10 +463,8 @@ func TestRefCountingCaches(t *testing.T) { baseSnapshot := session.Snapshot() extendedConfigPath := tspath.Path("/user/username/projects/myproject/tsconfig.base.json") clone := baseSnapshot.Clone(context.Background(), SnapshotChange{ - reason: UpdateReasonRequestedLanguageServiceProjectNotLoaded, - ResourceRequest: ResourceRequest{ - Documents: []lsproto.DocumentUri{uri}, - }, + reason: UpdateReasonRequestedLanguageServiceProjectNotLoaded, + Documents: []lsproto.DocumentUri{uri}, }, baseSnapshot.fs.overlays, session) project := clone.GetDefaultProject(uri) diff --git a/tsc/internal/project/session.go b/tsc/internal/project/session.go index d19fa70d16645..16d3e14ae2076 100644 --- a/tsc/internal/project/session.go +++ b/tsc/internal/project/session.go @@ -394,9 +394,7 @@ func (s *Session) DidOpenFile(ctx context.Context, uri lsproto.DocumentUri, vers s.UpdateSnapshot(ctx, overlays, SnapshotChange{ reason: UpdateReasonDidOpenFile, fileChanges: changes, - ResourceRequest: ResourceRequest{ - Documents: []lsproto.DocumentUri{uri}, - }, + Documents: []lsproto.DocumentUri{uri}, }) } @@ -416,9 +414,7 @@ func (s *Session) SetContentMapperContributions(ctx context.Context, contributio reason: UpdateReasonDidChangeContentMapperContributions, fileChanges: changes, contentMapperContributions: &contributions, - ResourceRequest: ResourceRequest{ - ConfiguredProjectDocuments: documentURIs, - }, + ConfiguredProjectDocuments: documentURIs, }) _ = s.updateContentMapperRegistrations(ctx, s.Snapshot()) } @@ -1368,11 +1364,9 @@ func (s *Session) GetSnapshotWithAutoImports(ctx context.Context, baseSnapshot * func (s *Session) cloneWithAutoImports(ctx context.Context, baseSnapshot *Snapshot, uri lsproto.DocumentUri, callerRef bool) *Snapshot { change := SnapshotChange{ - reason: UpdateReasonRequestedLanguageServiceWithAutoImports, - ResourceRequest: ResourceRequest{ - Documents: []lsproto.DocumentUri{uri}, - AutoImports: uri, - }, + reason: UpdateReasonRequestedLanguageServiceWithAutoImports, + Documents: []lsproto.DocumentUri{uri}, + AutoImports: uri, } newSnapshot := baseSnapshot.Clone(ctx, change, baseSnapshot.fs.overlays, s) if callerRef { @@ -2150,11 +2144,9 @@ func (s *Session) warmAutoImportCache(ctx context.Context, change SnapshotChange defer newSnapshot.Deref(s) warmChange := SnapshotChange{ - reason: UpdateReasonRequestedLanguageServiceWithAutoImports, - ResourceRequest: ResourceRequest{ - Documents: []lsproto.DocumentUri{changedFile}, - AutoImports: changedFile, - }, + reason: UpdateReasonRequestedLanguageServiceWithAutoImports, + Documents: []lsproto.DocumentUri{changedFile}, + AutoImports: changedFile, } clonedSnapshot := newSnapshot.Clone(warmCtx, warmChange, newSnapshot.fs.overlays, s) diff --git a/tsc/internal/project/snapshotfs.go b/tsc/internal/project/snapshotfs.go index 61fc7312977e1..994d2f4545818 100644 --- a/tsc/internal/project/snapshotfs.go +++ b/tsc/internal/project/snapshotfs.go @@ -342,7 +342,7 @@ func (s *snapshotFSBuilder) GetAccessibleEntries(path string) vfs.Entries { } func (s *snapshotFSBuilder) getDiskFile(fileName string, path tspath.Path, forceReload bool) FileHandle { - entry, loaded := s.diskFiles.LoadOrStore(path, &diskFile{fileBase: fileBase{fileName: fileName}, needsReload: true}) + entry, loaded := s.diskFiles.LoadOrStore(path, &diskFile{fileName: fileName, needsReload: true}) if entry != nil { if !loaded && strings.Contains(string(path), "/node_modules/") { s.recordRealpathAlias(entry, fileName, path) diff --git a/tsc/internal/testutil/autoimporttestutil/fixtures.go b/tsc/internal/testutil/autoimporttestutil/fixtures.go index 845080c5ee7dd..408c19418b9b3 100644 --- a/tsc/internal/testutil/autoimporttestutil/fixtures.go +++ b/tsc/internal/testutil/autoimporttestutil/fixtures.go @@ -366,7 +366,7 @@ func (r *projectRecord) toHandles() ProjectHandle { files := make([]ProjectFileHandle, len(r.sourceFiles)) for i, file := range r.sourceFiles { files[i] = ProjectFileHandle{ - FileHandle: FileHandle{fileName: file.FileName, content: file.Content}, + fileName: file.FileName, content: file.Content, exportIdentifier: file.ExportIdentifier, } } diff --git a/tsc/internal/testutil/contentmappertest/component.go b/tsc/internal/testutil/contentmappertest/component.go index 7da16c276f944..57ed38a5bccaf 100644 --- a/tsc/internal/testutil/contentmappertest/component.go +++ b/tsc/internal/testutil/contentmappertest/component.go @@ -27,7 +27,7 @@ func (componentHandler) HandleRequest(ctx context.Context, method string, params if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: text, Extension: ".ts", Mappings: mappings}}, nil + return contentmapper.TransformResult{Text: text, Extension: ".ts", Mappings: mappings}, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) } diff --git a/tsc/internal/testutil/contentmappertest/duplicate.go b/tsc/internal/testutil/contentmappertest/duplicate.go index 2ccd70b3fe3da..005fcf4e73cff 100644 --- a/tsc/internal/testutil/contentmappertest/duplicate.go +++ b/tsc/internal/testutil/contentmappertest/duplicate.go @@ -33,7 +33,7 @@ func (duplicateHandler) HandleRequest(ctx context.Context, method string, params if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}}, nil + return contentmapper.TransformResult{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}, nil } if strings.Contains(p.FileName, "hover-concat") { virtual := "namespace A { export const " + p.Content + " = 1; }\nnamespace B { export const " + p.Content + " = \"text\"; }\n" @@ -46,7 +46,7 @@ func (duplicateHandler) HandleRequest(ctx context.Context, method string, params if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}}, nil + return contentmapper.TransformResult{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}, nil } if strings.Contains(p.FileName, "signature-fallback") { virtual := "// " + p.Content + "\nfunction use(value: number): void {}\n" + p.Content + ";\n" @@ -59,7 +59,7 @@ func (duplicateHandler) HandleRequest(ctx context.Context, method string, params if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}}, nil + return contentmapper.TransformResult{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}, nil } if strings.Contains(p.FileName, "rename-conflict") { virtual := "export const " + p.Content + " = 1;\nconst object = { " + p.Content + " };\n" + p.Content + ";\n" @@ -74,7 +74,7 @@ func (duplicateHandler) HandleRequest(ctx context.Context, method string, params if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}}, nil + return contentmapper.TransformResult{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}, nil } virtual := "export const " + p.Content + " = 1;\n" + p.Content + ";\n" first := len("export const ") @@ -93,7 +93,7 @@ func (duplicateHandler) HandleRequest(ctx context.Context, method string, params if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}}, nil + return contentmapper.TransformResult{Text: virtual, Extension: ".ts", Mappings: json.Value(mappings)}, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) } diff --git a/tsc/internal/testutil/contentmappertest/editing.go b/tsc/internal/testutil/contentmappertest/editing.go index b3db5a3db234e..d295837a46bbe 100644 --- a/tsc/internal/testutil/contentmappertest/editing.go +++ b/tsc/internal/testutil/contentmappertest/editing.go @@ -96,12 +96,12 @@ func (prefixedSupplementalHandler) HandleRequest(ctx context.Context, method str return nil, err } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: p.Content[:thirdStart], Extension: ".ts", Mappings: json.Value(canonicalMappings)}, - Supplemental: []contentmapper.SupplementalOutput{{MappedOutput: contentmapper.MappedOutput{ + Text: p.Content[:thirdStart], Extension: ".ts", Mappings: json.Value(canonicalMappings), + Supplemental: []contentmapper.SupplementalOutput{{ Text: supplementalText, Extension: ".ts", Mappings: json.Value(mappings), - }}}, + }}, }, nil } mappings, err := spanmap.New(segments).Marshal() @@ -125,11 +125,11 @@ func (prefixedSupplementalHandler) HandleRequest(ctx context.Context, method str } return contentmapper.TransformResult{ MappedOutput: canonical, - Supplemental: []contentmapper.SupplementalOutput{{MappedOutput: contentmapper.MappedOutput{ + Supplemental: []contentmapper.SupplementalOutput{{ Text: supplementalText, Extension: ".ts", Mappings: json.Value(mappings), - }}}, + }}, }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) @@ -147,7 +147,7 @@ func (unmappedFoldingHandler) HandleRequest(ctx context.Context, method string, if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{ + return contentmapper.TransformResult{ Text: `import "a"; import "b"; /* @@ -156,7 +156,7 @@ import "b"; export {};`, Extension: ".ts", Mappings: json.Value(mappings), - }}, nil + }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) } diff --git a/tsc/internal/testutil/contentmappertest/lisp.go b/tsc/internal/testutil/contentmappertest/lisp.go index 97f8c174987be..74bb3c3427f6f 100644 --- a/tsc/internal/testutil/contentmappertest/lisp.go +++ b/tsc/internal/testutil/contentmappertest/lisp.go @@ -33,11 +33,11 @@ func (lispHandler) HandleRequest(ctx context.Context, method string, params json if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{ + return contentmapper.TransformResult{ Text: `add(1, 2, "oops");`, Extension: ".ts", Mappings: json.Value(mappings), - }}, nil + }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) } diff --git a/tsc/internal/testutil/contentmappertest/mapper_test.go b/tsc/internal/testutil/contentmappertest/mapper_test.go index fbad19ddefb4d..537039314e04b 100644 --- a/tsc/internal/testutil/contentmappertest/mapper_test.go +++ b/tsc/internal/testutil/contentmappertest/mapper_test.go @@ -37,16 +37,12 @@ func (stdio) Close() error { return nil } func testMapper() *contentmapper.Mapper { return &contentmapper.Mapper{ - Definition: contentmapper.Definition{ - Package: contentmappertest.PackageName, - Extensions: []string{".box"}, - }, - Manifest: contentmapper.Manifest{ - Name: contentmappertest.PackageName, - Version: "1.0.0", - Exec: []string{contentmappertest.TransformingMapper}, - CompilerOptions: contentmappertest.DeclaredOptions, - }, + Package: contentmappertest.PackageName, + Extensions: []string{".box"}, + Name: contentmappertest.PackageName, + Version: "1.0.0", + Exec: []string{contentmappertest.TransformingMapper}, + CompilerOptions: contentmappertest.DeclaredOptions, PackageDirectory: "/node_modules/" + contentmappertest.PackageName, } } diff --git a/tsc/internal/testutil/contentmappertest/supplemental.go b/tsc/internal/testutil/contentmappertest/supplemental.go index 599ed258e8a7a..0d96334485bc8 100644 --- a/tsc/internal/testutil/contentmappertest/supplemental.go +++ b/tsc/internal/testutil/contentmappertest/supplemental.go @@ -24,7 +24,7 @@ func (supplementalHandler) HandleRequest(ctx context.Context, method string, par return nil, err } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: "export {};", Extension: ".ts"}, + Text: "export {};", Extension: ".ts", Supplemental: []contentmapper.SupplementalOutput{{MappedOutput: mappedOutput}}, }, nil default: diff --git a/tsc/internal/testutil/contentmappertest/supplemental_diagnostics.go b/tsc/internal/testutil/contentmappertest/supplemental_diagnostics.go index 6ba9b509501d8..43dcc8af625d1 100644 --- a/tsc/internal/testutil/contentmappertest/supplemental_diagnostics.go +++ b/tsc/internal/testutil/contentmappertest/supplemental_diagnostics.go @@ -33,8 +33,8 @@ func (supplementalDiagnosticsHandler) HandleRequest(ctx context.Context, method return nil, err } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: "export {};", Extension: ".ts"}, - Supplemental: []contentmapper.SupplementalOutput{{MappedOutput: contentmapper.MappedOutput{Text: prefix + p.Content, Extension: ".ts", Mappings: json.Value(mappings)}}}, + Text: "export {};", Extension: ".ts", + Supplemental: []contentmapper.SupplementalOutput{{Text: prefix + p.Content, Extension: ".ts", Mappings: json.Value(mappings)}}, }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) diff --git a/tsc/internal/testutil/contentmappertest/supplemental_globals.go b/tsc/internal/testutil/contentmappertest/supplemental_globals.go index 61ea039af034f..d6833a7856fe5 100644 --- a/tsc/internal/testutil/contentmappertest/supplemental_globals.go +++ b/tsc/internal/testutil/contentmappertest/supplemental_globals.go @@ -30,8 +30,8 @@ func (supplementalGlobalsHandler) HandleRequest(ctx context.Context, method stri return nil, fmt.Errorf("contentmappertest: unexpected supplemental global input %q", p.FileName) } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: "export default shared.value;", Extension: ".ts"}, - Supplemental: []contentmapper.SupplementalOutput{{MappedOutput: contentmapper.MappedOutput{Text: supplemental, Extension: ".ts"}}}, + Text: "export default shared.value;", Extension: ".ts", + Supplemental: []contentmapper.SupplementalOutput{{Text: supplemental, Extension: ".ts"}}, }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) diff --git a/tsc/internal/testutil/contentmappertest/supplemental_module.go b/tsc/internal/testutil/contentmappertest/supplemental_module.go index 44a89b11497a7..8fca4fe0d549f 100644 --- a/tsc/internal/testutil/contentmappertest/supplemental_module.go +++ b/tsc/internal/testutil/contentmappertest/supplemental_module.go @@ -20,8 +20,8 @@ func (supplementalModuleHandler) HandleRequest(ctx context.Context, method strin return nil, err } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: "export default 1;", Extension: ".ts"}, - Supplemental: []contentmapper.SupplementalOutput{{MappedOutput: contentmapper.MappedOutput{Text: `export const privateValue: number = "wrong";`, Extension: ".ts"}}}, + Text: "export default 1;", Extension: ".ts", + Supplemental: []contentmapper.SupplementalOutput{{Text: `export const privateValue: number = "wrong";`, Extension: ".ts"}}, }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) diff --git a/tsc/internal/testutil/contentmappertest/synthesizing.go b/tsc/internal/testutil/contentmappertest/synthesizing.go index 7c79dfa34b822..de35db3ddef0e 100644 --- a/tsc/internal/testutil/contentmappertest/synthesizing.go +++ b/tsc/internal/testutil/contentmappertest/synthesizing.go @@ -26,11 +26,11 @@ func (synthesizingHandler) HandleRequest(ctx context.Context, method string, par if err != nil { return nil, err } - return contentmapper.TransformResult{MappedOutput: contentmapper.MappedOutput{ + return contentmapper.TransformResult{ Text: synthesizedOutput, Extension: ".ts", Mappings: json.Value(mappings), - }}, nil + }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) } diff --git a/tsc/internal/testutil/contentmappertest/transforming.go b/tsc/internal/testutil/contentmappertest/transforming.go index 41da490b47e5b..42ba711ea76a5 100644 --- a/tsc/internal/testutil/contentmappertest/transforming.go +++ b/tsc/internal/testutil/contentmappertest/transforming.go @@ -72,8 +72,8 @@ func (h *Handler) HandleRequest(ctx context.Context, method string, params json. return nil, err } return contentmapper.TransformResult{ - MappedOutput: contentmapper.MappedOutput{Text: text, Extension: mappedExtension(p.Content), Mappings: mappings, DiagnosticDirectives: diagnosticDirectives}, - Diagnostics: diagnostics, + Text: text, Extension: mappedExtension(p.Content), Mappings: mappings, DiagnosticDirectives: diagnosticDirectives, + Diagnostics: diagnostics, }, nil default: return nil, fmt.Errorf("contentmappertest: unexpected method %q", method) diff --git a/tsc/internal/transformers/estransforms/taggedtemplate.go b/tsc/internal/transformers/estransforms/taggedtemplate.go index 0beaf57e53d09..0349e7a79d13b 100644 --- a/tsc/internal/transformers/estransforms/taggedtemplate.go +++ b/tsc/internal/transformers/estransforms/taggedtemplate.go @@ -1,6 +1,7 @@ package estransforms import ( + "slices" "strings" "github.com/microsoft/TypeScript/tsc/internal/ast" @@ -45,7 +46,7 @@ func (tx *taggedTemplateTransformer) visitSourceFile(node *ast.SourceFile) *ast. if len(tx.taggedTemplateStringDeclarations) > 0 { visitedSourceFile := visited.AsSourceFile() statements := append( - visitedSourceFile.Statements.Nodes[:len(visitedSourceFile.Statements.Nodes):len(visitedSourceFile.Statements.Nodes)], + slices.Clip(visitedSourceFile.Statements.Nodes), tx.Factory().NewVariableStatement( nil, /*modifiers*/ tx.Factory().NewVariableDeclarationList( diff --git a/tsc/internal/tsoptions/contentmappers_test.go b/tsc/internal/tsoptions/contentmappers_test.go index 6d2bc9875126b..c5785dfb80f1b 100644 --- a/tsc/internal/tsoptions/contentmappers_test.go +++ b/tsc/internal/tsoptions/contentmappers_test.go @@ -19,8 +19,8 @@ type resolveContentMapperHost struct { func TestGetContentMapperForFileNameUsesLongestExtension(t *testing.T) { t.Parallel() - zMapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "z", Extensions: []string{".z"}}} - yzMapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Package: "yz", Extensions: []string{".y.z"}}} + zMapper := &contentmapper.Mapper{Package: "z", Extensions: []string{".z"}} + yzMapper := &contentmapper.Mapper{Package: "yz", Extensions: []string{".y.z"}} commandLine := &ParsedCommandLine{ParsedConfig: &ParsedOptions{ContentMappers: []*contentmapper.Mapper{zMapper, yzMapper}}} assert.Equal(t, commandLine.GetContentMapperForFileName("/src/Component.y.z"), yzMapper) @@ -29,7 +29,7 @@ func TestGetContentMapperForFileNameUsesLongestExtension(t *testing.T) { func TestGetContentMapperForFileNameUsesHostCaseSensitivity(t *testing.T) { t.Parallel() - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}} insensitive := &ParsedCommandLine{ ParsedConfig: &ParsedOptions{ContentMappers: []*contentmapper.Mapper{mapper}}, comparePathsOptions: tspath.ComparePathsOptions{UseCaseSensitiveFileNames: false}, @@ -45,7 +45,7 @@ func TestGetContentMapperForFileNameUsesHostCaseSensitivity(t *testing.T) { func TestGetOutputFileNamesExcludesMapperOwnedOutputs(t *testing.T) { t.Parallel() - mapper := &contentmapper.Mapper{Definition: contentmapper.Definition{Extensions: []string{".vue"}}} + mapper := &contentmapper.Mapper{Extensions: []string{".vue"}} commandLine := NewParsedCommandLine( &core.CompilerOptions{ OutDir: "/dist", diff --git a/tsc/internal/tsoptions/tsconfigparsing_test.go b/tsc/internal/tsoptions/tsconfigparsing_test.go index 85d15386919dc..69e62efc17724 100644 --- a/tsc/internal/tsoptions/tsconfigparsing_test.go +++ b/tsc/internal/tsoptions/tsconfigparsing_test.go @@ -140,11 +140,9 @@ func TestParseConfigFileTextToJson(t *testing.T) { baselineContent.WriteString("\n") baselineContent.WriteString("Errors::\n") diagnosticwriter.FormatDiagnosticsWithColorAndContext(&baselineContent, diagnosticwriter.FromASTDiagnostics(errors), &diagnosticwriter.FormattingOptions{ - NewLine: "\n", - ComparePathsOptions: tspath.ComparePathsOptions{ - CurrentDirectory: "/", - UseCaseSensitiveFileNames: true, - }, + NewLine: "\n", + CurrentDirectory: "/", + UseCaseSensitiveFileNames: true, }) baselineContent.WriteString("\n") if i != len(rec.input)-1 { @@ -1537,11 +1535,9 @@ func baselineParseConfigWith(t *testing.T, baselineFileName string, includeCompi baselineContent.WriteString("\n") baselineContent.WriteString("Errors::\n") diagnosticwriter.FormatDiagnosticsWithColorAndContext(&baselineContent, diagnosticwriter.FromASTDiagnostics(parsedConfigFileContent.Errors), &diagnosticwriter.FormattingOptions{ - NewLine: "\r\n", - ComparePathsOptions: tspath.ComparePathsOptions{ - CurrentDirectory: basePath, - UseCaseSensitiveFileNames: true, - }, + NewLine: "\r\n", + CurrentDirectory: basePath, + UseCaseSensitiveFileNames: true, }) baselineContent.WriteString("\n") if i != len(input)-1 { From c5c9a0bca53bd26a36b356de2311af2d69fd1a1b Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 20 Aug 2026 02:59:02 -0700 Subject: [PATCH 06/10] Apply slicesbackward modernizer --- .dprint.jsonc | 2 +- .golangci.yml | 4 ---- tsc/internal/astnav/tokens.go | 13 +++++++------ tsc/internal/checker/checker.go | 6 +++--- tsc/internal/core/core.go | 6 ++---- tsc/internal/format/span.go | 4 ++-- tsc/internal/fourslash/fourslash.go | 16 ++++++++-------- tsc/internal/fswatch/watcher.go | 8 ++++---- tsc/internal/ls/documenthighlights.go | 13 +++++++------ tsc/internal/ls/lsutil/children.go | 8 +++++--- tsc/internal/ls/symbols.go | 4 ++-- tsc/internal/printer/utilities.go | 3 +-- tsc/internal/pseudochecker/lookup.go | 4 ++-- tsc/internal/tsoptions/tsconfigparsing.go | 4 ++-- 14 files changed, 46 insertions(+), 49 deletions(-) diff --git a/.dprint.jsonc b/.dprint.jsonc index 15ae55f237c05..0bfc480fe4778 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -38,7 +38,7 @@ "trailingCommas": "never" }, "gofumpt": { - "langVersion": "go1.26", + "langVersion": "go1.27", "modulePath": "github.com/microsoft/TypeScript/tsc" }, "excludes": [ diff --git a/.golangci.yml b/.golangci.yml index 1309650b71452..6dad8234aa2e5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -65,10 +65,6 @@ linters: customlint: type: module - modernize: - disable: - - slicesbackward # https://github.com/golang/go/issues/78829 - depguard: rules: main: diff --git a/tsc/internal/astnav/tokens.go b/tsc/internal/astnav/tokens.go index 9b6b3257df890..b921912ad6884 100644 --- a/tsc/internal/astnav/tokens.go +++ b/tsc/internal/astnav/tokens.go @@ -2,6 +2,7 @@ package astnav import ( "fmt" + "slices" "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/core" @@ -142,9 +143,9 @@ func getTokenAtPosition( if nodeList.End() == position && includePrecedingTokenAtEndPosition != nil { left = nodeList.End() nodeAfterLeft = nil - for i := len(nodeList.Nodes) - 1; i >= 0; i-- { - if nodeList.Nodes[i].Flags&ast.NodeFlagsReparsed == 0 { - prevSubtree = nodeList.Nodes[i] + for _, v := range slices.Backward(nodeList.Nodes) { + if v.Flags&ast.NodeFlagsReparsed == 0 { + prevSubtree = v break } } @@ -416,9 +417,9 @@ func FindPrecedingTokenEx(sourceFile *ast.SourceFile, position int, startNode *a // Find jsdoc preceding the foundChild. var jsDoc *ast.Node nodeJSDoc := n.JSDoc(sourceFile) - for i := len(nodeJSDoc) - 1; i >= 0; i-- { - if nodeJSDoc[i].Pos() >= foundChild.Pos() { - jsDoc = nodeJSDoc[i] + for _, n := range slices.Backward(nodeJSDoc) { + if n.Pos() >= foundChild.Pos() { + jsDoc = n break } } diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 9c9cb64c78a31..8cbf7ea93edd5 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -31109,9 +31109,9 @@ func (c *Checker) popInferenceContext() { } func (c *Checker) getInferenceContext(node *ast.Node) *InferenceContext { - for i := len(c.inferenceContextInfos) - 1; i >= 0; i-- { - if isNodeDescendantOf(node, c.inferenceContextInfos[i].node) { - return c.inferenceContextInfos[i].context + for _, v := range slices.Backward(c.inferenceContextInfos) { + if isNodeDescendantOf(node, v.node) { + return v.context } } return nil diff --git a/tsc/internal/core/core.go b/tsc/internal/core/core.go index cb5cd9b6d8327..7436c0cb3186e 100644 --- a/tsc/internal/core/core.go +++ b/tsc/internal/core/core.go @@ -226,8 +226,7 @@ func Find[T any](slice []T, f func(T) bool) T { } func FindLast[T any](slice []T, f func(T) bool) T { - for i := len(slice) - 1; i >= 0; i-- { - value := slice[i] + for _, value := range slices.Backward(slice) { if f(value) { return value } @@ -245,8 +244,7 @@ func FindIndex[T any](slice []T, f func(T) bool) int { } func FindLastIndex[T any](slice []T, f func(T) bool) int { - for i := len(slice) - 1; i >= 0; i-- { - value := slice[i] + for i, value := range slices.Backward(slice) { if f(value) { return i } diff --git a/tsc/internal/format/span.go b/tsc/internal/format/span.go index ef268c873a404..0d8bc0d973142 100644 --- a/tsc/internal/format/span.go +++ b/tsc/internal/format/span.go @@ -659,8 +659,8 @@ func (w *formatSpanWorker) processPair(currentItem TextRangeWithKind, currentSta if len(w.currentRules) > 0 { // Apply rules in reverse order so that higher priority rules (which are first in the array) // win in a conflict with lower priority rules. - for i := len(w.currentRules) - 1; i >= 0; i-- { - rule := w.currentRules[i] + for _, rule := range slices.Backward(w.currentRules) { + lineAction = w.applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine) if dynamicIndentation != nil { switch lineAction { diff --git a/tsc/internal/fourslash/fourslash.go b/tsc/internal/fourslash/fourslash.go index 583fda609fa9e..cef5ed066f75f 100644 --- a/tsc/internal/fourslash/fourslash.go +++ b/tsc/internal/fourslash/fourslash.go @@ -2118,8 +2118,8 @@ func (f *FourslashTest) applyEditsToContent(content string, edits []*lsproto.Tex bStart := f.converters.LineAndCharacterToPosition(script, b.Range.Start) return int(aStart) - int(bStart) }) - for i := len(edits) - 1; i >= 0; i-- { - edit := edits[i] + for _, edit := range slices.Backward(edits) { + start := int(f.converters.LineAndCharacterToPosition(script, edit.Range.Start)) end := int(f.converters.LineAndCharacterToPosition(script, edit.Range.End)) content = content[:start] + edit.NewText + content[end:] @@ -3356,8 +3356,8 @@ func (f *FourslashTest) VerifyBaselineSelectionRanges(t *testing.T) { } trailingWidth := -1 - for j := len(maskedRunes) - 1; j >= 0; j-- { - if isRealCharacter(maskedRunes[j]) { + for j, maskedRune := range slices.Backward(maskedRunes) { + if isRealCharacter(maskedRune) { trailingWidth = j break } @@ -3980,8 +3980,8 @@ func (f *FourslashTest) applyTextEdits(t *testing.T, edits []*lsproto.TextEdit) totalOffset := 0 currentCaretPosition := int(f.converters.LineAndCharacterToPosition(script, f.currentCaretPosition)) // Apply edits in reverse order to avoid affecting the positions of earlier edits. - for i := len(edits) - 1; i >= 0; i-- { - edit := edits[i] + for _, edit := range slices.Backward(edits) { + start := int(f.converters.LineAndCharacterToPosition(script, edit.Range.Start)) end := int(f.converters.LineAndCharacterToPosition(script, edit.Range.End)) f.editScriptAndUpdateMarkers(t, f.activeFilename, start, end, edit.NewText) @@ -4069,8 +4069,8 @@ func (f *FourslashTest) editScriptAndUpdateMarkersWorker(t *testing.T, fileName }) // Apply changes in reverse order to preserve positions of earlier changes - for i := len(sortedChanges) - 1; i >= 0; i-- { - change := sortedChanges[i] + for _, change := range slices.Backward(sortedChanges) { + editStart := change.Pos() editEnd := change.End() script := f.editScript(t, fileName, change) diff --git a/tsc/internal/fswatch/watcher.go b/tsc/internal/fswatch/watcher.go index fa8a7489841d7..44ea4d141ed40 100644 --- a/tsc/internal/fswatch/watcher.go +++ b/tsc/internal/fswatch/watcher.go @@ -270,8 +270,8 @@ func (w *fallbackWatcher) WatchDirectories(requests []WatchDirectoryRequest) ([] watches = make([]Watch, 0, len(requests)) rollback := func() { - for i := len(watches) - 1; i >= 0; i-- { - _ = watches[i].Close() + for _, watch := range slices.Backward(watches) { + _ = watch.Close() } } for _, request := range requests { @@ -491,8 +491,8 @@ func (w *watcher) WatchDirectories(requests []WatchDirectoryRequest) ([]Watch, e uniqueDirWatches := make([]*dirWatch, 0, len(requests)) seenDirWatches := make(map[*dirWatch]struct{}, len(requests)) rollback := func() { - for i := len(prepared) - 1; i >= 0; i-- { - p := prepared[i] + for _, p := range slices.Backward(prepared) { + p.dw.unwatch(p.id) p.dw.unref(w) } diff --git a/tsc/internal/ls/documenthighlights.go b/tsc/internal/ls/documenthighlights.go index e3e8be49d1402..b2f0bc30d16a6 100644 --- a/tsc/internal/ls/documenthighlights.go +++ b/tsc/internal/ls/documenthighlights.go @@ -2,6 +2,7 @@ package ls import ( "context" + "slices" "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/astnav" @@ -364,9 +365,9 @@ func getIfElseKeywords(ifStatement *ast.IfStatement, sourceFile *ast.SourceFile) keywords = append(keywords, children[0]) } // Generally the 'else' keyword is second-to-last, so traverse backwards. - for i := len(children) - 1; i >= 0; i-- { - if children[i].Kind == ast.KindElseKeyword { - keywords = append(keywords, children[i]) + for _, c := range slices.Backward(children) { + if c.Kind == ast.KindElseKeyword { + keywords = append(keywords, c) break } } @@ -639,9 +640,9 @@ func getLoopBreakContinueOccurrences(node *ast.Node, sourceFile *ast.SourceFile) keywords = append(keywords, token) if node.Kind == ast.KindDoStatement { loopTokens := getChildrenFromNonJSDocNode(node, sourceFile) - for i := len(loopTokens) - 1; i >= 0; i-- { - if loopTokens[i].Kind == ast.KindWhileKeyword { - keywords = append(keywords, loopTokens[i]) + for _, loopToken := range slices.Backward(loopTokens) { + if loopToken.Kind == ast.KindWhileKeyword { + keywords = append(keywords, loopToken) break } } diff --git a/tsc/internal/ls/lsutil/children.go b/tsc/internal/ls/lsutil/children.go index 0a5ecf2a991e0..93ccb5a0ba3e2 100644 --- a/tsc/internal/ls/lsutil/children.go +++ b/tsc/internal/ls/lsutil/children.go @@ -1,6 +1,8 @@ package lsutil import ( + "slices" + "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/astnav" "github.com/microsoft/TypeScript/tsc/internal/core" @@ -68,9 +70,9 @@ func GetLastVisitedChild(node *ast.Node, sourceFile *ast.SourceFile) *ast.Node { } visitNodeList := func(nodeList *ast.NodeList, _ *ast.NodeVisitor) *ast.NodeList { if nodeList != nil && len(nodeList.Nodes) > 0 { - for i := len(nodeList.Nodes) - 1; i >= 0; i-- { - if nodeList.Nodes[i].Flags&ast.NodeFlagsReparsed == 0 { - lastChild = nodeList.Nodes[i] + for _, v := range slices.Backward(nodeList.Nodes) { + if v.Flags&ast.NodeFlagsReparsed == 0 { + lastChild = v break } } diff --git a/tsc/internal/ls/symbols.go b/tsc/internal/ls/symbols.go index c9a6d4e27fa42..fd261814ccad6 100644 --- a/tsc/internal/ls/symbols.go +++ b/tsc/internal/ls/symbols.go @@ -381,8 +381,8 @@ func mergeExpandos(symbols []*lsproto.DocumentSymbol) []*lsproto.DocumentSymbol // Merge expandos. if symbol.Kind == lsproto.SymbolKindProperty { symbolsWithSameName := nameToExpandoTargetIndex.Get(symbol.Name) - for j := len(symbolsWithSameName) - 1; j >= 0; j-- { - targetIndex := symbolsWithSameName[j] + for _, targetIndex := range slices.Backward(symbolsWithSameName) { + targetSymbol := symbols[targetIndex] mergeChildren(targetSymbol, symbol) // Mark this symbol as merged. diff --git a/tsc/internal/printer/utilities.go b/tsc/internal/printer/utilities.go index 0ae6a6a833854..857928ebf9f3a 100644 --- a/tsc/internal/printer/utilities.go +++ b/tsc/internal/printer/utilities.go @@ -603,8 +603,7 @@ func tryGetEnd(node interface{ End() int }) (int, bool) { } func greatestEnd(end int, nodes ...interface{ End() int }) int { - for i := len(nodes) - 1; i >= 0; i-- { - node := nodes[i] + for _, node := range slices.Backward(nodes) { if nodeEnd, ok := tryGetEnd(node); ok && end < nodeEnd { end = nodeEnd } diff --git a/tsc/internal/pseudochecker/lookup.go b/tsc/internal/pseudochecker/lookup.go index 38d4c30ec0a08..c2693a7ab1552 100644 --- a/tsc/internal/pseudochecker/lookup.go +++ b/tsc/internal/pseudochecker/lookup.go @@ -608,8 +608,8 @@ func isOptionalInitializedOrRestParameter(node *ast.ParameterDeclarationNode) bo // determine "has required parameter after index i" with `i+1 < lastRequired` // (equivalently, `i < lastRequired-1`) in O(1). func lastRequiredParamIndex(params []*ast.Node) int { - for i := len(params) - 1; i >= 0; i-- { - if !isOptionalInitializedOrRestParameter(params[i]) { + for i, param := range slices.Backward(params) { + if !isOptionalInitializedOrRestParameter(param) { return i + 1 } } diff --git a/tsc/internal/tsoptions/tsconfigparsing.go b/tsc/internal/tsoptions/tsconfigparsing.go index e491d40221679..8f50493b2747c 100644 --- a/tsc/internal/tsoptions/tsconfigparsing.go +++ b/tsc/internal/tsoptions/tsconfigparsing.go @@ -1914,8 +1914,8 @@ func removeWildcardFilesWithLowerPriorityExtension(file string, wildcardFiles *c if extensionGroup == nil { return } - for i := len(extensionGroup) - 1; i >= 0; i-- { - ext := extensionGroup[i] + for _, ext := range slices.Backward(extensionGroup) { + if tspath.FileExtensionIs(file, ext) { return } From c7b7f0fa5b37a69b7a340431a7c7a455f94b8661 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 21 Aug 2026 12:23:44 -0700 Subject: [PATCH 07/10] Complete Go 1.27 development setup --- .devcontainer/devcontainer.json | 3 +++ .golangci.yml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 0641f41ef0ca4..39b3987f6b761 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,9 @@ { "name": "TypeScript Compiler Development", "image": "mcr.microsoft.com/devcontainers/go:dev-1.26-bookworm", + "containerEnv": { + "GOTOOLCHAIN": "go1.27.0" + }, "features": { "ghcr.io/devcontainers/features/node:2": { "version": "24", diff --git a/.golangci.yml b/.golangci.yml index 6dad8234aa2e5..b2a47fb458a92 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -73,6 +73,8 @@ linters: desc: 'Use "github.com/microsoft/TypeScript/tsc/internal/json" instead.' - pkg: 'encoding/json/v2' desc: 'Use "github.com/microsoft/TypeScript/tsc/internal/json" instead.' + - pkg: 'encoding/json/jsontext' + desc: 'Use "github.com/microsoft/TypeScript/tsc/internal/json" instead.' forbidigo: analyze-types: true From 1287f18e5630432bbe992f48fa072d576d8f5f7a Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 21 Aug 2026 12:25:26 -0700 Subject: [PATCH 08/10] Use synctest.Sleep --- tsc/internal/lsp/progress_test.go | 21 +++++++-------------- tsc/internal/project/checkerpool_test.go | 21 +++++++-------------- tsc/internal/project/watchtimeout_test.go | 6 ++---- 3 files changed, 16 insertions(+), 32 deletions(-) diff --git a/tsc/internal/lsp/progress_test.go b/tsc/internal/lsp/progress_test.go index f442087af4997..1f43119dae5cf 100644 --- a/tsc/internal/lsp/progress_test.go +++ b/tsc/internal/lsp/progress_test.go @@ -85,8 +85,7 @@ func TestProgress(t *testing.T) { synctest.Wait() // Advance time past the delay to ensure no progress is sent. - time.Sleep(600 * time.Millisecond) - synctest.Wait() + synctest.Sleep(600 * time.Millisecond) calls := reporter.getCalls() if len(calls) != 0 { @@ -109,8 +108,7 @@ func TestProgress(t *testing.T) { synctest.Wait() // Let the delay fire. - time.Sleep(500 * time.Millisecond) - synctest.Wait() + synctest.Sleep(500 * time.Millisecond) calls := reporter.getCalls() if len(calls) != 2 { @@ -154,8 +152,7 @@ func TestProgress(t *testing.T) { synctest.Wait() // Let the delay fire. - time.Sleep(100 * time.Millisecond) - synctest.Wait() + synctest.Sleep(100 * time.Millisecond) calls := reporter.getCalls() // Should have: create, begin (with first message). @@ -212,8 +209,7 @@ func TestProgress(t *testing.T) { p.start(diagnostics.Project_0, "proj") synctest.Wait() - time.Sleep(100 * time.Millisecond) - synctest.Wait() + synctest.Sleep(100 * time.Millisecond) // Finish once (ref count = 1) — should NOT end. p.finish(diagnostics.Project_0, "proj") @@ -251,8 +247,7 @@ func TestProgress(t *testing.T) { // First cycle. p.start(diagnostics.Project_0, "proj") synctest.Wait() - time.Sleep(100 * time.Millisecond) - synctest.Wait() + synctest.Sleep(100 * time.Millisecond) calls := reporter.getCalls() firstToken := calls[0].token @@ -263,8 +258,7 @@ func TestProgress(t *testing.T) { // Second cycle — should get a new token. p.start(diagnostics.Project_0, "proj2") synctest.Wait() - time.Sleep(100 * time.Millisecond) - synctest.Wait() + synctest.Sleep(100 * time.Millisecond) calls = reporter.getCalls() var secondToken string @@ -301,8 +295,7 @@ func TestProgress(t *testing.T) { synctest.Wait() // Let delay fire. - time.Sleep(200 * time.Millisecond) - synctest.Wait() + synctest.Sleep(200 * time.Millisecond) calls := reporter.getCalls() if len(calls) < 2 { diff --git a/tsc/internal/project/checkerpool_test.go b/tsc/internal/project/checkerpool_test.go index 76fdcf12a7e10..fbd9f8dcef119 100644 --- a/tsc/internal/project/checkerpool_test.go +++ b/tsc/internal/project/checkerpool_test.go @@ -152,8 +152,7 @@ func TestCheckerPoolIdleCleanup(t *testing.T) { pool.mu.Unlock() // Advance past idle timeout. - time.Sleep(5 * time.Second) - synctest.Wait() + synctest.Sleep(5 * time.Second) // After cleanup, both checkers should be disposed. pool.mu.Lock() @@ -190,8 +189,7 @@ func TestCheckerPoolFileAssociationCleanup(t *testing.T) { assert.Assert(t, hasAssoc, "file should have a checker association") // Advance past idle timeout. - time.Sleep(5 * time.Second) - synctest.Wait() + synctest.Sleep(5 * time.Second) // File association should be cleared. pool.mu.Lock() @@ -428,8 +426,7 @@ func TestCheckerPoolDiagnosticsRecreatedAfterIdleDisposal(t *testing.T) { synctest.Wait() // Advance past idle timeout — diagnostics checker should be disposed. - time.Sleep(5 * time.Second) - synctest.Wait() + synctest.Sleep(5 * time.Second) pool.mu.Lock() assert.Assert(t, pool.checkers[0] == nil, "diagnostics checker should be disposed") @@ -634,8 +631,7 @@ func TestCheckerPoolDiscardKeepsIdleCheckers(t *testing.T) { pool.mu.Unlock() // Even after a long wait, checkers should not be disposed (no timer running). - time.Sleep(60 * time.Second) - synctest.Wait() + synctest.Sleep(60 * time.Second) pool.mu.Lock() assert.Assert(t, pool.checkers[0] == c1, "diagnostics checker should persist indefinitely on discarded pool") @@ -687,8 +683,7 @@ func TestCheckerPoolDiscardHeldCheckerSurvivesRelease(t *testing.T) { pool.mu.Unlock() // Even after a long wait, checker persists (no cleanup timer running). - time.Sleep(60 * time.Second) - synctest.Wait() + synctest.Sleep(60 * time.Second) pool.mu.Lock() assert.Assert(t, pool.checkers[heldIndex] == c, "checker should persist indefinitely on discarded pool") @@ -850,8 +845,7 @@ func TestCheckerPoolAPICheckerStableIdentity(t *testing.T) { release2() // Should survive idle timeout. - time.Sleep(60 * time.Second) - synctest.Wait() + synctest.Sleep(60 * time.Second) c3, release3 := pool.GetChecker(ctx, nil) assert.Assert(t, c3 == c1, "API checker should survive idle timeout") @@ -1093,8 +1087,7 @@ func TestCheckerPoolStaggeredIdleCleanup(t *testing.T) { // Advance past t=16 (when the timer fires). Both should be disposed // because A has been idle 16s and B has been idle 10s. - time.Sleep(11 * time.Second) - synctest.Wait() + synctest.Sleep(11 * time.Second) pool.mu.Lock() assert.Assert(t, pool.checkers[idxA] == nil, "checker A should be disposed after timer fires") diff --git a/tsc/internal/project/watchtimeout_test.go b/tsc/internal/project/watchtimeout_test.go index 4e77f430c94ea..129749dd0e1bb 100644 --- a/tsc/internal/project/watchtimeout_test.go +++ b/tsc/internal/project/watchtimeout_test.go @@ -69,8 +69,7 @@ func TestUpdateWatchTimeoutAndRollback(t *testing.T) { // Let the background goroutine block on WatchFiles, then advance // fake time past the 1s watchRequestTimeout. synctest.Wait() - time.Sleep(2 * time.Second) - synctest.Wait() + synctest.Sleep(2 * time.Second) mu.Lock() firstAttemptIDs := append([]project.WatcherID(nil), attemptedIDs...) @@ -108,8 +107,7 @@ func TestUpdateWatchTimeoutAndRollback(t *testing.T) { // Let the background task run updateWatches. synctest.Wait() - time.Sleep(2 * time.Second) - synctest.Wait() + synctest.Sleep(2 * time.Second) // Verify: WatchFiles was called again with the same watcher IDs, // and this time the calls succeeded. From bf6a7d047f222a29dd9b9ef2218d069b4e3e06d5 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sat, 29 Aug 2026 23:35:58 -0700 Subject: [PATCH 09/10] Make use of generic methods --- tsc/internal/api/encoder/encoder.go | 4 +- tsc/internal/ast/ast.go | 6 +- tsc/internal/checker/checker.go | 10 +- tsc/internal/checker/services.go | 14 +- tsc/internal/fourslash/baselineutil.go | 3 +- tsc/internal/fourslash/fourslash.go | 166 ++++++++-------- tsc/internal/fourslash/semantictokens.go | 2 +- tsc/internal/fourslash/statebaseline.go | 3 +- tsc/internal/ls/autoimport/registry.go | 8 +- tsc/internal/ls/autoimport/view.go | 4 +- tsc/internal/ls/autoinsert.go | 3 +- tsc/internal/ls/callhierarchy.go | 5 +- tsc/internal/ls/change/trackerimpl.go | 3 +- tsc/internal/ls/codeactions.go | 2 +- tsc/internal/ls/completions.go | 3 +- tsc/internal/ls/crossproject.go | 3 +- tsc/internal/ls/definition.go | 4 +- tsc/internal/ls/documenthighlights.go | 2 +- tsc/internal/ls/findallreferences.go | 17 +- tsc/internal/ls/folding.go | 2 +- tsc/internal/ls/format.go | 7 +- tsc/internal/ls/hover.go | 3 +- tsc/internal/ls/inlay_hints.go | 2 +- tsc/internal/ls/linkedediting.go | 3 +- tsc/internal/ls/lsconv/converters.go | 24 +-- tsc/internal/ls/lsconv/converters_test.go | 8 +- tsc/internal/ls/rename.go | 5 +- tsc/internal/ls/selectionranges.go | 3 +- tsc/internal/ls/semantictokens.go | 2 +- tsc/internal/ls/signaturehelp.go | 3 +- tsc/internal/ls/sourcedefinition.go | 3 +- tsc/internal/lsp/lsproto/lsp.go | 8 +- tsc/internal/lsp/lsproto/lsp_json_test.go | 4 +- tsc/internal/lsp/progress.go | 4 +- tsc/internal/lsp/server.go | 184 +++++++++--------- tsc/internal/lsp/server_completion_test.go | 34 ++-- tsc/internal/lsp/server_contentmapper_test.go | 28 +-- tsc/internal/lsp/server_progress_test.go | 10 +- tsc/internal/lsp/server_projectinfo_test.go | 12 +- .../server_projectreference_updates_test.go | 14 +- .../lsp/server_semantictokens_test.go | 20 +- tsc/internal/packagejson/exportsorimports.go | 2 +- tsc/internal/packagejson/jsonvalue.go | 37 +--- tsc/internal/parser/parser.go | 40 ++-- tsc/internal/project/overlayfs.go | 2 +- tsc/internal/project/session.go | 72 +++---- .../testutil/lsptestutil/lspclient.go | 6 +- tsc/internal/tspath/path.go | 4 +- 48 files changed, 377 insertions(+), 431 deletions(-) diff --git a/tsc/internal/api/encoder/encoder.go b/tsc/internal/api/encoder/encoder.go index f318a27c44547..c5786c5e39715 100644 --- a/tsc/internal/api/encoder/encoder.go +++ b/tsc/internal/api/encoder/encoder.go @@ -405,7 +405,7 @@ func BuildNodeIndexTable(sourceFile *ast.SourceFile) *NodeIndexTable { } func GetNodeIndexTable(sourceFile *ast.SourceFile) *NodeIndexTable { - return ast.GetOrComputeSourceFileData(sourceFile, nodeIndexTableKey, BuildNodeIndexTable) + return sourceFile.GetOrComputeData(nodeIndexTableKey, BuildNodeIndexTable) } // EncodeSourceFile encodes an entire source file AST into the binary format. @@ -415,7 +415,7 @@ func EncodeSourceFile(sourceFile *ast.SourceFile) ([]byte, *NodeIndexTable, erro if err != nil { return nil, nil, err } - nodeTable = ast.GetOrComputeSourceFileData(sourceFile, nodeIndexTableKey, func(*ast.SourceFile) *NodeIndexTable { + nodeTable = sourceFile.GetOrComputeData(nodeIndexTableKey, func(*ast.SourceFile) *NodeIndexTable { return nodeTable }) return data, nodeTable, nil diff --git a/tsc/internal/ast/ast.go b/tsc/internal/ast/ast.go index 07b0fdc62c644..1e2afec3c5bfb 100644 --- a/tsc/internal/ast/ast.go +++ b/tsc/internal/ast/ast.go @@ -2414,15 +2414,15 @@ func NewSourceFileDataKey[T any]() *SourceFileDataKey[T] { return &SourceFileDataKey[T]{key: sourceFileDataKey(sourceFileDataKeyCounter.Add(1))} } -func GetOrComputeSourceFileData[T any](file *SourceFile, key *SourceFileDataKey[T], compute func(*SourceFile) T) T { - cell := getSourceFileDataCell(file, key) +func (file *SourceFile) GetOrComputeData[T any](key *SourceFileDataKey[T], compute func(*SourceFile) T) T { + cell := file.getDataCell(key) cell.once.Do(func() { cell.value = compute(file) }) return cell.value } -func getSourceFileDataCell[T any](file *SourceFile, key *SourceFileDataKey[T]) *sourceFileDataCell[T] { +func (file *SourceFile) getDataCell[T any](key *SourceFileDataKey[T]) *sourceFileDataCell[T] { if key == nil || key.key == 0 { panic("invalid SourceFileDataKey; use NewSourceFileDataKey") } diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 8cbf7ea93edd5..18ffe0786a3cc 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -22902,22 +22902,22 @@ func (c *Checker) instantiateTypeAlias(alias *TypeAlias, m *TypeMapper) *TypeAli } func (c *Checker) instantiateTypes(types []*Type, m *TypeMapper) []*Type { - return instantiateList(c, types, m, (*Checker).instantiateType) + return c.instantiateList(types, m, (*Checker).instantiateType) } func (c *Checker) instantiateSymbols(symbols []*ast.Symbol, m *TypeMapper) []*ast.Symbol { - return instantiateList(c, symbols, m, (*Checker).instantiateSymbol) + return c.instantiateList(symbols, m, (*Checker).instantiateSymbol) } func (c *Checker) instantiateSignatures(signatures []*Signature, m *TypeMapper) []*Signature { - return instantiateList(c, signatures, m, (*Checker).instantiateSignature) + return c.instantiateList(signatures, m, (*Checker).instantiateSignature) } func (c *Checker) instantiateIndexInfos(indexInfos []*IndexInfo, m *TypeMapper) []*IndexInfo { - return instantiateList(c, indexInfos, m, (*Checker).instantiateIndexInfo) + return c.instantiateList(indexInfos, m, (*Checker).instantiateIndexInfo) } -func instantiateList[T comparable](c *Checker, values []T, m *TypeMapper, instantiator func(c *Checker, value T, m *TypeMapper) T) []T { +func (c *Checker) instantiateList[T comparable](values []T, m *TypeMapper, instantiator func(c *Checker, value T, m *TypeMapper) T) []T { for i, value := range values { mapped := instantiator(c, value, m) if mapped != value { diff --git a/tsc/internal/checker/services.go b/tsc/internal/checker/services.go index b6ded42d9504e..f0c1a1f893024 100644 --- a/tsc/internal/checker/services.go +++ b/tsc/internal/checker/services.go @@ -315,12 +315,12 @@ func (c *Checker) shouldTreatPropertiesOfExternalModuleAsExports(resolvedExterna func (c *Checker) GetContextualType(node *ast.Expression, contextFlags ContextFlags) *Type { if contextFlags&ContextFlagsIgnoreNodeInferences != 0 { - return runWithInferenceBlockedFromSourceNode(c, node, func() *Type { return c.getContextualType(node, contextFlags) }) + return c.runWithInferenceBlockedFromSourceNode(node, func() *Type { return c.getContextualType(node, contextFlags) }) } return c.getContextualType(node, contextFlags) } -func runWithInferenceBlockedFromSourceNode[T any](c *Checker, node *ast.Node, fn func() T) T { +func (c *Checker) runWithInferenceBlockedFromSourceNode[T any](node *ast.Node, fn func() T) T { containingCall := ast.FindAncestor(node, ast.IsCallLikeExpression) if containingCall != nil { toMarkSkip := node @@ -334,7 +334,7 @@ func runWithInferenceBlockedFromSourceNode[T any](c *Checker, node *ast.Node, fn } c.isInferencePartiallyBlocked = true - result := runWithoutResolvedSignatureCaching(c, node, fn) + result := c.runWithoutResolvedSignatureCaching(node, fn) c.isInferencePartiallyBlocked = false c.skipDirectInferenceNodes.Clear() @@ -346,14 +346,14 @@ func GetResolvedSignatureForSignatureHelp(node *ast.Node, argumentCount int, c * signature *Signature candidates []*Signature } - res := runWithoutResolvedSignatureCaching(c, node, func() result { + res := c.runWithoutResolvedSignatureCaching(node, func() result { signature, candidates := c.getResolvedSignatureWorker(node, CheckModeIsForSignatureHelp, argumentCount) return result{signature, candidates} }) return res.signature, res.candidates } -func runWithoutResolvedSignatureCaching[T any](c *Checker, node *ast.Node, fn func() T) T { +func (c *Checker) runWithoutResolvedSignatureCaching[T any](node *ast.Node, fn func() T) T { ancestorNode := ast.FindAncestor(node, ast.IsCallLikeOrFunctionLikeExpression) if ancestorNode != nil { cachedResolvedSignatures := make(map[*SignatureLinks]*Signature) @@ -899,14 +899,14 @@ func (c *Checker) getResolvedSignatureWorker(node *ast.Node, checkMode CheckMode func (c *Checker) GetCandidateSignaturesForStringLiteralCompletions(call *ast.CallLikeExpression, editingArgument *ast.Node) []*Signature { // first, get candidates when inference is blocked from the source node. - candidates := runWithInferenceBlockedFromSourceNode(c, editingArgument, func() []*Signature { + candidates := c.runWithInferenceBlockedFromSourceNode(editingArgument, func() []*Signature { _, blockedInferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0) return blockedInferenceCandidates }) candidatesSet := collections.NewSetFromItems(candidates...) // next, get candidates where the source node is considered for inference. - otherCandidates := runWithoutResolvedSignatureCaching(c, editingArgument, func() []*Signature { + otherCandidates := c.runWithoutResolvedSignatureCaching(editingArgument, func() []*Signature { _, inferenceCandidates := c.getResolvedSignatureWorker(call, CheckModeNormal, 0) return inferenceCandidates }) diff --git a/tsc/internal/fourslash/baselineutil.go b/tsc/internal/fourslash/baselineutil.go index c0c0f7615aefd..4745271dac8f3 100644 --- a/tsc/internal/fourslash/baselineutil.go +++ b/tsc/internal/fourslash/baselineutil.go @@ -665,9 +665,8 @@ type markerAndItem[T any] struct { Item T `json:"item"` } -func annotateContentWithTooltips[T comparable]( +func (f *FourslashTest) annotateContentWithTooltips[T comparable]( t *testing.T, - f *FourslashTest, markersAndItems []markerAndItem[T], opName string, getRange func(item T) *lsproto.Range, diff --git a/tsc/internal/fourslash/fourslash.go b/tsc/internal/fourslash/fourslash.go index cef5ed066f75f..155b7ab034254 100644 --- a/tsc/internal/fourslash/fourslash.go +++ b/tsc/internal/fourslash/fourslash.go @@ -93,7 +93,7 @@ func (c *testConverters) PositionToLineAndCharacter(script lsconv.Script, positi } func (c *testConverters) LineAndCharacterToPosition(script lsconv.Script, position lsproto.Position) core.TextPos { - positions := lsconv.FromLSPPosition(c.Converters, script, position, spanmap.FeatureAll) + positions := c.Converters.FromLSPPosition(script, position, spanmap.FeatureAll) debug.Assert(len(positions) == 1, "fourslash script must have exactly one position projection") return positions[0].Position } @@ -291,7 +291,7 @@ func (f *FourslashTest) handleServerRequest(_ context.Context, req *lsproto.Requ // Return current user preferences for each requested section. // The server requests multiple sections (js/ts, typescript, javascript, editor); // we return user preferences for "js/ts" and nil for others. - params, err := lsproto.UnmarshalParams[*lsproto.ConfigurationParams](req) + params, err := req.UnmarshalParams[*lsproto.ConfigurationParams]() if err != nil || params == nil || params.Items == nil { return &lsproto.ResponseMessage{ ID: req.ID, @@ -380,14 +380,14 @@ func (f *FourslashTest) initialize(t *testing.T, capabilities *lsproto.ClientCap } params.Capabilities = getCapabilitiesWithDefaults(capabilities) f.capabilities = params.Capabilities - resp, _, ok := lsptestutil.SendRequest(t, f.client, lsproto.InitializeInfo, params) + resp, _, ok := f.client.SendRequest(t, lsproto.InitializeInfo, params) if !ok { t.Fatalf("Initialize request failed") } if resp.AsResponse().Error != nil { t.Fatalf("Initialize request returned error: %s", resp.AsResponse().Error.String()) } - lsptestutil.SendNotification(t, f.client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + f.client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) // Wait for the initial configuration exchange to complete // The server will send workspace/configuration as part of handleInitialized @@ -736,19 +736,19 @@ func getCapabilitiesWithDefaults(capabilities *lsproto.ClientCapabilities) *lspr return &capabilitiesWithDefaults } -func sendRequest[Params, Resp any](t *testing.T, f *FourslashTest, info lsproto.RequestInfo[Params, Resp], params Params) Resp { +func (f *FourslashTest) sendRequest[Params, Resp any](t *testing.T, info lsproto.RequestInfo[Params, Resp], params Params) Resp { t.Helper() - return sendRequestAndBaselineWorker(t, f, info, params, true) + return f.sendRequestAndBaselineWorker(t, info, params, true) } -func sendRequestAndBaselineWorker[Params, Resp any](t *testing.T, f *FourslashTest, info lsproto.RequestInfo[Params, Resp], params Params, baselineProjects bool) Resp { +func (f *FourslashTest) sendRequestAndBaselineWorker[Params, Resp any](t *testing.T, info lsproto.RequestInfo[Params, Resp], params Params, baselineProjects bool) Resp { t.Helper() prefix := f.getCurrentPositionPrefix() if baselineProjects { f.baselineState(t) } f.baselineRequestOrNotification(t, info.Method, params) - resMsg, result, resultOk := lsptestutil.SendRequest(t, f.client, info, params) + resMsg, result, resultOk := f.client.SendRequest(t, info, params) if baselineProjects { f.baselineState(t) } @@ -773,7 +773,7 @@ func sendRequestAndBaselineWorker[Params, Resp any](t *testing.T, f *FourslashTe return result } -func sendNotification[Params any](t *testing.T, f *FourslashTest, info lsproto.NotificationInfo[Params], params Params) { +func (f *FourslashTest) sendNotification[Params any](t *testing.T, info lsproto.NotificationInfo[Params], params Params) { t.Helper() if info.Method != lsproto.MethodTextDocumentDidChange { // This is called eg when doing typeText = which is series of edits and formatting - which becomes non deterministic "after state" @@ -784,7 +784,7 @@ func sendNotification[Params any](t *testing.T, f *FourslashTest, info lsproto.N f.updateState(info.Method, params) } f.baselineRequestOrNotification(t, info.Method, params) - lsptestutil.SendNotification(t, f.client, info, params) + f.client.SendNotification(t, info, params) } func (f *FourslashTest) updateState(method lsproto.Method, params any) { @@ -805,7 +805,7 @@ func (f *FourslashTest) Configure(t *testing.T, config lsutil.UserPreferences) { // set of preferences for both languages). This should be fine in fourslash since tests that need // multiple options usually send reconfiguration commands for each `verify` anyways f.userPreferences = config - sendNotification(t, f, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{ + f.sendNotification(t, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{ Settings: map[string]any{ "js/ts": config, }, @@ -983,7 +983,7 @@ func (f *FourslashTest) CloseFileOfMarker(t *testing.T, markerName string) { } else { delete(f.scriptInfos, marker.FileName()) } - sendNotification(t, f, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ + f.sendNotification(t, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(marker.FileName()), }, @@ -1001,7 +1001,7 @@ func (f *FourslashTest) openFile(t *testing.T, filename string) { } } f.activeFilename = filename - sendNotification(t, f, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + f.sendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{ Uri: lsconv.FileNameToDocumentURI(filename), LanguageId: getLanguageKind(filename), @@ -1015,7 +1015,7 @@ func (f *FourslashTest) FormatDocument(t *testing.T, filename string) { if filename == "" { filename = f.activeFilename } - result := sendRequest(t, f, lsproto.TextDocumentFormattingInfo, &lsproto.DocumentFormattingParams{ + result := f.sendRequest(t, lsproto.TextDocumentFormattingInfo, &lsproto.DocumentFormattingParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(filename), }, @@ -1041,7 +1041,7 @@ func (f *FourslashTest) FormatSelection(t *testing.T, startMarkerName string, en t.Fatalf("Markers '%s' and '%s' are in different files", startMarkerName, endMarkerName) } filename := startMarker.FileName() - result := sendRequest(t, f, lsproto.TextDocumentRangeFormattingInfo, &lsproto.DocumentRangeFormattingParams{ + result := f.sendRequest(t, lsproto.TextDocumentRangeFormattingInfo, &lsproto.DocumentRangeFormattingParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(filename), }, @@ -1335,7 +1335,7 @@ func (f *FourslashTest) getCompletions(t *testing.T, userPreferences *lsutil.Use reset := f.ConfigureWithReset(t, preferences) defer reset() } - result := sendRequest(t, f, lsproto.TextDocumentCompletionInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentCompletionInfo, params) // For performance, the server may return unsorted completion lists. // The client is expected to sort them by SortText and then by Label. // We are the client here. @@ -1653,7 +1653,7 @@ func (f *FourslashTest) ResolveCompletionItem(t *testing.T, item *lsproto.Comple } func (f *FourslashTest) resolveCompletionItem(t *testing.T, item *lsproto.CompletionItem) *lsproto.CompletionItem { - result := sendRequest(t, f, lsproto.CompletionItemResolveInfo, item) + result := f.sendRequest(t, lsproto.CompletionItemResolveInfo, item) return result } @@ -1982,7 +1982,7 @@ func (f *FourslashTest) VerifySourceFixAll(t *testing.T, expectedContent string) Only: &only, }, } - result := sendRequest(t, f, lsproto.TextDocumentCodeActionInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentCodeActionInfo, params) if result.CommandOrCodeActionArray == nil { t.Fatalf("No source.fixAll code actions returned") @@ -2037,7 +2037,7 @@ func (f *FourslashTest) getAllQuickFixActions(t *testing.T, errorCode ...int) [] Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, } - diagResult := sendRequest(t, f, lsproto.TextDocumentDiagnosticInfo, diagParams) + diagResult := f.sendRequest(t, lsproto.TextDocumentDiagnosticInfo, diagParams) var diagnostics []*lsproto.Diagnostic if diagResult.FullDocumentDiagnosticReport != nil && diagResult.FullDocumentDiagnosticReport.Items != nil { @@ -2065,7 +2065,7 @@ func (f *FourslashTest) getAllQuickFixActions(t *testing.T, errorCode ...int) [] Diagnostics: diagnostics, }, } - result := sendRequest(t, f, lsproto.TextDocumentCodeActionInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentCodeActionInfo, params) var actions []*lsproto.CodeAction if result.CommandOrCodeActionArray != nil { @@ -2148,7 +2148,7 @@ func (f *FourslashTest) VerifyOrganizeImports(t *testing.T, expectedContent stri }, } - result := sendRequest(t, f, lsproto.TextDocumentCodeActionInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentCodeActionInfo, params) if result.CommandOrCodeActionArray == nil || len(*result.CommandOrCodeActionArray) == 0 { t.Fatalf("No organize imports code action found") @@ -2290,7 +2290,7 @@ func (f *FourslashTest) VerifyImportFixAtPosition(t *testing.T, expectedTexts [] Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, } - diagResult := sendRequest(t, f, lsproto.TextDocumentDiagnosticInfo, diagParams) + diagResult := f.sendRequest(t, lsproto.TextDocumentDiagnosticInfo, diagParams) var diagnostics []*lsproto.Diagnostic if diagResult.FullDocumentDiagnosticReport != nil && diagResult.FullDocumentDiagnosticReport.Items != nil { @@ -2310,7 +2310,7 @@ func (f *FourslashTest) VerifyImportFixAtPosition(t *testing.T, expectedTexts [] Diagnostics: diagnostics, }, } - result := sendRequest(t, f, lsproto.TextDocumentCodeActionInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentCodeActionInfo, params) // Find all auto-import code actions (fixes with fixId/fixName related to imports) // Skip fix-all entries (those without diagnostics attached) @@ -2404,7 +2404,7 @@ func (f *FourslashTest) VerifyImportFixModuleSpecifiers( Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, } - diagResult := sendRequest(t, f, lsproto.TextDocumentDiagnosticInfo, diagParams) + diagResult := f.sendRequest(t, lsproto.TextDocumentDiagnosticInfo, diagParams) var diagnostics []*lsproto.Diagnostic if diagResult.FullDocumentDiagnosticReport != nil && diagResult.FullDocumentDiagnosticReport.Items != nil { @@ -2423,7 +2423,7 @@ func (f *FourslashTest) VerifyImportFixModuleSpecifiers( Diagnostics: diagnostics, }, } - result := sendRequest(t, f, lsproto.TextDocumentCodeActionInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentCodeActionInfo, params) // Extract module specifiers from import fix code actions var actualModuleSpecifiers []string @@ -2512,7 +2512,7 @@ func (f *FourslashTest) VerifyBaselineFindAllReferences( IncludeDeclaration: true, }, } - result := sendRequest(t, f, lsproto.TextDocumentReferencesInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentReferencesInfo, params) f.addResultToBaseline(t, findAllReferencesCmd, f.getBaselineForLocationsWithFileContents(*result.Locations, baselineFourslashLocationsOptions{ marker: markerOrRange, markerName: "/*FIND ALL REFS*/", @@ -2539,7 +2539,7 @@ func (f *FourslashTest) VerifyBaselineVSFindAllReferences( IncludeDeclaration: true, }, } - result := sendRequest(t, f, lsproto.TextDocumentVSReferencesInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentVSReferencesInfo, params) // Sort cross-project results for deterministic baselines if result.VSReferenceItems != nil && len(*result.VSReferenceItems) > 0 { items := *result.VSReferenceItems @@ -2615,7 +2615,7 @@ func (f *FourslashTest) VerifyBaselineCodeLens(t *testing.T, preferences *lsutil }, } - unresolvedCodeLensList := sendRequest(t, f, lsproto.TextDocumentCodeLensInfo, params) + unresolvedCodeLensList := f.sendRequest(t, lsproto.TextDocumentCodeLensInfo, params) if unresolvedCodeLensList.CodeLenses == nil || len(*unresolvedCodeLensList.CodeLenses) == 0 { continue } @@ -2623,7 +2623,7 @@ func (f *FourslashTest) VerifyBaselineCodeLens(t *testing.T, preferences *lsutil for _, unresolvedCodeLens := range *unresolvedCodeLensList.CodeLenses { assert.Assert(t, unresolvedCodeLens != nil) - resolvedCodeLens := sendRequest(t, f, lsproto.CodeLensResolveInfo, unresolvedCodeLens) + resolvedCodeLens := f.sendRequest(t, lsproto.CodeLensResolveInfo, unresolvedCodeLens) assert.Assert(t, resolvedCodeLens != nil) assert.Assert(t, resolvedCodeLens.Command != nil, "Expected resolved code lens to have a command.") if len(resolvedCodeLens.Command.Command) > 0 { @@ -2640,7 +2640,7 @@ func (f *FourslashTest) VerifyBaselineCodeLens(t *testing.T, preferences *lsutil locations = locs } - ranges := lsconv.FromLSPRange(f.converters.Converters, f.getScriptInfo(openFile), resolvedCodeLens.Range, spanmap.FeatureAll) + ranges := f.converters.Converters.FromLSPRange(f.getScriptInfo(openFile), resolvedCodeLens.Range, spanmap.FeatureAll) if len(ranges) != 1 { continue } @@ -2682,7 +2682,7 @@ func (f *FourslashTest) VerifyBaselineGoToDefinition( Position: f.currentCaretPosition, } - return sendRequest(t, f, lsproto.TextDocumentDefinitionInfo, params) + return f.sendRequest(t, lsproto.TextDocumentDefinitionInfo, params) }, includeOriginalSelectionRange, markers..., @@ -2761,7 +2761,7 @@ func (f *FourslashTest) VerifyBaselineGoToTypeDefinition( Position: f.currentCaretPosition, } - return sendRequest(t, f, lsproto.TextDocumentTypeDefinitionInfo, params) + return f.sendRequest(t, lsproto.TextDocumentTypeDefinitionInfo, params) }, false, /*includeOriginalSelectionRange*/ markers..., @@ -2784,7 +2784,7 @@ func (f *FourslashTest) VerifyBaselineGoToSourceDefinition( Position: f.currentCaretPosition, } - result := sendRequest(t, f, lsproto.CustomTextDocumentSourceDefinitionInfo, params) + result := f.sendRequest(t, lsproto.CustomTextDocumentSourceDefinitionInfo, params) if result == nil { return lsproto.LocationOrLocationsOrDefinitionLinksOrNull{} } @@ -2797,7 +2797,7 @@ func (f *FourslashTest) VerifyBaselineGoToSourceDefinition( func (f *FourslashTest) VerifyBaselineWorkspaceSymbol(t *testing.T, query string) { t.Helper() - result := sendRequest(t, f, lsproto.WorkspaceSymbolInfo, &lsproto.WorkspaceSymbolParams{Query: query}) + result := f.sendRequest(t, lsproto.WorkspaceSymbolInfo, &lsproto.WorkspaceSymbolParams{Query: query}) locationToText := map[documentSpan]*lsproto.SymbolInformation{} groupedRanges := collections.MultiMap[lsproto.DocumentUri, documentSpan]{} @@ -2826,7 +2826,7 @@ func (f *FourslashTest) VerifyOutliningSpans(t *testing.T, foldingRangeKind ...l Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, } - result := sendRequest(t, f, lsproto.TextDocumentFoldingRangeInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentFoldingRangeInfo, params) if result.FoldingRanges == nil { t.Fatalf("Nil response received for folding range request") } @@ -2883,7 +2883,7 @@ func (f *FourslashTest) VerifyFoldingRangeLines(t *testing.T, expected []Folding Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, } - result := sendRequest(t, f, lsproto.TextDocumentFoldingRangeInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentFoldingRangeInfo, params) if result.FoldingRanges == nil { t.Fatalf("Nil response received for folding range request") } @@ -2915,7 +2915,7 @@ func (f *FourslashTest) VerifyBaselineHover(t *testing.T) { Position: marker.LSPosition, } - result := sendRequest(t, f, lsproto.TextDocumentHoverInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentHoverInfo, params) return markerAndItem[*lsproto.Hover]{Marker: marker, Item: result.Hover}, true }) @@ -2951,7 +2951,7 @@ func (f *FourslashTest) VerifyBaselineHover(t *testing.T) { return result } - f.addResultToBaseline(t, quickInfoCmd, annotateContentWithTooltips(t, f, markersAndItems, "quickinfo", getRange, getTooltipLines)) + f.addResultToBaseline(t, quickInfoCmd, f.annotateContentWithTooltips(t, markersAndItems, "quickinfo", getRange, getTooltipLines)) if jsonStr, err := core.StringifyJson(markersAndItems, "", " "); err == nil { f.writeToBaseline(quickInfoCmd, jsonStr) } else { @@ -2975,7 +2975,7 @@ func (f *FourslashTest) VerifyBaselineVSHover(t *testing.T) { Position: marker.LSPosition, } - result := sendRequest(t, f, lsproto.TextDocumentHoverInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentHoverInfo, params) return markerAndItem[*lsproto.Hover]{Marker: marker, Item: result.Hover}, true }) @@ -2996,7 +2996,7 @@ func (f *FourslashTest) VerifyBaselineVSHover(t *testing.T) { return renderVSContainerElement(item.VSRawContent, "") } - f.addResultToBaseline(t, vsQuickInfoCmd, annotateContentWithTooltips(t, f, markersAndItems, "vsquickinfo", getRange, getTooltipLines)) + f.addResultToBaseline(t, vsQuickInfoCmd, f.annotateContentWithTooltips(t, markersAndItems, "vsquickinfo", getRange, getTooltipLines)) if jsonStr, err := core.StringifyJson(markersAndItems, "", " "); err == nil { f.writeToBaseline(vsQuickInfoCmd, jsonStr) } else { @@ -3076,7 +3076,7 @@ func (f *FourslashTest) VerifyBaselineHoverWithVerbosity(t *testing.T, verbosity Position: marker.LSPosition, VerbosityLevel: verbLevel, } - result := sendRequest(t, f, lsproto.TextDocumentHoverInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentHoverInfo, params) item := &hoverWithVerbosity{ Hover: result.Hover, VerbosityLevel: level, @@ -3135,7 +3135,7 @@ func (f *FourslashTest) VerifyBaselineHoverWithVerbosity(t *testing.T, verbosity return result } - f.addResultToBaseline(t, quickInfoCmd, annotateContentWithTooltips(t, f, markersAndItems, "quickinfo", getRange, getTooltipLines)) + f.addResultToBaseline(t, quickInfoCmd, f.annotateContentWithTooltips(t, markersAndItems, "quickinfo", getRange, getTooltipLines)) if jsonStr, err := core.StringifyJson(markersAndItems, "", " "); err == nil { f.writeToBaseline(quickInfoCmd, jsonStr) } else { @@ -3156,7 +3156,7 @@ func (f *FourslashTest) VerifyBaselineSignatureHelp(t *testing.T) { Position: marker.LSPosition, } - result := sendRequest(t, f, lsproto.TextDocumentSignatureHelpInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentSignatureHelpInfo, params) return markerAndItem[*lsproto.SignatureHelp]{Marker: marker, Item: result.SignatureHelp}, true }) @@ -3245,7 +3245,7 @@ func (f *FourslashTest) VerifyBaselineSignatureHelp(t *testing.T) { return result } - f.addResultToBaseline(t, signatureHelpCmd, annotateContentWithTooltips(t, f, markersAndItems, "signaturehelp", getRange, getTooltipLines)) + f.addResultToBaseline(t, signatureHelpCmd, f.annotateContentWithTooltips(t, markersAndItems, "signaturehelp", getRange, getTooltipLines)) if jsonStr, err := core.StringifyJson(markersAndItems, "", " "); err == nil { f.writeToBaseline(signatureHelpCmd, jsonStr) } else { @@ -3284,7 +3284,7 @@ func (f *FourslashTest) VerifyBaselineSelectionRanges(t *testing.T) { Positions: []lsproto.Position{marker.LSPosition}, } - selectionRangeResult := sendRequest(t, f, lsproto.TextDocumentSelectionRangeInfo, params) + selectionRangeResult := f.sendRequest(t, lsproto.TextDocumentSelectionRangeInfo, params) if selectionRangeResult.SelectionRanges == nil || len(*selectionRangeResult.SelectionRanges) == 0 { result.WriteString("No selection ranges available\n") @@ -3402,7 +3402,7 @@ func (f *FourslashTest) VerifyBaselineCallHierarchy(t *testing.T) { Position: position, } - prepareResult := sendRequest(t, f, lsproto.TextDocumentPrepareCallHierarchyInfo, params) + prepareResult := f.sendRequest(t, lsproto.TextDocumentPrepareCallHierarchyInfo, params) if prepareResult.CallHierarchyItems == nil || len(*prepareResult.CallHierarchyItems) == 0 { f.addResultToBaseline(t, callHierarchyCmd, "No call hierarchy items available") return @@ -3478,7 +3478,7 @@ func formatCallHierarchyItem( incomingParams := &lsproto.CallHierarchyIncomingCallsParams{ Item: &callHierarchyItem, } - incomingResult := sendRequest(t, f, lsproto.CallHierarchyIncomingCallsInfo, incomingParams) + incomingResult := f.sendRequest(t, lsproto.CallHierarchyIncomingCallsInfo, incomingParams) if incomingResult.CallHierarchyIncomingCalls != nil { incomingCalls.values = *incomingResult.CallHierarchyIncomingCalls } @@ -3492,7 +3492,7 @@ func formatCallHierarchyItem( outgoingParams := &lsproto.CallHierarchyOutgoingCallsParams{ Item: &callHierarchyItem, } - outgoingResult := sendRequest(t, f, lsproto.CallHierarchyOutgoingCallsInfo, outgoingParams) + outgoingResult := f.sendRequest(t, lsproto.CallHierarchyOutgoingCallsInfo, outgoingParams) if outgoingResult.CallHierarchyOutgoingCalls != nil { outgoingCalls.values = *outgoingResult.CallHierarchyOutgoingCalls } @@ -3771,7 +3771,7 @@ func (f *FourslashTest) verifyBaselineDocumentHighlights( Position: f.currentCaretPosition, FilesToSearch: searchURIs, } - result := sendRequest(t, f, lsproto.CustomTextDocumentMultiDocumentHighlightInfo, params) + result := f.sendRequest(t, lsproto.CustomTextDocumentMultiDocumentHighlightInfo, params) multiHighlights := result.MultiDocumentHighlights if multiHighlights == nil { multiHighlights = &[]*lsproto.MultiDocumentHighlight{} @@ -3801,7 +3801,7 @@ func (f *FourslashTest) verifyBaselineDocumentHighlights( }, Position: f.currentCaretPosition, } - result := sendRequest(t, f, lsproto.TextDocumentDocumentHighlightInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentDocumentHighlightInfo, params) highlights := result.DocumentHighlights if highlights == nil { highlights = &[]*lsproto.DocumentHighlight{} @@ -3910,7 +3910,7 @@ func (f *FourslashTest) Paste(t *testing.T, text string) { // post-paste fomatting if f.stateEnableFormatting { - result := sendRequestAndBaselineWorker(t, f, lsproto.TextDocumentRangeFormattingInfo, &lsproto.DocumentRangeFormattingParams{ + result := f.sendRequestAndBaselineWorker(t, lsproto.TextDocumentRangeFormattingInfo, &lsproto.DocumentRangeFormattingParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, @@ -4038,7 +4038,7 @@ func (f *FourslashTest) typeText(t *testing.T, text string) { // Handle post-keystroke formatting if f.stateEnableFormatting { - result := sendRequestAndBaselineWorker(t, f, lsproto.TextDocumentOnTypeFormattingInfo, &lsproto.DocumentOnTypeFormattingParams{ + result := f.sendRequestAndBaselineWorker(t, lsproto.TextDocumentOnTypeFormattingInfo, &lsproto.DocumentOnTypeFormattingParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, @@ -4104,7 +4104,7 @@ func updatePosition(pos int, editStart int, editEnd int, newText string) int { } func (f *FourslashTest) fromLSPRange(script *scriptInfo, r lsproto.Range) core.TextRange { - ranges := lsconv.FromLSPRange(f.converters.Converters, script, r, spanmap.FeatureAll) + ranges := f.converters.Converters.FromLSPRange(script, r, spanmap.FeatureAll) if len(ranges) != 1 { return core.TextRange{} } @@ -4121,7 +4121,7 @@ func (f *FourslashTest) editScript(t *testing.T, fileName string, change core.Te if err := f.vfs.WriteFile(fileName, script.content); err != nil { t.Fatalf("failed to write to VFS for %s: %v", fileName, err) } - sendNotification(t, f, lsproto.TextDocumentDidChangeInfo, &lsproto.DidChangeTextDocumentParams{ + f.sendNotification(t, lsproto.TextDocumentDidChangeInfo, &lsproto.DidChangeTextDocumentParams{ TextDocument: lsproto.VersionedTextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(fileName), Version: script.version, @@ -4169,7 +4169,7 @@ func (f *FourslashTest) getQuickInfoAtCurrentPosition(t *testing.T) *lsproto.Hov }, Position: f.currentCaretPosition, } - result := sendRequest(t, f, lsproto.TextDocumentHoverInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentHoverInfo, params) return result.Hover } @@ -4236,7 +4236,7 @@ func (f *FourslashTest) VerifyJsxClosingTag(t *testing.T, markersToNewText map[s VSCh: ">", } - requestResult := sendRequest(t, f, lsproto.TextDocumentVSOnAutoInsertInfo, params) + requestResult := f.sendRequest(t, lsproto.TextDocumentVSOnAutoInsertInfo, params) var actualText *string if item := requestResult.VSOnAutoInsertResponseItem; item != nil && item.VSTextEdit != nil { @@ -4271,7 +4271,7 @@ func (f *FourslashTest) VerifyBaselineClosingTags(t *testing.T) { VSCh: ">", } - result := sendRequest(t, f, lsproto.TextDocumentVSOnAutoInsertInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentVSOnAutoInsertInfo, params) return markerAndItem[*lsproto.VSOnAutoInsertResponseItem]{Marker: marker, Item: result.VSOnAutoInsertResponseItem}, true }) @@ -4293,7 +4293,7 @@ func (f *FourslashTest) VerifyBaselineClosingTags(t *testing.T) { return []string{fmt.Sprintf("%s: %q", format, item.VSTextEdit.NewText)} } - result := annotateContentWithTooltips(t, f, markersAndItems, "closing tag", getRange, getTooltipLines) + result := f.annotateContentWithTooltips(t, markersAndItems, "closing tag", getRange, getTooltipLines) f.addResultToBaseline(t, closingTagCmd, result) } @@ -4332,7 +4332,7 @@ func (f *FourslashTest) VerifySignatureHelp(t *testing.T, expected VerifySignatu }, Position: f.currentCaretPosition, } - result := sendRequest(t, f, lsproto.TextDocumentSignatureHelpInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentSignatureHelpInfo, params) help := result.SignatureHelp if help == nil { t.Fatalf("%sCould not get signature help", prefix) @@ -4492,7 +4492,7 @@ func (f *FourslashTest) VerifyNoSignatureHelp(t *testing.T) { }, Position: f.currentCaretPosition, } - result := sendRequest(t, f, lsproto.TextDocumentSignatureHelpInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentSignatureHelpInfo, params) if result.SignatureHelp != nil && len(result.SignatureHelp.Signatures) > 0 { t.Errorf("%sExpected no signature help, but got %d signatures", prefix, len(result.SignatureHelp.Signatures)) } @@ -4509,7 +4509,7 @@ func (f *FourslashTest) VerifyNoSignatureHelpWithContext(t *testing.T, context * Position: f.currentCaretPosition, Context: context, } - result := sendRequest(t, f, lsproto.TextDocumentSignatureHelpInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentSignatureHelpInfo, params) if result.SignatureHelp != nil && len(result.SignatureHelp.Signatures) > 0 { t.Errorf("%sExpected no signature help, but got %d signatures", prefix, len(result.SignatureHelp.Signatures)) } @@ -4535,7 +4535,7 @@ func (f *FourslashTest) VerifySignatureHelpPresent(t *testing.T, context *lsprot Position: f.currentCaretPosition, Context: context, } - result := sendRequest(t, f, lsproto.TextDocumentSignatureHelpInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentSignatureHelpInfo, params) if result.SignatureHelp == nil || len(result.SignatureHelp.Signatures) == 0 { t.Errorf("%sExpected signature help to be present, but got none", prefix) } @@ -4607,7 +4607,7 @@ func (f *FourslashTest) verifySignatureHelp( Position: f.currentCaretPosition, Context: context, } - result := sendRequest(t, f, lsproto.TextDocumentSignatureHelpInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentSignatureHelpInfo, params) f.verifySignatureHelpResult(t, result.SignatureHelp, expected, prefix) } @@ -4650,7 +4650,7 @@ func (f *FourslashTest) BaselineAutoImportsCompletions(t *testing.T, markerNames Position: f.currentCaretPosition, Context: &lsproto.CompletionContext{}, } - result := sendRequest(t, f, lsproto.TextDocumentCompletionInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentCompletionInfo, params) prefix := fmt.Sprintf("At marker '%s': ", markerName) @@ -4689,7 +4689,7 @@ func (f *FourslashTest) BaselineAutoImportsCompletions(t *testing.T, markerNames if item.Data == nil || *item.SortText != string(ls.SortTextAutoImportSuggestions) { continue } - details := sendRequest(t, f, lsproto.CompletionItemResolveInfo, item) + details := f.sendRequest(t, lsproto.CompletionItemResolveInfo, item) if details == nil || details.AdditionalTextEdits == nil || len(*details.AdditionalTextEdits) == 0 { t.Fatalf(prefix+"Entry %s from %s returned no code changes from completion details request", item.Label, item.Detail) } @@ -4770,7 +4770,7 @@ func (f *FourslashTest) verifyBaselineRename( NewName: "?", } - result := sendRequest(t, f, lsproto.TextDocumentRenameInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentRenameInfo, params) var changes map[lsproto.DocumentUri][]*lsproto.TextEdit if result.WorkspaceEdit != nil && result.WorkspaceEdit.Changes != nil { @@ -4844,13 +4844,13 @@ func (f *FourslashTest) VerifyRenameSucceeded(t *testing.T, preferences *lsutil. } prefix := f.getCurrentPositionPrefix() - result := sendRequest(t, f, lsproto.TextDocumentPrepareRenameInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentPrepareRenameInfo, params) if result.Range == nil && result.PrepareRenamePlaceholder == nil && result.PrepareRenameDefaultBehavior == nil { t.Fatal(prefix + "Expected rename to succeed, but prepareRename returned null") } // Also verify that textDocument/rename produces edits, since prepareRename is optional. - renameResult := sendRequest(t, f, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ + renameResult := f.sendRequest(t, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, @@ -4874,7 +4874,7 @@ func (f *FourslashTest) VerifyRenameRange(t *testing.T, expectedRange lsproto.Ra Position: f.currentCaretPosition, } - result := sendRequest(t, f, lsproto.TextDocumentPrepareRenameInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentPrepareRenameInfo, params) if result.PrepareRenamePlaceholder == nil { t.Fatal(f.getCurrentPositionPrefix() + "Expected prepareRename to return a range and placeholder") } @@ -4884,7 +4884,7 @@ func (f *FourslashTest) VerifyRenameRange(t *testing.T, expectedRange lsproto.Ra func (f *FourslashTest) RenameAtCaret(t *testing.T, newName string) lsproto.RenameResponse { t.Helper() - result := sendRequest(t, f, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ + result := f.sendRequest(t, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, @@ -4956,7 +4956,7 @@ func (f *FourslashTest) RenameAtCaret(t *testing.T, newName string) lsproto.Rena func (f *FourslashTest) WillRenameFiles(t *testing.T, files ...*lsproto.FileRename) lsproto.WillRenameFilesResponse { t.Helper() - return sendRequest(t, f, lsproto.WorkspaceWillRenameFilesInfo, &lsproto.RenameFilesParams{ + return f.sendRequest(t, lsproto.WorkspaceWillRenameFilesInfo, &lsproto.RenameFilesParams{ Files: files, }) } @@ -5112,7 +5112,7 @@ func (f *FourslashTest) renameFileOrDirectory(t *testing.T, oldPath string, newP if _, isOpen := f.openFiles[oldFileName]; isOpen { script := f.scriptInfos[oldFileName] reopenAtNewPath[newFileName] = script.content - sendNotification(t, f, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ + f.sendNotification(t, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(oldFileName), }, @@ -5143,13 +5143,13 @@ func (f *FourslashTest) renameFileOrDirectory(t *testing.T, oldPath string, newP if err := f.vfs.Remove(oldPath); err != nil { t.Fatalf("failed to remove old path %s: %v", oldPath, err) } - sendNotification(t, f, lsproto.WorkspaceDidChangeWatchedFilesInfo, &lsproto.DidChangeWatchedFilesParams{ + f.sendNotification(t, lsproto.WorkspaceDidChangeWatchedFilesInfo, &lsproto.DidChangeWatchedFilesParams{ Changes: fileEvents, }) // Reopen files that were previously open at their new paths. for newFileName, content := range reopenAtNewPath { - sendNotification(t, f, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + f.sendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{ Uri: lsconv.FileNameToDocumentURI(newFileName), LanguageId: getLanguageKind(newFileName), @@ -5179,7 +5179,7 @@ func (f *FourslashTest) VerifyRenameFailed(t *testing.T, preferences *lsutil.Use prefix := f.getCurrentPositionPrefix() f.baselineState(t) f.baselineRequestOrNotification(t, lsproto.TextDocumentPrepareRenameInfo.Method, params) - resMsg, result, _ := lsptestutil.SendRequest(t, f.client, lsproto.TextDocumentPrepareRenameInfo, params) + resMsg, result, _ := f.client.SendRequest(t, lsproto.TextDocumentPrepareRenameInfo, params) f.baselineState(t) // prepareRename can reject via an error response (with a localized message) or a null result. @@ -5190,7 +5190,7 @@ func (f *FourslashTest) VerifyRenameFailed(t *testing.T, preferences *lsutil.Use } // Also verify that textDocument/rename does not produce usable edits, since prepareRename is optional. - renameMsg, renameResult, _ := lsptestutil.SendRequest(t, f.client, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ + renameMsg, renameResult, _ := f.client.SendRequest(t, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, @@ -5272,7 +5272,7 @@ func (f *FourslashTest) VerifyBaselineInlayHints( defer reset() prefix := fmt.Sprintf("At position (Ln %d, Col %d): ", lspRange.Start.Line, lspRange.Start.Character) - result := sendRequest(t, f, lsproto.TextDocumentInlayHintInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentInlayHintInfo, params) fileLines := strings.Split(f.getScriptInfo(fileName).content, "\n") var annotations []string if result.InlayHints != nil { @@ -5326,7 +5326,7 @@ func (f *FourslashTest) VerifyBaselineLinkedEditing(t *testing.T) { }, Position: f.converters.PositionToLineAndCharacter(f.getScriptInfo(file.FileName()), core.TextPos(i)), } - result := sendRequest(t, f, lsproto.TextDocumentLinkedEditingRangeInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentLinkedEditingRangeInfo, params) if result.LinkedEditingRanges != nil && len(result.LinkedEditingRanges.Ranges) > 0 && !found[result.LinkedEditingRanges.Ranges[0]] { results = append(results, result.LinkedEditingRanges) found[result.LinkedEditingRanges.Ranges[0]] = true @@ -5395,7 +5395,7 @@ func (f *FourslashTest) VerifyLinkedEditing(t *testing.T, markerNamesToExpected }, Position: f.currentCaretPosition, } - result := sendRequest(t, f, lsproto.TextDocumentLinkedEditingRangeInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentLinkedEditingRangeInfo, params) actualRanges := result.LinkedEditingRanges if len(expectedRanges) == 0 { if actualRanges != nil && len(actualRanges.Ranges) != 0 { @@ -5457,7 +5457,7 @@ func (f *FourslashTest) getDiagnostics(t *testing.T, fileName string) []*lsproto Uri: lsconv.FileNameToDocumentURI(fileName), }, } - result := sendRequest(t, f, lsproto.TextDocumentDiagnosticInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentDiagnosticInfo, params) if result.FullDocumentDiagnosticReport != nil { return result.FullDocumentDiagnosticReport.Items } @@ -5690,7 +5690,7 @@ func (f *FourslashTest) VerifyBaselineGoToImplementation(t *testing.T, markerNam Position: f.currentCaretPosition, } - return sendRequest(t, f, lsproto.TextDocumentImplementationInfo, params) + return f.sendRequest(t, lsproto.TextDocumentImplementationInfo, params) }, false, /*includeOriginalSelectionRange*/ markerNames..., @@ -5713,7 +5713,7 @@ func (f *FourslashTest) VerifyWorkspaceSymbol(t *testing.T, cases []*VerifyWorks preferences = new(lsutil.NewDefaultUserPreferences()) } f.Configure(t, *preferences) - result := sendRequest(t, f, lsproto.WorkspaceSymbolInfo, &lsproto.WorkspaceSymbolParams{ + result := f.sendRequest(t, lsproto.WorkspaceSymbolInfo, &lsproto.WorkspaceSymbolParams{ Query: testCase.Pattern, TextDocument: &lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(f.activeFilename), @@ -5781,7 +5781,7 @@ func (f *FourslashTest) VerifyBaselineDocumentSymbol(t *testing.T) { Uri: lsconv.FileNameToDocumentURI(f.activeFilename), }, } - result := sendRequest(t, f, lsproto.TextDocumentDocumentSymbolInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentDocumentSymbolInfo, params) uri := lsconv.FileNameToDocumentURI(f.activeFilename) symbolBySpan := make(map[documentSpanKey]*lsproto.DocumentSymbol) if result.DocumentSymbols != nil { diff --git a/tsc/internal/fourslash/semantictokens.go b/tsc/internal/fourslash/semantictokens.go index bba341cdc8c01..ada03d8766e8b 100644 --- a/tsc/internal/fourslash/semantictokens.go +++ b/tsc/internal/fourslash/semantictokens.go @@ -23,7 +23,7 @@ func (f *FourslashTest) VerifySemanticTokens(t *testing.T, expected []SemanticTo }, } - result := sendRequest(t, f, lsproto.TextDocumentSemanticTokensFullInfo, params) + result := f.sendRequest(t, lsproto.TextDocumentSemanticTokensFullInfo, params) if result.SemanticTokens == nil { if len(expected) == 0 { diff --git a/tsc/internal/fourslash/statebaseline.go b/tsc/internal/fourslash/statebaseline.go index c1e8a8873355a..3560b864fe7f1 100644 --- a/tsc/internal/fourslash/statebaseline.go +++ b/tsc/internal/fourslash/statebaseline.go @@ -17,7 +17,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/project" "github.com/microsoft/TypeScript/tsc/internal/testutil/fsbaselineutil" - "github.com/microsoft/TypeScript/tsc/internal/testutil/lsptestutil" "github.com/microsoft/TypeScript/tsc/internal/tspath" "github.com/microsoft/TypeScript/tsc/internal/vfs/iovfs" "gotest.tools/v3/assert" @@ -70,7 +69,7 @@ func (f *FourslashTest) baselineProjectsAfterNotification(t *testing.T, fileName return } // Do hover so we have snapshot to check things on!! - _, _, resultOk := lsptestutil.SendRequest(t, f.client, lsproto.TextDocumentHoverInfo, &lsproto.HoverParams{ + _, _, resultOk := f.client.SendRequest(t, lsproto.TextDocumentHoverInfo, &lsproto.HoverParams{ TextDocument: lsproto.TextDocumentIdentifier{ Uri: lsconv.FileNameToDocumentURI(fileName), }, diff --git a/tsc/internal/ls/autoimport/registry.go b/tsc/internal/ls/autoimport/registry.go index 2106e1b44310a..8f91b24ad6d1d 100644 --- a/tsc/internal/ls/autoimport/registry.go +++ b/tsc/internal/ls/autoimport/registry.go @@ -839,7 +839,7 @@ func (b *registryBuilder) updateIndexes(ctx context.Context, change RegistryChan // --- Collect node_modules tasks --- var nodeModulesTasks []*nodeModulesBucketTask - tspath.ForEachAncestorDirectoryPath(change.RequestedFile, func(dirPath tspath.Path) (any, bool) { + change.RequestedFile.ForEachAncestorDirectory(func(dirPath tspath.Path) (any, bool) { if nodeModulesBucket, ok := b.nodeModules.Get(dirPath); ok { dirName := core.FirstResult(b.directories.Get(dirPath)).Value().name dependencies := b.computeDependenciesForNodeModulesDirectory(change, allResolvedPackageNames, dirName, dirPath) @@ -1171,7 +1171,7 @@ func hasSymlinkToNodeModules(filePath tspath.Path, projectRootPath tspath.Path, return false } found := false - tspath.ForEachAncestorDirectoryPath(filePath, func(dirPath tspath.Path) (any, bool) { + filePath.ForEachAncestorDirectory(func(dirPath tspath.Path) (any, bool) { symlinkPaths, ok := directoriesByRealpath.Load(dirPath.EnsureTrailingDirectorySeparator()) if !ok { return nil, false @@ -1808,7 +1808,7 @@ func (b *registryBuilder) updateNodeModulesBucket( } func (b *registryBuilder) getNearestAncestorDirectoryWithPackageJson(filePath tspath.Path) *directory { - return core.FirstResult(tspath.ForEachAncestorDirectoryPath(filePath.GetDirectoryPath(), func(dirPath tspath.Path) (result *directory, stop bool) { + return core.FirstResult(filePath.GetDirectoryPath().ForEachAncestorDirectory(func(dirPath tspath.Path) (result *directory, stop bool) { if dirEntry, ok := b.directories.Get(dirPath); ok && dirEntry.Value().packageJson.Exists() { return dirEntry.Value(), true } @@ -1817,7 +1817,7 @@ func (b *registryBuilder) getNearestAncestorDirectoryWithPackageJson(filePath ts } func (b *registryBuilder) resolveAmbientModuleName(moduleName string, fromPath tspath.Path) []string { - return core.FirstResult(tspath.ForEachAncestorDirectoryPath(fromPath, func(dirPath tspath.Path) (result []string, stop bool) { + return core.FirstResult(fromPath.ForEachAncestorDirectory(func(dirPath tspath.Path) (result []string, stop bool) { if bucket, ok := b.nodeModules.Get(dirPath); ok { if fileNames, ok := bucket.Value().AmbientModuleNames[moduleName]; ok { return fileNames, true diff --git a/tsc/internal/ls/autoimport/view.go b/tsc/internal/ls/autoimport/view.go index 0e8704dd0b9e5..1962eddb2d303 100644 --- a/tsc/internal/ls/autoimport/view.go +++ b/tsc/internal/ls/autoimport/view.go @@ -123,7 +123,7 @@ func (v *View) search(searchFn func(*RegistryBucket) []*Export) []*Export { // plus packages that are directly imported by the project's program files. // If no package.json is found, allowedPackages remains nil and all packages are allowed. var allowedPackages *collections.Set[string] - tspath.ForEachAncestorDirectoryPath(v.importingFile.Path().GetDirectoryPath(), func(dirPath tspath.Path) (result any, stop bool) { + v.importingFile.Path().GetDirectoryPath().ForEachAncestorDirectory(func(dirPath tspath.Path) (result any, stop bool) { if dir, ok := v.registry.directories[dirPath]; ok { if pj := dir.packageJson; pj.Exists() && pj.Contents.Parseable { // Initialize to empty set if this is the first package.json we've seen @@ -143,7 +143,7 @@ func (v *View) search(searchFn func(*RegistryBucket) []*Export) []*Export { } excludePackages := &collections.Set[string]{} - tspath.ForEachAncestorDirectoryPath(v.importingFile.Path().GetDirectoryPath(), func(dirPath tspath.Path) (result any, stop bool) { + v.importingFile.Path().GetDirectoryPath().ForEachAncestorDirectory(func(dirPath tspath.Path) (result any, stop bool) { if nodeModulesBucket, ok := v.registry.nodeModules[dirPath]; ok { exports := searchFn(nodeModulesBucket) results = slices.Grow(results, len(exports)) diff --git a/tsc/internal/ls/autoinsert.go b/tsc/internal/ls/autoinsert.go index 862202d154391..f25ac95ef7f8c 100644 --- a/tsc/internal/ls/autoinsert.go +++ b/tsc/internal/ls/autoinsert.go @@ -5,7 +5,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/astnav" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/scanner" "github.com/microsoft/TypeScript/tsc/internal/spanmap" @@ -20,7 +19,7 @@ func (l *LanguageService) ProvideOnAutoInsert(ctx context.Context, params *lspro } _, sourceFile := l.getProgramAndFile(params.VSTextDocument.Uri) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, params.VSPosition, spanmap.FeatureAutoInsert) + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, params.VSPosition, spanmap.FeatureAutoInsert) if len(positions) != 1 || !positions[0].Fidelity.IsExact() { return lsproto.VSOnAutoInsertResponse{}, nil } diff --git a/tsc/internal/ls/callhierarchy.go b/tsc/internal/ls/callhierarchy.go index cea1d95ee8301..3ae6178d33a0b 100644 --- a/tsc/internal/ls/callhierarchy.go +++ b/tsc/internal/ls/callhierarchy.go @@ -650,8 +650,7 @@ func (l *LanguageService) getIncomingCalls(ctx context.Context, program *compile node: location, } - result, err := handleCrossProject( - l, + result, err := l.handleCrossProject( ctx, incomingEntry, orchestrator, @@ -1104,7 +1103,7 @@ func (l *LanguageService) ProvideCallHierarchyOutgoingCalls( } func (l *LanguageService) callHierarchyDeclarations(file *ast.SourceFile, position lsproto.Position, program *compiler.Program, allowSourceFile bool) []*ast.Node { - positions := lsconv.FromLSPPositionForSourceFile(l.converters, file, position, spanmap.FeatureCallHierarchy) + positions := l.converters.FromLSPPositionForSourceFile(file, position, spanmap.FeatureCallHierarchy) var declarations []*ast.Node var seen collections.Set[*ast.Node] for _, mapped := range positions { diff --git a/tsc/internal/ls/change/trackerimpl.go b/tsc/internal/ls/change/trackerimpl.go index 03479d5b11e72..c066bcc8c770c 100644 --- a/tsc/internal/ls/change/trackerimpl.go +++ b/tsc/internal/ls/change/trackerimpl.go @@ -10,7 +10,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/astnav" "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/format" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/ls/lsutil" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/parser" @@ -71,7 +70,7 @@ func (t *Tracker) computeNewText(change *trackerEdit, targetSourceFile *ast.Sour return change.NewText } - positions := lsconv.FromLSPPositionForSourceFile(t.converters, sourceFile, change.Range.Start, spanmap.FeatureAll) + positions := t.converters.FromLSPPositionForSourceFile(sourceFile, change.Range.Start, spanmap.FeatureAll) var result string found := false // The original range may have multiple verbatim copies; it is safe to lose their identity only when diff --git a/tsc/internal/ls/codeactions.go b/tsc/internal/ls/codeactions.go index 9a7443f5a7dd6..2e6f5038e5e96 100644 --- a/tsc/internal/ls/codeactions.go +++ b/tsc/internal/ls/codeactions.go @@ -118,7 +118,7 @@ func (l *LanguageService) ProvideCodeActions(ctx context.Context, params *lsprot continue } - for _, mapped := range lsconv.FromLSPRangeForSourceFile(l.converters, file, diag.Range, spanmap.FeatureCodeActions) { + for _, mapped := range l.converters.FromLSPRangeForSourceFile(file, diag.Range, spanmap.FeatureCodeActions) { fixContext := &CodeFixContext{ SourceFile: mapped.Script, Span: mapped.Span, diff --git a/tsc/internal/ls/completions.go b/tsc/internal/ls/completions.go index 2aef35353d1b1..5eac6832c376a 100644 --- a/tsc/internal/ls/completions.go +++ b/tsc/internal/ls/completions.go @@ -22,7 +22,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/locale" "github.com/microsoft/TypeScript/tsc/internal/ls/autoimport" "github.com/microsoft/TypeScript/tsc/internal/ls/change" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/ls/lsutil" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" @@ -47,7 +46,7 @@ func (l *LanguageService) ProvideCompletion( triggerCharacter = context.TriggerCharacter } ctx = format.WithFormatCodeSettings(ctx, l.FormatOptions(), l.FormatOptions().NewLineCharacter) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, file, LSPPosition, spanmap.FeatureCompletion) + positions := l.converters.FromLSPPositionForSourceFile(file, LSPPosition, spanmap.FeatureCompletion) if len(positions) == 0 || !positions[0].Fidelity.IsExact() { // In a content-mapped file the cursor is outside a verbatim span, so any completion committed here // could not be applied to the original text. Offer nothing rather than edits at a bogus location. diff --git a/tsc/internal/ls/crossproject.go b/tsc/internal/ls/crossproject.go index 6dc9b8882640a..b055730629d94 100644 --- a/tsc/internal/ls/crossproject.go +++ b/tsc/internal/ls/crossproject.go @@ -43,8 +43,7 @@ type CrossProjectOrchestrator interface { GetProjectsLoadingProjectTree(ctx context.Context, requestedProjectTrees *collections.Set[tspath.Path]) iter.Seq[Project] } -func handleCrossProject[Req lsproto.HasTextDocumentPosition, Resp any]( - defaultLs *LanguageService, +func (defaultLs *LanguageService) handleCrossProject[Req lsproto.HasTextDocumentPosition, Resp any]( ctx context.Context, params Req, orchestrator CrossProjectOrchestrator, diff --git a/tsc/internal/ls/definition.go b/tsc/internal/ls/definition.go index bb86c998257af..c1d3d4b6b63de 100644 --- a/tsc/internal/ls/definition.go +++ b/tsc/internal/ls/definition.go @@ -36,7 +36,7 @@ func (l *LanguageService) provideDefinitionWorker( clientSupportsLink := caps.TextDocument.Definition.LinkSupport program, file := l.getProgramAndFile(documentURI) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, file, position, spanmap.FeatureDefinition) + positions := l.converters.FromLSPPositionForSourceFile(file, position, spanmap.FeatureDefinition) results := make([]lsproto.DefinitionResponse, 0, len(positions)) for _, mapped := range positions { if mapped.Fidelity.IsSingleSegment() { @@ -119,7 +119,7 @@ func (l *LanguageService) ProvideTypeDefinition( clientSupportsLink := caps.TextDocument.TypeDefinition.LinkSupport program, file := l.getProgramAndFile(documentURI) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, file, position, spanmap.FeatureTypeDefinition) + positions := l.converters.FromLSPPositionForSourceFile(file, position, spanmap.FeatureTypeDefinition) results := make([]lsproto.TypeDefinitionResponse, 0, len(positions)) for _, mapped := range positions { if mapped.Fidelity.IsSingleSegment() { diff --git a/tsc/internal/ls/documenthighlights.go b/tsc/internal/ls/documenthighlights.go index b2f0bc30d16a6..ebde4a6189037 100644 --- a/tsc/internal/ls/documenthighlights.go +++ b/tsc/internal/ls/documenthighlights.go @@ -40,7 +40,7 @@ func (l *LanguageService) ProvideMultiDocumentHighlights(ctx context.Context, do func (l *LanguageService) provideDocumentHighlightsWorker(ctx context.Context, documentUri lsproto.DocumentUri, documentPosition lsproto.Position, filesToSearch []lsproto.DocumentUri) (lsproto.MultiDocumentHighlightsOrNull, error) { program, sourceFile := l.getProgramAndFile(documentUri) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, documentPosition, spanmap.FeatureDocumentHighlights) + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, documentPosition, spanmap.FeatureDocumentHighlights) results := make([]lsproto.MultiDocumentHighlightsOrNull, 0, len(positions)) for _, mapped := range positions { if mapped.Fidelity.IsSingleSegment() { diff --git a/tsc/internal/ls/findallreferences.go b/tsc/internal/ls/findallreferences.go index f893b61de8a4e..6900f93f0c1d8 100644 --- a/tsc/internal/ls/findallreferences.go +++ b/tsc/internal/ls/findallreferences.go @@ -651,7 +651,7 @@ func (l *LanguageService) provideSymbolsAndEntries(ctx context.Context, uri lspr } else if isRename { feature = spanmap.FeatureRename } - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, documentPosition, feature) + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, documentPosition, feature) if len(positions) == 0 { return SymbolAndEntriesData{}, false } @@ -746,8 +746,7 @@ func (l *LanguageService) getSymbolAndEntries( } func (l *LanguageService) ProvideReferences(ctx context.Context, params *lsproto.ReferenceParams, orchestrator CrossProjectOrchestrator) (lsproto.ReferencesResponse, error) { - return handleCrossProject( - l, + return l.handleCrossProject( ctx, params, orchestrator, @@ -761,8 +760,7 @@ func (l *LanguageService) ProvideReferences(ctx context.Context, params *lsproto } func (l *LanguageService) provideReferencesFromData(ctx context.Context, params *lsproto.ReferenceParams, orchestrator CrossProjectOrchestrator, data SymbolAndEntriesData) (lsproto.ReferencesResponse, error) { - return handleCrossProject( - l, + return l.handleCrossProject( ctx, params, orchestrator, @@ -776,8 +774,7 @@ func (l *LanguageService) provideReferencesFromData(ctx context.Context, params } func (l *LanguageService) ProvideVSReferences(ctx context.Context, params *lsproto.ReferenceParams, orchestrator CrossProjectOrchestrator) (lsproto.VSReferencesResponse, error) { - return handleCrossProject( - l, + return l.handleCrossProject( ctx, params, orchestrator, @@ -1022,8 +1019,7 @@ func (l *LanguageService) ProvideImplementations(ctx context.Context, params *ls } func (l *LanguageService) provideImplementationsEx(ctx context.Context, params *lsproto.ImplementationParams, options symbolEntryTransformOptions, orchestrator CrossProjectOrchestrator) (lsproto.ImplementationResponse, error) { - return handleCrossProject( - l, + return l.handleCrossProject( ctx, params, orchestrator, @@ -1037,8 +1033,7 @@ func (l *LanguageService) provideImplementationsEx(ctx context.Context, params * } func (l *LanguageService) provideImplementationsFromData(ctx context.Context, params *lsproto.ImplementationParams, options symbolEntryTransformOptions, orchestrator CrossProjectOrchestrator, data SymbolAndEntriesData) (lsproto.ImplementationResponse, error) { - return handleCrossProject( - l, + return l.handleCrossProject( ctx, params, orchestrator, diff --git a/tsc/internal/ls/folding.go b/tsc/internal/ls/folding.go index 4c97a768797f1..430f4f7dffcb2 100644 --- a/tsc/internal/ls/folding.go +++ b/tsc/internal/ls/folding.go @@ -88,7 +88,7 @@ func (l *LanguageService) adjustFoldingEnd(ranges []*lsproto.FoldingRange, sourc result := make([]*lsproto.FoldingRange, 0, len(ranges)) for _, r := range ranges { if r.EndCharacter != nil && *r.EndCharacter > 0 { - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, lsproto.Position{ + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, lsproto.Position{ Line: r.EndLine, Character: *r.EndCharacter, }, spanmap.FeatureFoldingRanges) diff --git a/tsc/internal/ls/format.go b/tsc/internal/ls/format.go index b9e6caf63e34b..2fc341ff7cf40 100644 --- a/tsc/internal/ls/format.go +++ b/tsc/internal/ls/format.go @@ -10,7 +10,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/astnav" "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/format" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/ls/lsutil" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/scanner" @@ -161,10 +160,10 @@ func (l *LanguageService) ProvideFormatDocumentRange( _, file := l.getProgramAndFile(documentURI) formatOpts := lsutil.FromLSFormatOptions(l.FormatOptions(), options) if file.ContentMapper() != "" { - edits := l.getFormattingEditsForMappedRange(ctx, file, formatOpts, lsconv.FromLSPRangeToOriginal(l.converters, file, r)) + edits := l.getFormattingEditsForMappedRange(ctx, file, formatOpts, l.converters.FromLSPRangeToOriginal(file, r)) return lsproto.TextEditsOrNull{TextEdits: &edits}, nil } - ranges := lsconv.FromLSPRangeForSourceFile(l.converters, file, r, spanmap.FeatureFormatting) + ranges := l.converters.FromLSPRangeForSourceFile(file, r, spanmap.FeatureFormatting) if len(ranges) != 1 || !ranges[0].Fidelity.IsExact() { return lsproto.TextEditsOrNull{}, nil } @@ -190,7 +189,7 @@ func (l *LanguageService) ProvideFormatDocumentOnType( } _, file := l.getProgramAndFile(documentURI) formatOpts := lsutil.FromLSFormatOptions(l.FormatOptions(), options) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, file, position, spanmap.FeatureFormatting) + positions := l.converters.FromLSPPositionForSourceFile(file, position, spanmap.FeatureFormatting) if len(positions) != 1 || !positions[0].Fidelity.IsExact() { return lsproto.TextEditsOrNull{}, nil } diff --git a/tsc/internal/ls/hover.go b/tsc/internal/ls/hover.go index c29957914f8c7..c6a351addd8a4 100644 --- a/tsc/internal/ls/hover.go +++ b/tsc/internal/ls/hover.go @@ -11,7 +11,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/checker" "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/ls/lsutil" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" @@ -35,7 +34,7 @@ func (l *LanguageService) ProvideHover(ctx context.Context, params *lsproto.Hove } program, file := l.getProgramAndFile(params.TextDocument.Uri) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, file, params.Position, spanmap.FeatureHover) + positions := l.converters.FromLSPPositionForSourceFile(file, params.Position, spanmap.FeatureHover) var hovers []*lsproto.Hover for _, projection := range positions { if !projection.Fidelity.IsSingleSegment() { diff --git a/tsc/internal/ls/inlay_hints.go b/tsc/internal/ls/inlay_hints.go index d99ff361a39c3..0864f8df361e7 100644 --- a/tsc/internal/ls/inlay_hints.go +++ b/tsc/internal/ls/inlay_hints.go @@ -35,7 +35,7 @@ func (l *LanguageService) ProvideInlayHint( program, file := l.getProgramAndFile(params.TextDocument.Uri) quotePreference := lsutil.GetQuotePreference(file, userPreferences) - mappedRanges := lsconv.FromLSPRangeIntersectingForSourceFile(l.converters, file, params.Range, spanmap.FeatureInlayHints) + mappedRanges := l.converters.FromLSPRangeIntersectingForSourceFile(file, params.Range, spanmap.FeatureInlayHints) result := make([]*lsproto.InlayHint, 0, len(mappedRanges)) for _, mapped := range mappedRanges { projection := mapped.Script diff --git a/tsc/internal/ls/linkedediting.go b/tsc/internal/ls/linkedediting.go index 8652e10c336e2..4aba5d388f862 100644 --- a/tsc/internal/ls/linkedediting.go +++ b/tsc/internal/ls/linkedediting.go @@ -7,7 +7,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/astnav" "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/debug" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/scanner" "github.com/microsoft/TypeScript/tsc/internal/spanmap" @@ -18,7 +17,7 @@ var jsxTagWordPattern = new("[a-zA-Z0-9:\\-\\._$]*") func (l *LanguageService) ProvideLinkedEditingRange(ctx context.Context, params *lsproto.LinkedEditingRangeParams) (lsproto.LinkedEditingRangeResponse, error) { _, sourceFile := l.getProgramAndFile(params.TextDocument.Uri) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, params.Position, spanmap.FeatureLinkedEditing) + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, params.Position, spanmap.FeatureLinkedEditing) if len(positions) != 1 || !positions[0].Fidelity.IsExact() { return lsproto.LinkedEditingRangeResponse{}, nil } diff --git a/tsc/internal/ls/lsconv/converters.go b/tsc/internal/ls/lsconv/converters.go index bdb724f7667a4..5f2d7c97dec9b 100644 --- a/tsc/internal/ls/lsconv/converters.go +++ b/tsc/internal/ls/lsconv/converters.go @@ -124,16 +124,16 @@ func (c *Converters) ToLSPLocationForFeature(script Script, rng core.TextRange, // FromLSPRange converts an lsproto.Range to offsets in one Script. For a content-mapped script, results // include each virtual projection covered by segments that participate in feature; it returns no // results when no projection qualifies. Normal scripts return one exact span. -func FromLSPRange[T Script](c *Converters, script T, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[T] { - return lspRangeToVirtual(c, []T{script}, textRange, feature) +func (c *Converters) FromLSPRange[T Script](script T, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[T] { + return c.lspRangeToVirtualForScripts([]T{script}, textRange, feature) } // FromLSPRangeForSourceFile converts an lsproto.Range to offsets in a SourceFile. When the file has // supplemental content-mapper outputs, results include every qualifying virtual projection across the // canonical and supplemental files. Projections not participating in feature are omitted. -func FromLSPRangeForSourceFile(c *Converters, file *ast.SourceFile, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[*ast.SourceFile] { +func (c *Converters) FromLSPRangeForSourceFile(file *ast.SourceFile, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[*ast.SourceFile] { files := sourceFileProjections(file) - return lspRangeToVirtual(c, files, textRange, feature) + return c.lspRangeToVirtualForScripts(files, textRange, feature) } // FromLSPRangeIntersectingForSourceFile projects every feature-enabled intersection with textRange @@ -146,7 +146,7 @@ func FromLSPRangeForSourceFile(c *Converters, file *ast.SourceFile, textRange ls // [----------) mapped script // // The result contains the script intersection even though both viewport endpoints are outside it. -func FromLSPRangeIntersectingForSourceFile(c *Converters, file *ast.SourceFile, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[*ast.SourceFile] { +func (c *Converters) FromLSPRangeIntersectingForSourceFile(file *ast.SourceFile, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[*ast.SourceFile] { files := sourceFileProjections(file) result := make([]MappedSpan[*ast.SourceFile], 0, len(files)) for _, script := range files { @@ -174,7 +174,7 @@ func FromLSPRangeIntersectingForSourceFile(c *Converters, file *ast.SourceFile, return result } -func lspRangeToVirtual[T Script](c *Converters, scripts []T, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[T] { +func (c *Converters) lspRangeToVirtualForScripts[T Script](scripts []T, textRange lsproto.Range, feature spanmap.Feature) []MappedSpan[T] { result := make([]MappedSpan[T], 0, len(scripts)) for _, script := range scripts { for _, mapped := range c.lspRangeToVirtual(script, textRange, feature) { @@ -208,20 +208,20 @@ func (c *Converters) lspRangeToVirtual(script Script, textRange lsproto.Range, f // FromLSPPosition converts an lsproto.Position to offsets in one Script. For a content-mapped script, // results include each virtual projection whose segment participates in feature; it returns no results // when no projection qualifies. Normal scripts return one exact position. -func FromLSPPosition[T Script](c *Converters, script T, position lsproto.Position, feature spanmap.Feature) []MappedPosition[T] { - return lspPositionToVirtual(c, []T{script}, position, feature) +func (c *Converters) FromLSPPosition[T Script](script T, position lsproto.Position, feature spanmap.Feature) []MappedPosition[T] { + return c.lspPositionToVirtualForScripts([]T{script}, position, feature) } // FromLSPPositionForSourceFile converts an lsproto.Position to offsets in a SourceFile. When the file has // supplemental content-mapper outputs, results include every qualifying virtual projection across the // canonical and supplemental files. Projections not participating in feature are omitted. -func FromLSPPositionForSourceFile(c *Converters, file *ast.SourceFile, position lsproto.Position, feature spanmap.Feature) []MappedPosition[*ast.SourceFile] { +func (c *Converters) FromLSPPositionForSourceFile(file *ast.SourceFile, position lsproto.Position, feature spanmap.Feature) []MappedPosition[*ast.SourceFile] { files := sourceFileProjections(file) - return lspPositionToVirtual(c, files, position, feature) + return c.lspPositionToVirtualForScripts(files, position, feature) } // FromLSPRangeToOriginal converts an LSP range in a content-mapped document directly to original-text offsets. -func FromLSPRangeToOriginal(c *Converters, script Script, textRange lsproto.Range) core.TextRange { +func (c *Converters) FromLSPRangeToOriginal(script Script, textRange lsproto.Range) core.TextRange { original := originalTextScript{fileName: script.OriginalFileName(), text: script.OriginalText()} return core.NewTextRange( int(c.lineAndCharacterToPosition(original, textRange.Start)), @@ -236,7 +236,7 @@ func sourceFileProjections(file *ast.SourceFile) []*ast.SourceFile { return append(files, supplemental...) } -func lspPositionToVirtual[T Script](c *Converters, scripts []T, position lsproto.Position, feature spanmap.Feature) []MappedPosition[T] { +func (c *Converters) lspPositionToVirtualForScripts[T Script](scripts []T, position lsproto.Position, feature spanmap.Feature) []MappedPosition[T] { result := make([]MappedPosition[T], 0, len(scripts)) for _, script := range scripts { for _, mapped := range c.lspPositionToVirtual(script, position, feature) { diff --git a/tsc/internal/ls/lsconv/converters_test.go b/tsc/internal/ls/lsconv/converters_test.go index cccdd24b597ae..9fa81b4a4109c 100644 --- a/tsc/internal/ls/lsconv/converters_test.go +++ b/tsc/internal/ls/lsconv/converters_test.go @@ -141,7 +141,7 @@ func TestConvertersSourceFileProjectionExpansion(t *testing.T) { lineMap := lsconv.ComputeLSPLineStarts(original) converters := lsconv.NewConverters(lsproto.PositionEncodingKindUTF16, func(_ string) *lsconv.LSPLineMap { return lineMap }) - positions := lsconv.FromLSPPositionForSourceFile(converters, canonical, lsproto.Position{}, spanmap.FeatureHover) + positions := converters.FromLSPPositionForSourceFile(canonical, lsproto.Position{}, spanmap.FeatureHover) assert.Equal(t, len(positions), 2) var projectedFile *ast.SourceFile = positions[0].Script assert.Assert(t, projectedFile == canonical) @@ -180,7 +180,7 @@ func TestConvertersInvalidUTF8(t *testing.T) { } for _, m := range mappings { lc := lsproto.Position{Line: m.line, Character: m.char} - positions := lsconv.FromLSPPosition(conv, script, lc, spanmap.FeatureAll) + positions := conv.FromLSPPosition(script, lc, spanmap.FeatureAll) assert.Equal(t, len(positions), 1) assert.Equal(t, positions[0].Position, m.bytePos, fmt.Sprintf("LineAndCharacterToPosition(%d,%d)", m.line, m.char)) @@ -192,7 +192,7 @@ func TestConvertersInvalidUTF8(t *testing.T) { // Byte-by-byte round-trip across the entire text. for bytePos := core.TextPos(0); bytePos <= core.TextPos(len(text)); bytePos++ { lc, _ := conv.ToLSPPosition(script, bytePos) - positions := lsconv.FromLSPPosition(conv, script, lc, spanmap.FeatureAll) + positions := conv.FromLSPPosition(script, lc, spanmap.FeatureAll) assert.Equal(t, len(positions), 1) assert.Equal(t, positions[0].Position, bytePos, fmt.Sprintf("round-trip byte %d", bytePos)) } @@ -370,7 +370,7 @@ func TestConvertersAgainstJSReference(t *testing.T) { assert.Equal(t, gotLC, expectedLC, fmt.Sprintf("PositionToLineAndCharacter(%d) mismatch in %q", bytePos, c.text)) - positions := lsconv.FromLSPPosition(conv, script, expectedLC, spanmap.FeatureAll) + positions := conv.FromLSPPosition(script, expectedLC, spanmap.FeatureAll) assert.Equal(t, len(positions), 1) assert.Equal(t, positions[0].Position, bytePos, fmt.Sprintf("LineAndCharacterToPosition(%d,%d) mismatch in %q", tup.Line, tup.Char, c.text)) diff --git a/tsc/internal/ls/rename.go b/tsc/internal/ls/rename.go index 2ddefa4810348..9aa51be791e34 100644 --- a/tsc/internal/ls/rename.go +++ b/tsc/internal/ls/rename.go @@ -63,8 +63,7 @@ func deduplicateRenameEdits(mappedEdits []mappedRenameEdit) (map[lsproto.Documen } func (l *LanguageService) ProvideRename(ctx context.Context, params *lsproto.RenameParams, orchestrator CrossProjectOrchestrator) (lsproto.WorkspaceEditOrNull, error) { - return handleCrossProject( - l, + return l.handleCrossProject( ctx, params, orchestrator, @@ -79,7 +78,7 @@ func (l *LanguageService) ProvideRename(ctx context.Context, params *lsproto.Ren func (l *LanguageService) GetRenameInfo(ctx context.Context, newName string, documentURI lsproto.DocumentUri, position lsproto.Position) RenameInfo { program, sourceFile := l.getProgramAndFile(documentURI) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, position, spanmap.FeatureRename) + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, position, spanmap.FeatureRename) for _, mapped := range positions { if !mapped.Fidelity.IsExact() { continue diff --git a/tsc/internal/ls/selectionranges.go b/tsc/internal/ls/selectionranges.go index cc96a867ce5bd..a8468baa9221b 100644 --- a/tsc/internal/ls/selectionranges.go +++ b/tsc/internal/ls/selectionranges.go @@ -6,7 +6,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/ast" "github.com/microsoft/TypeScript/tsc/internal/astnav" "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/scanner" "github.com/microsoft/TypeScript/tsc/internal/spanmap" @@ -54,7 +53,7 @@ func (l *LanguageService) ProvideSelectionRanges(ctx context.Context, params *ls results := make([]*lsproto.SelectionRange, 0, len(params.Positions)) for _, position := range params.Positions { - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, position, spanmap.FeatureSelectionRanges) + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, position, spanmap.FeatureSelectionRanges) if len(positions) != 1 || !positions[0].Fidelity.IsSingleSegment() { return lsproto.SelectionRangesOrNull{}, nil } diff --git a/tsc/internal/ls/semantictokens.go b/tsc/internal/ls/semantictokens.go index 6bdde51032475..4213c9016bc5d 100644 --- a/tsc/internal/ls/semantictokens.go +++ b/tsc/internal/ls/semantictokens.go @@ -160,7 +160,7 @@ func (l *LanguageService) ProvideSemanticTokens(ctx context.Context, documentURI func (l *LanguageService) ProvideSemanticTokensRange(ctx context.Context, documentURI lsproto.DocumentUri, rng lsproto.Range) (lsproto.SemanticTokensRangeResponse, error) { program, file := l.getProgramAndFile(documentURI) - mappedRanges := lsconv.FromLSPRangeIntersectingForSourceFile(l.converters, file, rng, spanmap.FeatureSemanticTokens) + mappedRanges := l.converters.FromLSPRangeIntersectingForSourceFile(file, rng, spanmap.FeatureSemanticTokens) tokens := make([]semanticToken, 0, len(mappedRanges)) var seen collections.Set[semanticToken] for _, mapped := range mappedRanges { diff --git a/tsc/internal/ls/signaturehelp.go b/tsc/internal/ls/signaturehelp.go index 25495583a9612..78aa78490d4b8 100644 --- a/tsc/internal/ls/signaturehelp.go +++ b/tsc/internal/ls/signaturehelp.go @@ -11,7 +11,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/compiler" "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/debug" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/nodebuilder" "github.com/microsoft/TypeScript/tsc/internal/printer" @@ -54,7 +53,7 @@ func (l *LanguageService) ProvideSignatureHelp( context *lsproto.SignatureHelpContext, ) (lsproto.SignatureHelpResponse, error) { program, sourceFile := l.getProgramAndFile(documentURI) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, sourceFile, position, spanmap.FeatureSignatureHelp) + positions := l.converters.FromLSPPositionForSourceFile(sourceFile, position, spanmap.FeatureSignatureHelp) for _, projection := range positions { if !projection.Fidelity.IsSingleSegment() { continue diff --git a/tsc/internal/ls/sourcedefinition.go b/tsc/internal/ls/sourcedefinition.go index ceb4e5d9fad64..bea42cddfe45a 100644 --- a/tsc/internal/ls/sourcedefinition.go +++ b/tsc/internal/ls/sourcedefinition.go @@ -13,7 +13,6 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/collections" "github.com/microsoft/TypeScript/tsc/internal/compiler" "github.com/microsoft/TypeScript/tsc/internal/core" - "github.com/microsoft/TypeScript/tsc/internal/ls/lsconv" "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/module" "github.com/microsoft/TypeScript/tsc/internal/modulespecifiers" @@ -29,7 +28,7 @@ func (l *LanguageService) ProvideSourceDefinition( position lsproto.Position, ) (lsproto.DefinitionResponse, error) { program, file := l.getProgramAndFile(documentURI) - positions := lsconv.FromLSPPositionForSourceFile(l.converters, file, position, spanmap.FeatureDefinition) + positions := l.converters.FromLSPPositionForSourceFile(file, position, spanmap.FeatureDefinition) results := make([]lsproto.DefinitionResponse, 0, len(positions)) for _, mapped := range positions { if mapped.Fidelity.IsSingleSegment() { diff --git a/tsc/internal/lsp/lsproto/lsp.go b/tsc/internal/lsp/lsproto/lsp.go index ae6c15b589ba1..0541db5df7415 100644 --- a/tsc/internal/lsp/lsproto/lsp.go +++ b/tsc/internal/lsp/lsproto/lsp.go @@ -232,13 +232,13 @@ func (info NotificationInfo[Params]) NewNotificationMessage(params Params) *Requ // // A [NoParams] method must be given no params; every other method must be given // params as an object or array. A violation returns [ErrorCodeInvalidParams]. -func UnmarshalParams[T any](req *RequestMessage) (T, error) { +func (r *RequestMessage) UnmarshalParams[T any]() (T, error) { var params T var raw json.Value - if req.Params != nil { - v, ok := req.Params.(json.Value) + if r.Params != nil { + v, ok := r.Params.(json.Value) if !ok { - return params, fmt.Errorf("%w: unexpected params type %T", ErrorCodeInvalidParams, req.Params) + return params, fmt.Errorf("%w: unexpected params type %T", ErrorCodeInvalidParams, r.Params) } raw = v } diff --git a/tsc/internal/lsp/lsproto/lsp_json_test.go b/tsc/internal/lsp/lsproto/lsp_json_test.go index 3f88840c0b43e..86f448c21d68a 100644 --- a/tsc/internal/lsp/lsproto/lsp_json_test.go +++ b/tsc/internal/lsp/lsproto/lsp_json_test.go @@ -998,7 +998,7 @@ func TestUnmarshalParamsRequiresParams(t *testing.T) { for _, tt := range noParamsTests { t.Run("NoParams/"+tt.name, func(t *testing.T) { t.Parallel() - _, err := UnmarshalParams[NoParams](&RequestMessage{Params: tt.params}) + _, err := (&RequestMessage{Params: tt.params}).UnmarshalParams[NoParams]() if tt.wantErr { assert.ErrorIs(t, err, ErrorCodeInvalidParams) } else { @@ -1024,7 +1024,7 @@ func TestUnmarshalParamsRequiresParams(t *testing.T) { for _, tt := range typedTests { t.Run("typed/"+tt.name, func(t *testing.T) { t.Parallel() - got, err := UnmarshalParams[*DidChangeConfigurationParams](&RequestMessage{Params: tt.params}) + got, err := (&RequestMessage{Params: tt.params}).UnmarshalParams[*DidChangeConfigurationParams]() if tt.wantErr { assert.ErrorIs(t, err, ErrorCodeInvalidParams) } else { diff --git a/tsc/internal/lsp/progress.go b/tsc/internal/lsp/progress.go index d9ca6a2dd25cf..648a0f6a9a574 100644 --- a/tsc/internal/lsp/progress.go +++ b/tsc/internal/lsp/progress.go @@ -44,13 +44,13 @@ func (r *serverProgressReporter) localize(msg *diagnostics.Message, args ...any) } func (r *serverProgressReporter) createWorkDoneProgress(token string) { - _ = sendClientRequestFireAndForget(r.server, lsproto.WindowWorkDoneProgressCreateInfo, &lsproto.WorkDoneProgressCreateParams{ + _ = r.server.sendClientRequestFireAndForget(lsproto.WindowWorkDoneProgressCreateInfo, &lsproto.WorkDoneProgressCreateParams{ Token: lsproto.IntegerOrString{String: &token}, }) } func (r *serverProgressReporter) sendProgress(token string, value lsproto.WorkDoneProgressBeginOrReportOrEnd) { - _ = sendNotification(r.server, lsproto.ProgressInfo, &lsproto.ProgressParams{ + _ = r.server.sendNotification(lsproto.ProgressInfo, &lsproto.ProgressParams{ Token: lsproto.IntegerOrString{String: &token}, Value: value, }) diff --git a/tsc/internal/lsp/server.go b/tsc/internal/lsp/server.go index 928f6e516c02d..33ff45e68d410 100644 --- a/tsc/internal/lsp/server.go +++ b/tsc/internal/lsp/server.go @@ -268,7 +268,7 @@ func (s *Server) WatchFiles(ctx context.Context, id project.WatcherID, watchers s.watchers.Add(id) return nil } - _, err := sendClientRequest(ctx, s, lsproto.ClientRegisterCapabilityInfo, &lsproto.RegistrationParams{ + _, err := s.sendClientRequest(ctx, lsproto.ClientRegisterCapabilityInfo, &lsproto.RegistrationParams{ Registrations: []*lsproto.Registration{ { Id: string(id), @@ -301,7 +301,7 @@ func (s *Server) UnwatchFiles(ctx context.Context, id project.WatcherID) error { return nil } if s.watchers.Has(id) { - _, err := sendClientRequest(ctx, s, lsproto.ClientUnregisterCapabilityInfo, &lsproto.UnregistrationParams{ + _, err := s.sendClientRequest(ctx, lsproto.ClientUnregisterCapabilityInfo, &lsproto.UnregistrationParams{ Unregisterations: []*lsproto.Unregistration{ { Id: string(id), @@ -449,7 +449,7 @@ func (s *Server) RegisterContentMapperExtensions(ctx context.Context, extensions unregistrations = slices.DeleteFunc(unregistrations, func(registration *lsproto.Unregistration) bool { return !s.supportsContentMapperRegistration(registration.Id) }) - if _, err := sendClientRequest(ctx, s, lsproto.ClientUnregisterCapabilityInfo, &lsproto.UnregistrationParams{ + if _, err := s.sendClientRequest(ctx, lsproto.ClientUnregisterCapabilityInfo, &lsproto.UnregistrationParams{ Unregisterations: unregistrations, }); err != nil { return fmt.Errorf("failed to unregister content mapper text document sync: %w", err) @@ -687,7 +687,7 @@ func (s *Server) RegisterContentMapperExtensions(ctx context.Context, extensions registrations = slices.DeleteFunc(registrations, func(registration *lsproto.Registration) bool { return !s.supportsContentMapperRegistration(registration.Id) }) - if _, err := sendClientRequest(ctx, s, lsproto.ClientRegisterCapabilityInfo, &lsproto.RegistrationParams{ + if _, err := s.sendClientRequest(ctx, lsproto.ClientRegisterCapabilityInfo, &lsproto.RegistrationParams{ Registrations: registrations, }); err != nil { return fmt.Errorf("failed to register content mapper text document sync: %w", err) @@ -710,7 +710,7 @@ func (s *Server) RefreshDiagnostics(ctx context.Context) error { // Fire-and-forget: the client always returns null, and waiting for the response // can cause the server to hang if the client is slow or unresponsive. // Any response from the client will be silently ignored by the read loop. - if err := sendClientRequestFireAndForget(s, lsproto.WorkspaceDiagnosticRefreshInfo, lsproto.NoParams{}); err != nil { + if err := s.sendClientRequestFireAndForget(lsproto.WorkspaceDiagnosticRefreshInfo, lsproto.NoParams{}); err != nil { return fmt.Errorf("failed to refresh diagnostics: %w", err) } @@ -719,7 +719,7 @@ func (s *Server) RefreshDiagnostics(ctx context.Context) error { // PublishDiagnostics implements project.Client. func (s *Server) PublishDiagnostics(ctx context.Context, params *lsproto.PublishDiagnosticsParams) error { - return sendNotification(s, lsproto.TextDocumentPublishDiagnosticsInfo, params) + return s.sendNotification(lsproto.TextDocumentPublishDiagnosticsInfo, params) } // SendTelemetry implements project.Client. @@ -727,7 +727,7 @@ func (s *Server) SendTelemetry(ctx context.Context, telemetry lsproto.TelemetryE if !s.telemetryEnabled { panic("SendTelemetry called with telemetry disabled") } - return sendNotification(s, lsproto.TelemetryEventInfo, telemetry) + return s.sendNotification(lsproto.TelemetryEventInfo, telemetry) } // IsActive implements project.Client. @@ -741,7 +741,7 @@ func (s *Server) RefreshInlayHints(ctx context.Context) error { return nil } - if err := sendClientRequestFireAndForget(s, lsproto.WorkspaceInlayHintRefreshInfo, lsproto.NoParams{}); err != nil { + if err := s.sendClientRequestFireAndForget(lsproto.WorkspaceInlayHintRefreshInfo, lsproto.NoParams{}); err != nil { return fmt.Errorf("failed to refresh inlay hints: %w", err) } return nil @@ -752,7 +752,7 @@ func (s *Server) RefreshCodeLens(ctx context.Context) error { return nil } - if err := sendClientRequestFireAndForget(s, lsproto.WorkspaceCodeLensRefreshInfo, lsproto.NoParams{}); err != nil { + if err := s.sendClientRequestFireAndForget(lsproto.WorkspaceCodeLensRefreshInfo, lsproto.NoParams{}); err != nil { return fmt.Errorf("failed to refresh code lens: %w", err) } return nil @@ -810,7 +810,7 @@ func (s *Server) RequestConfiguration(ctx context.Context) (lsutil.UserPreferenc } return lsutil.NewDefaultUserPreferences(), nil } - configs, err := sendClientRequest(ctx, s, lsproto.WorkspaceConfigurationInfo, &lsproto.ConfigurationParams{ + configs, err := s.sendClientRequest(ctx, lsproto.WorkspaceConfigurationInfo, &lsproto.ConfigurationParams{ Items: []*lsproto.ConfigurationItem{ { Section: new("js/ts"), @@ -901,7 +901,7 @@ func (s *Server) readLoop(ctx context.Context) error { if s.initializeParams == nil && msg.Kind == jsonrpc.MessageKindRequest { req := msg.AsRequest() if req.Method == lsproto.MethodInitialize { - params, err := lsproto.UnmarshalParams[*lsproto.InitializeParams](req) + params, err := req.UnmarshalParams[*lsproto.InitializeParams]() if err != nil { if err := s.sendError(req.ID, err); err != nil { return err @@ -935,7 +935,7 @@ func (s *Server) readLoop(ctx context.Context) error { } else { req := msg.AsRequest() if req.Method == lsproto.MethodCancelRequest { - if params, err := lsproto.UnmarshalParams[*lsproto.CancelParams](req); err == nil && params != nil { + if params, err := req.UnmarshalParams[*lsproto.CancelParams](); err == nil && params != nil { s.cancelRequest(params.Id) } } else { @@ -1046,7 +1046,7 @@ func (s *Server) writeLoop(ctx context.Context) error { // WARNING: this should only be called in the async portion of a request handler, // otherwise a deadlock can occur. -func sendClientRequest[Req, Resp any](ctx context.Context, s *Server, info lsproto.RequestInfo[Req, Resp], params Req) (Resp, error) { +func (s *Server) sendClientRequest[Req, Resp any](ctx context.Context, info lsproto.RequestInfo[Req, Resp], params Req) (Resp, error) { id := jsonrpc.NewIDString(fmt.Sprintf("ts%d", s.clientSeq.Add(1))) req := info.NewRequestMessage(id, params) @@ -1083,7 +1083,7 @@ func sendClientRequest[Req, Resp any](ctx context.Context, s *Server, info lspro // The response, if any, will be silently ignored by the read loop since no pending channel is registered. // This means any error returned by the client will not be observed. Use only for requests where the // response value is not needed (e.g., the client always returns null). -func sendClientRequestFireAndForget[Req, Resp any](s *Server, info lsproto.RequestInfo[Req, Resp], params Req) error { +func (s *Server) sendClientRequestFireAndForget[Req, Resp any](info lsproto.RequestInfo[Req, Resp], params Req) error { id := jsonrpc.NewIDString(fmt.Sprintf("ts%d", s.clientSeq.Add(1))) req := info.NewRequestMessage(id, params) return s.send(req.Message()) @@ -1122,7 +1122,7 @@ func (s *Server) sendError(id *jsonrpc.ID, err error) error { }) } -func sendNotification[Params any](s *Server, info lsproto.NotificationInfo[Params], params Params) error { +func (s *Server) sendNotification[Params any](info lsproto.NotificationInfo[Params], params Params) error { return s.send(info.NewNotificationMessage(params).Message()) } @@ -1225,81 +1225,81 @@ type handlerMap map[lsproto.Method]func(*Server, context.Context, *lsproto.Reque var handlers = sync.OnceValue(func() handlerMap { handlers := make(handlerMap) - registerRequestHandler(handlers, lsproto.InitializeInfo, (*Server).handleInitialize) - registerNotificationHandler(handlers, lsproto.InitializedInfo, (*Server).handleInitialized) - registerRequestHandler(handlers, lsproto.ShutdownInfo, (*Server).handleShutdown) - registerNotificationHandler(handlers, lsproto.ExitInfo, (*Server).handleExit) - - registerNotificationHandler(handlers, lsproto.WorkspaceDidChangeConfigurationInfo, (*Server).handleDidChangeWorkspaceConfiguration) - registerNotificationHandler(handlers, lsproto.TextDocumentDidOpenInfo, (*Server).handleDidOpen) - registerNotificationHandler(handlers, lsproto.TextDocumentDidChangeInfo, (*Server).handleDidChange) - registerNotificationHandler(handlers, lsproto.TextDocumentDidSaveInfo, (*Server).handleDidSave) - registerNotificationHandler(handlers, lsproto.TextDocumentDidCloseInfo, (*Server).handleDidClose) - registerNotificationHandler(handlers, lsproto.WorkspaceDidChangeWatchedFilesInfo, (*Server).handleDidChangeWatchedFiles) - registerNotificationHandler(handlers, lsproto.SetTraceInfo, (*Server).handleSetTrace) - registerNotificationHandler(handlers, lsproto.CustomSetLogVerbosityInfo, (*Server).handleSetLogVerbosity) - registerRequestHandler(handlers, lsproto.WorkspaceWillRenameFilesInfo, (*Server).handleWillRenameFiles) - - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDiagnosticInfo, (*Server).handleDocumentDiagnostic) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentHoverInfo, (*Server).handleHover) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDefinitionInfo, (*Server).handleDefinition) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.CustomTextDocumentSourceDefinitionInfo, (*Server).handleSourceDefinition) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentTypeDefinitionInfo, (*Server).handleTypeDefinition) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSignatureHelpInfo, (*Server).handleSignatureHelp) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentFormattingInfo, (*Server).handleDocumentFormat) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentRangeFormattingInfo, (*Server).handleDocumentRangeFormat) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentOnTypeFormattingInfo, (*Server).handleDocumentOnTypeFormat) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentSymbolInfo, (*Server).handleDocumentSymbol) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentHighlightInfo, (*Server).handleDocumentHighlight) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.CustomTextDocumentMultiDocumentHighlightInfo, (*Server).handleMultiDocumentHighlight) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSelectionRangeInfo, (*Server).handleSelectionRange) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentInlayHintInfo, (*Server).handleInlayHint) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentCodeLensInfo, (*Server).handleCodeLens) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentCodeActionInfo, (*Server).handleCodeAction) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentPrepareCallHierarchyInfo, (*Server).handlePrepareCallHierarchy) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentFoldingRangeInfo, (*Server).handleFoldingRange) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentPrepareRenameInfo, (*Server).handlePrepareRename) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentLinkedEditingRangeInfo, (*Server).handleLinkedEditingRange) - - registerLanguageServiceWithAutoImportsRequestHandler(handlers, lsproto.TextDocumentCompletionInfo, (*Server).handleCompletion) - registerLanguageServiceWithAutoImportsRequestHandler(handlers, lsproto.TextDocumentCodeActionInfo, (*Server).handleCodeAction) - - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentVSOnAutoInsertInfo, (*Server).handleVSOnAutoInsert) - - registerMultiProjectReferenceRequestHandler(handlers, lsproto.TextDocumentReferencesInfo, (*ls.LanguageService).ProvideReferences) - registerMultiProjectReferenceRequestHandler(handlers, lsproto.TextDocumentVSReferencesInfo, (*ls.LanguageService).ProvideVSReferences) - registerRequestHandler(handlers, lsproto.TextDocumentRenameInfo, (*Server).handleRename) - registerMultiProjectReferenceRequestHandler(handlers, lsproto.TextDocumentImplementationInfo, (*ls.LanguageService).ProvideImplementations) - - registerRequestHandler(handlers, lsproto.CallHierarchyIncomingCallsInfo, (*Server).handleCallHierarchyIncomingCalls) - registerRequestHandler(handlers, lsproto.CallHierarchyOutgoingCallsInfo, (*Server).handleCallHierarchyOutgoingCalls) - - registerRequestHandler(handlers, lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol) - registerRequestHandler(handlers, lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve) - registerRequestHandler(handlers, lsproto.CodeLensResolveInfo, (*Server).handleCodeLensResolve) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSemanticTokensFullInfo, (*Server).handleSemanticTokensFull) - registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSemanticTokensRangeInfo, (*Server).handleSemanticTokensRange) + handlers.registerRequestHandler(lsproto.InitializeInfo, (*Server).handleInitialize) + handlers.registerNotificationHandler(lsproto.InitializedInfo, (*Server).handleInitialized) + handlers.registerRequestHandler(lsproto.ShutdownInfo, (*Server).handleShutdown) + handlers.registerNotificationHandler(lsproto.ExitInfo, (*Server).handleExit) + + handlers.registerNotificationHandler(lsproto.WorkspaceDidChangeConfigurationInfo, (*Server).handleDidChangeWorkspaceConfiguration) + handlers.registerNotificationHandler(lsproto.TextDocumentDidOpenInfo, (*Server).handleDidOpen) + handlers.registerNotificationHandler(lsproto.TextDocumentDidChangeInfo, (*Server).handleDidChange) + handlers.registerNotificationHandler(lsproto.TextDocumentDidSaveInfo, (*Server).handleDidSave) + handlers.registerNotificationHandler(lsproto.TextDocumentDidCloseInfo, (*Server).handleDidClose) + handlers.registerNotificationHandler(lsproto.WorkspaceDidChangeWatchedFilesInfo, (*Server).handleDidChangeWatchedFiles) + handlers.registerNotificationHandler(lsproto.SetTraceInfo, (*Server).handleSetTrace) + handlers.registerNotificationHandler(lsproto.CustomSetLogVerbosityInfo, (*Server).handleSetLogVerbosity) + handlers.registerRequestHandler(lsproto.WorkspaceWillRenameFilesInfo, (*Server).handleWillRenameFiles) + + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentDiagnosticInfo, (*Server).handleDocumentDiagnostic) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentHoverInfo, (*Server).handleHover) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentDefinitionInfo, (*Server).handleDefinition) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.CustomTextDocumentSourceDefinitionInfo, (*Server).handleSourceDefinition) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentTypeDefinitionInfo, (*Server).handleTypeDefinition) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentSignatureHelpInfo, (*Server).handleSignatureHelp) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentFormattingInfo, (*Server).handleDocumentFormat) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentRangeFormattingInfo, (*Server).handleDocumentRangeFormat) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentOnTypeFormattingInfo, (*Server).handleDocumentOnTypeFormat) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentDocumentSymbolInfo, (*Server).handleDocumentSymbol) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentDocumentHighlightInfo, (*Server).handleDocumentHighlight) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.CustomTextDocumentMultiDocumentHighlightInfo, (*Server).handleMultiDocumentHighlight) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentSelectionRangeInfo, (*Server).handleSelectionRange) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentInlayHintInfo, (*Server).handleInlayHint) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentCodeLensInfo, (*Server).handleCodeLens) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentCodeActionInfo, (*Server).handleCodeAction) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentPrepareCallHierarchyInfo, (*Server).handlePrepareCallHierarchy) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentFoldingRangeInfo, (*Server).handleFoldingRange) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentPrepareRenameInfo, (*Server).handlePrepareRename) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentLinkedEditingRangeInfo, (*Server).handleLinkedEditingRange) + + handlers.registerLanguageServiceWithAutoImportsRequestHandler(lsproto.TextDocumentCompletionInfo, (*Server).handleCompletion) + handlers.registerLanguageServiceWithAutoImportsRequestHandler(lsproto.TextDocumentCodeActionInfo, (*Server).handleCodeAction) + + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentVSOnAutoInsertInfo, (*Server).handleVSOnAutoInsert) + + handlers.registerMultiProjectReferenceRequestHandler(lsproto.TextDocumentReferencesInfo, (*ls.LanguageService).ProvideReferences) + handlers.registerMultiProjectReferenceRequestHandler(lsproto.TextDocumentVSReferencesInfo, (*ls.LanguageService).ProvideVSReferences) + handlers.registerRequestHandler(lsproto.TextDocumentRenameInfo, (*Server).handleRename) + handlers.registerMultiProjectReferenceRequestHandler(lsproto.TextDocumentImplementationInfo, (*ls.LanguageService).ProvideImplementations) + + handlers.registerRequestHandler(lsproto.CallHierarchyIncomingCallsInfo, (*Server).handleCallHierarchyIncomingCalls) + handlers.registerRequestHandler(lsproto.CallHierarchyOutgoingCallsInfo, (*Server).handleCallHierarchyOutgoingCalls) + + handlers.registerRequestHandler(lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol) + handlers.registerRequestHandler(lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve) + handlers.registerRequestHandler(lsproto.CodeLensResolveInfo, (*Server).handleCodeLensResolve) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentSemanticTokensFullInfo, (*Server).handleSemanticTokensFull) + handlers.registerLanguageServiceDocumentRequestHandler(lsproto.TextDocumentSemanticTokensRangeInfo, (*Server).handleSemanticTokensRange) // Developer/debugging commands - registerRequestHandler(handlers, lsproto.CustomRunGCInfo, (*Server).handleRunGC) - registerRequestHandler(handlers, lsproto.CustomSaveHeapProfileInfo, (*Server).handleSaveHeapProfile) - registerRequestHandler(handlers, lsproto.CustomSaveAllocProfileInfo, (*Server).handleSaveAllocProfile) - registerRequestHandler(handlers, lsproto.CustomStartCPUProfileInfo, (*Server).handleStartCPUProfile) - registerRequestHandler(handlers, lsproto.CustomStopCPUProfileInfo, (*Server).handleStopCPUProfile) - - registerRequestHandler(handlers, lsproto.CustomInitializeAPISessionInfo, (*Server).handleInitializeAPISession) - registerRequestHandler(handlers, lsproto.CustomProjectInfoInfo, (*Server).handleProjectInfo) - registerRequestHandler(handlers, lsproto.CustomSetContentMapperContributionsInfo, (*Server).handleSetContentMapperContributions) + handlers.registerRequestHandler(lsproto.CustomRunGCInfo, (*Server).handleRunGC) + handlers.registerRequestHandler(lsproto.CustomSaveHeapProfileInfo, (*Server).handleSaveHeapProfile) + handlers.registerRequestHandler(lsproto.CustomSaveAllocProfileInfo, (*Server).handleSaveAllocProfile) + handlers.registerRequestHandler(lsproto.CustomStartCPUProfileInfo, (*Server).handleStartCPUProfile) + handlers.registerRequestHandler(lsproto.CustomStopCPUProfileInfo, (*Server).handleStopCPUProfile) + + handlers.registerRequestHandler(lsproto.CustomInitializeAPISessionInfo, (*Server).handleInitializeAPISession) + handlers.registerRequestHandler(lsproto.CustomProjectInfoInfo, (*Server).handleProjectInfo) + handlers.registerRequestHandler(lsproto.CustomSetContentMapperContributionsInfo, (*Server).handleSetContentMapperContributions) return handlers }) -func registerNotificationHandler[Req any](handlers handlerMap, info lsproto.NotificationInfo[Req], fn func(*Server, context.Context, Req) error) { +func (handlers handlerMap) registerNotificationHandler[Req any](info lsproto.NotificationInfo[Req], fn func(*Server, context.Context, Req) error) { handlers[info.Method] = func(s *Server, ctx context.Context, req *lsproto.RequestMessage) (func() error, error) { if s.session == nil && req.Method != lsproto.MethodInitialized { return nil, lsproto.ErrorCodeServerNotInitialized } - params, err := lsproto.UnmarshalParams[Req](req) + params, err := req.UnmarshalParams[Req]() if err != nil { return nil, err } @@ -1310,8 +1310,7 @@ func registerNotificationHandler[Req any](handlers handlerMap, info lsproto.Noti } } -func registerRequestHandler[Req, Resp any]( - handlers handlerMap, +func (handlers handlerMap) registerRequestHandler[Req, Resp any]( info lsproto.RequestInfo[Req, Resp], fn func(*Server, context.Context, Req, *lsproto.RequestMessage) (Resp, error), ) { @@ -1320,7 +1319,7 @@ func registerRequestHandler[Req, Resp any]( return nil, lsproto.ErrorCodeServerNotInitialized } - params, err := lsproto.UnmarshalParams[Req](req) + params, err := req.UnmarshalParams[Req]() if err != nil { return nil, err } @@ -1335,9 +1334,9 @@ func registerRequestHandler[Req, Resp any]( } } -func registerLanguageServiceDocumentRequestHandler[Req lsproto.HasTextDocumentURI, Resp any](handlers handlerMap, info lsproto.RequestInfo[Req, Resp], fn func(*Server, context.Context, *ls.LanguageService, Req) (Resp, error)) { +func (handlers handlerMap) registerLanguageServiceDocumentRequestHandler[Req lsproto.HasTextDocumentURI, Resp any](info lsproto.RequestInfo[Req, Resp], fn func(*Server, context.Context, *ls.LanguageService, Req) (Resp, error)) { handlers[info.Method] = func(s *Server, ctx context.Context, req *lsproto.RequestMessage) (func() error, error) { - params, err := lsproto.UnmarshalParams[Req](req) + params, err := req.UnmarshalParams[Req]() if err != nil { return nil, err } @@ -1362,9 +1361,9 @@ func registerLanguageServiceDocumentRequestHandler[Req lsproto.HasTextDocumentUR } } -func registerLanguageServiceWithAutoImportsRequestHandler[Req lsproto.HasTextDocumentURI, Resp any](handlers handlerMap, info lsproto.RequestInfo[Req, Resp], fn func(*Server, context.Context, *ls.LanguageService, Req) (Resp, error)) { +func (handlers handlerMap) registerLanguageServiceWithAutoImportsRequestHandler[Req lsproto.HasTextDocumentURI, Resp any](info lsproto.RequestInfo[Req, Resp], fn func(*Server, context.Context, *ls.LanguageService, Req) (Resp, error)) { handlers[info.Method] = func(s *Server, ctx context.Context, req *lsproto.RequestMessage) (func() error, error) { - params, err := lsproto.UnmarshalParams[Req](req) + params, err := req.UnmarshalParams[Req]() if err != nil { return nil, err } @@ -1397,13 +1396,12 @@ func registerLanguageServiceWithAutoImportsRequestHandler[Req lsproto.HasTextDoc } } -func registerMultiProjectReferenceRequestHandler[Req lsproto.HasTextDocumentPosition, Resp any]( - handlers handlerMap, +func (handlers handlerMap) registerMultiProjectReferenceRequestHandler[Req lsproto.HasTextDocumentPosition, Resp any]( info lsproto.RequestInfo[Req, Resp], fn func(*ls.LanguageService, context.Context, Req, ls.CrossProjectOrchestrator) (Resp, error), ) { handlers[info.Method] = func(s *Server, ctx context.Context, req *lsproto.RequestMessage) (func() error, error) { - params, err := lsproto.UnmarshalParams[Req](req) + params, err := req.UnmarshalParams[Req]() if err != nil { return nil, err } @@ -1483,7 +1481,7 @@ func (s *Server) recover(req *lsproto.RequestMessage) { } if s.telemetryEnabled { - _ = sendNotification(s, lsproto.TelemetryEventInfo, lsproto.TelemetryEvent{ + _ = s.sendNotification(lsproto.TelemetryEventInfo, lsproto.TelemetryEvent{ RequestFailureTelemetryEvent: &lsproto.RequestFailureTelemetryEvent{ Properties: &lsproto.RequestFailureTelemetryProperties{ ErrorCode: lsproto.ErrorCodeInternalError.String(), @@ -1758,7 +1756,7 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali } s.session.InitializeWithUserConfig(userPreferences) - _, err = sendClientRequest(ctx, s, lsproto.ClientRegisterCapabilityInfo, &lsproto.RegistrationParams{ + _, err = s.sendClientRequest(ctx, lsproto.ClientRegisterCapabilityInfo, &lsproto.RegistrationParams{ Registrations: []*lsproto.Registration{ { Id: "typescript-config-watch-id", @@ -1880,7 +1878,7 @@ func (s *Server) handleDocumentDiagnostic(ctx context.Context, languageService * if s.telemetryEnabled { sanitizedDiff := generateDiagnosticDiffString(missingFromPre, missingFromPost, (*lsproto.Diagnostic).CodeAsString) - _ = sendNotification(s, lsproto.TelemetryEventInfo, lsproto.TelemetryEvent{ + _ = s.sendNotification(lsproto.TelemetryEventInfo, lsproto.TelemetryEvent{ RequestFailureTelemetryEvent: &lsproto.RequestFailureTelemetryEvent{ Properties: &lsproto.RequestFailureTelemetryProperties{ ErrorCode: lsproto.ErrorCodeInternalError.String(), diff --git a/tsc/internal/lsp/server_completion_test.go b/tsc/internal/lsp/server_completion_test.go index 00d77e2834aae..f45d3e8082d17 100644 --- a/tsc/internal/lsp/server_completion_test.go +++ b/tsc/internal/lsp/server_completion_test.go @@ -48,14 +48,14 @@ func initCompletionClient(t *testing.T, files map[string]string, prefs *lsutil.U }, onServerRequest) t.Cleanup(func() { _ = closeClient() }) - initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{ + initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{ Capabilities: &lsproto.ClientCapabilities{}, }) assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "Initialize failed") - lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) <-client.Server.InitComplete() - lsptestutil.SendNotification(t, client, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{ + client.SendNotification(t, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{ Settings: map[string]any{"typescript": prefs}, }) @@ -102,18 +102,18 @@ func TestCompletionAfterFileClose(t *testing.T) { aURI := lsconv.FileNameToDocumentURI("/home/projects/a.ts") bURI := lsconv.FileNameToDocumentURI("/home/projects/b.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: aURI, LanguageId: "typescript", Text: "export const someVar = 10;"}, }) - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: bURI, LanguageId: "typescript", Text: "s"}, }) - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: bURI}, }) - msg, resp, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ + msg, resp, ok := client.SendRequest(t, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: bURI}, Position: lsproto.Position{Line: 0, Character: 1}, Context: &lsproto.CompletionContext{}, @@ -147,20 +147,20 @@ func TestCompletionWithConcurrentFileClose(t *testing.T) { aURI := lsconv.FileNameToDocumentURI("/home/projects/a.ts") bURI := lsconv.FileNameToDocumentURI("/home/projects/b.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: aURI, LanguageId: "typescript", Text: "export const someVar = 10;"}, }) - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: bURI, LanguageId: "typescript", Text: "s"}, }) - waitForCompletion := lsptestutil.SendRequestAsync(t, client, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ + waitForCompletion := client.SendRequestAsync(t, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: bURI}, Position: lsproto.Position{Line: 0, Character: 1}, Context: &lsproto.CompletionContext{}, }) - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: bURI}, }) @@ -187,7 +187,7 @@ func TestCompletionForUnopenedFile(t *testing.T) { }, prefs) cURI := lsconv.FileNameToDocumentURI("/home/projects/c.ts") - msg, resp, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ + msg, resp, ok := client.SendRequest(t, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: cURI}, Position: lsproto.Position{Line: 1, Character: 2}, Context: &lsproto.CompletionContext{}, @@ -215,7 +215,7 @@ func TestAutoImportCompletionForUnopenedFile(t *testing.T) { }, prefs) cURI := lsconv.FileNameToDocumentURI("/home/projects/c.ts") - msg, resp, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ + msg, resp, ok := client.SendRequest(t, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: cURI}, Position: lsproto.Position{Line: 0, Character: 1}, Context: &lsproto.CompletionContext{}, @@ -251,20 +251,20 @@ func TestCompletionSnapshotFreezing(t *testing.T) { aURI := lsconv.FileNameToDocumentURI("/home/projects/a.ts") bURI := lsconv.FileNameToDocumentURI("/home/projects/b.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: aURI, LanguageId: "typescript", Text: "export const someVar = 10;"}, }) - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: bURI, LanguageId: "typescript", Text: "someV"}, }) - waitForCompletion := lsptestutil.SendRequestAsync(t, client, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ + waitForCompletion := client.SendRequestAsync(t, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: bURI}, Position: lsproto.Position{Line: 0, Character: 5}, Context: &lsproto.CompletionContext{}, }) - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidChangeInfo, &lsproto.DidChangeTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidChangeInfo, &lsproto.DidChangeTextDocumentParams{ TextDocument: lsproto.VersionedTextDocumentIdentifier{Uri: bURI, Version: 2}, ContentChanges: []lsproto.TextDocumentContentChangePartialOrWholeDocument{ {WholeDocument: &lsproto.TextDocumentContentChangeWholeDocument{Text: "notMatching"}}, diff --git a/tsc/internal/lsp/server_contentmapper_test.go b/tsc/internal/lsp/server_contentmapper_test.go index a24b7639b330f..1f9968b70c681 100644 --- a/tsc/internal/lsp/server_contentmapper_test.go +++ b/tsc/internal/lsp/server_contentmapper_test.go @@ -45,14 +45,14 @@ export const title = "Profile"; case lsproto.MethodWorkspaceConfiguration: return &lsproto.ResponseMessage{ID: req.ID, JSONRPC: req.JSONRPC, Result: []any{nil, nil, nil, nil}} case lsproto.MethodClientRegisterCapability: - params, err := lsproto.UnmarshalParams[*lsproto.RegistrationParams](req) + params, err := req.UnmarshalParams[*lsproto.RegistrationParams]() assert.NilError(t, err) mu.Lock() registrations = append(registrations, params.Registrations...) mu.Unlock() return &lsproto.ResponseMessage{ID: req.ID, JSONRPC: req.JSONRPC, Result: lsproto.Null{}} case lsproto.MethodClientUnregisterCapability: - params, err := lsproto.UnmarshalParams[*lsproto.UnregistrationParams](req) + params, err := req.UnmarshalParams[*lsproto.UnregistrationParams]() assert.NilError(t, err) mu.Lock() unregistrations = append(unregistrations, params.Unregisterations...) @@ -105,18 +105,18 @@ export const title = "Profile"; }, }, } - initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{ + initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{ Capabilities: caps, InitializationOptions: &lsproto.InitializationOptionsOrNull{InitializationOptions: &lsproto.InitializationOptions{ RunExternalCode: new(true), }}, }) assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "initialize failed") - lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) <-client.Server.InitComplete() uri := lsproto.DocumentUri("file:///home/project/ProfileCard.vue") - msg, _, ok := lsptestutil.SendRequest(t, client, lsproto.CustomSetContentMapperContributionsInfo, &lsproto.SetContentMapperContributionsParams{ + msg, _, ok := client.SendRequest(t, lsproto.CustomSetContentMapperContributionsInfo, &lsproto.SetContentMapperContributionsParams{ OpenDocuments: []lsproto.TextDocumentIdentifier{{Uri: uri}}, Contributions: []*lsproto.ContentMapperContribution{{ ContributorId: "test", @@ -170,10 +170,10 @@ export const title = "Profile"; assert.Assert(t, found, "expected %s registration for .vue", id) } - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: uri, LanguageId: "vue", Version: 1, Text: component}, }) - hoverMsg, hover, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentHoverInfo, &lsproto.HoverParams{ + hoverMsg, hover, ok := client.SendRequest(t, lsproto.TextDocumentHoverInfo, &lsproto.HoverParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, Position: lsproto.Position{Line: 3, Character: 15}, }) @@ -183,35 +183,35 @@ export const title = "Profile"; assert.NilError(t, fs.WriteFile("/home/project/tsconfig.json", `{ "compilerOptions": { "target": "es2020", "module": "esnext", "moduleResolution": "bundler", "strict": true } }`)) - lsptestutil.SendNotification(t, client, lsproto.WorkspaceDidChangeWatchedFilesInfo, &lsproto.DidChangeWatchedFilesParams{ + client.SendNotification(t, lsproto.WorkspaceDidChangeWatchedFilesInfo, &lsproto.DidChangeWatchedFilesParams{ Changes: []*lsproto.FileEvent{{Uri: "file:///home/project/tsconfig.json", Type: lsproto.FileChangeTypeChanged}}, }) - hoverMsg, hover, _ = lsptestutil.SendRequest(t, client, lsproto.TextDocumentHoverInfo, &lsproto.HoverParams{ + hoverMsg, hover, _ = client.SendRequest(t, lsproto.TextDocumentHoverInfo, &lsproto.HoverParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, Position: lsproto.Position{Line: 3, Character: 15}, }) assert.Assert(t, hoverMsg != nil && hoverMsg.AsResponse().Error == nil, "request before didClose should return a null result") assert.Assert(t, hover.Hover == nil) - diagnosticMsg, diagnostics, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentDiagnosticInfo, &lsproto.DocumentDiagnosticParams{ + diagnosticMsg, diagnostics, ok := client.SendRequest(t, lsproto.TextDocumentDiagnosticInfo, &lsproto.DocumentDiagnosticParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, }) assert.Assert(t, ok && diagnosticMsg.AsResponse().Error == nil, "diagnostics before didClose should return an empty report") assert.Assert(t, diagnostics.FullDocumentDiagnosticReport != nil) assert.Equal(t, len(diagnostics.FullDocumentDiagnosticReport.Items), 0) - completionMsg, completion, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ + completionMsg, completion, ok := client.SendRequest(t, lsproto.TextDocumentCompletionInfo, &lsproto.CompletionParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, Position: lsproto.Position{Line: 3, Character: 15}, }) assert.Assert(t, ok && completionMsg.AsResponse().Error == nil) assert.Assert(t, completion.Items == nil && completion.List == nil) - referencesMsg, references, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentReferencesInfo, &lsproto.ReferenceParams{ + referencesMsg, references, ok := client.SendRequest(t, lsproto.TextDocumentReferencesInfo, &lsproto.ReferenceParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, Position: lsproto.Position{Line: 3, Character: 15}, Context: &lsproto.ReferenceContext{IncludeDeclaration: true}, }) assert.Assert(t, ok && referencesMsg.AsResponse().Error == nil) assert.Assert(t, references.Locations == nil) - renameMsg, rename, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ + renameMsg, rename, ok := client.SendRequest(t, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, Position: lsproto.Position{Line: 3, Character: 15}, NewName: "renamed", @@ -238,7 +238,7 @@ export const title = "Profile"; assert.Assert(t, found, "expected %s unregistration", id) } - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, }) } diff --git a/tsc/internal/lsp/server_progress_test.go b/tsc/internal/lsp/server_progress_test.go index 87a2ee0372fdd..f5d42c7e2316c 100644 --- a/tsc/internal/lsp/server_progress_test.go +++ b/tsc/internal/lsp/server_progress_test.go @@ -54,7 +54,7 @@ func TestProgressNotificationsEndToEnd(t *testing.T) { client.OnServerNotification = func(_ context.Context, req *lsproto.RequestMessage) { if req.Method == lsproto.MethodProgress { - if params, err := lsproto.UnmarshalParams[*lsproto.ProgressParams](req); err == nil && params != nil { + if params, err := req.UnmarshalParams[*lsproto.ProgressParams](); err == nil && params != nil { mu.Lock() progressNotifications = append(progressNotifications, params) isEnd := params.Value.End != nil @@ -71,7 +71,7 @@ func TestProgressNotificationsEndToEnd(t *testing.T) { } } - initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{ + initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{ Capabilities: &lsproto.ClientCapabilities{ Window: &lsproto.WindowClientCapabilities{ WorkDoneProgress: new(true), @@ -79,16 +79,16 @@ func TestProgressNotificationsEndToEnd(t *testing.T) { }, }) assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "Initialize failed") - lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) <-client.Server.InitComplete() uri := lsproto.DocumentUri("file:///home/projects/index.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: uri, LanguageId: "typescript", Text: "export const x = 1;"}, }) // Send a request to ensure the server has processed the didOpen and loaded the project. - msg, resp, ok := lsptestutil.SendRequest(t, client, lsproto.CustomProjectInfoInfo, &lsproto.ProjectInfoParams{ + msg, resp, ok := client.SendRequest(t, lsproto.CustomProjectInfoInfo, &lsproto.ProjectInfoParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, }) assert.Assert(t, ok, "expected a response") diff --git a/tsc/internal/lsp/server_projectinfo_test.go b/tsc/internal/lsp/server_projectinfo_test.go index cf6ae78a95f20..22d147c40440a 100644 --- a/tsc/internal/lsp/server_projectinfo_test.go +++ b/tsc/internal/lsp/server_projectinfo_test.go @@ -39,11 +39,11 @@ func initProjectInfoClient(t *testing.T, files map[string]string) *lsptestutil.L }, onServerRequest) t.Cleanup(func() { _ = closeClient() }) - initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{ + initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{ Capabilities: &lsproto.ClientCapabilities{}, }) assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "Initialize failed") - lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) <-client.Server.InitComplete() return client @@ -62,11 +62,11 @@ func TestProjectInfoConfiguredProject(t *testing.T) { }) uri := lsproto.DocumentUri("file:///home/projects/index.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: uri, LanguageId: "typescript", Text: "export const x = 1;"}, }) - msg, resp, ok := lsptestutil.SendRequest(t, client, lsproto.CustomProjectInfoInfo, &lsproto.ProjectInfoParams{ + msg, resp, ok := client.SendRequest(t, lsproto.CustomProjectInfoInfo, &lsproto.ProjectInfoParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, }) assert.Assert(t, ok, "expected a response") @@ -86,11 +86,11 @@ func TestProjectInfoInferredProject(t *testing.T) { }) uri := lsproto.DocumentUri("file:///home/projects/index.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: uri, LanguageId: "typescript", Text: "export const x = 1;"}, }) - msg, resp, ok := lsptestutil.SendRequest(t, client, lsproto.CustomProjectInfoInfo, &lsproto.ProjectInfoParams{ + msg, resp, ok := client.SendRequest(t, lsproto.CustomProjectInfoInfo, &lsproto.ProjectInfoParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, }) assert.Assert(t, ok, "expected a response") diff --git a/tsc/internal/lsp/server_projectreference_updates_test.go b/tsc/internal/lsp/server_projectreference_updates_test.go index b4b81ae734690..1e894f99e863a 100644 --- a/tsc/internal/lsp/server_projectreference_updates_test.go +++ b/tsc/internal/lsp/server_projectreference_updates_test.go @@ -50,14 +50,14 @@ func initMutableLSPClient(t *testing.T, files map[string]string, prefs *lsutil.U }, onServerRequest) t.Cleanup(func() { _ = closeClient() }) - initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{ + initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{ Capabilities: &lsproto.ClientCapabilities{}, }) assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "Initialize failed") - lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) <-client.Server.InitComplete() - lsptestutil.SendNotification(t, client, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{ + client.SendNotification(t, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{ Settings: map[string]any{"typescript": prefs}, }) @@ -84,26 +84,26 @@ func TestReferencesAfterAncestorProjectConfigDeletion1(t *testing.T) { }, &lsutil.UserPreferences{}) mainURI := lsconv.FileNameToDocumentURI("/root/project/src/main.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: mainURI, LanguageId: "typescript", Text: "export function helloWorld() {}\nhelloWorld()\n"}, }) // Prime the child project so opening a file creates the ancestor configured-project placeholder. - msg, _, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentDocumentSymbolInfo, &lsproto.DocumentSymbolParams{ + msg, _, ok := client.SendRequest(t, lsproto.TextDocumentDocumentSymbolInfo, &lsproto.DocumentSymbolParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: mainURI}, }) assert.Assert(t, ok, "expected response") assert.Assert(t, msg.AsResponse().Error == nil) assert.NilError(t, fs.Remove("root/tsconfig.json")) - lsptestutil.SendNotification(t, client, lsproto.WorkspaceDidChangeWatchedFilesInfo, &lsproto.DidChangeWatchedFilesParams{ + client.SendNotification(t, lsproto.WorkspaceDidChangeWatchedFilesInfo, &lsproto.DidChangeWatchedFilesParams{ Changes: []*lsproto.FileEvent{{ Uri: lsconv.FileNameToDocumentURI("/root/tsconfig.json"), Type: lsproto.FileChangeTypeDeleted, }}, }) - msg, resp, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentReferencesInfo, &lsproto.ReferenceParams{ + msg, resp, ok := client.SendRequest(t, lsproto.TextDocumentReferencesInfo, &lsproto.ReferenceParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: mainURI}, Position: lsproto.Position{Line: 1, Character: 3}, Context: &lsproto.ReferenceContext{IncludeDeclaration: true}, diff --git a/tsc/internal/lsp/server_semantictokens_test.go b/tsc/internal/lsp/server_semantictokens_test.go index f0c78bbca49c2..a3bfb2b7a0c93 100644 --- a/tsc/internal/lsp/server_semantictokens_test.go +++ b/tsc/internal/lsp/server_semantictokens_test.go @@ -50,7 +50,7 @@ func TestSemanticTokensCRLF(t *testing.T) { }, onServerRequest) t.Cleanup(func() { _ = closeClient() }) - initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{ + initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{ Capabilities: &lsproto.ClientCapabilities{ TextDocument: &lsproto.TextDocumentClientCapabilities{ SemanticTokens: &lsproto.SemanticTokensClientCapabilities{ @@ -64,27 +64,27 @@ func TestSemanticTokensCRLF(t *testing.T) { }, }) assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "Initialize failed") - lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) <-client.Server.InitComplete() // Open another project file to force the project to load test.ts from disk (LF). otherUri := lsproto.DocumentUri("file:///home/projects/other.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: otherUri, LanguageId: "typescript", Text: files["/home/projects/other.ts"]}, }) - msg1, _, _ := lsptestutil.SendRequest(t, client, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{ + msg1, _, _ := client.SendRequest(t, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: otherUri}, }) assert.Assert(t, msg1.AsResponse().Error == nil, "Initial request failed") // Open test.ts with CRLF content; the project already parsed it from disk (LF). uri := lsproto.DocumentUri("file:///home/projects/test.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: uri, LanguageId: "typescript", Text: fileFromEditor}, }) // This panics: AST positions are LF-based but the line map is CRLF-based. - msg, _, _ := lsptestutil.SendRequest(t, client, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{ + msg, _, _ := client.SendRequest(t, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, }) if msg.AsResponse().Error != nil { @@ -137,7 +137,7 @@ declare const console: { log(msg: any): void; }; }, onServerRequest) t.Cleanup(func() { _ = closeClient() }) - initMsg, _, ok := lsptestutil.SendRequest(t, client, lsproto.InitializeInfo, &lsproto.InitializeParams{ + initMsg, _, ok := client.SendRequest(t, lsproto.InitializeInfo, &lsproto.InitializeParams{ Capabilities: &lsproto.ClientCapabilities{ TextDocument: &lsproto.TextDocumentClientCapabilities{ SemanticTokens: &lsproto.SemanticTokensClientCapabilities{ @@ -151,15 +151,15 @@ declare const console: { log(msg: any): void; }; }, }) assert.Assert(t, ok && initMsg.AsResponse().Error == nil, "Initialize failed") - lsptestutil.SendNotification(t, client, lsproto.InitializedInfo, &lsproto.InitializedParams{}) + client.SendNotification(t, lsproto.InitializedInfo, &lsproto.InitializedParams{}) <-client.Server.InitComplete() uri := lsproto.DocumentUri("file:///home/projects/test.ts") - lsptestutil.SendNotification(t, client, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ + client.SendNotification(t, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{ TextDocument: &lsproto.TextDocumentItem{Uri: uri, LanguageId: "typescript", Text: files["/home/projects/test.ts"]}, }) - msg, result, ok := lsptestutil.SendRequest(t, client, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{ + msg, result, ok := client.SendRequest(t, lsproto.TextDocumentSemanticTokensFullInfo, &lsproto.SemanticTokensParams{ TextDocument: lsproto.TextDocumentIdentifier{Uri: uri}, }) assert.Assert(t, ok, "Semantic tokens request did not return a result") diff --git a/tsc/internal/packagejson/exportsorimports.go b/tsc/internal/packagejson/exportsorimports.go index 38ca1c349a5cb..7add2e9f4aaac 100644 --- a/tsc/internal/packagejson/exportsorimports.go +++ b/tsc/internal/packagejson/exportsorimports.go @@ -23,7 +23,7 @@ type ExportsOrImports struct { var _ json.UnmarshalerFrom = (*ExportsOrImports)(nil) func (e *ExportsOrImports) UnmarshalJSONFrom(dec *json.Decoder) error { - return unmarshalJSONValueV2[ExportsOrImports](&e.JSONValue, dec) + return e.JSONValue.unmarshalJSONValueFrom[ExportsOrImports](dec) } func (e ExportsOrImports) AsObject() *collections.OrderedMap[string, ExportsOrImports] { diff --git a/tsc/internal/packagejson/jsonvalue.go b/tsc/internal/packagejson/jsonvalue.go index 2260b4dd30c48..ef88e9b07c426 100644 --- a/tsc/internal/packagejson/jsonvalue.go +++ b/tsc/internal/packagejson/jsonvalue.go @@ -86,43 +86,10 @@ func (v JSONValue) AsString() string { var _ json.UnmarshalerFrom = (*JSONValue)(nil) func (v *JSONValue) UnmarshalJSONFrom(dec *json.Decoder) error { - return unmarshalJSONValueV2[JSONValue](v, dec) + return v.unmarshalJSONValueFrom[JSONValue](dec) } -func unmarshalJSONValue[T any](v *JSONValue, data []byte) error { - if string(data) == "null" { - *v = JSONValue{Type: JSONValueTypeNull} - } else if data[0] == '"' { - v.Type = JSONValueTypeString - return json.Unmarshal(data, &v.Value) - } else if data[0] == '[' { - var elements []T - if err := json.Unmarshal(data, &elements); err != nil { - return err - } - v.Type = JSONValueTypeArray - v.Value = elements - } else if data[0] == '{' { - var object collections.OrderedMap[string, T] - if err := json.Unmarshal(data, &object); err != nil { - return err - } - v.Type = JSONValueTypeObject - v.Value = &object - } else if string(data) == "true" { - v.Type = JSONValueTypeBoolean - v.Value = true - } else if string(data) == "false" { - v.Type = JSONValueTypeBoolean - v.Value = false - } else { - v.Type = JSONValueTypeNumber - return json.Unmarshal(data, &v.Value) - } - return nil -} - -func unmarshalJSONValueV2[T any](v *JSONValue, dec *json.Decoder) error { +func (v *JSONValue) unmarshalJSONValueFrom[T any](dec *json.Decoder) error { switch dec.PeekKind() { case 'n': // json.Null.Kind() if _, err := dec.ReadToken(); err != nil { diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index 8b53a39b0cda3..e45bfaa005b30 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -1303,13 +1303,13 @@ func (p *Parser) parseForOrForInOrForOfStatement() *ast.Node { p.token == ast.KindAwaitKeyword && p.lookAhead((*Parser).nextIsUsingKeywordThenBindingIdentifierOrStartOfObjectDestructuringOnSameLine) { initializer = p.parseVariableDeclarationList(true /*inForStatementInitializer*/) } else { - initializer = doInContext(p, ast.NodeFlagsDisallowInContext, true, (*Parser).parseExpression) + initializer = p.doInContext(ast.NodeFlagsDisallowInContext, true, (*Parser).parseExpression) } } var result *ast.Statement switch { case awaitToken != nil && p.parseExpected(ast.KindOfKeyword) || awaitToken == nil && p.parseOptional(ast.KindOfKeyword): - expression := doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) + expression := p.doInContext(ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) p.parseExpected(ast.KindCloseParenToken) result = p.factory.NewForInOrOfStatement(ast.KindForOfStatement, awaitToken, initializer, expression, p.parseStatement()) case p.parseOptional(ast.KindInKeyword): @@ -1386,7 +1386,7 @@ func (p *Parser) parseWithStatement() *ast.Node { openParenParsed := p.parseExpected(ast.KindOpenParenToken) expression := p.parseExpressionAllowIn() p.parseExpectedMatchingBrackets(ast.KindOpenParenToken, ast.KindCloseParenToken, openParenParsed, openParenPosition) - statement := doInContext(p, ast.NodeFlagsInWithStatement, true, (*Parser).parseStatement) + statement := p.doInContext(ast.NodeFlagsInWithStatement, true, (*Parser).parseStatement) result := p.finishNode(p.factory.NewWithStatement(expression, statement), pos) p.withJSDoc(result, jsdoc) return result @@ -2018,7 +2018,7 @@ func (p *Parser) parsePropertyDeclaration(pos int, jsdoc jsdocScannerInfo, modif postfixToken = p.parseOptionalToken(ast.KindExclamationToken) } typeNode := p.parseTypeAnnotation() - initializer := doInContext(p, ast.NodeFlagsYieldContext|ast.NodeFlagsAwaitContext|ast.NodeFlagsDisallowInContext, false, (*Parser).parseInitializer) + initializer := p.doInContext(ast.NodeFlagsYieldContext|ast.NodeFlagsAwaitContext|ast.NodeFlagsDisallowInContext, false, (*Parser).parseInitializer) p.parseSemicolonAfterPropertyName(name, typeNode, initializer) result := p.finishNode(p.factory.NewPropertyDeclaration(modifiers, name, postfixToken, typeNode, initializer), pos) p.withJSDoc(result, jsdoc) @@ -2172,7 +2172,7 @@ func (p *Parser) parseEnumMember() *ast.Node { pos := p.nodePos() jsdoc := p.jsdocScannerInfo() name := p.parsePropertyName() - initializer := doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseInitializer) + initializer := p.doInContext(ast.NodeFlagsDisallowInContext, false, (*Parser).parseInitializer) result := p.finishNode(p.factory.NewEnumMember(name, initializer), pos) p.withJSDoc(result, jsdoc) return result @@ -2663,11 +2663,11 @@ func (p *Parser) parseType() *ast.TypeNode { typeNode = p.parseUnionTypeOrHigher() if !p.inDisallowConditionalTypesContext() && !p.hasPrecedingLineBreak() && p.parseOptional(ast.KindExtendsKeyword) { // The type following 'extends' is not permitted to be another conditional type - extendsType := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, true, (*Parser).parseType) + extendsType := p.doInContext(ast.NodeFlagsDisallowConditionalTypesContext, true, (*Parser).parseType) p.parseExpected(ast.KindQuestionToken) - trueType := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseType) + trueType := p.doInContext(ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseType) p.parseExpected(ast.KindColonToken) - falseType := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseType) + falseType := p.doInContext(ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseType) conditionalType := p.factory.NewConditionalTypeNode(typeNode, extendsType, trueType, falseType) p.finishNode(conditionalType, pos) typeNode = conditionalType @@ -2726,7 +2726,7 @@ func (p *Parser) parseTypeOperatorOrHigher() *ast.TypeNode { case ast.KindInferKeyword: return p.parseInferType() } - return doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parsePostfixTypeOrHigher) + return p.doInContext(ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parsePostfixTypeOrHigher) } func (p *Parser) parseTypeOperator(operator ast.Kind) *ast.Node { @@ -2751,7 +2751,7 @@ func (p *Parser) parseTypeParameterOfInferType() *ast.Node { func (p *Parser) tryParseConstraintOfInferType() *ast.Node { state := p.mark() if p.parseOptional(ast.KindExtendsKeyword) { - constraint := doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, true, (*Parser).parseType) + constraint := p.doInContext(ast.NodeFlagsDisallowConditionalTypesContext, true, (*Parser).parseType) if p.inDisallowConditionalTypesContext() || p.token != ast.KindQuestionToken { return constraint } @@ -3429,7 +3429,7 @@ func (p *Parser) parseNameOfParameter(modifiers *ast.ModifierList) *ast.Node { func (p *Parser) parseReturnType(returnToken ast.Kind, isType bool) *ast.TypeNode { if p.shouldParseReturnType(returnToken, isType) { - return doInContext(p, ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseTypeOrTypePredicate) + return p.doInContext(ast.NodeFlagsDisallowConditionalTypesContext, false, (*Parser).parseTypeOrTypePredicate) } return nil } @@ -3948,7 +3948,7 @@ func (p *Parser) parseModifiersEx(allowDecorators bool, permitConstAsModifier bo func (p *Parser) parseDecorator() *ast.Node { pos := p.nodePos() p.parseExpected(ast.KindAtToken) - expression := doInContext(p, ast.NodeFlagsDecoratorContext, true, (*Parser).parseDecoratorExpression) + expression := p.doInContext(ast.NodeFlagsDecoratorContext, true, (*Parser).parseDecoratorExpression) return p.finishNode(p.factory.NewDecorator(expression), pos) } @@ -4120,7 +4120,7 @@ func (p *Parser) parseExpression() *ast.Expression { } func (p *Parser) parseExpressionAllowIn() *ast.Expression { - return doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseExpression) + return p.doInContext(ast.NodeFlagsDisallowInContext, false, (*Parser).parseExpression) } func (p *Parser) parseAssignmentExpressionOrHigher() *ast.Expression { @@ -5542,7 +5542,7 @@ func (p *Parser) parseArgumentList() *ast.NodeList { } func (p *Parser) parseArgumentExpression() *ast.Expression { - return doInContext(p, ast.NodeFlagsDisallowInContext|ast.NodeFlagsDecoratorContext, false, (*Parser).parseArgumentOrArrayLiteralElement) + return p.doInContext(ast.NodeFlagsDisallowInContext|ast.NodeFlagsDecoratorContext, false, (*Parser).parseArgumentOrArrayLiteralElement) } func (p *Parser) parseArgumentOrArrayLiteralElement() *ast.Expression { @@ -5714,12 +5714,12 @@ func (p *Parser) parseObjectLiteralElement() *ast.Node { equalsToken := p.parseOptionalToken(ast.KindEqualsToken) var initializer *ast.Expression if equalsToken != nil { - initializer = doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) + initializer = p.doInContext(ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) } node = p.factory.NewShorthandPropertyAssignment(modifiers, name, postfixToken, nil /*typeNode*/, equalsToken, initializer) } else { p.parseExpected(ast.KindColonToken) - initializer := doInContext(p, ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) + initializer := p.doInContext(ast.NodeFlagsDisallowInContext, false, (*Parser).parseAssignmentExpressionOrHigher) node = p.factory.NewPropertyAssignment(modifiers, name, postfixToken, nil /*typeNode*/, initializer) } p.finishNode(node, pos) @@ -5746,11 +5746,11 @@ func (p *Parser) parseFunctionExpression() *ast.Expression { var name *ast.Node switch { case isGenerator && isAsync: - name = doInContext(p, ast.NodeFlagsYieldContext|ast.NodeFlagsAwaitContext, true, (*Parser).parseOptionalBindingIdentifier) + name = p.doInContext(ast.NodeFlagsYieldContext|ast.NodeFlagsAwaitContext, true, (*Parser).parseOptionalBindingIdentifier) case isGenerator: - name = doInContext(p, ast.NodeFlagsYieldContext, true, (*Parser).parseOptionalBindingIdentifier) + name = p.doInContext(ast.NodeFlagsYieldContext, true, (*Parser).parseOptionalBindingIdentifier) case isAsync: - name = doInContext(p, ast.NodeFlagsAwaitContext, true, (*Parser).parseOptionalBindingIdentifier) + name = p.doInContext(ast.NodeFlagsAwaitContext, true, (*Parser).parseOptionalBindingIdentifier) default: name = p.parseOptionalBindingIdentifier() } @@ -6406,7 +6406,7 @@ func (p *Parser) setContextFlags(flags ast.NodeFlags, value bool) { } } -func doInContext[T any](p *Parser, flags ast.NodeFlags, value bool, f func(p *Parser) T) T { +func (p *Parser) doInContext[T any](flags ast.NodeFlags, value bool, f func(p *Parser) T) T { saveContextFlags := p.contextFlags p.setContextFlags(flags, value) result := f(p) diff --git a/tsc/internal/project/overlayfs.go b/tsc/internal/project/overlayfs.go index e1da6edd1fb94..3b66c885abe48 100644 --- a/tsc/internal/project/overlayfs.go +++ b/tsc/internal/project/overlayfs.go @@ -360,7 +360,7 @@ func (fs *overlayFS) processChanges(changes []FileChange) (FileChangeSummary, ma }) for _, textChange := range change.Changes { if partialChange := textChange.Partial; partialChange != nil { - ranges := lsconv.FromLSPRange(converters, o, partialChange.Range, spanmap.FeatureAll) + ranges := converters.FromLSPRange(o, partialChange.Range, spanmap.FeatureAll) debug.Assert(len(ranges) == 1, "expected exactly one range for partial change") textChange := core.TextChange{TextRange: ranges[0].Span, NewText: partialChange.Text} newContent := textChange.ApplyTo(o.content) diff --git a/tsc/internal/project/session.go b/tsc/internal/project/session.go index 16d3e14ae2076..be6a4f11805b7 100644 --- a/tsc/internal/project/session.go +++ b/tsc/internal/project/session.go @@ -1528,7 +1528,7 @@ func (s *Session) WaitForBackgroundTasks() { s.backgroundQueue.Wait() } -func updateWatch[T any](ctx context.Context, session *Session, logger logging.Logger, oldWatcher, newWatcher *WatchedFiles[T]) []error { +func (s *Session) updateWatch[T any](ctx context.Context, oldWatcher, newWatcher *WatchedFiles[T]) []error { var errors []error if newWatcher != nil { w := newWatcher.Watchers() @@ -1537,7 +1537,7 @@ func updateWatch[T any](ctx context.Context, session *Session, logger logging.Lo var newWatchers collections.OrderedMap[WatcherID, *lsproto.FileSystemWatcher] for i, watcher := range watchers { globId := WatcherID(fmt.Sprintf("%s.%d", w.WatcherID, i)) - if session.watches.Acquire(watcher, globId) { + if s.watches.Acquire(watcher, globId) { newWatchers.Set(globId, watcher) } } @@ -1546,18 +1546,18 @@ func updateWatch[T any](ctx context.Context, session *Session, logger logging.Lo // Create a fresh timeout per client call so earlier calls // don't consume the deadline for later ones. callCtx, callCancel := context.WithTimeout(ctx, watchRequestTimeout) - err := session.client.WatchFiles(callCtx, id, []*lsproto.FileSystemWatcher{watcher}) + err := s.client.WatchFiles(callCtx, id, []*lsproto.FileSystemWatcher{watcher}) callCancel() if err != nil { watchErrors = append(watchErrors, err) - } else if logger != nil { + } else if s.logger != nil { if oldWatcher == nil { - logger.Log(fmt.Sprintf("Added new watch: %s", id)) + s.logger.Log(fmt.Sprintf("Added new watch: %s", id)) } else { - logger.Log(fmt.Sprintf("Updated watch: %s", id)) + s.logger.Log(fmt.Sprintf("Updated watch: %s", id)) } - logger.Log("\t" + fileSystemWatcherGlobString(watcher)) - logger.Log("") + s.logger.Log("\t" + fileSystemWatcherGlobString(watcher)) + s.logger.Log("") } } if len(watchErrors) > 0 { @@ -1566,18 +1566,18 @@ func updateWatch[T any](ctx context.Context, session *Session, logger logging.Lo // Re-registering an already-registered watcher with the client // is harmless (registerCapability with the same ID replaces it). for _, watcher := range newWatchers.Entries() { - session.watches.Release(watcher) + s.watches.Release(watcher) } - session.watches.MarkPending(w.WatcherID) + s.watches.MarkPending(w.WatcherID) errors = append(errors, watchErrors...) } else { - session.watches.ClearPending(w.WatcherID) + s.watches.ClearPending(w.WatcherID) } if len(w.IgnoredPaths) > 0 { - logger.Logf("%d paths ineligible for watching", len(w.IgnoredPaths)) - if logger.IsVerbose() { + s.logger.Logf("%d paths ineligible for watching", len(w.IgnoredPaths)) + if s.logger.IsVerbose() { for path := range w.IgnoredPaths { - logger.Log("\t" + path) + s.logger.Log("\t" + path) } } } @@ -1589,18 +1589,18 @@ func updateWatch[T any](ctx context.Context, session *Session, logger logging.Lo if len(watchers) > 0 { var removedIDs []WatcherID for _, watcher := range watchers { - if id, removed := session.watches.Release(watcher); removed { + if id, removed := s.watches.Release(watcher); removed { removedIDs = append(removedIDs, id) } } for _, id := range removedIDs { callCtx, callCancel := context.WithTimeout(ctx, watchRequestTimeout) - err := session.client.UnwatchFiles(callCtx, id) + err := s.client.UnwatchFiles(callCtx, id) callCancel() if err != nil { errors = append(errors, err) - } else if logger != nil && newWatcher == nil { - logger.Log(fmt.Sprintf("Removed watch: %s", id)) + } else if s.logger != nil && newWatcher == nil { + s.logger.Log(fmt.Sprintf("Removed watch: %s", id)) } } } @@ -1658,13 +1658,13 @@ func (s *Session) updateWatches(oldSnapshot *Snapshot, newSnapshot *Snapshot) er return a.rootFilesWatch.ID() == b.rootFilesWatch.ID() }, func(_ tspath.Path, addedEntry *configFileEntry) { - errors = append(errors, updateWatch(ctx, s, s.logger, nil, addedEntry.rootFilesWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, addedEntry.rootFilesWatch)...) }, func(_ tspath.Path, removedEntry *configFileEntry) { - errors = append(errors, updateWatch(ctx, s, s.logger, removedEntry.rootFilesWatch, nil)...) + errors = append(errors, s.updateWatch(ctx, removedEntry.rootFilesWatch, nil)...) }, func(_ tspath.Path, oldEntry, newEntry *configFileEntry) { - errors = append(errors, updateWatch(ctx, s, s.logger, oldEntry.rootFilesWatch, newEntry.rootFilesWatch)...) + errors = append(errors, s.updateWatch(ctx, oldEntry.rootFilesWatch, newEntry.rootFilesWatch)...) }, ) // Retry config watchers whose IDs didn't change but whose previous registration failed. @@ -1672,7 +1672,7 @@ func (s *Session) updateWatches(oldSnapshot *Snapshot, newSnapshot *Snapshot) er if oldEntry, ok := oldSnapshot.ConfigFileRegistry.configs[path]; ok { if oldEntry.rootFilesWatch.ID() == newEntry.rootFilesWatch.ID() { if s.watches.IsPending(newEntry.rootFilesWatch.ID()) { - errors = append(errors, updateWatch(ctx, s, s.logger, nil, newEntry.rootFilesWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, newEntry.rootFilesWatch)...) } } } @@ -1682,43 +1682,43 @@ func (s *Session) updateWatches(oldSnapshot *Snapshot, newSnapshot *Snapshot) er oldSnapshot.ProjectCollection.ProjectsByPath(), newSnapshot.ProjectCollection.ProjectsByPath(), func(_ tspath.Path, addedProject *Project) { - errors = append(errors, updateWatch(ctx, s, s.logger, nil, addedProject.programFilesWatch)...) - errors = append(errors, updateWatch(ctx, s, s.logger, nil, addedProject.typingsWatch)...) - errors = append(errors, updateWatch(ctx, s, s.logger, nil, addedProject.contentMapperWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, addedProject.programFilesWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, addedProject.typingsWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, addedProject.contentMapperWatch)...) }, func(_ tspath.Path, removedProject *Project) { - errors = append(errors, updateWatch(ctx, s, s.logger, removedProject.programFilesWatch, nil)...) - errors = append(errors, updateWatch(ctx, s, s.logger, removedProject.typingsWatch, nil)...) - errors = append(errors, updateWatch(ctx, s, s.logger, removedProject.contentMapperWatch, nil)...) + errors = append(errors, s.updateWatch(ctx, removedProject.programFilesWatch, nil)...) + errors = append(errors, s.updateWatch(ctx, removedProject.typingsWatch, nil)...) + errors = append(errors, s.updateWatch(ctx, removedProject.contentMapperWatch, nil)...) }, func(_ tspath.Path, oldProject, newProject *Project) { if oldProject.programFilesWatch.ID() != newProject.programFilesWatch.ID() { - errors = append(errors, updateWatch(ctx, s, s.logger, oldProject.programFilesWatch, newProject.programFilesWatch)...) + errors = append(errors, s.updateWatch(ctx, oldProject.programFilesWatch, newProject.programFilesWatch)...) } else { if s.watches.IsPending(newProject.programFilesWatch.ID()) { - errors = append(errors, updateWatch(ctx, s, s.logger, nil, newProject.programFilesWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, newProject.programFilesWatch)...) } } if oldProject.typingsWatch.ID() != newProject.typingsWatch.ID() { - errors = append(errors, updateWatch(ctx, s, s.logger, oldProject.typingsWatch, newProject.typingsWatch)...) + errors = append(errors, s.updateWatch(ctx, oldProject.typingsWatch, newProject.typingsWatch)...) } else { if s.watches.IsPending(newProject.typingsWatch.ID()) { - errors = append(errors, updateWatch(ctx, s, s.logger, nil, newProject.typingsWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, newProject.typingsWatch)...) } } if oldProject.contentMapperWatch.ID() != newProject.contentMapperWatch.ID() { - errors = append(errors, updateWatch(ctx, s, s.logger, oldProject.contentMapperWatch, newProject.contentMapperWatch)...) + errors = append(errors, s.updateWatch(ctx, oldProject.contentMapperWatch, newProject.contentMapperWatch)...) } else if s.watches.IsPending(newProject.contentMapperWatch.ID()) { - errors = append(errors, updateWatch(ctx, s, s.logger, nil, newProject.contentMapperWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, newProject.contentMapperWatch)...) } }, ) if oldSnapshot.autoImportsWatch.ID() != newSnapshot.autoImportsWatch.ID() { - errors = append(errors, updateWatch(ctx, s, s.logger, oldSnapshot.autoImportsWatch, newSnapshot.autoImportsWatch)...) + errors = append(errors, s.updateWatch(ctx, oldSnapshot.autoImportsWatch, newSnapshot.autoImportsWatch)...) } else { if s.watches.IsPending(newSnapshot.autoImportsWatch.ID()) { - errors = append(errors, updateWatch(ctx, s, s.logger, nil, newSnapshot.autoImportsWatch)...) + errors = append(errors, s.updateWatch(ctx, nil, newSnapshot.autoImportsWatch)...) } } diff --git a/tsc/internal/testutil/lsptestutil/lspclient.go b/tsc/internal/testutil/lsptestutil/lspclient.go index f6d6045611fab..4bfa1c8200e37 100644 --- a/tsc/internal/testutil/lsptestutil/lspclient.go +++ b/tsc/internal/testutil/lsptestutil/lspclient.go @@ -247,7 +247,7 @@ func (c *LSPClient) WriteMsg(t *testing.T, msg *lsproto.Message) { } // SendRequest sends a typed request and waits for the response. -func SendRequest[Params, Resp any](t *testing.T, c *LSPClient, info lsproto.RequestInfo[Params, Resp], params Params) (*lsproto.Message, Resp, bool) { +func (c *LSPClient) SendRequest[Params, Resp any](t *testing.T, info lsproto.RequestInfo[Params, Resp], params Params) (*lsproto.Message, Resp, bool) { id := c.NextID() reqID := lsproto.NewID(lsproto.IntegerOrString{Integer: &id}) req := info.NewRequestMessage(reqID, params) @@ -262,7 +262,7 @@ func SendRequest[Params, Resp any](t *testing.T, c *LSPClient, info lsproto.Requ } // SendRequestAsync sends a typed request and returns a waiter for its response. -func SendRequestAsync[Params, Resp any](t *testing.T, c *LSPClient, info lsproto.RequestInfo[Params, Resp], params Params) func() (*lsproto.Message, Resp, bool) { +func (c *LSPClient) SendRequestAsync[Params, Resp any](t *testing.T, info lsproto.RequestInfo[Params, Resp], params Params) func() (*lsproto.Message, Resp, bool) { id := c.NextID() reqID := lsproto.NewID(lsproto.IntegerOrString{Integer: &id}) req := info.NewRequestMessage(reqID, params) @@ -314,7 +314,7 @@ func (c *LSPClient) waitForResponse(t *testing.T, reqID *jsonrpc.ID, responseCha } // SendNotification sends a typed notification. -func SendNotification[Params any](t *testing.T, c *LSPClient, info lsproto.NotificationInfo[Params], params Params) { +func (c *LSPClient) SendNotification[Params any](t *testing.T, info lsproto.NotificationInfo[Params], params Params) { notification := info.NewNotificationMessage( params, ) diff --git a/tsc/internal/tspath/path.go b/tsc/internal/tspath/path.go index 8b464c6752484..a8a15b88feda0 100644 --- a/tsc/internal/tspath/path.go +++ b/tsc/internal/tspath/path.go @@ -1130,8 +1130,8 @@ func ForEachAncestorDirectory[T any](directory string, callback func(directory s } } -func ForEachAncestorDirectoryPath[T any](directory Path, callback func(directory Path) (result T, stop bool)) (result T, ok bool) { - return ForEachAncestorDirectory(string(directory), func(directory string) (T, bool) { +func (p Path) ForEachAncestorDirectory[T any](callback func(directory Path) (result T, stop bool)) (result T, ok bool) { + return ForEachAncestorDirectory(string(p), func(directory string) (T, bool) { return callback(Path(directory)) }) } From 889b4614ee2fc465cf45cc2a34c54ace6b9ac514 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Sun, 30 Aug 2026 00:00:26 -0700 Subject: [PATCH 10/10] Update gofumpt dprint plugin --- .dprint.jsonc | 2 +- tsc/internal/ls/lsutil/formatcodeoptions.go | 24 ++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.dprint.jsonc b/.dprint.jsonc index 0bfc480fe4778..17978c58fc027 100644 --- a/.dprint.jsonc +++ b/.dprint.jsonc @@ -66,6 +66,6 @@ "npm:@dprint/typescript@0.96.1", "npm:@dprint/json@0.22.0", "npm:dprint-plugin-yaml@0.6.0", - "npm:@jakebailey/dprint-plugin-gofumpt@0.0.13" + "npm:@jakebailey/dprint-plugin-gofumpt@0.0.16" ] } diff --git a/tsc/internal/ls/lsutil/formatcodeoptions.go b/tsc/internal/ls/lsutil/formatcodeoptions.go index 73c8a899a63a1..fe39b21f4d1e6 100644 --- a/tsc/internal/ls/lsutil/formatcodeoptions.go +++ b/tsc/internal/ls/lsutil/formatcodeoptions.go @@ -113,18 +113,18 @@ func (settings FormatCodeSettings) ToLSFormatOptions() *lsproto.FormattingOption func GetDefaultFormatCodeSettings() FormatCodeSettings { return FormatCodeSettings{ - IndentSize: printer.GetDefaultIndentSize(), - TabSize: printer.GetDefaultIndentSize(), - NewLineCharacter: "\n", - ConvertTabsToSpaces: core.TSTrue, - IndentStyle: IndentStyleSmart, - TrimTrailingWhitespace: core.TSTrue, - InsertSpaceAfterConstructor: core.TSFalse, - InsertSpaceAfterCommaDelimiter: core.TSTrue, - InsertSpaceAfterSemicolonInForStatements: core.TSTrue, - InsertSpaceBeforeAndAfterBinaryOperators: core.TSTrue, - InsertSpaceAfterKeywordsInControlFlowStatements: core.TSTrue, - InsertSpaceAfterFunctionKeywordForAnonymousFunctions: core.TSFalse, + IndentSize: printer.GetDefaultIndentSize(), + TabSize: printer.GetDefaultIndentSize(), + NewLineCharacter: "\n", + ConvertTabsToSpaces: core.TSTrue, + IndentStyle: IndentStyleSmart, + TrimTrailingWhitespace: core.TSTrue, + InsertSpaceAfterConstructor: core.TSFalse, + InsertSpaceAfterCommaDelimiter: core.TSTrue, + InsertSpaceAfterSemicolonInForStatements: core.TSTrue, + InsertSpaceBeforeAndAfterBinaryOperators: core.TSTrue, + InsertSpaceAfterKeywordsInControlFlowStatements: core.TSTrue, + InsertSpaceAfterFunctionKeywordForAnonymousFunctions: core.TSFalse, InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: core.TSFalse, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: core.TSFalse, InsertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: core.TSTrue,