Skip to content

Commit 04097f6

Browse files
Merge pull request #125 from h-joo/refactorSourceMaps
Factor out repeated code and call one from another
2 parents b7d936c + a97dfbc commit 04097f6

File tree

9 files changed

+137
-190
lines changed

9 files changed

+137
-190
lines changed

src/compiler/emitter.ts

Lines changed: 60 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import {
5757
ConstructSignatureDeclaration,
5858
contains,
5959
ContinueStatement,
60+
CoreEmitHost,
6061
createBinaryExpressionTrampoline,
6162
createDiagnosticCollection,
6263
createGetCanonicalFileName,
@@ -403,6 +404,7 @@ import {
403404
SourceFilePrologueInfo,
404405
SourceMapEmitResult,
405406
SourceMapGenerator,
407+
SourceMapOptions,
406408
SourceMapSource,
407409
SpreadAssignment,
408410
SpreadElement,
@@ -722,6 +724,62 @@ export function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName
722724
return getOutputs();
723725
}
724726

727+
/** @internal */
728+
export function getSourceMapDirectory(host: CoreEmitHost, mapOptions: SourceMapOptions, filePath: string, sourceFile: SourceFile | undefined) {
729+
if (mapOptions.sourceRoot) return host.getCommonSourceDirectory();
730+
if (mapOptions.mapRoot) {
731+
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
732+
if (sourceFile) {
733+
// For modules or multiple emit files the mapRoot will have directory structure like the sources
734+
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
735+
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
736+
}
737+
if (getRootLength(sourceMapDir) === 0) {
738+
// The relative paths are relative to the common directory
739+
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
740+
}
741+
return sourceMapDir;
742+
}
743+
return getDirectoryPath(normalizePath(filePath));
744+
}
745+
746+
/** @internal */
747+
export function getSourceMappingURL(host: CoreEmitHost, mapOptions: SourceMapOptions, sourceMapGenerator: SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: SourceFile | undefined) {
748+
if (mapOptions.inlineSourceMap) {
749+
// Encode the sourceMap into the sourceMap url
750+
const sourceMapText = sourceMapGenerator.toString();
751+
const base64SourceMapText = base64encode(sys, sourceMapText);
752+
return `data:application/json;base64,${base64SourceMapText}`;
753+
}
754+
755+
const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath)));
756+
if (mapOptions.mapRoot) {
757+
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
758+
if (sourceFile) {
759+
// For modules or multiple emit files the mapRoot will have directory structure like the sources
760+
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
761+
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
762+
}
763+
if (getRootLength(sourceMapDir) === 0) {
764+
// The relative paths are relative to the common directory
765+
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
766+
return encodeURI(
767+
getRelativePathToDirectoryOrUrl(
768+
getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
769+
combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
770+
host.getCurrentDirectory(),
771+
host.getCanonicalFileName,
772+
/*isAbsolutePathAnUrl*/ true,
773+
),
774+
);
775+
}
776+
else {
777+
return encodeURI(combinePaths(sourceMapDir, sourceMapFile));
778+
}
779+
}
780+
return encodeURI(sourceMapFile);
781+
}
782+
725783
/** @internal */
726784
export function getFirstProjectOutput(configFile: ParsedCommandLine, ignoreCase: boolean): string {
727785
if (outFile(configFile.options)) {
@@ -983,7 +1041,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
9831041
host,
9841042
getBaseFileName(normalizeSlashes(jsFilePath)),
9851043
getSourceRoot(mapOptions),
986-
getSourceMapDirectory(mapOptions, jsFilePath, sourceFile),
1044+
getSourceMapDirectory(host, mapOptions, jsFilePath, sourceFile),
9871045
mapOptions,
9881046
);
9891047
}
@@ -1005,6 +1063,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
10051063
}
10061064

10071065
const sourceMappingURL = getSourceMappingURL(
1066+
host,
10081067
mapOptions,
10091068
sourceMapGenerator,
10101069
jsFilePath,
@@ -1040,15 +1099,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
10401099
writer.clear();
10411100
}
10421101

1043-
interface SourceMapOptions {
1044-
sourceMap?: boolean;
1045-
inlineSourceMap?: boolean;
1046-
inlineSources?: boolean;
1047-
sourceRoot?: string;
1048-
mapRoot?: string;
1049-
extendedDiagnostics?: boolean;
1050-
}
1051-
10521102
function shouldEmitSourceMaps(mapOptions: SourceMapOptions, sourceFileOrBundle: SourceFile | Bundle) {
10531103
return (mapOptions.sourceMap || mapOptions.inlineSourceMap)
10541104
&& (sourceFileOrBundle.kind !== SyntaxKind.SourceFile || !fileExtensionIs(sourceFileOrBundle.fileName, Extension.Json));
@@ -1060,60 +1110,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
10601110
const sourceRoot = normalizeSlashes(mapOptions.sourceRoot || "");
10611111
return sourceRoot ? ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot;
10621112
}
1063-
1064-
function getSourceMapDirectory(mapOptions: SourceMapOptions, filePath: string, sourceFile: SourceFile | undefined) {
1065-
if (mapOptions.sourceRoot) return host.getCommonSourceDirectory();
1066-
if (mapOptions.mapRoot) {
1067-
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
1068-
if (sourceFile) {
1069-
// For modules or multiple emit files the mapRoot will have directory structure like the sources
1070-
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
1071-
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
1072-
}
1073-
if (getRootLength(sourceMapDir) === 0) {
1074-
// The relative paths are relative to the common directory
1075-
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
1076-
}
1077-
return sourceMapDir;
1078-
}
1079-
return getDirectoryPath(normalizePath(filePath));
1080-
}
1081-
1082-
function getSourceMappingURL(mapOptions: SourceMapOptions, sourceMapGenerator: SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: SourceFile | undefined) {
1083-
if (mapOptions.inlineSourceMap) {
1084-
// Encode the sourceMap into the sourceMap url
1085-
const sourceMapText = sourceMapGenerator.toString();
1086-
const base64SourceMapText = base64encode(sys, sourceMapText);
1087-
return `data:application/json;base64,${base64SourceMapText}`;
1088-
}
1089-
1090-
const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath)));
1091-
if (mapOptions.mapRoot) {
1092-
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
1093-
if (sourceFile) {
1094-
// For modules or multiple emit files the mapRoot will have directory structure like the sources
1095-
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
1096-
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
1097-
}
1098-
if (getRootLength(sourceMapDir) === 0) {
1099-
// The relative paths are relative to the common directory
1100-
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
1101-
return encodeURI(
1102-
getRelativePathToDirectoryOrUrl(
1103-
getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
1104-
combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
1105-
host.getCurrentDirectory(),
1106-
host.getCanonicalFileName,
1107-
/*isAbsolutePathAnUrl*/ true,
1108-
),
1109-
);
1110-
}
1111-
else {
1112-
return encodeURI(combinePaths(sourceMapDir, sourceMapFile));
1113-
}
1114-
}
1115-
return encodeURI(sourceMapFile);
1116-
}
11171113
}
11181114

11191115
/** @internal */

src/compiler/transformers/declarations/transpileDeclaration.ts

Lines changed: 4 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,23 @@
11
import {
2-
base64encode,
3-
combinePaths,
42
CompilerOptions,
53
createEmitDeclarationResolver,
64
createGetCanonicalFileName,
75
createPrinter,
86
createSourceMapGenerator,
97
createTextWriter,
10-
Debug,
118
Diagnostic,
12-
EmitHost,
139
ensureTrailingDirectorySeparator,
1410
getAreDeclarationMapsEnabled,
1511
getBaseFileName,
1612
getDeclarationEmitOutputFilePathWorker,
17-
getDirectoryPath,
1813
getNewLineCharacter,
19-
getRelativePathToDirectoryOrUrl,
20-
getRootLength,
21-
getSourceFilePathInNewDir,
14+
getSourceMapDirectory,
15+
getSourceMappingURL,
2216
IsolatedTransformationContext,
23-
normalizePath,
2417
normalizeSlashes,
2518
nullTransformationContext,
2619
PrinterOptions,
2720
SourceFile,
28-
SourceMapGenerator,
29-
sys,
3021
TransformationContextKind,
3122
transformDeclarations,
3223
TranspileDeclarationsOptions,
@@ -94,25 +85,6 @@ export function transpileDeclaration(sourceFile: SourceFile, transpileOptions: T
9485
diagnostics,
9586
};
9687

97-
// logic replicated from emitter.ts
98-
function getSourceMapDirectory(mapOptions: CompilerOptions, filePath: string, sourceFile: SourceFile | undefined) {
99-
if (mapOptions.sourceRoot) return emitHost.getCommonSourceDirectory();
100-
if (mapOptions.mapRoot) {
101-
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
102-
if (sourceFile) {
103-
// For modules or multiple emit files the mapRoot will have directory structure like the sources
104-
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
105-
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, emitHost as unknown as EmitHost, sourceMapDir));
106-
}
107-
if (getRootLength(sourceMapDir) === 0) {
108-
// The relative paths are relative to the common directory
109-
sourceMapDir = combinePaths(emitHost.getCommonSourceDirectory(), sourceMapDir);
110-
}
111-
return sourceMapDir;
112-
}
113-
return getDirectoryPath(normalizePath(filePath));
114-
}
115-
11688
// logic replicated from emitter.ts
11789
function getSourceMapGenerator(declarationFilePath: string, declarationMapPath: string) {
11890
if (!getAreDeclarationMapsEnabled(compilerOptions)) return;
@@ -129,11 +101,12 @@ export function transpileDeclaration(sourceFile: SourceFile, transpileOptions: T
129101
emitHost,
130102
getBaseFileName(normalizeSlashes(declarationFilePath)),
131103
sourceRoot ? ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot,
132-
getSourceMapDirectory(compilerOptions, declarationFilePath, sourceFile),
104+
getSourceMapDirectory(emitHost, compilerOptions, declarationFilePath, sourceFile),
133105
mapOptions,
134106
);
135107

136108
const sourceMappingURL = getSourceMappingURL(
109+
emitHost,
137110
mapOptions,
138111
sourceMapGenerator,
139112
declarationFilePath,
@@ -142,41 +115,4 @@ export function transpileDeclaration(sourceFile: SourceFile, transpileOptions: T
142115
);
143116
return { sourceMapGenerator, sourceMappingURL: `//# ${"sourceMappingURL"}=${sourceMappingURL}` };
144117
}
145-
146-
// logic replicated from emitter.ts
147-
function getSourceMappingURL(mapOptions: CompilerOptions, sourceMapGenerator: SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: SourceFile | undefined) {
148-
if (mapOptions.inlineSourceMap) {
149-
// Encode the sourceMap into the sourceMap url
150-
const sourceMapText = sourceMapGenerator.toString();
151-
const base64SourceMapText = base64encode(sys, sourceMapText);
152-
return `data:application/json;base64,${base64SourceMapText}`;
153-
}
154-
155-
const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath)));
156-
if (mapOptions.mapRoot) {
157-
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
158-
if (sourceFile) {
159-
// For modules or multiple emit files the mapRoot will have directory structure like the sources
160-
// So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
161-
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, emitHost as unknown as EmitHost, sourceMapDir));
162-
}
163-
if (getRootLength(sourceMapDir) === 0) {
164-
// The relative paths are relative to the common directory
165-
sourceMapDir = combinePaths(emitHost.getCommonSourceDirectory(), sourceMapDir);
166-
return encodeURI(
167-
getRelativePathToDirectoryOrUrl(
168-
getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
169-
combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
170-
emitHost.getCurrentDirectory(),
171-
emitHost.getCanonicalFileName,
172-
/*isAbsolutePathAnUrl*/ true,
173-
),
174-
);
175-
}
176-
else {
177-
return encodeURI(combinePaths(sourceMapDir, sourceMapFile));
178-
}
179-
}
180-
return encodeURI(sourceMapFile);
181-
}
182118
}

src/compiler/types.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8197,18 +8197,20 @@ export interface SourceFileMayBeEmittedHost {
81978197
getCanonicalFileName: GetCanonicalFileName;
81988198
useCaseSensitiveFileNames(): boolean;
81998199
}
8200+
/** @internal */
8201+
export interface CoreEmitHost {
8202+
getCurrentDirectory(): string;
8203+
getCommonSourceDirectory(): string;
8204+
getCanonicalFileName(fileName: string): string;
8205+
}
82008206

82018207
/** @internal */
8202-
export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolutionHost, SourceFileMayBeEmittedHost {
8208+
export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolutionHost, SourceFileMayBeEmittedHost, CoreEmitHost {
82038209
getSourceFiles(): readonly SourceFile[];
82048210
useCaseSensitiveFileNames(): boolean;
8205-
getCurrentDirectory(): string;
82068211

82078212
getLibFileFromReference(ref: FileReference): SourceFile | undefined;
82088213

8209-
getCommonSourceDirectory(): string;
8210-
getCanonicalFileName(fileName: string): string;
8211-
82128214
isEmitBlocked(emitFileName: string): boolean;
82138215

82148216
/** @deprecated */ getPrependNodes(): readonly (InputFiles | UnparsedSource)[];
@@ -9681,6 +9683,16 @@ export interface SourceMapGenerator {
96819683
toString(): string;
96829684
}
96839685

9686+
/** @internal */
9687+
export interface SourceMapOptions {
9688+
sourceMap?: boolean;
9689+
inlineSourceMap?: boolean;
9690+
inlineSources?: boolean;
9691+
sourceRoot?: string;
9692+
mapRoot?: string;
9693+
extendedDiagnostics?: boolean;
9694+
}
9695+
96849696
/** @internal */
96859697
export interface DocumentPositionMapperHost {
96869698
getSourceFileLike(fileName: string): SourceFileLike | undefined;

src/compiler/utilities.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import {
8080
ContainerFlags,
8181
contains,
8282
containsPath,
83+
CoreEmitHost,
8384
createGetCanonicalFileName,
8485
createMultiMap,
8586
createScanner,
@@ -6409,7 +6410,7 @@ export function sourceFileMayBeEmitted(sourceFile: SourceFile, host: SourceFileM
64096410
}
64106411

64116412
/** @internal */
6412-
export function getSourceFilePathInNewDir(fileName: string, host: EmitHost, newDirPath: string): string {
6413+
export function getSourceFilePathInNewDir(fileName: string, host: CoreEmitHost, newDirPath: string): string {
64136414
return getSourceFilePathInNewDirWorker(fileName, newDirPath, host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f));
64146415
}
64156416

tests/baselines/reference/isolated-declarations/auto-fixed/diff/typeFromPropertyAssignment29.d.ts.diff

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,17 +68,17 @@
6868
+typeFromPropertyAssignment29.ts(67,5): error TS9009: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.
6969
typeFromPropertyAssignment29.ts(77,14): error TS2339: Property 'prop' does not exist on type '(n: number) => string'.
7070
typeFromPropertyAssignment29.ts(78,14): error TS2339: Property 'm' does not exist on type '(n: number) => string'.
71-
typeFromPropertyAssignment29.ts(81,22): error TS2339: Property 'prop' does not exist on type '(n: number) => string'.
72-
typeFromPropertyAssignment29.ts(81,42): error TS2339: Property 'm' does not exist on type '(n: number) => string'.
71+
typeFromPropertyAssignment29.ts(81,30): error TS2339: Property 'prop' does not exist on type '(n: number) => string'.
72+
typeFromPropertyAssignment29.ts(81,50): error TS2339: Property 'm' does not exist on type '(n: number) => string'.
7373
typeFromPropertyAssignment29.ts(87,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'.
7474
typeFromPropertyAssignment29.ts(88,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'.
75-
typeFromPropertyAssignment29.ts(91,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'.
76-
typeFromPropertyAssignment29.ts(91,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'.
75+
typeFromPropertyAssignment29.ts(91,30): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'.
76+
typeFromPropertyAssignment29.ts(91,50): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'.
7777
+typeFromPropertyAssignment29.ts(94,20): error TS9011: Declaration emit for class expressions are not supported with --isolatedDeclarations.
7878
typeFromPropertyAssignment29.ts(97,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'.
7979
typeFromPropertyAssignment29.ts(98,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'.
80-
typeFromPropertyAssignment29.ts(101,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'.
81-
typeFromPropertyAssignment29.ts(101,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'.
80+
typeFromPropertyAssignment29.ts(101,30): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'.
81+
typeFromPropertyAssignment29.ts(101,50): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'.
8282

8383

8484
-==== typeFromPropertyAssignment29.ts (12 errors) ====

0 commit comments

Comments
 (0)