diff --git a/internal/compiler/program.go b/internal/compiler/program.go
index ce89aaa601..d9af5c7249 100644
--- a/internal/compiler/program.go
+++ b/internal/compiler/program.go
@@ -144,10 +144,19 @@ func (p *Program) GetParseFileRedirect(fileName string) string {
return p.projectReferenceFileMapper.getParseFileRedirect(ast.NewHasFileName(fileName, p.toPath(fileName)))
}
-func (p *Program) ForEachResolvedProjectReference(
- fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int),
-) {
- p.projectReferenceFileMapper.forEachResolvedProjectReference(fn)
+func (p *Program) GetResolvedProjectReferences() []*tsoptions.ParsedCommandLine {
+ return p.projectReferenceFileMapper.getResolvedProjectReferences()
+}
+
+func (p *Program) ForEachResolvedProjectReference(fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int) bool) bool {
+ return p.projectReferenceFileMapper.forEachResolvedProjectReference(fn)
+}
+
+func (p *Program) ForEachResolvedProjectReferenceInChildConfig(
+ childConfig *tsoptions.ParsedCommandLine,
+ fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int) bool,
+) bool {
+ return p.projectReferenceFileMapper.forEachResolvedProjectReferenceInChildConfig(childConfig, fn)
}
// UseCaseSensitiveFileNames implements checker.Program.
@@ -904,13 +913,13 @@ func (p *Program) verifyProjectReferences() {
p.programDiagnostics = append(p.programDiagnostics, diag)
}
- p.ForEachResolvedProjectReference(func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int) {
+ p.ForEachResolvedProjectReference(func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int) bool {
ref := parent.ProjectReferences()[index]
// !!! Deprecated in 5.0 and removed since 5.5
// verifyRemovedProjectReference(ref, parent, index);
if config == nil {
createDiagnosticForReference(parent, index, diagnostics.File_0_not_found, ref.Path)
- return
+ return false
}
refOptions := config.CompilerOptions()
if !refOptions.Composite.IsTrue() || refOptions.NoEmit.IsTrue() {
@@ -927,6 +936,7 @@ func (p *Program) verifyProjectReferences() {
createDiagnosticForReference(parent, index, diagnostics.Cannot_write_file_0_because_it_will_overwrite_tsbuildinfo_file_generated_by_referenced_project_1, buildInfoFileName, ref.Path)
p.hasEmitBlockingDiagnostics.Add(p.toPath(buildInfoFileName))
}
+ return false
})
}
diff --git a/internal/compiler/projectreferencefilemapper.go b/internal/compiler/projectreferencefilemapper.go
index 17649ec3e0..550d89cd95 100644
--- a/internal/compiler/projectreferencefilemapper.go
+++ b/internal/compiler/projectreferencefilemapper.go
@@ -46,6 +46,9 @@ func (mapper *projectReferenceFileMapper) getParseFileRedirect(file ast.HasFileN
}
func (mapper *projectReferenceFileMapper) getResolvedProjectReferences() []*tsoptions.ParsedCommandLine {
+ if mapper.opts.Config.ConfigFile == nil {
+ return nil
+ }
refs, ok := mapper.referencesInConfigFile[mapper.opts.Config.ConfigFile.SourceFile.Path()]
var result []*tsoptions.ParsedCommandLine
if ok {
@@ -107,31 +110,49 @@ func (mapper *projectReferenceFileMapper) getResolvedReferenceFor(path tspath.Pa
}
func (mapper *projectReferenceFileMapper) forEachResolvedProjectReference(
- fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int),
-) {
+ fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int) bool,
+) bool {
if mapper.opts.Config.ConfigFile == nil {
- return
+ return false
}
seenRef := collections.NewSetWithSizeHint[tspath.Path](len(mapper.referencesInConfigFile))
seenRef.Add(mapper.opts.Config.ConfigFile.SourceFile.Path())
refs := mapper.referencesInConfigFile[mapper.opts.Config.ConfigFile.SourceFile.Path()]
- mapper.forEachResolvedReferenceWorker(refs, fn, mapper.opts.Config, seenRef)
+ return mapper.forEachResolvedReferenceWorker(refs, fn, mapper.opts.Config, seenRef)
}
func (mapper *projectReferenceFileMapper) forEachResolvedReferenceWorker(
references []tspath.Path,
- fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int),
+ fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int) bool,
parent *tsoptions.ParsedCommandLine,
seenRef *collections.Set[tspath.Path],
-) {
+) bool {
for index, path := range references {
if !seenRef.AddIfAbsent(path) {
continue
}
config, _ := mapper.configToProjectReference[path]
- fn(path, config, parent, index)
- mapper.forEachResolvedReferenceWorker(mapper.referencesInConfigFile[path], fn, config, seenRef)
+ if fn(path, config, parent, index) {
+ return true
+ }
+ if mapper.forEachResolvedReferenceWorker(mapper.referencesInConfigFile[path], fn, config, seenRef) {
+ return true
+ }
}
+ return false
+}
+
+func (mapper *projectReferenceFileMapper) forEachResolvedProjectReferenceInChildConfig(
+ childConfig *tsoptions.ParsedCommandLine,
+ fn func(path tspath.Path, config *tsoptions.ParsedCommandLine, parent *tsoptions.ParsedCommandLine, index int) bool,
+) bool {
+ if childConfig == nil || childConfig.ConfigFile == nil {
+ return false
+ }
+ seenRef := collections.NewSetWithSizeHint[tspath.Path](len(mapper.referencesInConfigFile))
+ seenRef.Add(childConfig.ConfigFile.SourceFile.Path())
+ refs := mapper.referencesInConfigFile[childConfig.ConfigFile.SourceFile.Path()]
+ return mapper.forEachResolvedReferenceWorker(refs, fn, mapper.opts.Config, seenRef)
}
func (mapper *projectReferenceFileMapper) getSourceToDtsIfSymlink(file ast.HasFileName) *tsoptions.SourceOutputAndProjectReference {
diff --git a/internal/execute/tsctests/sys.go b/internal/execute/tsctests/sys.go
index a11f33865e..cd75405529 100644
--- a/internal/execute/tsctests/sys.go
+++ b/internal/execute/tsctests/sys.go
@@ -3,9 +3,7 @@ package tsctests
import (
"fmt"
"io"
- "io/fs"
"maps"
- "slices"
"strconv"
"strings"
"sync"
@@ -14,8 +12,10 @@ import (
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/compiler"
"github.com/microsoft/typescript-go/internal/core"
+ "github.com/microsoft/typescript-go/internal/execute"
"github.com/microsoft/typescript-go/internal/execute/incremental"
"github.com/microsoft/typescript-go/internal/execute/tsc"
+ "github.com/microsoft/typescript-go/internal/testutil/fsbaselineutil"
"github.com/microsoft/typescript-go/internal/testutil/harnessutil"
"github.com/microsoft/typescript-go/internal/testutil/stringtestutil"
"github.com/microsoft/typescript-go/internal/tsoptions"
@@ -95,6 +95,20 @@ func NewTscSystem(files FileMap, useCaseSensitiveFileNames bool, cwd string) *Te
}
}
+func GetFileMapWithBuild(files FileMap, commandLineArgs []string) FileMap {
+ sys := newTestSys(&tscInput{
+ files: maps.Clone(files),
+ }, false)
+ execute.CommandLine(sys, commandLineArgs, sys)
+ sys.fs.writtenFiles.Range(func(key string) bool {
+ if text, ok := sys.fsFromFileMap().ReadFile(key); ok {
+ files[key] = text
+ }
+ return true
+ })
+ return files
+}
+
func newTestSys(tscInput *tscInput, forIncrementalCorrectness bool) *TestSys {
cwd := tscInput.cwd
if cwd == "" {
@@ -114,6 +128,11 @@ func newTestSys(tscInput *tscInput, forIncrementalCorrectness bool) *TestSys {
}, currentWrite)
sys.env = tscInput.env
sys.forIncrementalCorrectness = forIncrementalCorrectness
+ sys.fsDiffer = &fsbaselineutil.FSDiffer{
+ FS: sys.fs.FS.(iovfs.FsWithSys),
+ DefaultLibs: func() *collections.SyncSet[string] { return sys.fs.defaultLibs },
+ WrittenFiles: &sys.fs.writtenFiles,
+ }
// Ensure the default library file is present
sys.ensureLibPathExists("lib.d.ts")
@@ -126,24 +145,12 @@ func newTestSys(tscInput *tscInput, forIncrementalCorrectness bool) *TestSys {
return sys
}
-type diffEntry struct {
- content string
- mTime time.Time
- isWritten bool
- symlinkTarget string
-}
-
-type snapshot struct {
- snap map[string]*diffEntry
- defaultLibs *collections.SyncSet[string]
-}
-
type TestSys struct {
currentWrite *strings.Builder
programBaselines strings.Builder
programIncludeBaselines strings.Builder
tracer *harnessutil.TracerForBaselining
- serializedDiff *snapshot
+ fsDiffer *fsbaselineutil.FSDiffer
forIncrementalCorrectness bool
fs *testFs
@@ -171,11 +178,11 @@ func (s *TestSys) FS() vfs.FS {
}
func (s *TestSys) fsFromFileMap() iovfs.FsWithSys {
- return s.fs.FS.(iovfs.FsWithSys)
+ return s.fsDiffer.FS
}
func (s *TestSys) mapFs() *vfstest.MapFS {
- return s.fsFromFileMap().FSys().(*vfstest.MapFS)
+ return s.fsDiffer.MapFs()
}
func (s *TestSys) ensureLibPathExists(path string) {
@@ -223,8 +230,8 @@ func (s *TestSys) OnEmittedFiles(result *compiler.EmitResult, mTimesCache *colle
if result != nil {
for _, file := range result.EmittedFiles {
modTime := s.mapFs().GetModTime(file)
- if s.serializedDiff != nil {
- if diff, ok := s.serializedDiff.snap[file]; ok && diff.mTime.Equal(modTime) {
+ if serializedDiff := s.fsDiffer.SerializedDiff(); serializedDiff != nil {
+ if diff, ok := serializedDiff.Snap[file]; ok && diff.MTime.Equal(modTime) {
// Even though written, timestamp was reverted
continue
}
@@ -500,83 +507,7 @@ func (s *TestSys) clearOutput() {
}
func (s *TestSys) baselineFSwithDiff(baseline io.Writer) {
- // todo: baselines the entire fs, possibly doesn't correctly diff all cases of emitted files, since emit isn't fully implemented and doesn't always emit the same way as strada
- snap := map[string]*diffEntry{}
-
- diffs := map[string]string{}
-
- for path, file := range s.mapFs().Entries() {
- if file.Mode&fs.ModeSymlink != 0 {
- target, ok := s.mapFs().GetTargetOfSymlink(path)
- if !ok {
- panic("Failed to resolve symlink target: " + path)
- }
- newEntry := &diffEntry{symlinkTarget: target}
- snap[path] = newEntry
- s.addFsEntryDiff(diffs, newEntry, path)
- continue
- } else if file.Mode.IsRegular() {
- newEntry := &diffEntry{content: string(file.Data), mTime: file.ModTime, isWritten: s.fs.writtenFiles.Has(path)}
- snap[path] = newEntry
- s.addFsEntryDiff(diffs, newEntry, path)
- }
- }
- if s.serializedDiff != nil {
- for path := range s.serializedDiff.snap {
- if fileInfo := s.mapFs().GetFileInfo(path); fileInfo == nil {
- // report deleted
- s.addFsEntryDiff(diffs, nil, path)
- }
- }
- }
- var defaultLibs collections.SyncSet[string]
- if s.fs.defaultLibs != nil {
- s.fs.defaultLibs.Range(func(libPath string) bool {
- defaultLibs.Add(libPath)
- return true
- })
- }
- s.serializedDiff = &snapshot{
- snap: snap,
- defaultLibs: &defaultLibs,
- }
- diffKeys := slices.Collect(maps.Keys(diffs))
- slices.Sort(diffKeys)
- for _, path := range diffKeys {
- fmt.Fprint(baseline, "//// ["+path+"] ", diffs[path], "\n")
- }
- fmt.Fprintln(baseline)
- s.fs.writtenFiles = collections.SyncSet[string]{} // Reset written files after baseline
-}
-
-func (s *TestSys) addFsEntryDiff(diffs map[string]string, newDirContent *diffEntry, path string) {
- var oldDirContent *diffEntry
- var defaultLibs *collections.SyncSet[string]
- if s.serializedDiff != nil {
- oldDirContent = s.serializedDiff.snap[path]
- defaultLibs = s.serializedDiff.defaultLibs
- }
- // todo handle more cases of fs changes
- if oldDirContent == nil {
- if s.fs.defaultLibs == nil || !s.fs.defaultLibs.Has(path) {
- if newDirContent.symlinkTarget != "" {
- diffs[path] = "-> " + newDirContent.symlinkTarget + " *new*"
- } else {
- diffs[path] = "*new* \n" + newDirContent.content
- }
- }
- } else if newDirContent == nil {
- diffs[path] = "*deleted*"
- } else if newDirContent.content != oldDirContent.content {
- diffs[path] = "*modified* \n" + newDirContent.content
- } else if newDirContent.isWritten {
- diffs[path] = "*rewrite with same content*"
- } else if newDirContent.mTime != oldDirContent.mTime {
- diffs[path] = "*mTime changed*"
- } else if defaultLibs != nil && defaultLibs.Has(path) && s.fs.defaultLibs != nil && !s.fs.defaultLibs.Has(path) {
- // Lib file that was read
- diffs[path] = "*Lib*\n" + newDirContent.content
- }
+ s.fsDiffer.BaselineFSwithDiff(baseline)
}
func (s *TestSys) writeFileNoError(path string, content string, writeByteOrderMark bool) {
diff --git a/internal/fourslash/_scripts/updateFailing.mts b/internal/fourslash/_scripts/updateFailing.mts
index 85de8e8cf1..f4282e7588 100644
--- a/internal/fourslash/_scripts/updateFailing.mts
+++ b/internal/fourslash/_scripts/updateFailing.mts
@@ -13,7 +13,7 @@ function main() {
const go = which.sync("go");
let testOutput: string;
try {
- testOutput = cp.execFileSync(go, ["test", "./internal/fourslash/tests/gen"], { encoding: "utf-8" });
+ testOutput = cp.execFileSync(go, ["test", "-v", "./internal/fourslash/tests/gen"], { encoding: "utf-8" });
}
catch (error) {
testOutput = (error as { stdout: string; }).stdout as string;
@@ -21,7 +21,7 @@ function main() {
const panicRegex = /^panic/m;
if (panicRegex.test(testOutput)) {
fs.writeFileSync(failingTestsPath, oldFailingTests, "utf-8");
- throw new Error("Unrecovered panic detected in tests");
+ throw new Error("Unrecovered panic detected in tests\n" + testOutput);
}
const failRegex = /--- FAIL: ([\S]+)/gm;
const failingTests: string[] = [];
diff --git a/internal/fourslash/baselineutil.go b/internal/fourslash/baselineutil.go
index 84ffc4e747..12a638dc88 100644
--- a/internal/fourslash/baselineutil.go
+++ b/internal/fourslash/baselineutil.go
@@ -2,9 +2,7 @@ package fourslash
import (
"cmp"
- "errors"
"fmt"
- "io/fs"
"regexp"
"slices"
"strings"
@@ -12,12 +10,10 @@ import (
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
- "github.com/microsoft/typescript-go/internal/debug"
- "github.com/microsoft/typescript-go/internal/ls/lsconv"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/stringutil"
"github.com/microsoft/typescript-go/internal/testutil/baseline"
- "github.com/microsoft/typescript-go/internal/vfs"
+ "github.com/microsoft/typescript-go/internal/testutil/lsptestutil"
)
func (f *FourslashTest) addResultToBaseline(t *testing.T, command string, actual string) {
@@ -122,380 +118,8 @@ func normalizeCommandName(command string) string {
return stringutil.LowerFirstChar(command)
}
-type baselineFourslashLocationsOptions struct {
- // markerInfo
- marker MarkerOrRange // location
- markerName string // name of the marker to be printed in baseline
-
- endMarker string
-
- startMarkerPrefix func(span lsproto.Location) *string
- endMarkerSuffix func(span lsproto.Location) *string
-
- additionalLocation *lsproto.Location
-}
-
-func (f *FourslashTest) getBaselineForLocationsWithFileContents(spans []lsproto.Location, options baselineFourslashLocationsOptions) string {
- locationsByFile := collections.GroupBy(spans, func(span lsproto.Location) lsproto.DocumentUri { return span.Uri })
- rangesByFile := collections.MultiMap[lsproto.DocumentUri, lsproto.Range]{}
- for file, locs := range locationsByFile.M {
- for _, loc := range locs {
- rangesByFile.Add(file, loc.Range)
- }
- }
- return f.getBaselineForGroupedLocationsWithFileContents(
- &rangesByFile,
- options,
- )
-}
-
-func (f *FourslashTest) getBaselineForGroupedLocationsWithFileContents(groupedRanges *collections.MultiMap[lsproto.DocumentUri, lsproto.Range], options baselineFourslashLocationsOptions) string {
- // We must always print the file containing the marker,
- // but don't want to print it twice at the end if it already
- // found in a file with ranges.
- foundMarker := false
- foundAdditionalLocation := false
-
- baselineEntries := []string{}
- err := f.vfs.WalkDir("/", func(path string, d vfs.DirEntry, e error) error {
- if e != nil {
- return e
- }
-
- if !d.Type().IsRegular() {
- return nil
- }
-
- fileName := lsconv.FileNameToDocumentURI(path)
- ranges := groupedRanges.Get(fileName)
- if len(ranges) == 0 {
- return nil
- }
-
- content, ok := f.vfs.ReadFile(path)
- if !ok {
- // !!! error?
- return nil
- }
-
- if options.marker != nil && options.marker.FileName() == path {
- foundMarker = true
- }
-
- if options.additionalLocation != nil && options.additionalLocation.Uri == fileName {
- foundAdditionalLocation = true
- }
-
- baselineEntries = append(baselineEntries, f.getBaselineContentForFile(path, content, ranges, nil, options))
- return nil
- })
-
- if err != nil && !errors.Is(err, fs.ErrNotExist) {
- panic("walkdir error during fourslash baseline: " + err.Error())
- }
-
- // In Strada, there is a bug where we only ever add additional spans to baselines if we haven't
- // already added the file to the baseline.
- if options.additionalLocation != nil && !foundAdditionalLocation {
- fileName := options.additionalLocation.Uri.FileName()
- if content, ok := f.vfs.ReadFile(fileName); ok {
- baselineEntries = append(
- baselineEntries,
- f.getBaselineContentForFile(fileName, content, []lsproto.Range{options.additionalLocation.Range}, nil, options),
- )
- if options.marker != nil && options.marker.FileName() == fileName {
- foundMarker = true
- }
- }
- }
-
- if !foundMarker && options.marker != nil {
- // If we didn't find the marker in any file, we need to add it.
- markerFileName := options.marker.FileName()
- if content, ok := f.vfs.ReadFile(markerFileName); ok {
- baselineEntries = append(baselineEntries, f.getBaselineContentForFile(markerFileName, content, nil, nil, options))
- }
- }
-
- // !!! skipDocumentContainingOnlyMarker
-
- return strings.Join(baselineEntries, "\n\n")
-}
-
-type baselineDetail struct {
- pos lsproto.Position
- positionMarker string
- span *lsproto.Range
- kind string
-}
-
-func (f *FourslashTest) getBaselineContentForFile(
- fileName string,
- content string,
- spansInFile []lsproto.Range,
- spanToContextId map[lsproto.Range]int,
- options baselineFourslashLocationsOptions,
-) string {
- details := []*baselineDetail{}
- detailPrefixes := map[*baselineDetail]string{}
- detailSuffixes := map[*baselineDetail]string{}
- canDetermineContextIdInline := true
- uri := lsconv.FileNameToDocumentURI(fileName)
-
- if options.marker != nil && options.marker.FileName() == fileName {
- details = append(details, &baselineDetail{pos: options.marker.LSPos(), positionMarker: options.markerName})
- }
-
- for _, span := range spansInFile {
- textSpanIndex := len(details)
- details = append(details,
- &baselineDetail{pos: span.Start, positionMarker: "[|", span: &span, kind: "textStart"},
- &baselineDetail{pos: span.End, positionMarker: core.OrElse(options.endMarker, "|]"), span: &span, kind: "textEnd"},
- )
-
- if options.startMarkerPrefix != nil {
- startPrefix := options.startMarkerPrefix(lsproto.Location{Uri: uri, Range: span})
- if startPrefix != nil {
- // Special case: if this span starts at the same position as the provided marker,
- // we want the span's prefix to appear before the marker name.
- // i.e. We want `/*START PREFIX*/A: /*RENAME*/[|ARENAME|]`,
- // not `/*RENAME*//*START PREFIX*/A: [|ARENAME|]`
- if options.marker != nil && fileName == options.marker.FileName() && span.Start == options.marker.LSPos() {
- _, ok := detailPrefixes[details[0]]
- debug.Assert(!ok, "Expected only single prefix at marker location")
- detailPrefixes[details[0]] = *startPrefix
- } else {
- detailPrefixes[details[textSpanIndex]] = *startPrefix
- }
- }
- }
-
- if options.endMarkerSuffix != nil {
- endSuffix := options.endMarkerSuffix(lsproto.Location{Uri: uri, Range: span})
- if endSuffix != nil {
- detailSuffixes[details[textSpanIndex+1]] = *endSuffix
- }
- }
- }
-
- slices.SortStableFunc(details, func(d1, d2 *baselineDetail) int {
- return lsproto.ComparePositions(d1.pos, d2.pos)
- })
- // !!! if canDetermineContextIdInline
-
- textWithContext := newTextWithContext(fileName, content)
-
- // Our preferred way to write marker is
- // /*MARKER*/[| some text |]
- // [| some /*MARKER*/ text |]
- // [| some text |]/*MARKER*/
- // Stable sort should handle first two cases but with that marker will be before rangeEnd if locations match
- // So we will defer writing marker in this case by checking and finding index of rangeEnd if same
- var deferredMarkerIndex *int
-
- for index, detail := range details {
- if detail.span == nil && deferredMarkerIndex == nil {
- // If this is marker position and its same as textEnd and/or contextEnd we want to write marker after those
- for matchingEndPosIndex := index + 1; matchingEndPosIndex < len(details); matchingEndPosIndex++ {
- // Defer after the location if its same as rangeEnd
- if details[matchingEndPosIndex].pos == detail.pos && strings.HasSuffix(details[matchingEndPosIndex].kind, "End") {
- deferredMarkerIndex = ptrTo(matchingEndPosIndex)
- }
- // Dont defer further than already determined
- break
- }
- // Defer writing marker position to deffered marker index
- if deferredMarkerIndex != nil {
- continue
- }
- }
- textWithContext.add(detail)
- textWithContext.pos = detail.pos
- // Prefix
- prefix := detailPrefixes[detail]
- if prefix != "" {
- textWithContext.newContent.WriteString(prefix)
- }
- textWithContext.newContent.WriteString(detail.positionMarker)
- if detail.span != nil {
- switch detail.kind {
- case "textStart":
- var text string
- if contextId, ok := spanToContextId[*detail.span]; ok {
- isAfterContextStart := false
- for textStartIndex := index - 1; textStartIndex >= 0; textStartIndex-- {
- textStartDetail := details[textStartIndex]
- if textStartDetail.kind == "contextStart" && textStartDetail.span == detail.span {
- isAfterContextStart = true
- break
- }
- // Marker is ok to skip over
- if textStartDetail.span != nil {
- break
- }
- }
- // Skip contextId on span thats surrounded by context span immediately
- if !isAfterContextStart {
- if text == "" {
- text = fmt.Sprintf(`contextId: %v`, contextId)
- } else {
- text = fmt.Sprintf(`contextId: %v`, contextId) + `, ` + text
- }
- }
- }
- if text != "" {
- textWithContext.newContent.WriteString(`{ ` + text + ` |}`)
- }
- case "contextStart":
- if canDetermineContextIdInline {
- spanToContextId[*detail.span] = len(spanToContextId)
- }
- }
-
- if deferredMarkerIndex != nil && *deferredMarkerIndex == index {
- // Write the marker
- textWithContext.newContent.WriteString(options.markerName)
- deferredMarkerIndex = nil
- detail = details[0] // Marker detail
- }
- }
- if suffix, ok := detailSuffixes[detail]; ok {
- textWithContext.newContent.WriteString(suffix)
- }
- }
- textWithContext.add(nil)
- if textWithContext.newContent.Len() != 0 {
- textWithContext.readableContents.WriteString("\n")
- textWithContext.readableJsoncBaseline(textWithContext.newContent.String())
- }
- return textWithContext.readableContents.String()
-}
-
-var lineSplitter = regexp.MustCompile(`\r?\n`)
-
-type textWithContext struct {
- nLinesContext int // number of context lines to write to baseline
-
- readableContents *strings.Builder // builds what will be returned to be written to baseline
-
- newContent *strings.Builder // helper; the part of the original file content to write between details
- pos lsproto.Position
- isLibFile bool
- fileName string
- content string // content of the original file
- lineStarts *lsconv.LSPLineMap
- converters *lsconv.Converters
-
- // posLineInfo
- posInfo *lsproto.Position
- lineInfo int
-}
-
-// implements lsconv.Script
-func (t *textWithContext) FileName() string {
- return t.fileName
-}
-
-// implements lsconv.Script
-func (t *textWithContext) Text() string {
- return t.content
-}
-
-func newTextWithContext(fileName string, content string) *textWithContext {
- t := &textWithContext{
- nLinesContext: 4,
-
- readableContents: &strings.Builder{},
-
- isLibFile: regexp.MustCompile(`lib.*\.d\.ts$`).MatchString(fileName),
- newContent: &strings.Builder{},
- pos: lsproto.Position{Line: 0, Character: 0},
- fileName: fileName,
- content: content,
- lineStarts: lsconv.ComputeLSPLineStarts(content),
- }
-
- t.converters = lsconv.NewConverters(lsproto.PositionEncodingKindUTF8, func(_ string) *lsconv.LSPLineMap {
- return t.lineStarts
- })
- t.readableContents.WriteString("// === " + fileName + " ===")
- return t
-}
-
-func (t *textWithContext) add(detail *baselineDetail) {
- if t.content == "" && detail == nil {
- panic("Unsupported")
- }
- if detail == nil || (detail.kind != "textEnd" && detail.kind != "contextEnd") {
- // Calculate pos to location number of lines
- posLineIndex := t.lineInfo
- if t.posInfo == nil || *t.posInfo != t.pos {
- posLineIndex = t.lineStarts.ComputeIndexOfLineStart(t.converters.LineAndCharacterToPosition(t, t.pos))
- }
-
- locationLineIndex := len(t.lineStarts.LineStarts) - 1
- if detail != nil {
- locationLineIndex = t.lineStarts.ComputeIndexOfLineStart(t.converters.LineAndCharacterToPosition(t, detail.pos))
- t.posInfo = &detail.pos
- t.lineInfo = locationLineIndex
- }
-
- nLines := 0
- if t.newContent.Len() != 0 {
- nLines += t.nLinesContext + 1
- }
- if detail != nil {
- nLines += t.nLinesContext + 1
- }
- // first nLinesContext and last nLinesContext
- if locationLineIndex-posLineIndex > nLines {
- if t.newContent.Len() != 0 {
- var skippedString string
- if t.isLibFile {
- skippedString = "--- (line: --) skipped ---\n"
- } else {
- skippedString = fmt.Sprintf(`// --- (line: %v) skipped ---`, posLineIndex+t.nLinesContext+1)
- }
-
- t.readableContents.WriteString("\n")
- t.readableJsoncBaseline(t.newContent.String() + t.sliceOfContent(
- t.getIndex(t.pos),
- t.getIndex(t.lineStarts.LineStarts[posLineIndex+t.nLinesContext]),
- ) + skippedString)
-
- if detail != nil {
- t.readableContents.WriteString("\n")
- }
- t.newContent.Reset()
- }
- if detail != nil {
- if t.isLibFile {
- t.newContent.WriteString("--- (line: --) skipped ---\n")
- } else {
- t.newContent.WriteString(fmt.Sprintf("--- (line: %v) skipped ---\n", locationLineIndex-t.nLinesContext+1))
- }
- t.newContent.WriteString(t.sliceOfContent(
- t.getIndex(t.lineStarts.LineStarts[locationLineIndex-t.nLinesContext+1]),
- t.getIndex(detail.pos),
- ))
- }
- return
- }
- }
- if detail == nil {
- t.newContent.WriteString(t.sliceOfContent(t.getIndex(t.pos), nil))
- } else {
- t.newContent.WriteString(t.sliceOfContent(t.getIndex(t.pos), t.getIndex(detail.pos)))
- }
-}
-
-func (t *textWithContext) readableJsoncBaseline(text string) {
- for i, line := range lineSplitter.Split(text, -1) {
- if i > 0 {
- t.readableContents.WriteString("\n")
- }
- t.readableContents.WriteString(`// ` + line)
- }
+func (f *FourslashTest) getBaselineForLocationsWithFileContents(spans []lsproto.Location, options lsptestutil.BaselineLocationsOptions) string {
+ return lsptestutil.GetBaselineForLocationsWithFileContents(f.FS, spans, options)
}
type markerAndItem[T any] struct {
@@ -546,7 +170,7 @@ func annotateContentWithTooltips[T comparable](
fileName := marker.FileName()
lines, ok := filesToLines.Get(fileName)
if !ok {
- lines = lineSplitter.Split(f.getScriptInfo(fileName).content, -1)
+ lines = lsptestutil.LineSplitter.Split(f.getScriptInfo(fileName).content, -1)
}
var tooltipLines []string
@@ -596,40 +220,6 @@ func annotateContentWithTooltips[T comparable](
return builder.String()
}
-func (t *textWithContext) sliceOfContent(start *int, end *int) string {
- if start == nil || *start < 0 {
- start = ptrTo(0)
- }
-
- if end == nil || *end > len(t.content) {
- end = ptrTo(len(t.content))
- }
-
- if *start > *end {
- return ""
- }
-
- return t.content[*start:*end]
-}
-
-func (t *textWithContext) getIndex(i any) *int {
- switch i := i.(type) {
- case *int:
- return i
- case int:
- return ptrTo(i)
- case core.TextPos:
- return ptrTo(int(i))
- case *core.TextPos:
- return ptrTo(int(*i))
- case lsproto.Position:
- return t.getIndex(t.converters.LineAndCharacterToPosition(t, i))
- case *lsproto.Position:
- return t.getIndex(t.converters.LineAndCharacterToPosition(t, *i))
- }
- panic(fmt.Sprintf("getIndex: unsupported type %T", i))
-}
-
func codeFence(lang string, code string) string {
return "```" + lang + "\n" + code + "\n```"
}
diff --git a/internal/fourslash/fourslash.go b/internal/fourslash/fourslash.go
index 1b78246b62..2e77267349 100644
--- a/internal/fourslash/fourslash.go
+++ b/internal/fourslash/fourslash.go
@@ -1,16 +1,13 @@
package fourslash
import (
- "context"
"fmt"
- "io"
"maps"
"slices"
"strings"
"testing"
"unicode/utf8"
- "github.com/go-json-experiment/json"
"github.com/google/go-cmp/cmp"
"github.com/microsoft/typescript-go/internal/bundled"
"github.com/microsoft/typescript-go/internal/collections"
@@ -18,25 +15,20 @@ import (
"github.com/microsoft/typescript-go/internal/ls"
"github.com/microsoft/typescript-go/internal/ls/lsconv"
"github.com/microsoft/typescript-go/internal/ls/lsutil"
- "github.com/microsoft/typescript-go/internal/lsp"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/project"
"github.com/microsoft/typescript-go/internal/repo"
"github.com/microsoft/typescript-go/internal/stringutil"
"github.com/microsoft/typescript-go/internal/testutil/baseline"
"github.com/microsoft/typescript-go/internal/testutil/harnessutil"
+ "github.com/microsoft/typescript-go/internal/testutil/lsptestutil"
"github.com/microsoft/typescript-go/internal/tspath"
- "github.com/microsoft/typescript-go/internal/vfs"
"github.com/microsoft/typescript-go/internal/vfs/vfstest"
"gotest.tools/v3/assert"
)
type FourslashTest struct {
- server *lsp.Server
- in *lspWriter
- out *lspReader
- id int32
- vfs vfs.FS
+ lsptestutil.TestLspServer
testData *TestData // !!! consolidate test files from test data and script info
baselines map[string]*strings.Builder
@@ -45,7 +37,6 @@ type FourslashTest struct {
scriptInfos map[string]*scriptInfo
converters *lsconv.Converters
- userPreferences *lsutil.UserPreferences
currentCaretPosition lsproto.Position
lastKnownMarkerName *string
activeFilename string
@@ -82,41 +73,6 @@ func (s *scriptInfo) FileName() string {
return s.fileName
}
-type lspReader struct {
- c <-chan *lsproto.Message
-}
-
-func (r *lspReader) Read() (*lsproto.Message, error) {
- msg, ok := <-r.c
- if !ok {
- return nil, io.EOF
- }
- return msg, nil
-}
-
-type lspWriter struct {
- c chan<- *lsproto.Message
-}
-
-func (w *lspWriter) Write(msg *lsproto.Message) error {
- w.c <- msg
- return nil
-}
-
-func (r *lspWriter) Close() {
- close(r.c)
-}
-
-var (
- _ lsp.Reader = (*lspReader)(nil)
- _ lsp.Writer = (*lspWriter)(nil)
-)
-
-func newLSPPipe() (*lspReader, *lspWriter) {
- c := make(chan *lsproto.Message, 100)
- return &lspReader{c: c}, &lspWriter{c: c}
-}
-
const rootDir = "/"
var parseCache = project.ParseCache{
@@ -146,34 +102,14 @@ func NewFourslash(t *testing.T, capabilities *lsproto.ClientCapabilities, conten
SkipDefaultLibCheck: core.TSTrue,
}
harnessutil.SetCompilerOptionsFromTestConfig(t, testData.GlobalOptions, compilerOptions, rootDir)
-
- inputReader, inputWriter := newLSPPipe()
- outputReader, outputWriter := newLSPPipe()
fs := bundled.WrapFS(vfstest.FromMap(testfs, true /*useCaseSensitiveFileNames*/))
-
- var err strings.Builder
- server := lsp.NewServer(&lsp.ServerOptions{
- In: inputReader,
- Out: outputWriter,
- Err: &err,
-
- Cwd: "/",
- FS: fs,
- DefaultLibraryPath: bundled.LibPath(),
-
- ParseCache: &parseCache,
+ lspTestServer := lsptestutil.NewTestLspServer(t, &lsptestutil.TestLspServerOptions{
+ FS: fs,
+ ParseCache: &parseCache,
+ OptionsForInferredProject: compilerOptions,
+ Capabilities: capabilities,
})
- go func() {
- defer func() {
- outputWriter.Close()
- }()
- err := server.Run(context.TODO())
- if err != nil {
- t.Error("server error:", err)
- }
- }()
-
converters := lsconv.NewConverters(lsproto.PositionEncodingKindUTF8, func(fileName string) *lsconv.LSPLineMap {
scriptInfo, ok := scriptInfos[fileName]
if !ok {
@@ -183,28 +119,19 @@ func NewFourslash(t *testing.T, capabilities *lsproto.ClientCapabilities, conten
})
f := &FourslashTest{
- server: server,
- in: inputWriter,
- out: outputReader,
- testData: &testData,
- userPreferences: lsutil.NewDefaultUserPreferences(), // !!! parse default preferences for fourslash case?
- vfs: fs,
- scriptInfos: scriptInfos,
- converters: converters,
- baselines: make(map[string]*strings.Builder),
- }
-
- // !!! temporary; remove when we have `handleDidChangeConfiguration`/implicit project config support
- // !!! replace with a proper request *after initialize*
- f.server.SetCompilerOptionsForInferredProjects(t.Context(), compilerOptions)
- f.initialize(t, capabilities)
+ TestLspServer: *lspTestServer,
+ testData: &testData,
+ scriptInfos: scriptInfos,
+ converters: converters,
+ baselines: make(map[string]*strings.Builder),
+ }
+
for _, file := range testData.Files {
f.openFile(t, file.fileName)
}
f.activeFilename = f.testData.Files[0].fileName
t.Cleanup(func() {
- inputWriter.Close()
f.verifyBaselines(t)
})
return f
@@ -215,187 +142,23 @@ func getBaseFileNameFromTest(t *testing.T) string {
return stringutil.LowerFirstChar(name)
}
-func (f *FourslashTest) nextID() int32 {
- id := f.id
- f.id++
- return id
-}
-
-func (f *FourslashTest) initialize(t *testing.T, capabilities *lsproto.ClientCapabilities) {
- params := &lsproto.InitializeParams{
- Locale: ptrTo("en-US"),
- }
- params.Capabilities = getCapabilitiesWithDefaults(capabilities)
- // !!! check for errors?
- sendRequest(t, f, lsproto.InitializeInfo, params)
- sendNotification(t, f, lsproto.InitializedInfo, &lsproto.InitializedParams{})
-}
-
-var (
- ptrTrue = ptrTo(true)
- defaultCompletionCapabilities = &lsproto.CompletionClientCapabilities{
- CompletionItem: &lsproto.ClientCompletionItemOptions{
- SnippetSupport: ptrTrue,
- CommitCharactersSupport: ptrTrue,
- PreselectSupport: ptrTrue,
- LabelDetailsSupport: ptrTrue,
- InsertReplaceSupport: ptrTrue,
- DocumentationFormat: &[]lsproto.MarkupKind{lsproto.MarkupKindMarkdown, lsproto.MarkupKindPlainText},
- },
- CompletionList: &lsproto.CompletionListCapabilities{
- ItemDefaults: &[]string{"commitCharacters", "editRange"},
- },
- }
- defaultDefinitionCapabilities = &lsproto.DefinitionClientCapabilities{
- LinkSupport: ptrTrue,
- }
- defaultTypeDefinitionCapabilities = &lsproto.TypeDefinitionClientCapabilities{
- LinkSupport: ptrTrue,
- }
- defaultHoverCapabilities = &lsproto.HoverClientCapabilities{
- ContentFormat: &[]lsproto.MarkupKind{lsproto.MarkupKindMarkdown, lsproto.MarkupKindPlainText},
- }
-)
-
-func getCapabilitiesWithDefaults(capabilities *lsproto.ClientCapabilities) *lsproto.ClientCapabilities {
- var capabilitiesWithDefaults lsproto.ClientCapabilities
- if capabilities != nil {
- capabilitiesWithDefaults = *capabilities
- }
- capabilitiesWithDefaults.General = &lsproto.GeneralClientCapabilities{
- PositionEncodings: &[]lsproto.PositionEncodingKind{lsproto.PositionEncodingKindUTF8},
- }
- if capabilitiesWithDefaults.TextDocument == nil {
- capabilitiesWithDefaults.TextDocument = &lsproto.TextDocumentClientCapabilities{}
- }
- if capabilitiesWithDefaults.TextDocument.Completion == nil {
- capabilitiesWithDefaults.TextDocument.Completion = defaultCompletionCapabilities
- }
- if capabilitiesWithDefaults.TextDocument.Diagnostic == nil {
- capabilitiesWithDefaults.TextDocument.Diagnostic = &lsproto.DiagnosticClientCapabilities{
- RelatedInformation: ptrTrue,
- TagSupport: &lsproto.ClientDiagnosticsTagOptions{
- ValueSet: []lsproto.DiagnosticTag{
- lsproto.DiagnosticTagUnnecessary,
- lsproto.DiagnosticTagDeprecated,
- },
- },
- }
- }
- if capabilitiesWithDefaults.TextDocument.PublishDiagnostics == nil {
- capabilitiesWithDefaults.TextDocument.PublishDiagnostics = &lsproto.PublishDiagnosticsClientCapabilities{
- RelatedInformation: ptrTrue,
- TagSupport: &lsproto.ClientDiagnosticsTagOptions{
- ValueSet: []lsproto.DiagnosticTag{
- lsproto.DiagnosticTagUnnecessary,
- lsproto.DiagnosticTagDeprecated,
- },
- },
- }
- }
- if capabilitiesWithDefaults.Workspace == nil {
- capabilitiesWithDefaults.Workspace = &lsproto.WorkspaceClientCapabilities{}
- }
- if capabilitiesWithDefaults.Workspace.Configuration == nil {
- capabilitiesWithDefaults.Workspace.Configuration = ptrTrue
- }
- if capabilitiesWithDefaults.TextDocument.Definition == nil {
- capabilitiesWithDefaults.TextDocument.Definition = defaultDefinitionCapabilities
- }
- if capabilitiesWithDefaults.TextDocument.TypeDefinition == nil {
- capabilitiesWithDefaults.TextDocument.TypeDefinition = defaultTypeDefinitionCapabilities
- }
- if capabilitiesWithDefaults.TextDocument.Hover == nil {
- capabilitiesWithDefaults.TextDocument.Hover = defaultHoverCapabilities
- }
- if capabilitiesWithDefaults.TextDocument.SignatureHelp == nil {
- capabilitiesWithDefaults.TextDocument.SignatureHelp = &lsproto.SignatureHelpClientCapabilities{
- SignatureInformation: &lsproto.ClientSignatureInformationOptions{
- DocumentationFormat: &[]lsproto.MarkupKind{lsproto.MarkupKindMarkdown, lsproto.MarkupKindPlainText},
- ParameterInformation: &lsproto.ClientSignatureParameterInformationOptions{
- LabelOffsetSupport: ptrTrue,
- },
- ActiveParameterSupport: ptrTrue,
- },
- ContextSupport: ptrTrue,
- }
- }
- return &capabilitiesWithDefaults
-}
-
func sendRequest[Params, Resp any](t *testing.T, f *FourslashTest, info lsproto.RequestInfo[Params, Resp], params Params) (*lsproto.Message, Resp, bool) {
- id := f.nextID()
- req := lsproto.NewRequestMessage(
- info.Method,
- lsproto.NewID(lsproto.IntegerOrString{Integer: &id}),
- params,
- )
- f.writeMsg(t, req.Message())
- resp := f.readMsg(t)
- if resp == nil {
- return nil, *new(Resp), false
- }
-
- // currently, the only request that may be sent by the server during a client request is one `config` request
- // !!! remove if `config` is handled in initialization and there are no other server-initiated requests
- if resp.Kind == lsproto.MessageKindRequest {
- req := resp.AsRequest()
- switch req.Method {
- case lsproto.MethodWorkspaceConfiguration:
- req := lsproto.ResponseMessage{
- ID: req.ID,
- JSONRPC: req.JSONRPC,
- Result: []any{f.userPreferences},
- }
- f.writeMsg(t, req.Message())
- resp = f.readMsg(t)
- default:
- // other types of requests not yet used in fourslash; implement them if needed
- t.Fatalf("Unexpected request received: %s", req.Method)
- }
- }
-
- if resp == nil {
- return nil, *new(Resp), false
- }
- result, ok := resp.AsResponse().Result.(Resp)
- return resp, result, ok
+ return lsptestutil.SendRequest(t, &f.TestLspServer, info, params)
}
func sendNotification[Params any](t *testing.T, f *FourslashTest, info lsproto.NotificationInfo[Params], params Params) {
- notification := lsproto.NewNotificationMessage(
- info.Method,
- params,
- )
- f.writeMsg(t, notification.Message())
-}
-
-func (f *FourslashTest) writeMsg(t *testing.T, msg *lsproto.Message) {
- assert.NilError(t, json.MarshalWrite(io.Discard, msg), "failed to encode message as JSON")
- if err := f.in.Write(msg); err != nil {
- t.Fatalf("failed to write message: %v", err)
- }
-}
-
-func (f *FourslashTest) readMsg(t *testing.T) *lsproto.Message {
- // !!! filter out response by id etc
- msg, err := f.out.Read()
- if err != nil {
- t.Fatalf("failed to read message: %v", err)
- }
- assert.NilError(t, json.MarshalWrite(io.Discard, msg), "failed to encode message as JSON")
- return msg
+ lsptestutil.SendNotification(t, &f.TestLspServer, info, params)
}
func (f *FourslashTest) Configure(t *testing.T, config *lsutil.UserPreferences) {
- f.userPreferences = config
+ f.TestLspServer.UserPreferences = config
sendNotification(t, f, lsproto.WorkspaceDidChangeConfigurationInfo, &lsproto.DidChangeConfigurationParams{
Settings: config,
})
}
func (f *FourslashTest) ConfigureWithReset(t *testing.T, config *lsutil.UserPreferences) (reset func()) {
- originalConfig := f.userPreferences.Copy()
+ originalConfig := f.TestLspServer.UserPreferences.Copy()
f.Configure(t, config)
return func() {
f.Configure(t, originalConfig)
@@ -539,7 +302,7 @@ func (f *FourslashTest) openFile(t *testing.T, filename string) {
t.Fatalf("File %s not found in test data", filename)
}
f.activeFilename = filename
- sendNotification(t, f, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{
+ lsptestutil.SendNotification(t, &f.TestLspServer, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{
TextDocument: &lsproto.TextDocumentItem{
Uri: lsconv.FileNameToDocumentURI(filename),
LanguageId: getLanguageKind(filename),
@@ -1059,9 +822,9 @@ func (f *FourslashTest) VerifyBaselineFindAllReferences(
}
}
- f.addResultToBaseline(t, "findAllReferences", f.getBaselineForLocationsWithFileContents(*result.Locations, baselineFourslashLocationsOptions{
- marker: markerOrRange,
- markerName: "/*FIND ALL REFS*/",
+ f.addResultToBaseline(t, "findAllReferences", f.getBaselineForLocationsWithFileContents(*result.Locations, lsptestutil.BaselineLocationsOptions{
+ Marker: markerOrRange,
+ MarkerName: "/*FIND ALL REFS*/",
}))
}
@@ -1127,10 +890,10 @@ func (f *FourslashTest) VerifyBaselineGoToDefinition(
}
}
- f.addResultToBaseline(t, "goToDefinition", f.getBaselineForLocationsWithFileContents(resultAsLocations, baselineFourslashLocationsOptions{
- marker: markerOrRange,
- markerName: "/*GOTO DEF*/",
- additionalLocation: additionalLocation,
+ f.addResultToBaseline(t, "goToDefinition", f.getBaselineForLocationsWithFileContents(resultAsLocations, lsptestutil.BaselineLocationsOptions{
+ Marker: markerOrRange,
+ MarkerName: "/*GOTO DEF*/",
+ AdditionalLocation: additionalLocation,
}))
}
}
@@ -1182,9 +945,9 @@ func (f *FourslashTest) VerifyBaselineGoToTypeDefinition(
})
}
- f.addResultToBaseline(t, "goToType", f.getBaselineForLocationsWithFileContents(resultAsLocations, baselineFourslashLocationsOptions{
- marker: markerOrRange,
- markerName: "/*GOTO TYPE*/",
+ f.addResultToBaseline(t, "goToType", f.getBaselineForLocationsWithFileContents(resultAsLocations, lsptestutil.BaselineLocationsOptions{
+ Marker: markerOrRange,
+ MarkerName: "/*GOTO TYPE*/",
}))
}
}
@@ -1581,9 +1344,9 @@ func (f *FourslashTest) verifyBaselineDocumentHighlights(
}
// Add result to baseline
- f.addResultToBaseline(t, "documentHighlights", f.getBaselineForLocationsWithFileContents(spans, baselineFourslashLocationsOptions{
- marker: markerOrRange,
- markerName: "/*HIGHLIGHTS*/",
+ f.addResultToBaseline(t, "documentHighlights", f.getBaselineForLocationsWithFileContents(spans, lsptestutil.BaselineLocationsOptions{
+ Marker: markerOrRange,
+ MarkerName: "/*HIGHLIGHTS*/",
}))
}
}
@@ -1768,7 +1531,7 @@ func (f *FourslashTest) editScript(t *testing.T, fileName string, start int, end
}
script.editContent(start, end, newText)
- err := f.vfs.WriteFile(fileName, script.content, false)
+ err := f.FS.WriteFile(fileName, script.content, false)
if err != nil {
panic(fmt.Sprintf("Failed to write file %s: %v", fileName, err))
}
@@ -1972,7 +1735,7 @@ func (f *FourslashTest) BaselineAutoImportsCompletions(t *testing.T, markerNames
f.writeToBaseline("Auto Imports", "// === Auto Imports === \n")
- fileContent, ok := f.vfs.ReadFile(f.activeFilename)
+ fileContent, ok := f.FS.ReadFile(f.activeFilename)
if !ok {
t.Fatalf(prefix+"Failed to read file %s for auto-import baseline", f.activeFilename)
}
@@ -2098,19 +1861,6 @@ func (f *FourslashTest) verifyBaselineRename(
t.Fatalf(prefix+"Unexpected rename response type: %T", resMsg.AsResponse().Result)
}
- var changes map[lsproto.DocumentUri][]*lsproto.TextEdit
- if result.WorkspaceEdit != nil && result.WorkspaceEdit.Changes != nil {
- changes = *result.WorkspaceEdit.Changes
- }
- locationToText := map[lsproto.Location]string{}
- fileToRange := collections.MultiMap[lsproto.DocumentUri, lsproto.Range]{}
- for uri, edits := range changes {
- for _, edit := range edits {
- fileToRange.Add(uri, edit.Range)
- locationToText[lsproto.Location{Uri: uri, Range: edit.Range}] = edit.NewText
- }
- }
-
var renameOptions strings.Builder
if preferences != nil {
if preferences.UseAliasesForRename != core.TSUnknown {
@@ -2121,29 +1871,10 @@ func (f *FourslashTest) verifyBaselineRename(
}
}
- baselineFileContent := f.getBaselineForGroupedLocationsWithFileContents(
- &fileToRange,
- baselineFourslashLocationsOptions{
- marker: markerOrRange,
- markerName: "/*RENAME*/",
- endMarker: "RENAME|]",
- startMarkerPrefix: func(span lsproto.Location) *string {
- text := locationToText[span]
- prefixAndSuffix := strings.Split(text, "?")
- if prefixAndSuffix[0] != "" {
- return ptrTo("/*START PREFIX*/" + prefixAndSuffix[0])
- }
- return nil
- },
- endMarkerSuffix: func(span lsproto.Location) *string {
- text := locationToText[span]
- prefixAndSuffix := strings.Split(text, "?")
- if prefixAndSuffix[1] != "" {
- return ptrTo(prefixAndSuffix[1] + "/*END SUFFIX*/")
- }
- return nil
- },
- },
+ baselineFileContent := lsptestutil.GetBaselineForRename(
+ f.FS,
+ result,
+ lsptestutil.BaselineLocationsOptions{Marker: markerOrRange},
)
var baselineResult string
diff --git a/internal/ls/documenthighlights.go b/internal/ls/documenthighlights.go
index a29261249f..3c1f237439 100644
--- a/internal/ls/documenthighlights.go
+++ b/internal/ls/documenthighlights.go
@@ -75,7 +75,7 @@ func (l *LanguageService) toDocumentHighlight(entry *ReferenceEntry) (string, *l
kind := lsproto.DocumentHighlightKindRead
if entry.kind == entryKindRange {
return entry.fileName, &lsproto.DocumentHighlight{
- Range: *entry.textRange,
+ Range: *l.getRangeOfEntry(entry),
Kind: &kind,
}
}
@@ -86,7 +86,7 @@ func (l *LanguageService) toDocumentHighlight(entry *ReferenceEntry) (string, *l
}
dh := &lsproto.DocumentHighlight{
- Range: *entry.textRange,
+ Range: *l.getRangeOfEntry(entry),
Kind: &kind,
}
diff --git a/internal/ls/findallreferences.go b/internal/ls/findallreferences.go
index 933a15252f..ffa0ab9d1b 100644
--- a/internal/ls/findallreferences.go
+++ b/internal/ls/findallreferences.go
@@ -6,6 +6,7 @@ import (
"fmt"
"slices"
"strings"
+ "sync"
"github.com/microsoft/typescript-go/internal/ast"
"github.com/microsoft/typescript-go/internal/astnav"
@@ -104,33 +105,52 @@ type ReferenceEntry struct {
node *ast.Node
context *ast.Node // !!! ContextWithStartAndEndNode, optional
fileName string
- textRange *lsproto.Range
+ textRange *core.TextRange
+ lspRange *lsproto.Location
+}
+
+func (entry *SymbolAndEntries) canUseDefinitionSymbol() bool {
+ if entry.definition == nil {
+ return false
+ }
+
+ switch entry.definition.Kind {
+ case definitionKindSymbol, definitionKindThis:
+ return entry.definition.symbol != nil
+ case definitionKindTripleSlashReference:
+ // !!! TODO : need to find file reference instead?
+ // May need to return true to indicate this to be file search instead and might need to do for import stuff as well
+ // For now
+ return false
+ default:
+ return false
+ }
}
func (l *LanguageService) getRangeOfEntry(entry *ReferenceEntry) *lsproto.Range {
- return l.resolveEntry(entry).textRange
+ return &l.resolveEntry(entry).lspRange.Range
+}
+
+func (l *LanguageService) getFileNameOfEntry(entry *ReferenceEntry) lsproto.DocumentUri {
+ return l.resolveEntry(entry).lspRange.Uri
}
-func (l *LanguageService) getFileNameOfEntry(entry *ReferenceEntry) string {
- return l.resolveEntry(entry).fileName
+func (l *LanguageService) getLocationOfEntry(entry *ReferenceEntry) *lsproto.Location {
+ return l.resolveEntry(entry).lspRange
}
func (l *LanguageService) resolveEntry(entry *ReferenceEntry) *ReferenceEntry {
if entry.textRange == nil {
sourceFile := ast.GetSourceFileOfNode(entry.node)
- entry.textRange = l.getLspRangeOfNode(entry.node, sourceFile, nil /*endNode*/)
+ textRange := getRangeOfNode(entry.node, sourceFile, nil /*endNode*/)
+ entry.textRange = &textRange
entry.fileName = sourceFile.FileName()
}
- return entry
-}
-
-func (l *LanguageService) newRangeEntry(file *ast.SourceFile, start, end int) *ReferenceEntry {
- // !!! used in not-yet implemented features
- return &ReferenceEntry{
- kind: entryKindRange,
- fileName: file.FileName(),
- textRange: l.createLspRangeFromBounds(start, end, file),
+ if entry.lspRange == nil {
+ location := l.getMappedLocation(entry.fileName, *entry.textRange)
+ entry.lspRange = &location
}
+ return entry
}
func newNodeEntryWithKind(node *ast.Node, kind entryKind) *ReferenceEntry {
@@ -266,10 +286,9 @@ func (l *LanguageService) getLspRangeOfNode(node *ast.Node, sourceFile *ast.Sour
sourceFile = ast.GetSourceFileOfNode(node)
}
textRange := getRangeOfNode(node, sourceFile, endNode)
- return l.createLspRangeFromRange(textRange, sourceFile)
+ return l.createLspRangeFromBounds(textRange.Pos(), textRange.End(), sourceFile)
}
-// `getTextSpan`
func getRangeOfNode(node *ast.Node, sourceFile *ast.SourceFile, endNode *ast.Node) core.TextRange {
if sourceFile == nil {
sourceFile = ast.GetSourceFileOfNode(node)
@@ -416,16 +435,170 @@ func getSymbolScope(symbol *ast.Symbol) *ast.Node {
// === functions on (*ls) ===
-func (l *LanguageService) ProvideReferences(ctx context.Context, params *lsproto.ReferenceParams) (lsproto.ReferencesResponse, error) {
+type position struct {
+ uri lsproto.DocumentUri
+ pos lsproto.Position
+}
+
+var _ lsproto.HasTextDocumentPosition = (*position)(nil)
+
+func (nld *position) TextDocumentURI() lsproto.DocumentUri { return nld.uri }
+func (nld *position) TextDocumentPosition() lsproto.Position { return nld.pos }
+
+type NonLocalDefinition struct {
+ position
+ GetSourcePosition func() lsproto.HasTextDocumentPosition
+ GetGeneratedPosition func() lsproto.HasTextDocumentPosition
+}
+
+func getFileAndStartPosFromDeclaration(declaration *ast.Node) (*ast.SourceFile, core.TextPos) {
+ file := ast.GetSourceFileOfNode(declaration)
+ name := core.OrElse(ast.GetNameOfDeclaration(declaration), declaration)
+ textRange := getRangeOfNode(name, file, nil /*endNode*/)
+
+ return file, core.TextPos(textRange.Pos())
+}
+
+func (l *LanguageService) GetNonLocalDefinition(ctx context.Context, entry *SymbolAndEntries) *NonLocalDefinition {
+ if !entry.canUseDefinitionSymbol() {
+ return nil
+ }
+
+ program := l.GetProgram()
+ checker, done := program.GetTypeChecker(ctx)
+ defer done()
+ emitResolver := checker.GetEmitResolver()
+ for _, d := range entry.definition.symbol.Declarations {
+ if isDefinitionVisible(emitResolver, d) {
+ file, startPos := getFileAndStartPosFromDeclaration(d)
+ fileName := file.FileName()
+ return &NonLocalDefinition{
+ position: position{
+ uri: lsconv.FileNameToDocumentURI(fileName),
+ pos: l.converters.PositionToLineAndCharacter(file, startPos),
+ },
+ GetSourcePosition: sync.OnceValue(func() lsproto.HasTextDocumentPosition {
+ mapped := l.tryGetSourcePosition(fileName, startPos)
+ if mapped != nil {
+ return &position{
+ uri: lsconv.FileNameToDocumentURI(mapped.FileName),
+ pos: l.converters.PositionToLineAndCharacter(l.getScript(mapped.FileName), core.TextPos(mapped.Pos)),
+ }
+ }
+ return nil
+ }),
+ GetGeneratedPosition: sync.OnceValue(func() lsproto.HasTextDocumentPosition {
+ mapped := l.tryGetGeneratedPosition(fileName, startPos)
+ if mapped != nil {
+ return &position{
+ uri: lsconv.FileNameToDocumentURI(mapped.FileName),
+ pos: l.converters.PositionToLineAndCharacter(l.getScript(mapped.FileName), core.TextPos(mapped.Pos)),
+ }
+ }
+ return nil
+ }),
+ }
+ }
+ }
+ return nil
+}
+
+// This is special handling to determine if we should load up more projects and find location in other projects
+// By default arrows (and such other ast kinds) are not visible as declaration emitter doesnt need them
+// But we want to handle them specially so that they are visible if their parent is visible
+func isDefinitionVisible(emitResolver *checker.EmitResolver, declaration *ast.Node) bool {
+ if emitResolver.IsDeclarationVisible(declaration) {
+ return true
+ }
+ if declaration.Parent == nil {
+ return false
+ }
+
+ // Variable initializers are visible if variable is visible
+ if ast.HasInitializer(declaration.Parent) && declaration.Parent.Initializer() == declaration {
+ return isDefinitionVisible(emitResolver, declaration.Parent)
+ }
+
+ // Handle some exceptions here like arrow function, members of class and object literal expression which are technically not visible but we want the definition to be determined by its parent
+ switch declaration.Kind {
+ case ast.KindPropertyDeclaration,
+ ast.KindGetAccessor,
+ ast.KindSetAccessor,
+ ast.KindMethodDeclaration:
+ // Private/protected properties/methods are not visible
+ if ast.HasModifier(declaration, ast.ModifierFlagsPrivate) || ast.IsPrivateIdentifier(declaration.Name()) {
+ return false
+ }
+ // Public properties/methods are visible if its parents are visible, so:
+ // falls through
+ fallthrough
+ case ast.KindConstructor,
+ ast.KindPropertyAssignment,
+ ast.KindShorthandPropertyAssignment,
+ ast.KindObjectLiteralExpression,
+ ast.KindClassExpression,
+ ast.KindArrowFunction,
+ ast.KindFunctionExpression:
+ return isDefinitionVisible(emitResolver, declaration.Parent)
+ default:
+ return false
+ }
+}
+
+func (l *LanguageService) ForEachOriginalDefinitionLocation(
+ ctx context.Context,
+ entry *SymbolAndEntries,
+ cb func(lsproto.DocumentUri, lsproto.Position),
+) {
+ if !entry.canUseDefinitionSymbol() {
+ return
+ }
+
+ program := l.GetProgram()
+ for _, d := range entry.definition.symbol.Declarations {
+ file, startPos := getFileAndStartPosFromDeclaration(d)
+ fileName := file.FileName()
+ if tspath.IsDeclarationFileName(fileName) {
+ // Map to ts position
+ mapped := l.tryGetSourcePosition(file.FileName(), startPos)
+ if mapped != nil {
+ cb(
+ lsconv.FileNameToDocumentURI(mapped.FileName),
+ l.converters.PositionToLineAndCharacter(l.getScript(mapped.FileName), core.TextPos(mapped.Pos)),
+ )
+ }
+ } else if program.IsSourceFromProjectReference(l.toPath(fileName)) {
+ cb(
+ lsconv.FileNameToDocumentURI(fileName),
+ l.converters.PositionToLineAndCharacter(file, startPos),
+ )
+ }
+ }
+}
+
+func (l *LanguageService) ProvideSymbolsAndEntries(ctx context.Context, uri lsproto.DocumentUri, documentPosition lsproto.Position, isRename bool) (*ast.Node, []*SymbolAndEntries, bool) {
// `findReferencedSymbols` except only computes the information needed to return reference locations
- program, sourceFile := l.getProgramAndFile(params.TextDocument.Uri)
- position := int(l.converters.LineAndCharacterToPosition(sourceFile, params.Position))
+ program, sourceFile := l.getProgramAndFile(uri)
+ position := int(l.converters.LineAndCharacterToPosition(sourceFile, documentPosition))
node := astnav.GetTouchingPropertyName(sourceFile, position)
- options := refOptions{use: referenceUseReferences}
+ if isRename && node.Kind != ast.KindIdentifier {
+ return node, nil, false
+ }
- symbolsAndEntries := l.getReferencedSymbolsForNode(ctx, position, node, program, program.GetSourceFiles(), options, nil)
+ var options refOptions
+ if !isRename {
+ options.use = referenceUseReferences
+ } else {
+ options.use = referenceUseRename
+ options.useAliasesForRename = true
+ }
+
+ return node, l.getReferencedSymbolsForNode(ctx, position, node, program, program.GetSourceFiles(), options, nil), true
+}
+func (l *LanguageService) ProvideReferencesFromSymbolAndEntries(ctx context.Context, params *lsproto.ReferenceParams, originalNode *ast.Node, symbolsAndEntries []*SymbolAndEntries) (lsproto.ReferencesResponse, error) {
+ // `findReferencedSymbols` except only computes the information needed to return reference locations
locations := core.FlatMap(symbolsAndEntries, l.convertSymbolAndEntriesToLocations)
return lsproto.LocationsOrNull{Locations: &locations}, nil
}
@@ -466,24 +639,21 @@ func (l *LanguageService) getImplementationReferenceEntries(ctx context.Context,
return core.FlatMap(symbolsAndEntries, func(s *SymbolAndEntries) []*ReferenceEntry { return s.references })
}
-func (l *LanguageService) ProvideRename(ctx context.Context, params *lsproto.RenameParams) (lsproto.WorkspaceEditOrNull, error) {
- program, sourceFile := l.getProgramAndFile(params.TextDocument.Uri)
- position := int(l.converters.LineAndCharacterToPosition(sourceFile, params.Position))
- node := astnav.GetTouchingPropertyName(sourceFile, position)
- if node.Kind != ast.KindIdentifier {
+func (l *LanguageService) ProvideRenameFromSymbolAndEntries(ctx context.Context, params *lsproto.RenameParams, originalNode *ast.Node, symbolsAndEntries []*SymbolAndEntries) (lsproto.WorkspaceEditOrNull, error) {
+ if originalNode.Kind != ast.KindIdentifier {
return lsproto.WorkspaceEditOrNull{}, nil
}
- options := refOptions{use: referenceUseRename, useAliasesForRename: true}
- symbolsAndEntries := l.getReferencedSymbolsForNode(ctx, position, node, program, program.GetSourceFiles(), options, nil)
+
+ program := l.GetProgram()
entries := core.FlatMap(symbolsAndEntries, func(s *SymbolAndEntries) []*ReferenceEntry { return s.references })
changes := make(map[lsproto.DocumentUri][]*lsproto.TextEdit)
checker, done := program.GetTypeChecker(ctx)
defer done()
for _, entry := range entries {
- uri := lsconv.FileNameToDocumentURI(l.getFileNameOfEntry(entry))
+ uri := l.getFileNameOfEntry(entry)
textEdit := &lsproto.TextEdit{
Range: *l.getRangeOfEntry(entry),
- NewText: l.getTextForRename(node, entry, params.NewName, checker),
+ NewText: l.getTextForRename(originalNode, entry, params.NewName, checker),
}
changes[uri] = append(changes[uri], textEdit)
}
@@ -550,10 +720,7 @@ func (l *LanguageService) convertSymbolAndEntriesToLocations(s *SymbolAndEntries
func (l *LanguageService) convertEntriesToLocations(entries []*ReferenceEntry) []lsproto.Location {
locations := make([]lsproto.Location, len(entries))
for i, entry := range entries {
- locations[i] = lsproto.Location{
- Uri: lsconv.FileNameToDocumentURI(l.getFileNameOfEntry(entry)),
- Range: *l.getRangeOfEntry(entry),
- }
+ locations[i] = *l.getLocationOfEntry(entry)
}
return locations
}
@@ -561,30 +728,20 @@ func (l *LanguageService) convertEntriesToLocations(entries []*ReferenceEntry) [
func (l *LanguageService) convertEntriesToLocationLinks(entries []*ReferenceEntry) []*lsproto.LocationLink {
links := make([]*lsproto.LocationLink, len(entries))
for i, entry := range entries {
- var targetSelectionRange, targetRange *lsproto.Range
+
+ // Get the selection range (the actual reference)
+ targetSelectionRange := &l.getLocationOfEntry(entry).Range
+ targetRange := targetSelectionRange
// For entries with nodes, compute ranges directly from the node
if entry.node != nil {
- sourceFile := ast.GetSourceFileOfNode(entry.node)
- entry.fileName = sourceFile.FileName()
-
- // Get the selection range (the actual reference)
- selectionTextRange := getRangeOfNode(entry.node, sourceFile, nil /*endNode*/)
- targetSelectionRange = l.createLspRangeFromRange(selectionTextRange, sourceFile)
-
// Get the context range (broader scope including declaration context)
contextNode := core.OrElse(getContextNode(entry.node), entry.node)
- contextTextRange := toContextRange(&selectionTextRange, sourceFile, contextNode)
+ contextTextRange := toContextRange(entry.textRange, l.program.GetSourceFile(entry.fileName), contextNode)
if contextTextRange != nil {
- targetRange = l.createLspRangeFromRange(*contextTextRange, sourceFile)
- } else {
- targetRange = targetSelectionRange
+ contextLocation := l.getMappedLocation(entry.fileName, *contextTextRange)
+ targetRange = &contextLocation.Range
}
- } else {
- // For range entries, use the pre-computed range
- l.resolveEntry(entry)
- targetSelectionRange = entry.textRange
- targetRange = targetSelectionRange
}
links[i] = &lsproto.LocationLink{
@@ -903,7 +1060,7 @@ func getReferencesForThisKeyword(thisOrSuperKeyword *ast.Node, sourceFiles []*as
if thisParameter == nil {
thisParameter = thisOrSuperKeyword
}
- return []*SymbolAndEntries{NewSymbolAndEntries(definitionKindThis, thisParameter, nil, references)}
+ return []*SymbolAndEntries{NewSymbolAndEntries(definitionKindThis, thisParameter, searchSpaceNode.Symbol(), references)}
}
func getReferencesForSuperKeyword(superKeyword *ast.Node) []*SymbolAndEntries {
@@ -1117,7 +1274,7 @@ func (l *LanguageService) getReferencedSymbolsForModule(ctx context.Context, pro
return &ReferenceEntry{
kind: entryKindRange,
fileName: reference.referencingFile.FileName(),
- textRange: l.createLspRangeFromBounds(reference.ref.Pos(), reference.ref.End(), reference.referencingFile),
+ textRange: &reference.ref.TextRange,
}
}
return nil
diff --git a/internal/ls/languageservice.go b/internal/ls/languageservice.go
index e2fc95f24c..2cfe172468 100644
--- a/internal/ls/languageservice.go
+++ b/internal/ls/languageservice.go
@@ -8,6 +8,7 @@ import (
"github.com/microsoft/typescript-go/internal/ls/lsutil"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
"github.com/microsoft/typescript-go/internal/sourcemap"
+ "github.com/microsoft/typescript-go/internal/tspath"
)
type LanguageService struct {
@@ -29,6 +30,10 @@ func NewLanguageService(
}
}
+func (l *LanguageService) toPath(fileName string) tspath.Path {
+ return tspath.ToPath(fileName, l.program.GetCurrentDirectory(), l.UseCaseSensitiveFileNames())
+}
+
func (l *LanguageService) GetProgram() *compiler.Program {
return l.program
}
diff --git a/internal/ls/source_map.go b/internal/ls/source_map.go
index bbda05ddfe..dee315cf45 100644
--- a/internal/ls/source_map.go
+++ b/internal/ls/source_map.go
@@ -5,6 +5,7 @@ import (
"github.com/microsoft/typescript-go/internal/debug"
"github.com/microsoft/typescript-go/internal/ls/lsconv"
"github.com/microsoft/typescript-go/internal/lsp/lsproto"
+ "github.com/microsoft/typescript-go/internal/outputpaths"
"github.com/microsoft/typescript-go/internal/sourcemap"
"github.com/microsoft/typescript-go/internal/tspath"
)
@@ -86,3 +87,47 @@ func (l *LanguageService) tryGetSourcePositionWorker(
}
return documentPos
}
+
+func (l *LanguageService) tryGetGeneratedPosition(
+ fileName string,
+ position core.TextPos,
+) *sourcemap.DocumentPosition {
+ newPos := l.tryGetGeneratedPositionWorker(fileName, position)
+ if newPos != nil {
+ if _, ok := l.ReadFile(newPos.FileName); !ok { // File doesn't exist
+ return nil
+ }
+ }
+ return newPos
+}
+
+func (l *LanguageService) tryGetGeneratedPositionWorker(
+ fileName string,
+ position core.TextPos,
+) *sourcemap.DocumentPosition {
+ if tspath.IsDeclarationFileName(fileName) {
+ return nil
+ }
+
+ program := l.GetProgram()
+ if program == nil || program.GetSourceFile(fileName) == nil {
+ return nil
+ }
+
+ path := l.toPath(fileName)
+ // If this is source file of project reference source (instead of redirect) there is no generated position
+ if program.IsSourceFromProjectReference(path) {
+ return nil
+ }
+
+ declarationFileName := outputpaths.GetOutputDeclarationFileNameWorker(fileName, program.Options(), program)
+ positionMapper := l.GetDocumentPositionMapper(declarationFileName)
+ documentPos := positionMapper.GetGeneratedPosition(&sourcemap.DocumentPosition{FileName: fileName, Pos: int(position)})
+ if documentPos == nil {
+ return nil
+ }
+ if newPos := l.tryGetGeneratedPositionWorker(documentPos.FileName, core.TextPos(documentPos.Pos)); newPos != nil {
+ return newPos
+ }
+ return documentPos
+}
diff --git a/internal/lsp/lsproto/_generate/generate.mts b/internal/lsp/lsproto/_generate/generate.mts
index 1828abd62f..8e8bc3f639 100644
--- a/internal/lsp/lsproto/_generate/generate.mts
+++ b/internal/lsp/lsproto/_generate/generate.mts
@@ -526,6 +526,14 @@ function generateCode() {
writeLine(`\treturn s.TextDocument.Uri`);
writeLine(`}`);
writeLine("");
+
+ if (hasTextDocumentPosition(structure)) {
+ // Generate TextDocumentPosition method
+ writeLine(`func (s *${structure.name}) TextDocumentPosition() Position {`);
+ writeLine(`\treturn s.Position`);
+ writeLine(`}`);
+ writeLine("");
+ }
}
// Generate UnmarshalJSONFrom method for structure validation
@@ -880,15 +888,23 @@ function generateCode() {
return parts.join("");
}
-function hasTextDocumentURI(structure: Structure) {
+function hasSomeProp(structure: Structure, propName: string, propTypeName: string) {
return structure.properties?.some(p =>
!p.optional &&
- p.name === "textDocument" &&
+ p.name === propName &&
p.type.kind === "reference" &&
- p.type.name === "TextDocumentIdentifier"
+ p.type.name === propTypeName
);
}
+function hasTextDocumentURI(structure: Structure) {
+ return hasSomeProp(structure, "textDocument", "TextDocumentIdentifier");
+}
+
+function hasTextDocumentPosition(structure: Structure) {
+ return hasSomeProp(structure, "position", "Position");
+}
+
/**
* Main function
*/
diff --git a/internal/lsp/lsproto/lsp.go b/internal/lsp/lsproto/lsp.go
index dd172077c2..e25f489575 100644
--- a/internal/lsp/lsproto/lsp.go
+++ b/internal/lsp/lsproto/lsp.go
@@ -58,6 +58,11 @@ type HasTextDocumentURI interface {
TextDocumentURI() DocumentUri
}
+type HasTextDocumentPosition interface {
+ HasTextDocumentURI
+ TextDocumentPosition() Position
+}
+
type URI string // !!!
type Method string
diff --git a/internal/lsp/lsproto/lsp_generated.go b/internal/lsp/lsproto/lsp_generated.go
index 04892d51b9..0457ab055c 100644
--- a/internal/lsp/lsproto/lsp_generated.go
+++ b/internal/lsp/lsproto/lsp_generated.go
@@ -32,6 +32,10 @@ func (s *ImplementationParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *ImplementationParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*ImplementationParams)(nil)
func (s *ImplementationParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -226,6 +230,10 @@ func (s *TypeDefinitionParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *TypeDefinitionParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*TypeDefinitionParams)(nil)
func (s *TypeDefinitionParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -1115,6 +1123,10 @@ func (s *DeclarationParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *DeclarationParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*DeclarationParams)(nil)
func (s *DeclarationParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -1528,6 +1540,10 @@ func (s *CallHierarchyPrepareParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *CallHierarchyPrepareParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*CallHierarchyPrepareParams)(nil)
func (s *CallHierarchyPrepareParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -2654,6 +2670,10 @@ func (s *LinkedEditingRangeParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *LinkedEditingRangeParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*LinkedEditingRangeParams)(nil)
func (s *LinkedEditingRangeParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -3072,6 +3092,10 @@ func (s *MonikerParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *MonikerParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*MonikerParams)(nil)
func (s *MonikerParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -3280,6 +3304,10 @@ func (s *TypeHierarchyPrepareParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *TypeHierarchyPrepareParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*TypeHierarchyPrepareParams)(nil)
func (s *TypeHierarchyPrepareParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -4819,6 +4847,10 @@ func (s *InlineCompletionParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *InlineCompletionParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*InlineCompletionParams)(nil)
func (s *InlineCompletionParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -6525,6 +6557,10 @@ func (s *CompletionParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *CompletionParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*CompletionParams)(nil)
func (s *CompletionParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -7060,6 +7096,10 @@ func (s *HoverParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *HoverParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*HoverParams)(nil)
func (s *HoverParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -7241,6 +7281,10 @@ func (s *SignatureHelpParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *SignatureHelpParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*SignatureHelpParams)(nil)
func (s *SignatureHelpParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -7474,6 +7518,10 @@ func (s *DefinitionParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *DefinitionParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*DefinitionParams)(nil)
func (s *DefinitionParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -7606,6 +7654,10 @@ func (s *ReferenceParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *ReferenceParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*ReferenceParams)(nil)
func (s *ReferenceParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -7745,6 +7797,10 @@ func (s *DocumentHighlightParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *DocumentHighlightParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*DocumentHighlightParams)(nil)
func (s *DocumentHighlightParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -9608,6 +9664,10 @@ func (s *DocumentOnTypeFormattingParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *DocumentOnTypeFormattingParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*DocumentOnTypeFormattingParams)(nil)
func (s *DocumentOnTypeFormattingParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -9764,6 +9824,10 @@ func (s *RenameParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *RenameParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*RenameParams)(nil)
func (s *RenameParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -9903,6 +9967,10 @@ func (s *PrepareRenameParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *PrepareRenameParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*PrepareRenameParams)(nil)
func (s *PrepareRenameParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
@@ -10624,6 +10692,10 @@ func (s *TextDocumentPositionParams) TextDocumentURI() DocumentUri {
return s.TextDocument.Uri
}
+func (s *TextDocumentPositionParams) TextDocumentPosition() Position {
+ return s.Position
+}
+
var _ json.UnmarshalerFrom = (*TextDocumentPositionParams)(nil)
func (s *TextDocumentPositionParams) UnmarshalJSONFrom(dec *jsontext.Decoder) error {
diff --git a/internal/lsp/lspservertests/declarationmaps_test.go b/internal/lsp/lspservertests/declarationmaps_test.go
new file mode 100644
index 0000000000..fa24e6ed69
--- /dev/null
+++ b/internal/lsp/lspservertests/declarationmaps_test.go
@@ -0,0 +1,520 @@
+package lspservertests
+
+import (
+ "fmt"
+ "slices"
+ "testing"
+
+ "github.com/microsoft/typescript-go/internal/bundled"
+ "github.com/microsoft/typescript-go/internal/execute/tsctests"
+ "github.com/microsoft/typescript-go/internal/lsp/lsproto"
+ "github.com/microsoft/typescript-go/internal/testutil/lsptestutil"
+ "github.com/microsoft/typescript-go/internal/testutil/stringtestutil"
+)
+
+func TestDeclarationMaps(t *testing.T) {
+ t.Parallel()
+
+ if !bundled.Embedded {
+ t.Skip("bundled files are not embedded")
+ }
+
+ testCases := slices.Concat(
+ getDeclarationMapTestCasesForProjectReferences(),
+ getDeclarationMapTestCasesForMaps(),
+ getDeclarationMapTestCasesForRename(),
+ []*lspServerTest{
+ {
+ subScenario: "findAllReferences definition is in mapped file",
+ files: func() map[string]any {
+ return map[string]any{
+ "/home/src/projects/project/a/a.ts": "export function f() {}",
+ "/home/src/projects/project/a/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+ }`),
+ "/home/src/projects/project/b/b.ts": stringtestutil.Dedent(`
+ import { f } from "../a/bin/a";
+ f();`),
+ "/home/src/projects/project/b/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "references": [
+ { "path": "../a" }
+ ]
+ }`),
+ "/home/src/projects/project/bin/a.d.ts": stringtestutil.Dedent(`
+ export declare function f(): void;
+ //# sourceMappingURL=a.d.ts.map`),
+ "/home/src/projects/project/bin/a.d.ts.map": stringtestutil.Dedent(`
+ {
+ "version":3,
+ "file":"a.d.ts",
+ "sourceRoot":"",
+ "sources":["a.ts"],
+ "names":[],
+ "mappings":"AAAA,wBAAgB,CAAC,SAAK"
+ }`),
+ }
+ },
+ test: func(server *testServer) {
+ bTs := "/home/src/projects/project/b/b.ts"
+ server.openFile(bTs, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ server.baselineReferences(bTs, lsptestutil.PositionToLineAndCharacter(bTs, server.content(bTs), "f()", 0))
+ },
+ },
+ },
+ )
+
+ for _, test := range testCases {
+ test.run(t, "declarationMaps")
+ }
+}
+
+func getDeclarationMapTestCasesForMaps() []*lspServerTest {
+ files := func() map[string]any {
+ configContent := stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+ }`)
+ return map[string]any{
+ "/home/src/projects/project/a/a.ts": stringtestutil.Dedent(`
+ export function fnA() {}
+ export interface IfaceA {}
+ export const instanceA: IfaceA = {};
+ `),
+ "/home/src/projects/project/a/tsconfig.json": configContent,
+ "/home/src/projects/project/a/bin/a.d.ts.map": stringtestutil.Dedent(`
+ {
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+ }`),
+ "/home/src/projects/project/a/bin/a.d.ts": stringtestutil.Dedent(`
+ export declare function fnA(): void;
+ export interface IfaceA {
+ }
+ export declare const instanceA: IfaceA;
+ //# sourceMappingURL=a.d.ts.map`),
+ "/home/src/projects/project/b/tsconfig.json": configContent,
+ "/home/src/projects/project/b/bin/b.d.ts.map": stringtestutil.Dedent(`
+ {
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+ }`),
+ "/home/src/projects/project/b/bin/b.d.ts": stringtestutil.Dedent(`
+ export declare function fnB(): void;
+ //# sourceMappingURL=b.d.ts.map`),
+ "/home/src/projects/project/user/user.ts": stringtestutil.Dedent(`
+ import * as a from "../a/bin/a";
+ import * as b from "../b/bin/b";
+ export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }`),
+ "/home/src/projects/project/dummy/dummy.ts": "export const a = 10;",
+ "/home/src/projects/project/dummy/tsconfig.json": "{}",
+ }
+ }
+ return []*lspServerTest{
+ {
+ subScenario: "findAllReferences",
+ files: files,
+ test: func(server *testServer) {
+ userTs := "/home/src/projects/project/user/user.ts"
+ server.openFile(userTs, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ server.baselineReferences(userTs, lsptestutil.PositionToLineAndCharacter(userTs, server.content(userTs), "fnA()", 0))
+
+ // Open temp file and verify all projects alive
+ server.closeFile(userTs)
+ server.openFile("/home/src/projects/project/dummy/dummy.ts", lsproto.LanguageKindTypeScript)
+ },
+ },
+ {
+ subScenario: "findAllReferences starting at definition",
+ files: files,
+ test: func(server *testServer) {
+ userTs := "/home/src/projects/project/user/user.ts"
+ server.openFile(userTs, lsproto.LanguageKindTypeScript)
+ aTs := "/home/src/projects/project/a/a.ts"
+ server.openFile(aTs, lsproto.LanguageKindTypeScript) // If it's not opened, the reference isn't found.
+
+ // Ref projects are loaded after as part of this command
+ server.baselineReferences(aTs, lsptestutil.PositionToLineAndCharacter(aTs, server.content(aTs), "fnA", 0))
+
+ // Open temp file and verify all projects alive
+ server.closeFile(userTs)
+ server.openFile("/home/src/projects/project/dummy/dummy.ts", lsproto.LanguageKindTypeScript)
+ },
+ },
+ {
+ subScenario: "findAllReferences target does not exist",
+ files: files,
+ test: func(server *testServer) {
+ userTs := "/home/src/projects/project/user/user.ts"
+ server.openFile(userTs, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ server.baselineReferences(userTs, lsptestutil.PositionToLineAndCharacter(userTs, server.content(userTs), "fnB()", 0))
+
+ // Open temp file and verify all projects alive
+ server.closeFile(userTs)
+ server.openFile("/home/src/projects/project/dummy/dummy.ts", lsproto.LanguageKindTypeScript)
+ },
+ },
+ {
+ subScenario: "rename",
+ files: files,
+ test: func(server *testServer) {
+ userTs := "/home/src/projects/project/user/user.ts"
+ server.openFile(userTs, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ server.baselineRename(userTs, lsptestutil.PositionToLineAndCharacter(userTs, server.content(userTs), "fnA()", 0))
+
+ // Open temp file and verify all projects alive
+ server.closeFile(userTs)
+ server.openFile("/home/src/projects/project/dummy/dummy.ts", lsproto.LanguageKindTypeScript)
+ },
+ },
+ {
+ subScenario: "rename starting at definition",
+ files: files,
+ test: func(server *testServer) {
+ userTs := "/home/src/projects/project/user/user.ts"
+ server.openFile(userTs, lsproto.LanguageKindTypeScript)
+ aTs := "/home/src/projects/project/a/a.ts"
+ server.openFile(aTs, lsproto.LanguageKindTypeScript) // If it's not opened, the reference isn't found.
+
+ // Ref projects are loaded after as part of this command
+ server.baselineRename(aTs, lsptestutil.PositionToLineAndCharacter(aTs, server.content(aTs), "fnA", 0))
+
+ // Open temp file and verify all projects alive
+ server.closeFile(userTs)
+ server.openFile("/home/src/projects/project/dummy/dummy.ts", lsproto.LanguageKindTypeScript)
+ },
+ },
+ {
+ subScenario: "rename target does not exist",
+ files: files,
+ test: func(server *testServer) {
+ userTs := "/home/src/projects/project/user/user.ts"
+ server.openFile(userTs, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ server.baselineRename(userTs, lsptestutil.PositionToLineAndCharacter(userTs, server.content(userTs), "fnB()", 0))
+
+ // Open temp file and verify all projects alive
+ server.closeFile(userTs)
+ server.openFile("/home/src/projects/project/dummy/dummy.ts", lsproto.LanguageKindTypeScript)
+ },
+ },
+ {
+ subScenario: "workspace symbols",
+ files: func() map[string]any {
+ allFiles := files()
+ allFiles["/home/src/projects/project/user/user.ts"] = stringtestutil.Dedent(`
+ import * as a from "../a/a";
+ import * as b from "../b/b";
+ export function fnUser() {
+ a.fnA();
+ b.fnB();
+ a.instanceA;
+ }`)
+ allFiles["/home/src/projects/project/user/tsconfig.json"] = stringtestutil.Dedent(`
+ {
+ "references": [{ "path": "../a" }, { "path": "../b" }]
+ }`)
+ allFiles["/home/src/projects/project/b/b.ts"] = stringtestutil.Dedent(`
+ export function fnB() {}`)
+ allFiles["/home/src/projects/project/b/c.ts"] = stringtestutil.Dedent(`
+ export function fnC() {}`)
+ return allFiles
+ },
+ test: func(server *testServer) {
+ userTs := "/home/src/projects/project/user/user.ts"
+ server.openFile(userTs, lsproto.LanguageKindTypeScript)
+ server.baselineWorkspaceSymbol("fn")
+ // Open temp file and verify all projects alive
+ server.closeFile(userTs)
+ server.openFile("/home/src/projects/project/dummy/dummy.ts", lsproto.LanguageKindTypeScript)
+ },
+ },
+ }
+}
+
+func getDeclarationMapTestCasesForProjectReferences() []*lspServerTest {
+ files := func(disableSourceOfProjectReferenceRedirect bool) map[string]any {
+ return map[string]any{
+ "/user/username/projects/a/a.ts": "export class A { }",
+ "/user/username/projects/a/tsconfig.json": "{}",
+ "/user/username/projects/a/a.d.ts": stringtestutil.Dedent(`
+ export declare class A {
+ }
+ //# sourceMappingURL=a.d.ts.map`),
+ "/user/username/projects/a/a.d.ts.map": stringtestutil.Dedent(`
+ {
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["./a.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;CAAI"
+ }
+ `),
+ "/user/username/projects/b/b.ts": stringtestutil.Dedent(`
+ import {A} from "../a/a";
+ new A();
+ `),
+ "/user/username/projects/b/tsconfig.json": stringtestutil.Dedent(fmt.Sprintf(`
+ {
+ "compilerOptions": {
+ "disableSourceOfProjectReferenceRedirect": %t
+ },
+ "references": [
+ { "path": "../a" }
+ ]
+ }`, disableSourceOfProjectReferenceRedirect)),
+ }
+ }
+ test := func(server *testServer) {
+ bTs := "/user/username/projects/b/b.ts"
+ server.openFile(bTs, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ server.baselineReferences(bTs, lsptestutil.PositionToLineAndCharacter(bTs, server.content(bTs), "A();", 0))
+ }
+
+ return []*lspServerTest{
+ {
+ subScenario: "opening original location project",
+ files: func() map[string]any { return files(false) },
+ test: test,
+ },
+ {
+ subScenario: "opening original location project disableSourceOfProjectReferenceRedirect",
+ files: func() map[string]any { return files(true) },
+ test: test,
+ },
+ }
+}
+
+func getDeclarationMapTestCasesForRename() []*lspServerTest {
+ dependencyTs := "/user/username/projects/myproject/dependency/FnS.ts"
+ filesWithRef := func() map[string]any {
+ return map[string]any{
+ dependencyTs: stringtestutil.Dedent(`
+ export function fn1() { }
+ export function fn2() { }
+ export function fn3() { }
+ export function fn4() { }
+ export function fn5() { }
+ `) + "\n",
+ "/user/username/projects/myproject/dependency/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+ }`),
+ "/user/username/projects/myproject/main/main.ts": stringtestutil.Dedent(`
+ import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+ } from "../decls/FnS";
+
+ fn1();
+ fn2();
+ fn3();
+ fn4();
+ fn5();
+ `),
+ "/user/username/projects/myproject/main/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+ }`),
+ "/user/username/projects/myproject/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "references": [
+ { "path": "main" }
+ ]
+ }`),
+ "/user/username/projects/random/random.ts": "export const a = 10;",
+ "/user/username/projects/random/tsconfig.json": "{}",
+ }
+ }
+ filesWithBuiltRef := func() map[string]any {
+ allFiles := filesWithRef()
+ tsctests.GetFileMapWithBuild(allFiles, []string{"-b", "/user/username/projects/myproject/tsconfig.json"})
+ return allFiles
+ }
+
+ fileWithNoRefs := func() map[string]any {
+ allFiles := filesWithBuiltRef()
+ allFiles["/user/username/projects/myproject/main/tsconfig.json"] = stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+ }`)
+ return allFiles
+ }
+
+ filesWithDisableProjectRefSource := func() map[string]any {
+ allFiles := filesWithBuiltRef()
+ allFiles["/user/username/projects/myproject/main/tsconfig.json"] = stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "disableSourceOfProjectReferenceRedirect": true
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+ }`)
+ return allFiles
+ }
+
+ baselineRename := func(server *testServer) {
+ server.baselineRename(dependencyTs, lsptestutil.PositionToLineAndCharacter(dependencyTs, server.content(dependencyTs), "fn3", 0))
+ }
+
+ testRename := func(server *testServer) {
+ dummyTs := "/user/username/projects/random/random.ts"
+ server.openFile(dependencyTs, lsproto.LanguageKindTypeScript)
+ server.openFile(dummyTs, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ baselineRename(server)
+
+ // Collecting at this point retains dependency.d.ts and map
+ server.closeFile(dummyTs)
+ server.openFile(dummyTs, lsproto.LanguageKindTypeScript)
+
+ // Closing open file, removes dependencies too
+ server.closeFile(dependencyTs)
+ server.closeFile(dummyTs)
+ server.openFile(dummyTs, lsproto.LanguageKindTypeScript)
+ }
+
+ openFileAndBaselineRename := func(server *testServer) {
+ server.openFile(dependencyTs, lsproto.LanguageKindTypeScript)
+ baselineRename(server)
+ }
+
+ testPrefix := func(server *testServer) {
+ openFileAndBaselineRename(server)
+ server.changeFile(&lsproto.DidChangeTextDocumentParams{
+ TextDocument: lsproto.VersionedTextDocumentIdentifier{
+ Uri: lsproto.DocumentUri("file://" + dependencyTs),
+ Version: 2,
+ },
+ ContentChanges: []lsproto.TextDocumentContentChangePartialOrWholeDocument{
+ {
+ Partial: &lsproto.TextDocumentContentChangePartial{
+ Range: lsproto.Range{
+ Start: lsproto.Position{
+ Line: 0,
+ Character: 0,
+ },
+ End: lsproto.Position{
+ Line: 0,
+ Character: 0,
+ },
+ },
+ Text: "function fooBar() { }\n",
+ },
+ },
+ },
+ })
+ baselineRename(server)
+ }
+
+ testSuffix := func(server *testServer) {
+ openFileAndBaselineRename(server)
+ server.changeFile(&lsproto.DidChangeTextDocumentParams{
+ TextDocument: lsproto.VersionedTextDocumentIdentifier{
+ Uri: lsproto.DocumentUri("file://" + dependencyTs),
+ Version: 2,
+ },
+ ContentChanges: []lsproto.TextDocumentContentChangePartialOrWholeDocument{
+ {
+ Partial: &lsproto.TextDocumentContentChangePartial{
+ Range: lsproto.Range{
+ Start: lsproto.Position{
+ Line: 5,
+ Character: 0,
+ },
+ End: lsproto.Position{
+ Line: 5,
+ Character: 0,
+ },
+ },
+ Text: "const x = 10;",
+ },
+ },
+ },
+ })
+ baselineRename(server)
+ }
+
+ getAllConfigKindTests := func(subScenario string, testFn func(server *testServer)) []*lspServerTest {
+ return []*lspServerTest{
+ {
+ subScenario: subScenario + " with project references",
+ files: filesWithBuiltRef,
+ test: testFn,
+ },
+ {
+ subScenario: subScenario + " with disableSourceOfProjectReferenceRedirect",
+ files: filesWithDisableProjectRefSource,
+ test: testFn,
+ },
+ {
+ subScenario: subScenario + " with source maps",
+ files: fileWithNoRefs,
+ test: testFn,
+ },
+ }
+ }
+
+ return slices.Concat(
+ getAllConfigKindTests("rename", testRename),
+ getAllConfigKindTests("rename on edit", testPrefix),
+ getAllConfigKindTests("rename on edit at end", testSuffix),
+ []*lspServerTest{
+ {
+ subScenario: "rename before project is built",
+ files: filesWithRef,
+ test: testRename,
+ },
+ },
+ )
+}
diff --git a/internal/lsp/lspservertests/findallrefs_test.go b/internal/lsp/lspservertests/findallrefs_test.go
new file mode 100644
index 0000000000..509f603776
--- /dev/null
+++ b/internal/lsp/lspservertests/findallrefs_test.go
@@ -0,0 +1,780 @@
+package lspservertests
+
+import (
+ "fmt"
+ "maps"
+ "slices"
+ "strings"
+ "testing"
+
+ "github.com/microsoft/typescript-go/internal/bundled"
+ "github.com/microsoft/typescript-go/internal/core"
+ "github.com/microsoft/typescript-go/internal/execute/tsctests"
+ "github.com/microsoft/typescript-go/internal/lsp/lsproto"
+ "github.com/microsoft/typescript-go/internal/testutil/lsptestutil"
+ "github.com/microsoft/typescript-go/internal/testutil/stringtestutil"
+)
+
+func TestFindAllReferences(t *testing.T) {
+ t.Parallel()
+
+ if !bundled.Embedded {
+ t.Skip("bundled files are not embedded")
+ }
+
+ testCases := slices.Concat(
+ getFindAllRefsTestCasesForDefaultProjects(),
+ getFindAllRefsTestcasesForRootOfReferencedProject(),
+ []*lspServerTest{
+ {
+ subScenario: "finding local reference doesnt load ancestor sibling projects",
+ files: func() map[string]any {
+ return getFindAllRefsFileMapForLocalness(false)
+ },
+ test: func(server *testServer) {
+ programFile := "/user/username/projects/solution/compiler/program.ts"
+ server.openFile(programFile, lsproto.LanguageKindTypeScript)
+
+ // Find all references for getSourceFile
+ // Shouldnt load more projects
+ server.baselineReferences(programFile, lsptestutil.PositionToLineAndCharacter(programFile, server.content(programFile), "getSourceFile", 1))
+
+ // Find all references for getSourceFiles
+ // Should load more projects
+ server.baselineReferences(programFile, lsptestutil.PositionToLineAndCharacter(programFile, server.content(programFile), "getSourceFiles", 0))
+ },
+ },
+ {
+ subScenario: "disableSolutionSearching solution and siblings are not loaded",
+ files: func() map[string]any {
+ return getFindAllRefsFileMapForLocalness(true)
+ },
+ test: func(server *testServer) {
+ programFile := "/user/username/projects/solution/compiler/program.ts"
+ server.openFile(programFile, lsproto.LanguageKindTypeScript)
+
+ // Find all references
+ // No new solutions/projects loaded
+ server.baselineReferences(programFile, lsptestutil.PositionToLineAndCharacter(programFile, server.content(programFile), "getSourceFiles", 0))
+ },
+ },
+ {
+ subScenario: "finding references in overlapping projects",
+ files: func() map[string]any {
+ return map[string]any{
+ "/user/username/projects/solution/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "files": [],
+ "include": [],
+ "references": [
+ { "path": "./a" },
+ { "path": "./b" },
+ { "path": "./c" },
+ { "path": "./d" },
+ ],
+ }`),
+ "/user/username/projects/solution/a/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ },
+ "files": ["./index.ts"]
+ }`),
+ "/user/username/projects/solution/a/index.ts": stringtestutil.Dedent(`
+ export interface I {
+ M(): void;
+ }`),
+ "/user/username/projects/solution/b/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../a" },
+ ],
+ }`),
+ "/user/username/projects/solution/b/index.ts": stringtestutil.Dedent(`
+ import { I } from "../a";
+ export class B implements I {
+ M() {}
+ }`),
+ "/user/username/projects/solution/c/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../b" },
+ ],
+ }`),
+ "/user/username/projects/solution/c/index.ts": stringtestutil.Dedent(`
+ import { I } from "../a";
+ import { B } from "../b";
+ export const C: I = new B();`),
+ "/user/username/projects/solution/d/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../c" },
+ ],
+ }`),
+ "/user/username/projects/solution/d/index.ts": stringtestutil.Dedent(`
+ import { I } from "../a";
+ import { C } from "../c";
+ export const D: I = C;`),
+ }
+ },
+ test: func(server *testServer) {
+ bFile := "/user/username/projects/solution/b/index.ts"
+ server.openFile(bFile, lsproto.LanguageKindTypeScript)
+
+ // The first search will trigger project loads
+ server.baselineReferences(bFile, lsptestutil.PositionToLineAndCharacter(bFile, server.content(bFile), "I", 1))
+
+ // The second search starts with the projects already loaded
+ // Formerly, this would search some projects multiple times
+ server.baselineReferences(bFile, lsptestutil.PositionToLineAndCharacter(bFile, server.content(bFile), "I", 1))
+ },
+ },
+ {
+ subScenario: "files from two projects are open and one project references",
+ files: func() map[string]any {
+ files := map[string]any{}
+ applyPackageConfigAndFile := func(packageName string, references []string, disableReferencedProjectLoad bool) {
+ files[fmt.Sprintf("/user/username/projects/myproject/%s/src/file1.ts", packageName)] = fmt.Sprintf(`export const %sConst = 10;`, packageName)
+ var extraStr string
+ if disableReferencedProjectLoad {
+ extraStr = `"disableReferencedProjectLoad": true,`
+ }
+ var referencesStr strings.Builder
+ for _, ref := range references {
+ referencesStr.WriteString(fmt.Sprintf(`{ "path": "../%s" },\n`, ref))
+ }
+ files[fmt.Sprintf("/user/username/projects/myproject/%s/tsconfig.json", packageName)] = stringtestutil.Dedent(fmt.Sprintf(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ %s
+ },
+ %s
+ }
+ `, extraStr, referencesStr.String()))
+ }
+ applyPackageConfigAndFile("main", []string{"core", "indirect", "noCoreRef1", "indirectDisabledChildLoad1", "indirectDisabledChildLoad2", "refToCoreRef3", "indirectNoCoreRef"}, false)
+ applyPackageConfigAndFile("core", nil, false)
+ applyPackageConfigAndFile("noCoreRef1", nil, false)
+ applyPackageConfigAndFile("indirect", []string{"coreRef1"}, false)
+ applyPackageConfigAndFile("coreRef1", []string{"core"}, false)
+ applyPackageConfigAndFile("indirectDisabledChildLoad1", []string{"coreRef2"}, true)
+ applyPackageConfigAndFile("coreRef2", []string{"core"}, false)
+ applyPackageConfigAndFile("indirectDisabledChildLoad2", []string{"coreRef3"}, true)
+ applyPackageConfigAndFile("coreRef3", []string{"core"}, false)
+ applyPackageConfigAndFile("refToCoreRef3", []string{"coreRef3"}, false)
+ applyPackageConfigAndFile("indirectNoCoreRef", []string{"noCoreRef2"}, false)
+ applyPackageConfigAndFile("noCoreRef2", nil, false)
+ return files
+ },
+ test: func(server *testServer) {
+ mainFile := "/user/username/projects/myproject/main/src/file1.ts"
+ coreFile := "/user/username/projects/myproject/core/src/file1.ts"
+ server.openFile(mainFile, lsproto.LanguageKindTypeScript)
+ server.openFile(coreFile, lsproto.LanguageKindTypeScript)
+
+ // Find all refs in coreFile
+ server.baselineReferences(coreFile, lsptestutil.PositionToLineAndCharacter(coreFile, server.content(coreFile), "coreConst", 0))
+ },
+ },
+ {
+ subScenario: "does not try to open a file in a project that was updated and no longer has the file",
+ files: func() map[string]any {
+ return map[string]any{
+ "/home/src/projects/project/packages/babel-loader/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "target": "ES2018",
+ "module": "commonjs",
+ "strict": true,
+ "esModuleInterop": true,
+ "composite": true,
+ "rootDir": "src",
+ "outDir": "dist"
+ },
+ "include": ["src"],
+ "references": [{"path": "../core"}]
+ }`),
+ "/home/src/projects/project/packages/babel-loader/src/index.ts": stringtestutil.Dedent(`
+ import type { Foo } from "../../core/src/index.js";`),
+ "/home/src/projects/project/packages/core/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "target": "ES2018",
+ "module": "commonjs",
+ "strict": true,
+ "esModuleInterop": true,
+ "composite": true,
+ "rootDir": "./src",
+ "outDir": "./dist",
+ },
+ "include": ["./src"]
+ }`),
+ "/home/src/projects/project/packages/core/src/index.ts": stringtestutil.Dedent(`
+ import { Bar } from "./loading-indicator.js";
+ export type Foo = {};
+ const bar: Bar = {
+ prop: 0
+ }`),
+ "/home/src/projects/project/packages/core/src/loading-indicator.ts": stringtestutil.Dedent(`
+ export interface Bar {
+ prop: number;
+ }
+ const bar: Bar = {
+ prop: 1
+ }`),
+ }
+ },
+ test: func(server *testServer) {
+ // Open files in the two configured projects
+ indexFile := "/home/src/projects/project/packages/babel-loader/src/index.ts"
+ coreFile := "/home/src/projects/project/packages/core/src/index.ts"
+ server.openFile(indexFile, lsproto.LanguageKindTypeScript)
+ server.openFile(coreFile, lsproto.LanguageKindTypeScript)
+
+ // Now change `babel-loader` project to no longer import `core` project
+ server.changeFile(&lsproto.DidChangeTextDocumentParams{
+ TextDocument: lsproto.VersionedTextDocumentIdentifier{
+ Uri: lsproto.DocumentUri("file://" + indexFile),
+ Version: 2,
+ },
+ ContentChanges: []lsproto.TextDocumentContentChangePartialOrWholeDocument{
+ {
+ Partial: &lsproto.TextDocumentContentChangePartial{
+ Range: lsproto.Range{
+ Start: lsproto.Position{
+ Line: 0,
+ Character: 0,
+ },
+ End: lsproto.Position{
+ Line: 0,
+ Character: 0,
+ },
+ },
+ Text: "// comment",
+ },
+ },
+ },
+ })
+
+ // At this point, we haven't updated `babel-loader` project yet,
+ // so `babel-loader` is still a containing project of `loading-indicator` file.
+ // When calling find all references,
+ // we shouldn't crash due to using outdated information on a file's containing projects.
+ server.baselineReferences(coreFile, lsptestutil.PositionToLineAndCharacter(coreFile, server.content(coreFile), "prop", 0))
+ },
+ },
+ {
+ subScenario: "references on file opened is in configured project that will be removed",
+ files: func() map[string]any {
+ return map[string]any{
+ "/user/username/projects/myproject/playground/tsconfig.json": "{}",
+ "/user/username/projects/myproject/playground/tests.ts": "export function foo() {}",
+ "/user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts": "export function bar() { }",
+ "/user/username/projects/myproject/playground/tsconfig-json/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "include": ["./src"],
+ }`),
+ "/user/username/projects/myproject/playground/tsconfig-json/src/src.ts": "export function foobar() { }",
+ }
+ },
+ test: func(server *testServer) {
+ testsFile := "/user/username/projects/myproject/playground/tests.ts"
+ server.openFile(testsFile, lsproto.LanguageKindTypeScript)
+ server.closeFile(testsFile)
+ innerFile := "/user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts"
+ server.openFile(innerFile, lsproto.LanguageKindTypeScript)
+ server.baselineReferences(innerFile, lsptestutil.PositionToLineAndCharacter(innerFile, server.content(innerFile), "bar", 0))
+ },
+ },
+ getFindAllRefsTestCaseForSpecialLocalnessHandling(
+ "when using arrow function assignment",
+ `export const dog = () => { };`,
+ `shared.dog();`,
+ "dog",
+ ),
+ getFindAllRefsTestCaseForSpecialLocalnessHandling(
+ "when using arrow function as object literal property types",
+ `export const foo = { bar: () => { } };`,
+ `shared.foo.bar();`,
+ "bar",
+ ),
+ getFindAllRefsTestCaseForSpecialLocalnessHandling(
+ "when using object literal property",
+ `export const foo = { baz: "BAZ" };`,
+ `shared.foo.baz;`,
+ "baz",
+ ),
+ getFindAllRefsTestCaseForSpecialLocalnessHandling(
+ "when using method of class expression",
+ `export const foo = class { fly() {} };`,
+ stringtestutil.Dedent(`
+ const instance = new shared.foo();
+ instance.fly();`),
+ "fly",
+ ),
+ getFindAllRefsTestCaseForSpecialLocalnessHandling(
+ // when using arrow function as object literal property is loaded through indirect assignment with original declaration local to project is treated as local
+ "when using arrow function as object literal property",
+ stringtestutil.Dedent(`
+ const local = { bar: () => { } };
+ export const foo = local;`),
+ `shared.foo.bar();`,
+ "bar",
+ ),
+ // Pre-loaded = A file from project B is already open when FindAllRefs is invoked
+ // dRPL = Project A has disableReferencedProjectLoad
+ // dSOPRR = Project A has disableSourceOfProjectReferenceRedirect
+ // Map = The declaration map file b/lib/index.d.ts.map exists
+ // B refs = files under directory b in which references are found (all scenarios find all references in a/index.ts)
+
+ // Pre-loaded |dRPL|dSOPRR|Map | B state | Notes | B refs | Notes
+ // -----------+----+------+------+------------------+--------------+---------------------+---------------------------------------------------
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, true, true, true), // Pre-loaded | | index.ts, helper.ts | Via map and pre-loaded project
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, true, true, false), // Pre-loaded | | lib/index.d.ts | Even though project is loaded
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, true, false, true), // Pre-loaded | | index.ts, helper.ts |
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, true, false, false), // Pre-loaded | | index.ts, helper.ts |
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, false, true, true), // Pre-loaded | | index.ts, helper.ts | Via map and pre-loaded project
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, false, true, false), // Pre-loaded | | lib/index.d.ts | Even though project is loaded
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, false, false, true), // Pre-loaded | | index.ts, helper.ts |
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(true, false, false, false), // Pre-loaded | | index.ts, helper.ts |
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, true, true, true), // Not loaded | | lib/index.d.ts | Even though map is present
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, true, true, false), // Not loaded | | lib/index.d.ts |
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, true, false, true), // Not loaded | | index.ts | But not helper.ts, which is not referenced from a
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, true, false, false), // Not loaded | | index.ts | But not helper.ts, which is not referenced from a
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, false, true, true), // Loaded | Via map | index.ts, helper.ts | Via map and newly loaded project
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, false, true, false), // Not loaded | | lib/index.d.ts |
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, false, false, true), // Loaded | Via redirect | index.ts, helper.ts |
+ getTestcaseFindAllRefsWithDisableReferencedProjectLoad(false, false, false, false), // Loaded | Via redirect | index.ts, helper.ts |
+ },
+ )
+
+ for _, test := range testCases {
+ test.run(t, "findAllRefs")
+ }
+}
+
+func getFindAllRefsTestCasesForDefaultProjects() []*lspServerTest {
+ filesForSolutionConfigFile := func(solutionRefs []string, disableReferencedProjectLoad bool, ownFiles []string) map[string]any {
+ var disableReferencedProjectLoadStr string
+ if disableReferencedProjectLoad {
+ disableReferencedProjectLoadStr = `"disableReferencedProjectLoad": true`
+ }
+ var ownFilesStr string
+ if len(ownFiles) > 0 {
+ ownFilesStr = strings.Join(ownFiles, ",")
+ }
+ files := map[string]any{
+ "/user/username/workspaces/dummy/dummy.ts": `const x = 1;`,
+ "/user/username/workspaces/dummy/tsconfig.json": `{ }`,
+ "/user/username/projects/myproject/tsconfig.json": stringtestutil.Dedent(fmt.Sprintf(`
+ {
+ "compilerOptions": {
+ %s
+ },
+ "files": [%s],
+ "references": [
+ %s
+ ]
+ }`, disableReferencedProjectLoadStr, ownFilesStr, strings.Join(core.Map(solutionRefs, func(ref string) string {
+ return fmt.Sprintf(`{ "path": "%s" }`, ref)
+ }), ","))),
+ "/user/username/projects/myproject/tsconfig-src.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target",
+ },
+ "include": ["./src/**/*"]
+ }`),
+ "/user/username/projects/myproject/src/main.ts": stringtestutil.Dedent(`
+ import { foo } from './helpers/functions';
+ foo()`),
+ "/user/username/projects/myproject/src/helpers/functions.ts": `export function foo() { return 1; }`,
+ "/user/username/projects/myproject/indirect3/tsconfig.json": `{ }`,
+ "/user/username/projects/myproject/indirect3/main.ts": stringtestutil.Dedent(`
+ import { foo } from '../target/src/main';
+ foo()
+ export function bar() {}`),
+ }
+ return files
+ }
+ filesForIndirectProject := func(projectIndex int, compilerOptions string) map[string]any {
+ files := map[string]any{
+ fmt.Sprintf("/user/username/projects/myproject/tsconfig-indirect%d.json", projectIndex): fmt.Sprintf(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target/",
+ %s
+ },
+ "files": [
+ "./indirect%d/main.ts"
+ ],
+ "references": [
+ {
+ "path": "./tsconfig-src.json"
+ }
+ ]
+ }`, compilerOptions, projectIndex),
+ fmt.Sprintf("/user/username/projects/myproject/indirect%d/main.ts", projectIndex): `export const indirect = 1;`,
+ }
+ return files
+ }
+ applyIndirectProjectFiles := func(files map[string]any, projectIndex int, compilerOptions string) {
+ maps.Copy(files, filesForIndirectProject(projectIndex, compilerOptions))
+ }
+ testSolution := func(server *testServer) {
+ file := "/user/username/projects/myproject/src/main.ts"
+ // Ensure configured project is found for open file
+ server.openFile(file, lsproto.LanguageKindTypeScript)
+
+ // !!! TODO Verify errors
+
+ dummyFile := "/user/username/workspaces/dummy/dummy.ts"
+
+ server.openFile(dummyFile, lsproto.LanguageKindTypeScript)
+
+ server.closeFile(dummyFile)
+ server.closeFile(file)
+ server.openFile(dummyFile, lsproto.LanguageKindTypeScript)
+
+ server.closeFile(dummyFile)
+ server.openFile(file, lsproto.LanguageKindTypeScript)
+
+ // Find all ref in default project
+ server.baselineReferences(file, lsptestutil.PositionToLineAndCharacter(file, server.content(file), "foo", 1))
+
+ server.closeFile(file)
+ file = "/user/username/projects/myproject/indirect3/main.ts"
+ server.openFile(file, lsproto.LanguageKindTypeScript)
+
+ // Find all ref in non default project
+ server.baselineReferences(file, lsptestutil.PositionToLineAndCharacter(file, server.content(file), "foo", 0))
+ }
+ return []*lspServerTest{
+ {
+ subScenario: "project found is solution referencing default project directly",
+ files: func() map[string]any {
+ return filesForSolutionConfigFile([]string{"./tsconfig-src.json"}, false, nil)
+ },
+ test: testSolution,
+ },
+ {
+ subScenario: "project found is solution referencing default project indirectly",
+ files: func() map[string]any {
+ files := filesForSolutionConfigFile([]string{"./tsconfig-indirect1.json", "./tsconfig-indirect2.json"}, false, nil)
+ applyIndirectProjectFiles(files, 1, "")
+ applyIndirectProjectFiles(files, 2, "")
+ return files
+ },
+ test: testSolution,
+ },
+ {
+ subScenario: "project found is solution with disableReferencedProjectLoad referencing default project directly",
+ files: func() map[string]any {
+ return filesForSolutionConfigFile([]string{"./tsconfig-src.json"}, true, nil)
+ },
+ test: testSolution,
+ },
+ {
+ subScenario: "project found is solution referencing default project indirectly through disableReferencedProjectLoad",
+ files: func() map[string]any {
+ files := filesForSolutionConfigFile([]string{"./tsconfig-indirect1.json", "./tsconfig-indirect2.json"}, false, nil)
+ applyIndirectProjectFiles(files, 1, `"disableReferencedProjectLoad": true`)
+ return files
+ },
+ test: testSolution,
+ },
+ {
+ subScenario: "project found is solution referencing default project indirectly through disableReferencedProjectLoad in one but without it in another",
+ files: func() map[string]any {
+ files := filesForSolutionConfigFile([]string{"./tsconfig-indirect1.json", "./tsconfig-indirect2.json"}, false, nil)
+ applyIndirectProjectFiles(files, 1, `"disableReferencedProjectLoad": true`)
+ applyIndirectProjectFiles(files, 2, "")
+ return files
+ },
+ test: testSolution,
+ },
+ {
+ subScenario: "project found is project with own files referencing the file from referenced project",
+ files: func() map[string]any {
+ files := filesForSolutionConfigFile([]string{"./tsconfig-src.json"}, false, []string{`"./own/main.ts"`})
+ files["/user/username/projects/myproject/own/main.ts"] = stringtestutil.Dedent(`
+ import { foo } from '../src/main';
+ foo;
+ export function bar() {}
+ `)
+ return files
+ },
+ test: testSolution,
+ },
+ }
+}
+
+func getFindAllRefsTestcasesForRootOfReferencedProject() []*lspServerTest {
+ files := func(disableSourceOfProjectReferenceRedirect bool) map[string]any {
+ return map[string]any{
+ "/user/username/projects/project/src/common/input/keyboard.ts": stringtestutil.Dedent(`
+ function bar() { return "just a random function so .d.ts location doesnt match"; }
+ export function evaluateKeyboardEvent() { }
+ `),
+ "/user/username/projects/project/src/common/input/keyboard.test.ts": stringtestutil.Dedent(`
+ import { evaluateKeyboardEvent } from 'common/input/keyboard';
+ function testEvaluateKeyboardEvent() {
+ return evaluateKeyboardEvent();
+ }`),
+ "/user/username/projects/project/src/terminal.ts": stringtestutil.Dedent(`
+ import { evaluateKeyboardEvent } from 'common/input/keyboard';
+ function foo() {
+ return evaluateKeyboardEvent();
+ }`),
+ "/user/username/projects/project/src/common/tsconfig.json": stringtestutil.Dedent(fmt.Sprintf(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "../../out",
+ "disableSourceOfProjectReferenceRedirect": %v,
+ "paths": {
+ "*": ["../*"],
+ },
+ },
+ "include": ["./**/*"]
+ }`, disableSourceOfProjectReferenceRedirect)),
+ "/user/username/projects/project/src/tsconfig.json": stringtestutil.Dedent(fmt.Sprintf(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "../out",
+ "disableSourceOfProjectReferenceRedirect": %v,
+ "paths": {
+ "common/*": ["./common/*"],
+ },
+ "tsBuildInfoFile": "../out/src.tsconfig.tsbuildinfo"
+ },
+ "include": ["./**/*"],
+ "references": [
+ { "path": "./common" },
+ ],
+ }`, disableSourceOfProjectReferenceRedirect)),
+ }
+ }
+ testSolution := func(server *testServer) {
+ keyboardTs := "/user/username/projects/project/src/common/input/keyboard.ts"
+ terminalTs := "/user/username/projects/project/src/terminal.ts"
+ server.openFile(keyboardTs, lsproto.LanguageKindTypeScript)
+ server.openFile(terminalTs, lsproto.LanguageKindTypeScript)
+
+ // Find all ref in default project
+ server.baselineReferences(keyboardTs, lsptestutil.PositionToLineAndCharacter(keyboardTs, server.content(keyboardTs), "evaluateKeyboardEvent", 0))
+ }
+ return []*lspServerTest{
+ {
+ subScenario: "root file is file from referenced project",
+ files: func() map[string]any {
+ return files(false)
+ },
+ test: testSolution,
+ },
+ {
+ subScenario: "root file is file from referenced project and using declaration maps",
+ files: func() map[string]any {
+ return tsctests.GetFileMapWithBuild(files(true), []string{"-b", "/user/username/projects/project/src/tsconfig.json"})
+ },
+ test: testSolution,
+ },
+ }
+}
+
+func getFindAllRefsFileMapForLocalness(disableSolutionSearching bool) map[string]any {
+ var extraStr string
+ if disableSolutionSearching {
+ extraStr = `"disableSolutionSearching": true,`
+ }
+ return map[string]any{
+ "/user/username/projects/solution/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "files": [],
+ "include": [],
+ "references": [
+ { "path": "./compiler" },
+ { "path": "./services" },
+ ],
+ }`),
+ "/user/username/projects/solution/compiler/tsconfig.json": stringtestutil.Dedent(fmt.Sprintf(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ %s
+ },
+ "files": ["./types.ts", "./program.ts"]
+ }`, extraStr)),
+ "/user/username/projects/solution/compiler/types.ts": stringtestutil.Dedent(`
+ namespace ts {
+ export interface Program {
+ getSourceFiles(): string[];
+ }
+ }`),
+ "/user/username/projects/solution/compiler/program.ts": stringtestutil.Dedent(`
+ namespace ts {
+ export const program: Program = {
+ getSourceFiles: () => [getSourceFile()]
+ };
+ function getSourceFile() { return "something"; }
+ }`),
+ "/user/username/projects/solution/services/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./services.ts"],
+ "references": [
+ { "path": "../compiler" },
+ ],
+ }`),
+ "/user/username/projects/solution/services/services.ts": stringtestutil.Dedent(`
+ ///
+ ///
+ namespace ts {
+ const result = program.getSourceFiles();
+ }`),
+ }
+}
+
+func getFindAllRefsTestCaseForSpecialLocalnessHandling(scenario string, definition string, usage string, referenceTerm string) *lspServerTest {
+ return &lspServerTest{
+ subScenario: "special handling of localness " + scenario,
+ files: func() map[string]any {
+ return map[string]any{
+ "/user/username/projects/solution/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "files": [],
+ "references": [
+ { "path": "./api" },
+ { "path": "./app" },
+ ],
+ }`),
+ "/user/username/projects/solution/api/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+ }`),
+ "/user/username/projects/solution/api/src/server.ts": `import * as shared from "../../shared/dist"` + "\n" + usage,
+ "/user/username/projects/solution/app/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+ }`),
+ "/user/username/projects/solution/app/src/app.ts": `import * as shared from "../../shared/dist"` + "\n" + usage,
+ "/user/username/projects/solution/shared/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ }`),
+ "/user/username/projects/solution/shared/src/index.ts": definition,
+ }
+ },
+ test: func(server *testServer) {
+ apiFile := "/user/username/projects/solution/api/src/server.ts"
+ server.openFile(apiFile, lsproto.LanguageKindTypeScript)
+
+ // Find all references
+ server.baselineReferences(apiFile, lsptestutil.PositionToLineAndCharacter(apiFile, server.content(apiFile), referenceTerm, 0))
+ },
+ }
+}
+
+func getTestcaseFindAllRefsWithDisableReferencedProjectLoad(
+ projectAlreadyLoaded bool,
+ disableReferencedProjectLoad bool,
+ disableSourceOfProjectReferenceRedirect bool,
+ dtsMapPresent bool,
+) *lspServerTest {
+ subScenario := fmt.Sprintf(`when proj %s loaded`, core.IfElse(projectAlreadyLoaded, "is", "is not")) +
+ ` and refd proj loading is ` + core.IfElse(disableReferencedProjectLoad, "disabled", "enabled") +
+ ` and proj ref redirects are ` + core.IfElse(disableSourceOfProjectReferenceRedirect, "disabled", "enabled") +
+ ` and a decl map is ` + core.IfElse(dtsMapPresent, "present", "missing")
+
+ return &lspServerTest{
+ subScenario: "find refs to decl in other proj " + subScenario,
+ files: func() map[string]any {
+ files := map[string]any{
+ "/user/username/projects/myproject/a/tsconfig.json": stringtestutil.Dedent(fmt.Sprintf(`
+ {
+ "disableReferencedProjectLoad": %t,
+ "disableSourceOfProjectReferenceRedirect": %t,
+ "composite": true
+ }`, disableReferencedProjectLoad, disableSourceOfProjectReferenceRedirect)),
+ "/user/username/projects/myproject/a/index.ts": stringtestutil.Dedent(`
+ import { B } from "../b/lib";
+ const b: B = new B();`),
+ "/user/username/projects/myproject/b/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+ }`),
+ "/user/username/projects/myproject/b/index.ts": stringtestutil.Dedent(`
+ export class B {
+ M() {}
+ }`),
+ "/user/username/projects/myproject/b/helper.ts": stringtestutil.Dedent(`
+ import { B } from ".";
+ const b: B = new B();`),
+ "/user/username/projects/myproject/b/lib/index.d.ts": stringtestutil.Dedent(`
+ export declare class B {
+ M(): void;
+ }
+ //# sourceMappingURL=index.d.ts.map`),
+ }
+ if dtsMapPresent {
+ files["/user/username/projects/myproject/b/lib/index.d.ts.map"] = stringtestutil.Dedent(`
+ {
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+ }`)
+ }
+ return files
+ },
+ test: func(server *testServer) {
+ indexA := "/user/username/projects/myproject/a/index.ts"
+ server.openFile(indexA, lsproto.LanguageKindTypeScript)
+ if projectAlreadyLoaded {
+ server.openFile("/user/username/projects/myproject/b/helper.ts", lsproto.LanguageKindTypeScript)
+ }
+ server.baselineReferences(indexA, lsptestutil.PositionToLineAndCharacter(indexA, server.content(indexA), "B", 1))
+ },
+ }
+}
diff --git a/internal/lsp/lspservertests/rename_test.go b/internal/lsp/lspservertests/rename_test.go
new file mode 100644
index 0000000000..0b90135952
--- /dev/null
+++ b/internal/lsp/lspservertests/rename_test.go
@@ -0,0 +1,136 @@
+package lspservertests
+
+import (
+ "testing"
+
+ "github.com/microsoft/typescript-go/internal/bundled"
+ "github.com/microsoft/typescript-go/internal/lsp/lsproto"
+ "github.com/microsoft/typescript-go/internal/testutil/lsptestutil"
+ "github.com/microsoft/typescript-go/internal/testutil/stringtestutil"
+ "github.com/microsoft/typescript-go/internal/vfs/vfstest"
+)
+
+func TestRename(t *testing.T) {
+ t.Parallel()
+
+ if !bundled.Embedded {
+ t.Skip("bundled files are not embedded")
+ }
+
+ testCases := []*lspServerTest{
+ {
+ subScenario: "ancestor and project ref management",
+ files: func() map[string]any {
+ return map[string]any{
+ "/user/username/projects/temp/temp.ts": "let x = 10",
+ "/user/username/projects/temp/tsconfig.json": "{}",
+ "/user/username/projects/container/lib/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ },
+ references: [],
+ files: [
+ "index.ts",
+ ],
+ }`),
+ "/user/username/projects/container/lib/index.ts": stringtestutil.Dedent(`
+ export const myConst = 30;`),
+ "/user/username/projects/container/exec/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../lib" },
+ ],
+ }`),
+ "/user/username/projects/container/exec/index.ts": stringtestutil.Dedent(`
+ import { myConst } from "../lib";
+ export function getMyConst() {
+ return myConst;
+ }`),
+ "/user/username/projects/container/compositeExec/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "compilerOptions": {
+ "composite": true,
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../lib" },
+ ],
+ }`),
+ "/user/username/projects/container/compositeExec/index.ts": stringtestutil.Dedent(`
+ import { myConst } from "../lib";
+ export function getMyConst() {
+ return myConst;
+ }`),
+ "/user/username/projects/container/tsconfig.json": stringtestutil.Dedent(`
+ {
+ "files": [],
+ "include": [],
+ "references": [
+ { "path": "./exec" },
+ { "path": "./compositeExec" },
+ ],
+ }`),
+ }
+ },
+ test: func(server *testServer) {
+ file := "/user/username/projects/container/compositeExec/index.ts"
+ temp := "/user/username/projects/temp/temp.ts"
+ server.openFile(file, lsproto.LanguageKindTypeScript)
+ // Open temp file and verify all projects alive
+ server.openFile(temp, lsproto.LanguageKindTypeScript)
+
+ // Ref projects are loaded after as part of this command
+ server.baselineRename(file, lsptestutil.PositionToLineAndCharacter(file, server.content(file), "myConst", 0))
+
+ // Open temp file and verify all projects alive
+ server.closeFile(temp)
+ server.openFile(temp, lsproto.LanguageKindTypeScript)
+
+ // Close all files and open temp file, only inferred project should be alive
+ server.closeFile(file)
+ server.closeFile(temp)
+ server.openFile(temp, lsproto.LanguageKindTypeScript)
+ },
+ },
+ {
+ subScenario: "rename in common file renames all project",
+ files: func() map[string]any {
+ return map[string]any{
+ "/users/username/projects/a/a.ts": stringtestutil.Dedent(`
+ import {C} from "./c/fc";
+ console.log(C)
+ `),
+ "/users/username/projects/a/tsconfig.json": "{}",
+ "/users/username/projects/a/c": vfstest.Symlink("/users/username/projects/c"),
+ "/users/username/projects/b/b.ts": stringtestutil.Dedent(`
+ import {C} from "../c/fc";
+ console.log(C)
+ `),
+ "/users/username/projects/b/tsconfig.json": "{}",
+ "/users/username/projects/b/c": vfstest.Symlink("/users/username/projects/c"),
+ "/users/username/projects/c/fc.ts": stringtestutil.Dedent(`
+ export const C = 42;
+ `),
+ }
+ },
+ test: func(server *testServer) {
+ aTs := "/users/username/projects/a/a.ts"
+ bTs := "/users/username/projects/b/b.ts"
+ aFc := "/users/username/projects/a/c/fc.ts"
+ bFc := "/users/username/projects/b/c/fc.ts"
+ server.openFile(aTs, lsproto.LanguageKindTypeScript)
+ server.openFile(bTs, lsproto.LanguageKindTypeScript)
+ cContent := server.content("/users/username/projects/c/fc.ts")
+ server.openFileWithContent(aFc, cContent, lsproto.LanguageKindTypeScript)
+ server.openFileWithContent(bFc, cContent, lsproto.LanguageKindTypeScript)
+ server.baselineRename(aFc, lsptestutil.PositionToLineAndCharacter(aFc, cContent, "C", 0))
+ },
+ },
+ }
+
+ for _, test := range testCases {
+ test.run(t, "rename")
+ }
+}
diff --git a/internal/lsp/lspservertests/runner.go b/internal/lsp/lspservertests/runner.go
new file mode 100644
index 0000000000..c3b1225f43
--- /dev/null
+++ b/internal/lsp/lspservertests/runner.go
@@ -0,0 +1,25 @@
+package lspservertests
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/microsoft/typescript-go/internal/testutil/baseline"
+ "github.com/microsoft/typescript-go/internal/tspath"
+)
+
+type lspServerTest struct {
+ subScenario string
+ files func() map[string]any
+ test func(server *testServer)
+}
+
+func (test *lspServerTest) run(t *testing.T, scenario string) {
+ t.Helper()
+ t.Run(scenario+"/"+test.subScenario, func(t *testing.T) {
+ t.Parallel()
+ server := newTestServer(t, test.files())
+ test.test(server)
+ baseline.Run(t, strings.ReplaceAll(test.subScenario, " ", "-")+".js", server.baseline.String(), baseline.Options{Subfolder: tspath.CombinePaths("lspservertests", scenario)})
+ })
+}
diff --git a/internal/lsp/lspservertests/statediff.go b/internal/lsp/lspservertests/statediff.go
new file mode 100644
index 0000000000..cac1646e4c
--- /dev/null
+++ b/internal/lsp/lspservertests/statediff.go
@@ -0,0 +1,431 @@
+package lspservertests
+
+import (
+ "fmt"
+ "io"
+ "iter"
+ "maps"
+ "slices"
+
+ "github.com/microsoft/typescript-go/internal/collections"
+ "github.com/microsoft/typescript-go/internal/compiler"
+ "github.com/microsoft/typescript-go/internal/project"
+ "github.com/microsoft/typescript-go/internal/tspath"
+)
+
+type projectInfo = *compiler.Program
+
+type openFileInfo struct {
+ defaultProjectName string
+ allProjects []string
+}
+
+type diffTableOptions struct {
+ indent string
+ sortKeys bool
+}
+
+type diffTable struct {
+ diff collections.OrderedMap[string, string]
+ options diffTableOptions
+}
+
+func (d *diffTable) add(key, value string) {
+ d.diff.Set(key, value)
+}
+
+func (d *diffTable) print(w io.Writer, header string) {
+ count := d.diff.Size()
+ if count == 0 {
+ return
+ }
+ if header != "" {
+ fmt.Fprintf(w, "%s%s\n", d.options.indent, header)
+ }
+ diffKeys := make([]string, 0, count)
+ keyWidth := 0
+ indent := d.options.indent + " "
+ for key := range d.diff.Keys() {
+ keyWidth = max(keyWidth, len(key))
+ diffKeys = append(diffKeys, key)
+ }
+ if d.options.sortKeys {
+ slices.Sort(diffKeys)
+ }
+
+ for _, key := range diffKeys {
+ value := d.diff.GetOrZero(key)
+ fmt.Fprintf(w, "%s%-*s %s\n", indent, keyWidth+1, key, value)
+ }
+}
+
+type diffTableWriter struct {
+ hasChange bool
+ header string
+ diffs map[string]func(io.Writer)
+}
+
+func newDiffTableWriter(header string) *diffTableWriter {
+ return &diffTableWriter{header: header, diffs: make(map[string]func(io.Writer))}
+}
+
+func (d *diffTableWriter) setHasChange() {
+ d.hasChange = true
+}
+
+func (d *diffTableWriter) add(key string, fn func(io.Writer)) {
+ d.diffs[key] = fn
+}
+
+func (d *diffTableWriter) print(w io.Writer) {
+ if d.hasChange {
+ fmt.Fprintf(w, "%s::\n", d.header)
+ keys := slices.Collect(maps.Keys(d.diffs))
+ slices.Sort(keys)
+ for _, key := range keys {
+ d.diffs[key](w)
+ }
+ }
+}
+
+func areIterSeqEqual(a, b iter.Seq[tspath.Path]) bool {
+ aSlice := slices.Collect(a)
+ bSlice := slices.Collect(b)
+ slices.Sort(aSlice)
+ slices.Sort(bSlice)
+ return slices.Equal(aSlice, bSlice)
+}
+
+func printSlicesWithDiffTable(w io.Writer, header string, newSlice []string, getOldSlice func() []string, options diffTableOptions, topChange string, isDefault func(entry string) bool) {
+ var oldSlice []string
+ if topChange == "*modified*" {
+ oldSlice = getOldSlice()
+ }
+ table := diffTable{options: options}
+ for _, entry := range newSlice {
+ entryChange := ""
+ if isDefault != nil && isDefault(entry) {
+ entryChange = "(default) "
+ }
+ if topChange == "*modified*" && !slices.Contains(oldSlice, entry) {
+ entryChange = "*new*"
+ }
+ table.add(entry, entryChange)
+ }
+ if topChange == "*modified*" {
+ for _, entry := range oldSlice {
+ if !slices.Contains(newSlice, entry) {
+ table.add(entry, "*deleted*")
+ }
+ }
+ }
+ table.print(w, header)
+}
+
+func sliceFromIterSeqPath(seq iter.Seq[tspath.Path]) []string {
+ var result []string
+ for path := range seq {
+ result = append(result, string(path))
+ }
+ slices.Sort(result)
+ return result
+}
+
+func printPathIterSeqWithDiffTable(w io.Writer, header string, newIterSeq iter.Seq[tspath.Path], getOldIterSeq func() iter.Seq[tspath.Path], options diffTableOptions, topChange string) {
+ printSlicesWithDiffTable(
+ w,
+ header,
+ sliceFromIterSeqPath(newIterSeq),
+ func() []string { return sliceFromIterSeqPath(getOldIterSeq()) },
+ options,
+ topChange,
+ nil,
+ )
+}
+
+type stateDiff struct {
+ server *testServer
+ snapshot *project.Snapshot
+
+ currentProjects map[string]projectInfo
+ projectDiffs *diffTableWriter
+
+ currentOpenFiles map[string]*openFileInfo
+ filesDiff *diffTableWriter
+
+ configFileRegistry *project.ConfigFileRegistry
+ configDiffs *diffTableWriter
+ configFileNamesDiffs *diffTableWriter
+}
+
+func printStateDiff(server *testServer, w io.Writer) {
+ if !server.isInitialized {
+ return
+ }
+ snapshot, release := server.server.Session().Snapshot()
+ defer release()
+
+ stateDiff := &stateDiff{
+ server: server,
+ snapshot: snapshot,
+ configFileRegistry: snapshot.ProjectCollection.ConfigFileRegistry(),
+ currentProjects: make(map[string]projectInfo),
+ currentOpenFiles: make(map[string]*openFileInfo),
+ projectDiffs: newDiffTableWriter("Projects"),
+ filesDiff: newDiffTableWriter("Open Files"),
+ configDiffs: newDiffTableWriter("Config"),
+ configFileNamesDiffs: newDiffTableWriter("Config File Names"),
+ }
+ stateDiff.checkProjects()
+ stateDiff.checkOpenFiles()
+ stateDiff.checkConfigFileRegistry()
+ stateDiff.print(w)
+}
+
+func (d *stateDiff) checkProjects() {
+ d.server.t.Helper()
+ options := diffTableOptions{indent: " "}
+ for _, project := range d.snapshot.ProjectCollection.Projects() {
+ program := project.GetProgram()
+ var oldProgram *compiler.Program
+ d.currentProjects[project.Name()] = program
+ projectChange := ""
+ if existing, ok := d.server.serializedProjects[project.Name()]; ok {
+ oldProgram = existing
+ if oldProgram != program {
+ projectChange = "*modified*"
+ d.projectDiffs.setHasChange()
+ } else {
+ projectChange = ""
+ }
+ } else {
+ projectChange = "*new*"
+ d.projectDiffs.setHasChange()
+ }
+
+ d.projectDiffs.add(project.Name(), func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] %s\n", project.Name(), projectChange)
+ subDiff := diffTable{options: options}
+ if program != nil {
+ for _, file := range program.GetSourceFiles() {
+ fileDiff := ""
+ // No need to write "*new*" for files as its obvious
+ fileName := file.FileName()
+ if projectChange == "*modified*" {
+ if oldProgram == nil {
+ if !d.server.isLibFile(fileName) {
+ fileDiff = "*new*"
+ }
+ } else if oldFile := oldProgram.GetSourceFileByPath(file.Path()); oldFile == nil {
+ fileDiff = "*new*"
+ } else if oldFile != file {
+ fileDiff = "*modified*"
+ }
+ }
+ if fileDiff != "" || !d.server.isLibFile(fileName) {
+ subDiff.add(fileName, fileDiff)
+ }
+ }
+ }
+ if oldProgram != program && oldProgram != nil {
+ for _, file := range oldProgram.GetSourceFiles() {
+ if program == nil || program.GetSourceFileByPath(file.Path()) == nil {
+ subDiff.add(file.FileName(), "*deleted*")
+ }
+ }
+ }
+ subDiff.print(w, "")
+ })
+ }
+
+ for projectName, info := range d.server.serializedProjects {
+ if _, found := d.currentProjects[projectName]; !found {
+ d.projectDiffs.setHasChange()
+ d.projectDiffs.add(projectName, func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] *deleted*\n", projectName)
+ subDiff := diffTable{options: options}
+ if info != nil {
+ for _, file := range info.GetSourceFiles() {
+ if fileName := file.FileName(); !d.server.isLibFile(fileName) {
+ subDiff.add(fileName, "")
+ }
+ }
+ }
+ subDiff.print(w, "")
+ })
+ }
+ }
+ d.server.serializedProjects = d.currentProjects
+}
+
+func (d *stateDiff) checkOpenFiles() {
+ d.server.t.Helper()
+ options := diffTableOptions{indent: " ", sortKeys: true}
+ for fileName := range d.server.openFiles {
+ path := tspath.ToPath(fileName, "/", d.server.server.FS.UseCaseSensitiveFileNames())
+ defaultProject := d.snapshot.ProjectCollection.GetDefaultProject(fileName, path)
+ newFileInfo := &openFileInfo{}
+ if defaultProject != nil {
+ newFileInfo.defaultProjectName = defaultProject.Name()
+ }
+ for _, project := range d.snapshot.ProjectCollection.Projects() {
+ if program := project.GetProgram(); program != nil && program.GetSourceFileByPath(path) != nil {
+ newFileInfo.allProjects = append(newFileInfo.allProjects, project.Name())
+ }
+ }
+ slices.Sort(newFileInfo.allProjects)
+ d.currentOpenFiles[fileName] = newFileInfo
+ openFileChange := ""
+ var oldFileInfo *openFileInfo
+ if existing, ok := d.server.serializedOpenFiles[fileName]; ok {
+ oldFileInfo = existing
+ if existing.defaultProjectName != newFileInfo.defaultProjectName || !slices.Equal(existing.allProjects, newFileInfo.allProjects) {
+ openFileChange = "*modified*"
+ d.filesDiff.setHasChange()
+ } else {
+ openFileChange = ""
+ }
+ } else {
+ openFileChange = "*new*"
+ d.filesDiff.setHasChange()
+ }
+
+ d.filesDiff.add(fileName, func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] %s\n", fileName, openFileChange)
+ printSlicesWithDiffTable(
+ w,
+ "",
+ newFileInfo.allProjects,
+ func() []string { return oldFileInfo.allProjects },
+ options,
+ openFileChange,
+ func(projectName string) bool { return projectName == newFileInfo.defaultProjectName },
+ )
+ })
+ }
+ for fileName := range d.server.serializedOpenFiles {
+ if _, found := d.currentOpenFiles[fileName]; !found {
+ d.filesDiff.setHasChange()
+ d.filesDiff.add(fileName, func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] *closed*\n", fileName)
+ })
+ }
+ }
+ d.server.serializedOpenFiles = d.currentOpenFiles
+}
+
+func (d *stateDiff) checkConfigFileRegistry() {
+ if d.server.serializedConfigFileRegistry == d.configFileRegistry {
+ return
+ }
+ options := diffTableOptions{indent: " ", sortKeys: true}
+ d.configFileRegistry.ForEachTestConfigEntry(func(path tspath.Path, entry *project.TestConfigEntry) {
+ configChange := ""
+ oldEntry := d.server.serializedConfigFileRegistry.GetTestConfigEntry(path)
+ if oldEntry == nil {
+ configChange = "*new*"
+ d.configDiffs.setHasChange()
+ } else if oldEntry != entry {
+ if !areIterSeqEqual(oldEntry.RetainingProjects, entry.RetainingProjects) ||
+ !areIterSeqEqual(oldEntry.RetainingOpenFiles, entry.RetainingOpenFiles) ||
+ !areIterSeqEqual(oldEntry.RetainingConfigs, entry.RetainingConfigs) {
+ configChange = "*modified*"
+ d.configDiffs.setHasChange()
+ }
+ }
+ d.configDiffs.add(string(path), func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] %s\n", entry.FileName, configChange)
+ // Print the details of the config entry
+ var retainingProjectsModified string
+ var retainingOpenFilesModified string
+ var retainingConfigsModified string
+ if configChange == "*modified*" {
+ if !areIterSeqEqual(entry.RetainingProjects, oldEntry.RetainingProjects) {
+ retainingProjectsModified = " *modified*"
+ }
+ if !areIterSeqEqual(entry.RetainingOpenFiles, oldEntry.RetainingOpenFiles) {
+ retainingOpenFilesModified = " *modified*"
+ }
+ if !areIterSeqEqual(entry.RetainingConfigs, oldEntry.RetainingConfigs) {
+ retainingConfigsModified = " *modified*"
+ }
+ }
+ printPathIterSeqWithDiffTable(w, "RetainingProjects:"+retainingProjectsModified, entry.RetainingProjects, func() iter.Seq[tspath.Path] { return oldEntry.RetainingProjects }, options, configChange)
+ printPathIterSeqWithDiffTable(w, "RetainingOpenFiles:"+retainingOpenFilesModified, entry.RetainingOpenFiles, func() iter.Seq[tspath.Path] { return oldEntry.RetainingOpenFiles }, options, configChange)
+ printPathIterSeqWithDiffTable(w, "RetainingConfigs:"+retainingConfigsModified, entry.RetainingConfigs, func() iter.Seq[tspath.Path] { return oldEntry.RetainingConfigs }, options, configChange)
+ })
+ })
+ d.configFileRegistry.ForEachTestConfigFileNamesEntry(func(path tspath.Path, entry *project.TestConfigFileNamesEntry) {
+ configFileNamesChange := ""
+ oldEntry := d.server.serializedConfigFileRegistry.GetTestConfigFileNamesEntry(path)
+ if oldEntry == nil {
+ configFileNamesChange = "*new*"
+ d.configFileNamesDiffs.setHasChange()
+ } else if oldEntry.NearestConfigFileName != entry.NearestConfigFileName ||
+ !maps.Equal(oldEntry.Ancestors, entry.Ancestors) {
+ configFileNamesChange = "*modified*"
+ d.configFileNamesDiffs.setHasChange()
+ }
+ d.configFileNamesDiffs.add(string(path), func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] %s\n", path, configFileNamesChange)
+ var nearestConfigFileNameModified string
+ var ancestorDiffModified string
+ if configFileNamesChange == "*modified*" {
+ if oldEntry.NearestConfigFileName != entry.NearestConfigFileName {
+ nearestConfigFileNameModified = " *modified*"
+ }
+ if !maps.Equal(oldEntry.Ancestors, entry.Ancestors) {
+ ancestorDiffModified = " *modified*"
+ }
+ }
+ fmt.Fprintf(w, " NearestConfigFileName: %s%s\n", entry.NearestConfigFileName, nearestConfigFileNameModified)
+ ancestorDiff := diffTable{options: options}
+ for config, ancestorOfConfig := range entry.Ancestors {
+ ancestorChange := ""
+ if configFileNamesChange == "*modified*" {
+ if oldConfigFileName, ok := oldEntry.Ancestors[config]; ok {
+ if oldConfigFileName != ancestorOfConfig {
+ ancestorChange = "*modified*"
+ }
+ } else {
+ ancestorChange = "*new*"
+ }
+ }
+ ancestorDiff.add(config, fmt.Sprintf("%s %s", ancestorOfConfig, ancestorChange))
+ }
+ if configFileNamesChange == "*modified*" {
+ for ancestorPath, oldConfigFileName := range oldEntry.Ancestors {
+ if _, ok := entry.Ancestors[ancestorPath]; !ok {
+ ancestorDiff.add(ancestorPath, oldConfigFileName+" *deleted*")
+ }
+ }
+ }
+ ancestorDiff.print(w, "Ancestors:"+ancestorDiffModified)
+ })
+ })
+
+ d.server.serializedConfigFileRegistry.ForEachTestConfigEntry(func(path tspath.Path, entry *project.TestConfigEntry) {
+ if d.configFileRegistry.GetTestConfigEntry(path) == nil {
+ d.configDiffs.setHasChange()
+ d.configDiffs.add(string(path), func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] *deleted*\n", entry.FileName)
+ })
+ }
+ })
+ d.server.serializedConfigFileRegistry.ForEachTestConfigFileNamesEntry(func(path tspath.Path, entry *project.TestConfigFileNamesEntry) {
+ if d.configFileRegistry.GetTestConfigFileNamesEntry(path) == nil {
+ d.configFileNamesDiffs.setHasChange()
+ d.configFileNamesDiffs.add(string(path), func(w io.Writer) {
+ fmt.Fprintf(w, " [%s] *deleted*\n", path)
+ })
+ }
+ })
+ d.server.serializedConfigFileRegistry = d.configFileRegistry
+}
+
+func (d *stateDiff) print(w io.Writer) {
+ d.projectDiffs.print(w)
+ d.filesDiff.print(w)
+ d.configDiffs.print(w)
+ d.configFileNamesDiffs.print(w)
+}
diff --git a/internal/lsp/lspservertests/testserver.go b/internal/lsp/lspservertests/testserver.go
new file mode 100644
index 0000000000..2c7b119335
--- /dev/null
+++ b/internal/lsp/lspservertests/testserver.go
@@ -0,0 +1,254 @@
+package lspservertests
+
+import (
+ "fmt"
+ "strings"
+ "testing"
+
+ "github.com/go-json-experiment/json"
+ "github.com/go-json-experiment/json/jsontext"
+ "github.com/microsoft/typescript-go/internal/bundled"
+ "github.com/microsoft/typescript-go/internal/collections"
+ "github.com/microsoft/typescript-go/internal/ls/lsconv"
+ "github.com/microsoft/typescript-go/internal/lsp/lsproto"
+ "github.com/microsoft/typescript-go/internal/project"
+ "github.com/microsoft/typescript-go/internal/testutil/fsbaselineutil"
+ "github.com/microsoft/typescript-go/internal/testutil/lsptestutil"
+ "github.com/microsoft/typescript-go/internal/testutil/projecttestutil"
+ "gotest.tools/v3/assert"
+)
+
+type testServer struct {
+ t *testing.T
+ files map[string]any
+ server *lsptestutil.TestLspServer
+ utils *projecttestutil.SessionUtils
+ baseline strings.Builder
+ fsDiffer *fsbaselineutil.FSDiffer
+ writtenFiles collections.SyncSet[string]
+ isInitialized bool
+
+ serializedProjects map[string]projectInfo
+ serializedOpenFiles map[string]*openFileInfo
+ serializedConfigFileRegistry *project.ConfigFileRegistry
+ openFiles map[string]string
+}
+
+func newTestServer(t *testing.T, files map[string]any) *testServer {
+ t.Helper()
+ server, utils := lsptestutil.Setup(t, files)
+ testServer := &testServer{
+ t: t,
+ files: files,
+ server: server,
+ utils: utils,
+ openFiles: make(map[string]string),
+ }
+ testServer.fsDiffer = &fsbaselineutil.FSDiffer{
+ FS: utils.FsFromFileMap(),
+ WrittenFiles: &testServer.writtenFiles,
+ }
+ fmt.Fprintf(&testServer.baseline, "UseCaseSensitiveFileNames: %v\n", utils.FsFromFileMap().UseCaseSensitiveFileNames())
+ testServer.fsDiffer.BaselineFSwithDiff(&testServer.baseline)
+ return testServer
+}
+
+func (s *testServer) content(fileName string) string {
+ if text, ok := s.openFiles[fileName]; ok {
+ return text
+ }
+ return s.files[fileName].(string)
+}
+
+func (s *testServer) hoverToWriteProjectStatus(fileName string) {
+ // Do hover so we have snapshot to check things on!!
+ _, _, resultOk := lsptestutil.SendRequest(s.t, s.server, lsproto.TextDocumentHoverInfo, &lsproto.HoverParams{
+ TextDocument: lsproto.TextDocumentIdentifier{
+ Uri: lsproto.DocumentUri("file://" + fileName),
+ },
+ Position: lsproto.Position{
+ Line: uint32(0),
+ Character: uint32(0),
+ },
+ })
+ assert.Assert(s.t, resultOk)
+}
+
+func (s *testServer) baselineProjectsAfterNotification(fileName string) {
+ s.t.Helper()
+ s.hoverToWriteProjectStatus(fileName)
+ s.baselineState(false)
+}
+
+func (s *testServer) baselineState(before bool) {
+ s.t.Helper()
+
+ serialized := s.serializedState()
+ if serialized != "" {
+ s.baseline.WriteString(serialized)
+ }
+}
+
+func (s *testServer) serializedState() string {
+ var builder strings.Builder
+ s.fsDiffer.BaselineFSwithDiff(&builder)
+ if strings.TrimSpace(builder.String()) == "" {
+ builder.Reset()
+ }
+
+ printStateDiff(s, &builder)
+ return builder.String()
+}
+
+func (s *testServer) isLibFile(fileName string) bool {
+ return strings.HasPrefix(fileName, bundled.LibPath()+"/")
+}
+
+type requestOrMessage struct {
+ Method lsproto.Method `json:"method"`
+ Params any `json:"params,omitzero"`
+}
+
+func baselineRequestOrNotification(t *testing.T, server *testServer, method lsproto.Method, params any) {
+ server.t.Helper()
+ server.baselineState(true)
+ res, _ := json.Marshal(requestOrMessage{
+ Method: method,
+ Params: params,
+ }, jsontext.WithIndent(" "))
+ server.baseline.WriteString(fmt.Sprintln(string(res)))
+ server.isInitialized = true
+}
+
+func sendNotification[Params any](t *testing.T, server *testServer, info lsproto.NotificationInfo[Params], params Params) {
+ server.t.Helper()
+ baselineRequestOrNotification(t, server, info.Method, params)
+ switch info.Method {
+ case lsproto.TextDocumentDidOpenInfo.Method:
+ openFileParams := any(params).(*lsproto.DidOpenTextDocumentParams)
+ server.openFiles[openFileParams.TextDocument.Uri.FileName()] = openFileParams.TextDocument.Text
+ case lsproto.TextDocumentDidCloseInfo.Method:
+ closeFileParams := any(params).(*lsproto.DidCloseTextDocumentParams)
+ delete(server.openFiles, closeFileParams.TextDocument.Uri.FileName())
+ case lsproto.TextDocumentDidChangeInfo.Method:
+ changeFileParams := any(params).(*lsproto.DidChangeTextDocumentParams)
+ fileName := changeFileParams.TextDocument.Uri.FileName()
+ text := server.openFiles[fileName]
+ converters := lsconv.NewConverters(lsproto.PositionEncodingKindUTF8, func(fileName string) *lsconv.LSPLineMap {
+ return lsconv.ComputeLSPLineStarts(text)
+ })
+ // Update the contents in openFiles
+ for _, textChange := range changeFileParams.ContentChanges {
+ if partialChange := textChange.Partial; partialChange != nil {
+ text = converters.FromLSPTextChange(lsptestutil.NewLsScript(fileName, text), partialChange).ApplyTo(text)
+ } else if wholeChange := textChange.WholeDocument; wholeChange != nil {
+ text = wholeChange.Text
+ }
+ }
+ server.openFiles[fileName] = text
+ }
+ lsptestutil.SendNotification(server.t, server.server, info, params)
+}
+
+func sendRequest[Params, Resp any](t *testing.T, server *testServer, info lsproto.RequestInfo[Params, Resp], params Params) Resp {
+ server.t.Helper()
+ baselineRequestOrNotification(t, server, info.Method, params)
+ resMsg, result, resultOk := lsptestutil.SendRequest(t, server.server, info, params)
+ server.baselineState(false)
+ if resMsg == nil {
+ server.t.Fatalf("Nil response received for %s", info.Method)
+ }
+ if !resultOk {
+ server.t.Fatalf("Unexpected response type for %s: %T", info.Method, resMsg.AsResponse().Result)
+ }
+ return result
+}
+
+func (s *testServer) openFile(fileName string, languageID lsproto.LanguageKind) {
+ s.t.Helper()
+ s.openFileWithContent(fileName, s.content(fileName), languageID)
+}
+
+func (s *testServer) openFileWithContent(fileName string, content string, languageID lsproto.LanguageKind) {
+ s.t.Helper()
+ sendNotification(s.t, s, lsproto.TextDocumentDidOpenInfo, &lsproto.DidOpenTextDocumentParams{
+ TextDocument: &lsproto.TextDocumentItem{
+ Uri: lsproto.DocumentUri("file://" + fileName),
+ LanguageId: languageID,
+ Text: content,
+ },
+ })
+ s.baselineProjectsAfterNotification(fileName)
+}
+
+func (s *testServer) closeFile(fileName string) {
+ s.t.Helper()
+ sendNotification(s.t, s, lsproto.TextDocumentDidCloseInfo, &lsproto.DidCloseTextDocumentParams{
+ TextDocument: lsproto.TextDocumentIdentifier{
+ Uri: lsproto.DocumentUri("file://" + fileName),
+ },
+ })
+ // Skip baselining projects here since updated snapshot is not generated right away after this
+}
+
+func (s *testServer) changeFile(params *lsproto.DidChangeTextDocumentParams) {
+ s.t.Helper()
+ sendNotification(s.t, s, lsproto.TextDocumentDidChangeInfo, params)
+ // Skip baselining projects here since updated snapshot is not generated right away after this
+}
+
+func (s *testServer) baselineReferences(fileName string, position lsproto.Position) {
+ s.t.Helper()
+ result := sendRequest(s.t, s, lsproto.TextDocumentReferencesInfo, &lsproto.ReferenceParams{
+ TextDocument: lsproto.TextDocumentIdentifier{
+ Uri: lsproto.DocumentUri("file://" + fileName),
+ },
+ Position: position,
+ Context: &lsproto.ReferenceContext{},
+ })
+ s.baseline.WriteString(lsptestutil.GetBaselineForLocationsWithFileContents(s.server.FS, *result.Locations, lsptestutil.BaselineLocationsOptions{
+ Marker: &marker{fileName, position},
+ MarkerName: "/*FIND ALL REFS*/",
+ OpenFiles: s.openFiles,
+ }) + "\n")
+}
+
+func (s *testServer) baselineRename(fileName string, position lsproto.Position) {
+ s.t.Helper()
+ result := sendRequest(s.t, s, lsproto.TextDocumentRenameInfo, &lsproto.RenameParams{
+ TextDocument: lsproto.TextDocumentIdentifier{
+ Uri: lsproto.DocumentUri("file://" + fileName),
+ },
+ Position: position,
+ NewName: "?",
+ })
+ s.baseline.WriteString(lsptestutil.GetBaselineForRename(s.server.FS, result, lsptestutil.BaselineLocationsOptions{
+ Marker: &marker{fileName, position},
+ OpenFiles: s.openFiles,
+ }) + "\n")
+}
+
+func (s *testServer) baselineWorkspaceSymbol(query string) {
+ s.t.Helper()
+ result := sendRequest(s.t, s, lsproto.WorkspaceSymbolInfo, &lsproto.WorkspaceSymbolParams{
+ Query: query,
+ })
+ s.baseline.WriteString(lsptestutil.GetBaselineForWorkspaceSymbol(s.server.FS, result, lsptestutil.BaselineLocationsOptions{
+ OpenFiles: s.openFiles,
+ }) + "\n")
+}
+
+type marker struct {
+ fileName string
+ position lsproto.Position
+}
+
+var _ lsptestutil.LocationMarker = (*marker)(nil)
+
+func (m *marker) FileName() string {
+ return m.fileName
+}
+
+func (m *marker) LSPos() lsproto.Position {
+ return m.position
+}
diff --git a/internal/lsp/server.go b/internal/lsp/server.go
index cecd426747..3cbc7ff2e9 100644
--- a/internal/lsp/server.go
+++ b/internal/lsp/server.go
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"io"
+ "iter"
"runtime/debug"
"slices"
"sync"
@@ -12,6 +13,7 @@ import (
"time"
"github.com/go-json-experiment/json"
+ "github.com/microsoft/typescript-go/internal/ast"
"github.com/microsoft/typescript-go/internal/collections"
"github.com/microsoft/typescript-go/internal/core"
"github.com/microsoft/typescript-go/internal/ls"
@@ -38,17 +40,27 @@ type ServerOptions struct {
TypingsLocation string
ParseCache *project.ParseCache
NpmInstall func(cwd string, args []string) ([]byte, error)
+
+ // Test options
+ Client project.Client
+ Logger logging.Logger
}
func NewServer(opts *ServerOptions) *Server {
if opts.Cwd == "" {
panic("Cwd is required")
}
+ var logger logging.Logger
+ if opts.Logger != nil {
+ logger = opts.Logger
+ } else {
+ logger = logging.NewLogger(opts.Err)
+ }
return &Server{
r: opts.In,
w: opts.Out,
stderr: opts.Err,
- logger: logging.NewLogger(opts.Err),
+ logger: logger,
requestQueue: make(chan *lsproto.RequestMessage, 100),
outgoingQueue: make(chan *lsproto.Message, 100),
pendingClientRequests: make(map[lsproto.ID]pendingClientRequest),
@@ -59,6 +71,7 @@ func NewServer(opts *ServerOptions) *Server {
typingsLocation: opts.TypingsLocation,
parseCache: opts.ParseCache,
npmInstall: opts.NpmInstall,
+ client: opts.Client,
}
}
@@ -153,6 +166,9 @@ type Server struct {
session *project.Session
+ // Test options for initializing session
+ client project.Client
+
// !!! temporary; remove when we have `handleDidChangeConfiguration`/implicit project config support
compilerOptionsForInferredProjects *core.CompilerOptions
// parseCache can be passed in so separate tests can share ASTs
@@ -161,6 +177,8 @@ type Server struct {
npmInstall func(cwd string, args []string) ([]byte, error)
}
+func (s *Server) Session() *project.Session { return s.session }
+
// WatchFiles implements project.Client.
func (s *Server) WatchFiles(ctx context.Context, id project.WatcherID, watchers []*lsproto.FileSystemWatcher) error {
_, err := s.sendRequest(ctx, lsproto.MethodClientRegisterCapability, &lsproto.RegistrationParams{
@@ -480,16 +498,18 @@ var handlers = sync.OnceValue(func() handlerMap {
registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDefinitionInfo, (*Server).handleDefinition)
registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentTypeDefinitionInfo, (*Server).handleTypeDefinition)
registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentCompletionInfo, (*Server).handleCompletion)
- registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentReferencesInfo, (*Server).handleReferences)
registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentImplementationInfo, (*Server).handleImplementations)
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.TextDocumentRenameInfo, (*Server).handleRename)
registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentDocumentHighlightInfo, (*Server).handleDocumentHighlight)
registerLanguageServiceDocumentRequestHandler(handlers, lsproto.TextDocumentSelectionRangeInfo, (*Server).handleSelectionRange)
+
+ registerMultiProjectReferenceRequestHandler(handlers, lsproto.TextDocumentReferencesInfo, (*Server).handleReferences, combineReferences)
+ registerMultiProjectReferenceRequestHandler(handlers, lsproto.TextDocumentRenameInfo, (*Server).handleRename, combineRenameResponse)
+
registerRequestHandler(handlers, lsproto.WorkspaceSymbolInfo, (*Server).handleWorkspaceSymbol)
registerRequestHandler(handlers, lsproto.CompletionItemResolveInfo, (*Server).handleCompletionItemResolve)
@@ -565,6 +585,215 @@ func registerLanguageServiceDocumentRequestHandler[Req lsproto.HasTextDocumentUR
}
}
+type projectAndTextDocumentPosition struct {
+ project *project.Project
+ ls *ls.LanguageService
+ Uri lsproto.DocumentUri
+ Position lsproto.Position
+}
+
+type response[Resp any] struct {
+ complete bool
+ result Resp
+}
+
+func registerMultiProjectReferenceRequestHandler[Req lsproto.HasTextDocumentPosition, Resp any](
+ handlers handlerMap,
+ info lsproto.RequestInfo[Req, Resp],
+ fn func(*Server, context.Context, *ls.LanguageService, Req, *ast.Node, []*ls.SymbolAndEntries) (Resp, error),
+ combineResults func(iter.Seq[Resp]) Resp,
+) {
+ handlers[info.Method] = func(s *Server, ctx context.Context, req *lsproto.RequestMessage) error {
+ var params Req
+ // Ignore empty params.
+ if req.Params != nil {
+ params = req.Params.(Req)
+ }
+ // !!! sheetal: multiple projects that contain the file through symlinks
+ defaultProject, defaultLs, allProjects, err := s.session.GetLanguageServiceAndProjectsForFile(ctx, params.TextDocumentURI())
+ if err != nil {
+ return err
+ }
+ defer s.recover(req)
+
+ var results collections.SyncMap[tspath.Path, *response[Resp]]
+ var defaultDefinition *ls.NonLocalDefinition
+ canSearchProject := func(project *project.Project) bool {
+ _, searched := results.Load(project.Id())
+ return !searched
+ }
+ wg := core.NewWorkGroup(false)
+ var errMu sync.Mutex
+ var enqueueItem func(item projectAndTextDocumentPosition)
+ enqueueItem = func(item projectAndTextDocumentPosition) {
+ var response response[Resp]
+ if _, loaded := results.LoadOrStore(item.project.Id(), &response); loaded {
+ return
+ }
+ wg.Queue(func() {
+ if ctx.Err() != nil {
+ return
+ }
+ defer s.recover(req)
+ // Process the item
+ ls := item.ls
+ if ls == nil {
+ // Get it now
+ ls = s.session.GetLanguageServiceForProjectWithFile(ctx, item.project, item.Uri)
+ if ls == nil {
+ return
+ }
+ }
+ originalNode, symbolsAndEntries, ok := ls.ProvideSymbolsAndEntries(ctx, item.Uri, item.Position, info.Method == lsproto.MethodTextDocumentRename)
+ if ok {
+ for _, entry := range symbolsAndEntries {
+ // Find the default definition that can be in another project
+ // Later we will use this load ancestor tree that references this location and expand search
+ if item.project == defaultProject && defaultDefinition == nil {
+ defaultDefinition = ls.GetNonLocalDefinition(ctx, entry)
+ }
+ ls.ForEachOriginalDefinitionLocation(ctx, entry, func(uri lsproto.DocumentUri, position lsproto.Position) {
+ // Get default configured project for this file
+ defProjects, errProjects := s.session.GetProjectsForFile(ctx, uri)
+ if errProjects != nil {
+ return
+ }
+ for _, defProject := range defProjects {
+ // Optimization: don't enqueue if will be discarded
+ if canSearchProject(defProject) {
+ enqueueItem(projectAndTextDocumentPosition{
+ project: defProject,
+ Uri: uri,
+ Position: position,
+ })
+ }
+ }
+ })
+ }
+ }
+
+ if result, errSearch := fn(s, ctx, ls, params, originalNode, symbolsAndEntries); errSearch == nil {
+ response.complete = true
+ response.result = result
+ } else {
+ errMu.Lock()
+ defer errMu.Unlock()
+ if err != nil {
+ err = errSearch
+ }
+ }
+ })
+ }
+
+ // Initial set of projects and locations in the queue, starting with default project
+ enqueueItem(projectAndTextDocumentPosition{
+ project: defaultProject,
+ ls: defaultLs,
+ Uri: params.TextDocumentURI(),
+ Position: params.TextDocumentPosition(),
+ })
+ for _, project := range allProjects {
+ if project != defaultProject {
+ enqueueItem(projectAndTextDocumentPosition{
+ project: project,
+ // TODO!! symlinks need to change the URI
+ Uri: params.TextDocumentURI(),
+ Position: params.TextDocumentPosition(),
+ })
+ }
+ }
+
+ getResultsIterator := func() iter.Seq[Resp] {
+ return func(yield func(Resp) bool) {
+ var seenProjects collections.SyncSet[tspath.Path]
+ if response, loaded := results.Load(defaultProject.Id()); loaded && response.complete {
+ if !yield(response.result) {
+ return
+ }
+ }
+ seenProjects.Add(defaultProject.Id())
+ for _, project := range allProjects {
+ if seenProjects.AddIfAbsent(project.Id()) {
+ if response, loaded := results.Load(project.Id()); loaded && response.complete {
+ if !yield(response.result) {
+ return
+ }
+ }
+ }
+ }
+ results.Range(func(key tspath.Path, response *response[Resp]) bool {
+ if seenProjects.AddIfAbsent(key) && response.complete {
+ return yield(response.result)
+ }
+ return true
+ })
+ }
+ }
+
+ // Outer loop - to complete work if more is added after completing existing queue
+ for {
+ // Process existing known projects first
+ wg.RunAndWait()
+ if ctx.Err() != nil {
+ return ctx.Err()
+ }
+ // No need to use mu here since we are not in parallel at this point
+ if err != nil {
+ return err
+ }
+
+ wg = core.NewWorkGroup(false)
+ hasMoreWork := false
+ if defaultDefinition != nil {
+ requestedProjectTrees := make(map[tspath.Path]struct{})
+ results.Range(func(key tspath.Path, response *response[Resp]) bool {
+ if response.complete {
+ requestedProjectTrees[key] = struct{}{}
+ }
+ return true
+ })
+
+ // Load more projects based on default definition found
+ if errFromLoadingTree := s.session.ForEachProjectLocationLoadingProjectTree(
+ ctx,
+ requestedProjectTrees,
+ defaultDefinition,
+ // Can loop forever without this (enqueue here, dequeue above, repeat)
+ canSearchProject,
+ func(project *project.Project, uri lsproto.DocumentUri, position lsproto.Position) {
+ // Enqueue the project and location for further processing
+ enqueueItem(projectAndTextDocumentPosition{
+ project: project,
+ Uri: uri,
+ Position: position,
+ })
+ hasMoreWork = true
+ },
+ ); errFromLoadingTree != nil {
+ return errFromLoadingTree
+ }
+ }
+ if !hasMoreWork {
+ break
+ }
+ }
+
+ var resp Resp
+ if results.Size() > 1 {
+ resp = combineResults(getResultsIterator())
+ } else {
+ // Single result, return that directly
+ for value := range getResultsIterator() {
+ resp = value
+ break
+ }
+ }
+
+ s.sendResult(req.ID, resp)
+ return nil
+ }
+}
+
func (s *Server) recover(req *lsproto.RequestMessage) {
if r := recover(); r != nil {
stack := debug.Stack()
@@ -701,6 +930,13 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali
cwd = s.cwd
}
+ var client project.Client
+ if s.client != nil {
+ client = s.client
+ } else {
+ client = s
+ }
+
s.session = project.NewSession(&project.SessionInit{
Options: &project.SessionOptions{
CurrentDirectory: cwd,
@@ -711,11 +947,10 @@ func (s *Server) handleInitialized(ctx context.Context, params *lsproto.Initiali
LoggingEnabled: true,
DebounceDelay: 500 * time.Millisecond,
},
- FS: s.fs,
- Logger: s.logger,
- Client: s,
- NpmExecutor: s,
- ParseCache: s.parseCache,
+ FS: s.fs,
+ Logger: s.logger,
+ Client: client,
+ ParseCache: s.parseCache,
})
if s.initializeParams != nil && s.initializeParams.InitializationOptions != nil && *s.initializeParams.InitializationOptions != nil {
@@ -826,9 +1061,25 @@ func (s *Server) handleTypeDefinition(ctx context.Context, ls *ls.LanguageServic
return ls.ProvideTypeDefinition(ctx, params.TextDocument.Uri, params.Position, getTypeDefinitionClientSupportsLink(s.initializeParams))
}
-func (s *Server) handleReferences(ctx context.Context, ls *ls.LanguageService, params *lsproto.ReferenceParams) (lsproto.ReferencesResponse, error) {
+func (s *Server) handleReferences(ctx context.Context, ls *ls.LanguageService, params *lsproto.ReferenceParams, originalNode *ast.Node, symbolAndEntries []*ls.SymbolAndEntries) (lsproto.ReferencesResponse, error) {
// findAllReferences
- return ls.ProvideReferences(ctx, params)
+ return ls.ProvideReferencesFromSymbolAndEntries(ctx, params, originalNode, symbolAndEntries)
+}
+
+func combineReferences(results iter.Seq[lsproto.ReferencesResponse]) lsproto.ReferencesResponse {
+ var combined []lsproto.Location
+ var seenLocations collections.Set[lsproto.Location]
+ for resp := range results {
+ if resp.Locations != nil {
+ for _, loc := range *resp.Locations {
+ if !seenLocations.Has(loc) {
+ seenLocations.Add(loc)
+ combined = append(combined, loc)
+ }
+ }
+ }
+ }
+ return lsproto.LocationsOrNull{Locations: &combined}
}
func (s *Server) handleImplementations(ctx context.Context, ls *ls.LanguageService, params *lsproto.ImplementationParams) (lsproto.ImplementationResponse, error) {
@@ -892,9 +1143,9 @@ func (s *Server) handleDocumentOnTypeFormat(ctx context.Context, ls *ls.Language
}
func (s *Server) handleWorkspaceSymbol(ctx context.Context, params *lsproto.WorkspaceSymbolParams, reqMsg *lsproto.RequestMessage) (lsproto.WorkspaceSymbolResponse, error) {
- snapshot, release := s.session.Snapshot()
- defer release()
+ snapshot := s.session.GetSnapshotLoadingProjectTree(ctx, nil)
defer s.recover(reqMsg)
+
programs := core.Map(snapshot.ProjectCollection.Projects(), (*project.Project).GetProgram)
return ls.ProvideWorkspaceSymbols(ctx, programs, snapshot.Converters(), params.Query)
}
@@ -903,8 +1154,47 @@ func (s *Server) handleDocumentSymbol(ctx context.Context, ls *ls.LanguageServic
return ls.ProvideDocumentSymbols(ctx, params.TextDocument.Uri, getDocumentSymbolClientSupportsHierarchical(s.initializeParams))
}
-func (s *Server) handleRename(ctx context.Context, ls *ls.LanguageService, params *lsproto.RenameParams) (lsproto.RenameResponse, error) {
- return ls.ProvideRename(ctx, params)
+func (s *Server) handleRename(ctx context.Context, ls *ls.LanguageService, params *lsproto.RenameParams, originalNode *ast.Node, symbolAndEntries []*ls.SymbolAndEntries) (lsproto.RenameResponse, error) {
+ return ls.ProvideRenameFromSymbolAndEntries(ctx, params, originalNode, symbolAndEntries)
+}
+
+func combineRenameResponse(results iter.Seq[lsproto.RenameResponse]) lsproto.RenameResponse {
+ combined := make(map[lsproto.DocumentUri][]*lsproto.TextEdit)
+ seenChanges := make(map[lsproto.DocumentUri]*collections.Set[lsproto.Range])
+ // !!! this is not used any more so we will skip this part of deduplication and combining
+ // DocumentChanges *[]TextDocumentEditOrCreateFileOrRenameFileOrDeleteFile `json:"documentChanges,omitzero"`
+ // ChangeAnnotations *map[string]*ChangeAnnotation `json:"changeAnnotations,omitzero"`
+
+ for resp := range results {
+ if resp.WorkspaceEdit != nil && resp.WorkspaceEdit.Changes != nil {
+ for doc, changes := range *resp.WorkspaceEdit.Changes {
+ seenSet, ok := seenChanges[doc]
+ if !ok {
+ seenSet = &collections.Set[lsproto.Range]{}
+ seenChanges[doc] = seenSet
+ }
+ changesForDoc, exists := combined[doc]
+ if !exists {
+ changesForDoc = []*lsproto.TextEdit{}
+ }
+ for _, change := range changes {
+ if !seenSet.Has(change.Range) {
+ seenSet.Add(change.Range)
+ changesForDoc = append(changesForDoc, change)
+ }
+ }
+ combined[doc] = changesForDoc
+ }
+ }
+ }
+ if len(combined) > 0 {
+ return lsproto.RenameResponse{
+ WorkspaceEdit: &lsproto.WorkspaceEdit{
+ Changes: &combined,
+ },
+ }
+ }
+ return lsproto.RenameResponse{}
}
func (s *Server) handleDocumentHighlight(ctx context.Context, ls *ls.LanguageService, params *lsproto.DocumentHighlightParams) (lsproto.DocumentHighlightResponse, error) {
diff --git a/internal/project/configfileregistry.go b/internal/project/configfileregistry.go
index 000decbd3e..45d862f48a 100644
--- a/internal/project/configfileregistry.go
+++ b/internal/project/configfileregistry.go
@@ -1,6 +1,7 @@
package project
import (
+ "iter"
"maps"
"github.com/microsoft/typescript-go/internal/core"
@@ -108,6 +109,73 @@ func (c *ConfigFileRegistry) clone() *ConfigFileRegistry {
}
}
+// For testing
+type TestConfigEntry struct {
+ FileName string
+ RetainingProjects iter.Seq[tspath.Path]
+ RetainingOpenFiles iter.Seq[tspath.Path]
+ RetainingConfigs iter.Seq[tspath.Path]
+}
+
+// For testing
+func (c *ConfigFileRegistry) ForEachTestConfigEntry(cb func(tspath.Path, *TestConfigEntry)) {
+ if c != nil {
+ for path, entry := range c.configs {
+ cb(path, &TestConfigEntry{
+ FileName: entry.fileName,
+ RetainingProjects: maps.Keys(entry.retainingProjects),
+ RetainingOpenFiles: maps.Keys(entry.retainingOpenFiles),
+ RetainingConfigs: maps.Keys(entry.retainingConfigs),
+ })
+ }
+ }
+}
+
+// For testing
+func (c *ConfigFileRegistry) GetTestConfigEntry(path tspath.Path) *TestConfigEntry {
+ if c != nil {
+ if entry, ok := c.configs[path]; ok {
+ return &TestConfigEntry{
+ FileName: entry.fileName,
+ RetainingProjects: maps.Keys(entry.retainingProjects),
+ RetainingOpenFiles: maps.Keys(entry.retainingOpenFiles),
+ RetainingConfigs: maps.Keys(entry.retainingConfigs),
+ }
+ }
+ }
+ return nil
+}
+
+type TestConfigFileNamesEntry struct {
+ NearestConfigFileName string
+ Ancestors map[string]string
+}
+
+// For testing
+func (c *ConfigFileRegistry) ForEachTestConfigFileNamesEntry(cb func(tspath.Path, *TestConfigFileNamesEntry)) {
+ if c != nil {
+ for path, entry := range c.configFileNames {
+ cb(path, &TestConfigFileNamesEntry{
+ NearestConfigFileName: entry.nearestConfigFileName,
+ Ancestors: entry.ancestors,
+ })
+ }
+ }
+}
+
+// For testing
+func (c *ConfigFileRegistry) GetTestConfigFileNamesEntry(path tspath.Path) *TestConfigFileNamesEntry {
+ if c != nil {
+ if entry, ok := c.configFileNames[path]; ok {
+ return &TestConfigFileNamesEntry{
+ NearestConfigFileName: entry.nearestConfigFileName,
+ Ancestors: entry.ancestors,
+ }
+ }
+ }
+ return nil
+}
+
type configFileNames struct {
// nearestConfigFileName is the file name of the nearest ancestor config file.
nearestConfigFileName string
diff --git a/internal/project/configfileregistrybuilder.go b/internal/project/configfileregistrybuilder.go
index 6dbb3c5f34..051ab23186 100644
--- a/internal/project/configfileregistrybuilder.go
+++ b/internal/project/configfileregistrybuilder.go
@@ -76,10 +76,10 @@ func (c *configFileRegistryBuilder) Finalize() *ConfigFileRegistry {
return newRegistry
}
-func (c *configFileRegistryBuilder) findOrAcquireConfigForOpenFile(
+func (c *configFileRegistryBuilder) findOrAcquireConfigForFile(
configFileName string,
configFilePath tspath.Path,
- openFilePath tspath.Path,
+ filePath tspath.Path,
loadKind projectLoadKind,
logger *logging.LogTree,
) *tsoptions.ParsedCommandLine {
@@ -90,7 +90,7 @@ func (c *configFileRegistryBuilder) findOrAcquireConfigForOpenFile(
}
return nil
case projectLoadKindCreate:
- return c.acquireConfigForOpenFile(configFileName, configFilePath, openFilePath, logger)
+ return c.acquireConfigForFile(configFileName, configFilePath, filePath, logger)
default:
panic(fmt.Sprintf("unknown project load kind: %d", loadKind))
}
@@ -248,17 +248,19 @@ func (c *configFileRegistryBuilder) acquireConfigForProject(fileName string, pat
return entry.Value().commandLine
}
-// acquireConfigForOpenFile loads a config file entry from the cache, or parses it if not already
+// acquireConfigForFile loads a config file entry from the cache, or parses it if not already
// cached, then adds the open file to `retainingOpenFiles` to keep it alive in the cache.
-// Each `acquireConfigForOpenFile` call that passes an `openFilePath`
+// Each `acquireConfigForFile` call that passes an `openFilePath`
// should be accompanied by an eventual `releaseConfigForOpenFile` call with the same open file.
-func (c *configFileRegistryBuilder) acquireConfigForOpenFile(configFileName string, configFilePath tspath.Path, openFilePath tspath.Path, logger *logging.LogTree) *tsoptions.ParsedCommandLine {
+func (c *configFileRegistryBuilder) acquireConfigForFile(configFileName string, configFilePath tspath.Path, filePath tspath.Path, logger *logging.LogTree) *tsoptions.ParsedCommandLine {
entry, _ := c.configs.LoadOrStore(configFilePath, newConfigFileEntry(configFileName))
var needsRetainOpenFile bool
entry.ChangeIf(
func(config *configFileEntry) bool {
- _, alreadyRetaining := config.retainingOpenFiles[openFilePath]
- needsRetainOpenFile = !alreadyRetaining
+ if c.fs.isOpenFile(filePath) {
+ _, alreadyRetaining := config.retainingOpenFiles[filePath]
+ needsRetainOpenFile = !alreadyRetaining
+ }
return needsRetainOpenFile || config.pendingReload != PendingReloadNone
},
func(config *configFileEntry) {
@@ -266,7 +268,7 @@ func (c *configFileRegistryBuilder) acquireConfigForOpenFile(configFileName stri
if config.retainingOpenFiles == nil {
config.retainingOpenFiles = make(map[tspath.Path]struct{})
}
- config.retainingOpenFiles[openFilePath] = struct{}{}
+ config.retainingOpenFiles[filePath] = struct{}{}
}
c.reloadIfNeeded(config, configFileName, configFilePath, logger)
},
@@ -524,8 +526,7 @@ func (c *configFileRegistryBuilder) getConfigFileNameForFile(fileName string, pa
}
configName := c.computeConfigFileName(fileName, false, logger)
-
- if _, ok := c.fs.overlays[path]; ok {
+ if c.fs.isOpenFile(path) {
c.configFileNames.Add(path, &configFileNames{
nearestConfigFileName: configName,
})
@@ -533,6 +534,24 @@ func (c *configFileRegistryBuilder) getConfigFileNameForFile(fileName string, pa
return configName
}
+func (c *configFileRegistryBuilder) forEachConfigFileNameFor(fileName string, path tspath.Path, cb func(configFileName string)) {
+ if isDynamicFileName(fileName) {
+ return
+ }
+
+ if entry, ok := c.configFileNames.Get(path); ok {
+ configFileName := entry.Value().nearestConfigFileName
+ for configFileName != "" {
+ cb(configFileName)
+ if ancestorConfigName, found := entry.Value().ancestors[configFileName]; found {
+ configFileName = ancestorConfigName
+ } else {
+ return
+ }
+ }
+ }
+}
+
func (c *configFileRegistryBuilder) getAncestorConfigFileName(fileName string, path tspath.Path, configFileName string, logger *logging.LogTree) string {
if isDynamicFileName(fileName) {
return ""
@@ -542,6 +561,7 @@ func (c *configFileRegistryBuilder) getAncestorConfigFileName(fileName string, p
if !ok {
return ""
}
+
if ancestorConfigName, found := entry.Value().ancestors[configFileName]; found {
return ancestorConfigName
}
@@ -549,7 +569,7 @@ func (c *configFileRegistryBuilder) getAncestorConfigFileName(fileName string, p
// Look for config in parent folders of config file
result := c.computeConfigFileName(configFileName, true, logger)
- if _, ok := c.fs.overlays[path]; ok {
+ if c.fs.isOpenFile(path) {
entry.Change(func(value *configFileNames) {
if value.ancestors == nil {
value.ancestors = make(map[string]string)
diff --git a/internal/project/project.go b/internal/project/project.go
index 77a99abf06..9f6f4e43d5 100644
--- a/internal/project/project.go
+++ b/internal/project/project.go
@@ -68,6 +68,9 @@ type Project struct {
ProgramUpdateKind ProgramUpdateKind
// The ID of the snapshot that created the program stored in this project.
ProgramLastUpdate uint64
+ // Set of projects that this project could be referencing.
+ // Only set before actually loading config file to get actual project references
+ potentialProjectReferences *collections.Set[tspath.Path]
programFilesWatch *WatchedFiles[PatternsAndIgnored]
failedLookupsWatch *WatchedFiles[map[tspath.Path]string]
@@ -192,6 +195,10 @@ func (p *Project) ConfigFilePath() tspath.Path {
return p.configFilePath
}
+func (p *Project) Id() tspath.Path {
+ return p.configFilePath
+}
+
func (p *Project) GetProgram() *compiler.Program {
return p.Program
}
@@ -220,6 +227,7 @@ func (p *Project) Clone() *Project {
Program: p.Program,
ProgramUpdateKind: ProgramUpdateKindNone,
ProgramLastUpdate: p.ProgramLastUpdate,
+ potentialProjectReferences: p.potentialProjectReferences,
programFilesWatch: p.programFilesWatch,
failedLookupsWatch: p.failedLookupsWatch,
@@ -267,6 +275,32 @@ func (p *Project) getCommandLineWithTypingsFiles() *tsoptions.ParsedCommandLine
return p.commandLineWithTypingsFiles
}
+func (p *Project) setPotentialProjectReference(configFilePath tspath.Path) {
+ if p.potentialProjectReferences == nil {
+ p.potentialProjectReferences = &collections.Set[tspath.Path]{}
+ } else {
+ p.potentialProjectReferences = p.potentialProjectReferences.Clone()
+ }
+ p.potentialProjectReferences.Add(configFilePath)
+}
+
+func (p *Project) forEachPotentialProjectReference(fn func(tspath.Path) bool) bool {
+ if p.CommandLine != nil {
+ for _, path := range p.CommandLine.ResolvedProjectReferencePaths() {
+ if fn(p.toPath(path)) {
+ return true
+ }
+ }
+ } else if p.potentialProjectReferences != nil {
+ for path := range p.potentialProjectReferences.Keys() {
+ if fn(path) {
+ return true
+ }
+ }
+ }
+ return false
+}
+
type CreateProgramResult struct {
Program *compiler.Program
UpdateKind ProgramUpdateKind
diff --git a/internal/project/projectcollection.go b/internal/project/projectcollection.go
index aebf7293a8..127e0986ed 100644
--- a/internal/project/projectcollection.go
+++ b/internal/project/projectcollection.go
@@ -29,6 +29,8 @@ type ProjectCollection struct {
apiOpenedProjects map[tspath.Path]struct{}
}
+func (c *ProjectCollection) ConfigFileRegistry() *ConfigFileRegistry { return c.configFileRegistry }
+
func (c *ProjectCollection) ConfiguredProject(path tspath.Path) *Project {
return c.configuredProjects[path]
}
@@ -91,6 +93,19 @@ func (c *ProjectCollection) InferredProject() *Project {
return c.inferredProject
}
+func (c *ProjectCollection) GetProjectsContainingFile(path tspath.Path) []*Project {
+ var projects []*Project
+ for _, project := range c.ConfiguredProjects() {
+ if project.containsFile(path) {
+ projects = append(projects, project)
+ }
+ }
+ if c.inferredProject != nil && c.inferredProject.containsFile(path) {
+ projects = append(projects, c.inferredProject)
+ }
+ return projects
+}
+
// !!! result could be cached
func (c *ProjectCollection) GetDefaultProject(fileName string, path tspath.Path) *Project {
if result, ok := c.fileDefaultProjects[path]; ok {
diff --git a/internal/project/projectcollectionbuilder.go b/internal/project/projectcollectionbuilder.go
index 0aa1da4cf8..0d73be8584 100644
--- a/internal/project/projectcollectionbuilder.go
+++ b/internal/project/projectcollectionbuilder.go
@@ -38,9 +38,10 @@ type ProjectCollectionBuilder struct {
newSnapshotID uint64
programStructureChanged bool
- fileDefaultProjects map[tspath.Path]tspath.Path
- configuredProjects *dirty.SyncMap[tspath.Path, *Project]
- inferredProject *dirty.Box[*Project]
+
+ fileDefaultProjects map[tspath.Path]tspath.Path
+ configuredProjects *dirty.SyncMap[tspath.Path, *Project]
+ inferredProject *dirty.Box[*Project]
apiOpenedProjects map[tspath.Path]struct{}
}
@@ -243,17 +244,67 @@ func (b *ProjectCollectionBuilder) DidChangeFiles(summary FileChangeSummary, log
fileName := summary.Opened.FileName()
path := b.toPath(fileName)
var toRemoveProjects collections.Set[tspath.Path]
- openFileResult := b.ensureConfiguredProjectAndAncestorsForOpenFile(fileName, path, logger)
+ openFileResult := b.ensureConfiguredProjectAndAncestorsForFile(fileName, path, logger)
b.configuredProjects.Range(func(entry *dirty.SyncMapEntry[tspath.Path, *Project]) bool {
- toRemoveProjects.Add(entry.Value().configFilePath)
- b.updateProgram(entry, logger)
+ toRemoveProjects.Add(entry.Key())
return true
})
+ var isReferencedBy func(project *Project, refPath tspath.Path, seenProjects *collections.Set[*Project]) bool
+ isReferencedBy = func(project *Project, refPath tspath.Path, seenProjects *collections.Set[*Project]) bool {
+ if !seenProjects.AddIfAbsent(project) {
+ return false
+ }
+
+ if project.potentialProjectReferences != nil {
+ for potentialRef := range project.potentialProjectReferences.Keys() {
+ if potentialRef == refPath {
+ return true
+ }
+ }
+ for potentialRef := range project.potentialProjectReferences.Keys() {
+ if refProject, foundRef := b.configuredProjects.Load(potentialRef); foundRef && isReferencedBy(refProject.Value(), refPath, seenProjects) {
+ return true
+ }
+ }
+ } else if program := project.GetProgram(); program != nil && program.ForEachResolvedProjectReference(func(referencePath tspath.Path, _ *tsoptions.ParsedCommandLine, _ *tsoptions.ParsedCommandLine, _ int) bool {
+ return referencePath == refPath
+ }) {
+ return true
+ }
+ return false
+ }
+
+ retainProjectAndReferences := func(project *Project) {
+ // Retain project
+ toRemoveProjects.Delete(project.configFilePath)
+ if program := project.GetProgram(); program != nil {
+ program.ForEachResolvedProjectReference(func(referencePath tspath.Path, _ *tsoptions.ParsedCommandLine, _ *tsoptions.ParsedCommandLine, _ int) bool {
+ if _, ok := b.configuredProjects.Load(referencePath); ok {
+ toRemoveProjects.Delete(referencePath)
+ }
+ return false
+ })
+ }
+ }
+
+ retainDefaultConfiguredProject := func(openFile string, openFilePath tspath.Path, project *Project) {
+ // Retain project and its references
+ retainProjectAndReferences(project)
+
+ // Retain all the ancestor projects
+ b.configFileRegistryBuilder.forEachConfigFileNameFor(openFile, openFilePath, func(configFileName string) {
+ if ancestor := b.findOrCreateProject(configFileName, b.toPath(configFileName), projectLoadKindFind, logger); ancestor != nil {
+ retainProjectAndReferences(ancestor.Value())
+ }
+ })
+ }
var inferredProjectFiles []string
for _, overlay := range b.fs.overlays {
- if p := b.findDefaultConfiguredProject(overlay.FileName(), b.toPath(overlay.FileName())); p != nil {
- toRemoveProjects.Delete(p.Value().configFilePath)
+ openFile := overlay.FileName()
+ openFilePath := b.toPath(openFile)
+ if p := b.findDefaultConfiguredProject(openFile, openFilePath); p != nil {
+ retainDefaultConfiguredProject(openFile, openFilePath, p.Value())
} else {
inferredProjectFiles = append(inferredProjectFiles, overlay.FileName())
}
@@ -338,6 +389,130 @@ func (b *ProjectCollectionBuilder) DidRequestFile(uri lsproto.DocumentUri, logge
}
}
+func (b *ProjectCollectionBuilder) DidRequestProject(projectId tspath.Path, logger *logging.LogTree) {
+ startTime := time.Now()
+ if projectId == inferredProjectName {
+ // Update inferred project
+ if b.inferredProject.Value() != nil {
+ b.updateProgram(b.inferredProject, logger)
+ }
+ } else {
+ if entry, ok := b.configuredProjects.Load(projectId); ok {
+ b.updateProgram(entry, logger)
+ }
+ }
+
+ if logger != nil {
+ elapsed := time.Since(startTime)
+ logger.Log(fmt.Sprintf("Completed project update request for %s in %v", projectId, elapsed))
+ }
+}
+
+func (b *ProjectCollectionBuilder) DidRequestEnsureDefaultProject(uri lsproto.DocumentUri, logger *logging.LogTree) {
+ fileName := uri.FileName()
+ path := b.toPath(fileName)
+ if b.fs.isOpenFile(path) {
+ b.DidRequestFile(uri, logger)
+ return
+ }
+
+ startTime := time.Now()
+ b.ensureConfiguredProjectAndAncestorsForFile(fileName, path, logger)
+
+ if logger != nil {
+ elapsed := time.Since(startTime)
+ logger.Log(fmt.Sprintf("Completed file request for %s in %v", fileName, elapsed))
+ }
+}
+
+func (b *ProjectCollectionBuilder) DidRequestProjectTrees(projectsReferenced map[tspath.Path]struct{}, logger *logging.LogTree) {
+ startTime := time.Now()
+
+ var currentProjects []tspath.Path
+ b.configuredProjects.Range(func(sme *dirty.SyncMapEntry[tspath.Path, *Project]) bool {
+ currentProjects = append(currentProjects, sme.Key())
+ return true
+ })
+
+ var seenProjects collections.SyncSet[tspath.Path]
+ wg := core.NewWorkGroup(false)
+ for _, projectId := range currentProjects {
+ wg.Queue(func() {
+ if entry, ok := b.configuredProjects.Load(projectId); ok {
+ // If this project has potential project reference for any of the project we are loading ancestor tree for
+ // load this project first
+ if project := entry.Value(); project != nil && project.forEachPotentialProjectReference(func(p tspath.Path) bool {
+ if projectsReferenced == nil {
+ return true
+ }
+ _, isReferenced := projectsReferenced[p]
+ return isReferenced
+ }) {
+ b.updateProgram(entry, logger)
+ }
+ b.ensureProjectTree(wg, entry, projectsReferenced, &seenProjects, logger)
+ }
+ })
+ }
+ wg.RunAndWait()
+
+ if logger != nil {
+ elapsed := time.Since(startTime)
+ logger.Log(fmt.Sprintf("Completed project tree request for %v in %v", maps.Keys(projectsReferenced), elapsed))
+ }
+}
+
+func (b *ProjectCollectionBuilder) ensureProjectTree(
+ wg core.WorkGroup,
+ entry *dirty.SyncMapEntry[tspath.Path, *Project],
+ projectsReferenced map[tspath.Path]struct{},
+ seenProjects *collections.SyncSet[tspath.Path],
+ logger *logging.LogTree,
+) {
+ if !seenProjects.AddIfAbsent(entry.Key()) {
+ return
+ }
+
+ project := entry.Value()
+ if project == nil {
+ return
+ }
+
+ program := project.GetProgram()
+ if program == nil {
+ return
+ }
+
+ // If this project disables child load ignore it
+ if program.CommandLine().CompilerOptions().DisableReferencedProjectLoad.IsTrue() {
+ return
+ }
+
+ children := program.GetResolvedProjectReferences()
+ if children == nil {
+ return
+ }
+ for _, childConfig := range children {
+ wg.Queue(func() {
+ if projectsReferenced != nil && !program.ForEachResolvedProjectReferenceInChildConfig(
+ childConfig,
+ func(referencePath tspath.Path, config *tsoptions.ParsedCommandLine, _ *tsoptions.ParsedCommandLine, _ int) bool {
+ _, isReferenced := projectsReferenced[referencePath]
+ return isReferenced
+ }) {
+ return
+ }
+
+ // Load this child project since this is referenced
+ childProjectEntry := b.findOrCreateProject(childConfig.ConfigName(), childConfig.ConfigFile.SourceFile.Path(), projectLoadKindCreate, logger)
+ b.updateProgram(childProjectEntry, logger)
+
+ // Ensure children for this project
+ b.ensureProjectTree(wg, childProjectEntry, projectsReferenced, seenProjects, logger)
+ })
+ }
+}
+
func (b *ProjectCollectionBuilder) DidUpdateATAState(ataChanges map[tspath.Path]*ATAStateChange, logger *logging.LogTree) {
updateProject := func(project dirty.Value[*Project], ataChange *ATAStateChange) {
project.ChangeIf(
@@ -408,7 +583,7 @@ func (b *ProjectCollectionBuilder) markProjectsAffectedByConfigChanges(
var hasChanges bool
for path := range configChangeResult.affectedFiles {
fileName := b.fs.overlays[path].FileName()
- _ = b.ensureConfiguredProjectAndAncestorsForOpenFile(fileName, path, logger)
+ _ = b.ensureConfiguredProjectAndAncestorsForFile(fileName, path, logger)
hasChanges = true
}
@@ -449,7 +624,7 @@ func (b *ProjectCollectionBuilder) findDefaultConfiguredProject(fileName string,
})
if multipleCandidates {
- if p := b.findOrCreateDefaultConfiguredProjectForOpenScriptInfo(fileName, path, projectLoadKindFind, nil).project; p != nil {
+ if p := b.findOrCreateDefaultConfiguredProjectForFile(fileName, path, projectLoadKindFind, nil).project; p != nil {
return p
}
}
@@ -457,28 +632,53 @@ func (b *ProjectCollectionBuilder) findDefaultConfiguredProject(fileName string,
return configuredProjects[project]
}
-func (b *ProjectCollectionBuilder) ensureConfiguredProjectAndAncestorsForOpenFile(fileName string, path tspath.Path, logger *logging.LogTree) searchResult {
- result := b.findOrCreateDefaultConfiguredProjectForOpenScriptInfo(fileName, path, projectLoadKindCreate, logger)
- if result.project != nil {
- // !!! sheetal todo this later
- // // Create ancestor tree for findAllRefs (dont load them right away)
- // forEachAncestorProjectLoad(
- // info,
- // tsconfigProject!,
- // ancestor => {
- // seenProjects.set(ancestor.project, kind);
- // },
- // kind,
- // `Creating project possibly referencing default composite project ${defaultProject.getProjectName()} of open file ${info.fileName}`,
- // allowDeferredClosed,
- // reloadedProjects,
- // /*searchOnlyPotentialSolution*/ true,
- // delayReloadedConfiguredProjects,
- // );
+func (b *ProjectCollectionBuilder) ensureConfiguredProjectAndAncestorsForFile(fileName string, path tspath.Path, logger *logging.LogTree) searchResult {
+ result := b.findOrCreateDefaultConfiguredProjectForFile(fileName, path, projectLoadKindCreate, logger)
+ if result.project != nil && b.fs.isOpenFile(path) {
+ b.createAncestorTree(fileName, path, &result, logger)
}
return result
}
+func (b *ProjectCollectionBuilder) createAncestorTree(fileName string, path tspath.Path, openResult *searchResult, logger *logging.LogTree) {
+ project := openResult.project.Value()
+ for {
+ // Skip if project is not composite and we are only looking for solution
+ if project.CommandLine != nil &&
+ (!project.CommandLine.CompilerOptions().Composite.IsTrue() ||
+ project.CommandLine.CompilerOptions().DisableSolutionSearching.IsTrue()) {
+ return
+ }
+
+ // Get config file name
+ ancestorConfigName := b.configFileRegistryBuilder.getAncestorConfigFileName(fileName, path, project.configFileName, logger)
+ if ancestorConfigName == "" {
+ return
+ }
+
+ // find or delay load the project
+ ancestorPath := b.toPath(ancestorConfigName)
+ ancestor := b.findOrCreateProject(ancestorConfigName, ancestorPath, projectLoadKindCreate, logger)
+ if ancestor == nil {
+ return
+ }
+
+ openResult.retain.Add(ancestorPath)
+
+ // If this ancestor is new and was not updated because we are just creating it for future loading
+ // eg when invoking find all references or rename that could span multiple projects
+ // we would make the current project as its potential project reference
+ if ancestor.Value().CommandLine == nil &&
+ (project.CommandLine == nil || project.CommandLine.CompilerOptions().Composite.IsTrue()) {
+ ancestor.Change(func(ancestorProject *Project) {
+ ancestorProject.setPotentialProjectReference(project.configFilePath)
+ })
+ }
+
+ project = ancestor.Value()
+ }
+}
+
type searchNode struct {
configFileName string
loadKind projectLoadKind
@@ -531,7 +731,7 @@ func (b *ProjectCollectionBuilder) findOrCreateDefaultConfiguredProjectWorker(
},
func(node searchNode) (isResult bool, stop bool) {
configFilePath := b.toPath(node.configFileName)
- config := b.configFileRegistryBuilder.findOrAcquireConfigForOpenFile(node.configFileName, configFilePath, path, node.loadKind, node.logger.Fork("Acquiring config for open file"))
+ config := b.configFileRegistryBuilder.findOrAcquireConfigForFile(node.configFileName, configFilePath, path, node.loadKind, node.logger.Fork("Acquiring config for open file"))
if config == nil {
node.logger.Log("Config file for project does not already exist")
return false, false
@@ -653,7 +853,7 @@ func (b *ProjectCollectionBuilder) findOrCreateDefaultConfiguredProjectWorker(
return searchResult{retain: retain}
}
-func (b *ProjectCollectionBuilder) findOrCreateDefaultConfiguredProjectForOpenScriptInfo(
+func (b *ProjectCollectionBuilder) findOrCreateDefaultConfiguredProjectForFile(
fileName string,
path tspath.Path,
loadKind projectLoadKind,
@@ -784,6 +984,7 @@ func (b *ProjectCollectionBuilder) updateProgram(entry dirty.Value[*Project], lo
entry.Change(func(p *Project) {
p.CommandLine = commandLine
p.commandLineWithTypingsFiles = nil
+ p.potentialProjectReferences = nil
})
}
}
@@ -881,8 +1082,9 @@ func (b *ProjectCollectionBuilder) deleteConfiguredProject(project dirty.Value[*
logger.Log("Deleting configured project: " + project.Value().configFileName)
}
if program := project.Value().Program; program != nil {
- program.ForEachResolvedProjectReference(func(referencePath tspath.Path, config *tsoptions.ParsedCommandLine, _ *tsoptions.ParsedCommandLine, _ int) {
+ program.ForEachResolvedProjectReference(func(referencePath tspath.Path, config *tsoptions.ParsedCommandLine, _ *tsoptions.ParsedCommandLine, _ int) bool {
b.configFileRegistryBuilder.releaseConfigForProject(referencePath, projectPath)
+ return false
})
}
b.configFileRegistryBuilder.releaseConfigForProject(projectPath, projectPath)
diff --git a/internal/project/projectcollectionbuilder_test.go b/internal/project/projectcollectionbuilder_test.go
index bc40f9fd1c..48fc87fff3 100644
--- a/internal/project/projectcollectionbuilder_test.go
+++ b/internal/project/projectcollectionbuilder_test.go
@@ -320,9 +320,11 @@ func TestProjectCollectionBuilder(t *testing.T) {
session.DidOpenFile(context.Background(), uri, 1, content, lsproto.LanguageKindTypeScript)
snapshot, release := session.Snapshot()
defer release()
- assert.Equal(t, len(snapshot.ProjectCollection.Projects()), 1)
+ assert.Equal(t, len(snapshot.ProjectCollection.Projects()), 2)
demoProject := snapshot.ProjectCollection.ConfiguredProject(tspath.Path("/home/src/projects/project/demos/tsconfig.json"))
assert.Assert(t, demoProject != nil)
+ solutionProject := snapshot.ProjectCollection.ConfiguredProject(tspath.Path("/home/src/projects/project/tsconfig.json"))
+ assert.Assert(t, solutionProject != nil)
// Verify the default project is the demos project (not the app project that excludes demos files)
defaultProject := snapshot.GetDefaultProject(uri)
diff --git a/internal/project/session.go b/internal/project/session.go
index 0e2b2de6b1..f1a16a56bd 100644
--- a/internal/project/session.go
+++ b/internal/project/session.go
@@ -31,7 +31,9 @@ const (
UpdateReasonDidChangeCompilerOptionsForInferredProjects
UpdateReasonRequestedLanguageServicePendingChanges
UpdateReasonRequestedLanguageServiceProjectNotLoaded
+ UpdateReasonRequestedLanguageServiceForFileNotOpen
UpdateReasonRequestedLanguageServiceProjectDirty
+ UpdateReasonRequestedLoadProjectTree
)
// SessionOptions are the immutable initialization options for a session.
@@ -227,9 +229,11 @@ func (s *Session) DidOpenFile(ctx context.Context, uri lsproto.DocumentUri, vers
changes, overlays := s.flushChangesLocked(ctx)
s.pendingFileChangesMu.Unlock()
s.UpdateSnapshot(ctx, overlays, SnapshotChange{
- reason: UpdateReasonDidOpenFile,
- fileChanges: changes,
- requestedURIs: []lsproto.DocumentUri{uri},
+ reason: UpdateReasonDidOpenFile,
+ fileChanges: changes,
+ snapshotChangeRequest: snapshotChangeRequest{
+ requestedURIs: []lsproto.DocumentUri{uri},
+ },
})
}
@@ -371,7 +375,11 @@ func (s *Session) Snapshot() (*Snapshot, func()) {
}
}
-func (s *Session) GetLanguageService(ctx context.Context, uri lsproto.DocumentUri) (*ls.LanguageService, error) {
+func (s *Session) getSnapshot(
+ ctx context.Context,
+ changeRequest snapshotChangeRequest,
+ updateIf func(snapshot *Snapshot, updatedSnapshot bool) UpdateReason,
+) *Snapshot {
var snapshot *Snapshot
fileChanges, overlays, ataChanges, newConfig := s.flushChanges(ctx)
updateSnapshot := !fileChanges.IsEmpty() || len(ataChanges) > 0 || newConfig != nil
@@ -379,11 +387,11 @@ func (s *Session) GetLanguageService(ctx context.Context, uri lsproto.DocumentUr
// If there are pending file changes, we need to update the snapshot.
// Sending the requested URI ensures that the project for this URI is loaded.
snapshot = s.UpdateSnapshot(ctx, overlays, SnapshotChange{
- reason: UpdateReasonRequestedLanguageServicePendingChanges,
- fileChanges: fileChanges,
- ataChanges: ataChanges,
- newConfig: newConfig,
- requestedURIs: []lsproto.DocumentUri{uri},
+ reason: UpdateReasonRequestedLanguageServicePendingChanges,
+ fileChanges: fileChanges,
+ ataChanges: ataChanges,
+ newConfig: newConfig,
+ snapshotChangeRequest: changeRequest,
})
} else {
// If there are no pending file changes, we can try to use the current snapshot.
@@ -391,22 +399,134 @@ func (s *Session) GetLanguageService(ctx context.Context, uri lsproto.DocumentUr
snapshot = s.snapshot
s.snapshotMu.RUnlock()
}
-
- project := snapshot.GetDefaultProject(uri)
- if project == nil && !updateSnapshot || project != nil && project.dirty {
- // The current snapshot does not have an up to date project for the URI,
- // so we need to update the snapshot to ensure the project is loaded.
- // !!! Allow multiple projects to update in parallel
+ if updateReason := updateIf(snapshot, updateSnapshot); updateReason != UpdateReasonUnknown {
snapshot = s.UpdateSnapshot(ctx, overlays, SnapshotChange{
- reason: core.IfElse(project == nil, UpdateReasonRequestedLanguageServiceProjectNotLoaded, UpdateReasonRequestedLanguageServiceProjectDirty),
- requestedURIs: []lsproto.DocumentUri{uri},
+ reason: updateReason,
+ snapshotChangeRequest: changeRequest,
})
- project = snapshot.GetDefaultProject(uri)
}
+ return snapshot
+}
+
+func (s *Session) getSnapshotAndDefaultProject(ctx context.Context, uri lsproto.DocumentUri) (*Snapshot, *Project, *ls.LanguageService, error) {
+ snapshot := s.getSnapshot(
+ ctx,
+ snapshotChangeRequest{requestedURIs: []lsproto.DocumentUri{uri}},
+ func(snapshot *Snapshot, updatedSnapshot bool) UpdateReason {
+ project := snapshot.GetDefaultProject(uri)
+ if project == nil && !updatedSnapshot || project != nil && project.dirty {
+ // The current snapshot does not have an up to date project for the URI,
+ // so we need to update the snapshot to ensure the project is loaded.
+ // !!! Allow multiple projects to update in parallel
+ return core.IfElse(project == nil, UpdateReasonRequestedLanguageServiceProjectNotLoaded, UpdateReasonRequestedLanguageServiceProjectDirty)
+ }
+ return UpdateReasonUnknown
+ },
+ )
+ project := snapshot.GetDefaultProject(uri)
if project == nil {
- return nil, fmt.Errorf("no project found for URI %s", uri)
+ return nil, nil, nil, fmt.Errorf("no project found for URI %s", uri)
}
- return ls.NewLanguageService(project.GetProgram(), snapshot), nil
+ return snapshot, project, ls.NewLanguageService(project.GetProgram(), snapshot), nil
+}
+
+func (s *Session) GetLanguageService(ctx context.Context, uri lsproto.DocumentUri) (*ls.LanguageService, error) {
+ _, _, languageService, err := s.getSnapshotAndDefaultProject(ctx, uri)
+ if err != nil {
+ return nil, err
+ }
+ return languageService, nil
+}
+
+func (s *Session) GetLanguageServiceAndProjectsForFile(ctx context.Context, uri lsproto.DocumentUri) (*Project, *ls.LanguageService, []*Project, error) {
+ snapshot, project, defaultLs, err := s.getSnapshotAndDefaultProject(ctx, uri)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ // !!! TODO: sheetal: Get other projects that contain the file with symlink
+ allProjects := snapshot.GetProjectsContainingFile(uri)
+ return project, defaultLs, allProjects, nil
+}
+
+func (s *Session) GetProjectsForFile(ctx context.Context, uri lsproto.DocumentUri) ([]*Project, error) {
+ snapshot := s.getSnapshot(
+ ctx,
+ snapshotChangeRequest{ensureDefaultProjectForURIs: []lsproto.DocumentUri{uri}},
+ func(snapshot *Snapshot, updatedSnapshot bool) UpdateReason {
+ return core.IfElse(!updatedSnapshot, UpdateReasonRequestedLanguageServiceForFileNotOpen, UpdateReasonUnknown)
+ },
+ )
+
+ // !!! TODO: sheetal: Get other projects that contain the file with symlink
+ allProjects := snapshot.GetProjectsContainingFile(uri)
+ return allProjects, nil
+}
+
+func (s *Session) GetLanguageServiceForProjectWithFile(ctx context.Context, project *Project, uri lsproto.DocumentUri) *ls.LanguageService {
+ snapshot := s.getSnapshot(
+ ctx,
+ snapshotChangeRequest{requestedProjectUpdates: []tspath.Path{project.Id()}},
+ func(snapshot *Snapshot, updatedSnapshot bool) UpdateReason {
+ return core.IfElse(!updatedSnapshot, UpdateReasonRequestedLanguageServiceProjectDirty, UpdateReasonUnknown)
+ },
+ )
+ // Ensure we have updated project
+ project = snapshot.ProjectCollection.GetProjectByPath(project.Id())
+ if project == nil {
+ return nil
+ }
+ // if program doesnt contain this file any more ignore it
+ if !s.projectContainsFile(project, uri) {
+ return nil
+ }
+ return ls.NewLanguageService(project.GetProgram(), snapshot)
+}
+
+func (s *Session) projectContainsFile(project *Project, uri lsproto.DocumentUri) bool {
+ path := s.toPath(uri.FileName())
+ return project.containsFile(path)
+}
+
+func (s *Session) GetSnapshotLoadingProjectTree(
+ ctx context.Context,
+ // If null, all project trees need to be loaded, otherwise only those that are referenced
+ requestedProjectTrees map[tspath.Path]struct{},
+) *Snapshot {
+ snapshot := s.getSnapshot(
+ ctx,
+ snapshotChangeRequest{requestedProjectTrees: &projectTreeRequest{requestedProjectTrees}},
+ func(snapshot *Snapshot, updatedSnapshot bool) UpdateReason {
+ return core.IfElse(!updatedSnapshot, UpdateReasonRequestedLoadProjectTree, UpdateReasonUnknown)
+ },
+ )
+ return snapshot
+}
+
+func (s *Session) ForEachProjectLocationLoadingProjectTree(
+ ctx context.Context,
+ requestedProjectTrees map[tspath.Path]struct{},
+ defaultDefinition *ls.NonLocalDefinition,
+ canIterateProject func(project *Project) bool,
+ handleLocation func(*Project, lsproto.DocumentUri, lsproto.Position),
+) error {
+ for _, project := range s.GetSnapshotLoadingProjectTree(ctx, requestedProjectTrees).ProjectCollection.Projects() {
+ if ctx.Err() != nil {
+ return ctx.Err()
+ }
+
+ if !canIterateProject(project) || project.GetProgram() == nil {
+ continue
+ }
+
+ if s.projectContainsFile(project, defaultDefinition.TextDocumentURI()) {
+ handleLocation(project, defaultDefinition.TextDocumentURI(), defaultDefinition.TextDocumentPosition())
+ } else if sourcePos := defaultDefinition.GetSourcePosition(); sourcePos != nil && s.projectContainsFile(project, sourcePos.TextDocumentURI()) {
+ handleLocation(project, sourcePos.TextDocumentURI(), sourcePos.TextDocumentPosition())
+ } else if generatedPos := defaultDefinition.GetGeneratedPosition(); generatedPos != nil && s.projectContainsFile(project, generatedPos.TextDocumentURI()) {
+ handleLocation(project, generatedPos.TextDocumentURI(), generatedPos.TextDocumentPosition())
+ }
+ }
+ return nil
}
func (s *Session) UpdateSnapshot(ctx context.Context, overlays map[tspath.Path]*Overlay, change SnapshotChange) *Snapshot {
diff --git a/internal/project/snapshot.go b/internal/project/snapshot.go
index 72af69381e..d9d0366107 100644
--- a/internal/project/snapshot.go
+++ b/internal/project/snapshot.go
@@ -3,6 +3,7 @@ package project
import (
"context"
"fmt"
+ "maps"
"sync/atomic"
"time"
@@ -76,6 +77,13 @@ func (s *Snapshot) GetDefaultProject(uri lsproto.DocumentUri) *Project {
return s.ProjectCollection.GetDefaultProject(fileName, path)
}
+func (s *Snapshot) GetProjectsContainingFile(uri lsproto.DocumentUri) []*Project {
+ fileName := uri.FileName()
+ path := s.toPath(fileName)
+ // TODO!! sheetal may be change this to handle symlinks!!
+ return s.ProjectCollection.GetProjectsContainingFile(path)
+}
+
func (s *Snapshot) GetFile(fileName string) FileHandle {
return s.fs.GetFile(fileName)
}
@@ -128,13 +136,33 @@ type APISnapshotRequest struct {
UpdateProjects *collections.Set[tspath.Path]
}
+type projectTreeRequest struct {
+ // If null, all project trees need to be loaded, otherwise only those that are referenced
+ referencedProjects map[tspath.Path]struct{}
+}
+
+type snapshotChangeRequest struct {
+ // requestedURIs are URIs that were requested by the client.
+ // The new snapshot should ensure projects for these URIs have loaded programs.
+ requestedURIs []lsproto.DocumentUri
+ // Update requested projects.
+ // this is used when we want to get LS and from all the projects the file can be part of
+ requestedProjectUpdates []tspath.Path
+ // Ensure default project for these URIs
+ // These are documents that might not be open, but we need default project for them
+ // eg for Find all references when the definition is in a mapped location that is not yet open
+ ensureDefaultProjectForURIs []lsproto.DocumentUri
+ // Update and ensure project trees that reference the projects
+ // This is used to compute the solution and project tree so that
+ // we can find references across all the projects in the solution irrespective of which project is open
+ requestedProjectTrees *projectTreeRequest
+}
+
type SnapshotChange struct {
+ snapshotChangeRequest
reason UpdateReason
// fileChanges are the changes that have occurred since the last snapshot.
fileChanges FileChangeSummary
- // requestedURIs are URIs that were requested by the client.
- // The new snapshot should ensure projects for these URIs have loaded programs.
- requestedURIs []lsproto.DocumentUri
// compilerOptionsForInferredProjects is the compiler options to use for inferred projects.
// It should only be set the value in the next snapshot should be changed. If nil, the
// value from the previous snapshot will be copied to the new snapshot.
@@ -179,17 +207,37 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma
if session.options.LoggingEnabled {
logger = logging.NewLogTree(fmt.Sprintf("Cloning snapshot %d", s.id))
+ getDetails := func() string {
+ details := ""
+ if len(change.requestedURIs) != 0 {
+ details += fmt.Sprintf(" requestedURIs: %v", change.requestedURIs)
+ }
+ if len(change.requestedProjectUpdates) != 0 {
+ details += fmt.Sprintf(" requestedProjectUpdates: %v", change.requestedProjectUpdates)
+ }
+ if len(change.ensureDefaultProjectForURIs) != 0 {
+ details += fmt.Sprintf(" ensureDefaultProjectForURIs: %v", change.ensureDefaultProjectForURIs)
+ }
+ if change.requestedProjectTrees != nil {
+ details += fmt.Sprintf(" requestedProjectTrees: %v", maps.Keys(change.requestedProjectTrees.referencedProjects))
+ }
+ return details
+ }
switch change.reason {
case UpdateReasonDidOpenFile:
logger.Logf("Reason: DidOpenFile - %s", change.fileChanges.Opened)
case UpdateReasonDidChangeCompilerOptionsForInferredProjects:
logger.Logf("Reason: DidChangeCompilerOptionsForInferredProjects")
case UpdateReasonRequestedLanguageServicePendingChanges:
- logger.Logf("Reason: RequestedLanguageService (pending file changes) - %v", change.requestedURIs)
+ logger.Logf("Reason: RequestedLanguageService (pending file changes) - %v", getDetails())
case UpdateReasonRequestedLanguageServiceProjectNotLoaded:
- logger.Logf("Reason: RequestedLanguageService (project not loaded) - %v", change.requestedURIs)
+ logger.Logf("Reason: RequestedLanguageService (project not loaded) - %v", getDetails())
+ case UpdateReasonRequestedLanguageServiceForFileNotOpen:
+ logger.Logf("Reason: RequestedLanguageService (file not open) - %v", getDetails())
case UpdateReasonRequestedLanguageServiceProjectDirty:
- logger.Logf("Reason: RequestedLanguageService (project dirty) - %v", change.requestedURIs)
+ logger.Logf("Reason: RequestedLanguageService (project dirty) - %v", getDetails())
+ case UpdateReasonRequestedLoadProjectTree:
+ logger.Logf("Reason: RequestedLoadProjectTree - %v", getDetails())
}
}
@@ -248,6 +296,18 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma
projectCollectionBuilder.DidRequestFile(uri, logger.Fork("DidRequestFile"))
}
+ for _, projectId := range change.requestedProjectUpdates {
+ projectCollectionBuilder.DidRequestProject(projectId, logger.Fork("DidRequestProject"))
+ }
+
+ for _, uri := range change.ensureDefaultProjectForURIs {
+ projectCollectionBuilder.DidRequestEnsureDefaultProject(uri, logger.Fork("DidRequestFile"))
+ }
+
+ if change.requestedProjectTrees != nil {
+ projectCollectionBuilder.DidRequestProjectTrees(change.requestedProjectTrees.referencedProjects, logger.Fork("DidRequestProjectTrees"))
+ }
+
projectCollection, configFileRegistry := projectCollectionBuilder.Finalize(logger)
// Clean cached disk files not touched by any open project. It's not important that we do this on
@@ -266,7 +326,7 @@ func (s *Snapshot) Clone(ctx context.Context, change SnapshotChange, overlays ma
removedFiles := 0
fs.diskFiles.Range(func(entry *dirty.SyncMapEntry[tspath.Path, *diskFile]) bool {
for _, project := range projectCollection.Projects() {
- if project.host.seenFiles.Has(entry.Key()) {
+ if project.host != nil && project.host.seenFiles.Has(entry.Key()) {
return true
}
}
diff --git a/internal/project/snapshotfs.go b/internal/project/snapshotfs.go
index 50023347e0..a823093c1a 100644
--- a/internal/project/snapshotfs.go
+++ b/internal/project/snapshotfs.go
@@ -92,6 +92,11 @@ func (s *snapshotFSBuilder) Finalize() (*SnapshotFS, bool) {
}, changed
}
+func (s *snapshotFSBuilder) isOpenFile(path tspath.Path) bool {
+ _, ok := s.overlays[path]
+ return ok
+}
+
func (s *snapshotFSBuilder) GetFile(fileName string) FileHandle {
path := s.toPath(fileName)
return s.GetFileByPath(fileName, path)
diff --git a/internal/project/untitled_test.go b/internal/project/untitled_test.go
index 8eb0b93054..f8aedb2e63 100644
--- a/internal/project/untitled_test.go
+++ b/internal/project/untitled_test.go
@@ -71,7 +71,9 @@ x++;`
Context: &lsproto.ReferenceContext{IncludeDeclaration: true},
}
- resp, err := languageService.ProvideReferences(ctx, refParams)
+ originalNode, symbolAndEntries, ok := languageService.ProvideSymbolsAndEntries(ctx, refParams.TextDocumentURI(), refParams.Position, false)
+ assert.Assert(t, ok)
+ resp, err := languageService.ProvideReferencesFromSymbolAndEntries(ctx, refParams, originalNode, symbolAndEntries)
assert.NilError(t, err)
refs := *resp.Locations
@@ -144,7 +146,9 @@ x++;`
Context: &lsproto.ReferenceContext{IncludeDeclaration: true},
}
- resp, err := languageService.ProvideReferences(ctx, refParams)
+ originalNode, symbolAndEntries, ok := languageService.ProvideSymbolsAndEntries(ctx, refParams.TextDocumentURI(), refParams.Position, false)
+ assert.Assert(t, ok)
+ resp, err := languageService.ProvideReferencesFromSymbolAndEntries(ctx, refParams, originalNode, symbolAndEntries)
assert.NilError(t, err)
refs := *resp.Locations
diff --git a/internal/sourcemap/lineinfo.go b/internal/sourcemap/lineinfo.go
index c2f4aad60f..0c87fde9e8 100644
--- a/internal/sourcemap/lineinfo.go
+++ b/internal/sourcemap/lineinfo.go
@@ -15,6 +15,9 @@ func CreateECMALineInfo(text string, lineStarts core.ECMALineStarts) *ECMALineIn
}
func (li *ECMALineInfo) LineCount() int {
+ if li == nil {
+ return 0
+ }
return len(li.lineStarts)
}
diff --git a/internal/testutil/fsbaselineutil/differ.go b/internal/testutil/fsbaselineutil/differ.go
new file mode 100644
index 0000000000..285d5e345e
--- /dev/null
+++ b/internal/testutil/fsbaselineutil/differ.go
@@ -0,0 +1,122 @@
+package fsbaselineutil
+
+import (
+ "fmt"
+ "io"
+ "io/fs"
+ "maps"
+ "slices"
+ "time"
+
+ "github.com/microsoft/typescript-go/internal/collections"
+ "github.com/microsoft/typescript-go/internal/vfs/iovfs"
+ "github.com/microsoft/typescript-go/internal/vfs/vfstest"
+)
+
+type DiffEntry struct {
+ Content string
+ MTime time.Time
+ IsWritten bool
+ SymlinkTarget string
+}
+
+type Snapshot struct {
+ Snap map[string]*DiffEntry
+ DefaultLibs *collections.SyncSet[string]
+}
+
+type FSDiffer struct {
+ FS iovfs.FsWithSys
+ DefaultLibs func() *collections.SyncSet[string]
+ WrittenFiles *collections.SyncSet[string]
+
+ serializedDiff *Snapshot
+}
+
+func (d *FSDiffer) MapFs() *vfstest.MapFS {
+ return d.FS.FSys().(*vfstest.MapFS)
+}
+
+func (d *FSDiffer) SerializedDiff() *Snapshot {
+ return d.serializedDiff
+}
+
+func (d *FSDiffer) BaselineFSwithDiff(baseline io.Writer) {
+ // todo: baselines the entire fs, possibly doesn't correctly diff all cases of emitted files, since emit isn't fully implemented and doesn't always emit the same way as strada
+ snap := map[string]*DiffEntry{}
+
+ diffs := map[string]string{}
+
+ for path, file := range d.MapFs().Entries() {
+ if file.Mode&fs.ModeSymlink != 0 {
+ target, ok := d.MapFs().GetTargetOfSymlink(path)
+ if !ok {
+ panic("Failed to resolve symlink target: " + path)
+ }
+ newEntry := &DiffEntry{SymlinkTarget: target}
+ snap[path] = newEntry
+ d.addFsEntryDiff(diffs, newEntry, path)
+ continue
+ } else if file.Mode.IsRegular() {
+ newEntry := &DiffEntry{Content: string(file.Data), MTime: file.ModTime, IsWritten: d.WrittenFiles.Has(path)}
+ snap[path] = newEntry
+ d.addFsEntryDiff(diffs, newEntry, path)
+ }
+ }
+ if d.serializedDiff != nil {
+ for path := range d.serializedDiff.Snap {
+ if fileInfo := d.MapFs().GetFileInfo(path); fileInfo == nil {
+ // report deleted
+ d.addFsEntryDiff(diffs, nil, path)
+ }
+ }
+ }
+ var defaultLibs collections.SyncSet[string]
+ if d.DefaultLibs != nil && d.DefaultLibs() != nil {
+ d.DefaultLibs().Range(func(libPath string) bool {
+ defaultLibs.Add(libPath)
+ return true
+ })
+ }
+ d.serializedDiff = &Snapshot{
+ Snap: snap,
+ DefaultLibs: &defaultLibs,
+ }
+ diffKeys := slices.Collect(maps.Keys(diffs))
+ slices.Sort(diffKeys)
+ for _, path := range diffKeys {
+ fmt.Fprint(baseline, "//// ["+path+"] ", diffs[path], "\n")
+ }
+ fmt.Fprintln(baseline)
+ *d.WrittenFiles = collections.SyncSet[string]{} // Reset written files after baseline
+}
+
+func (d *FSDiffer) addFsEntryDiff(diffs map[string]string, newDirContent *DiffEntry, path string) {
+ var oldDirContent *DiffEntry
+ var defaultLibs *collections.SyncSet[string]
+ if d.serializedDiff != nil {
+ oldDirContent = d.serializedDiff.Snap[path]
+ defaultLibs = d.serializedDiff.DefaultLibs
+ }
+ // todo handle more cases of fs changes
+ if oldDirContent == nil {
+ if d.DefaultLibs == nil || d.DefaultLibs() == nil || !d.DefaultLibs().Has(path) {
+ if newDirContent.SymlinkTarget != "" {
+ diffs[path] = "-> " + newDirContent.SymlinkTarget + " *new*"
+ } else {
+ diffs[path] = "*new* \n" + newDirContent.Content
+ }
+ }
+ } else if newDirContent == nil {
+ diffs[path] = "*deleted*"
+ } else if newDirContent.Content != oldDirContent.Content {
+ diffs[path] = "*modified* \n" + newDirContent.Content
+ } else if newDirContent.IsWritten {
+ diffs[path] = "*rewrite with same content*"
+ } else if newDirContent.MTime != oldDirContent.MTime {
+ diffs[path] = "*mTime changed*"
+ } else if defaultLibs != nil && defaultLibs.Has(path) && d.DefaultLibs != nil && d.DefaultLibs() != nil && !d.DefaultLibs().Has(path) {
+ // Lib file that was read
+ diffs[path] = "*Lib*\n" + newDirContent.Content
+ }
+}
diff --git a/internal/testutil/lsptestutil/baseline.go b/internal/testutil/lsptestutil/baseline.go
new file mode 100644
index 0000000000..c88144d380
--- /dev/null
+++ b/internal/testutil/lsptestutil/baseline.go
@@ -0,0 +1,589 @@
+package lsptestutil
+
+import (
+ "errors"
+ "fmt"
+ "io/fs"
+ "regexp"
+ "slices"
+ "strings"
+
+ "github.com/microsoft/typescript-go/internal/collections"
+ "github.com/microsoft/typescript-go/internal/core"
+ "github.com/microsoft/typescript-go/internal/debug"
+ "github.com/microsoft/typescript-go/internal/ls/lsconv"
+ "github.com/microsoft/typescript-go/internal/lsp/lsproto"
+ "github.com/microsoft/typescript-go/internal/vfs"
+)
+
+type LocationMarker interface {
+ FileName() string
+ LSPos() lsproto.Position
+}
+
+type BaselineLocationsOptions struct {
+ // markerInfo
+ Marker LocationMarker // location
+ MarkerName string // name of the marker to be printed in baseline
+
+ EndMarker string
+
+ StartMarkerPrefix func(span lsproto.Location) *string
+ EndMarkerSuffix func(span lsproto.Location) *string
+ GetLocationData func(span lsproto.Location) string
+
+ AdditionalLocation *lsproto.Location
+
+ OpenFiles map[string]string
+}
+
+func GetBaselineForRename(
+ fs vfs.FS,
+ result lsproto.WorkspaceEditOrNull,
+ options BaselineLocationsOptions,
+) string {
+ var changes map[lsproto.DocumentUri][]*lsproto.TextEdit
+ if result.WorkspaceEdit != nil && result.WorkspaceEdit.Changes != nil {
+ changes = *result.WorkspaceEdit.Changes
+ }
+ locationToText := map[lsproto.Location]string{}
+ fileToRange := collections.MultiMap[lsproto.DocumentUri, lsproto.Range]{}
+ for uri, edits := range changes {
+ for _, edit := range edits {
+ fileToRange.Add(uri, edit.Range)
+ locationToText[lsproto.Location{Uri: uri, Range: edit.Range}] = edit.NewText
+ }
+ }
+
+ return getBaselineForGroupedLocationsWithFileContents(
+ fs,
+ &fileToRange,
+ BaselineLocationsOptions{
+ Marker: options.Marker,
+ MarkerName: "/*RENAME*/",
+ EndMarker: "RENAME|]",
+ StartMarkerPrefix: func(span lsproto.Location) *string {
+ text := locationToText[span]
+ prefixAndSuffix := strings.Split(text, "?")
+ if prefixAndSuffix[0] != "" {
+ return ptrTo("/*START PREFIX*/" + prefixAndSuffix[0])
+ }
+ return nil
+ },
+ EndMarkerSuffix: func(span lsproto.Location) *string {
+ text := locationToText[span]
+ prefixAndSuffix := strings.Split(text, "?")
+ if prefixAndSuffix[1] != "" {
+ return ptrTo(prefixAndSuffix[1] + "/*END SUFFIX*/")
+ }
+ return nil
+ },
+ OpenFiles: options.OpenFiles,
+ },
+ )
+}
+
+func symbolKindToString(kind lsproto.SymbolKind) string {
+ switch kind {
+ case lsproto.SymbolKindFile:
+ return "file"
+ case lsproto.SymbolKindModule:
+ return "module"
+ case lsproto.SymbolKindNamespace:
+ return "namespace"
+ case lsproto.SymbolKindPackage:
+ return "package"
+ case lsproto.SymbolKindClass:
+ return "class"
+ case lsproto.SymbolKindMethod:
+ return "method"
+ case lsproto.SymbolKindProperty:
+ return "property"
+ case lsproto.SymbolKindField:
+ return "field"
+ case lsproto.SymbolKindConstructor:
+ return "constructor"
+ case lsproto.SymbolKindEnum:
+ return "enum"
+ case lsproto.SymbolKindInterface:
+ return "interface"
+ case lsproto.SymbolKindFunction:
+ return "function"
+ case lsproto.SymbolKindVariable:
+ return "variable"
+ case lsproto.SymbolKindConstant:
+ return "constant"
+ case lsproto.SymbolKindString:
+ return "string"
+ case lsproto.SymbolKindNumber:
+ return "number"
+ case lsproto.SymbolKindBoolean:
+ return "boolean"
+ case lsproto.SymbolKindArray:
+ return "array"
+ case lsproto.SymbolKindObject:
+ return "object"
+ case lsproto.SymbolKindKey:
+ return "key"
+ case lsproto.SymbolKindNull:
+ return "null"
+ case lsproto.SymbolKindEnumMember:
+ return "enumMember"
+ case lsproto.SymbolKindStruct:
+ return "struct"
+ case lsproto.SymbolKindEvent:
+ return "event"
+ case lsproto.SymbolKindOperator:
+ return "operator"
+ case lsproto.SymbolKindTypeParameter:
+ return "typeParameter"
+ default:
+ return "unknown"
+ }
+}
+
+func GetBaselineForWorkspaceSymbol(
+ fs vfs.FS,
+ result lsproto.SymbolInformationsOrWorkspaceSymbolsOrNull,
+ options BaselineLocationsOptions,
+) string {
+ locationToText := map[lsproto.Location]*lsproto.SymbolInformation{}
+ fileToRange := collections.MultiMap[lsproto.DocumentUri, lsproto.Range]{}
+ var symbolInformations []*lsproto.SymbolInformation
+ if result.SymbolInformations != nil {
+ symbolInformations = *result.SymbolInformations
+ }
+ for _, symbol := range symbolInformations {
+ uri := symbol.Location.Uri
+ fileToRange.Add(uri, symbol.Location.Range)
+ locationToText[symbol.Location] = symbol
+ }
+ return getBaselineForGroupedLocationsWithFileContents(
+ fs,
+ &fileToRange,
+ BaselineLocationsOptions{
+ GetLocationData: func(span lsproto.Location) string {
+ symbol := locationToText[span]
+ return fmt.Sprintf("{| name: %s, kind: %s |}", symbol.Name, symbolKindToString(symbol.Kind))
+ },
+ OpenFiles: options.OpenFiles,
+ },
+ )
+}
+
+func GetBaselineForLocationsWithFileContents(
+ f vfs.FS,
+ spans []lsproto.Location,
+ options BaselineLocationsOptions,
+) string {
+ locationsByFile := collections.GroupBy(spans, func(span lsproto.Location) lsproto.DocumentUri { return span.Uri })
+ rangesByFile := collections.MultiMap[lsproto.DocumentUri, lsproto.Range]{}
+ for file, locs := range locationsByFile.M {
+ for _, loc := range locs {
+ rangesByFile.Add(file, loc.Range)
+ }
+ }
+ return getBaselineForGroupedLocationsWithFileContents(
+ f,
+ &rangesByFile,
+ options,
+ )
+}
+
+func getBaselineForGroupedLocationsWithFileContents(
+ f vfs.FS,
+ groupedRanges *collections.MultiMap[lsproto.DocumentUri, lsproto.Range],
+ options BaselineLocationsOptions,
+) string {
+ // We must always print the file containing the marker,
+ // but don't want to print it twice at the end if it already
+ // found in a file with ranges.
+ foundMarker := false
+ foundAdditionalLocation := false
+
+ baselineEntries := []string{}
+ err := f.WalkDir("/", func(path string, d vfs.DirEntry, e error) error {
+ if e != nil {
+ return e
+ }
+
+ if !d.Type().IsRegular() {
+ return nil
+ }
+
+ fileName := lsconv.FileNameToDocumentURI(path)
+ ranges := groupedRanges.Get(fileName)
+ if len(ranges) == 0 {
+ return nil
+ }
+
+ content, ok := readFile(f, path, options)
+ if !ok {
+ // !!! error?
+ return nil
+ }
+
+ if options.Marker != nil && options.Marker.FileName() == path {
+ foundMarker = true
+ }
+
+ if options.AdditionalLocation != nil && options.AdditionalLocation.Uri == fileName {
+ foundAdditionalLocation = true
+ }
+
+ baselineEntries = append(baselineEntries, getBaselineContentForFile(path, content, ranges, nil, options))
+ return nil
+ })
+
+ if err != nil && !errors.Is(err, fs.ErrNotExist) {
+ panic("walkdir error during fourslash baseline: " + err.Error())
+ }
+
+ // In Strada, there is a bug where we only ever add additional spans to baselines if we haven't
+ // already added the file to the baseline.
+ if options.AdditionalLocation != nil && !foundAdditionalLocation {
+ fileName := options.AdditionalLocation.Uri.FileName()
+ if content, ok := readFile(f, fileName, options); ok {
+ baselineEntries = append(
+ baselineEntries,
+ getBaselineContentForFile(fileName, content, []lsproto.Range{options.AdditionalLocation.Range}, nil, options),
+ )
+ if options.Marker != nil && options.Marker.FileName() == fileName {
+ foundMarker = true
+ }
+ }
+ }
+
+ if !foundMarker && options.Marker != nil {
+ // If we didn't find the marker in any file, we need to add it.
+ markerFileName := options.Marker.FileName()
+ if content, ok := readFile(f, markerFileName, options); ok {
+ baselineEntries = append(baselineEntries, getBaselineContentForFile(markerFileName, content, nil, nil, options))
+ }
+ }
+
+ // !!! skipDocumentContainingOnlyMarker
+
+ return strings.Join(baselineEntries, "\n\n")
+}
+
+func readFile(f vfs.FS, fileName string, options BaselineLocationsOptions) (string, bool) {
+ if content, ok := options.OpenFiles[fileName]; ok {
+ return content, ok
+ }
+ return f.ReadFile(fileName)
+}
+
+type baselineDetail struct {
+ pos lsproto.Position
+ positionMarker string
+ span *lsproto.Range
+ kind string
+}
+
+func getBaselineContentForFile(
+ fileName string,
+ content string,
+ spansInFile []lsproto.Range,
+ spanToContextId map[lsproto.Range]int,
+ options BaselineLocationsOptions,
+) string {
+ details := []*baselineDetail{}
+ detailPrefixes := map[*baselineDetail]string{}
+ detailSuffixes := map[*baselineDetail]string{}
+ canDetermineContextIdInline := true
+ uri := lsconv.FileNameToDocumentURI(fileName)
+
+ if options.Marker != nil && options.Marker.FileName() == fileName {
+ details = append(details, &baselineDetail{pos: options.Marker.LSPos(), positionMarker: options.MarkerName})
+ }
+
+ for _, span := range spansInFile {
+ textSpanIndex := len(details)
+ startMarker := "[|"
+ if options.GetLocationData != nil {
+ startMarker += options.GetLocationData(lsproto.Location{Uri: uri, Range: span})
+ }
+ details = append(details,
+ &baselineDetail{pos: span.Start, positionMarker: startMarker, span: &span, kind: "textStart"},
+ &baselineDetail{pos: span.End, positionMarker: core.OrElse(options.EndMarker, "|]"), span: &span, kind: "textEnd"},
+ )
+
+ if options.StartMarkerPrefix != nil {
+ startPrefix := options.StartMarkerPrefix(lsproto.Location{Uri: uri, Range: span})
+ if startPrefix != nil {
+ // Special case: if this span starts at the same position as the provided marker,
+ // we want the span's prefix to appear before the marker name.
+ // i.e. We want `/*START PREFIX*/A: /*RENAME*/[|ARENAME|]`,
+ // not `/*RENAME*//*START PREFIX*/A: [|ARENAME|]`
+ if options.Marker != nil && fileName == options.Marker.FileName() && span.Start == options.Marker.LSPos() {
+ _, ok := detailPrefixes[details[0]]
+ debug.Assert(!ok, "Expected only single prefix at marker location")
+ detailPrefixes[details[0]] = *startPrefix
+ } else {
+ detailPrefixes[details[textSpanIndex]] = *startPrefix
+ }
+ }
+ }
+
+ if options.EndMarkerSuffix != nil {
+ endSuffix := options.EndMarkerSuffix(lsproto.Location{Uri: uri, Range: span})
+ if endSuffix != nil {
+ detailSuffixes[details[textSpanIndex+1]] = *endSuffix
+ }
+ }
+ }
+
+ slices.SortStableFunc(details, func(d1, d2 *baselineDetail) int {
+ return lsproto.ComparePositions(d1.pos, d2.pos)
+ })
+ // !!! if canDetermineContextIdInline
+
+ textWithContext := newTextWithContext(fileName, content)
+
+ // Our preferred way to write marker is
+ // /*MARKER*/[| some text |]
+ // [| some /*MARKER*/ text |]
+ // [| some text |]/*MARKER*/
+ // Stable sort should handle first two cases but with that marker will be before rangeEnd if locations match
+ // So we will defer writing marker in this case by checking and finding index of rangeEnd if same
+ var deferredMarkerIndex *int
+
+ for index, detail := range details {
+ if detail.span == nil && deferredMarkerIndex == nil {
+ // If this is marker position and its same as textEnd and/or contextEnd we want to write marker after those
+ for matchingEndPosIndex := index + 1; matchingEndPosIndex < len(details); matchingEndPosIndex++ {
+ // Defer after the location if its same as rangeEnd
+ if details[matchingEndPosIndex].pos == detail.pos && strings.HasSuffix(details[matchingEndPosIndex].kind, "End") {
+ deferredMarkerIndex = ptrTo(matchingEndPosIndex)
+ }
+ // Dont defer further than already determined
+ break
+ }
+ // Defer writing marker position to deffered marker index
+ if deferredMarkerIndex != nil {
+ continue
+ }
+ }
+ textWithContext.add(detail)
+ textWithContext.pos = detail.pos
+ // Prefix
+ prefix := detailPrefixes[detail]
+ if prefix != "" {
+ textWithContext.newContent.WriteString(prefix)
+ }
+ textWithContext.newContent.WriteString(detail.positionMarker)
+ if detail.span != nil {
+ switch detail.kind {
+ case "textStart":
+ var text string
+ if contextId, ok := spanToContextId[*detail.span]; ok {
+ isAfterContextStart := false
+ for textStartIndex := index - 1; textStartIndex >= 0; textStartIndex-- {
+ textStartDetail := details[textStartIndex]
+ if textStartDetail.kind == "contextStart" && textStartDetail.span == detail.span {
+ isAfterContextStart = true
+ break
+ }
+ // Marker is ok to skip over
+ if textStartDetail.span != nil {
+ break
+ }
+ }
+ // Skip contextId on span thats surrounded by context span immediately
+ if !isAfterContextStart {
+ if text == "" {
+ text = fmt.Sprintf(`contextId: %v`, contextId)
+ } else {
+ text = fmt.Sprintf(`contextId: %v`, contextId) + `, ` + text
+ }
+ }
+ }
+ if text != "" {
+ textWithContext.newContent.WriteString(`{ ` + text + ` |}`)
+ }
+ case "contextStart":
+ if canDetermineContextIdInline {
+ spanToContextId[*detail.span] = len(spanToContextId)
+ }
+ }
+
+ if deferredMarkerIndex != nil && *deferredMarkerIndex == index {
+ // Write the marker
+ textWithContext.newContent.WriteString(options.MarkerName)
+ deferredMarkerIndex = nil
+ detail = details[0] // Marker detail
+ }
+ }
+ if suffix, ok := detailSuffixes[detail]; ok {
+ textWithContext.newContent.WriteString(suffix)
+ }
+ }
+ textWithContext.add(nil)
+ if textWithContext.newContent.Len() != 0 {
+ textWithContext.readableContents.WriteString("\n")
+ textWithContext.readableJsoncBaseline(textWithContext.newContent.String())
+ }
+ return textWithContext.readableContents.String()
+}
+
+var LineSplitter = regexp.MustCompile(`\r?\n`)
+
+type textWithContext struct {
+ nLinesContext int // number of context lines to write to baseline
+
+ readableContents *strings.Builder // builds what will be returned to be written to baseline
+
+ newContent *strings.Builder // helper; the part of the original file content to write between details
+ pos lsproto.Position
+ isLibFile bool
+ fileName string
+ content string // content of the original file
+ lineStarts *lsconv.LSPLineMap
+ converters *lsconv.Converters
+
+ // posLineInfo
+ posInfo *lsproto.Position
+ lineInfo int
+}
+
+// implements ls.Script
+func (t *textWithContext) FileName() string {
+ return t.fileName
+}
+
+// implements ls.Script
+func (t *textWithContext) Text() string {
+ return t.content
+}
+
+func newTextWithContext(fileName string, content string) *textWithContext {
+ t := &textWithContext{
+ nLinesContext: 4,
+
+ readableContents: &strings.Builder{},
+
+ isLibFile: regexp.MustCompile(`lib.*\.d\.ts$`).MatchString(fileName),
+ newContent: &strings.Builder{},
+ pos: lsproto.Position{Line: 0, Character: 0},
+ fileName: fileName,
+ content: content,
+ lineStarts: lsconv.ComputeLSPLineStarts(content),
+ }
+
+ t.converters = lsconv.NewConverters(lsproto.PositionEncodingKindUTF8, func(_ string) *lsconv.LSPLineMap {
+ return t.lineStarts
+ })
+ t.readableContents.WriteString("// === " + fileName + " ===")
+ return t
+}
+
+func (t *textWithContext) add(detail *baselineDetail) {
+ if t.content == "" && detail == nil {
+ panic("Unsupported")
+ }
+ if detail == nil || (detail.kind != "textEnd" && detail.kind != "contextEnd") {
+ // Calculate pos to location number of lines
+ posLineIndex := t.lineInfo
+ if t.posInfo == nil || *t.posInfo != t.pos {
+ posLineIndex = t.lineStarts.ComputeIndexOfLineStart(t.converters.LineAndCharacterToPosition(t, t.pos))
+ }
+
+ locationLineIndex := len(t.lineStarts.LineStarts) - 1
+ if detail != nil {
+ locationLineIndex = t.lineStarts.ComputeIndexOfLineStart(t.converters.LineAndCharacterToPosition(t, detail.pos))
+ t.posInfo = &detail.pos
+ t.lineInfo = locationLineIndex
+ }
+
+ nLines := 0
+ if t.newContent.Len() != 0 {
+ nLines += t.nLinesContext + 1
+ }
+ if detail != nil {
+ nLines += t.nLinesContext + 1
+ }
+ // first nLinesContext and last nLinesContext
+ if locationLineIndex-posLineIndex > nLines {
+ if t.newContent.Len() != 0 {
+ var skippedString string
+ if t.isLibFile {
+ skippedString = "--- (line: --) skipped ---\n"
+ } else {
+ skippedString = fmt.Sprintf(`// --- (line: %v) skipped ---`, posLineIndex+t.nLinesContext+1)
+ }
+
+ t.readableContents.WriteString("\n")
+ t.readableJsoncBaseline(t.newContent.String() + t.sliceOfContent(
+ t.getIndex(t.pos),
+ t.getIndex(t.lineStarts.LineStarts[posLineIndex+t.nLinesContext]),
+ ) + skippedString)
+
+ if detail != nil {
+ t.readableContents.WriteString("\n")
+ }
+ t.newContent.Reset()
+ }
+ if detail != nil {
+ if t.isLibFile {
+ t.newContent.WriteString("--- (line: --) skipped ---\n")
+ } else {
+ t.newContent.WriteString(fmt.Sprintf("--- (line: %v) skipped ---\n", locationLineIndex-t.nLinesContext+1))
+ }
+ t.newContent.WriteString(t.sliceOfContent(
+ t.getIndex(t.lineStarts.LineStarts[locationLineIndex-t.nLinesContext+1]),
+ t.getIndex(detail.pos),
+ ))
+ }
+ return
+ }
+ }
+ if detail == nil {
+ t.newContent.WriteString(t.sliceOfContent(t.getIndex(t.pos), nil))
+ } else {
+ t.newContent.WriteString(t.sliceOfContent(t.getIndex(t.pos), t.getIndex(detail.pos)))
+ }
+}
+
+func (t *textWithContext) readableJsoncBaseline(text string) {
+ for i, line := range LineSplitter.Split(text, -1) {
+ if i > 0 {
+ t.readableContents.WriteString("\n")
+ }
+ t.readableContents.WriteString(`// ` + line)
+ }
+}
+
+func (t *textWithContext) sliceOfContent(start *int, end *int) string {
+ if start == nil || *start < 0 {
+ start = ptrTo(0)
+ }
+
+ if end == nil || *end > len(t.content) {
+ end = ptrTo(len(t.content))
+ }
+
+ if *start > *end {
+ return ""
+ }
+
+ return t.content[*start:*end]
+}
+
+func (t *textWithContext) getIndex(i any) *int {
+ switch i := i.(type) {
+ case *int:
+ return i
+ case int:
+ return ptrTo(i)
+ case core.TextPos:
+ return ptrTo(int(i))
+ case *core.TextPos:
+ return ptrTo(int(*i))
+ case lsproto.Position:
+ return t.getIndex(t.converters.LineAndCharacterToPosition(t, i))
+ case *lsproto.Position:
+ return t.getIndex(t.converters.LineAndCharacterToPosition(t, *i))
+ }
+ panic(fmt.Sprintf("getIndex: unsupported type %T", i))
+}
diff --git a/internal/testutil/lsptestutil/converters.go b/internal/testutil/lsptestutil/converters.go
new file mode 100644
index 0000000000..d735ab46de
--- /dev/null
+++ b/internal/testutil/lsptestutil/converters.go
@@ -0,0 +1,45 @@
+package lsptestutil
+
+import (
+ "strings"
+
+ "github.com/microsoft/typescript-go/internal/core"
+ "github.com/microsoft/typescript-go/internal/ls/lsconv"
+ "github.com/microsoft/typescript-go/internal/lsp/lsproto"
+)
+
+type LsScript struct {
+ file string
+ text string
+}
+
+func NewLsScript(file string, text string) *LsScript {
+ return &LsScript{file: file, text: text}
+}
+
+var _ lsconv.Script = (*LsScript)(nil)
+
+func (s *LsScript) FileName() string { return s.file }
+func (s *LsScript) Text() string { return s.text }
+
+func PositionToLineAndCharacter(file string, text string, substring string, index int) lsproto.Position {
+ offset := nthIndexOf(text, substring, index)
+
+ converters := lsconv.NewConverters(lsproto.PositionEncodingKindUTF8, func(fileName string) *lsconv.LSPLineMap {
+ return lsconv.ComputeLSPLineStarts(text)
+ })
+ return converters.PositionToLineAndCharacter(NewLsScript(file, text), core.TextPos(offset))
+}
+
+func nthIndexOf(str string, substr string, n int) int {
+ index := 0
+ for i := range n + 1 {
+ start := core.IfElse(i == 0, index, index+len(substr))
+ index = strings.Index(str[start:], substr)
+ if index == -1 {
+ return -1
+ }
+ index += start
+ }
+ return index
+}
diff --git a/internal/testutil/lsptestutil/lsptestutil.go b/internal/testutil/lsptestutil/lsptestutil.go
new file mode 100644
index 0000000000..3af03c1d6a
--- /dev/null
+++ b/internal/testutil/lsptestutil/lsptestutil.go
@@ -0,0 +1,339 @@
+package lsptestutil
+
+import (
+ "context"
+ "io"
+ "strings"
+ "testing"
+
+ "github.com/go-json-experiment/json"
+ "github.com/microsoft/typescript-go/internal/bundled"
+ "github.com/microsoft/typescript-go/internal/core"
+ "github.com/microsoft/typescript-go/internal/ls/lsutil"
+ "github.com/microsoft/typescript-go/internal/lsp"
+ "github.com/microsoft/typescript-go/internal/lsp/lsproto"
+ "github.com/microsoft/typescript-go/internal/project"
+ "github.com/microsoft/typescript-go/internal/project/ata"
+ "github.com/microsoft/typescript-go/internal/project/logging"
+ "github.com/microsoft/typescript-go/internal/testutil/projecttestutil"
+ "github.com/microsoft/typescript-go/internal/vfs"
+ "gotest.tools/v3/assert"
+)
+
+type lspReader struct {
+ c <-chan *lsproto.Message
+}
+
+func (r *lspReader) Read() (*lsproto.Message, error) {
+ msg, ok := <-r.c
+ if !ok {
+ return nil, io.EOF
+ }
+ return msg, nil
+}
+
+type lspWriter struct {
+ c chan<- *lsproto.Message
+}
+
+func (w *lspWriter) Write(msg *lsproto.Message) error {
+ w.c <- msg
+ return nil
+}
+
+func (r *lspWriter) Close() {
+ close(r.c)
+}
+
+var (
+ _ lsp.Reader = (*lspReader)(nil)
+ _ lsp.Writer = (*lspWriter)(nil)
+)
+
+func newLSPPipe() (*lspReader, *lspWriter) {
+ c := make(chan *lsproto.Message, 100)
+ return &lspReader{c: c}, &lspWriter{c: c}
+}
+
+var (
+ ptrTrue = ptrTo(true)
+ defaultCompletionCapabilities = &lsproto.CompletionClientCapabilities{
+ CompletionItem: &lsproto.ClientCompletionItemOptions{
+ SnippetSupport: ptrTrue,
+ CommitCharactersSupport: ptrTrue,
+ PreselectSupport: ptrTrue,
+ LabelDetailsSupport: ptrTrue,
+ InsertReplaceSupport: ptrTrue,
+ DocumentationFormat: &[]lsproto.MarkupKind{lsproto.MarkupKindMarkdown, lsproto.MarkupKindPlainText},
+ },
+ CompletionList: &lsproto.CompletionListCapabilities{
+ ItemDefaults: &[]string{"commitCharacters", "editRange"},
+ },
+ }
+ defaultDefinitionCapabilities = &lsproto.DefinitionClientCapabilities{
+ LinkSupport: ptrTrue,
+ }
+ defaultTypeDefinitionCapabilities = &lsproto.TypeDefinitionClientCapabilities{
+ LinkSupport: ptrTrue,
+ }
+ defaultHoverCapabilities = &lsproto.HoverClientCapabilities{
+ ContentFormat: &[]lsproto.MarkupKind{lsproto.MarkupKindMarkdown, lsproto.MarkupKindPlainText},
+ }
+)
+
+type TestLspServer struct {
+ Server *lsp.Server
+ in *lspWriter
+ out *lspReader
+ id int32
+ FS vfs.FS
+ UserPreferences *lsutil.UserPreferences
+ TypingsLocation string
+}
+
+type TestLspServerOptions struct {
+ FS vfs.FS
+ Client project.Client
+ Logger logging.Logger
+ NpmExecutor ata.NpmExecutor
+ ParseCache *project.ParseCache
+ OptionsForInferredProject *core.CompilerOptions
+ TypingsLocation string
+ Capabilities *lsproto.ClientCapabilities
+}
+
+func NewTestLspServer(t *testing.T, options *TestLspServerOptions) *TestLspServer {
+ t.Helper()
+
+ inputReader, inputWriter := newLSPPipe()
+ outputReader, outputWriter := newLSPPipe()
+
+ var npmInstall func(cwd string, args []string) ([]byte, error)
+ if options.NpmExecutor != nil {
+ npmInstall = func(cwd string, args []string) ([]byte, error) {
+ return options.NpmExecutor.NpmInstall(cwd, args)
+ }
+ }
+
+ var err strings.Builder
+ server := lsp.NewServer(&lsp.ServerOptions{
+ In: inputReader,
+ Out: outputWriter,
+ Err: &err,
+
+ Cwd: "/",
+ FS: options.FS,
+ DefaultLibraryPath: bundled.LibPath(),
+ TypingsLocation: options.TypingsLocation,
+
+ ParseCache: options.ParseCache,
+ Client: options.Client,
+ Logger: options.Logger,
+ NpmInstall: npmInstall,
+ })
+
+ go func() {
+ defer func() {
+ outputWriter.Close()
+ }()
+ err := server.Run(context.TODO())
+ if err != nil {
+ t.Error("server error:", err)
+ }
+ }()
+
+ s := &TestLspServer{
+ Server: server,
+ in: inputWriter,
+ out: outputReader,
+ FS: options.FS,
+ UserPreferences: lsutil.NewDefaultUserPreferences(), // !!! parse default preferences for fourslash case?
+ TypingsLocation: options.TypingsLocation,
+ }
+
+ // !!! temporary; remove when we have `handleDidChangeConfiguration`/implicit project config support
+ // !!! replace with a proper request *after initialize*
+ if options.OptionsForInferredProject != nil {
+ s.Server.SetCompilerOptionsForInferredProjects(t.Context(), options.OptionsForInferredProject)
+ }
+ s.initialize(t, options.Capabilities)
+
+ t.Cleanup(func() {
+ inputWriter.Close()
+ })
+ return s
+}
+
+func (s *TestLspServer) nextID() int32 {
+ id := s.id
+ s.id++
+ return id
+}
+
+func (s *TestLspServer) initialize(t *testing.T, capabilities *lsproto.ClientCapabilities) {
+ params := &lsproto.InitializeParams{
+ Locale: ptrTo("en-US"),
+ }
+ params.Capabilities = getCapabilitiesWithDefaults(capabilities)
+ // !!! check for errors?
+ SendRequest(t, s, lsproto.InitializeInfo, params)
+ SendNotification(t, s, lsproto.InitializedInfo, &lsproto.InitializedParams{})
+}
+
+func getCapabilitiesWithDefaults(capabilities *lsproto.ClientCapabilities) *lsproto.ClientCapabilities {
+ var capabilitiesWithDefaults lsproto.ClientCapabilities
+ if capabilities != nil {
+ capabilitiesWithDefaults = *capabilities
+ }
+ capabilitiesWithDefaults.General = &lsproto.GeneralClientCapabilities{
+ PositionEncodings: &[]lsproto.PositionEncodingKind{lsproto.PositionEncodingKindUTF8},
+ }
+ if capabilitiesWithDefaults.TextDocument == nil {
+ capabilitiesWithDefaults.TextDocument = &lsproto.TextDocumentClientCapabilities{}
+ }
+ if capabilitiesWithDefaults.TextDocument.Completion == nil {
+ capabilitiesWithDefaults.TextDocument.Completion = defaultCompletionCapabilities
+ }
+ if capabilitiesWithDefaults.TextDocument.Diagnostic == nil {
+ capabilitiesWithDefaults.TextDocument.Diagnostic = &lsproto.DiagnosticClientCapabilities{
+ RelatedInformation: ptrTrue,
+ TagSupport: &lsproto.ClientDiagnosticsTagOptions{
+ ValueSet: []lsproto.DiagnosticTag{
+ lsproto.DiagnosticTagUnnecessary,
+ lsproto.DiagnosticTagDeprecated,
+ },
+ },
+ }
+ }
+ if capabilitiesWithDefaults.TextDocument.PublishDiagnostics == nil {
+ capabilitiesWithDefaults.TextDocument.PublishDiagnostics = &lsproto.PublishDiagnosticsClientCapabilities{
+ RelatedInformation: ptrTrue,
+ TagSupport: &lsproto.ClientDiagnosticsTagOptions{
+ ValueSet: []lsproto.DiagnosticTag{
+ lsproto.DiagnosticTagUnnecessary,
+ lsproto.DiagnosticTagDeprecated,
+ },
+ },
+ }
+ }
+ if capabilitiesWithDefaults.Workspace == nil {
+ capabilitiesWithDefaults.Workspace = &lsproto.WorkspaceClientCapabilities{}
+ }
+ if capabilitiesWithDefaults.Workspace.Configuration == nil {
+ capabilitiesWithDefaults.Workspace.Configuration = ptrTrue
+ }
+ if capabilitiesWithDefaults.TextDocument.Definition == nil {
+ capabilitiesWithDefaults.TextDocument.Definition = defaultDefinitionCapabilities
+ }
+ if capabilitiesWithDefaults.TextDocument.TypeDefinition == nil {
+ capabilitiesWithDefaults.TextDocument.TypeDefinition = defaultTypeDefinitionCapabilities
+ }
+ if capabilitiesWithDefaults.TextDocument.Hover == nil {
+ capabilitiesWithDefaults.TextDocument.Hover = defaultHoverCapabilities
+ }
+ if capabilitiesWithDefaults.TextDocument.SignatureHelp == nil {
+ capabilitiesWithDefaults.TextDocument.SignatureHelp = &lsproto.SignatureHelpClientCapabilities{
+ SignatureInformation: &lsproto.ClientSignatureInformationOptions{
+ DocumentationFormat: &[]lsproto.MarkupKind{lsproto.MarkupKindMarkdown, lsproto.MarkupKindPlainText},
+ ParameterInformation: &lsproto.ClientSignatureParameterInformationOptions{
+ LabelOffsetSupport: ptrTrue,
+ },
+ ActiveParameterSupport: ptrTrue,
+ },
+ ContextSupport: ptrTrue,
+ }
+ }
+ return &capabilitiesWithDefaults
+}
+
+func SendRequest[Params, Resp any](t *testing.T, server *TestLspServer, info lsproto.RequestInfo[Params, Resp], params Params) (*lsproto.Message, Resp, bool) {
+ id := server.nextID()
+ req := lsproto.NewRequestMessage(
+ info.Method,
+ lsproto.NewID(lsproto.IntegerOrString{Integer: &id}),
+ params,
+ )
+ server.writeMsg(t, req.Message())
+ resp := server.readMsg(t)
+ if resp == nil {
+ return nil, *new(Resp), false
+ }
+
+ // currently, the only request that may be sent by the server during a client request is one `config` request
+ // !!! remove if `config` is handled in initialization and there are no other server-initiated requests
+ if resp.Kind == lsproto.MessageKindRequest {
+ req := resp.AsRequest()
+ switch req.Method {
+ case lsproto.MethodWorkspaceConfiguration:
+ req := lsproto.ResponseMessage{
+ ID: req.ID,
+ JSONRPC: req.JSONRPC,
+ Result: []any{server.UserPreferences},
+ }
+ server.writeMsg(t, req.Message())
+ resp = server.readMsg(t)
+ default:
+ // other types of requests not yet used in fourslash; implement them if needed
+ t.Fatalf("Unexpected request received: %s", req.Method)
+ }
+ }
+
+ if resp == nil {
+ return nil, *new(Resp), false
+ }
+ result, ok := resp.AsResponse().Result.(Resp)
+ return resp, result, ok
+}
+
+func SendNotification[Params any](t *testing.T, server *TestLspServer, info lsproto.NotificationInfo[Params], params Params) {
+ notification := lsproto.NewNotificationMessage(
+ info.Method,
+ params,
+ )
+ server.writeMsg(t, notification.Message())
+}
+
+func (s *TestLspServer) writeMsg(t *testing.T, msg *lsproto.Message) {
+ assert.NilError(t, json.MarshalWrite(io.Discard, msg), "failed to encode message as JSON")
+ if err := s.in.Write(msg); err != nil {
+ t.Fatalf("failed to write message: %v", err)
+ }
+}
+
+func (s *TestLspServer) readMsg(t *testing.T) *lsproto.Message {
+ // !!! filter out response by id etc
+ msg, err := s.out.Read()
+ if err != nil {
+ t.Fatalf("failed to read message: %v", err)
+ }
+ assert.NilError(t, json.MarshalWrite(io.Discard, msg), "failed to encode message as JSON")
+ return msg
+}
+
+func (s *TestLspServer) Session() *project.Session { return s.Server.Session() }
+
+func ptrTo[T any](v T) *T {
+ return &v
+}
+
+func Setup(t *testing.T, files map[string]any) (*TestLspServer, *projecttestutil.SessionUtils) {
+ initOptions, sessionUtils := projecttestutil.GetSessionInitOptions(files, nil, &projecttestutil.TypingsInstallerOptions{})
+ initOptions.Options.TypingsLocation = "" // Disable ata
+ watchEnabledCapabilities := &lsproto.ClientCapabilities{
+ Workspace: &lsproto.WorkspaceClientCapabilities{
+ DidChangeWatchedFiles: &lsproto.DidChangeWatchedFilesClientCapabilities{
+ DynamicRegistration: ptrTo(true),
+ },
+ },
+ }
+ server := NewTestLspServer(t, &TestLspServerOptions{
+ FS: initOptions.FS,
+ Client: initOptions.Client,
+ Logger: initOptions.Logger,
+ NpmExecutor: initOptions.NpmExecutor,
+ ParseCache: initOptions.ParseCache,
+ TypingsLocation: initOptions.Options.TypingsLocation,
+ Capabilities: watchEnabledCapabilities,
+ })
+ return server, sessionUtils
+}
diff --git a/internal/testutil/projecttestutil/projecttestutil.go b/internal/testutil/projecttestutil/projecttestutil.go
index 169709d42c..73b2a6ceb4 100644
--- a/internal/testutil/projecttestutil/projecttestutil.go
+++ b/internal/testutil/projecttestutil/projecttestutil.go
@@ -15,6 +15,7 @@ import (
"github.com/microsoft/typescript-go/internal/project/logging"
"github.com/microsoft/typescript-go/internal/testutil/baseline"
"github.com/microsoft/typescript-go/internal/vfs"
+ "github.com/microsoft/typescript-go/internal/vfs/iovfs"
"github.com/microsoft/typescript-go/internal/vfs/vfstest"
)
@@ -34,11 +35,16 @@ type TypingsInstallerOptions struct {
}
type SessionUtils struct {
- fs vfs.FS
- client *ClientMock
- npmExecutor *NpmExecutorMock
- tiOptions *TypingsInstallerOptions
- logger logging.LogCollector
+ fsFromFileMap iovfs.FsWithSys
+ fs vfs.FS
+ client *ClientMock
+ npmExecutor *NpmExecutorMock
+ tiOptions *TypingsInstallerOptions
+ logger logging.LogCollector
+}
+
+func (h *SessionUtils) FsFromFileMap() iovfs.FsWithSys {
+ return h.fsFromFileMap
}
func (h *SessionUtils) Client() *ClientMock {
@@ -192,15 +198,28 @@ func SetupWithTypingsInstaller(files map[string]any, tiOptions *TypingsInstaller
}
func SetupWithOptionsAndTypingsInstaller(files map[string]any, options *project.SessionOptions, tiOptions *TypingsInstallerOptions) (*project.Session, *SessionUtils) {
- fs := bundled.WrapFS(vfstest.FromMap(files, false /*useCaseSensitiveFileNames*/))
+ init, sessionUtils := GetSessionInitOptions(files, options, tiOptions)
+ session := project.NewSession(init)
+
+ return session, sessionUtils
+}
+
+func WithRequestID(ctx context.Context) context.Context {
+ return core.WithRequestID(ctx, "0")
+}
+
+func GetSessionInitOptions(files map[string]any, options *project.SessionOptions, tiOptions *TypingsInstallerOptions) (*project.SessionInit, *SessionUtils) {
+ fsFromFileMap := vfstest.FromMap(files, false /*useCaseSensitiveFileNames*/)
+ fs := bundled.WrapFS(fsFromFileMap)
clientMock := &ClientMock{}
npmExecutorMock := &NpmExecutorMock{}
sessionUtils := &SessionUtils{
- fs: fs,
- client: clientMock,
- npmExecutor: npmExecutorMock,
- tiOptions: tiOptions,
- logger: logging.NewTestLogger(),
+ fsFromFileMap: fsFromFileMap.(iovfs.FsWithSys),
+ fs: fs,
+ client: clientMock,
+ npmExecutor: npmExecutorMock,
+ tiOptions: tiOptions,
+ logger: logging.NewTestLogger(),
}
// Configure the npm executor mock to handle typings installation
@@ -218,17 +237,11 @@ func SetupWithOptionsAndTypingsInstaller(files map[string]any, options *project.
}
}
- session := project.NewSession(&project.SessionInit{
+ return &project.SessionInit{
Options: options,
FS: fs,
Client: clientMock,
NpmExecutor: npmExecutorMock,
Logger: sessionUtils.logger,
- })
-
- return session, sessionUtils
-}
-
-func WithRequestID(ctx context.Context) context.Context {
- return core.WithRequestID(ctx, "0")
+ }, sessionUtils
}
diff --git a/internal/testutil/stringtestutil/stringtestutil.go b/internal/testutil/stringtestutil/stringtestutil.go
index 4a1e70f271..482186d64c 100644
--- a/internal/testutil/stringtestutil/stringtestutil.go
+++ b/internal/testutil/stringtestutil/stringtestutil.go
@@ -29,7 +29,15 @@ func Dedent(text string) string {
}
}
lines = lines[startLine : lastLine+1]
- indentation := stringutil.GuessIndentation(lines)
+ mappedLines := make([]string, len(lines))
+ for i, line := range lines {
+ if trimmed := strings.TrimSpace(line); trimmed == "" {
+ mappedLines[i] = ""
+ } else {
+ mappedLines[i] = line
+ }
+ }
+ indentation := stringutil.GuessIndentation(mappedLines)
if indentation > 0 {
for i := range lines {
if len(lines[i]) > indentation {
diff --git a/testdata/baselines/reference/fourslash/findAllReferences/autoImportProvider_referencesCrash.baseline.jsonc b/testdata/baselines/reference/fourslash/findAllReferences/autoImportProvider_referencesCrash.baseline.jsonc
index a1f16deccb..4d12d4f3f4 100644
--- a/testdata/baselines/reference/fourslash/findAllReferences/autoImportProvider_referencesCrash.baseline.jsonc
+++ b/testdata/baselines/reference/fourslash/findAllReferences/autoImportProvider_referencesCrash.baseline.jsonc
@@ -1,8 +1,6 @@
// === findAllReferences ===
-// === /home/src/workspaces/project/a/index.d.ts ===
-// declare class [|A|] {
-// }
-// //# sourceMappingURL=index.d.ts.map
+// === /home/src/workspaces/project/a/index.ts ===
+// class A {}[||]
// === /home/src/workspaces/project/b/b.ts ===
// ///
diff --git a/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesUmdModuleAsGlobalConst.baseline.jsonc b/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesUmdModuleAsGlobalConst.baseline.jsonc
index 63169a81fa..e6b3049cf9 100644
--- a/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesUmdModuleAsGlobalConst.baseline.jsonc
+++ b/testdata/baselines/reference/fourslash/findAllReferences/findAllReferencesUmdModuleAsGlobalConst.baseline.jsonc
@@ -6,6 +6,10 @@
// === findAllReferences ===
+// === /node_modules/@types/three/index.d.ts ===
+// export * from "[|./three-core|]";
+// export as namespace THREE;
+
// === /typings/global.d.ts ===
// import * as _THREE from '/*FIND ALL REFS*/[|three|]';
// declare global {
diff --git a/testdata/baselines/reference/fourslash/findAllReferences/isDefinitionAcrossModuleProjects.baseline.jsonc b/testdata/baselines/reference/fourslash/findAllReferences/isDefinitionAcrossModuleProjects.baseline.jsonc
index bab15b51fa..ed26eaa2e9 100644
--- a/testdata/baselines/reference/fourslash/findAllReferences/isDefinitionAcrossModuleProjects.baseline.jsonc
+++ b/testdata/baselines/reference/fourslash/findAllReferences/isDefinitionAcrossModuleProjects.baseline.jsonc
@@ -43,6 +43,27 @@
// FC() { },
// };
+// === /home/src/workspaces/project/a2/index.ts ===
+// import { NS } from "../b";
+// import { [|I|] } from "../c";
+//
+// declare module "../b" {
+// export namespace NS {
+// export function FA();
+// }
+// }
+//
+// declare module "../c" {
+// export interface [|I|] {
+// FA();
+// }
+// }
+//
+// const ia: [|I|] = {
+// FA: NS.FA,
+// FC() { },
+// };
+
// === /home/src/workspaces/project/c/index.ts ===
// export namespace NS {
// export function FC() {}
@@ -97,6 +118,27 @@
// === findAllReferences ===
+// === /home/src/workspaces/project/a/index.ts ===
+// import { NS } from "../b";
+// import { [|I|] } from "../c";
+//
+// declare module "../b" {
+// export namespace NS {
+// export function FA();
+// }
+// }
+//
+// declare module "../c" {
+// export interface [|I|] {
+// FA();
+// }
+// }
+//
+// const ia: [|I|] = {
+// FA: NS.FA,
+// FC() { },
+// };
+
// === /home/src/workspaces/project/a2/index.ts ===
// import { NS } from "../b";
// import { [|I|] } from "../c";
@@ -199,6 +241,48 @@
// === findAllReferences ===
+// === /home/src/workspaces/project/a/index.ts ===
+// import { NS } from "../b";
+// import { [|I|] } from "../c";
+//
+// declare module "../b" {
+// export namespace NS {
+// export function FA();
+// }
+// }
+//
+// declare module "../c" {
+// export interface [|I|] {
+// FA();
+// }
+// }
+//
+// const ia: [|I|] = {
+// FA: NS.FA,
+// FC() { },
+// };
+
+// === /home/src/workspaces/project/a2/index.ts ===
+// import { NS } from "../b";
+// import { [|I|] } from "../c";
+//
+// declare module "../b" {
+// export namespace NS {
+// export function FA();
+// }
+// }
+//
+// declare module "../c" {
+// export interface [|I|] {
+// FA();
+// }
+// }
+//
+// const ia: [|I|] = {
+// FA: NS.FA,
+// FC() { },
+// };
+
// === /home/src/workspaces/project/c/index.ts ===
// export namespace NS {
// export function FC() {}
@@ -213,6 +297,22 @@
// === findAllReferences ===
+// === /home/src/workspaces/project/a/index.ts ===
+// --- (line: 14) skipped ---
+//
+// const ia: I = {
+// FA: NS.FA,
+// [|FC|]() { },
+// };
+
+// === /home/src/workspaces/project/a2/index.ts ===
+// --- (line: 14) skipped ---
+//
+// const ia: I = {
+// FA: NS.FA,
+// [|FC|]() { },
+// };
+
// === /home/src/workspaces/project/c/index.ts ===
// export namespace NS {
// export function FC() {}
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-definition-is-in-mapped-file.js b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-definition-is-in-mapped-file.js
new file mode 100644
index 0000000000..9019f5296c
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-definition-is-in-mapped-file.js
@@ -0,0 +1,100 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function f() {}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/b.ts] *new*
+import { f } from "../a/bin/a";
+f();
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "../a" }
+ ]
+}
+//// [/home/src/projects/project/bin/a.d.ts] *new*
+export declare function f(): void;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/bin/a.d.ts.map] *new*
+{
+ "version":3,
+ "file":"a.d.ts",
+ "sourceRoot":"",
+ "sources":["a.ts"],
+ "names":[],
+ "mappings":"AAAA,wBAAgB,CAAC,SAAK"
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/b/b.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { f } from \"../a/bin/a\";\nf();"
+ }
+ }
+}
+Projects::
+ [/home/src/projects/project/b/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+ /home/src/projects/project/b/b.ts
+Open Files::
+ [/home/src/projects/project/b/b.ts] *new*
+ /home/src/projects/project/b/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/b/tsconfig.json
+ [/home/src/projects/project/b/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/b/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/b/b.ts
+Config File Names::
+ [/home/src/projects/project/b/b.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/b/b.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 0
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/b/tsconfig.json]
+ /home/src/projects/project/a/a.ts
+ /home/src/projects/project/b/b.ts
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /home/src/projects/project/a/tsconfig.json *new*
+ /home/src/projects/project/b/tsconfig.json
+ [/home/src/projects/project/b/tsconfig.json]
+ RetainingProjects:
+ /home/src/projects/project/b/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/b/b.ts
+// === /home/src/projects/project/a/a.ts ===
+// export function [|f|]() {}
+
+// === /home/src/projects/project/b/b.ts ===
+// import { [|f|] } from "../a/bin/a";
+// /*FIND ALL REFS*/[|f|]();
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-starting-at-definition.js b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-starting-at-definition.js
new file mode 100644
index 0000000000..ff95ca32f0
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-starting-at-definition.js
@@ -0,0 +1,195 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function fnA() {}
+export interface IfaceA {}
+export const instanceA: IfaceA = {};
+//// [/home/src/projects/project/a/bin/a.d.ts] *new*
+export declare function fnA(): void;
+export interface IfaceA {
+}
+export declare const instanceA: IfaceA;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/a/bin/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/bin/b.d.ts] *new*
+export declare function fnB(): void;
+//# sourceMappingURL=b.d.ts.map
+//// [/home/src/projects/project/b/bin/b.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+}
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/dummy/dummy.ts] *new*
+export const a = 10;
+//// [/home/src/projects/project/dummy/tsconfig.json] *new*
+{}
+//// [/home/src/projects/project/user/user.ts] *new*
+import * as a from "../a/bin/a";
+import * as b from "../b/bin/b";
+export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as a from \"../a/bin/a\";\nimport * as b from \"../b/bin/b\";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/user/user.ts] *new*
+ /dev/null/inferred (default)
+Config File Names::
+ [/home/src/projects/project/user/user.ts] *new*
+ NearestConfigFileName:
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/a/a.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fnA() {}\nexport interface IfaceA {}\nexport const instanceA: IfaceA = {};"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred]
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+Open Files::
+ [/home/src/projects/project/a/a.ts] *new*
+ /home/src/projects/project/a/tsconfig.json (default)
+ [/home/src/projects/project/user/user.ts]
+ /dev/null/inferred (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/a/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/a/a.ts
+Config File Names::
+ [/home/src/projects/project/a/a.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/a/tsconfig.json
+ Ancestors:
+ /home/src/projects/project/a/tsconfig.json
+ [/home/src/projects/project/user/user.ts]
+ NearestConfigFileName:
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/a/a.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 16
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /home/src/projects/project/a/a.ts ===
+// export function /*FIND ALL REFS*/[|fnA|]() {}
+// export interface IfaceA {}
+// export const instanceA: IfaceA = {};
+
+// === /home/src/projects/project/user/user.ts ===
+// import * as a from "../a/bin/a";
+// import * as b from "../b/bin/b";
+// export function fnUser() { a.[|fnA|](); b.fnB(); a.instanceA; }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ }
+ }
+}
+Open Files::
+ [/home/src/projects/project/a/a.ts]
+ /home/src/projects/project/a/tsconfig.json (default)
+ [/home/src/projects/project/user/user.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json]
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ /home/src/projects/project/dummy/dummy.ts
+Open Files::
+ [/home/src/projects/project/a/a.ts]
+ /home/src/projects/project/a/tsconfig.json (default)
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ /home/src/projects/project/dummy/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json]
+ RetainingProjects:
+ /home/src/projects/project/a/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/dummy/dummy.ts
+Config File Names::
+ [/home/src/projects/project/a/a.ts]
+ NearestConfigFileName: /home/src/projects/project/a/tsconfig.json
+ Ancestors:
+ /home/src/projects/project/a/tsconfig.json
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/dummy/tsconfig.json
+ [/home/src/projects/project/user/user.ts] *deleted*
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-target-does-not-exist.js b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-target-does-not-exist.js
new file mode 100644
index 0000000000..de25051493
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences-target-does-not-exist.js
@@ -0,0 +1,143 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function fnA() {}
+export interface IfaceA {}
+export const instanceA: IfaceA = {};
+//// [/home/src/projects/project/a/bin/a.d.ts] *new*
+export declare function fnA(): void;
+export interface IfaceA {
+}
+export declare const instanceA: IfaceA;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/a/bin/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/bin/b.d.ts] *new*
+export declare function fnB(): void;
+//# sourceMappingURL=b.d.ts.map
+//// [/home/src/projects/project/b/bin/b.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+}
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/dummy/dummy.ts] *new*
+export const a = 10;
+//// [/home/src/projects/project/dummy/tsconfig.json] *new*
+{}
+//// [/home/src/projects/project/user/user.ts] *new*
+import * as a from "../a/bin/a";
+import * as b from "../b/bin/b";
+export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as a from \"../a/bin/a\";\nimport * as b from \"../b/bin/b\";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/user/user.ts] *new*
+ /dev/null/inferred (default)
+Config File Names::
+ [/home/src/projects/project/user/user.ts] *new*
+ NearestConfigFileName:
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 38
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /home/src/projects/project/b/bin/b.d.ts ===
+// export declare function [|fnB|](): void;
+// //# sourceMappingURL=b.d.ts.map
+
+// === /home/src/projects/project/user/user.ts ===
+// import * as a from "../a/bin/a";
+// import * as b from "../b/bin/b";
+// export function fnUser() { a.fnA(); b./*FIND ALL REFS*/[|fnB|](); a.instanceA; }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ }
+ }
+}
+Open Files::
+ [/home/src/projects/project/user/user.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ /home/src/projects/project/dummy/dummy.ts
+Open Files::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ /home/src/projects/project/dummy/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/dummy/dummy.ts
+Config File Names::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/dummy/tsconfig.json
+ [/home/src/projects/project/user/user.ts] *deleted*
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences.js b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences.js
new file mode 100644
index 0000000000..46d24f10e0
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/findAllReferences.js
@@ -0,0 +1,158 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function fnA() {}
+export interface IfaceA {}
+export const instanceA: IfaceA = {};
+//// [/home/src/projects/project/a/bin/a.d.ts] *new*
+export declare function fnA(): void;
+export interface IfaceA {
+}
+export declare const instanceA: IfaceA;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/a/bin/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/bin/b.d.ts] *new*
+export declare function fnB(): void;
+//# sourceMappingURL=b.d.ts.map
+//// [/home/src/projects/project/b/bin/b.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+}
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/dummy/dummy.ts] *new*
+export const a = 10;
+//// [/home/src/projects/project/dummy/tsconfig.json] *new*
+{}
+//// [/home/src/projects/project/user/user.ts] *new*
+import * as a from "../a/bin/a";
+import * as b from "../b/bin/b";
+export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as a from \"../a/bin/a\";\nimport * as b from \"../b/bin/b\";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/user/user.ts] *new*
+ /dev/null/inferred (default)
+Config File Names::
+ [/home/src/projects/project/user/user.ts] *new*
+ NearestConfigFileName:
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 29
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred]
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/a/tsconfig.json
+// === /home/src/projects/project/a/a.ts ===
+// export function [|fnA|]() {}
+// export interface IfaceA {}
+// export const instanceA: IfaceA = {};
+
+// === /home/src/projects/project/user/user.ts ===
+// import * as a from "../a/bin/a";
+// import * as b from "../b/bin/b";
+// export function fnUser() { a./*FIND ALL REFS*/[|fnA|](); b.fnB(); a.instanceA; }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ }
+ }
+}
+Open Files::
+ [/home/src/projects/project/user/user.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json] *deleted*
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ /home/src/projects/project/dummy/dummy.ts
+Open Files::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ /home/src/projects/project/dummy/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *deleted*
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/dummy/dummy.ts
+Config File Names::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/dummy/tsconfig.json
+ [/home/src/projects/project/user/user.ts] *deleted*
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/opening-original-location-project-disableSourceOfProjectReferenceRedirect.js b/testdata/baselines/reference/lspservertests/declarationMaps/opening-original-location-project-disableSourceOfProjectReferenceRedirect.js
new file mode 100644
index 0000000000..2b6fbac228
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/opening-original-location-project-disableSourceOfProjectReferenceRedirect.js
@@ -0,0 +1,98 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/a/a.d.ts] *new*
+export declare class A {
+}
+//# sourceMappingURL=a.d.ts.map
+//// [/user/username/projects/a/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["./a.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;CAAI"
+}
+//// [/user/username/projects/a/a.ts] *new*
+export class A { }
+//// [/user/username/projects/a/tsconfig.json] *new*
+{}
+//// [/user/username/projects/b/b.ts] *new*
+import {A} from "../a/a";
+new A();
+//// [/user/username/projects/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "disableSourceOfProjectReferenceRedirect": true
+ },
+ "references": [
+ { "path": "../a" }
+ ]
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/b/b.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import {A} from \"../a/a\";\nnew A();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/b/tsconfig.json] *new*
+ /user/username/projects/a/a.d.ts
+ /user/username/projects/b/b.ts
+Open Files::
+ [/user/username/projects/b/b.ts] *new*
+ /user/username/projects/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/b/tsconfig.json
+ [/user/username/projects/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/b/b.ts
+Config File Names::
+ [/user/username/projects/b/b.ts] *new*
+ NearestConfigFileName: /user/username/projects/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/b/b.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 4
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/a/tsconfig.json] *new*
+ /user/username/projects/a/a.ts
+ [/user/username/projects/b/tsconfig.json]
+ /user/username/projects/a/a.d.ts
+ /user/username/projects/b/b.ts
+Config::
+ [/user/username/projects/a/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/a/tsconfig.json *new*
+ /user/username/projects/b/tsconfig.json
+ [/user/username/projects/b/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/b/b.ts
+// === /user/username/projects/a/a.ts ===
+// export class [|A|] { }
+
+// === /user/username/projects/b/b.ts ===
+// import {[|A|]} from "../a/a";
+// new /*FIND ALL REFS*/[|A|]();
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/opening-original-location-project.js b/testdata/baselines/reference/lspservertests/declarationMaps/opening-original-location-project.js
new file mode 100644
index 0000000000..462ba342d2
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/opening-original-location-project.js
@@ -0,0 +1,98 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/a/a.d.ts] *new*
+export declare class A {
+}
+//# sourceMappingURL=a.d.ts.map
+//// [/user/username/projects/a/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["./a.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;CAAI"
+}
+//// [/user/username/projects/a/a.ts] *new*
+export class A { }
+//// [/user/username/projects/a/tsconfig.json] *new*
+{}
+//// [/user/username/projects/b/b.ts] *new*
+import {A} from "../a/a";
+new A();
+//// [/user/username/projects/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "disableSourceOfProjectReferenceRedirect": false
+ },
+ "references": [
+ { "path": "../a" }
+ ]
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/b/b.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import {A} from \"../a/a\";\nnew A();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/b/tsconfig.json] *new*
+ /user/username/projects/a/a.ts
+ /user/username/projects/b/b.ts
+Open Files::
+ [/user/username/projects/b/b.ts] *new*
+ /user/username/projects/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/b/tsconfig.json
+ [/user/username/projects/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/b/b.ts
+Config File Names::
+ [/user/username/projects/b/b.ts] *new*
+ NearestConfigFileName: /user/username/projects/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/b/b.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 4
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/a/tsconfig.json] *new*
+ /user/username/projects/a/a.ts
+ [/user/username/projects/b/tsconfig.json]
+ /user/username/projects/a/a.ts
+ /user/username/projects/b/b.ts
+Config::
+ [/user/username/projects/a/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/a/tsconfig.json *new*
+ /user/username/projects/b/tsconfig.json
+ [/user/username/projects/b/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/b/b.ts
+// === /user/username/projects/a/a.ts ===
+// export class [|A|] { }
+
+// === /user/username/projects/b/b.ts ===
+// import {[|A|]} from "../a/a";
+// new /*FIND ALL REFS*/[|A|]();
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-before-project-is-built.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-before-project-is-built.js
new file mode 100644
index 0000000000..35dc86e798
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-before-project-is-built.js
@@ -0,0 +1,287 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ [/user/username/projects/random/tsconfig.json] *new*
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/random/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts]
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *closed*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/main/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *deleted*
+ [/user/username/projects/random/random.ts]
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-disableSourceOfProjectReferenceRedirect.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-disableSourceOfProjectReferenceRedirect.js
new file mode 100644
index 0000000000..fd3ada8222
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-disableSourceOfProjectReferenceRedirect.js
@@ -0,0 +1,388 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "disableSourceOfProjectReferenceRedirect": true
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json *new*
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
+{
+ "method": "textDocument/didChange",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 0
+ },
+ "end": {
+ "line": 5,
+ "character": 0
+ }
+ },
+ "text": "const x = 10;"
+ }
+ ]
+ }
+}
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ [/user/username/projects/myproject/main/tsconfig.json]
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+// const x = 10;
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-project-references.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-project-references.js
new file mode 100644
index 0000000000..b08ec4d4c4
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-project-references.js
@@ -0,0 +1,388 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
+{
+ "method": "textDocument/didChange",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 0
+ },
+ "end": {
+ "line": 5,
+ "character": 0
+ }
+ },
+ "text": "const x = 10;"
+ }
+ ]
+ }
+}
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ [/user/username/projects/myproject/main/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+// const x = 10;
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-source-maps.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-source-maps.js
new file mode 100644
index 0000000000..e8873fb5ff
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-at-end-with-source-maps.js
@@ -0,0 +1,347 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/decls/FnS.d.ts *new*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json *new*
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+{
+ "method": "textDocument/didChange",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": {
+ "line": 5,
+ "character": 0
+ },
+ "end": {
+ "line": 5,
+ "character": 0
+ }
+ },
+ "text": "const x = 10;"
+ }
+ ]
+ }
+}
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+// const x = 10;
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-disableSourceOfProjectReferenceRedirect.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-disableSourceOfProjectReferenceRedirect.js
new file mode 100644
index 0000000000..554a98f847
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-disableSourceOfProjectReferenceRedirect.js
@@ -0,0 +1,389 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "disableSourceOfProjectReferenceRedirect": true
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json *new*
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
+{
+ "method": "textDocument/didChange",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 0
+ },
+ "end": {
+ "line": 0,
+ "character": 0
+ }
+ },
+ "text": "function fooBar() { }\n"
+ }
+ ]
+ }
+}
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 3,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ [/user/username/projects/myproject/main/tsconfig.json]
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// function fooBar() { }
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-project-references.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-project-references.js
new file mode 100644
index 0000000000..4be8d7aa48
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-project-references.js
@@ -0,0 +1,389 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
+{
+ "method": "textDocument/didChange",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 0
+ },
+ "end": {
+ "line": 0,
+ "character": 0
+ }
+ },
+ "text": "function fooBar() { }\n"
+ }
+ ]
+ }
+}
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 3,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ [/user/username/projects/myproject/main/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// function fooBar() { }
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-source-maps.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-source-maps.js
new file mode 100644
index 0000000000..6e2cab5fe8
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-on-edit-with-source-maps.js
@@ -0,0 +1,348 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/decls/FnS.d.ts *new*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json *new*
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+{
+ "method": "textDocument/didChange",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 0
+ },
+ "end": {
+ "line": 0,
+ "character": 0
+ }
+ },
+ "text": "function fooBar() { }\n"
+ }
+ ]
+ }
+}
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 3,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/dependency/FnS.ts *modified*
+ /user/username/projects/myproject/main/main.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// function fooBar() { }
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-starting-at-definition.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-starting-at-definition.js
new file mode 100644
index 0000000000..e1a61f24a9
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-starting-at-definition.js
@@ -0,0 +1,193 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function fnA() {}
+export interface IfaceA {}
+export const instanceA: IfaceA = {};
+//// [/home/src/projects/project/a/bin/a.d.ts] *new*
+export declare function fnA(): void;
+export interface IfaceA {
+}
+export declare const instanceA: IfaceA;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/a/bin/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/bin/b.d.ts] *new*
+export declare function fnB(): void;
+//# sourceMappingURL=b.d.ts.map
+//// [/home/src/projects/project/b/bin/b.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+}
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/dummy/dummy.ts] *new*
+export const a = 10;
+//// [/home/src/projects/project/dummy/tsconfig.json] *new*
+{}
+//// [/home/src/projects/project/user/user.ts] *new*
+import * as a from "../a/bin/a";
+import * as b from "../b/bin/b";
+export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as a from \"../a/bin/a\";\nimport * as b from \"../b/bin/b\";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/user/user.ts] *new*
+ /dev/null/inferred (default)
+Config File Names::
+ [/home/src/projects/project/user/user.ts] *new*
+ NearestConfigFileName:
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/a/a.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fnA() {}\nexport interface IfaceA {}\nexport const instanceA: IfaceA = {};"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred]
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+Open Files::
+ [/home/src/projects/project/a/a.ts] *new*
+ /home/src/projects/project/a/tsconfig.json (default)
+ [/home/src/projects/project/user/user.ts]
+ /dev/null/inferred (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/a/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/a/a.ts
+Config File Names::
+ [/home/src/projects/project/a/a.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/a/tsconfig.json
+ Ancestors:
+ /home/src/projects/project/a/tsconfig.json
+ [/home/src/projects/project/user/user.ts]
+ NearestConfigFileName:
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/a/a.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+// === /home/src/projects/project/a/a.ts ===
+// export function /*RENAME*/[|fnARENAME|]() {}
+// export interface IfaceA {}
+// export const instanceA: IfaceA = {};
+
+// === /home/src/projects/project/user/user.ts ===
+// import * as a from "../a/bin/a";
+// import * as b from "../b/bin/b";
+// export function fnUser() { a.[|fnARENAME|](); b.fnB(); a.instanceA; }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ }
+ }
+}
+Open Files::
+ [/home/src/projects/project/a/a.ts]
+ /home/src/projects/project/a/tsconfig.json (default)
+ [/home/src/projects/project/user/user.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json]
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ /home/src/projects/project/dummy/dummy.ts
+Open Files::
+ [/home/src/projects/project/a/a.ts]
+ /home/src/projects/project/a/tsconfig.json (default)
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ /home/src/projects/project/dummy/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json]
+ RetainingProjects:
+ /home/src/projects/project/a/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/dummy/dummy.ts
+Config File Names::
+ [/home/src/projects/project/a/a.ts]
+ NearestConfigFileName: /home/src/projects/project/a/tsconfig.json
+ Ancestors:
+ /home/src/projects/project/a/tsconfig.json
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/dummy/tsconfig.json
+ [/home/src/projects/project/user/user.ts] *deleted*
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-target-does-not-exist.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-target-does-not-exist.js
new file mode 100644
index 0000000000..45b7354efa
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-target-does-not-exist.js
@@ -0,0 +1,141 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function fnA() {}
+export interface IfaceA {}
+export const instanceA: IfaceA = {};
+//// [/home/src/projects/project/a/bin/a.d.ts] *new*
+export declare function fnA(): void;
+export interface IfaceA {
+}
+export declare const instanceA: IfaceA;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/a/bin/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/bin/b.d.ts] *new*
+export declare function fnB(): void;
+//# sourceMappingURL=b.d.ts.map
+//// [/home/src/projects/project/b/bin/b.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+}
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/dummy/dummy.ts] *new*
+export const a = 10;
+//// [/home/src/projects/project/dummy/tsconfig.json] *new*
+{}
+//// [/home/src/projects/project/user/user.ts] *new*
+import * as a from "../a/bin/a";
+import * as b from "../b/bin/b";
+export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as a from \"../a/bin/a\";\nimport * as b from \"../b/bin/b\";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/user/user.ts] *new*
+ /dev/null/inferred (default)
+Config File Names::
+ [/home/src/projects/project/user/user.ts] *new*
+ NearestConfigFileName:
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 38
+ },
+ "newName": "?"
+ }
+}
+// === /home/src/projects/project/b/bin/b.d.ts ===
+// export declare function [|fnBRENAME|](): void;
+// //# sourceMappingURL=b.d.ts.map
+
+// === /home/src/projects/project/user/user.ts ===
+// import * as a from "../a/bin/a";
+// import * as b from "../b/bin/b";
+// export function fnUser() { a.fnA(); b./*RENAME*/[|fnBRENAME|](); a.instanceA; }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ }
+ }
+}
+Open Files::
+ [/home/src/projects/project/user/user.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ /home/src/projects/project/dummy/dummy.ts
+Open Files::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ /home/src/projects/project/dummy/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/dummy/dummy.ts
+Config File Names::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/dummy/tsconfig.json
+ [/home/src/projects/project/user/user.ts] *deleted*
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-disableSourceOfProjectReferenceRedirect.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-disableSourceOfProjectReferenceRedirect.js
new file mode 100644
index 0000000000..cb7e26f6d8
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-disableSourceOfProjectReferenceRedirect.js
@@ -0,0 +1,460 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "disableSourceOfProjectReferenceRedirect": true
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ [/user/username/projects/random/tsconfig.json] *new*
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/random/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts]
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json *new*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *closed*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *deleted*
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/main/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *deleted*
+ [/user/username/projects/random/random.ts]
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-project-references.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-project-references.js
new file mode 100644
index 0000000000..96e86999c6
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-project-references.js
@@ -0,0 +1,462 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+ "references": [
+ { "path": "../dependency" }
+ ]
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ [/user/username/projects/random/tsconfig.json] *new*
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/random/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts]
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json
+ /user/username/projects/myproject/main/tsconfig.json *new*
+ /user/username/projects/myproject/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+
+// === /user/username/projects/myproject/main/main.ts ===
+// import {
+// fn1,
+// fn2,
+// [|fn3RENAME|],
+// fn4,
+// fn5
+// } from "../decls/FnS";
+//
+// fn1();
+// fn2();
+// [|fn3RENAME|]();
+// fn4();
+// fn5();
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/main/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *closed*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/main/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *deleted*
+ [/user/username/projects/random/random.ts]
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-source-maps.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-source-maps.js
new file mode 100644
index 0000000000..1332836528
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename-with-source-maps.js
@@ -0,0 +1,434 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/decls/FnS.d.ts] *new*
+export declare function fn1(): void;
+export declare function fn2(): void;
+export declare function fn3(): void;
+export declare function fn4(): void;
+export declare function fn5(): void;
+//# sourceMappingURL=FnS.d.ts.map
+//// [/user/username/projects/myproject/decls/FnS.d.ts.map] *new*
+{"version":3,"file":"FnS.d.ts","sourceRoot":"","sources":["../dependency/FnS.ts"],"names":[],"mappings":"AAAA,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM;AACzB,wBAAgB,GAAG,SAAM"}
+//// [/user/username/projects/myproject/dependency/FnS.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fn1 = fn1;
+exports.fn2 = fn2;
+exports.fn3 = fn3;
+exports.fn4 = fn4;
+exports.fn5 = fn5;
+function fn1() { }
+function fn2() { }
+function fn3() { }
+function fn4() { }
+function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/FnS.ts] *new*
+export function fn1() { }
+export function fn2() { }
+export function fn3() { }
+export function fn4() { }
+export function fn5() { }
+
+//// [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "declarationDir": "../decls"
+ }
+}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[2],"fileNames":["lib.d.ts","./FnS.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n","signature":"bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n","impliedNodeFormat":1}],"options":{"composite":true,"declarationDir":"../decls","declarationMap":true},"latestChangedDtsFile":"../decls/FnS.d.ts"}
+//// [/user/username/projects/myproject/dependency/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./FnS.ts"
+ ],
+ "original": 2
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./FnS.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./FnS.ts",
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "dabc23167a661a3e71744cf63ff5adcc-export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n",
+ "signature": "bf56b5172c2fd500384b437b7700d594-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "options": {
+ "composite": true,
+ "declarationDir": "../decls",
+ "declarationMap": true
+ },
+ "latestChangedDtsFile": "../decls/FnS.d.ts",
+ "size": 1423
+}
+//// [/user/username/projects/myproject/main/main.d.ts] *new*
+export {};
+//# sourceMappingURL=main.d.ts.map
+//// [/user/username/projects/myproject/main/main.d.ts.map] *new*
+{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/myproject/main/main.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const FnS_1 = require("../decls/FnS");
+(0, FnS_1.fn1)();
+(0, FnS_1.fn2)();
+(0, FnS_1.fn3)();
+(0, FnS_1.fn4)();
+(0, FnS_1.fn5)();
+
+//// [/user/username/projects/myproject/main/main.ts] *new*
+import {
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ fn5
+} from "../decls/FnS";
+
+fn1();
+fn2();
+fn3();
+fn4();
+fn5();
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ },
+}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[3],"fileNames":["lib.d.ts","../decls/FnS.d.ts","./main.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",{"version":"4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true},"referencedMap":[[3,1]],"latestChangedDtsFile":"./main.d.ts"}
+//// [/user/username/projects/myproject/main/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./main.ts"
+ ],
+ "original": 3
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../decls/FnS.d.ts",
+ "./main.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../decls/FnS.d.ts",
+ "version": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "signature": "ccbe7f3de9ff1ded77b994bef4cf9dce-export declare function fn1(): void;\nexport declare function fn2(): void;\nexport declare function fn3(): void;\nexport declare function fn4(): void;\nexport declare function fn5(): void;\n//# sourceMappingURL=FnS.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "./main.ts",
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "4fd5832b607095e96718cc3f14637677-import {\n fn1,\n fn2,\n fn3,\n fn4,\n fn5\n} from \"../decls/FnS\";\n\nfn1();\nfn2();\nfn3();\nfn4();\nfn5();",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../decls/FnS.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true
+ },
+ "referencedMap": {
+ "./main.ts": [
+ "../decls/FnS.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./main.d.ts",
+ "size": 1525
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "references": [
+ { "path": "main" }
+ ]
+}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":["./dependency/FnS.ts","./main/main.ts"]}
+//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./dependency/FnS.ts"
+ ],
+ "original": "./dependency/FnS.ts"
+ },
+ {
+ "files": [
+ "./main/main.ts"
+ ],
+ "original": "./main/main.ts"
+ }
+ ],
+ "size": 75
+}
+//// [/user/username/projects/random/random.ts] *new*
+export const a = 10;
+//// [/user/username/projects/random/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function fn1() { }\nexport function fn2() { }\nexport function fn3() { }\nexport function fn4() { }\nexport function fn5() { }\n"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *new*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ [/user/username/projects/random/tsconfig.json] *new*
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/random/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts]
+ NearestConfigFileName: /user/username/projects/myproject/dependency/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/dependency/tsconfig.json /user/username/projects/myproject/tsconfig.json
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 16
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *modified*
+ /user/username/projects/myproject/decls/FnS.d.ts *new*
+ /user/username/projects/myproject/dependency/FnS.ts *new*
+ /user/username/projects/myproject/main/main.ts *new*
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *modified*
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json *new*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/dependency/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/dependency/fns.ts
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+// === /user/username/projects/myproject/dependency/FnS.ts ===
+// export function fn1() { }
+// export function fn2() { }
+// export function /*RENAME*/[|fn3RENAME|]() { }
+// export function fn4() { }
+// export function fn5() { }
+//
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts]
+ /user/username/projects/myproject/dependency/tsconfig.json (default)
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/dependency/FnS.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/dependency/FnS.ts] *closed*
+ [/user/username/projects/random/random.ts]
+ /user/username/projects/random/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/random/random.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/random/random.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ /user/username/projects/myproject/dependency/FnS.ts
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ /user/username/projects/myproject/decls/FnS.d.ts
+ /user/username/projects/myproject/dependency/FnS.ts
+ /user/username/projects/myproject/main/main.ts
+ [/user/username/projects/random/tsconfig.json]
+ /user/username/projects/random/random.ts
+Open Files::
+ [/user/username/projects/random/random.ts] *new*
+ /user/username/projects/random/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/dependency/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/main/tsconfig.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/projects/random/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/random/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/random/random.ts
+Config File Names::
+ [/user/username/projects/myproject/dependency/fns.ts] *deleted*
+ [/user/username/projects/random/random.ts]
+ NearestConfigFileName: /user/username/projects/random/tsconfig.json
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/rename.js b/testdata/baselines/reference/lspservertests/declarationMaps/rename.js
new file mode 100644
index 0000000000..fd9dab1e69
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/rename.js
@@ -0,0 +1,156 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function fnA() {}
+export interface IfaceA {}
+export const instanceA: IfaceA = {};
+//// [/home/src/projects/project/a/bin/a.d.ts] *new*
+export declare function fnA(): void;
+export interface IfaceA {
+}
+export declare const instanceA: IfaceA;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/a/bin/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/bin/b.d.ts] *new*
+export declare function fnB(): void;
+//# sourceMappingURL=b.d.ts.map
+//// [/home/src/projects/project/b/bin/b.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+}
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/dummy/dummy.ts] *new*
+export const a = 10;
+//// [/home/src/projects/project/dummy/tsconfig.json] *new*
+{}
+//// [/home/src/projects/project/user/user.ts] *new*
+import * as a from "../a/bin/a";
+import * as b from "../b/bin/b";
+export function fnUser() { a.fnA(); b.fnB(); a.instanceA; }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as a from \"../a/bin/a\";\nimport * as b from \"../b/bin/b\";\nexport function fnUser() { a.fnA(); b.fnB(); a.instanceA; }"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/user/user.ts] *new*
+ /dev/null/inferred (default)
+Config File Names::
+ [/home/src/projects/project/user/user.ts] *new*
+ NearestConfigFileName:
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 29
+ },
+ "newName": "?"
+ }
+}
+Projects::
+ [/dev/null/inferred]
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/a/tsconfig.json
+// === /home/src/projects/project/a/a.ts ===
+// export function [|fnARENAME|]() {}
+// export interface IfaceA {}
+// export const instanceA: IfaceA = {};
+
+// === /home/src/projects/project/user/user.ts ===
+// import * as a from "../a/bin/a";
+// import * as b from "../b/bin/b";
+// export function fnUser() { a./*RENAME*/[|fnARENAME|](); b.fnB(); a.instanceA; }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ }
+ }
+}
+Open Files::
+ [/home/src/projects/project/user/user.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /home/src/projects/project/a/bin/a.d.ts
+ /home/src/projects/project/b/bin/b.d.ts
+ /home/src/projects/project/user/user.ts
+ [/home/src/projects/project/a/tsconfig.json] *deleted*
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ /home/src/projects/project/dummy/dummy.ts
+Open Files::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ /home/src/projects/project/dummy/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *deleted*
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/dummy/dummy.ts
+Config File Names::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/dummy/tsconfig.json
+ [/home/src/projects/project/user/user.ts] *deleted*
diff --git a/testdata/baselines/reference/lspservertests/declarationMaps/workspace-symbols.js b/testdata/baselines/reference/lspservertests/declarationMaps/workspace-symbols.js
new file mode 100644
index 0000000000..7fdade5630
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/declarationMaps/workspace-symbols.js
@@ -0,0 +1,201 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/a/a.ts] *new*
+export function fnA() {}
+export interface IfaceA {}
+export const instanceA: IfaceA = {};
+//// [/home/src/projects/project/a/bin/a.d.ts] *new*
+export declare function fnA(): void;
+export interface IfaceA {
+}
+export declare const instanceA: IfaceA;
+//# sourceMappingURL=a.d.ts.map
+//// [/home/src/projects/project/a/bin/a.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "a.d.ts",
+ "sourceRoot": "",
+ "sources": ["../a.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK;AACxB,MAAM,WAAW,MAAM;CAAG;AAC1B,eAAO,MAAM,SAAS,EAAE,MAAW,CAAC"
+}
+//// [/home/src/projects/project/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/b/b.ts] *new*
+export function fnB() {}
+//// [/home/src/projects/project/b/bin/b.d.ts] *new*
+export declare function fnB(): void;
+//# sourceMappingURL=b.d.ts.map
+//// [/home/src/projects/project/b/bin/b.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "b.d.ts",
+ "sourceRoot": "",
+ "sources": ["../b.ts"],
+ "names": [],
+ "mappings": "AAAA,wBAAgB,GAAG,SAAK"
+}
+//// [/home/src/projects/project/b/c.ts] *new*
+export function fnC() {}
+//// [/home/src/projects/project/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "outDir": "bin",
+ "declarationMap": true,
+ "composite": true
+ }
+}
+//// [/home/src/projects/project/dummy/dummy.ts] *new*
+export const a = 10;
+//// [/home/src/projects/project/dummy/tsconfig.json] *new*
+{}
+//// [/home/src/projects/project/user/tsconfig.json] *new*
+{
+ "references": [{ "path": "../a" }, { "path": "../b" }]
+}
+//// [/home/src/projects/project/user/user.ts] *new*
+import * as a from "../a/a";
+import * as b from "../b/b";
+export function fnUser() {
+ a.fnA();
+ b.fnB();
+ a.instanceA;
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as a from \"../a/a\";\nimport * as b from \"../b/b\";\nexport function fnUser() {\n a.fnA();\n b.fnB();\n a.instanceA;\n}"
+ }
+ }
+}
+Projects::
+ [/home/src/projects/project/user/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+ /home/src/projects/project/b/b.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/user/user.ts] *new*
+ /home/src/projects/project/user/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/user/tsconfig.json
+ [/home/src/projects/project/b/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/user/tsconfig.json
+ [/home/src/projects/project/user/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/user/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/user/user.ts
+Config File Names::
+ [/home/src/projects/project/user/user.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/user/tsconfig.json
+{
+ "method": "workspace/symbol",
+ "params": {
+ "query": "fn"
+ }
+}
+Projects::
+ [/home/src/projects/project/a/tsconfig.json] *new*
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/b/tsconfig.json] *new*
+ /home/src/projects/project/b/b.ts
+ /home/src/projects/project/b/c.ts
+ [/home/src/projects/project/user/tsconfig.json]
+ /home/src/projects/project/a/a.ts
+ /home/src/projects/project/b/b.ts
+ /home/src/projects/project/user/user.ts
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /home/src/projects/project/a/tsconfig.json *new*
+ /home/src/projects/project/user/tsconfig.json
+ [/home/src/projects/project/b/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /home/src/projects/project/b/tsconfig.json *new*
+ /home/src/projects/project/user/tsconfig.json
+ [/home/src/projects/project/user/tsconfig.json]
+ RetainingProjects:
+ /home/src/projects/project/user/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/user/user.ts
+// === /home/src/projects/project/a/a.ts ===
+// export function [|{| name: fnA, kind: function |}fnA|]() {}
+// export interface IfaceA {}
+// export const instanceA: IfaceA = {};
+
+// === /home/src/projects/project/b/b.ts ===
+// export function [|{| name: fnB, kind: function |}fnB|]() {}
+
+// === /home/src/projects/project/b/c.ts ===
+// export function [|{| name: fnC, kind: function |}fnC|]() {}
+
+// === /home/src/projects/project/user/user.ts ===
+// import * as a from "../a/a";
+// import * as b from "../b/b";
+// export function [|{| name: fnUser, kind: function |}fnUser|]() {
+// a.fnA();
+// b.fnB();
+// a.instanceA;
+// }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/user/user.ts"
+ }
+ }
+}
+Open Files::
+ [/home/src/projects/project/user/user.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const a = 10;"
+ }
+ }
+}
+Projects::
+ [/home/src/projects/project/a/tsconfig.json] *deleted*
+ /home/src/projects/project/a/a.ts
+ [/home/src/projects/project/b/tsconfig.json] *deleted*
+ /home/src/projects/project/b/b.ts
+ /home/src/projects/project/b/c.ts
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ /home/src/projects/project/dummy/dummy.ts
+ [/home/src/projects/project/user/tsconfig.json] *deleted*
+ /home/src/projects/project/a/a.ts
+ /home/src/projects/project/b/b.ts
+ /home/src/projects/project/user/user.ts
+Open Files::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ /home/src/projects/project/dummy/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/a/tsconfig.json] *deleted*
+ [/home/src/projects/project/b/tsconfig.json] *deleted*
+ [/home/src/projects/project/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/dummy/dummy.ts
+ [/home/src/projects/project/user/tsconfig.json] *deleted*
+Config File Names::
+ [/home/src/projects/project/dummy/dummy.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/dummy/tsconfig.json
+ [/home/src/projects/project/user/user.ts] *deleted*
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/disableSolutionSearching-solution-and-siblings-are-not-loaded.js b/testdata/baselines/reference/lspservertests/findAllRefs/disableSolutionSearching-solution-and-siblings-are-not-loaded.js
new file mode 100644
index 0000000000..303d6fda04
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/disableSolutionSearching-solution-and-siblings-are-not-loaded.js
@@ -0,0 +1,104 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/compiler/program.ts] *new*
+namespace ts {
+ export const program: Program = {
+ getSourceFiles: () => [getSourceFile()]
+ };
+ function getSourceFile() { return "something"; }
+}
+//// [/user/username/projects/solution/compiler/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "disableSolutionSearching": true,
+ },
+ "files": ["./types.ts", "./program.ts"]
+}
+//// [/user/username/projects/solution/compiler/types.ts] *new*
+namespace ts {
+ export interface Program {
+ getSourceFiles(): string[];
+ }
+}
+//// [/user/username/projects/solution/services/services.ts] *new*
+///
+///
+namespace ts {
+ const result = program.getSourceFiles();
+}
+//// [/user/username/projects/solution/services/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./services.ts"],
+ "references": [
+ { "path": "../compiler" },
+ ],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "include": [],
+ "references": [
+ { "path": "./compiler" },
+ { "path": "./services" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/compiler/program.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "namespace ts {\n export const program: Program = {\n getSourceFiles: () => [getSourceFile()]\n };\n function getSourceFile() { return \"something\"; }\n}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/compiler/tsconfig.json] *new*
+ /user/username/projects/solution/compiler/types.ts
+ /user/username/projects/solution/compiler/program.ts
+Open Files::
+ [/user/username/projects/solution/compiler/program.ts] *new*
+ /user/username/projects/solution/compiler/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/compiler/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/compiler/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/compiler/program.ts
+Config File Names::
+ [/user/username/projects/solution/compiler/program.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/compiler/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/compiler/program.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 8
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/solution/compiler/program.ts ===
+// namespace ts {
+// export const program: Program = {
+// /*FIND ALL REFS*/[|getSourceFiles|]: () => [getSourceFile()]
+// };
+// function getSourceFile() { return "something"; }
+// }
+
+// === /user/username/projects/solution/compiler/types.ts ===
+// namespace ts {
+// export interface Program {
+// [|getSourceFiles|](): string[];
+// }
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/does-not-try-to-open-a-file-in-a-project-that-was-updated-and-no-longer-has-the-file.js b/testdata/baselines/reference/lspservertests/findAllRefs/does-not-try-to-open-a-file-in-a-project-that-was-updated-and-no-longer-has-the-file.js
new file mode 100644
index 0000000000..f1133be84e
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/does-not-try-to-open-a-file-in-a-project-that-was-updated-and-no-longer-has-the-file.js
@@ -0,0 +1,190 @@
+UseCaseSensitiveFileNames: false
+//// [/home/src/projects/project/packages/babel-loader/src/index.ts] *new*
+import type { Foo } from "../../core/src/index.js";
+//// [/home/src/projects/project/packages/babel-loader/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "target": "ES2018",
+ "module": "commonjs",
+ "strict": true,
+ "esModuleInterop": true,
+ "composite": true,
+ "rootDir": "src",
+ "outDir": "dist"
+ },
+ "include": ["src"],
+ "references": [{"path": "../core"}]
+}
+//// [/home/src/projects/project/packages/core/src/index.ts] *new*
+import { Bar } from "./loading-indicator.js";
+export type Foo = {};
+const bar: Bar = {
+ prop: 0
+}
+//// [/home/src/projects/project/packages/core/src/loading-indicator.ts] *new*
+export interface Bar {
+ prop: number;
+}
+const bar: Bar = {
+ prop: 1
+}
+//// [/home/src/projects/project/packages/core/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "target": "ES2018",
+ "module": "commonjs",
+ "strict": true,
+ "esModuleInterop": true,
+ "composite": true,
+ "rootDir": "./src",
+ "outDir": "./dist",
+ },
+ "include": ["./src"]
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/packages/babel-loader/src/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import type { Foo } from \"../../core/src/index.js\";"
+ }
+ }
+}
+Projects::
+ [/home/src/projects/project/packages/babel-loader/tsconfig.json] *new*
+ /home/src/projects/project/packages/core/src/loading-indicator.ts
+ /home/src/projects/project/packages/core/src/index.ts
+ /home/src/projects/project/packages/babel-loader/src/index.ts
+Open Files::
+ [/home/src/projects/project/packages/babel-loader/src/index.ts] *new*
+ /home/src/projects/project/packages/babel-loader/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/packages/babel-loader/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/packages/babel-loader/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/packages/babel-loader/src/index.ts
+ [/home/src/projects/project/packages/core/tsconfig.json] *new*
+ RetainingProjects:
+ /home/src/projects/project/packages/babel-loader/tsconfig.json
+Config File Names::
+ [/home/src/projects/project/packages/babel-loader/src/index.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/packages/babel-loader/tsconfig.json
+ Ancestors:
+ /home/src/projects/project/packages/babel-loader/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/packages/core/src/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { Bar } from \"./loading-indicator.js\";\nexport type Foo = {};\nconst bar: Bar = {\n prop: 0\n}"
+ }
+ }
+}
+Projects::
+ [/home/src/projects/project/packages/babel-loader/tsconfig.json]
+ /home/src/projects/project/packages/core/src/loading-indicator.ts
+ /home/src/projects/project/packages/core/src/index.ts
+ /home/src/projects/project/packages/babel-loader/src/index.ts
+ [/home/src/projects/project/packages/core/tsconfig.json] *new*
+ /home/src/projects/project/packages/core/src/loading-indicator.ts
+ /home/src/projects/project/packages/core/src/index.ts
+Open Files::
+ [/home/src/projects/project/packages/babel-loader/src/index.ts]
+ /home/src/projects/project/packages/babel-loader/tsconfig.json (default)
+ [/home/src/projects/project/packages/core/src/index.ts] *new*
+ /home/src/projects/project/packages/babel-loader/tsconfig.json
+ /home/src/projects/project/packages/core/tsconfig.json (default)
+Config::
+ [/home/src/projects/project/packages/babel-loader/tsconfig.json]
+ RetainingProjects:
+ /home/src/projects/project/packages/babel-loader/tsconfig.json
+ RetainingOpenFiles:
+ /home/src/projects/project/packages/babel-loader/src/index.ts
+ [/home/src/projects/project/packages/core/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /home/src/projects/project/packages/babel-loader/tsconfig.json
+ /home/src/projects/project/packages/core/tsconfig.json *new*
+ RetainingOpenFiles: *modified*
+ /home/src/projects/project/packages/core/src/index.ts *new*
+Config File Names::
+ [/home/src/projects/project/packages/babel-loader/src/index.ts]
+ NearestConfigFileName: /home/src/projects/project/packages/babel-loader/tsconfig.json
+ Ancestors:
+ /home/src/projects/project/packages/babel-loader/tsconfig.json
+ [/home/src/projects/project/packages/core/src/index.ts] *new*
+ NearestConfigFileName: /home/src/projects/project/packages/core/tsconfig.json
+ Ancestors:
+ /home/src/projects/project/packages/core/tsconfig.json
+{
+ "method": "textDocument/didChange",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/packages/babel-loader/src/index.ts",
+ "version": 2
+ },
+ "contentChanges": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 0
+ },
+ "end": {
+ "line": 0,
+ "character": 0
+ }
+ },
+ "text": "// comment"
+ }
+ ]
+ }
+}
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///home/src/projects/project/packages/core/src/index.ts"
+ },
+ "position": {
+ "line": 3,
+ "character": 4
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/home/src/projects/project/packages/babel-loader/tsconfig.json] *modified*
+ /home/src/projects/project/packages/babel-loader/src/index.ts *modified*
+ /home/src/projects/project/packages/core/src/loading-indicator.ts *deleted*
+ /home/src/projects/project/packages/core/src/index.ts *deleted*
+ [/home/src/projects/project/packages/core/tsconfig.json]
+ /home/src/projects/project/packages/core/src/loading-indicator.ts
+ /home/src/projects/project/packages/core/src/index.ts
+Open Files::
+ [/home/src/projects/project/packages/babel-loader/src/index.ts]
+ /home/src/projects/project/packages/babel-loader/tsconfig.json (default)
+ [/home/src/projects/project/packages/core/src/index.ts] *modified*
+ /home/src/projects/project/packages/babel-loader/tsconfig.json *deleted*
+ /home/src/projects/project/packages/core/tsconfig.json (default)
+// === /home/src/projects/project/packages/core/src/index.ts ===
+// import { Bar } from "./loading-indicator.js";
+// export type Foo = {};
+// const bar: Bar = {
+// /*FIND ALL REFS*/[|prop|]: 0
+// }
+
+// === /home/src/projects/project/packages/core/src/loading-indicator.ts ===
+// export interface Bar {
+// [|prop|]: number;
+// }
+// const bar: Bar = {
+// [|prop|]: 1
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/files-from-two-projects-are-open-and-one-project-references.js b/testdata/baselines/reference/lspservertests/findAllRefs/files-from-two-projects-are-open-and-one-project-references.js
new file mode 100644
index 0000000000..d5b5c6288c
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/files-from-two-projects-are-open-and-one-project-references.js
@@ -0,0 +1,208 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/core/src/file1.ts] *new*
+export const coreConst = 10;
+//// [/user/username/projects/myproject/core/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+
+}
+//// [/user/username/projects/myproject/coreRef1/src/file1.ts] *new*
+export const coreRef1Const = 10;
+//// [/user/username/projects/myproject/coreRef1/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ { "path": "../core" },\n
+}
+//// [/user/username/projects/myproject/coreRef2/src/file1.ts] *new*
+export const coreRef2Const = 10;
+//// [/user/username/projects/myproject/coreRef2/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ { "path": "../core" },\n
+}
+//// [/user/username/projects/myproject/coreRef3/src/file1.ts] *new*
+export const coreRef3Const = 10;
+//// [/user/username/projects/myproject/coreRef3/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ { "path": "../core" },\n
+}
+//// [/user/username/projects/myproject/indirect/src/file1.ts] *new*
+export const indirectConst = 10;
+//// [/user/username/projects/myproject/indirect/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ { "path": "../coreRef1" },\n
+}
+//// [/user/username/projects/myproject/indirectDisabledChildLoad1/src/file1.ts] *new*
+export const indirectDisabledChildLoad1Const = 10;
+//// [/user/username/projects/myproject/indirectDisabledChildLoad1/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "disableReferencedProjectLoad": true,
+ },
+ { "path": "../coreRef2" },\n
+}
+//// [/user/username/projects/myproject/indirectDisabledChildLoad2/src/file1.ts] *new*
+export const indirectDisabledChildLoad2Const = 10;
+//// [/user/username/projects/myproject/indirectDisabledChildLoad2/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "disableReferencedProjectLoad": true,
+ },
+ { "path": "../coreRef3" },\n
+}
+//// [/user/username/projects/myproject/indirectNoCoreRef/src/file1.ts] *new*
+export const indirectNoCoreRefConst = 10;
+//// [/user/username/projects/myproject/indirectNoCoreRef/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ { "path": "../noCoreRef2" },\n
+}
+//// [/user/username/projects/myproject/main/src/file1.ts] *new*
+export const mainConst = 10;
+//// [/user/username/projects/myproject/main/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ { "path": "../core" },\n{ "path": "../indirect" },\n{ "path": "../noCoreRef1" },\n{ "path": "../indirectDisabledChildLoad1" },\n{ "path": "../indirectDisabledChildLoad2" },\n{ "path": "../refToCoreRef3" },\n{ "path": "../indirectNoCoreRef" },\n
+}
+//// [/user/username/projects/myproject/noCoreRef1/src/file1.ts] *new*
+export const noCoreRef1Const = 10;
+//// [/user/username/projects/myproject/noCoreRef1/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+
+}
+//// [/user/username/projects/myproject/noCoreRef2/src/file1.ts] *new*
+export const noCoreRef2Const = 10;
+//// [/user/username/projects/myproject/noCoreRef2/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+
+}
+//// [/user/username/projects/myproject/refToCoreRef3/src/file1.ts] *new*
+export const refToCoreRef3Const = 10;
+//// [/user/username/projects/myproject/refToCoreRef3/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ { "path": "../coreRef3" },\n
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/main/src/file1.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const mainConst = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ /user/username/projects/myproject/main/src/file1.ts
+Open Files::
+ [/user/username/projects/myproject/main/src/file1.ts] *new*
+ /user/username/projects/myproject/main/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/main/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/main/src/file1.ts
+Config File Names::
+ [/user/username/projects/myproject/main/src/file1.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/main/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/main/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/core/src/file1.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const coreConst = 10;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/core/tsconfig.json] *new*
+ /user/username/projects/myproject/core/src/file1.ts
+ [/user/username/projects/myproject/main/tsconfig.json]
+ /user/username/projects/myproject/main/src/file1.ts
+Open Files::
+ [/user/username/projects/myproject/core/src/file1.ts] *new*
+ /user/username/projects/myproject/core/tsconfig.json (default)
+ [/user/username/projects/myproject/main/src/file1.ts]
+ /user/username/projects/myproject/main/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/core/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/core/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/core/src/file1.ts
+ [/user/username/projects/myproject/main/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/main/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/main/src/file1.ts
+Config File Names::
+ [/user/username/projects/myproject/core/src/file1.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/core/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/core/tsconfig.json
+ [/user/username/projects/myproject/main/src/file1.ts]
+ NearestConfigFileName: /user/username/projects/myproject/main/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/main/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/core/src/file1.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 13
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/core/src/file1.ts ===
+// export const /*FIND ALL REFS*/[|coreConst|] = 10;
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..23fab7ff03
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,120 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..42f5ae2ecc
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
@@ -0,0 +1,132 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..fe4b23b629
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,120 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..6bff937a92
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
@@ -0,0 +1,132 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..afdf6120ef
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,120 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..9e652c4c22
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
@@ -0,0 +1,132 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..04036d9b81
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,120 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..c23df53b2c
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
@@ -0,0 +1,132 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/b/helper.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \".\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts]
+ /user/username/projects/myproject/a/tsconfig.json (default)
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ /user/username/projects/myproject/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/b/helper.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts]
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+ [/user/username/projects/myproject/b/helper.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/b/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..7eed8d4d0b
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,80 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..cd10ec66b9
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
@@ -0,0 +1,109 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..dcdad55258
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,80 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..d355d35f03
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-disabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
@@ -0,0 +1,109 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": true,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..d097d320aa
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,80 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..7e57426296
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-disabled-and-a-decl-map-is-present.js
@@ -0,0 +1,109 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": true,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
new file mode 100644
index 0000000000..168deac1f5
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-missing.js
@@ -0,0 +1,80 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/lib/index.d.ts ===
+// export declare class [|B|] {
+// M(): void;
+// }
+// //# sourceMappingURL=index.d.ts.map
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
new file mode 100644
index 0000000000..63a7712517
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/find-refs-to-decl-in-other-proj-when-proj-is-not-loaded-and-refd-proj-loading-is-enabled-and-proj-ref-redirects-are-enabled-and-a-decl-map-is-present.js
@@ -0,0 +1,109 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/a/index.ts] *new*
+import { B } from "../b/lib";
+const b: B = new B();
+//// [/user/username/projects/myproject/a/tsconfig.json] *new*
+{
+ "disableReferencedProjectLoad": false,
+ "disableSourceOfProjectReferenceRedirect": false,
+ "composite": true
+}
+//// [/user/username/projects/myproject/b/helper.ts] *new*
+import { B } from ".";
+const b: B = new B();
+//// [/user/username/projects/myproject/b/index.ts] *new*
+export class B {
+ M() {}
+}
+//// [/user/username/projects/myproject/b/lib/index.d.ts] *new*
+export declare class B {
+ M(): void;
+}
+//# sourceMappingURL=index.d.ts.map
+//// [/user/username/projects/myproject/b/lib/index.d.ts.map] *new*
+{
+ "version": 3,
+ "file": "index.d.ts",
+ "sourceRoot": "",
+ "sources": ["../index.ts"],
+ "names": [],
+ "mappings": "AAAA,qBAAa,CAAC;IACV,CAAC;CACJ"
+}
+//// [/user/username/projects/myproject/b/tsconfig.json] *new*
+{
+ "declarationMap": true,
+ "outDir": "lib",
+ "composite": true,
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { B } from \"../b/lib\";\nconst b: B = new B();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+Open Files::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ /user/username/projects/myproject/a/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+Config File Names::
+ [/user/username/projects/myproject/a/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/a/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/a/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ /user/username/projects/myproject/b/lib/index.d.ts
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ /user/username/projects/myproject/b/index.ts
+ /user/username/projects/myproject/b/helper.ts
+ /user/username/projects/myproject/b/lib/index.d.ts
+Config::
+ [/user/username/projects/myproject/a/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/a/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/a/index.ts
+ [/user/username/projects/myproject/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/b/tsconfig.json
+// === /user/username/projects/myproject/a/index.ts ===
+// import { [|B|] } from "../b/lib";
+// const b: /*FIND ALL REFS*/[|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/helper.ts ===
+// import { [|B|] } from ".";
+// const b: [|B|] = new [|B|]();
+
+// === /user/username/projects/myproject/b/index.ts ===
+// export class [|B|] {
+// M() {}
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/finding-local-reference-doesnt-load-ancestor-sibling-projects.js b/testdata/baselines/reference/lspservertests/findAllRefs/finding-local-reference-doesnt-load-ancestor-sibling-projects.js
new file mode 100644
index 0000000000..ce79ec4da8
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/finding-local-reference-doesnt-load-ancestor-sibling-projects.js
@@ -0,0 +1,165 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/compiler/program.ts] *new*
+namespace ts {
+ export const program: Program = {
+ getSourceFiles: () => [getSourceFile()]
+ };
+ function getSourceFile() { return "something"; }
+}
+//// [/user/username/projects/solution/compiler/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+
+ },
+ "files": ["./types.ts", "./program.ts"]
+}
+//// [/user/username/projects/solution/compiler/types.ts] *new*
+namespace ts {
+ export interface Program {
+ getSourceFiles(): string[];
+ }
+}
+//// [/user/username/projects/solution/services/services.ts] *new*
+///
+///
+namespace ts {
+ const result = program.getSourceFiles();
+}
+//// [/user/username/projects/solution/services/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./services.ts"],
+ "references": [
+ { "path": "../compiler" },
+ ],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "include": [],
+ "references": [
+ { "path": "./compiler" },
+ { "path": "./services" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/compiler/program.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "namespace ts {\n export const program: Program = {\n getSourceFiles: () => [getSourceFile()]\n };\n function getSourceFile() { return \"something\"; }\n}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/compiler/tsconfig.json] *new*
+ /user/username/projects/solution/compiler/types.ts
+ /user/username/projects/solution/compiler/program.ts
+ [/user/username/projects/solution/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/solution/compiler/program.ts] *new*
+ /user/username/projects/solution/compiler/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/compiler/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/compiler/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/compiler/program.ts
+Config File Names::
+ [/user/username/projects/solution/compiler/program.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/compiler/tsconfig.json
+ Ancestors:
+ /user/username/projects/solution/compiler/tsconfig.json /user/username/projects/solution/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/compiler/program.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 31
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/solution/compiler/program.ts ===
+// namespace ts {
+// export const program: Program = {
+// getSourceFiles: () => [/*FIND ALL REFS*/[|getSourceFile|]()]
+// };
+// function [|getSourceFile|]() { return "something"; }
+// }
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/compiler/program.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 8
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/compiler/tsconfig.json]
+ /user/username/projects/solution/compiler/types.ts
+ /user/username/projects/solution/compiler/program.ts
+ [/user/username/projects/solution/services/tsconfig.json] *new*
+ /user/username/projects/solution/compiler/types.ts
+ /user/username/projects/solution/compiler/program.ts
+ /user/username/projects/solution/services/services.ts
+ [/user/username/projects/solution/tsconfig.json] *modified*
+Open Files::
+ [/user/username/projects/solution/compiler/program.ts] *modified*
+ /user/username/projects/solution/compiler/tsconfig.json (default)
+ /user/username/projects/solution/services/tsconfig.json *new*
+Config::
+ [/user/username/projects/solution/compiler/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/compiler/tsconfig.json
+ /user/username/projects/solution/services/tsconfig.json *new*
+ /user/username/projects/solution/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/solution/compiler/program.ts
+ [/user/username/projects/solution/services/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/services/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+ [/user/username/projects/solution/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/tsconfig.json
+// === /user/username/projects/solution/compiler/program.ts ===
+// namespace ts {
+// export const program: Program = {
+// /*FIND ALL REFS*/[|getSourceFiles|]: () => [getSourceFile()]
+// };
+// function getSourceFile() { return "something"; }
+// }
+
+// === /user/username/projects/solution/compiler/types.ts ===
+// namespace ts {
+// export interface Program {
+// [|getSourceFiles|](): string[];
+// }
+// }
+
+// === /user/username/projects/solution/services/services.ts ===
+// ///
+// ///
+// namespace ts {
+// const result = program.[|getSourceFiles|]();
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/finding-references-in-overlapping-projects.js b/testdata/baselines/reference/lspservertests/findAllRefs/finding-references-in-overlapping-projects.js
new file mode 100644
index 0000000000..98d7ad840a
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/finding-references-in-overlapping-projects.js
@@ -0,0 +1,220 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/a/index.ts] *new*
+export interface I {
+ M(): void;
+}
+//// [/user/username/projects/solution/a/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ },
+ "files": ["./index.ts"]
+}
+//// [/user/username/projects/solution/b/index.ts] *new*
+import { I } from "../a";
+export class B implements I {
+ M() {}
+}
+//// [/user/username/projects/solution/b/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../a" },
+ ],
+}
+//// [/user/username/projects/solution/c/index.ts] *new*
+import { I } from "../a";
+import { B } from "../b";
+export const C: I = new B();
+//// [/user/username/projects/solution/c/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../b" },
+ ],
+}
+//// [/user/username/projects/solution/d/index.ts] *new*
+import { I } from "../a";
+import { C } from "../c";
+export const D: I = C;
+//// [/user/username/projects/solution/d/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../c" },
+ ],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "include": [],
+ "references": [
+ { "path": "./a" },
+ { "path": "./b" },
+ { "path": "./c" },
+ { "path": "./d" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/b/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { I } from \"../a\";\nexport class B implements I {\n M() {}\n}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/b/tsconfig.json] *new*
+ /user/username/projects/solution/a/index.ts
+ /user/username/projects/solution/b/index.ts
+ [/user/username/projects/solution/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/solution/b/index.ts] *new*
+ /user/username/projects/solution/b/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/a/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/b/tsconfig.json
+ [/user/username/projects/solution/b/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/b/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/b/index.ts
+Config File Names::
+ [/user/username/projects/solution/b/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/b/tsconfig.json
+ Ancestors:
+ /user/username/projects/solution/b/tsconfig.json /user/username/projects/solution/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/b/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 26
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/a/tsconfig.json] *new*
+ /user/username/projects/solution/a/index.ts
+ [/user/username/projects/solution/b/tsconfig.json]
+ /user/username/projects/solution/a/index.ts
+ /user/username/projects/solution/b/index.ts
+ [/user/username/projects/solution/c/tsconfig.json] *new*
+ /user/username/projects/solution/a/index.ts
+ /user/username/projects/solution/b/index.ts
+ /user/username/projects/solution/c/index.ts
+ [/user/username/projects/solution/d/tsconfig.json] *new*
+ /user/username/projects/solution/a/index.ts
+ /user/username/projects/solution/b/index.ts
+ /user/username/projects/solution/c/index.ts
+ /user/username/projects/solution/d/index.ts
+ [/user/username/projects/solution/tsconfig.json] *modified*
+Open Files::
+ [/user/username/projects/solution/b/index.ts] *modified*
+ /user/username/projects/solution/b/tsconfig.json (default)
+ /user/username/projects/solution/c/tsconfig.json *new*
+ /user/username/projects/solution/d/tsconfig.json *new*
+Config::
+ [/user/username/projects/solution/a/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/a/tsconfig.json *new*
+ /user/username/projects/solution/b/tsconfig.json
+ /user/username/projects/solution/c/tsconfig.json *new*
+ /user/username/projects/solution/d/tsconfig.json *new*
+ /user/username/projects/solution/tsconfig.json *new*
+ [/user/username/projects/solution/b/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/b/tsconfig.json
+ /user/username/projects/solution/c/tsconfig.json *new*
+ /user/username/projects/solution/d/tsconfig.json *new*
+ /user/username/projects/solution/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/solution/b/index.ts
+ [/user/username/projects/solution/c/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/c/tsconfig.json
+ /user/username/projects/solution/d/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+ [/user/username/projects/solution/d/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/d/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+ [/user/username/projects/solution/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/tsconfig.json
+// === /user/username/projects/solution/a/index.ts ===
+// export interface [|I|] {
+// M(): void;
+// }
+
+// === /user/username/projects/solution/b/index.ts ===
+// import { [|I|] } from "../a";
+// export class B implements /*FIND ALL REFS*/[|I|] {
+// M() {}
+// }
+
+// === /user/username/projects/solution/c/index.ts ===
+// import { [|I|] } from "../a";
+// import { B } from "../b";
+// export const C: [|I|] = new B();
+
+// === /user/username/projects/solution/d/index.ts ===
+// import { [|I|] } from "../a";
+// import { C } from "../c";
+// export const D: [|I|] = C;
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/b/index.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 26
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/solution/a/index.ts ===
+// export interface [|I|] {
+// M(): void;
+// }
+
+// === /user/username/projects/solution/b/index.ts ===
+// import { [|I|] } from "../a";
+// export class B implements /*FIND ALL REFS*/[|I|] {
+// M() {}
+// }
+
+// === /user/username/projects/solution/c/index.ts ===
+// import { [|I|] } from "../a";
+// import { B } from "../b";
+// export const C: [|I|] = new B();
+
+// === /user/username/projects/solution/d/index.ts ===
+// import { [|I|] } from "../a";
+// import { C } from "../c";
+// export const D: [|I|] = C;
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-project-with-own-files-referencing-the-file-from-referenced-project.js b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-project-with-own-files-referencing-the-file-from-referenced-project.js
new file mode 100644
index 0000000000..ae4d333682
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-project-with-own-files-referencing-the-file-from-referenced-project.js
@@ -0,0 +1,329 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/indirect3/main.ts] *new*
+import { foo } from '../target/src/main';
+foo()
+export function bar() {}
+//// [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+{ }
+//// [/user/username/projects/myproject/own/main.ts] *new*
+import { foo } from '../src/main';
+foo;
+export function bar() {}
+//// [/user/username/projects/myproject/src/helpers/functions.ts] *new*
+export function foo() { return 1; }
+//// [/user/username/projects/myproject/src/main.ts] *new*
+import { foo } from './helpers/functions';
+foo()
+//// [/user/username/projects/myproject/tsconfig-src.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target",
+ },
+ "include": ["./src/**/*"]
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "compilerOptions": {
+
+ },
+ "files": ["./own/main.ts"],
+ "references": [
+ { "path": "./tsconfig-src.json" }
+ ]
+}
+//// [/user/username/workspaces/dummy/dummy.ts] *new*
+const x = 1;
+//// [/user/username/workspaces/dummy/tsconfig.json] *new*
+{ }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ /user/username/projects/myproject/own/main.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ /user/username/projects/myproject/tsconfig.json
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ /user/username/projects/myproject/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json]
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ /user/username/projects/myproject/own/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json]
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ /user/username/projects/myproject/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts]
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ /user/username/projects/myproject/own/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json]
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/workspaces/dummy/tsconfig.json]
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+ [/user/username/workspaces/dummy/dummy.ts]
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ /user/username/projects/myproject/own/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ /user/username/projects/myproject/tsconfig.json
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ /user/username/projects/myproject/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 0
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/src/helpers/functions.ts ===
+// export function [|foo|]() { return 1; }
+
+// === /user/username/projects/myproject/src/main.ts ===
+// import { [|foo|] } from './helpers/functions';
+// /*FIND ALL REFS*/[|foo|]()
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from '../target/src/main';\nfoo()\nexport function bar() {}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ /user/username/projects/myproject/own/main.ts
+Open Files::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ /user/username/projects/myproject/indirect3/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/indirect3/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/indirect3/tsconfig.json
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/indirect3/main.ts ===
+// import { /*FIND ALL REFS*/[|foo|] } from '../target/src/main';
+// [|foo|]()
+// export function bar() {}
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-directly.js b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-directly.js
new file mode 100644
index 0000000000..fefe387e9d
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-directly.js
@@ -0,0 +1,292 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/indirect3/main.ts] *new*
+import { foo } from '../target/src/main';
+foo()
+export function bar() {}
+//// [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+{ }
+//// [/user/username/projects/myproject/src/helpers/functions.ts] *new*
+export function foo() { return 1; }
+//// [/user/username/projects/myproject/src/main.ts] *new*
+import { foo } from './helpers/functions';
+foo()
+//// [/user/username/projects/myproject/tsconfig-src.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target",
+ },
+ "include": ["./src/**/*"]
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "compilerOptions": {
+
+ },
+ "files": [],
+ "references": [
+ { "path": "./tsconfig-src.json" }
+ ]
+}
+//// [/user/username/workspaces/dummy/dummy.ts] *new*
+const x = 1;
+//// [/user/username/workspaces/dummy/tsconfig.json] *new*
+{ }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json]
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json]
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts]
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json]
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/workspaces/dummy/tsconfig.json]
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+ [/user/username/workspaces/dummy/dummy.ts]
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 0
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/src/helpers/functions.ts ===
+// export function [|foo|]() { return 1; }
+
+// === /user/username/projects/myproject/src/main.ts ===
+// import { [|foo|] } from './helpers/functions';
+// /*FIND ALL REFS*/[|foo|]()
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from '../target/src/main';\nfoo()\nexport function bar() {}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ /user/username/projects/myproject/indirect3/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/indirect3/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/indirect3/tsconfig.json
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/indirect3/main.ts ===
+// import { /*FIND ALL REFS*/[|foo|] } from '../target/src/main';
+// [|foo|]()
+// export function bar() {}
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly-through-disableReferencedProjectLoad-in-one-but-without-it-in-another.js b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly-through-disableReferencedProjectLoad-in-one-but-without-it-in-another.js
new file mode 100644
index 0000000000..ec9da862a5
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly-through-disableReferencedProjectLoad-in-one-but-without-it-in-another.js
@@ -0,0 +1,352 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/indirect1/main.ts] *new*
+export const indirect = 1;
+//// [/user/username/projects/myproject/indirect2/main.ts] *new*
+export const indirect = 1;
+//// [/user/username/projects/myproject/indirect3/main.ts] *new*
+import { foo } from '../target/src/main';
+foo()
+export function bar() {}
+//// [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+{ }
+//// [/user/username/projects/myproject/src/helpers/functions.ts] *new*
+export function foo() { return 1; }
+//// [/user/username/projects/myproject/src/main.ts] *new*
+import { foo } from './helpers/functions';
+foo()
+//// [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target/",
+ "disableReferencedProjectLoad": true
+ },
+ "files": [
+ "./indirect1/main.ts"
+ ],
+ "references": [
+ {
+ "path": "./tsconfig-src.json"
+ }
+ ]
+ }
+//// [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target/",
+
+ },
+ "files": [
+ "./indirect2/main.ts"
+ ],
+ "references": [
+ {
+ "path": "./tsconfig-src.json"
+ }
+ ]
+ }
+//// [/user/username/projects/myproject/tsconfig-src.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target",
+ },
+ "include": ["./src/**/*"]
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "compilerOptions": {
+
+ },
+ "files": [],
+ "references": [
+ { "path": "./tsconfig-indirect1.json" },{ "path": "./tsconfig-indirect2.json" }
+ ]
+}
+//// [/user/username/workspaces/dummy/dummy.ts] *new*
+const x = 1;
+//// [/user/username/workspaces/dummy/tsconfig.json] *new*
+{ }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json]
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json]
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts]
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json]
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/workspaces/dummy/tsconfig.json]
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+ [/user/username/workspaces/dummy/dummy.ts]
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 0
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/src/helpers/functions.ts ===
+// export function [|foo|]() { return 1; }
+
+// === /user/username/projects/myproject/src/main.ts ===
+// import { [|foo|] } from './helpers/functions';
+// /*FIND ALL REFS*/[|foo|]()
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from '../target/src/main';\nfoo()\nexport function bar() {}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ /user/username/projects/myproject/indirect3/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/indirect3/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/indirect3/tsconfig.json
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/indirect3/main.ts ===
+// import { /*FIND ALL REFS*/[|foo|] } from '../target/src/main';
+// [|foo|]()
+// export function bar() {}
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly-through-disableReferencedProjectLoad.js b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly-through-disableReferencedProjectLoad.js
new file mode 100644
index 0000000000..eae1dd50f8
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly-through-disableReferencedProjectLoad.js
@@ -0,0 +1,316 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/indirect1/main.ts] *new*
+export const indirect = 1;
+//// [/user/username/projects/myproject/indirect3/main.ts] *new*
+import { foo } from '../target/src/main';
+foo()
+export function bar() {}
+//// [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+{ }
+//// [/user/username/projects/myproject/src/helpers/functions.ts] *new*
+export function foo() { return 1; }
+//// [/user/username/projects/myproject/src/main.ts] *new*
+import { foo } from './helpers/functions';
+foo()
+//// [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target/",
+ "disableReferencedProjectLoad": true
+ },
+ "files": [
+ "./indirect1/main.ts"
+ ],
+ "references": [
+ {
+ "path": "./tsconfig-src.json"
+ }
+ ]
+ }
+//// [/user/username/projects/myproject/tsconfig-src.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target",
+ },
+ "include": ["./src/**/*"]
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "compilerOptions": {
+
+ },
+ "files": [],
+ "references": [
+ { "path": "./tsconfig-indirect1.json" },{ "path": "./tsconfig-indirect2.json" }
+ ]
+}
+//// [/user/username/workspaces/dummy/dummy.ts] *new*
+const x = 1;
+//// [/user/username/workspaces/dummy/tsconfig.json] *new*
+{ }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /dev/null/inferred (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred]
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /dev/null/inferred (default)
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts]
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /dev/null/inferred (default)
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json]
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/workspaces/dummy/tsconfig.json]
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+ [/user/username/workspaces/dummy/dummy.ts]
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /dev/null/inferred (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/workspaces/dummy/dummy.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 0
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/src/helpers/functions.ts ===
+// export function [|foo|]() { return 1; }
+
+// === /user/username/projects/myproject/src/main.ts ===
+// import { [|foo|] } from './helpers/functions';
+// /*FIND ALL REFS*/[|foo|]()
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from '../target/src/main';\nfoo()\nexport function bar() {}"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ /user/username/projects/myproject/indirect3/main.ts
+Open Files::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ /user/username/projects/myproject/indirect3/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/indirect3/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/indirect3/tsconfig.json
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/indirect3/main.ts ===
+// import { /*FIND ALL REFS*/[|foo|] } from '../target/src/main';
+// [|foo|]()
+// export function bar() {}
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly.js b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly.js
new file mode 100644
index 0000000000..af3a9aa85d
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-referencing-default-project-indirectly.js
@@ -0,0 +1,352 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/indirect1/main.ts] *new*
+export const indirect = 1;
+//// [/user/username/projects/myproject/indirect2/main.ts] *new*
+export const indirect = 1;
+//// [/user/username/projects/myproject/indirect3/main.ts] *new*
+import { foo } from '../target/src/main';
+foo()
+export function bar() {}
+//// [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+{ }
+//// [/user/username/projects/myproject/src/helpers/functions.ts] *new*
+export function foo() { return 1; }
+//// [/user/username/projects/myproject/src/main.ts] *new*
+import { foo } from './helpers/functions';
+foo()
+//// [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target/",
+
+ },
+ "files": [
+ "./indirect1/main.ts"
+ ],
+ "references": [
+ {
+ "path": "./tsconfig-src.json"
+ }
+ ]
+ }
+//// [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+
+ {
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target/",
+
+ },
+ "files": [
+ "./indirect2/main.ts"
+ ],
+ "references": [
+ {
+ "path": "./tsconfig-src.json"
+ }
+ ]
+ }
+//// [/user/username/projects/myproject/tsconfig-src.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target",
+ },
+ "include": ["./src/**/*"]
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "compilerOptions": {
+
+ },
+ "files": [],
+ "references": [
+ { "path": "./tsconfig-indirect1.json" },{ "path": "./tsconfig-indirect2.json" }
+ ]
+}
+//// [/user/username/workspaces/dummy/dummy.ts] *new*
+const x = 1;
+//// [/user/username/workspaces/dummy/tsconfig.json] *new*
+{ }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json]
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json]
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts]
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /user/username/projects/myproject/tsconfig-src.json (default)
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json]
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/workspaces/dummy/tsconfig.json]
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+ [/user/username/workspaces/dummy/dummy.ts]
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /user/username/projects/myproject/tsconfig-src.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/tsconfig-src.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig-src.json
+ [/user/username/workspaces/dummy/dummy.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 0
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/src/helpers/functions.ts ===
+// export function [|foo|]() { return 1; }
+
+// === /user/username/projects/myproject/src/main.ts ===
+// import { [|foo|] } from './helpers/functions';
+// /*FIND ALL REFS*/[|foo|]()
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from '../target/src/main';\nfoo()\nexport function bar() {}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ /user/username/projects/myproject/indirect3/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/indirect3/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig-indirect1.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-indirect2.json] *deleted*
+ [/user/username/projects/myproject/tsconfig-src.json] *deleted*
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/indirect3/tsconfig.json
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/indirect3/main.ts ===
+// import { /*FIND ALL REFS*/[|foo|] } from '../target/src/main';
+// [|foo|]()
+// export function bar() {}
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-with-disableReferencedProjectLoad-referencing-default-project-directly.js b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-with-disableReferencedProjectLoad-referencing-default-project-directly.js
new file mode 100644
index 0000000000..ea9faf58a7
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/project-found-is-solution-with-disableReferencedProjectLoad-referencing-default-project-directly.js
@@ -0,0 +1,275 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/indirect3/main.ts] *new*
+import { foo } from '../target/src/main';
+foo()
+export function bar() {}
+//// [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+{ }
+//// [/user/username/projects/myproject/src/helpers/functions.ts] *new*
+export function foo() { return 1; }
+//// [/user/username/projects/myproject/src/main.ts] *new*
+import { foo } from './helpers/functions';
+foo()
+//// [/user/username/projects/myproject/tsconfig-src.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "./target",
+ },
+ "include": ["./src/**/*"]
+}
+//// [/user/username/projects/myproject/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "disableReferencedProjectLoad": true
+ },
+ "files": [],
+ "references": [
+ { "path": "./tsconfig-src.json" }
+ ]
+}
+//// [/user/username/workspaces/dummy/dummy.ts] *new*
+const x = 1;
+//// [/user/username/workspaces/dummy/tsconfig.json] *new*
+{ }
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /dev/null/inferred (default)
+Config::
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred]
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /dev/null/inferred (default)
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig.json]
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts]
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts]
+ /dev/null/inferred (default)
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "const x = 1;"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json]
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *new*
+ /user/username/workspaces/dummy/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+ [/user/username/workspaces/dummy/tsconfig.json]
+ RetainingProjects:
+ /user/username/workspaces/dummy/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/workspaces/dummy/dummy.ts
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+ [/user/username/workspaces/dummy/dummy.ts]
+ NearestConfigFileName: /user/username/workspaces/dummy/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/workspaces/dummy/dummy.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/workspaces/dummy/dummy.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from './helpers/functions';\nfoo()"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *new*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+ /user/username/workspaces/dummy/dummy.ts
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ /dev/null/inferred (default)
+Config::
+ [/user/username/projects/myproject/tsconfig.json] *new*
+ RetainingOpenFiles:
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/workspaces/dummy/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/src/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/tsconfig.json
+ [/user/username/workspaces/dummy/dummy.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 0
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/src/helpers/functions.ts ===
+// export function [|foo|]() { return 1; }
+
+// === /user/username/projects/myproject/src/main.ts ===
+// import { [|foo|] } from './helpers/functions';
+// /*FIND ALL REFS*/[|foo|]()
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/src/main.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/src/main.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { foo } from '../target/src/main';\nfoo()\nexport function bar() {}"
+ }
+ }
+}
+Projects::
+ [/dev/null/inferred] *deleted*
+ /user/username/projects/myproject/src/helpers/functions.ts
+ /user/username/projects/myproject/src/main.ts
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ /user/username/projects/myproject/indirect3/main.ts
+Open Files::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ /user/username/projects/myproject/indirect3/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/indirect3/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/indirect3/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/indirect3/main.ts
+ [/user/username/projects/myproject/tsconfig.json] *deleted*
+Config File Names::
+ [/user/username/projects/myproject/indirect3/main.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/indirect3/tsconfig.json
+ [/user/username/projects/myproject/src/main.ts] *deleted*
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/indirect3/main.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/indirect3/main.ts ===
+// import { /*FIND ALL REFS*/[|foo|] } from '../target/src/main';
+// [|foo|]()
+// export function bar() {}
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/references-on-file-opened-is-in-configured-project-that-will-be-removed.js b/testdata/baselines/reference/lspservertests/findAllRefs/references-on-file-opened-is-in-configured-project-that-will-be-removed.js
new file mode 100644
index 0000000000..7d164d68ee
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/references-on-file-opened-is-in-configured-project-that-will-be-removed.js
@@ -0,0 +1,108 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/myproject/playground/tests.ts] *new*
+export function foo() {}
+//// [/user/username/projects/myproject/playground/tsconfig-json/src/src.ts] *new*
+export function foobar() { }
+//// [/user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts] *new*
+export function bar() { }
+//// [/user/username/projects/myproject/playground/tsconfig-json/tsconfig.json] *new*
+{
+ "include": ["./src"],
+}
+//// [/user/username/projects/myproject/playground/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/playground/tests.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function foo() {}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/playground/tsconfig.json] *new*
+ /user/username/projects/myproject/playground/tests.ts
+ /user/username/projects/myproject/playground/tsconfig-json/src/src.ts
+ /user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts
+Open Files::
+ [/user/username/projects/myproject/playground/tests.ts] *new*
+ /user/username/projects/myproject/playground/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/playground/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/playground/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/playground/tests.ts
+Config File Names::
+ [/user/username/projects/myproject/playground/tests.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/playground/tsconfig.json
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/playground/tests.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/myproject/playground/tests.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export function bar() { }"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/myproject/playground/tsconfig-json/tsconfig.json] *new*
+ /user/username/projects/myproject/playground/tsconfig-json/src/src.ts
+ [/user/username/projects/myproject/playground/tsconfig.json]
+ /user/username/projects/myproject/playground/tests.ts
+ /user/username/projects/myproject/playground/tsconfig-json/src/src.ts
+ /user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts
+Open Files::
+ [/user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts] *new*
+ /user/username/projects/myproject/playground/tsconfig.json (default)
+Config::
+ [/user/username/projects/myproject/playground/tsconfig-json/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/myproject/playground/tsconfig-json/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts
+ [/user/username/projects/myproject/playground/tsconfig.json] *modified*
+ RetainingProjects:
+ /user/username/projects/myproject/playground/tsconfig.json
+ RetainingOpenFiles: *modified*
+ /user/username/projects/myproject/playground/tests.ts *deleted*
+ /user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts *new*
+Config File Names::
+ [/user/username/projects/myproject/playground/tests.ts] *deleted*
+ [/user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts] *new*
+ NearestConfigFileName: /user/username/projects/myproject/playground/tsconfig-json/tsconfig.json
+ Ancestors:
+ /user/username/projects/myproject/playground/tsconfig-json/tsconfig.json /user/username/projects/myproject/playground/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 16
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/myproject/playground/tsconfig-json/tests/spec.ts ===
+// export function /*FIND ALL REFS*/[|bar|]() { }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/root-file-is-file-from-referenced-project-and-using-declaration-maps.js b/testdata/baselines/reference/lspservertests/findAllRefs/root-file-is-file-from-referenced-project-and-using-declaration-maps.js
new file mode 100644
index 0000000000..3cecd5ab40
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/root-file-is-file-from-referenced-project-and-using-declaration-maps.js
@@ -0,0 +1,358 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/project/out/input/keyboard.d.ts] *new*
+export declare function evaluateKeyboardEvent(): void;
+//# sourceMappingURL=keyboard.d.ts.map
+//// [/user/username/projects/project/out/input/keyboard.d.ts.map] *new*
+{"version":3,"file":"keyboard.d.ts","sourceRoot":"","sources":["../../src/common/input/keyboard.ts"],"names":[],"mappings":"AACA,wBAAgB,qBAAqB,SAAM"}
+//// [/user/username/projects/project/out/input/keyboard.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.evaluateKeyboardEvent = evaluateKeyboardEvent;
+function bar() { return "just a random function so .d.ts location doesnt match"; }
+function evaluateKeyboardEvent() { }
+
+//// [/user/username/projects/project/out/input/keyboard.test.d.ts] *new*
+export {};
+//# sourceMappingURL=keyboard.test.d.ts.map
+//// [/user/username/projects/project/out/input/keyboard.test.d.ts.map] *new*
+{"version":3,"file":"keyboard.test.d.ts","sourceRoot":"","sources":["../../src/common/input/keyboard.test.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/project/out/input/keyboard.test.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const keyboard_1 = require("common/input/keyboard");
+function testEvaluateKeyboardEvent() {
+ return (0, keyboard_1.evaluateKeyboardEvent)();
+}
+
+//// [/user/username/projects/project/out/src.tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[[2,4]],"fileNames":["lib.d.ts","./input/keyboard.d.ts","../src/terminal.ts","./input/keyboard.test.d.ts","../src/common/input/keyboard.ts","../src/common/input/keyboard.test.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},"362bf1943c7d2a927f25978d1f24d61f-export declare function evaluateKeyboardEvent(): void;\n//# sourceMappingURL=keyboard.d.ts.map",{"version":"03ece765cef2ff28231304b4d7007649-import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction foo() {\n return evaluateKeyboardEvent();\n}","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1},"aaff3960e003a07ef50db935cb91a696-export {};\n//# sourceMappingURL=keyboard.test.d.ts.map"],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true,"outDir":"./","tsBuildInfoFile":"./src.tsconfig.tsbuildinfo"},"referencedMap":[[3,1]],"latestChangedDtsFile":"./terminal.d.ts","resolvedRoot":[[2,5],[4,6]]}
+//// [/user/username/projects/project/out/src.tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "./input/keyboard.d.ts",
+ "../src/terminal.ts",
+ "./input/keyboard.test.d.ts"
+ ],
+ "original": [
+ 2,
+ 4
+ ]
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "./input/keyboard.d.ts",
+ "../src/terminal.ts",
+ "./input/keyboard.test.d.ts",
+ "../src/common/input/keyboard.ts",
+ "../src/common/input/keyboard.test.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./input/keyboard.d.ts",
+ "version": "362bf1943c7d2a927f25978d1f24d61f-export declare function evaluateKeyboardEvent(): void;\n//# sourceMappingURL=keyboard.d.ts.map",
+ "signature": "362bf1943c7d2a927f25978d1f24d61f-export declare function evaluateKeyboardEvent(): void;\n//# sourceMappingURL=keyboard.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ },
+ {
+ "fileName": "../src/terminal.ts",
+ "version": "03ece765cef2ff28231304b4d7007649-import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction foo() {\n return evaluateKeyboardEvent();\n}",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "03ece765cef2ff28231304b4d7007649-import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction foo() {\n return evaluateKeyboardEvent();\n}",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "./input/keyboard.test.d.ts",
+ "version": "aaff3960e003a07ef50db935cb91a696-export {};\n//# sourceMappingURL=keyboard.test.d.ts.map",
+ "signature": "aaff3960e003a07ef50db935cb91a696-export {};\n//# sourceMappingURL=keyboard.test.d.ts.map",
+ "impliedNodeFormat": "CommonJS"
+ }
+ ],
+ "fileIdsList": [
+ [
+ "./input/keyboard.d.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "./",
+ "tsBuildInfoFile": "./src.tsconfig.tsbuildinfo"
+ },
+ "referencedMap": {
+ "../src/terminal.ts": [
+ "./input/keyboard.d.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./terminal.d.ts",
+ "resolvedRoot": [
+ [
+ "./input/keyboard.d.ts",
+ "../src/common/input/keyboard.ts"
+ ],
+ [
+ "./input/keyboard.test.d.ts",
+ "../src/common/input/keyboard.test.ts"
+ ]
+ ],
+ "size": 1695
+}
+//// [/user/username/projects/project/out/terminal.d.ts] *new*
+export {};
+//# sourceMappingURL=terminal.d.ts.map
+//// [/user/username/projects/project/out/terminal.d.ts.map] *new*
+{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":""}
+//// [/user/username/projects/project/out/terminal.js] *new*
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+const keyboard_1 = require("common/input/keyboard");
+function foo() {
+ return (0, keyboard_1.evaluateKeyboardEvent)();
+}
+
+//// [/user/username/projects/project/out/tsconfig.tsbuildinfo] *new*
+{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.d.ts","../src/common/input/keyboard.ts","../src/common/input/keyboard.test.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"6e37abb18685aa8e2642ab0218eef699-function bar() { return \"just a random function so .d.ts location doesnt match\"; }\nexport function evaluateKeyboardEvent() { }","signature":"569df1f274cf52f322c6e7a2f4e891fe-export declare function evaluateKeyboardEvent(): void;\n","impliedNodeFormat":1},{"version":"80dddc2f6e9d5c8a92919e5a78fab3c0-import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction testEvaluateKeyboardEvent() {\n return evaluateKeyboardEvent();\n}","signature":"abe7d9981d6018efb6b2b794f40a1607-export {};\n","impliedNodeFormat":1}],"fileIdsList":[[2]],"options":{"composite":true,"declarationMap":true,"outDir":"./"},"referencedMap":[[3,1]],"latestChangedDtsFile":"./input/keyboard.test.d.ts"}
+//// [/user/username/projects/project/out/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
+{
+ "version": "FakeTSVersion",
+ "root": [
+ {
+ "files": [
+ "../src/common/input/keyboard.ts",
+ "../src/common/input/keyboard.test.ts"
+ ],
+ "original": [
+ 2,
+ 3
+ ]
+ }
+ ],
+ "fileNames": [
+ "lib.d.ts",
+ "../src/common/input/keyboard.ts",
+ "../src/common/input/keyboard.test.ts"
+ ],
+ "fileInfos": [
+ {
+ "fileName": "lib.d.ts",
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "signature": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };",
+ "affectsGlobalScope": true,
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../src/common/input/keyboard.ts",
+ "version": "6e37abb18685aa8e2642ab0218eef699-function bar() { return \"just a random function so .d.ts location doesnt match\"; }\nexport function evaluateKeyboardEvent() { }",
+ "signature": "569df1f274cf52f322c6e7a2f4e891fe-export declare function evaluateKeyboardEvent(): void;\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "6e37abb18685aa8e2642ab0218eef699-function bar() { return \"just a random function so .d.ts location doesnt match\"; }\nexport function evaluateKeyboardEvent() { }",
+ "signature": "569df1f274cf52f322c6e7a2f4e891fe-export declare function evaluateKeyboardEvent(): void;\n",
+ "impliedNodeFormat": 1
+ }
+ },
+ {
+ "fileName": "../src/common/input/keyboard.test.ts",
+ "version": "80dddc2f6e9d5c8a92919e5a78fab3c0-import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction testEvaluateKeyboardEvent() {\n return evaluateKeyboardEvent();\n}",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": "CommonJS",
+ "original": {
+ "version": "80dddc2f6e9d5c8a92919e5a78fab3c0-import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction testEvaluateKeyboardEvent() {\n return evaluateKeyboardEvent();\n}",
+ "signature": "abe7d9981d6018efb6b2b794f40a1607-export {};\n",
+ "impliedNodeFormat": 1
+ }
+ }
+ ],
+ "fileIdsList": [
+ [
+ "../src/common/input/keyboard.ts"
+ ]
+ ],
+ "options": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "./"
+ },
+ "referencedMap": {
+ "../src/common/input/keyboard.test.ts": [
+ "../src/common/input/keyboard.ts"
+ ]
+ },
+ "latestChangedDtsFile": "./input/keyboard.test.d.ts",
+ "size": 1660
+}
+//// [/user/username/projects/project/src/common/input/keyboard.test.ts] *new*
+import { evaluateKeyboardEvent } from 'common/input/keyboard';
+function testEvaluateKeyboardEvent() {
+ return evaluateKeyboardEvent();
+}
+//// [/user/username/projects/project/src/common/input/keyboard.ts] *new*
+function bar() { return "just a random function so .d.ts location doesnt match"; }
+export function evaluateKeyboardEvent() { }
+//// [/user/username/projects/project/src/common/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "../../out",
+ "disableSourceOfProjectReferenceRedirect": true,
+ "paths": {
+ "*": ["../*"],
+ },
+ },
+ "include": ["./**/*"]
+}
+//// [/user/username/projects/project/src/terminal.ts] *new*
+import { evaluateKeyboardEvent } from 'common/input/keyboard';
+function foo() {
+ return evaluateKeyboardEvent();
+}
+//// [/user/username/projects/project/src/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "../out",
+ "disableSourceOfProjectReferenceRedirect": true,
+ "paths": {
+ "common/*": ["./common/*"],
+ },
+ "tsBuildInfoFile": "../out/src.tsconfig.tsbuildinfo"
+ },
+ "include": ["./**/*"],
+ "references": [
+ { "path": "./common" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/project/src/common/input/keyboard.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "function bar() { return \"just a random function so .d.ts location doesnt match\"; }\nexport function evaluateKeyboardEvent() { }"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/project/src/common/tsconfig.json] *new*
+ /user/username/projects/project/src/common/input/keyboard.ts
+ /user/username/projects/project/src/common/input/keyboard.test.ts
+ [/user/username/projects/project/src/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/project/src/common/input/keyboard.ts] *new*
+ /user/username/projects/project/src/common/tsconfig.json (default)
+Config::
+ [/user/username/projects/project/src/common/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/project/src/common/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/project/src/common/input/keyboard.ts
+Config File Names::
+ [/user/username/projects/project/src/common/input/keyboard.ts] *new*
+ NearestConfigFileName: /user/username/projects/project/src/common/tsconfig.json
+ Ancestors:
+ /user/username/projects/project/src/common/tsconfig.json /user/username/projects/project/src/tsconfig.json
+ /user/username/projects/project/src/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/project/src/terminal.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction foo() {\n return evaluateKeyboardEvent();\n}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/project/src/common/tsconfig.json]
+ /user/username/projects/project/src/common/input/keyboard.ts
+ /user/username/projects/project/src/common/input/keyboard.test.ts
+ [/user/username/projects/project/src/tsconfig.json] *modified*
+ /user/username/projects/project/out/input/keyboard.d.ts *new*
+ /user/username/projects/project/src/terminal.ts *new*
+ /user/username/projects/project/out/input/keyboard.test.d.ts *new*
+Open Files::
+ [/user/username/projects/project/src/common/input/keyboard.ts]
+ /user/username/projects/project/src/common/tsconfig.json (default)
+ [/user/username/projects/project/src/terminal.ts] *new*
+ /user/username/projects/project/src/tsconfig.json (default)
+Config::
+ [/user/username/projects/project/src/common/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/project/src/common/tsconfig.json
+ /user/username/projects/project/src/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/project/src/common/input/keyboard.ts
+ [/user/username/projects/project/src/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/project/src/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/project/src/terminal.ts
+Config File Names::
+ [/user/username/projects/project/src/common/input/keyboard.ts]
+ NearestConfigFileName: /user/username/projects/project/src/common/tsconfig.json
+ Ancestors:
+ /user/username/projects/project/src/common/tsconfig.json /user/username/projects/project/src/tsconfig.json
+ /user/username/projects/project/src/tsconfig.json
+ [/user/username/projects/project/src/terminal.ts] *new*
+ NearestConfigFileName: /user/username/projects/project/src/tsconfig.json
+ Ancestors:
+ /user/username/projects/project/src/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/project/src/common/input/keyboard.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 16
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/project/src/common/input/keyboard.test.ts ===
+// import { [|evaluateKeyboardEvent|] } from 'common/input/keyboard';
+// function testEvaluateKeyboardEvent() {
+// return [|evaluateKeyboardEvent|]();
+// }
+
+// === /user/username/projects/project/src/common/input/keyboard.ts ===
+// function bar() { return "just a random function so .d.ts location doesnt match"; }
+// export function /*FIND ALL REFS*/[|evaluateKeyboardEvent|]() { }
+
+// === /user/username/projects/project/src/terminal.ts ===
+// import { [|evaluateKeyboardEvent|] } from 'common/input/keyboard';
+// function foo() {
+// return [|evaluateKeyboardEvent|]();
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/root-file-is-file-from-referenced-project.js b/testdata/baselines/reference/lspservertests/findAllRefs/root-file-is-file-from-referenced-project.js
new file mode 100644
index 0000000000..da67eb43ce
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/root-file-is-file-from-referenced-project.js
@@ -0,0 +1,153 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/project/src/common/input/keyboard.test.ts] *new*
+import { evaluateKeyboardEvent } from 'common/input/keyboard';
+function testEvaluateKeyboardEvent() {
+ return evaluateKeyboardEvent();
+}
+//// [/user/username/projects/project/src/common/input/keyboard.ts] *new*
+function bar() { return "just a random function so .d.ts location doesnt match"; }
+export function evaluateKeyboardEvent() { }
+//// [/user/username/projects/project/src/common/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "../../out",
+ "disableSourceOfProjectReferenceRedirect": false,
+ "paths": {
+ "*": ["../*"],
+ },
+ },
+ "include": ["./**/*"]
+}
+//// [/user/username/projects/project/src/terminal.ts] *new*
+import { evaluateKeyboardEvent } from 'common/input/keyboard';
+function foo() {
+ return evaluateKeyboardEvent();
+}
+//// [/user/username/projects/project/src/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "declarationMap": true,
+ "outDir": "../out",
+ "disableSourceOfProjectReferenceRedirect": false,
+ "paths": {
+ "common/*": ["./common/*"],
+ },
+ "tsBuildInfoFile": "../out/src.tsconfig.tsbuildinfo"
+ },
+ "include": ["./**/*"],
+ "references": [
+ { "path": "./common" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/project/src/common/input/keyboard.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "function bar() { return \"just a random function so .d.ts location doesnt match\"; }\nexport function evaluateKeyboardEvent() { }"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/project/src/common/tsconfig.json] *new*
+ /user/username/projects/project/src/common/input/keyboard.ts
+ /user/username/projects/project/src/common/input/keyboard.test.ts
+ [/user/username/projects/project/src/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/project/src/common/input/keyboard.ts] *new*
+ /user/username/projects/project/src/common/tsconfig.json (default)
+Config::
+ [/user/username/projects/project/src/common/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/project/src/common/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/project/src/common/input/keyboard.ts
+Config File Names::
+ [/user/username/projects/project/src/common/input/keyboard.ts] *new*
+ NearestConfigFileName: /user/username/projects/project/src/common/tsconfig.json
+ Ancestors:
+ /user/username/projects/project/src/common/tsconfig.json /user/username/projects/project/src/tsconfig.json
+ /user/username/projects/project/src/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/project/src/terminal.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { evaluateKeyboardEvent } from 'common/input/keyboard';\nfunction foo() {\n return evaluateKeyboardEvent();\n}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/project/src/common/tsconfig.json]
+ /user/username/projects/project/src/common/input/keyboard.ts
+ /user/username/projects/project/src/common/input/keyboard.test.ts
+ [/user/username/projects/project/src/tsconfig.json] *modified*
+ /user/username/projects/project/src/common/input/keyboard.ts *new*
+ /user/username/projects/project/src/terminal.ts *new*
+ /user/username/projects/project/src/common/input/keyboard.test.ts *new*
+Open Files::
+ [/user/username/projects/project/src/common/input/keyboard.ts] *modified*
+ /user/username/projects/project/src/common/tsconfig.json (default)
+ /user/username/projects/project/src/tsconfig.json *new*
+ [/user/username/projects/project/src/terminal.ts] *new*
+ /user/username/projects/project/src/tsconfig.json (default)
+Config::
+ [/user/username/projects/project/src/common/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/project/src/common/tsconfig.json
+ /user/username/projects/project/src/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/project/src/common/input/keyboard.ts
+ [/user/username/projects/project/src/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/project/src/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/project/src/terminal.ts
+Config File Names::
+ [/user/username/projects/project/src/common/input/keyboard.ts]
+ NearestConfigFileName: /user/username/projects/project/src/common/tsconfig.json
+ Ancestors:
+ /user/username/projects/project/src/common/tsconfig.json /user/username/projects/project/src/tsconfig.json
+ /user/username/projects/project/src/tsconfig.json
+ [/user/username/projects/project/src/terminal.ts] *new*
+ NearestConfigFileName: /user/username/projects/project/src/tsconfig.json
+ Ancestors:
+ /user/username/projects/project/src/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/project/src/common/input/keyboard.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 16
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+// === /user/username/projects/project/src/common/input/keyboard.test.ts ===
+// import { [|evaluateKeyboardEvent|] } from 'common/input/keyboard';
+// function testEvaluateKeyboardEvent() {
+// return [|evaluateKeyboardEvent|]();
+// }
+
+// === /user/username/projects/project/src/common/input/keyboard.ts ===
+// function bar() { return "just a random function so .d.ts location doesnt match"; }
+// export function /*FIND ALL REFS*/[|evaluateKeyboardEvent|]() { }
+
+// === /user/username/projects/project/src/terminal.ts ===
+// import { [|evaluateKeyboardEvent|] } from 'common/input/keyboard';
+// function foo() {
+// return [|evaluateKeyboardEvent|]();
+// }
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-as-object-literal-property-types.js b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-as-object-literal-property-types.js
new file mode 100644
index 0000000000..bb532ce1ed
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-as-object-literal-property-types.js
@@ -0,0 +1,136 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/api/src/server.ts] *new*
+import * as shared from "../../shared/dist"
+shared.foo.bar();
+//// [/user/username/projects/solution/api/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/app/src/app.ts] *new*
+import * as shared from "../../shared/dist"
+shared.foo.bar();
+//// [/user/username/projects/solution/app/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/shared/src/index.ts] *new*
+export const foo = { bar: () => { } };
+//// [/user/username/projects/solution/shared/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "references": [
+ { "path": "./api" },
+ { "path": "./app" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as shared from \"../../shared/dist\"\nshared.foo.bar();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ /user/username/projects/solution/api/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+Config File Names::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/api/tsconfig.json
+ Ancestors:
+ /user/username/projects/solution/api/tsconfig.json /user/username/projects/solution/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 11
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json]
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/app/src/app.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ [/user/username/projects/solution/tsconfig.json] *modified*
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/app/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+ [/user/username/projects/solution/shared/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/app/tsconfig.json *new*
+ /user/username/projects/solution/shared/tsconfig.json *new*
+ /user/username/projects/solution/tsconfig.json *new*
+ [/user/username/projects/solution/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/tsconfig.json
+// === /user/username/projects/solution/api/src/server.ts ===
+// import * as shared from "../../shared/dist"
+// shared.foo./*FIND ALL REFS*/[|bar|]();
+
+// === /user/username/projects/solution/app/src/app.ts ===
+// import * as shared from "../../shared/dist"
+// shared.foo.[|bar|]();
+
+// === /user/username/projects/solution/shared/src/index.ts ===
+// export const foo = { [|bar|]: () => { } };
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-as-object-literal-property.js b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-as-object-literal-property.js
new file mode 100644
index 0000000000..3f15022a00
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-as-object-literal-property.js
@@ -0,0 +1,121 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/api/src/server.ts] *new*
+import * as shared from "../../shared/dist"
+shared.foo.bar();
+//// [/user/username/projects/solution/api/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/app/src/app.ts] *new*
+import * as shared from "../../shared/dist"
+shared.foo.bar();
+//// [/user/username/projects/solution/app/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/shared/src/index.ts] *new*
+const local = { bar: () => { } };
+export const foo = local;
+//// [/user/username/projects/solution/shared/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "references": [
+ { "path": "./api" },
+ { "path": "./app" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as shared from \"../../shared/dist\"\nshared.foo.bar();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ /user/username/projects/solution/api/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+Config File Names::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/api/tsconfig.json
+ Ancestors:
+ /user/username/projects/solution/api/tsconfig.json /user/username/projects/solution/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 11
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json]
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ [/user/username/projects/solution/tsconfig.json]
+Config::
+ [/user/username/projects/solution/api/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/shared/tsconfig.json *new*
+// === /user/username/projects/solution/api/src/server.ts ===
+// import * as shared from "../../shared/dist"
+// shared.foo./*FIND ALL REFS*/[|bar|]();
+
+// === /user/username/projects/solution/shared/src/index.ts ===
+// const local = { [|bar|]: () => { } };
+// export const foo = local;
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-assignment.js b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-assignment.js
new file mode 100644
index 0000000000..d972f3201e
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-arrow-function-assignment.js
@@ -0,0 +1,136 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/api/src/server.ts] *new*
+import * as shared from "../../shared/dist"
+shared.dog();
+//// [/user/username/projects/solution/api/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/app/src/app.ts] *new*
+import * as shared from "../../shared/dist"
+shared.dog();
+//// [/user/username/projects/solution/app/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/shared/src/index.ts] *new*
+export const dog = () => { };
+//// [/user/username/projects/solution/shared/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "references": [
+ { "path": "./api" },
+ { "path": "./app" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as shared from \"../../shared/dist\"\nshared.dog();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ /user/username/projects/solution/api/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+Config File Names::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/api/tsconfig.json
+ Ancestors:
+ /user/username/projects/solution/api/tsconfig.json /user/username/projects/solution/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 7
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json]
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/app/src/app.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ [/user/username/projects/solution/tsconfig.json] *modified*
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/app/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+ [/user/username/projects/solution/shared/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/app/tsconfig.json *new*
+ /user/username/projects/solution/shared/tsconfig.json *new*
+ /user/username/projects/solution/tsconfig.json *new*
+ [/user/username/projects/solution/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/tsconfig.json
+// === /user/username/projects/solution/api/src/server.ts ===
+// import * as shared from "../../shared/dist"
+// shared./*FIND ALL REFS*/[|dog|]();
+
+// === /user/username/projects/solution/app/src/app.ts ===
+// import * as shared from "../../shared/dist"
+// shared.[|dog|]();
+
+// === /user/username/projects/solution/shared/src/index.ts ===
+// export const [|dog|] = () => { };
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-method-of-class-expression.js b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-method-of-class-expression.js
new file mode 100644
index 0000000000..880b4899fe
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-method-of-class-expression.js
@@ -0,0 +1,140 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/api/src/server.ts] *new*
+import * as shared from "../../shared/dist"
+const instance = new shared.foo();
+instance.fly();
+//// [/user/username/projects/solution/api/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/app/src/app.ts] *new*
+import * as shared from "../../shared/dist"
+const instance = new shared.foo();
+instance.fly();
+//// [/user/username/projects/solution/app/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/shared/src/index.ts] *new*
+export const foo = class { fly() {} };
+//// [/user/username/projects/solution/shared/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "references": [
+ { "path": "./api" },
+ { "path": "./app" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as shared from \"../../shared/dist\"\nconst instance = new shared.foo();\ninstance.fly();"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ /user/username/projects/solution/api/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+Config File Names::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/api/tsconfig.json
+ Ancestors:
+ /user/username/projects/solution/api/tsconfig.json /user/username/projects/solution/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts"
+ },
+ "position": {
+ "line": 2,
+ "character": 9
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json]
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/app/src/app.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ [/user/username/projects/solution/tsconfig.json] *modified*
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/app/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+ [/user/username/projects/solution/shared/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/app/tsconfig.json *new*
+ /user/username/projects/solution/shared/tsconfig.json *new*
+ /user/username/projects/solution/tsconfig.json *new*
+ [/user/username/projects/solution/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/tsconfig.json
+// === /user/username/projects/solution/api/src/server.ts ===
+// import * as shared from "../../shared/dist"
+// const instance = new shared.foo();
+// instance./*FIND ALL REFS*/[|fly|]();
+
+// === /user/username/projects/solution/app/src/app.ts ===
+// import * as shared from "../../shared/dist"
+// const instance = new shared.foo();
+// instance.[|fly|]();
+
+// === /user/username/projects/solution/shared/src/index.ts ===
+// export const foo = class { [|fly|]() {} };
diff --git a/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-object-literal-property.js b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-object-literal-property.js
new file mode 100644
index 0000000000..8f7d169da4
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/findAllRefs/special-handling-of-localness-when-using-object-literal-property.js
@@ -0,0 +1,136 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/solution/api/src/server.ts] *new*
+import * as shared from "../../shared/dist"
+shared.foo.baz;
+//// [/user/username/projects/solution/api/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/app/src/app.ts] *new*
+import * as shared from "../../shared/dist"
+shared.foo.baz;
+//// [/user/username/projects/solution/app/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+ "references": [{ "path": "../shared" }],
+}
+//// [/user/username/projects/solution/shared/src/index.ts] *new*
+export const foo = { baz: "BAZ" };
+//// [/user/username/projects/solution/shared/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ "outDir": "dist",
+ "rootDir": "src"
+ },
+ "include": ["src"],
+}
+//// [/user/username/projects/solution/tsconfig.json] *new*
+{
+ "files": [],
+ "references": [
+ { "path": "./api" },
+ { "path": "./app" },
+ ],
+}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import * as shared from \"../../shared/dist\"\nshared.foo.baz;"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ /user/username/projects/solution/api/tsconfig.json (default)
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/api/tsconfig.json
+Config File Names::
+ [/user/username/projects/solution/api/src/server.ts] *new*
+ NearestConfigFileName: /user/username/projects/solution/api/tsconfig.json
+ Ancestors:
+ /user/username/projects/solution/api/tsconfig.json /user/username/projects/solution/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+{
+ "method": "textDocument/references",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/solution/api/src/server.ts"
+ },
+ "position": {
+ "line": 1,
+ "character": 11
+ },
+ "context": {
+ "includeDeclaration": false
+ }
+ }
+}
+Projects::
+ [/user/username/projects/solution/api/tsconfig.json]
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ /user/username/projects/solution/app/src/app.ts
+ [/user/username/projects/solution/shared/tsconfig.json] *new*
+ /user/username/projects/solution/shared/src/index.ts
+ [/user/username/projects/solution/tsconfig.json] *modified*
+Config::
+ [/user/username/projects/solution/api/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/tsconfig.json *new*
+ RetainingOpenFiles:
+ /user/username/projects/solution/api/src/server.ts
+ [/user/username/projects/solution/app/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/app/tsconfig.json
+ /user/username/projects/solution/tsconfig.json
+ [/user/username/projects/solution/shared/tsconfig.json] *modified*
+ RetainingProjects: *modified*
+ /user/username/projects/solution/api/tsconfig.json
+ /user/username/projects/solution/app/tsconfig.json *new*
+ /user/username/projects/solution/shared/tsconfig.json *new*
+ /user/username/projects/solution/tsconfig.json *new*
+ [/user/username/projects/solution/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/solution/tsconfig.json
+// === /user/username/projects/solution/api/src/server.ts ===
+// import * as shared from "../../shared/dist"
+// shared.foo./*FIND ALL REFS*/[|baz|];
+
+// === /user/username/projects/solution/app/src/app.ts ===
+// import * as shared from "../../shared/dist"
+// shared.foo.[|baz|];
+
+// === /user/username/projects/solution/shared/src/index.ts ===
+// export const foo = { [|baz|]: "BAZ" };
diff --git a/testdata/baselines/reference/lspservertests/rename/ancestor-and-project-ref-management.js b/testdata/baselines/reference/lspservertests/rename/ancestor-and-project-ref-management.js
new file mode 100644
index 0000000000..84e8cebbdd
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/rename/ancestor-and-project-ref-management.js
@@ -0,0 +1,234 @@
+UseCaseSensitiveFileNames: false
+//// [/user/username/projects/container/compositeExec/index.ts] *new*
+import { myConst } from "../lib";
+export function getMyConst() {
+ return myConst;
+}
+//// [/user/username/projects/container/compositeExec/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ },
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../lib" },
+ ],
+}
+//// [/user/username/projects/container/exec/index.ts] *new*
+import { myConst } from "../lib";
+export function getMyConst() {
+ return myConst;
+}
+//// [/user/username/projects/container/exec/tsconfig.json] *new*
+{
+ "files": ["./index.ts"],
+ "references": [
+ { "path": "../lib" },
+ ],
+}
+//// [/user/username/projects/container/lib/index.ts] *new*
+export const myConst = 30;
+//// [/user/username/projects/container/lib/tsconfig.json] *new*
+{
+ "compilerOptions": {
+ "composite": true,
+ },
+ references: [],
+ files: [
+ "index.ts",
+ ],
+}
+//// [/user/username/projects/container/tsconfig.json] *new*
+{
+ "files": [],
+ "include": [],
+ "references": [
+ { "path": "./exec" },
+ { "path": "./compositeExec" },
+ ],
+}
+//// [/user/username/projects/temp/temp.ts] *new*
+let x = 10
+//// [/user/username/projects/temp/tsconfig.json] *new*
+{}
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/container/compositeExec/index.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import { myConst } from \"../lib\";\nexport function getMyConst() {\n return myConst;\n}"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/container/compositeExec/tsconfig.json] *new*
+ /user/username/projects/container/lib/index.ts
+ /user/username/projects/container/compositeExec/index.ts
+ [/user/username/projects/container/tsconfig.json] *new*
+Open Files::
+ [/user/username/projects/container/compositeExec/index.ts] *new*
+ /user/username/projects/container/compositeExec/tsconfig.json (default)
+Config::
+ [/user/username/projects/container/compositeExec/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/container/compositeexec/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/container/compositeexec/index.ts
+ [/user/username/projects/container/lib/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/container/compositeexec/tsconfig.json
+Config File Names::
+ [/user/username/projects/container/compositeexec/index.ts] *new*
+ NearestConfigFileName: /user/username/projects/container/compositeExec/tsconfig.json
+ Ancestors:
+ /user/username/projects/container/compositeExec/tsconfig.json /user/username/projects/container/tsconfig.json
+ /user/username/projects/container/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/temp/temp.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "let x = 10"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/container/compositeExec/tsconfig.json]
+ /user/username/projects/container/lib/index.ts
+ /user/username/projects/container/compositeExec/index.ts
+ [/user/username/projects/container/tsconfig.json]
+ [/user/username/projects/temp/tsconfig.json] *new*
+ /user/username/projects/temp/temp.ts
+Open Files::
+ [/user/username/projects/container/compositeExec/index.ts]
+ /user/username/projects/container/compositeExec/tsconfig.json (default)
+ [/user/username/projects/temp/temp.ts] *new*
+ /user/username/projects/temp/tsconfig.json (default)
+Config::
+ [/user/username/projects/container/compositeExec/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/container/compositeexec/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/container/compositeexec/index.ts
+ [/user/username/projects/container/lib/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/container/compositeexec/tsconfig.json
+ [/user/username/projects/temp/tsconfig.json] *new*
+ RetainingProjects:
+ /user/username/projects/temp/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/temp/temp.ts
+Config File Names::
+ [/user/username/projects/container/compositeexec/index.ts]
+ NearestConfigFileName: /user/username/projects/container/compositeExec/tsconfig.json
+ Ancestors:
+ /user/username/projects/container/compositeExec/tsconfig.json /user/username/projects/container/tsconfig.json
+ /user/username/projects/container/tsconfig.json
+ [/user/username/projects/temp/temp.ts] *new*
+ NearestConfigFileName: /user/username/projects/temp/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/container/compositeExec/index.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 9
+ },
+ "newName": "?"
+ }
+}
+// === /user/username/projects/container/compositeExec/index.ts ===
+// import { /*START PREFIX*/myConst as /*RENAME*/[|myConstRENAME|] } from "../lib";
+// export function getMyConst() {
+// return [|myConstRENAME|];
+// }
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/temp/temp.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/container/compositeExec/index.ts]
+ /user/username/projects/container/compositeExec/tsconfig.json (default)
+ [/user/username/projects/temp/temp.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/temp/temp.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "let x = 10"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/container/compositeExec/index.ts]
+ /user/username/projects/container/compositeExec/tsconfig.json (default)
+ [/user/username/projects/temp/temp.ts] *new*
+ /user/username/projects/temp/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/container/compositeExec/index.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/container/compositeExec/index.ts] *closed*
+ [/user/username/projects/temp/temp.ts]
+ /user/username/projects/temp/tsconfig.json (default)
+{
+ "method": "textDocument/didClose",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/temp/temp.ts"
+ }
+ }
+}
+Open Files::
+ [/user/username/projects/temp/temp.ts] *closed*
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///user/username/projects/temp/temp.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "let x = 10"
+ }
+ }
+}
+Projects::
+ [/user/username/projects/container/compositeExec/tsconfig.json] *deleted*
+ /user/username/projects/container/lib/index.ts
+ /user/username/projects/container/compositeExec/index.ts
+ [/user/username/projects/container/tsconfig.json] *deleted*
+ [/user/username/projects/temp/tsconfig.json]
+ /user/username/projects/temp/temp.ts
+Open Files::
+ [/user/username/projects/temp/temp.ts] *new*
+ /user/username/projects/temp/tsconfig.json (default)
+Config::
+ [/user/username/projects/container/compositeExec/tsconfig.json] *deleted*
+ [/user/username/projects/container/lib/tsconfig.json] *deleted*
+ [/user/username/projects/temp/tsconfig.json]
+ RetainingProjects:
+ /user/username/projects/temp/tsconfig.json
+ RetainingOpenFiles:
+ /user/username/projects/temp/temp.ts
+Config File Names::
+ [/user/username/projects/container/compositeexec/index.ts] *deleted*
+ [/user/username/projects/temp/temp.ts]
+ NearestConfigFileName: /user/username/projects/temp/tsconfig.json
diff --git a/testdata/baselines/reference/lspservertests/rename/rename-in-common-file-renames-all-project.js b/testdata/baselines/reference/lspservertests/rename/rename-in-common-file-renames-all-project.js
new file mode 100644
index 0000000000..07eea90bc4
--- /dev/null
+++ b/testdata/baselines/reference/lspservertests/rename/rename-in-common-file-renames-all-project.js
@@ -0,0 +1,181 @@
+UseCaseSensitiveFileNames: false
+//// [/users/username/projects/a/a.ts] *new*
+import {C} from "./c/fc";
+console.log(C)
+//// [/users/username/projects/a/c] -> /users/username/projects/c *new*
+//// [/users/username/projects/a/tsconfig.json] *new*
+{}
+//// [/users/username/projects/b/b.ts] *new*
+import {C} from "../c/fc";
+console.log(C)
+//// [/users/username/projects/b/c] -> /users/username/projects/c *new*
+//// [/users/username/projects/b/tsconfig.json] *new*
+{}
+//// [/users/username/projects/c/fc.ts] *new*
+export const C = 42;
+
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///users/username/projects/a/a.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import {C} from \"./c/fc\";\nconsole.log(C)"
+ }
+ }
+}
+Projects::
+ [/users/username/projects/a/tsconfig.json] *new*
+ /users/username/projects/a/c/fc.ts
+ /users/username/projects/a/a.ts
+Open Files::
+ [/users/username/projects/a/a.ts] *new*
+ /users/username/projects/a/tsconfig.json (default)
+Config::
+ [/users/username/projects/a/tsconfig.json] *new*
+ RetainingProjects:
+ /users/username/projects/a/tsconfig.json
+ RetainingOpenFiles:
+ /users/username/projects/a/a.ts
+Config File Names::
+ [/users/username/projects/a/a.ts] *new*
+ NearestConfigFileName: /users/username/projects/a/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///users/username/projects/b/b.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "import {C} from \"../c/fc\";\nconsole.log(C)"
+ }
+ }
+}
+Projects::
+ [/users/username/projects/a/tsconfig.json]
+ /users/username/projects/a/c/fc.ts
+ /users/username/projects/a/a.ts
+ [/users/username/projects/b/tsconfig.json] *new*
+ /users/username/projects/c/fc.ts
+ /users/username/projects/b/b.ts
+ /users/username/projects/b/c/fc.ts
+Open Files::
+ [/users/username/projects/a/a.ts]
+ /users/username/projects/a/tsconfig.json (default)
+ [/users/username/projects/b/b.ts] *new*
+ /users/username/projects/b/tsconfig.json (default)
+Config::
+ [/users/username/projects/a/tsconfig.json]
+ RetainingProjects:
+ /users/username/projects/a/tsconfig.json
+ RetainingOpenFiles:
+ /users/username/projects/a/a.ts
+ [/users/username/projects/b/tsconfig.json] *new*
+ RetainingProjects:
+ /users/username/projects/b/tsconfig.json
+ RetainingOpenFiles:
+ /users/username/projects/b/b.ts
+Config File Names::
+ [/users/username/projects/a/a.ts]
+ NearestConfigFileName: /users/username/projects/a/tsconfig.json
+ [/users/username/projects/b/b.ts] *new*
+ NearestConfigFileName: /users/username/projects/b/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///users/username/projects/a/c/fc.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const C = 42;"
+ }
+ }
+}
+Open Files::
+ [/users/username/projects/a/a.ts]
+ /users/username/projects/a/tsconfig.json (default)
+ [/users/username/projects/a/c/fc.ts] *new*
+ /users/username/projects/a/tsconfig.json (default)
+ [/users/username/projects/b/b.ts]
+ /users/username/projects/b/tsconfig.json (default)
+Config::
+ [/users/username/projects/a/tsconfig.json] *modified*
+ RetainingProjects:
+ /users/username/projects/a/tsconfig.json
+ RetainingOpenFiles: *modified*
+ /users/username/projects/a/a.ts
+ /users/username/projects/a/c/fc.ts *new*
+ [/users/username/projects/b/tsconfig.json]
+ RetainingProjects:
+ /users/username/projects/b/tsconfig.json
+ RetainingOpenFiles:
+ /users/username/projects/b/b.ts
+Config File Names::
+ [/users/username/projects/a/a.ts]
+ NearestConfigFileName: /users/username/projects/a/tsconfig.json
+ [/users/username/projects/a/c/fc.ts] *new*
+ NearestConfigFileName: /users/username/projects/a/tsconfig.json
+ [/users/username/projects/b/b.ts]
+ NearestConfigFileName: /users/username/projects/b/tsconfig.json
+{
+ "method": "textDocument/didOpen",
+ "params": {
+ "textDocument": {
+ "uri": "file:///users/username/projects/b/c/fc.ts",
+ "languageId": "typescript",
+ "version": 0,
+ "text": "export const C = 42;"
+ }
+ }
+}
+Open Files::
+ [/users/username/projects/a/a.ts]
+ /users/username/projects/a/tsconfig.json (default)
+ [/users/username/projects/a/c/fc.ts]
+ /users/username/projects/a/tsconfig.json (default)
+ [/users/username/projects/b/b.ts]
+ /users/username/projects/b/tsconfig.json (default)
+ [/users/username/projects/b/c/fc.ts] *new*
+ /users/username/projects/b/tsconfig.json (default)
+Config::
+ [/users/username/projects/a/tsconfig.json]
+ RetainingProjects:
+ /users/username/projects/a/tsconfig.json
+ RetainingOpenFiles:
+ /users/username/projects/a/a.ts
+ /users/username/projects/a/c/fc.ts
+ [/users/username/projects/b/tsconfig.json] *modified*
+ RetainingProjects:
+ /users/username/projects/b/tsconfig.json
+ RetainingOpenFiles: *modified*
+ /users/username/projects/b/b.ts
+ /users/username/projects/b/c/fc.ts *new*
+Config File Names::
+ [/users/username/projects/a/a.ts]
+ NearestConfigFileName: /users/username/projects/a/tsconfig.json
+ [/users/username/projects/a/c/fc.ts]
+ NearestConfigFileName: /users/username/projects/a/tsconfig.json
+ [/users/username/projects/b/b.ts]
+ NearestConfigFileName: /users/username/projects/b/tsconfig.json
+ [/users/username/projects/b/c/fc.ts] *new*
+ NearestConfigFileName: /users/username/projects/b/tsconfig.json
+{
+ "method": "textDocument/rename",
+ "params": {
+ "textDocument": {
+ "uri": "file:///users/username/projects/a/c/fc.ts"
+ },
+ "position": {
+ "line": 0,
+ "character": 13
+ },
+ "newName": "?"
+ }
+}
+// === /users/username/projects/a/a.ts ===
+// import {[|CRENAME|]} from "./c/fc";
+// console.log([|CRENAME|])
+
+// === /users/username/projects/a/c/fc.ts ===
+// export const /*RENAME*/C = 42;
diff --git a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-23-projects-in-a-solution.js b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-23-projects-in-a-solution.js
index 623ffc3bf9..f5811f29a9 100644
--- a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-23-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-23-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-3-projects-in-a-solution.js b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-3-projects-in-a-solution.js
index 19eaec4182..7750dc3617 100644
--- a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-3-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-3-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-5-projects-in-a-solution.js b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-5-projects-in-a-solution.js
index 7e44575678..50cbed8e6b 100644
--- a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-5-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-5-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-8-projects-in-a-solution.js b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-8-projects-in-a-solution.js
index baaf20c983..34b8d6cd59 100644
--- a/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-8-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuild/projectsBuilding/when-there-are-8-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file-non-composite.js
index ebb3b8f37a..2de0d0724c 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "files": [ "src/index.ts", "src/hello.json", ],
- }
+ },
+ "files": [ "src/index.ts", "src/hello.json", ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file.js
index 6aeb39923e..4d2ffe41ee 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/files-containing-json-file.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "files": [ "src/index.ts", "src/hello.json", ],
- }
+ },
+ "files": [ "src/index.ts", "src/hello.json", ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files-non-composite.js
index a066b6fa31..a5c35c529d 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "files": [ "src/hello.json" ], "include": [ "src/**/*" ],
- }
+ },
+ "files": [ "src/hello.json" ], "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files.js
index 75c1106d57..81fcda1a8d 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-and-files.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "files": [ "src/hello.json" ], "include": [ "src/**/*" ],
- }
+ },
+ "files": [ "src/hello.json" ], "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file-non-composite.js
index b91f4bdf71..d7297ab4df 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "./index.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*", "src/**/*.json" ],
- }
+ },
+ "include": [ "src/**/*", "src/**/*.json" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file.js
index e809cb4e10..e880633a38 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-and-file-name-matches-ts-file.js
@@ -9,20 +9,20 @@ Input::
import hello from "./index.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*", "src/**/*.json" ],
- }
+ },
+ "include": [ "src/**/*", "src/**/*.json" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-non-composite.js
index 1cec780948..08c030581a 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*", "src/**/*.json" ],
- }
+ },
+ "include": [ "src/**/*", "src/**/*.json" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include.js
index dc8239edd9..9a8ea2bfa6 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-of-json-along-with-other-include.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*", "src/**/*.json" ],
- }
+ },
+ "include": [ "src/**/*", "src/**/*.json" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-non-composite.js
index 5bd9751d2b..5e9ff93637 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*" ],
- }
+ },
+ "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory-non-composite.js
index a872caddc9..bc173d2e26 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "../../hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*" ],
- }
+ },
+ "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory.js
index 8a4dc3f779..2f77989c1f 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-with-json-without-rootDir-but-outside-configDirectory.js
@@ -9,20 +9,20 @@ Input::
import hello from "../../hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*" ],
- }
+ },
+ "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir-non-composite.js
index 545fcf8cb2..eeb98c56f4 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
- "skipDefaultLibCheck": true,
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*" ],
- }
+ },
+ "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir.js
index 29840e7834..8b71bbde26 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only-without-outDir.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
- "skipDefaultLibCheck": true,
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*" ],
- }
+ },
+ "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only.js
index 75134d2b92..64344f15aa 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/include-only.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "outDir": "dist",
- "skipDefaultLibCheck": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "outDir": "dist",
+ "skipDefaultLibCheck": true,
- },
- "include": [ "src/**/*" ],
- }
+ },
+ "include": [ "src/**/*" ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: DiagnosticsPresent_OutputsGenerated
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir-non-composite.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir-non-composite.js
index a6a4b93f44..2a94e0f674 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir-non-composite.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir-non-composite.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": false,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
+{
+ "compilerOptions": {
+ "composite": false,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
- "skipDefaultLibCheck": true,
+ "skipDefaultLibCheck": true,
- },
- "files": [ "src/index.ts", "src/hello.json", ],
- }
+ },
+ "files": [ "src/index.ts", "src/hello.json", ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir.js b/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir.js
index 01b7cb87c6..91bb4a9ae1 100644
--- a/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir.js
+++ b/testdata/baselines/reference/tsbuild/resolveJsonModule/without-outDir.js
@@ -9,20 +9,20 @@ Input::
import hello from "./hello.json"
export default hello.hello
//// [/home/src/workspaces/solution/project/tsconfig.json] *new*
- {
- "compilerOptions": {
- "composite": true,
- "moduleResolution": "node",
- "module": "commonjs",
- "resolveJsonModule": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
+{
+ "compilerOptions": {
+ "composite": true,
+ "moduleResolution": "node",
+ "module": "commonjs",
+ "resolveJsonModule": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
- "skipDefaultLibCheck": true,
+ "skipDefaultLibCheck": true,
- },
- "files": [ "src/index.ts", "src/hello.json", ],
- }
+ },
+ "files": [ "src/index.ts", "src/hello.json", ],
+}
tsgo --b project --v --explainFiles --listEmittedFiles
ExitStatus:: Success
diff --git a/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-file-with-no-error-changes.js b/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-file-with-no-error-changes.js
index 100bdbf0cb..b4ce0716d8 100644
--- a/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-file-with-no-error-changes.js
+++ b/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-file-with-no-error-changes.js
@@ -2,10 +2,10 @@ currentDirectory::/user/username/projects/solution
useCaseSensitiveFileNames::true
Input::
//// [/user/username/projects/solution/app/fileWithError.ts] *new*
- export var myClassWithError = class {
- tags() { }
+export var myClassWithError = class {
+ tags() { }
- };
+};
//// [/user/username/projects/solution/app/fileWithoutError.ts] *new*
export class myClass { }
//// [/user/username/projects/solution/app/tsconfig.json] *new*
@@ -74,7 +74,7 @@ class myClass {
exports.myClass = myClass;
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo] *new*
-{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.d.ts","./fileWithError.ts","./fileWithoutError.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"d4354dbd4fafaa0ad3a5b65966837613- export var myClassWithError = class {\n tags() { }\n\n };","signature":"767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n","impliedNodeFormat":1},{"version":"181818468a51a2348d25d30b10b6b1bb-export class myClass { }","signature":"00d3ac9a4cccbf94649ca3c19d44376a-export declare class myClass {\n}\n","impliedNodeFormat":1}],"options":{"composite":true},"latestChangedDtsFile":"./fileWithoutError.d.ts"}
+{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.d.ts","./fileWithError.ts","./fileWithoutError.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"037c56906f2b733e17b4a0bfeb8ada65-export var myClassWithError = class {\n tags() { }\n\n};","signature":"767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n","impliedNodeFormat":1},{"version":"181818468a51a2348d25d30b10b6b1bb-export class myClass { }","signature":"00d3ac9a4cccbf94649ca3c19d44376a-export declare class myClass {\n}\n","impliedNodeFormat":1}],"options":{"composite":true},"latestChangedDtsFile":"./fileWithoutError.d.ts"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
{
"version": "FakeTSVersion",
@@ -110,11 +110,11 @@ exports.myClass = myClass;
},
{
"fileName": "./fileWithError.ts",
- "version": "d4354dbd4fafaa0ad3a5b65966837613- export var myClassWithError = class {\n tags() { }\n\n };",
+ "version": "037c56906f2b733e17b4a0bfeb8ada65-export var myClassWithError = class {\n tags() { }\n\n};",
"signature": "767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n",
"impliedNodeFormat": "CommonJS",
"original": {
- "version": "d4354dbd4fafaa0ad3a5b65966837613- export var myClassWithError = class {\n tags() { }\n\n };",
+ "version": "037c56906f2b733e17b4a0bfeb8ada65-export var myClassWithError = class {\n tags() { }\n\n};",
"signature": "767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n",
"impliedNodeFormat": 1
}
@@ -135,7 +135,7 @@ exports.myClass = myClass;
"composite": true
},
"latestChangedDtsFile": "./fileWithoutError.d.ts",
- "size": 1460
+ "size": 1418
}
app/tsconfig.json::
diff --git a/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-fixing-errors-only-changed-file-is-emitted.js b/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-fixing-errors-only-changed-file-is-emitted.js
index a1c5d40a3f..d9ec913ddc 100644
--- a/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-fixing-errors-only-changed-file-is-emitted.js
+++ b/testdata/baselines/reference/tsbuildWatch/programUpdates/declarationEmitErrors-introduceError-when-fixing-errors-only-changed-file-is-emitted.js
@@ -2,10 +2,10 @@ currentDirectory::/user/username/projects/solution
useCaseSensitiveFileNames::true
Input::
//// [/user/username/projects/solution/app/fileWithError.ts] *new*
- export var myClassWithError = class {
- tags() { }
+export var myClassWithError = class {
+ tags() { }
- };
+};
//// [/user/username/projects/solution/app/fileWithoutError.ts] *new*
export class myClass { }
//// [/user/username/projects/solution/app/tsconfig.json] *new*
@@ -74,7 +74,7 @@ class myClass {
exports.myClass = myClass;
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo] *new*
-{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.d.ts","./fileWithError.ts","./fileWithoutError.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"d4354dbd4fafaa0ad3a5b65966837613- export var myClassWithError = class {\n tags() { }\n\n };","signature":"767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n","impliedNodeFormat":1},{"version":"181818468a51a2348d25d30b10b6b1bb-export class myClass { }","signature":"00d3ac9a4cccbf94649ca3c19d44376a-export declare class myClass {\n}\n","impliedNodeFormat":1}],"options":{"composite":true},"latestChangedDtsFile":"./fileWithoutError.d.ts"}
+{"version":"FakeTSVersion","root":[[2,3]],"fileNames":["lib.d.ts","./fileWithError.ts","./fileWithoutError.ts"],"fileInfos":[{"version":"8859c12c614ce56ba9a18e58384a198f-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ninterface SymbolConstructor {\n (desc?: string | number): symbol;\n for(name: string): symbol;\n readonly toStringTag: symbol;\n}\ndeclare var Symbol: SymbolConstructor;\ninterface Symbol {\n readonly [Symbol.toStringTag]: string;\n}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedNodeFormat":1},{"version":"037c56906f2b733e17b4a0bfeb8ada65-export var myClassWithError = class {\n tags() { }\n\n};","signature":"767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n","impliedNodeFormat":1},{"version":"181818468a51a2348d25d30b10b6b1bb-export class myClass { }","signature":"00d3ac9a4cccbf94649ca3c19d44376a-export declare class myClass {\n}\n","impliedNodeFormat":1}],"options":{"composite":true},"latestChangedDtsFile":"./fileWithoutError.d.ts"}
//// [/user/username/projects/solution/app/tsconfig.tsbuildinfo.readable.baseline.txt] *new*
{
"version": "FakeTSVersion",
@@ -110,11 +110,11 @@ exports.myClass = myClass;
},
{
"fileName": "./fileWithError.ts",
- "version": "d4354dbd4fafaa0ad3a5b65966837613- export var myClassWithError = class {\n tags() { }\n\n };",
+ "version": "037c56906f2b733e17b4a0bfeb8ada65-export var myClassWithError = class {\n tags() { }\n\n};",
"signature": "767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n",
"impliedNodeFormat": "CommonJS",
"original": {
- "version": "d4354dbd4fafaa0ad3a5b65966837613- export var myClassWithError = class {\n tags() { }\n\n };",
+ "version": "037c56906f2b733e17b4a0bfeb8ada65-export var myClassWithError = class {\n tags() { }\n\n};",
"signature": "767d370715ef9e7e7e190b09dbf6cb11-export declare var myClassWithError: {\n new (): {\n tags(): void;\n };\n};\n",
"impliedNodeFormat": 1
}
@@ -135,7 +135,7 @@ exports.myClass = myClass;
"composite": true
},
"latestChangedDtsFile": "./fileWithoutError.d.ts",
- "size": 1460
+ "size": 1418
}
app/tsconfig.json::
diff --git a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-23-projects-in-a-solution.js b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-23-projects-in-a-solution.js
index 439e6d0f17..f15526f64c 100644
--- a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-23-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-23-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-3-projects-in-a-solution.js b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-3-projects-in-a-solution.js
index e5ed697ea6..1f77cdb780 100644
--- a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-3-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-3-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-5-projects-in-a-solution.js b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-5-projects-in-a-solution.js
index edb535d021..ac20861239 100644
--- a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-5-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-5-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-8-projects-in-a-solution.js b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-8-projects-in-a-solution.js
index 53b176f580..75a250ca94 100644
--- a/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-8-projects-in-a-solution.js
+++ b/testdata/baselines/reference/tsbuildWatch/projectsBuilding/when-there-are-8-projects-in-a-solution.js
@@ -4,10 +4,10 @@ Input::
//// [/user/username/projects/myproject/pkg0/index.ts] *new*
export const pkg0 = 0;
//// [/user/username/projects/myproject/pkg0/tsconfig.json] *new*
- {
- "compilerOptions": { "composite": true },
+{
+ "compilerOptions": { "composite": true },
- }
+}
//// [/user/username/projects/myproject/pkg1/index.ts] *new*
export const pkg1 = 1;
//// [/user/username/projects/myproject/pkg1/tsconfig.json] *new*
diff --git a/testdata/baselines/reference/tsc/declarationEmit/when-using-Windows-paths-and-uppercase-letters.js b/testdata/baselines/reference/tsc/declarationEmit/when-using-Windows-paths-and-uppercase-letters.js
index 6b382550cf..852c8a05f5 100644
--- a/testdata/baselines/reference/tsc/declarationEmit/when-using-Windows-paths-and-uppercase-letters.js
+++ b/testdata/baselines/reference/tsc/declarationEmit/when-using-Windows-paths-and-uppercase-letters.js
@@ -8,31 +8,31 @@ Input::
"main": "index.js"
}
//// [D:/Work/pkg1/src/main.ts] *new*
- import { PartialType } from './utils';
+import { PartialType } from './utils';
- class Common {}
+class Common {}
- export class Sub extends PartialType(Common) {
- id: string;
- }
+export class Sub extends PartialType(Common) {
+ id: string;
+}
//// [D:/Work/pkg1/src/utils/index.ts] *new*
- import { MyType, MyReturnType } from './type-helpers';
+import { MyType, MyReturnType } from './type-helpers';
- export function PartialType(classRef: MyType) {
- abstract class PartialClassType {
- constructor() {}
- }
+export function PartialType