Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitba78807

Browse files
authored
Handle project / program roots in tsserver correctly (microsoft#58562)
1 parentd84431e commitba78807

10 files changed

+703
-40
lines changed

‎src/server/editorServices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2893,7 +2893,7 @@ export class ProjectService {
28932893
path=normalizedPathToPath(fileName,this.currentDirectory,this.toCanonicalFileName);
28942894
constexistingValue=projectRootFilesMap.get(path);
28952895
if(existingValue){
2896-
if(existingValue.info){
2896+
if(existingValue.info?.path===path){
28972897
project.removeFile(existingValue.info,/*fileExists*/false,/*detachFromProject*/true);
28982898
existingValue.info=undefined;
28992899
}

‎src/server/project.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ import {
8888
noopFileWatcher,
8989
normalizePath,
9090
normalizeSlashes,
91-
orderedRemoveItem,
9291
PackageJsonAutoImportPreference,
9392
PackageJsonInfo,
9493
ParsedCommandLine,
@@ -309,8 +308,7 @@ const enum TypingWatcherType {
309308
typeTypingWatchers=Map<Path,FileWatcher>&{isInvoked?:boolean;};
310309

311310
exportabstractclassProjectimplementsLanguageServiceHost,ModuleResolutionHost{
312-
privaterootFiles:ScriptInfo[]=[];
313-
privaterootFilesMap=newMap<string,ProjectRootFile>();
311+
privaterootFilesMap=newMap<Path,ProjectRootFile>();
314312
privateprogram:Program|undefined;
315313
privateexternalFiles:SortedReadonlyArray<string>|undefined;
316314
privatemissingFilesMap:Map<Path,FileWatcher>|undefined;
@@ -641,7 +639,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
641639
}
642640

643641
getScriptFileNames(){
644-
if(!this.rootFiles){
642+
if(!this.rootFilesMap.size){
645643
returnts.emptyArray;
646644
}
647645

@@ -667,7 +665,6 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
667665
constexistingValue=this.rootFilesMap.get(scriptInfo.path);
668666
if(existingValue&&existingValue.info!==scriptInfo){
669667
// This was missing path earlier but now the file exists. Update the root
670-
this.rootFiles.push(scriptInfo);
671668
existingValue.info=scriptInfo;
672669
}
673670
scriptInfo.attachToProject(this);
@@ -1079,12 +1076,9 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
10791076
// Release external files
10801077
forEach(this.externalFiles,externalFile=>this.detachScriptInfoIfNotRoot(externalFile));
10811078
// Always remove root files from the project
1082-
for(constrootofthis.rootFiles){
1083-
root.detachFromProject(this);
1084-
}
1079+
this.rootFilesMap.forEach(root=>root.info?.detachFromProject(this));
10851080
this.projectService.pendingEnsureProjectForOpenFiles=true;
10861081

1087-
this.rootFiles=undefined!;
10881082
this.rootFilesMap=undefined!;
10891083
this.externalFiles=undefined;
10901084
this.program=undefined;
@@ -1135,20 +1129,20 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
11351129
}
11361130

11371131
isClosed(){
1138-
returnthis.rootFiles===undefined;
1132+
returnthis.rootFilesMap===undefined;
11391133
}
11401134

11411135
hasRoots(){
1142-
returnthis.rootFiles&&this.rootFiles.length>0;
1136+
return!!this.rootFilesMap?.size;
11431137
}
11441138

11451139
/**@internal */
11461140
isOrphan(){
11471141
returnfalse;
11481142
}
11491143

1150-
getRootFiles(){
1151-
returnthis.rootFiles&&this.rootFiles.map(info=>info.fileName);
1144+
getRootFiles():NormalizedPath[]{
1145+
returnthis.rootFilesMap&&arrayFrom(ts.mapDefinedIterator(this.rootFilesMap.values(),value=>value.info?.fileName));
11521146
}
11531147

11541148
/**@internal */
@@ -1157,13 +1151,13 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
11571151
}
11581152

11591153
getRootScriptInfos(){
1160-
returnthis.rootFiles;
1154+
returnarrayFrom(ts.mapDefinedIterator(this.rootFilesMap.values(),value=>value.info));
11611155
}
11621156

11631157
getScriptInfos():ScriptInfo[]{
11641158
if(!this.languageServiceEnabled){
11651159
// if language service is not enabled - return just root files
1166-
returnthis.rootFiles;
1160+
returnthis.getRootScriptInfos();
11671161
}
11681162
returnmap(this.program!.getSourceFiles(),sourceFile=>{
11691163
constscriptInfo=this.projectService.getScriptInfoForPath(sourceFile.resolvedPath);
@@ -1256,13 +1250,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
12561250
}
12571251

12581252
isRoot(info:ScriptInfo){
1259-
returnthis.rootFilesMap&&this.rootFilesMap.get(info.path)?.info===info;
1253+
returnthis.rootFilesMap?.get(info.path)?.info===info;
12601254
}
12611255

12621256
// add a root file to project
12631257
addRoot(info:ScriptInfo,fileName?:NormalizedPath){
12641258
Debug.assert(!this.isRoot(info));
1265-
this.rootFiles.push(info);
12661259
this.rootFilesMap.set(info.path,{fileName:fileName||info.fileName, info});
12671260
info.attachToProject(this);
12681261

@@ -1586,6 +1579,16 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
15861579
});
15871580
}
15881581

1582+
// Update roots
1583+
this.rootFilesMap.forEach((value,path)=>{
1584+
constfile=this.program!.getSourceFileByPath(path);
1585+
constinfo=value.info;
1586+
if(!file||value.info?.path===file.resolvedPath)return;
1587+
value.info=this.projectService.getScriptInfo(file.fileName)!;
1588+
Debug.assert(value.info.isAttached(this));
1589+
info?.detachFromProject(this);
1590+
});
1591+
15891592
// Update the missing file paths watcher
15901593
updateMissingFilePathsWatch(
15911594
this.program,
@@ -2006,7 +2009,6 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo
20062009

20072010
// remove a root file from project
20082011
protectedremoveRoot(info:ScriptInfo):void{
2009-
orderedRemoveItem(this.rootFiles,info);
20102012
this.rootFilesMap.delete(info.path);
20112013
}
20122014

‎src/testRunner/unittests/tsserver/dynamicFiles.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,7 @@ describe("unittests:: tsserver:: dynamicFiles:: ", () => {
217217
}],session);
218218
}
219219
catch(e){
220-
assert.strictEqual(
221-
e.message.replace(/\r?\n/,"\n"),
222-
`Debug Failure. False expression.\nVerbose Debug Information: {"fileName":"^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js","currentDirectory":"/user/username/projects/myproject","hostCurrentDirectory":"/","openKeys":[]}\nDynamic files must always be opened with service's current directory or service should support inferred project per projectRootPath.`,
223-
);
220+
session.logger.info(e.message);
224221
}
225222
constfile2Path=file.path.replace("#1","#2");
226223
openFilesForSession([{file:file2Path,content:file.content}],session);

‎src/testRunner/unittests/tsserver/projectReferences.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import*astsfrom"../../_namespaces/ts.js";
22
import{dedent}from"../../_namespaces/Utils.js";
33
import{jsonToReadableText}from"../helpers.js";
4+
import{libContent}from"../helpers/contents.js";
45
import{solutionBuildWithBaseline}from"../helpers/solutionBuilder.js";
56
import{
67
baselineTsserverLogs,
@@ -1930,4 +1931,56 @@ const b: B = new B();`,
19301931
});
19311932
}
19321933
});
1934+
1935+
it("with dts file next to ts file",()=>{
1936+
constindexDts:File={
1937+
path:"/home/src/projects/project/src/index.d.ts",
1938+
content:dedent`
1939+
declare global {
1940+
interface Window {
1941+
electron: ElectronAPI
1942+
api: unknown
1943+
}
1944+
}
1945+
`,
1946+
};
1947+
consthost=createServerHost({
1948+
[indexDts.path]:indexDts.content,
1949+
"/home/src/projects/project/src/index.ts":dedent`
1950+
const api = {}
1951+
`,
1952+
"/home/src/projects/project/tsconfig.json":jsonToReadableText({
1953+
include:[
1954+
"src/*.d.ts",
1955+
],
1956+
references:[{path:"./tsconfig.node.json"}],
1957+
}),
1958+
"/home/src/projects/project/tsconfig.node.json":jsonToReadableText({
1959+
include:["src/**/*"],
1960+
compilerOptions:{
1961+
composite:true,
1962+
},
1963+
}),
1964+
[libFile.path]:libContent,
1965+
});
1966+
constsession=newTestSession(host);
1967+
openFilesForSession([{file:indexDts,projectRootPath:"/home/src/projects/project"}],session);
1968+
session.executeCommandSeq<ts.server.protocol.DocumentHighlightsRequest>({
1969+
command:ts.server.protocol.CommandTypes.DocumentHighlights,
1970+
arguments:{
1971+
...protocolFileLocationFromSubstring(indexDts,"global"),
1972+
filesToSearch:["/home/src/projects/project/src/index.d.ts"],
1973+
},
1974+
});
1975+
session.executeCommandSeq<ts.server.protocol.EncodedSemanticClassificationsRequest>({
1976+
command:ts.server.protocol.CommandTypes.EncodedSemanticClassificationsFull,
1977+
arguments:{
1978+
file:indexDts.path,
1979+
start:0,
1980+
length:indexDts.content.length,
1981+
format:"2020",
1982+
},
1983+
});
1984+
baselineTsserverLogs("projectReferences","with dts file next to ts file",session);
1985+
});
19331986
});

‎src/testRunner/unittests/tsserver/projects.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1416,7 +1416,7 @@ describe("unittests:: tsserver:: projects::", () => {
14161416
});
14171417
}
14181418
catch(e){
1419-
assert.isTrue(e.message.indexOf("Debug Failure. False expression: Found script Info still attached to project")===0);
1419+
session.logger.log(e.message);
14201420
}
14211421
baselineTsserverLogs("projects","assert when removing project",session);
14221422
});

‎tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2756,7 +2756,6 @@ declare namespace ts {
27562756
private compilerOptions;
27572757
compileOnSaveEnabled: boolean;
27582758
protected watchOptions: WatchOptions | undefined;
2759-
private rootFiles;
27602759
private rootFilesMap;
27612760
private program;
27622761
private externalFiles;
@@ -2837,7 +2836,7 @@ declare namespace ts {
28372836
private detachScriptInfoIfNotRoot;
28382837
isClosed(): boolean;
28392838
hasRoots(): boolean;
2840-
getRootFiles():ts.server.NormalizedPath[];
2839+
getRootFiles(): NormalizedPath[];
28412840
getRootScriptInfos(): ts.server.ScriptInfo[];
28422841
getScriptInfos(): ScriptInfo[];
28432842
getExcludedFiles(): readonly NormalizedPath[];

‎tests/baselines/reference/tsserver/dynamicFiles/dynamic-file-with-projectRootPath-fails-when-useInferredProjectPerProjectRoot-is-false.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ Info seq [hh:mm:ss:mss] request:
3232
"seq":1,
3333
"type":"request"
3434
}
35+
Infoseq[hh:mm:ss:mss]DebugFailure.Falseexpression.
36+
VerboseDebug Information:{"fileName":"^walkThroughSnippet:/Users/UserName/projects/someProject/out/someFile#1.js","currentDirectory":"/user/username/projects/myproject","hostCurrentDirectory":"/","openKeys":[]}
37+
Dynamicfilesmustalwaysbeopenedwithservice's current directory or service should support inferred project per projectRootPath.
3538
Beforerequest
3639

3740
Infoseq[hh:mm:ss:mss] request:

‎tests/baselines/reference/tsserver/projectReferences/root-file-is-file-from-referenced-project-and-using-declaration-maps.js

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ Info seq [hh:mm:ss:mss] Files (4)
701701
Infoseq[hh:mm:ss:mss]-----------------------------------------------
702702
Infoseq[hh:mm:ss:mss]Openfiles:
703703
Infoseq[hh:mm:ss:mss] FileName:/user/username/projects/project/src/common/input/keyboard.ts ProjectRootPath:undefined
704-
Infoseq[hh:mm:ss:mss] Projects:/user/username/projects/project/src/common/tsconfig.json,/user/username/projects/project/src/tsconfig.json
704+
Infoseq[hh:mm:ss:mss] Projects:/user/username/projects/project/src/common/tsconfig.json
705705
Infoseq[hh:mm:ss:mss] FileName:/user/username/projects/project/src/terminal.ts ProjectRootPath:undefined
706706
Infoseq[hh:mm:ss:mss] Projects:/user/username/projects/project/src/tsconfig.json
707707
Infoseq[hh:mm:ss:mss] response:
@@ -777,16 +777,14 @@ ScriptInfos::
777777
version:Text-1
778778
containingProjects:1
779779
/user/username/projects/project/src/tsconfig.json
780-
/user/username/projects/project/src/common/input/keyboard.test.ts*changed*
780+
/user/username/projects/project/src/common/input/keyboard.test.ts
781781
version:Text-1
782-
containingProjects:2*changed*
782+
containingProjects:1
783783
/user/username/projects/project/src/common/tsconfig.json
784-
/user/username/projects/project/src/tsconfig.json*new*
785-
/user/username/projects/project/src/common/input/keyboard.ts(Open)*changed*
784+
/user/username/projects/project/src/common/input/keyboard.ts(Open)
786785
version:SVC-1-0
787-
containingProjects:2*changed*
786+
containingProjects:1
788787
/user/username/projects/project/src/common/tsconfig.json*default*
789-
/user/username/projects/project/src/tsconfig.json*new*
790788
/user/username/projects/project/src/terminal.ts(Open)*new*
791789
version:SVC-1-0
792790
containingProjects:1
@@ -972,9 +970,8 @@ Projects::
972970
projectProgramVersion:1
973971
documentPositionMappers:1*changed*
974972
/user/username/projects/project/out/input/keyboard.d.ts:DocumentPositionMapper1*new*
975-
originalConfiguredProjects:2*changed*
973+
originalConfiguredProjects:1*changed*
976974
/user/username/projects/project/src/common/tsconfig.json*new*
977-
/user/username/projects/project/src/tsconfig.json*new*
978975

979976
ScriptInfos::
980977
/a/lib/lib.d.ts
@@ -1000,14 +997,12 @@ ScriptInfos::
1000997
/user/username/projects/project/src/tsconfig.json
1001998
/user/username/projects/project/src/common/input/keyboard.test.ts
1002999
version:Text-1
1003-
containingProjects:2
1000+
containingProjects:1
10041001
/user/username/projects/project/src/common/tsconfig.json
1005-
/user/username/projects/project/src/tsconfig.json
10061002
/user/username/projects/project/src/common/input/keyboard.ts(Open)
10071003
version:SVC-1-0
1008-
containingProjects:2
1004+
containingProjects:1
10091005
/user/username/projects/project/src/common/tsconfig.json*default*
1010-
/user/username/projects/project/src/tsconfig.json
10111006
/user/username/projects/project/src/terminal.ts(Open)
10121007
version:SVC-1-0
10131008
containingProjects:1

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp