Map dts file to sections to write and fix from

This commit is contained in:
Sheetal Nandi 2019-02-01 20:10:31 -08:00
parent a64e5ad3f3
commit d9ead78e8c
5 changed files with 139 additions and 18 deletions

View File

@ -51,7 +51,7 @@ namespace ts {
const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath) + Extension.Dts : undefined;
const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
const buildInfoPath = jsFilePath && (options.composite || hasPrependReference(projectReferences)) ? combinePaths(getDirectoryPath(jsFilePath), infoFile) : undefined;
const buildInfoPath = outPath && (options.composite || hasPrependReference(projectReferences)) ? combinePaths(getDirectoryPath(outPath), infoFile) : undefined;
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath };
}
@ -132,7 +132,7 @@ namespace ts {
};
function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, buildInfoPath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
if (buildInfoPath && !emitOnlyDtsFiles) buildInfo = { js: [], dts: [], commonSourceDirectory: host.getCommonSourceDirectory(), sources: {} };
if (buildInfoPath) buildInfo = { js: [], dts: [], commonSourceDirectory: host.getCommonSourceDirectory(), sources: {} };
emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath, buildInfo && { sections: buildInfo.js, sources: buildInfo.sources });
emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath, buildInfo && { sections: buildInfo.dts, sources: buildInfo.sources });
// Write bundled offset information if applicable
@ -498,13 +498,19 @@ namespace ts {
buildInfo,
/*onlyOwnText*/ true
);
const optionsWithoutDeclaration = clone(config.options);
optionsWithoutDeclaration.declaration = false;
optionsWithoutDeclaration.composite = false;
const outputFiles: OutputFile[] = [];
const newBuildInfo: BuildInfo = clone(buildInfo);
let writeByteOrderMarkBuildInfo = false;
const prependNodes = createPrependNodes(config.projectReferences, getCommandLine, f => host.readFile(f));
const emitHost: EmitHost = {
getPrependNodes: () => createPrependNodes(config.projectReferences, getCommandLine, f => host.readFile(f)). concat(ownPrependInput),
getPrependNodes: () => prependNodes.concat(ownPrependInput),
getProjectReferences: () => config.projectReferences,
getCanonicalFileName: host.getCanonicalFileName,
getCommonSourceDirectory: () => buildInfo.commonSourceDirectory,
getCompilerOptions: () => config.options,
getCompilerOptions: () => optionsWithoutDeclaration,
getCurrentDirectory: () => host.getCurrentDirectory(),
getNewLine: () => host.getNewLine(),
getSourceFile: notImplemented,
@ -513,30 +519,56 @@ namespace ts {
getLibFileFromReference: notImplemented,
isSourceFileFromExternalLibrary: notImplemented,
writeFile: (name, text, writeByteOrderMark) => {
// no need to write dts file
if (fileExtensionIs(name, Extension.Dts)) return;
if (name === buildInfoPath) {
// Add dts and sources build info since we are not touching that file
const newBuildInfo = JSON.parse(text) as BuildInfo;
newBuildInfo.dts = buildInfo.dts;
newBuildInfo.sources = buildInfo.sources;
text = getBuildInfoText(newBuildInfo);
if (name !== buildInfoPath) {
outputFiles.push({ name, text, writeByteOrderMark });
}
else {
// Add dts and sources build info since we are not touching that file
const buildInfo = JSON.parse(text) as BuildInfo;
newBuildInfo.js = buildInfo.js;
writeByteOrderMarkBuildInfo = writeByteOrderMarkBuildInfo || writeByteOrderMark;
}
outputFiles.push({ name, text, writeByteOrderMark });
},
isEmitBlocked: returnFalse,
readFile: f => host.readFile(f),
fileExists: f => host.fileExists(f),
...(host.directoryExists ? { directoryExists: f => host.directoryExists!(f) } : {}),
directoryExists: host.directoryExists && (f => host.directoryExists!(f)),
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
};
// Emit js
emitFiles(
notImplementedResolver,
emitHost,
/*targetSourceFile*/ undefined,
/*emitOnlyDtsFiles*/ false,
getTransformers(config.options)
getTransformers(optionsWithoutDeclaration)
);
// Emit d.ts map
if (declarationMapText) {
emitHost.getPrependNodes = () => [createUnparsedDtsSourceFileWithPrepend(ownPrependInput, prependNodes)];
emitHost.getCompilerOptions = () => config.options;
emitHost.writeFile = (name, text, writeByteOrderMark) => {
// Same dts ignore
if (fileExtensionIs(name, Extension.Dts)) return;
if (name !== buildInfoPath) {
outputFiles.push({ name, text, writeByteOrderMark });
}
else {
// Add dts and sources build info since we are not touching that file
const buildInfo = JSON.parse(text) as BuildInfo;
newBuildInfo.dts = buildInfo.dts;
writeByteOrderMarkBuildInfo = writeByteOrderMarkBuildInfo || writeByteOrderMark;
}
};
emitFiles(
notImplementedResolver,
emitHost,
/*targetSourceFile*/ undefined,
/*emitOnlyDtsFiles*/ true
);
}
outputFiles.push({ name: buildInfoPath!, text: getBuildInfoText(newBuildInfo), writeByteOrderMark: writeByteOrderMarkBuildInfo });
console.log(JSON.stringify(outputFiles, undefined, 2));
return outputFiles;
}
@ -882,6 +914,10 @@ namespace ts {
case SyntaxKind.UnparsedSourceMapUrl:
return emitUnparsedNode(<UnparsedNode>node);
case SyntaxKind.UnparsedSectionText:
return emitUnparsedSectionText(<UnparsedSectionText>node);
// Identifiers
case SyntaxKind.Identifier:
return emitIdentifier(<Identifier>node);
@ -1391,6 +1427,7 @@ namespace ts {
// SyntaxKind.UnparsedSource
function emitUnparsedSource(unparsed: UnparsedSource) {
for (const text of unparsed.texts) {
writeLine();
emit(text);
}
}
@ -1402,6 +1439,18 @@ namespace ts {
writer.rawWrite(unparsed.parent.text.substring(unparsed.pos, unparsed.end));
}
// SyntaxKind.UnparsedSectionText
function emitUnparsedSectionText(unparsed: UnparsedSectionText) {
const pos = getTextPosWithWriteLine();
emitUnparsedNode(unparsed);
if (bundleFileInfo) {
const section = clone(unparsed.section);
section.pos = pos;
section.end = writer.getTextPos();
bundleFileInfo.sections.push(section);
}
}
//
// Identifiers
//

View File

@ -2728,6 +2728,61 @@ namespace ts {
return node;
}
/*@internal*/
export function createUnparsedDtsSourceFileWithPrepend(input: InputFiles, prepends: ReadonlyArray<InputFiles>): UnparsedSource {
Debug.assert(!!input.oldFileOfCurrentEmit);
const node = <UnparsedSource>createNode(SyntaxKind.UnparsedSource);
node.oldFileOfCurrentEmit = true;
node.fileName = Debug.assertDefined(input.declarationPath);
node.sourceMapPath = Debug.assertDefined(input.declarationMapPath);
node.text = input.declarationText;
node.sourceMapText = input.declarationMapText;
const mapOfPrepend = arrayToMap(prepends, prepend => prepend.declarationPath!, prepend => createUnparsedSourceFile(prepend, "dts"));
const texts: UnparsedSourceText[] = [];
const sections = input.buildInfo!.dts;
for (const section of sections) {
switch (section.kind) {
case BundleFileSectionKind.NoDefaultLib:
case BundleFileSectionKind.Reference:
case BundleFileSectionKind.Type:
case BundleFileSectionKind.Lib:
texts.push(createUnparsedSectionText(section, node));
break;
case BundleFileSectionKind.Prepend:
const parent = mapOfPrepend.get(section.data)!;
const sectionNode = createUnparsedSectionText(section, parent);
sectionNode.pos = parent.texts[0].pos;
sectionNode.end = last(parent.texts).end;
texts.push(sectionNode);
break;
case BundleFileSectionKind.Text:
texts.push(createUnparsedNode(section, node) as UnparsedSourceText);
break;
// Ignore
case BundleFileSectionKind.SourceMapUrl:
break;
// Should never have
case BundleFileSectionKind.Prologue:
case BundleFileSectionKind.EmitHelpers:
Debug.fail(`Dts shouldnt have section: ${JSON.stringify(section)}`);
break;
default:
Debug.assertNever(section);
}
}
node.prologues = emptyArray;
node.referencedFiles = emptyArray;
node.libReferenceDirectives = emptyArray;
node.texts = texts;
node.getLineAndCharacterOfPosition = pos => getLineAndCharacterOfPosition(node, pos);
return node;
}
function mapBundleFileSectionKindToSyntaxKind(kind: BundleFileSectionKind): SyntaxKind {
switch (kind) {
case BundleFileSectionKind.Prologue: return SyntaxKind.UnparsedPrologue;
@ -2754,6 +2809,14 @@ namespace ts {
return node;
}
function createUnparsedSectionText(section: BundleFileSection, parent: UnparsedSource) {
const node = createNode(SyntaxKind.UnparsedSectionText, section.pos, section.end) as UnparsedSectionText;
node.parent = parent;
node.data = section.data;
node.section = section;
return node;
}
export function createInputFiles(
javascriptText: string,
declarationText: string

View File

@ -214,6 +214,7 @@ namespace ts {
collectLibs(sourceFile, libs);
return sourceFile;
}
return prepend;
}));
bundle.syntheticFileReferences = [];
bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();

View File

@ -433,6 +433,7 @@ namespace ts {
UnparsedPrependText,
UnparsedText,
UnparsedSourceMapUrl,
UnparsedSectionText,
// Top-level nodes
SourceFile,
@ -2803,7 +2804,7 @@ namespace ts {
getLineAndCharacterOfPosition(pos: number): LineAndCharacter;
}
export type UnparsedSourceText = UnparsedPrependText | UnparsedText | UnparsedSourceMapUrl;
export type UnparsedSourceText = UnparsedPrependText | UnparsedText | UnparsedSourceMapUrl | UnparsedSectionText;
export type UnparsedNode = UnparsedPrologue | UnparsedSourceText;
export interface UnparsedSection extends Node {
@ -2834,6 +2835,12 @@ namespace ts {
parent: UnparsedSource;
}
export interface UnparsedSectionText extends UnparsedSection {
kind: SyntaxKind.UnparsedSectionText;
parent: UnparsedSource;
section: BundleFileSection;
}
export interface JsonSourceFile extends SourceFile {
statements: NodeArray<JsonObjectExpressionStatement>;
}
@ -5311,7 +5318,7 @@ namespace ts {
isEmitBlocked(emitFileName: string): boolean;
getPrependNodes(): ReadonlyArray<InputFiles>;
getPrependNodes(): ReadonlyArray<InputFiles | UnparsedSource>;
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
writeFile: WriteFileCallback;

View File

@ -5994,7 +5994,8 @@ namespace ts {
return node.kind === SyntaxKind.UnparsedPrologue ||
node.kind === SyntaxKind.UnparsedPrependText ||
node.kind === SyntaxKind.UnparsedText ||
node.kind === SyntaxKind.UnparsedSourceMapUrl;
node.kind === SyntaxKind.UnparsedSourceMapUrl ||
node.kind === SyntaxKind.UnparsedSectionText;
}
// JSDoc