Skip to content

Commit

Permalink
Merge pull request #125 from h-joo/refactorSourceMaps
Browse files Browse the repository at this point in the history
Factor out repeated code and call one from another
  • Loading branch information
dragomirtitian authored Jan 8, 2024
2 parents b7d936c + a97dfbc commit 04097f6
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 190 deletions.
124 changes: 60 additions & 64 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
ConstructSignatureDeclaration,
contains,
ContinueStatement,
CoreEmitHost,
createBinaryExpressionTrampoline,
createDiagnosticCollection,
createGetCanonicalFileName,
Expand Down Expand Up @@ -403,6 +404,7 @@ import {
SourceFilePrologueInfo,
SourceMapEmitResult,
SourceMapGenerator,
SourceMapOptions,
SourceMapSource,
SpreadAssignment,
SpreadElement,
Expand Down Expand Up @@ -722,6 +724,62 @@ export function getOutputFileNames(commandLine: ParsedCommandLine, inputFileName
return getOutputs();
}

/** @internal */
export function getSourceMapDirectory(host: CoreEmitHost, mapOptions: SourceMapOptions, filePath: string, sourceFile: SourceFile | undefined) {
if (mapOptions.sourceRoot) return host.getCommonSourceDirectory();
if (mapOptions.mapRoot) {
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
if (sourceFile) {
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// 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
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
}
if (getRootLength(sourceMapDir) === 0) {
// The relative paths are relative to the common directory
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
}
return sourceMapDir;
}
return getDirectoryPath(normalizePath(filePath));
}

/** @internal */
export function getSourceMappingURL(host: CoreEmitHost, mapOptions: SourceMapOptions, sourceMapGenerator: SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: SourceFile | undefined) {
if (mapOptions.inlineSourceMap) {
// Encode the sourceMap into the sourceMap url
const sourceMapText = sourceMapGenerator.toString();
const base64SourceMapText = base64encode(sys, sourceMapText);
return `data:application/json;base64,${base64SourceMapText}`;
}

const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath)));
if (mapOptions.mapRoot) {
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
if (sourceFile) {
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// 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
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
}
if (getRootLength(sourceMapDir) === 0) {
// The relative paths are relative to the common directory
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
return encodeURI(
getRelativePathToDirectoryOrUrl(
getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
host.getCurrentDirectory(),
host.getCanonicalFileName,
/*isAbsolutePathAnUrl*/ true,
),
);
}
else {
return encodeURI(combinePaths(sourceMapDir, sourceMapFile));
}
}
return encodeURI(sourceMapFile);
}

/** @internal */
export function getFirstProjectOutput(configFile: ParsedCommandLine, ignoreCase: boolean): string {
if (outFile(configFile.options)) {
Expand Down Expand Up @@ -983,7 +1041,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
host,
getBaseFileName(normalizeSlashes(jsFilePath)),
getSourceRoot(mapOptions),
getSourceMapDirectory(mapOptions, jsFilePath, sourceFile),
getSourceMapDirectory(host, mapOptions, jsFilePath, sourceFile),
mapOptions,
);
}
Expand All @@ -1005,6 +1063,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
}

const sourceMappingURL = getSourceMappingURL(
host,
mapOptions,
sourceMapGenerator,
jsFilePath,
Expand Down Expand Up @@ -1040,15 +1099,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
writer.clear();
}

interface SourceMapOptions {
sourceMap?: boolean;
inlineSourceMap?: boolean;
inlineSources?: boolean;
sourceRoot?: string;
mapRoot?: string;
extendedDiagnostics?: boolean;
}

function shouldEmitSourceMaps(mapOptions: SourceMapOptions, sourceFileOrBundle: SourceFile | Bundle) {
return (mapOptions.sourceMap || mapOptions.inlineSourceMap)
&& (sourceFileOrBundle.kind !== SyntaxKind.SourceFile || !fileExtensionIs(sourceFileOrBundle.fileName, Extension.Json));
Expand All @@ -1060,60 +1110,6 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
const sourceRoot = normalizeSlashes(mapOptions.sourceRoot || "");
return sourceRoot ? ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot;
}

function getSourceMapDirectory(mapOptions: SourceMapOptions, filePath: string, sourceFile: SourceFile | undefined) {
if (mapOptions.sourceRoot) return host.getCommonSourceDirectory();
if (mapOptions.mapRoot) {
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
if (sourceFile) {
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// 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
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
}
if (getRootLength(sourceMapDir) === 0) {
// The relative paths are relative to the common directory
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
}
return sourceMapDir;
}
return getDirectoryPath(normalizePath(filePath));
}

function getSourceMappingURL(mapOptions: SourceMapOptions, sourceMapGenerator: SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: SourceFile | undefined) {
if (mapOptions.inlineSourceMap) {
// Encode the sourceMap into the sourceMap url
const sourceMapText = sourceMapGenerator.toString();
const base64SourceMapText = base64encode(sys, sourceMapText);
return `data:application/json;base64,${base64SourceMapText}`;
}

const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath)));
if (mapOptions.mapRoot) {
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
if (sourceFile) {
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// 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
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, host, sourceMapDir));
}
if (getRootLength(sourceMapDir) === 0) {
// The relative paths are relative to the common directory
sourceMapDir = combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
return encodeURI(
getRelativePathToDirectoryOrUrl(
getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
host.getCurrentDirectory(),
host.getCanonicalFileName,
/*isAbsolutePathAnUrl*/ true,
),
);
}
else {
return encodeURI(combinePaths(sourceMapDir, sourceMapFile));
}
}
return encodeURI(sourceMapFile);
}
}

/** @internal */
Expand Down
72 changes: 4 additions & 68 deletions src/compiler/transformers/declarations/transpileDeclaration.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,23 @@
import {
base64encode,
combinePaths,
CompilerOptions,
createEmitDeclarationResolver,
createGetCanonicalFileName,
createPrinter,
createSourceMapGenerator,
createTextWriter,
Debug,
Diagnostic,
EmitHost,
ensureTrailingDirectorySeparator,
getAreDeclarationMapsEnabled,
getBaseFileName,
getDeclarationEmitOutputFilePathWorker,
getDirectoryPath,
getNewLineCharacter,
getRelativePathToDirectoryOrUrl,
getRootLength,
getSourceFilePathInNewDir,
getSourceMapDirectory,
getSourceMappingURL,
IsolatedTransformationContext,
normalizePath,
normalizeSlashes,
nullTransformationContext,
PrinterOptions,
SourceFile,
SourceMapGenerator,
sys,
TransformationContextKind,
transformDeclarations,
TranspileDeclarationsOptions,
Expand Down Expand Up @@ -94,25 +85,6 @@ export function transpileDeclaration(sourceFile: SourceFile, transpileOptions: T
diagnostics,
};

// logic replicated from emitter.ts
function getSourceMapDirectory(mapOptions: CompilerOptions, filePath: string, sourceFile: SourceFile | undefined) {
if (mapOptions.sourceRoot) return emitHost.getCommonSourceDirectory();
if (mapOptions.mapRoot) {
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
if (sourceFile) {
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// 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
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, emitHost as unknown as EmitHost, sourceMapDir));
}
if (getRootLength(sourceMapDir) === 0) {
// The relative paths are relative to the common directory
sourceMapDir = combinePaths(emitHost.getCommonSourceDirectory(), sourceMapDir);
}
return sourceMapDir;
}
return getDirectoryPath(normalizePath(filePath));
}

// logic replicated from emitter.ts
function getSourceMapGenerator(declarationFilePath: string, declarationMapPath: string) {
if (!getAreDeclarationMapsEnabled(compilerOptions)) return;
Expand All @@ -129,11 +101,12 @@ export function transpileDeclaration(sourceFile: SourceFile, transpileOptions: T
emitHost,
getBaseFileName(normalizeSlashes(declarationFilePath)),
sourceRoot ? ensureTrailingDirectorySeparator(sourceRoot) : sourceRoot,
getSourceMapDirectory(compilerOptions, declarationFilePath, sourceFile),
getSourceMapDirectory(emitHost, compilerOptions, declarationFilePath, sourceFile),
mapOptions,
);

const sourceMappingURL = getSourceMappingURL(
emitHost,
mapOptions,
sourceMapGenerator,
declarationFilePath,
Expand All @@ -142,41 +115,4 @@ export function transpileDeclaration(sourceFile: SourceFile, transpileOptions: T
);
return { sourceMapGenerator, sourceMappingURL: `//# ${"sourceMappingURL"}=${sourceMappingURL}` };
}

// logic replicated from emitter.ts
function getSourceMappingURL(mapOptions: CompilerOptions, sourceMapGenerator: SourceMapGenerator, filePath: string, sourceMapFilePath: string | undefined, sourceFile: SourceFile | undefined) {
if (mapOptions.inlineSourceMap) {
// Encode the sourceMap into the sourceMap url
const sourceMapText = sourceMapGenerator.toString();
const base64SourceMapText = base64encode(sys, sourceMapText);
return `data:application/json;base64,${base64SourceMapText}`;
}

const sourceMapFile = getBaseFileName(normalizeSlashes(Debug.checkDefined(sourceMapFilePath)));
if (mapOptions.mapRoot) {
let sourceMapDir = normalizeSlashes(mapOptions.mapRoot);
if (sourceFile) {
// For modules or multiple emit files the mapRoot will have directory structure like the sources
// 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
sourceMapDir = getDirectoryPath(getSourceFilePathInNewDir(sourceFile.fileName, emitHost as unknown as EmitHost, sourceMapDir));
}
if (getRootLength(sourceMapDir) === 0) {
// The relative paths are relative to the common directory
sourceMapDir = combinePaths(emitHost.getCommonSourceDirectory(), sourceMapDir);
return encodeURI(
getRelativePathToDirectoryOrUrl(
getDirectoryPath(normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath
combinePaths(sourceMapDir, sourceMapFile), // this is where user expects to see sourceMap
emitHost.getCurrentDirectory(),
emitHost.getCanonicalFileName,
/*isAbsolutePathAnUrl*/ true,
),
);
}
else {
return encodeURI(combinePaths(sourceMapDir, sourceMapFile));
}
}
return encodeURI(sourceMapFile);
}
}
22 changes: 17 additions & 5 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8197,18 +8197,20 @@ export interface SourceFileMayBeEmittedHost {
getCanonicalFileName: GetCanonicalFileName;
useCaseSensitiveFileNames(): boolean;
}
/** @internal */
export interface CoreEmitHost {
getCurrentDirectory(): string;
getCommonSourceDirectory(): string;
getCanonicalFileName(fileName: string): string;
}

/** @internal */
export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolutionHost, SourceFileMayBeEmittedHost {
export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolutionHost, SourceFileMayBeEmittedHost, CoreEmitHost {
getSourceFiles(): readonly SourceFile[];
useCaseSensitiveFileNames(): boolean;
getCurrentDirectory(): string;

getLibFileFromReference(ref: FileReference): SourceFile | undefined;

getCommonSourceDirectory(): string;
getCanonicalFileName(fileName: string): string;

isEmitBlocked(emitFileName: string): boolean;

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

/** @internal */
export interface SourceMapOptions {
sourceMap?: boolean;
inlineSourceMap?: boolean;
inlineSources?: boolean;
sourceRoot?: string;
mapRoot?: string;
extendedDiagnostics?: boolean;
}

/** @internal */
export interface DocumentPositionMapperHost {
getSourceFileLike(fileName: string): SourceFileLike | undefined;
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import {
ContainerFlags,
contains,
containsPath,
CoreEmitHost,
createGetCanonicalFileName,
createMultiMap,
createScanner,
Expand Down Expand Up @@ -6409,7 +6410,7 @@ export function sourceFileMayBeEmitted(sourceFile: SourceFile, host: SourceFileM
}

/** @internal */
export function getSourceFilePathInNewDir(fileName: string, host: EmitHost, newDirPath: string): string {
export function getSourceFilePathInNewDir(fileName: string, host: CoreEmitHost, newDirPath: string): string {
return getSourceFilePathInNewDirWorker(fileName, newDirPath, host.getCurrentDirectory(), host.getCommonSourceDirectory(), f => host.getCanonicalFileName(f));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@
+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.
typeFromPropertyAssignment29.ts(77,14): error TS2339: Property 'prop' does not exist on type '(n: number) => string'.
typeFromPropertyAssignment29.ts(78,14): error TS2339: Property 'm' does not exist on type '(n: number) => string'.
typeFromPropertyAssignment29.ts(81,22): error TS2339: Property 'prop' does not exist on type '(n: number) => string'.
typeFromPropertyAssignment29.ts(81,42): error TS2339: Property 'm' does not exist on type '(n: number) => string'.
typeFromPropertyAssignment29.ts(81,30): error TS2339: Property 'prop' does not exist on type '(n: number) => string'.
typeFromPropertyAssignment29.ts(81,50): error TS2339: Property 'm' does not exist on type '(n: number) => string'.
typeFromPropertyAssignment29.ts(87,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'.
typeFromPropertyAssignment29.ts(88,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'.
typeFromPropertyAssignment29.ts(91,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'.
typeFromPropertyAssignment29.ts(91,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'.
typeFromPropertyAssignment29.ts(91,30): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoClass'.
typeFromPropertyAssignment29.ts(91,50): error TS2339: Property 'm' does not exist on type 'typeof ExpandoClass'.
+typeFromPropertyAssignment29.ts(94,20): error TS9011: Declaration emit for class expressions are not supported with --isolatedDeclarations.
typeFromPropertyAssignment29.ts(97,14): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'.
typeFromPropertyAssignment29.ts(98,14): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'.
typeFromPropertyAssignment29.ts(101,22): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'.
typeFromPropertyAssignment29.ts(101,42): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'.
typeFromPropertyAssignment29.ts(101,30): error TS2339: Property 'prop' does not exist on type 'typeof ExpandoExpr3'.
typeFromPropertyAssignment29.ts(101,50): error TS2339: Property 'm' does not exist on type 'typeof ExpandoExpr3'.


-==== typeFromPropertyAssignment29.ts (12 errors) ====
Expand Down
Loading

0 comments on commit 04097f6

Please sign in to comment.