Merge pull request #24920 from Microsoft/vfsDiff

Add vfs diff, update tsbuild test
This commit is contained in:
Ron Buckton 2018-06-13 11:28:41 -07:00 committed by GitHub
commit 6e570e332a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 386 additions and 147 deletions

View file

@ -126,6 +126,24 @@ namespace vfs {
return this._shadowRoot;
}
/**
* Snapshots the current file system, effectively shadowing itself. This is useful for
* generating file system patches using `.diff()` from one snapshot to the next. Performs
* no action if this file system is read-only.
*/
public snapshot() {
if (this.isReadonly) return;
const fs = new FileSystem(this.ignoreCase, { time: this._time });
fs._lazy = this._lazy;
fs._cwd = this._cwd;
fs._time = this._time;
fs._shadowRoot = this._shadowRoot;
fs._dirStack = this._dirStack;
fs.makeReadonly();
this._lazy = {};
this._shadowRoot = fs;
}
/**
* Gets a shadow copy of this file system. Changes to the shadow copy do not affect the
* original, allowing multiple copies of the same core file system without multiple copies
@ -671,6 +689,160 @@ namespace vfs {
node.ctimeMs = time;
}
/**
* Generates a `FileSet` patch containing all the entries in this `FileSystem` that are not in `base`.
* @param base The base file system. If not provided, this file system's `shadowRoot` is used (if present).
*/
public diff(base = this.shadowRoot) {
const differences: FileSet = {};
const hasDifferences = base ? FileSystem.rootDiff(differences, this, base) : FileSystem.trackCreatedInodes(differences, this, this._getRootLinks());
return hasDifferences ? differences : undefined;
}
/**
* Generates a `FileSet` patch containing all the entries in `chagned` that are not in `base`.
*/
public static diff(changed: FileSystem, base: FileSystem) {
const differences: FileSet = {};
return FileSystem.rootDiff(differences, changed, base) ? differences : undefined;
}
private static diffWorker(container: FileSet, changed: FileSystem, changedLinks: ReadonlyMap<string, Inode> | undefined, base: FileSystem, baseLinks: ReadonlyMap<string, Inode> | undefined) {
if (changedLinks && !baseLinks) return FileSystem.trackCreatedInodes(container, changed, changedLinks);
if (baseLinks && !changedLinks) return FileSystem.trackDeletedInodes(container, baseLinks);
if (changedLinks && baseLinks) {
let hasChanges = false;
// track base items missing in changed
baseLinks.forEach((node, basename) => {
if (!changedLinks.has(basename)) {
container[basename] = isDirectory(node) ? new Rmdir() : new Unlink();
hasChanges = true;
}
});
// track changed items missing or differing in base
changedLinks.forEach((changedNode, basename) => {
const baseNode = baseLinks.get(basename);
if (baseNode) {
if (isDirectory(changedNode) && isDirectory(baseNode)) {
return hasChanges = FileSystem.directoryDiff(container, basename, changed, changedNode, base, baseNode) || hasChanges;
}
if (isFile(changedNode) && isFile(baseNode)) {
return hasChanges = FileSystem.fileDiff(container, basename, changed, changedNode, base, baseNode) || hasChanges;
}
if (isSymlink(changedNode) && isSymlink(baseNode)) {
return hasChanges = FileSystem.symlinkDiff(container, basename, changedNode, baseNode) || hasChanges;
}
}
return hasChanges = FileSystem.trackCreatedInode(container, basename, changed, changedNode) || hasChanges;
});
return hasChanges;
}
return false;
}
private static rootDiff(container: FileSet, changed: FileSystem, base: FileSystem) {
while (!changed._lazy.links && changed._shadowRoot) changed = changed._shadowRoot;
while (!base._lazy.links && base._shadowRoot) base = base._shadowRoot;
// no difference if the file systems are the same reference
if (changed === base) return false;
// no difference if the root links are empty and unshadowed
if (!changed._lazy.links && !changed._shadowRoot && !base._lazy.links && !base._shadowRoot) return false;
return FileSystem.diffWorker(container, changed, changed._getRootLinks(), base, base._getRootLinks());
}
private static directoryDiff(container: FileSet, basename: string, changed: FileSystem, changedNode: DirectoryInode, base: FileSystem, baseNode: DirectoryInode) {
while (!changedNode.links && changedNode.shadowRoot) changedNode = changedNode.shadowRoot;
while (!baseNode.links && baseNode.shadowRoot) baseNode = baseNode.shadowRoot;
// no difference if the nodes are the same reference
if (changedNode === baseNode) return false;
// no difference if both nodes are non shadowed and have no entries
if (isEmptyNonShadowedDirectory(changedNode) && isEmptyNonShadowedDirectory(baseNode)) return false;
// no difference if both nodes are unpopulated and point to the same mounted file system
if (!changedNode.links && !baseNode.links &&
changedNode.resolver && changedNode.source !== undefined &&
baseNode.resolver === changedNode.resolver && baseNode.source === changedNode.source) return false;
// no difference if both nodes have identical children
const children: FileSet = {};
if (!FileSystem.diffWorker(children, changed, changed._getLinks(changedNode), base, base._getLinks(baseNode))) {
return false;
}
container[basename] = new Directory(children);
return true;
}
private static fileDiff(container: FileSet, basename: string, changed: FileSystem, changedNode: FileInode, base: FileSystem, baseNode: FileInode) {
while (!changedNode.buffer && changedNode.shadowRoot) changedNode = changedNode.shadowRoot;
while (!baseNode.buffer && baseNode.shadowRoot) baseNode = baseNode.shadowRoot;
// no difference if the nodes are the same reference
if (changedNode === baseNode) return false;
// no difference if both nodes are non shadowed and have no entries
if (isEmptyNonShadowedFile(changedNode) && isEmptyNonShadowedFile(baseNode)) return false;
// no difference if both nodes are unpopulated and point to the same mounted file system
if (!changedNode.buffer && !baseNode.buffer &&
changedNode.resolver && changedNode.source !== undefined &&
baseNode.resolver === changedNode.resolver && baseNode.source === changedNode.source) return false;
const changedBuffer = changed._getBuffer(changedNode);
const baseBuffer = base._getBuffer(baseNode);
// no difference if both buffers are the same reference
if (changedBuffer === baseBuffer) return false;
// no difference if both buffers are identical
if (Buffer.compare(changedBuffer, baseBuffer) === 0) return false;
container[basename] = new File(changedBuffer);
return true;
}
private static symlinkDiff(container: FileSet, basename: string, changedNode: SymlinkInode, baseNode: SymlinkInode) {
// no difference if the nodes are the same reference
if (changedNode.symlink === baseNode.symlink) return false;
container[basename] = new Symlink(changedNode.symlink);
return true;
}
private static trackCreatedInode(container: FileSet, basename: string, changed: FileSystem, node: Inode) {
if (isDirectory(node)) {
const children: FileSet = {};
FileSystem.trackCreatedInodes(children, changed, changed._getLinks(node));
container[basename] = new Directory(children);
}
else if (isSymlink(node)) {
container[basename] = new Symlink(node.symlink);
}
else {
container[basename] = new File(node.buffer || "");
}
return true;
}
private static trackCreatedInodes(container: FileSet, changed: FileSystem, changedLinks: ReadonlyMap<string, Inode>) {
// no difference if links are empty
if (!changedLinks.size) return false;
changedLinks.forEach((node, basename) => { FileSystem.trackCreatedInode(container, basename, changed, node); });
return true;
}
private static trackDeletedInodes(container: FileSet, baseLinks: ReadonlyMap<string, Inode>) {
// no difference if links are empty
if (!baseLinks.size) return false;
baseLinks.forEach((node, basename) => { container[basename] = isDirectory(node) ? new Rmdir() : new Unlink(); });
return true;
}
private _mknod(dev: number, type: typeof S_IFREG, mode: number, time?: number): FileInode;
private _mknod(dev: number, type: typeof S_IFDIR, mode: number, time?: number): DirectoryInode;
private _mknod(dev: number, type: typeof S_IFLNK, mode: number, time?: number): SymlinkInode;
@ -940,10 +1112,10 @@ namespace vfs {
private _applyFilesWorker(files: FileSet, dirname: string, deferred: [Symlink | Link | Mount, string][]) {
for (const key of Object.keys(files)) {
const value = this._normalizeFileSetEntry(files[key]);
const value = normalizeFileSetEntry(files[key]);
const path = dirname ? vpath.resolve(dirname, key) : key;
vpath.validate(path, vpath.ValidationFlags.Absolute);
if (value === null || value === undefined) {
if (value === null || value === undefined || value instanceof Rmdir || value instanceof Unlink) {
if (this.stringComparer(vpath.dirname(path), path) === 0) {
throw new TypeError("Roots cannot be deleted.");
}
@ -967,19 +1139,6 @@ namespace vfs {
}
}
}
private _normalizeFileSetEntry(value: FileSet[string]) {
if (value === undefined ||
value === null ||
value instanceof Directory ||
value instanceof File ||
value instanceof Link ||
value instanceof Symlink ||
value instanceof Mount) {
return value;
}
return typeof value === "string" || Buffer.isBuffer(value) ? new File(value) : new Directory(value);
}
}
export interface FileSystemOptions {
@ -997,12 +1156,9 @@ namespace vfs {
meta?: Record<string, any>;
}
export interface FileSystemCreateOptions {
export interface FileSystemCreateOptions extends FileSystemOptions {
// Sets the documents to add to the file system.
documents?: ReadonlyArray<documents.TextDocument>;
// Sets the initial working directory for the file system.
cwd?: string;
}
export type Axis = "ancestors" | "ancestors-or-self" | "self" | "descendants-or-self" | "descendants";
@ -1062,8 +1218,16 @@ namespace vfs {
*
* Unless overridden, `/.src` will be the current working directory for the virtual file system.
*/
export function createFromFileSystem(host: FileSystemResolverHost, ignoreCase: boolean, { documents, cwd }: FileSystemCreateOptions = {}) {
export function createFromFileSystem(host: FileSystemResolverHost, ignoreCase: boolean, { documents, files, cwd, time, meta }: FileSystemCreateOptions = {}) {
const fs = getBuiltLocal(host, ignoreCase).shadow();
if (meta) {
for (const key of Object.keys(meta)) {
fs.meta.set(key, meta[key]);
}
}
if (time) {
fs.time(time);
}
if (cwd) {
fs.mkdirpSync(cwd);
fs.chdir(cwd);
@ -1083,6 +1247,9 @@ namespace vfs {
}
}
}
if (files) {
fs.apply(files);
}
return fs;
}
@ -1165,7 +1332,7 @@ namespace vfs {
* A template used to populate files, directories, links, etc. in a virtual file system.
*/
export interface FileSet {
[name: string]: DirectoryLike | FileLike | Link | Symlink | Mount | null | undefined;
[name: string]: DirectoryLike | FileLike | Link | Symlink | Mount | Rmdir | Unlink | null | undefined;
}
export type DirectoryLike = FileSet | Directory;
@ -1201,6 +1368,16 @@ namespace vfs {
}
}
/** Removes a directory in a `FileSet` */
export class Rmdir {
public _rmdirBrand?: never; // brand necessary for proper type guards
}
/** Unlinks a file in a `FileSet` */
export class Unlink {
public _unlinkBrand?: never; // brand necessary for proper type guards
}
/** Extended options for a symbolic link in a `FileSet` */
export class Symlink {
public readonly symlink: string;
@ -1273,6 +1450,14 @@ namespace vfs {
meta?: collections.Metadata;
}
function isEmptyNonShadowedDirectory(node: DirectoryInode) {
return !node.links && !node.shadowRoot && !node.resolver && !node.source;
}
function isEmptyNonShadowedFile(node: FileInode) {
return !node.buffer && !node.shadowRoot && !node.resolver && !node.source;
}
function isFile(node: Inode | undefined): node is FileInode {
return node !== undefined && (node.mode & S_IFMT) === S_IFREG;
}
@ -1324,5 +1509,55 @@ namespace vfs {
}
return builtLocalCS;
}
function normalizeFileSetEntry(value: FileSet[string]) {
if (value === undefined ||
value === null ||
value instanceof Directory ||
value instanceof File ||
value instanceof Link ||
value instanceof Symlink ||
value instanceof Mount ||
value instanceof Rmdir ||
value instanceof Unlink) {
return value;
}
return typeof value === "string" || Buffer.isBuffer(value) ? new File(value) : new Directory(value);
}
export function formatPatch(patch: FileSet) {
return formatPatchWorker("", patch);
}
function formatPatchWorker(dirname: string, container: FileSet): string {
let text = "";
for (const name of Object.keys(container)) {
const entry = normalizeFileSetEntry(container[name]);
const file = dirname ? vpath.combine(dirname, name) : name;
if (entry === null || entry === undefined || entry instanceof Unlink || entry instanceof Rmdir) {
text += `//// [${file}] unlink\r\n`;
}
else if (entry instanceof Rmdir) {
text += `//// [${vpath.addTrailingSeparator(file)}] rmdir\r\n`;
}
else if (entry instanceof Directory) {
text += formatPatchWorker(file, entry.files);
}
else if (entry instanceof File) {
const content = typeof entry.data === "string" ? entry.data : entry.data.toString("utf8");
text += `//// [${file}]\r\n${content}\r\n\r\n`;
}
else if (entry instanceof Link) {
text += `//// [${file}] link(${entry.path})\r\n`;
}
else if (entry instanceof Symlink) {
text += `//// [${file}] symlink(${entry.symlink})\r\n`;
}
else if (entry instanceof Mount) {
text += `//// [${file}] mount(${entry.source})\r\n`;
}
}
return text;
}
}
// tslint:enable:no-null-keyword

View file

@ -12,7 +12,7 @@ namespace ts {
export namespace Sample1 {
tick();
const projFs = loadProjectFromDisk("../../tests/projects/sample1");
const projFs = loadProjectFromDisk("tests/projects/sample1");
const allExpectedOutputs = ["/src/tests/index.js",
"/src/core/index.js", "/src/core/index.d.ts",
@ -236,40 +236,33 @@ namespace ts {
}
export namespace OutFile {
const outFileFs = loadProjectFromDisk("../../tests/projects/outfile-concat");
const outFileFs = loadProjectFromDisk("tests/projects/outfile-concat");
describe("tsbuild - baseline sectioned sourcemaps", () => {
const fs = outFileFs.shadow();
const host = new fakes.CompilerHost(fs);
const builder = createSolutionBuilder(host, buildHost, ["/src/third"], { dry: false, force: false, verbose: false });
clearDiagnostics();
builder.buildAllProjects();
assertDiagnosticMessages(/*none*/);
const files = [
"/src/third/thirdjs/output/third-output.js",
"/src/third/thirdjs/output/third-output.js.map"
];
for (const file of files) {
it(`Generates files matching the baseline - ${file}`, () => {
Harness.Baseline.runBaseline(getBaseFileName(file), () => {
return fs.readFileSync(file, "utf-8");
});
});
}
it(`Generates files matching the baseline - file listing for outFile-concat`, () => {
Harness.Baseline.runBaseline("outfile-concat-fileListing.txt", () => {
return fs.getFileListing();
let fs: vfs.FileSystem | undefined;
before(() => {
fs = outFileFs.shadow();
const host = new fakes.CompilerHost(fs);
const builder = createSolutionBuilder(host, buildHost, ["/src/third"], { dry: false, force: false, verbose: false });
clearDiagnostics();
builder.buildAllProjects();
assertDiagnosticMessages(/*none*/);
});
after(() => {
fs = undefined;
});
it(`Generates files matching the baseline`, () => {
Harness.Baseline.runBaseline("outfile-concat.js", () => {
const patch = fs!.diff();
// tslint:disable-next-line:no-null-keyword
return patch ? vfs.formatPatch(patch) : null;
});
});
});
}
describe("tsbuild - graph-ordering", () => {
const fs = new vfs.FileSystem(false);
const host = new fakes.CompilerHost(fs);
let host: fakes.CompilerHost | undefined;
const deps: [string, string][] = [
["A", "B"],
["B", "C"],
@ -280,7 +273,15 @@ namespace ts {
["F", "E"]
];
writeProjects(fs, ["A", "B", "C", "D", "E", "F", "G"], deps);
before(() => {
const fs = new vfs.FileSystem(false);
host = new fakes.CompilerHost(fs);
writeProjects(fs, ["A", "B", "C", "D", "E", "F", "G"], deps);
});
after(() => {
host = undefined;
});
it("orders the graph correctly - specify two roots", () => {
checkGraphOrdering(["A", "G"], ["A", "B", "C", "D", "E", "G"]);
@ -299,7 +300,7 @@ namespace ts {
});
function checkGraphOrdering(rootNames: string[], expectedBuildSet: string[]) {
const builder = createSolutionBuilder(host, buildHost, rootNames, { dry: true, force: false, verbose: false });
const builder = createSolutionBuilder(host!, buildHost, rootNames, { dry: true, force: false, verbose: false });
const projFileNames = rootNames.map(getProjectFileName);
const graph = builder.getBuildGraph(projFileNames);
@ -394,32 +395,17 @@ namespace ts {
}
function loadProjectFromDisk(root: string): vfs.FileSystem {
const fs = new vfs.FileSystem(/*ignoreCase*/ false, { time });
const rootPath = resolvePath(__dirname, root);
loadFsMirror(fs, rootPath, "/src");
fs.mkdirpSync("/lib");
const libs = ["es5", "dom", "webworker.importscripts", "scripthost"];
for (const lib of libs) {
const content = Harness.IO.readFile(combinePaths(Harness.libFolder, `lib.${lib}.d.ts`));
if (content === undefined) {
throw new Error(`Failed to read lib ${lib}`);
}
fs.writeFileSync(`/lib/lib.${lib}.d.ts`, content);
}
fs.writeFileSync("/lib/lib.d.ts", Harness.IO.readFile(combinePaths(Harness.libFolder, "lib.d.ts"))!);
fs.meta.set("defaultLibLocation", "/lib");
const resolver = vfs.createResolver(Harness.IO);
const fs = new vfs.FileSystem(/*ignoreCase*/ true, {
files: {
["/lib"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), "built/local"), resolver),
["/src"]: new vfs.Mount(vpath.resolve(Harness.IO.getWorkspaceRoot(), root), resolver)
},
cwd: "/",
meta: { defaultLibLocation: "/lib" },
time
});
fs.makeReadonly();
return fs;
}
function loadFsMirror(vfs: vfs.FileSystem, localRoot: string, virtualRoot: string) {
vfs.mkdirpSync(virtualRoot);
for (const path of Harness.IO.readDirectory(localRoot)) {
const file = getBaseFileName(path);
vfs.writeFileSync(virtualRoot + "/" + file, Harness.IO.readFile(localRoot + "/" + file)!);
}
for (const dir of Harness.IO.getDirectories(localRoot)) {
loadFsMirror(vfs, localRoot + "/" + dir, virtualRoot + "/" + dir);
}
}
}

View file

@ -1,43 +0,0 @@
*/
/lib/
/lib/lib.d.ts
/lib/lib.dom.d.ts
/lib/lib.es5.d.ts
/lib/lib.scripthost.d.ts
/lib/lib.webworker.importscripts.d.ts
/src/
/src/2/
/src/2/second-output.d.ts
/src/2/second-output.d.ts.map
/src/2/second-output.js
/src/2/second-output.js.map
/src/first/
/src/first/bin/
/src/first/bin/first-output.d.ts
/src/first/bin/first-output.d.ts.map
/src/first/bin/first-output.js
/src/first/bin/first-output.js.map
/src/first/first_part1.ts
/src/first/first_part2.ts
/src/first/first_part3.ts
/src/first/tsconfig.json
/src/first_part1.ts
/src/first_part2.ts
/src/first_part3.ts
/src/second/
/src/second/second_part1.ts
/src/second/second_part2.ts
/src/second/tsconfig.json
/src/second_part1.ts
/src/second_part2.ts
/src/third/
/src/third/third_part1.ts
/src/third/thirdjs/
/src/third/thirdjs/output/
/src/third/thirdjs/output/third-output.d.ts
/src/third/thirdjs/output/third-output.d.ts.map
/src/third/thirdjs/output/third-output.js
/src/third/thirdjs/output/third-output.js.map
/src/third/tsconfig.json
/src/third_part1.ts
/src/tsconfig.json

View file

@ -1,3 +1,88 @@
//// [/src/2/second-output.d.ts]
declare namespace N {
}
declare namespace N {
}
declare class C {
doSomething(): void;
}
//# sourceMappingURL=second-output.d.ts.map
//// [/src/2/second-output.d.ts.map]
{"version":3,"file":"second-output.d.ts","sourceRoot":"","sources":["../second/second_part1.ts","../second/second_part2.ts"],"names":[],"mappings":"AAAA,kBAAU,CAAC,CAAC;CAEX;AAED,kBAAU,CAAC,CAAC;CAMX;ACVD;IACI,WAAW;CAGd"}
//// [/src/2/second-output.js]
var N;
(function (N) {
function f() {
console.log('testing');
}
f();
})(N || (N = {}));
var C = (function () {
function C() {
}
C.prototype.doSomething = function () {
console.log("something got done");
};
return C;
}());
//# sourceMappingURL=second-output.js.map
//// [/src/2/second-output.js.map]
{"version":3,"file":"second-output.js","sourceRoot":"","sources":["../second/second_part1.ts","../second/second_part2.ts"],"names":[],"mappings":"AAIA,IAAU,CAAC,CAMV;AAND,WAAU,CAAC;IACP;QACI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,CAAC,EAAE,CAAC;AACR,CAAC,EANS,CAAC,KAAD,CAAC,QAMV;ACVD;IAAA;IAIA,CAAC;IAHG,uBAAW,GAAX;QACI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,CAAC;IACL,QAAC;AAAD,CAAC,AAJD,IAIC"}
//// [/src/first/bin/first-output.d.ts]
interface TheFirst {
none: any;
}
declare const s = "Hello, world";
interface NoJsForHereEither {
none: any;
}
declare function f(): string;
//# sourceMappingURL=first-output.d.ts.map
//// [/src/first/bin/first-output.d.ts.map]
{"version":3,"file":"first-output.d.ts","sourceRoot":"","sources":["../first_part1.ts","../first_part2.ts","../first_part3.ts"],"names":[],"mappings":"AAAA,UAAU,QAAQ;IACd,IAAI,EAAE,GAAG,CAAC;CACb;AAED,QAAA,MAAM,CAAC,iBAAiB,CAAC;AAEzB,UAAU,iBAAiB;IACvB,IAAI,EAAE,GAAG,CAAC;CACb;AERD,6BAEC"}
//// [/src/first/bin/first-output.js]
var s = "Hello, world";
console.log(s);
console.log(f());
function f() {
return "JS does hoists";
}
//# sourceMappingURL=first-output.js.map
//// [/src/first/bin/first-output.js.map]
{"version":3,"file":"first-output.js","sourceRoot":"","sources":["../first_part1.ts","../first_part2.ts","../first_part3.ts"],"names":[],"mappings":"AAIA,IAAM,CAAC,GAAG,cAAc,CAAC;AAMzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;ACVf,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;ACAjB;IACI,OAAO,gBAAgB,CAAC;AAC5B,CAAC"}
//// [/src/third/thirdjs/output/third-output.d.ts]
interface TheFirst {
none: any;
}
declare const s = "Hello, world";
interface NoJsForHereEither {
none: any;
}
declare function f(): string;
//# sourceMappingURL=first-output.d.ts.map
declare namespace N {
}
declare namespace N {
}
declare class C {
doSomething(): void;
}
//# sourceMappingURL=second-output.d.ts.map
declare var c: C;
//# sourceMappingURL=third-output.d.ts.map
//// [/src/third/thirdjs/output/third-output.d.ts.map]
{"version":3,"file":"third-output.d.ts","sections":[{"offset":{"line":0,"column":0},"map":{"version":3,"file":"first-output.d.ts","sourceRoot":"","sources":["../first_part1.ts","../first_part2.ts","../first_part3.ts"],"names":[],"mappings":"AAAA,UAAU,QAAQ;IACd,IAAI,EAAE,GAAG,CAAC;CACb;AAED,QAAA,MAAM,CAAC,iBAAiB,CAAC;AAEzB,UAAU,iBAAiB;IACvB,IAAI,EAAE,GAAG,CAAC;CACb;AERD,6BAEC"}},{"offset":{"line":9,"column":0},"map":{"version":3,"file":"second-output.d.ts","sourceRoot":"","sources":["../second/second_part1.ts","../second/second_part2.ts"],"names":[],"mappings":"AAAA,kBAAU,CAAC,CAAC;CAEX;AAED,kBAAU,CAAC,CAAC;CAMX;ACVD;IACI,WAAW;CAGd"}},{"offset":{"line":16,"column":43},"map":{"version":3,"file":"third-output.d.ts","sourceRoot":"","sources":["../../third_part1.ts"],"names":[],"mappings":";AAAA,QAAA,IAAI,CAAC,GAAU,CAAC"}}]}
//// [/src/third/thirdjs/output/third-output.js]
var s = "Hello, world";
console.log(s);
console.log(f());
@ -23,4 +108,8 @@ var C = (function () {
//# sourceMappingURL=second-output.js.map
var c = new C();
c.doSomething();
//# sourceMappingURL=third-output.js.map
//# sourceMappingURL=third-output.js.map
//// [/src/third/thirdjs/output/third-output.js.map]
{"version":3,"file":"third-output.js","sections":[{"offset":{"line":0,"column":0},"map":{"version":3,"file":"first-output.js","sourceRoot":"","sources":["../first_part1.ts","../first_part2.ts","../first_part3.ts"],"names":[],"mappings":"AAIA,IAAM,CAAC,GAAG,cAAc,CAAC;AAMzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;ACVf,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;ACAjB;IACI,OAAO,gBAAgB,CAAC;AAC5B,CAAC"}},{"offset":{"line":7,"column":0},"map":{"version":3,"file":"second-output.js","sourceRoot":"","sources":["../second/second_part1.ts","../second/second_part2.ts"],"names":[],"mappings":"AAIA,IAAU,CAAC,CAMV;AAND,WAAU,CAAC;IACP;QACI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,CAAC,EAAE,CAAC;AACR,CAAC,EANS,CAAC,KAAD,CAAC,QAMV;ACVD;IAAA;IAIA,CAAC;IAHG,uBAAW,GAAX;QACI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,CAAC;IACL,QAAC;AAAD,CAAC,AAJD,IAIC"}},{"offset":{"line":22,"column":41},"map":{"version":3,"file":"third-output.js","sourceRoot":"","sources":["../../third_part1.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AAChB,CAAC,CAAC,WAAW,EAAE,CAAC"}}]}

View file

@ -1 +0,0 @@
{"version":3,"file":"third-output.js","sections":[{"offset":{"line":0,"column":0},"map":{"version":3,"file":"first-output.js","sourceRoot":"","sources":["first_part1.ts","first_part2.ts","first_part3.ts"],"names":[],"mappings":"AAIA,IAAM,CAAC,GAAG,cAAc,CAAC;AAMzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;ACVf,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;ACAjB;IACI,OAAO,gBAAgB,CAAC;AAC5B,CAAC"}},{"offset":{"line":7,"column":0},"map":{"version":3,"file":"second-output.js","sourceRoot":"","sources":["second_part1.ts","second_part2.ts"],"names":[],"mappings":"AAIA,IAAU,CAAC,CAMV;AAND,WAAU,CAAC;IACP;QACI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,CAAC,EAAE,CAAC;AACR,CAAC,EANS,CAAC,KAAD,CAAC,QAMV;ACVD;IAAA;IAIA,CAAC;IAHG,uBAAW,GAAX;QACI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,CAAC;IACL,QAAC;AAAD,CAAC,AAJD,IAIC"}},{"offset":{"line":22,"column":41},"map":{"version":3,"file":"third-output.js","sourceRoot":"","sources":["third_part1.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AAChB,CAAC,CAAC,WAAW,EAAE,CAAC"}}]}

View file

@ -1,26 +0,0 @@
var s = "Hello, world";
console.log(s);
console.log(f());
function f() {
return "JS does hoists";
}
//# sourceMappingURL=first-output.js.map
var N;
(function (N) {
function f() {
console.log('testing');
}
f();
})(N || (N = {}));
var C = (function () {
function C() {
}
C.prototype.doSomething = function () {
console.log("something got done");
};
return C;
}());
//# sourceMappingURL=second-output.js.map
var c = new C();
c.doSomething();
//# sourceMappingURL=third-output.js.map

View file

@ -1 +0,0 @@
{"version":3,"file":"third-output.js","sections":[{"offset":{"line":0,"column":0},"map":{"version":3,"file":"first-output.js","sourceRoot":"","sources":["../first_part1.ts","../first_part2.ts","../first_part3.ts"],"names":[],"mappings":"AAIA,IAAM,CAAC,GAAG,cAAc,CAAC;AAMzB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;ACVf,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;ACAjB;IACI,OAAO,gBAAgB,CAAC;AAC5B,CAAC"}},{"offset":{"line":7,"column":0},"map":{"version":3,"file":"second-output.js","sourceRoot":"","sources":["../second/second_part1.ts","../second/second_part2.ts"],"names":[],"mappings":"AAIA,IAAU,CAAC,CAMV;AAND,WAAU,CAAC;IACP;QACI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC3B,CAAC;IAED,CAAC,EAAE,CAAC;AACR,CAAC,EANS,CAAC,KAAD,CAAC,QAMV;ACVD;IAAA;IAIA,CAAC;IAHG,uBAAW,GAAX;QACI,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACtC,CAAC;IACL,QAAC;AAAD,CAAC,AAJD,IAIC"}},{"offset":{"line":22,"column":41},"map":{"version":3,"file":"third-output.js","sourceRoot":"","sources":["../../third_part1.ts"],"names":[],"mappings":";AAAA,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;AAChB,CAAC,CAAC,WAAW,EAAE,CAAC"}}]}