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

Commit0684152

Browse files
authored
If module exports const enum, invalidate js files along with dts as it can impact js emit as well (microsoft#58594)
1 parent6f72e24 commit0684152

8 files changed

+3942
-31
lines changed

‎src/compiler/builder.ts

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import {
5050
getOptionsNameMap,
5151
getOwnKeys,
5252
getRelativePathFromDirectory,
53+
getSourceFileOfNode,
5354
getTsBuildInfoEmitOutputFilePath,
5455
handleNoEmitOptions,
5556
HostForComputeHash,
@@ -74,10 +75,13 @@ import {
7475
sameMap,
7576
SemanticDiagnosticsBuilderProgram,
7677
SignatureInfo,
78+
skipAlias,
7779
skipTypeChecking,
80+
some,
7881
SourceFile,
7982
sourceFileMayBeEmitted,
8083
SourceMapEmitResult,
84+
SymbolFlags,
8185
toPath,
8286
tryAddToSet,
8387
WriteFileCallback,
@@ -762,6 +766,7 @@ function handleDtsMayChangeOfAffectedFile(
762766
functionhandleDtsMayChangeOf(
763767
state:BuilderProgramState,
764768
path:Path,
769+
invalidateJsFiles:boolean,
765770
cancellationToken:CancellationToken|undefined,
766771
host:BuilderProgramHost,
767772
):void{
@@ -785,7 +790,10 @@ function handleDtsMayChangeOf(
785790
/*useFileVersionAsSignature*/true,
786791
);
787792
// If not dts emit, nothing more to do
788-
if(getEmitDeclarations(state.compilerOptions)){
793+
if(invalidateJsFiles){
794+
addToAffectedFilesPendingEmit(state,path,getBuilderFileEmit(state.compilerOptions));
795+
}
796+
elseif(getEmitDeclarations(state.compilerOptions)){
789797
addToAffectedFilesPendingEmit(state,path,state.compilerOptions.declarationMap ?BuilderFileEmit.AllDts :BuilderFileEmit.Dts);
790798
}
791799
}
@@ -814,6 +822,7 @@ function isChangedSignature(state: BuilderProgramState, path: Path) {
814822
functionhandleDtsMayChangeOfGlobalScope(
815823
state:BuilderProgramState,
816824
filePath:Path,
825+
invalidateJsFiles:boolean,
817826
cancellationToken:CancellationToken|undefined,
818827
host:BuilderProgramHost,
819828
):boolean{
@@ -824,6 +833,7 @@ function handleDtsMayChangeOfGlobalScope(
824833
handleDtsMayChangeOf(
825834
state,
826835
file.resolvedPath,
836+
invalidateJsFiles,
827837
cancellationToken,
828838
host,
829839
)
@@ -856,8 +866,16 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
856866
constcurrentPath=queue.pop()!;
857867
if(!seenFileNamesMap.has(currentPath)){
858868
seenFileNamesMap.set(currentPath,true);
859-
if(handleDtsMayChangeOfGlobalScope(state,currentPath,cancellationToken,host))return;
860-
handleDtsMayChangeOf(state,currentPath,cancellationToken,host);
869+
if(
870+
handleDtsMayChangeOfGlobalScope(
871+
state,
872+
currentPath,
873+
/*invalidateJsFiles*/false,
874+
cancellationToken,
875+
host,
876+
)
877+
)return;
878+
handleDtsMayChangeOf(state,currentPath,/*invalidateJsFiles*/false,cancellationToken,host);
861879
if(isChangedSignature(state,currentPath)){
862880
constcurrentSourceFile=Debug.checkDefined(state.program).getSourceFileByPath(currentPath)!;
863881
queue.push(...BuilderState.getReferencedByPaths(state,currentSourceFile.resolvedPath));
@@ -867,14 +885,26 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
867885
}
868886

869887
constseenFileAndExportsOfFile=newSet<string>();
888+
// If exported const enum, we need to ensure that js files are emitted as well since the const enum value changed
889+
constinvalidateJsFiles=!!affectedFile.symbol?.exports&&!!forEachEntry(
890+
affectedFile.symbol.exports,
891+
exported=>{
892+
if((exported.flags&SymbolFlags.ConstEnum)!==0)returntrue;
893+
constaliased=skipAlias(exported,state.program!.getTypeChecker());
894+
if(aliased===exported)returnfalse;
895+
return(aliased.flags&SymbolFlags.ConstEnum)!==0&&
896+
some(aliased.declarations,d=>getSourceFileOfNode(d)===affectedFile);
897+
},
898+
);
870899
// Go through files that reference affected file and handle dts emit and semantic diagnostics for them and their references
871900
state.referencedMap.getKeys(affectedFile.resolvedPath)?.forEach(exportedFromPath=>{
872-
if(handleDtsMayChangeOfGlobalScope(state,exportedFromPath,cancellationToken,host))returntrue;
901+
if(handleDtsMayChangeOfGlobalScope(state,exportedFromPath,invalidateJsFiles,cancellationToken,host))returntrue;
873902
constreferences=state.referencedMap!.getKeys(exportedFromPath);
874903
returnreferences&&forEachKey(references,filePath=>
875904
handleDtsMayChangeOfFileAndExportsOfFile(
876905
state,
877906
filePath,
907+
invalidateJsFiles,
878908
seenFileAndExportsOfFile,
879909
cancellationToken,
880910
host,
@@ -889,20 +919,22 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
889919
functionhandleDtsMayChangeOfFileAndExportsOfFile(
890920
state:BuilderProgramState,
891921
filePath:Path,
922+
invalidateJsFiles:boolean,
892923
seenFileAndExportsOfFile:Set<string>,
893924
cancellationToken:CancellationToken|undefined,
894925
host:BuilderProgramHost,
895926
):boolean|undefined{
896927
if(!tryAddToSet(seenFileAndExportsOfFile,filePath))returnundefined;
897928

898-
if(handleDtsMayChangeOfGlobalScope(state,filePath,cancellationToken,host))returntrue;
899-
handleDtsMayChangeOf(state,filePath,cancellationToken,host);
929+
if(handleDtsMayChangeOfGlobalScope(state,filePath,invalidateJsFiles,cancellationToken,host))returntrue;
930+
handleDtsMayChangeOf(state,filePath,invalidateJsFiles,cancellationToken,host);
900931

901932
// Remove the diagnostics of files that import this file and handle all its exports too
902933
state.referencedMap!.getKeys(filePath)?.forEach(referencingFilePath=>
903934
handleDtsMayChangeOfFileAndExportsOfFile(
904935
state,
905936
referencingFilePath,
937+
invalidateJsFiles,
906938
seenFileAndExportsOfFile,
907939
cancellationToken,
908940
host,

‎src/testRunner/unittests/tsc/incremental.ts

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import*astsfrom"../../_namespaces/ts.js";
2-
import*asUtilsfrom"../../_namespaces/Utils.js";
3-
import*asvfsfrom"../../_namespaces/vfs.js";
2+
import{dedent}from"../../_namespaces/Utils.js";
3+
import{FileSystem}from"../../_namespaces/vfs.js";
44
import{jsonToReadableText}from"../helpers.js";
55
import{
66
compilerOptionsToConfigJson,
@@ -27,7 +27,7 @@ describe("unittests:: tsc:: incremental::", () => {
2727
fs:()=>
2828
loadProjectFromFiles({
2929
"/src/project/src/main.ts":"export const x = 10;",
30-
"/src/project/tsconfig.json":Utils.dedent`
30+
"/src/project/tsconfig.json":dedent`
3131
{
3232
"compilerOptions": {
3333
"target": "es5",
@@ -48,7 +48,7 @@ describe("unittests:: tsc:: incremental::", () => {
4848
fs:()=>
4949
loadProjectFromFiles({
5050
"/src/project/src/main.ts":"export const x = 10;",
51-
"/src/project/tsconfig.json":Utils.dedent`
51+
"/src/project/tsconfig.json":dedent`
5252
{
5353
"compilerOptions": {
5454
"incremental": true,
@@ -85,7 +85,7 @@ describe("unittests:: tsc:: incremental::", () => {
8585
fs:()=>
8686
loadProjectFromFiles({
8787
"/src/project/src/main.ts":"export const x = 10;",
88-
"/src/project/tsconfig.json":Utils.dedent`
88+
"/src/project/tsconfig.json":dedent`
8989
{
9090
"compilerOptions": {
9191
"incremental": true,
@@ -115,7 +115,7 @@ describe("unittests:: tsc:: incremental::", () => {
115115
});
116116

117117
describe("with noEmitOnError",()=>{
118-
letprojFs:vfs.FileSystem;
118+
letprojFs:FileSystem;
119119
before(()=>{
120120
projFs=getFsForNoEmitOnError();
121121
});
@@ -275,25 +275,25 @@ const a: string = 10;`,
275275

276276
functionfs(){
277277
returnloadProjectFromFiles({
278-
"/src/project/src/class.ts":Utils.dedent`
278+
"/src/project/src/class.ts":dedent`
279279
export class classC {
280280
prop = 1;
281281
}`,
282-
"/src/project/src/indirectClass.ts":Utils.dedent`
282+
"/src/project/src/indirectClass.ts":dedent`
283283
import { classC } from './class';
284284
export class indirectClass {
285285
classC = new classC();
286286
}`,
287-
"/src/project/src/directUse.ts":Utils.dedent`
287+
"/src/project/src/directUse.ts":dedent`
288288
import { indirectClass } from './indirectClass';
289289
new indirectClass().classC.prop;`,
290-
"/src/project/src/indirectUse.ts":Utils.dedent`
290+
"/src/project/src/indirectUse.ts":dedent`
291291
import { indirectClass } from './indirectClass';
292292
new indirectClass().classC.prop;`,
293-
"/src/project/src/noChangeFile.ts":Utils.dedent`
293+
"/src/project/src/noChangeFile.ts":dedent`
294294
export function writeLog(s: string) {
295295
}`,
296-
"/src/project/src/noChangeFileWithEmitSpecificError.ts":Utils.dedent`
296+
"/src/project/src/noChangeFileWithEmitSpecificError.ts":dedent`
297297
function someFunc(arguments: boolean, ...rest: any[]) {
298298
}`,
299299
"/src/project/tsconfig.json":jsonToReadableText({ compilerOptions}),
@@ -307,12 +307,12 @@ const a: string = 10;`,
307307
subScenario:`when global file is added, the signatures are updated`,
308308
fs:()=>
309309
loadProjectFromFiles({
310-
"/src/project/src/main.ts":Utils.dedent`
310+
"/src/project/src/main.ts":dedent`
311311
/// <reference path="./filePresent.ts"/>
312312
/// <reference path="./fileNotFound.ts"/>
313313
function main() { }
314314
`,
315-
"/src/project/src/anotherFileWithSameReferenes.ts":Utils.dedent`
315+
"/src/project/src/anotherFileWithSameReferenes.ts":dedent`
316316
/// <reference path="./filePresent.ts"/>
317317
/// <reference path="./fileNotFound.ts"/>
318318
function anotherFileWithSameReferenes() { }
@@ -495,7 +495,7 @@ declare global {
495495
module:"esnext",
496496
},
497497
}),
498-
"/src/project/index.tsx":Utils.dedent`
498+
"/src/project/index.tsx":dedent`
499499
declare namespace JSX {
500500
interface ElementChildrenAttribute { children: {}; }
501501
interface IntrinsicElements { div: {} }
@@ -518,7 +518,7 @@ declare global {
518518
subScenario:"ts file with no-default-lib that augments the global scope",
519519
fs:()=>
520520
loadProjectFromFiles({
521-
"/src/project/src/main.ts":Utils.dedent`
521+
"/src/project/src/main.ts":dedent`
522522
/// <reference no-default-lib="true"/>
523523
/// <reference lib="esnext" />
524524
@@ -529,7 +529,7 @@ declare global {
529529
530530
export {};
531531
`,
532-
"/src/project/tsconfig.json":Utils.dedent`
532+
"/src/project/tsconfig.json":dedent`
533533
{
534534
"compilerOptions": {
535535
"target": "ESNext",
@@ -590,12 +590,12 @@ console.log(a);`,
590590
fs:()=>
591591
loadProjectFromFiles({
592592
"/src/project/tsconfig.json":jsonToReadableText({compilerOptions:{ declaration}}),
593-
"/src/project/main.ts":Utils.dedent`
593+
"/src/project/main.ts":dedent`
594594
import MessageablePerson from './MessageablePerson.js';
595595
function logMessage( person: MessageablePerson ) {
596596
console.log( person.message );
597597
}`,
598-
"/src/project/MessageablePerson.ts":Utils.dedent`
598+
"/src/project/MessageablePerson.ts":dedent`
599599
const Messageable = () => {
600600
return class MessageableClass {
601601
public message = 'hello';
@@ -609,7 +609,7 @@ console.log(a);`,
609609
appendText(
610610
fs,
611611
"/lib/lib.d.ts",
612-
Utils.dedent`
612+
dedent`
613613
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
614614
type InstanceType<T extends abstract new (...args: any) => any> = T extends abstract new (...args: any) => infer R ? R : any;`,
615615
),
@@ -922,12 +922,12 @@ console.log(a);`,
922922
},
923923
include:["src"],
924924
}),
925-
"/src/project/src/box.ts":Utils.dedent`
925+
"/src/project/src/box.ts":dedent`
926926
export interface Box<T> {
927927
unbox(): T
928928
}
929929
`,
930-
"/src/project/src/bug.js":Utils.dedent`
930+
"/src/project/src/bug.js":dedent`
931931
import * as B from "./box.js"
932932
import * as W from "./wrap.js"
933933
@@ -947,7 +947,7 @@ console.log(a);`,
947947
948948
export const bug = wrap({ n: box(1) });
949949
`,
950-
"/src/project/src/wrap.ts":Utils.dedent`
950+
"/src/project/src/wrap.ts":dedent`
951951
export type Wrap<C> = {
952952
[K in keyof C]: { wrapped: C[K] }
953953
}
@@ -974,14 +974,14 @@ console.log(a);`,
974974
skipDefaultLibCheck:true,
975975
},
976976
}),
977-
"/src/project/index.ts":Utils.dedent`
977+
"/src/project/index.ts":dedent`
978978
import ky from 'ky';
979979
export const api = ky.extend({});
980980
`,
981981
"/src/project/package.json":jsonToReadableText({
982982
type:"module",
983983
}),
984-
"/src/project/node_modules/ky/distribution/index.d.ts":Utils.dedent`
984+
"/src/project/node_modules/ky/distribution/index.d.ts":dedent`
985985
type KyInstance = {
986986
extend(options: Record<string,unknown>): KyInstance;
987987
}
@@ -1003,4 +1003,79 @@ console.log(a);`,
10031003
},
10041004
],
10051005
});
1006+
1007+
describe("with const enums",()=>{
1008+
enumAliasType{
1009+
None="",
1010+
SameFile="aliased ",
1011+
DifferentFile="aliased in different file ",
1012+
}
1013+
functionfileWithEnum(withAlias:AliasType){
1014+
returnwithAlias!==AliasType.DifferentFile ?"/src/project/b.d.ts" :"/src/project/worker.d.ts";
1015+
}
1016+
functionverify(withAlias:AliasType,preserveConstEnums:boolean){
1017+
verifyTsc({
1018+
scenario:"incremental",
1019+
subScenario:`with${withAlias}const enums${preserveConstEnums ?" with preserveConstEnums" :""}`,
1020+
commandLineArgs:["-i",`/src/project/a.ts`,"--tsbuildinfofile","/src/project/a.tsbuildinfo", ...preserveConstEnums ?["--preserveConstEnums"] :[]],
1021+
fs:()=>
1022+
loadProjectFromFiles({
1023+
"/src/project/a.ts":dedent`
1024+
import {A} from "./c"
1025+
let a = A.ONE
1026+
`,
1027+
"/src/project/b.d.ts":withAlias===AliasType.SameFile ?
1028+
dedent`
1029+
declare const enum AWorker {
1030+
ONE = 1
1031+
}
1032+
export { AWorker as A };
1033+
` :
1034+
withAlias===AliasType.DifferentFile ?
1035+
dedent`
1036+
export { AWorker as A } from "./worker";
1037+
` :
1038+
dedent`
1039+
export const enum A {
1040+
ONE = 1
1041+
}
1042+
`,
1043+
"/src/project/c.ts":dedent`
1044+
import {A} from "./b"
1045+
let b = A.ONE
1046+
export {A}
1047+
`,
1048+
"/src/project/worker.d.ts":dedent`
1049+
export const enum AWorker {
1050+
ONE = 1
1051+
}
1052+
`,
1053+
}),
1054+
edits:[
1055+
{
1056+
caption:"change enum value",
1057+
edit:fs=>replaceText(fs,fileWithEnum(withAlias),"1","2"),
1058+
},
1059+
{
1060+
caption:"change enum value again",
1061+
edit:fs=>replaceText(fs,fileWithEnum(withAlias),"2","3"),
1062+
},
1063+
{
1064+
caption:"something else changes in b.d.ts",
1065+
edit:fs=>appendText(fs,"/src/project/b.d.ts","export const randomThing = 10;"),
1066+
},
1067+
{
1068+
caption:"something else changes in b.d.ts again",
1069+
edit:fs=>appendText(fs,"/src/project/b.d.ts","export const randomThing2 = 10;"),
1070+
},
1071+
],
1072+
});
1073+
}
1074+
verify(/*withAlias*/AliasType.None,/*preserveConstEnums*/false);
1075+
verify(/*withAlias*/AliasType.SameFile,/*preserveConstEnums*/false);
1076+
verify(/*withAlias*/AliasType.DifferentFile,/*preserveConstEnums*/false);
1077+
verify(/*withAlias*/AliasType.None,/*preserveConstEnums*/true);
1078+
verify(/*withAlias*/AliasType.SameFile,/*preserveConstEnums*/true);
1079+
verify(/*withAlias*/AliasType.DifferentFile,/*preserveConstEnums*/true);
1080+
});
10061081
});

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp