Skip to content

Commit

Permalink
Factor out repeated code and call one from another,
Browse files Browse the repository at this point in the history
Also make the functions use the new type CoreEmitHost
to take into account of methods that are not available
from DTE mode.

Signed-off-by: Hana Joo <hanajoo@google.com>
  • Loading branch information
h-joo committed Nov 30, 2023
1 parent f2528c2 commit 87e30cc
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 138 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 @@ -402,6 +403,7 @@ import {
SourceFilePrologueInfo,
SourceMapEmitResult,
SourceMapGenerator,
SourceMapOptions,
SourceMapSource,
SpreadAssignment,
SpreadElement,
Expand Down Expand Up @@ -721,6 +723,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 @@ -982,7 +1040,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 @@ -1004,6 +1062,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
}

const sourceMappingURL = getSourceMappingURL(
host,
mapOptions,
sourceMapGenerator,
jsFilePath,
Expand Down Expand Up @@ -1039,15 +1098,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 @@ -1059,60 +1109,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,31 +1,22 @@
import {
base64encode,
combinePaths,
CompilerOptions,
createEmitDeclarationResolver,
createGetCanonicalFileName,
createPrinter,
createSourceMapGenerator,
createTextWriter,
Debug,
Diagnostic,
EmitHost,
ensureTrailingDirectorySeparator,
getAreDeclarationMapsEnabled,
getBaseFileName,
getDeclarationEmitOutputFilePathWorker,
getDirectoryPath,
getNewLineCharacter,
getRelativePathToDirectoryOrUrl,
getRootLength,
getSourceFilePathInNewDir,
normalizePath,
getSourceMapDirectory,
getSourceMappingURL,
normalizeSlashes,
nullTransformationContext,
PrinterOptions,
SourceFile,
SourceMapGenerator,
sys,
transformDeclarations,
TranspileDeclarationsOptions,
TranspileDeclarationsOutput,
Expand Down Expand Up @@ -98,25 +89,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 @@ -133,11 +105,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 @@ -146,41 +119,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 @@ -8179,18 +8179,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 @@ -9635,6 +9637,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 @@ -79,6 +79,7 @@ import {
ContainerFlags,
contains,
containsPath,
CoreEmitHost,
createGetCanonicalFileName,
createMultiMap,
createScanner,
Expand Down Expand Up @@ -6391,7 +6392,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

0 comments on commit 87e30cc

Please sign in to comment.