From d9c50bec10659a574830248dc84e9ce8e95b411a Mon Sep 17 00:00:00 2001
From: Sheetal Nandi <shkamat@microsoft.com>
Date: Wed, 17 Jul 2024 17:07:17 -0700
Subject: [PATCH] Allow declarationMap to be emitted when transpiling
 declarations and option is enabled (#59337)

---
 src/compiler/builderState.ts                  |   3 +-
 src/compiler/commandLineParser.ts             |   1 -
 src/compiler/emitter.ts                       |   2 +-
 src/compiler/types.ts                         |   1 +
 src/testRunner/transpileRunner.ts             |  13 +-
 ...ionBasicSyntax(declarationMap=false).d.ts} |   0
 ...ationBasicSyntax(declarationMap=false).js} |   0
 ...ationBasicSyntax(declarationMap=true).d.ts | 128 ++++++++++++++
 ...arationBasicSyntax(declarationMap=true).js | 145 ++++++++++++++++
 ...neSourceMapBasic(inlineSourceMap=false).js | 145 ++++++++++++++++
 ...ineSourceMapBasic(inlineSourceMap=true).js | 150 ++++++++++++++++
 .../jsWithSourceMapBasic(sourceMap=false).js  | 145 ++++++++++++++++
 .../jsWithSourceMapBasic(sourceMap=true).js   | 160 ++++++++++++++++++
 .../cases/transpile/declarationBasicSyntax.ts |   1 +
 .../transpile/jsWithInlineSourceMapBasic.ts   |  45 +++++
 tests/cases/transpile/jsWithSourceMapBasic.ts |  45 +++++
 16 files changed, 980 insertions(+), 4 deletions(-)
 rename tests/baselines/reference/transpile/{declarationBasicSyntax.d.ts => declarationBasicSyntax(declarationMap=false).d.ts} (100%)
 rename tests/baselines/reference/transpile/{declarationBasicSyntax.js => declarationBasicSyntax(declarationMap=false).js} (100%)
 create mode 100644 tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).d.ts
 create mode 100644 tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).js
 create mode 100644 tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=false).js
 create mode 100644 tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=true).js
 create mode 100644 tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=false).js
 create mode 100644 tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=true).js
 create mode 100644 tests/cases/transpile/jsWithInlineSourceMapBasic.ts
 create mode 100644 tests/cases/transpile/jsWithSourceMapBasic.ts

diff --git a/src/compiler/builderState.ts b/src/compiler/builderState.ts
index 6e23eaddc3741..0e571d233d7e8 100644
--- a/src/compiler/builderState.ts
+++ b/src/compiler/builderState.ts
@@ -5,6 +5,7 @@ import {
     computeSignatureWithDiagnostics,
     CustomTransformers,
     Debug,
+    EmitOnly,
     EmitOutput,
     emptyArray,
     GetCanonicalFileName,
@@ -418,7 +419,7 @@ export namespace BuilderState {
                 );
             },
             cancellationToken,
-            /*emitOnly*/ true,
+            EmitOnly.BuilderSignature,
             /*customTransformers*/ undefined,
             /*forceDtsEmit*/ true,
         );
diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts
index bcbbb1d4e3db6..aa121858a79d7 100644
--- a/src/compiler/commandLineParser.ts
+++ b/src/compiler/commandLineParser.ts
@@ -468,7 +468,6 @@ export const commonOptionsWithBuild: CommandLineOption[] = [
         affectsBuildInfo: true,
         showInSimplifiedHelpView: true,
         category: Diagnostics.Emit,
-        transpileOptionValue: undefined,
         defaultValueDescription: false,
         description: Diagnostics.Create_sourcemaps_for_d_ts_files,
     },
diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts
index b56630f9b9d92..f9a2afdc08c81 100644
--- a/src/compiler/emitter.ts
+++ b/src/compiler/emitter.ts
@@ -893,7 +893,7 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
                 noEmitHelpers: true,
                 module: compilerOptions.module,
                 target: compilerOptions.target,
-                sourceMap: !forceDtsEmit && compilerOptions.declarationMap,
+                sourceMap: emitOnly !== EmitOnly.BuilderSignature && compilerOptions.declarationMap,
                 inlineSourceMap: compilerOptions.inlineSourceMap,
                 extendedDiagnostics: compilerOptions.extendedDiagnostics,
                 onlyPrintJsDocStyle: true,
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 0c00b8cb3bde8..bdf793a65486f 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -4641,6 +4641,7 @@ export type FilePreprocessingDiagnostics = FilePreprocessingLibReferenceDiagnost
 export const enum EmitOnly {
     Js,
     Dts,
+    BuilderSignature,
 }
 
 /** @internal */
diff --git a/src/testRunner/transpileRunner.ts b/src/testRunner/transpileRunner.ts
index 80a9794fe2bc1..5ef62de5c806e 100644
--- a/src/testRunner/transpileRunner.ts
+++ b/src/testRunner/transpileRunner.ts
@@ -48,7 +48,11 @@ enum TranspileKind {
 }
 
 class TranspileTestCase {
-    static varyBy = [];
+    static varyBy = [
+        "declarationMap",
+        "sourceMap",
+        "inlineSourceMap",
+    ];
 
     static getConfigurations(file: string): TranspileTestCase[] {
         const ext = vpath.extname(file);
@@ -104,6 +108,13 @@ class TranspileTestCase {
                 if (!result.outputText.endsWith("\n")) {
                     baselineText += "\r\n";
                 }
+                if (result.sourceMapText) {
+                    baselineText += `//// [${ts.changeExtension(unit.name, kind === TranspileKind.Module ? this.getJsOutputExtension(unit.name) : ts.getDeclarationEmitExtensionForPath(unit.name))}.map] ////\r\n`;
+                    baselineText += result.sourceMapText;
+                    if (!result.outputText.endsWith("\n")) {
+                        baselineText += "\r\n";
+                    }
+                }
                 if (result.diagnostics && result.diagnostics.length) {
                     baselineText += "\r\n\r\n//// [Diagnostics reported]\r\n";
                     baselineText += Compiler.getErrorBaseline([{ content: unit.content, unitName: unit.name }], result.diagnostics, !!opts.pretty);
diff --git a/tests/baselines/reference/transpile/declarationBasicSyntax.d.ts b/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=false).d.ts
similarity index 100%
rename from tests/baselines/reference/transpile/declarationBasicSyntax.d.ts
rename to tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=false).d.ts
diff --git a/tests/baselines/reference/transpile/declarationBasicSyntax.js b/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=false).js
similarity index 100%
rename from tests/baselines/reference/transpile/declarationBasicSyntax.js
rename to tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=false).js
diff --git a/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).d.ts b/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).d.ts
new file mode 100644
index 0000000000000..c82e9f9b1b65c
--- /dev/null
+++ b/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).d.ts
@@ -0,0 +1,128 @@
+//// [variables.ts] ////
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+//// [interface.ts] ////
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+//// [class.ts] ////
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+//// [namespace.ts] ////
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+//// [alias.ts] ////
+export type A<T> = { x: T };
+//// [variables.d.ts] ////
+export declare const a = 1;
+export declare let b: number;
+export declare var c: number;
+declare const d: any;
+export { d };
+declare const e: any;
+export { e };
+//# sourceMappingURL=variables.d.ts.map
+//// [variables.d.ts.map] ////
+{"version":3,"file":"variables.d.ts","sourceRoot":"","sources":["variables.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,IAAI,CAAC,QAAI,CAAC;AACjB,eAAO,IAAI,CAAC,QAAI,CAAC;AACjB,QAAA,MAAM,CAAC,KAAY,CAAC;AACpB,OAAO,EAAE,CAAC,EAAE,CAAC;AACb,QAAA,MAAY,CAAC,KAAY,CAAC;AAC1B,OAAO,EAAE,CAAC,EAAE,CAAC"}
+//// [interface.d.ts] ////
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+//# sourceMappingURL=interface.d.ts.map
+//// [interface.d.ts.map] ////
+{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["interface.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IAChB,CAAC,EAAE,MAAM,CAAC;IACV,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,CAAC,EAAE,MAAM,CAAC;CACd"}
+//// [class.d.ts] ////
+export declare class Bar {
+    #private;
+    a: string;
+    b?: string;
+    c: string;
+    e: string;
+    protected f: string;
+    private g;
+    ["h"]: string;
+}
+export declare abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+//# sourceMappingURL=class.d.ts.map
+//// [class.d.ts.map] ////
+{"version":3,"file":"class.d.ts","sourceRoot":"","sources":["class.ts"],"names":[],"mappings":"AACA,qBAAa,GAAG;;IACZ,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,CAAC,EAAE,MAAM,CAAC;IACH,CAAC,EAAE,MAAM,CAAC;IAEX,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,CAAC,CAAS;IAClB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CAEjB;AAED,8BAAsB,GAAG;IACrB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,MAAM,IAAI,IAAI;CAC1B"}
+
+
+//// [Diagnostics reported]
+class.ts(11,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
+
+
+==== class.ts (1 errors) ====
+    const i = Symbol();
+    export class Bar {
+        a: string;
+        b?: string;
+        declare c: string;
+        #d: string;
+        public e: string;
+        protected f: string;
+        private g: string;
+        ["h"]: string;
+        [i]: string;
+        ~~~
+!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
+    }
+    
+    export abstract class Baz {
+        abstract a: string;
+        abstract method(): void;
+    }
+//// [namespace.d.ts] ////
+export declare namespace ns {
+    namespace internal {
+        class Foo {
+        }
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+    export {};
+}
+//# sourceMappingURL=namespace.d.ts.map
+//// [namespace.d.ts.map] ////
+{"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["namespace.ts"],"names":[],"mappings":"AAAA,yBAAiB,EAAE,CAAC;IAChB,UAAU,QAAQ,CAAC;QACf,MAAa,GAAG;SAAG;KACtB;IACD,MAAM,WAAW,MAAM,CAAC;QACpB,MAAM,QAAQ,KAAK,GAAG,QAAQ,CAAC;KAClC;;CACJ"}
+//// [alias.d.ts] ////
+export type A<T> = {
+    x: T;
+};
+//# sourceMappingURL=alias.d.ts.map
+//// [alias.d.ts.map] ////
+{"version":3,"file":"alias.d.ts","sourceRoot":"","sources":["alias.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,CAAC,CAAC,CAAC,IAAI;IAAE,CAAC,EAAE,CAAC,CAAA;CAAE,CAAC"}
diff --git a/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).js b/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).js
new file mode 100644
index 0000000000000..dd7a762bf285b
--- /dev/null
+++ b/tests/baselines/reference/transpile/declarationBasicSyntax(declarationMap=true).js
@@ -0,0 +1,145 @@
+//// [variables.ts] ////
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+//// [interface.ts] ////
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+//// [class.ts] ////
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+//// [namespace.ts] ////
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+//// [alias.ts] ////
+export type A<T> = { x: T };
+//// [variables.js] ////
+var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
+    if (value !== null && value !== void 0) {
+        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
+        var dispose, inner;
+        if (async) {
+            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
+            dispose = value[Symbol.asyncDispose];
+        }
+        if (dispose === void 0) {
+            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
+            dispose = value[Symbol.dispose];
+            if (async) inner = dispose;
+        }
+        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
+        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
+        env.stack.push({ value: value, dispose: dispose, async: async });
+    }
+    else if (async) {
+        env.stack.push({ async: true });
+    }
+    return value;
+};
+var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
+    return function (env) {
+        function fail(e) {
+            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
+            env.hasError = true;
+        }
+        var r, s = 0;
+        function next() {
+            while (r = env.stack.pop()) {
+                try {
+                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
+                    if (r.dispose) {
+                        var result = r.dispose.call(r.value);
+                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
+                    }
+                    else s |= 1;
+                }
+                catch (e) {
+                    fail(e);
+                }
+            }
+            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
+            if (env.hasError) throw env.error;
+        }
+        return next();
+    };
+})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
+    var e = new Error(message);
+    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
+});
+export const a = 1;
+export let b = 2;
+export var c = 3;
+export { d };
+export { e };
+var d, e;
+const env_1 = { stack: [], error: void 0, hasError: false };
+try {
+    d = __addDisposableResource(env_1, undefined, false);
+    e = __addDisposableResource(env_1, undefined, true);
+}
+catch (e_1) {
+    env_1.error = e_1;
+    env_1.hasError = true;
+}
+finally {
+    const result_1 = __disposeResources(env_1);
+    if (result_1)
+        await result_1;
+}
+//// [interface.js] ////
+export {};
+//// [class.js] ////
+var _Bar_d;
+const i = Symbol();
+export class Bar {
+    constructor() {
+        _Bar_d.set(this, void 0);
+    }
+}
+_Bar_d = new WeakMap();
+export class Baz {
+}
+//// [namespace.js] ////
+export var ns;
+(function (ns) {
+    let internal;
+    (function (internal) {
+        class Foo {
+        }
+        internal.Foo = Foo;
+    })(internal || (internal = {}));
+    let nested;
+    (function (nested) {
+        nested.inner = internal;
+    })(nested = ns.nested || (ns.nested = {}));
+})(ns || (ns = {}));
+//// [alias.js] ////
+export {};
diff --git a/tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=false).js b/tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=false).js
new file mode 100644
index 0000000000000..dd7a762bf285b
--- /dev/null
+++ b/tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=false).js
@@ -0,0 +1,145 @@
+//// [variables.ts] ////
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+//// [interface.ts] ////
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+//// [class.ts] ////
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+//// [namespace.ts] ////
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+//// [alias.ts] ////
+export type A<T> = { x: T };
+//// [variables.js] ////
+var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
+    if (value !== null && value !== void 0) {
+        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
+        var dispose, inner;
+        if (async) {
+            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
+            dispose = value[Symbol.asyncDispose];
+        }
+        if (dispose === void 0) {
+            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
+            dispose = value[Symbol.dispose];
+            if (async) inner = dispose;
+        }
+        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
+        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
+        env.stack.push({ value: value, dispose: dispose, async: async });
+    }
+    else if (async) {
+        env.stack.push({ async: true });
+    }
+    return value;
+};
+var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
+    return function (env) {
+        function fail(e) {
+            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
+            env.hasError = true;
+        }
+        var r, s = 0;
+        function next() {
+            while (r = env.stack.pop()) {
+                try {
+                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
+                    if (r.dispose) {
+                        var result = r.dispose.call(r.value);
+                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
+                    }
+                    else s |= 1;
+                }
+                catch (e) {
+                    fail(e);
+                }
+            }
+            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
+            if (env.hasError) throw env.error;
+        }
+        return next();
+    };
+})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
+    var e = new Error(message);
+    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
+});
+export const a = 1;
+export let b = 2;
+export var c = 3;
+export { d };
+export { e };
+var d, e;
+const env_1 = { stack: [], error: void 0, hasError: false };
+try {
+    d = __addDisposableResource(env_1, undefined, false);
+    e = __addDisposableResource(env_1, undefined, true);
+}
+catch (e_1) {
+    env_1.error = e_1;
+    env_1.hasError = true;
+}
+finally {
+    const result_1 = __disposeResources(env_1);
+    if (result_1)
+        await result_1;
+}
+//// [interface.js] ////
+export {};
+//// [class.js] ////
+var _Bar_d;
+const i = Symbol();
+export class Bar {
+    constructor() {
+        _Bar_d.set(this, void 0);
+    }
+}
+_Bar_d = new WeakMap();
+export class Baz {
+}
+//// [namespace.js] ////
+export var ns;
+(function (ns) {
+    let internal;
+    (function (internal) {
+        class Foo {
+        }
+        internal.Foo = Foo;
+    })(internal || (internal = {}));
+    let nested;
+    (function (nested) {
+        nested.inner = internal;
+    })(nested = ns.nested || (ns.nested = {}));
+})(ns || (ns = {}));
+//// [alias.js] ////
+export {};
diff --git a/tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=true).js b/tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=true).js
new file mode 100644
index 0000000000000..196e30479cece
--- /dev/null
+++ b/tests/baselines/reference/transpile/jsWithInlineSourceMapBasic(inlineSourceMap=true).js
@@ -0,0 +1,150 @@
+//// [variables.ts] ////
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+//// [interface.ts] ////
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+//// [class.ts] ////
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+//// [namespace.ts] ////
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+//// [alias.ts] ////
+export type A<T> = { x: T };
+//// [variables.js] ////
+var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
+    if (value !== null && value !== void 0) {
+        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
+        var dispose, inner;
+        if (async) {
+            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
+            dispose = value[Symbol.asyncDispose];
+        }
+        if (dispose === void 0) {
+            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
+            dispose = value[Symbol.dispose];
+            if (async) inner = dispose;
+        }
+        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
+        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
+        env.stack.push({ value: value, dispose: dispose, async: async });
+    }
+    else if (async) {
+        env.stack.push({ async: true });
+    }
+    return value;
+};
+var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
+    return function (env) {
+        function fail(e) {
+            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
+            env.hasError = true;
+        }
+        var r, s = 0;
+        function next() {
+            while (r = env.stack.pop()) {
+                try {
+                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
+                    if (r.dispose) {
+                        var result = r.dispose.call(r.value);
+                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
+                    }
+                    else s |= 1;
+                }
+                catch (e) {
+                    fail(e);
+                }
+            }
+            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
+            if (env.hasError) throw env.error;
+        }
+        return next();
+    };
+})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
+    var e = new Error(message);
+    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
+});
+export const a = 1;
+export let b = 2;
+export var c = 3;
+export { d };
+export { e };
+var d, e;
+const env_1 = { stack: [], error: void 0, hasError: false };
+try {
+    d = __addDisposableResource(env_1, undefined, false);
+    e = __addDisposableResource(env_1, undefined, true);
+}
+catch (e_1) {
+    env_1.error = e_1;
+    env_1.hasError = true;
+}
+finally {
+    const result_1 = __disposeResources(env_1);
+    if (result_1)
+        await result_1;
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFyaWFibGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidmFyaWFibGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ25CLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDakIsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUVqQixPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFFYixPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUM7Ozs7SUFIUCxtQ0FBSSxTQUFTLFFBQUEsQ0FBQztJQUVSLG1DQUFJLFNBQVMsT0FBQSxDQUFDIn0=
+//// [interface.js] ////
+export {};
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaW50ZXJmYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
+//// [class.js] ////
+var _Bar_d;
+const i = Symbol();
+export class Bar {
+    constructor() {
+        _Bar_d.set(this, void 0);
+    }
+}
+_Bar_d = new WeakMap();
+export class Baz {
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsTUFBTSxDQUFDLEdBQUcsTUFBTSxFQUFFLENBQUM7QUFDbkIsTUFBTSxPQUFPLEdBQUc7SUFBaEI7UUFJSSx5QkFBVztJQU1mLENBQUM7Q0FBQTs7QUFFRCxNQUFNLE9BQWdCLEdBQUc7Q0FHeEIifQ==
+//// [namespace.js] ////
+export var ns;
+(function (ns) {
+    let internal;
+    (function (internal) {
+        class Foo {
+        }
+        internal.Foo = Foo;
+    })(internal || (internal = {}));
+    let nested;
+    (function (nested) {
+        nested.inner = internal;
+    })(nested = ns.nested || (ns.nested = {}));
+})(ns || (ns = {}));
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFtZXNwYWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibmFtZXNwYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sS0FBVyxFQUFFLENBT2xCO0FBUEQsV0FBaUIsRUFBRTtJQUNmLElBQVUsUUFBUSxDQUVqQjtJQUZELFdBQVUsUUFBUTtRQUNkLE1BQWEsR0FBRztTQUFHO1FBQU4sWUFBRyxNQUFHLENBQUE7SUFDdkIsQ0FBQyxFQUZTLFFBQVEsS0FBUixRQUFRLFFBRWpCO0lBQ0QsSUFBaUIsTUFBTSxDQUV0QjtJQUZELFdBQWlCLE1BQU07UUFDTCxZQUFLLEdBQUcsUUFBUSxDQUFDO0lBQ25DLENBQUMsRUFGZ0IsTUFBTSxHQUFOLFNBQU0sS0FBTixTQUFNLFFBRXRCO0FBQ0wsQ0FBQyxFQVBnQixFQUFFLEtBQUYsRUFBRSxRQU9sQiJ9
+//// [alias.js] ////
+export {};
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxpYXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhbGlhcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
diff --git a/tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=false).js b/tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=false).js
new file mode 100644
index 0000000000000..dd7a762bf285b
--- /dev/null
+++ b/tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=false).js
@@ -0,0 +1,145 @@
+//// [variables.ts] ////
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+//// [interface.ts] ////
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+//// [class.ts] ////
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+//// [namespace.ts] ////
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+//// [alias.ts] ////
+export type A<T> = { x: T };
+//// [variables.js] ////
+var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
+    if (value !== null && value !== void 0) {
+        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
+        var dispose, inner;
+        if (async) {
+            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
+            dispose = value[Symbol.asyncDispose];
+        }
+        if (dispose === void 0) {
+            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
+            dispose = value[Symbol.dispose];
+            if (async) inner = dispose;
+        }
+        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
+        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
+        env.stack.push({ value: value, dispose: dispose, async: async });
+    }
+    else if (async) {
+        env.stack.push({ async: true });
+    }
+    return value;
+};
+var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
+    return function (env) {
+        function fail(e) {
+            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
+            env.hasError = true;
+        }
+        var r, s = 0;
+        function next() {
+            while (r = env.stack.pop()) {
+                try {
+                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
+                    if (r.dispose) {
+                        var result = r.dispose.call(r.value);
+                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
+                    }
+                    else s |= 1;
+                }
+                catch (e) {
+                    fail(e);
+                }
+            }
+            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
+            if (env.hasError) throw env.error;
+        }
+        return next();
+    };
+})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
+    var e = new Error(message);
+    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
+});
+export const a = 1;
+export let b = 2;
+export var c = 3;
+export { d };
+export { e };
+var d, e;
+const env_1 = { stack: [], error: void 0, hasError: false };
+try {
+    d = __addDisposableResource(env_1, undefined, false);
+    e = __addDisposableResource(env_1, undefined, true);
+}
+catch (e_1) {
+    env_1.error = e_1;
+    env_1.hasError = true;
+}
+finally {
+    const result_1 = __disposeResources(env_1);
+    if (result_1)
+        await result_1;
+}
+//// [interface.js] ////
+export {};
+//// [class.js] ////
+var _Bar_d;
+const i = Symbol();
+export class Bar {
+    constructor() {
+        _Bar_d.set(this, void 0);
+    }
+}
+_Bar_d = new WeakMap();
+export class Baz {
+}
+//// [namespace.js] ////
+export var ns;
+(function (ns) {
+    let internal;
+    (function (internal) {
+        class Foo {
+        }
+        internal.Foo = Foo;
+    })(internal || (internal = {}));
+    let nested;
+    (function (nested) {
+        nested.inner = internal;
+    })(nested = ns.nested || (ns.nested = {}));
+})(ns || (ns = {}));
+//// [alias.js] ////
+export {};
diff --git a/tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=true).js b/tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=true).js
new file mode 100644
index 0000000000000..c0f0e49c71267
--- /dev/null
+++ b/tests/baselines/reference/transpile/jsWithSourceMapBasic(sourceMap=true).js
@@ -0,0 +1,160 @@
+//// [variables.ts] ////
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+//// [interface.ts] ////
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+//// [class.ts] ////
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+//// [namespace.ts] ////
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+//// [alias.ts] ////
+export type A<T> = { x: T };
+//// [variables.js] ////
+var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
+    if (value !== null && value !== void 0) {
+        if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
+        var dispose, inner;
+        if (async) {
+            if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
+            dispose = value[Symbol.asyncDispose];
+        }
+        if (dispose === void 0) {
+            if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
+            dispose = value[Symbol.dispose];
+            if (async) inner = dispose;
+        }
+        if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
+        if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
+        env.stack.push({ value: value, dispose: dispose, async: async });
+    }
+    else if (async) {
+        env.stack.push({ async: true });
+    }
+    return value;
+};
+var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
+    return function (env) {
+        function fail(e) {
+            env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
+            env.hasError = true;
+        }
+        var r, s = 0;
+        function next() {
+            while (r = env.stack.pop()) {
+                try {
+                    if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
+                    if (r.dispose) {
+                        var result = r.dispose.call(r.value);
+                        if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
+                    }
+                    else s |= 1;
+                }
+                catch (e) {
+                    fail(e);
+                }
+            }
+            if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
+            if (env.hasError) throw env.error;
+        }
+        return next();
+    };
+})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
+    var e = new Error(message);
+    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
+});
+export const a = 1;
+export let b = 2;
+export var c = 3;
+export { d };
+export { e };
+var d, e;
+const env_1 = { stack: [], error: void 0, hasError: false };
+try {
+    d = __addDisposableResource(env_1, undefined, false);
+    e = __addDisposableResource(env_1, undefined, true);
+}
+catch (e_1) {
+    env_1.error = e_1;
+    env_1.hasError = true;
+}
+finally {
+    const result_1 = __disposeResources(env_1);
+    if (result_1)
+        await result_1;
+}
+//# sourceMappingURL=variables.js.map
+//// [variables.js.map] ////
+{"version":3,"file":"variables.js","sourceRoot":"","sources":["variables.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACnB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEjB,OAAO,EAAE,CAAC,EAAE,CAAC;AAEb,OAAO,EAAE,CAAC,EAAE,CAAC;;;;IAHP,mCAAI,SAAS,QAAA,CAAC;IAER,mCAAI,SAAS,OAAA,CAAC"}
+//// [interface.js] ////
+export {};
+//# sourceMappingURL=interface.js.map
+//// [interface.js.map] ////
+{"version":3,"file":"interface.js","sourceRoot":"","sources":["interface.ts"],"names":[],"mappings":""}
+//// [class.js] ////
+var _Bar_d;
+const i = Symbol();
+export class Bar {
+    constructor() {
+        _Bar_d.set(this, void 0);
+    }
+}
+_Bar_d = new WeakMap();
+export class Baz {
+}
+//# sourceMappingURL=class.js.map
+//// [class.js.map] ////
+{"version":3,"file":"class.js","sourceRoot":"","sources":["class.ts"],"names":[],"mappings":";AAAA,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;AACnB,MAAM,OAAO,GAAG;IAAhB;QAII,yBAAW;IAMf,CAAC;CAAA;;AAED,MAAM,OAAgB,GAAG;CAGxB"}
+//// [namespace.js] ////
+export var ns;
+(function (ns) {
+    let internal;
+    (function (internal) {
+        class Foo {
+        }
+        internal.Foo = Foo;
+    })(internal || (internal = {}));
+    let nested;
+    (function (nested) {
+        nested.inner = internal;
+    })(nested = ns.nested || (ns.nested = {}));
+})(ns || (ns = {}));
+//# sourceMappingURL=namespace.js.map
+//// [namespace.js.map] ////
+{"version":3,"file":"namespace.js","sourceRoot":"","sources":["namespace.ts"],"names":[],"mappings":"AAAA,MAAM,KAAW,EAAE,CAOlB;AAPD,WAAiB,EAAE;IACf,IAAU,QAAQ,CAEjB;IAFD,WAAU,QAAQ;QACd,MAAa,GAAG;SAAG;QAAN,YAAG,MAAG,CAAA;IACvB,CAAC,EAFS,QAAQ,KAAR,QAAQ,QAEjB;IACD,IAAiB,MAAM,CAEtB;IAFD,WAAiB,MAAM;QACL,YAAK,GAAG,QAAQ,CAAC;IACnC,CAAC,EAFgB,MAAM,GAAN,SAAM,KAAN,SAAM,QAEtB;AACL,CAAC,EAPgB,EAAE,KAAF,EAAE,QAOlB"}
+//// [alias.js] ////
+export {};
+//# sourceMappingURL=alias.js.map
+//// [alias.js.map] ////
+{"version":3,"file":"alias.js","sourceRoot":"","sources":["alias.ts"],"names":[],"mappings":""}
diff --git a/tests/cases/transpile/declarationBasicSyntax.ts b/tests/cases/transpile/declarationBasicSyntax.ts
index 606808e509b47..7ed0ce9368ae1 100644
--- a/tests/cases/transpile/declarationBasicSyntax.ts
+++ b/tests/cases/transpile/declarationBasicSyntax.ts
@@ -1,4 +1,5 @@
 // @declaration: true
+// @declarationMap: true,false
 // @target: es6
 // @filename: variables.ts
 export const a = 1;
diff --git a/tests/cases/transpile/jsWithInlineSourceMapBasic.ts b/tests/cases/transpile/jsWithInlineSourceMapBasic.ts
new file mode 100644
index 0000000000000..89f9546f2938b
--- /dev/null
+++ b/tests/cases/transpile/jsWithInlineSourceMapBasic.ts
@@ -0,0 +1,45 @@
+// @inlineSourceMap: true,false
+// @target: es6
+// @filename: variables.ts
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+// @filename: interface.ts
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+// @filename: class.ts
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+// @filename: namespace.ts
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+// @filename: alias.ts
+export type A<T> = { x: T };
\ No newline at end of file
diff --git a/tests/cases/transpile/jsWithSourceMapBasic.ts b/tests/cases/transpile/jsWithSourceMapBasic.ts
new file mode 100644
index 0000000000000..914133536c272
--- /dev/null
+++ b/tests/cases/transpile/jsWithSourceMapBasic.ts
@@ -0,0 +1,45 @@
+// @sourceMap: true,false
+// @target: es6
+// @filename: variables.ts
+export const a = 1;
+export let b = 2;
+export var c = 3;
+using d = undefined;
+export { d };
+await using e = undefined;
+export { e };
+// @filename: interface.ts
+export interface Foo {
+    a: string;
+    readonly b: string;
+    c?: string;
+}
+// @filename: class.ts
+const i = Symbol();
+export class Bar {
+    a: string;
+    b?: string;
+    declare c: string;
+    #d: string;
+    public e: string;
+    protected f: string;
+    private g: string;
+    ["h"]: string;
+    [i]: string;
+}
+
+export abstract class Baz {
+    abstract a: string;
+    abstract method(): void;
+}
+// @filename: namespace.ts
+export namespace ns {
+    namespace internal {
+        export class Foo {}
+    }
+    export namespace nested {
+        export import inner = internal;
+    }
+}
+// @filename: alias.ts
+export type A<T> = { x: T };
\ No newline at end of file