diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts
index b91399e8ee1..ecea3a76673 100644
--- a/src/compiler/diagnosticInformationMap.generated.ts
+++ b/src/compiler/diagnosticInformationMap.generated.ts
@@ -509,7 +509,6 @@ namespace ts {
Option_noEmit_cannot_be_specified_with_option_out_or_outDir: { code: 5040, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'out' or 'outDir'." },
Option_noEmit_cannot_be_specified_with_option_declaration: { code: 5041, category: DiagnosticCategory.Error, key: "Option 'noEmit' cannot be specified with option 'declaration'." },
Option_project_cannot_be_mixed_with_source_files_on_a_command_line: { code: 5042, category: DiagnosticCategory.Error, key: "Option 'project' cannot be mixed with source files on a command line." },
- Option_sourceMap_cannot_be_specified_with_option_isolatedModules: { code: 5043, category: DiagnosticCategory.Error, key: "Option 'sourceMap' cannot be specified with option 'isolatedModules'." },
Option_declaration_cannot_be_specified_with_option_isolatedModules: { code: 5044, category: DiagnosticCategory.Error, key: "Option 'declaration' cannot be specified with option 'isolatedModules'." },
Option_noEmitOnError_cannot_be_specified_with_option_isolatedModules: { code: 5045, category: DiagnosticCategory.Error, key: "Option 'noEmitOnError' cannot be specified with option 'isolatedModules'." },
Option_out_cannot_be_specified_with_option_isolatedModules: { code: 5046, category: DiagnosticCategory.Error, key: "Option 'out' cannot be specified with option 'isolatedModules'." },
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 9fda73740ba..2765d04f400 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -2025,10 +2025,6 @@
"category": "Error",
"code": 5042
},
- "Option 'sourceMap' cannot be specified with option 'isolatedModules'.": {
- "category": "Error",
- "code": 5043
- },
"Option 'declaration' cannot be specified with option 'isolatedModules'.": {
"category": "Error",
"code": 5044
diff --git a/src/compiler/program.ts b/src/compiler/program.ts
index 5ce4846b43b..b8f48a0fd63 100644
--- a/src/compiler/program.ts
+++ b/src/compiler/program.ts
@@ -341,7 +341,7 @@ namespace ts {
});
}
- function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
+ function getDeclarationDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
return runWithCancellationToken(() => {
if (!isDeclarationFile(sourceFile)) {
let resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
@@ -350,7 +350,7 @@ namespace ts {
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
}
});
- }
+ }
function getOptionsDiagnostics(): Diagnostic[] {
let allDiagnostics: Diagnostic[] = [];
@@ -602,10 +602,6 @@ namespace ts {
function verifyCompilerOptions() {
if (options.isolatedModules) {
- if (options.sourceMap) {
- diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_sourceMap_cannot_be_specified_with_option_isolatedModules));
- }
-
if (options.declaration) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_declaration_cannot_be_specified_with_option_isolatedModules));
}
diff --git a/src/services/services.ts b/src/services/services.ts
index 16f5b0b91fe..de4004000d4 100644
--- a/src/services/services.ts
+++ b/src/services/services.ts
@@ -1754,18 +1754,31 @@ namespace ts {
sourceFile.version = version;
sourceFile.scriptSnapshot = scriptSnapshot;
}
-
+
+ export interface TranspileOptions {
+ compilerOptions?: CompilerOptions;
+ fileName?: string;
+ reportDiagnostics?: boolean;
+ moduleName?: string;
+ }
+
+ export interface TranspileOutput {
+ outputText: string;
+ diagnostics?: Diagnostic[];
+ sourceMapText?: string;
+ }
+
/*
* This function will compile source text from 'input' argument using specified compiler options.
* If not options are provided - it will use a set of default compiler options.
- * Extra compiler options that will unconditionally be used bu this function are:
+ * Extra compiler options that will unconditionally be used by this function are:
* - isolatedModules = true
* - allowNonTsExtensions = true
* - noLib = true
* - noResolve = true
- */
- export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
- let options = compilerOptions ? clone(compilerOptions) : getDefaultCompilerOptions();
+ */
+ export function transpileModule(input: string, transpileOptions?: TranspileOptions): TranspileOutput {
+ let options = transpileOptions.compilerOptions ? clone(transpileOptions.compilerOptions) : getDefaultCompilerOptions();
options.isolatedModules = true;
@@ -1781,23 +1794,30 @@ namespace ts {
options.noResolve = true;
// Parse
- let inputFileName = fileName || "module.ts";
+ let inputFileName = transpileOptions.fileName || "module.ts";
let sourceFile = createSourceFile(inputFileName, input, options.target);
- if (moduleName) {
- sourceFile.moduleName = moduleName;
+ if (transpileOptions.moduleName) {
+ sourceFile.moduleName = transpileOptions.moduleName;
}
let newLine = getNewLineCharacter(options);
// Output
let outputText: string;
+ let sourceMapText: string;
// Create a compilerHost object to allow the compiler to read and write files
let compilerHost: CompilerHost = {
getSourceFile: (fileName, target) => fileName === inputFileName ? sourceFile : undefined,
writeFile: (name, text, writeByteOrderMark) => {
- Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
- outputText = text;
+ if (fileExtensionIs(name, ".map")) {
+ Debug.assert(sourceMapText === undefined, `Unexpected multiple source map outputs for the file '${name}'`);
+ sourceMapText = text;
+ }
+ else {
+ Debug.assert(outputText === undefined, "Unexpected multiple outputs for the file: " + name);
+ outputText = text;
+ }
},
getDefaultLibFileName: () => "lib.d.ts",
useCaseSensitiveFileNames: () => false,
@@ -1807,16 +1827,29 @@ namespace ts {
};
let program = createProgram([inputFileName], options, compilerHost);
-
- addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
- addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
-
+
+ let diagnostics: Diagnostic[];
+ if (transpileOptions.reportDiagnostics) {
+ diagnostics = [];
+ addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile));
+ addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics());
+ }
// Emit
program.emit();
Debug.assert(outputText !== undefined, "Output generation failed");
- return outputText;
+ return { outputText, diagnostics, sourceMapText };
+ }
+
+ /*
+ * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result.
+ */
+ export function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string {
+ let output = transpileModule(input, { compilerOptions, fileName, reportDiagnostics: !!diagnostics, moduleName });
+ // addRange correctly handles cases when wither 'from' or 'to' argument is missing
+ addRange(diagnostics, output.diagnostics);
+ return output.outputText;
}
export function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile {
diff --git a/tests/baselines/reference/isolatedModulesSourceMap.errors.txt b/tests/baselines/reference/isolatedModulesSourceMap.errors.txt
deleted file mode 100644
index 6383e85ecd5..00000000000
--- a/tests/baselines/reference/isolatedModulesSourceMap.errors.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'.
-
-
-!!! error TS5043: Option 'sourceMap' cannot be specified with option 'isolatedModules'.
-==== tests/cases/compiler/isolatedModulesSourceMap.ts (0 errors) ====
-
- export var x;
\ No newline at end of file
diff --git a/tests/baselines/reference/isolatedModulesSourceMap.js b/tests/baselines/reference/isolatedModulesSourceMap.js
index ca6f4b4190e..2722a3ce7ab 100644
--- a/tests/baselines/reference/isolatedModulesSourceMap.js
+++ b/tests/baselines/reference/isolatedModulesSourceMap.js
@@ -1,7 +1,7 @@
//// [isolatedModulesSourceMap.ts]
-export var x;
+export var x = 1;
//// [isolatedModulesSourceMap.js]
-export var x;
+export var x = 1;
//# sourceMappingURL=isolatedModulesSourceMap.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/isolatedModulesSourceMap.js.map b/tests/baselines/reference/isolatedModulesSourceMap.js.map
index 8e505dcda7a..9fa3e0da0d6 100644
--- a/tests/baselines/reference/isolatedModulesSourceMap.js.map
+++ b/tests/baselines/reference/isolatedModulesSourceMap.js.map
@@ -1,2 +1,2 @@
//// [isolatedModulesSourceMap.js.map]
-{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,CAAC"}
\ No newline at end of file
+{"version":3,"file":"isolatedModulesSourceMap.js","sourceRoot":"","sources":["isolatedModulesSourceMap.ts"],"names":[],"mappings":"AACA,WAAW,CAAC,GAAG,CAAC,CAAC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt b/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt
index 5c6b7659bc6..d31445505f7 100644
--- a/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt
+++ b/tests/baselines/reference/isolatedModulesSourceMap.sourcemap.txt
@@ -8,20 +8,26 @@ sources: isolatedModulesSourceMap.ts
emittedFile:tests/cases/compiler/isolatedModulesSourceMap.js
sourceFile:isolatedModulesSourceMap.ts
-------------------------------------------------------------------
->>>export var x;
+>>>export var x = 1;
1 >
2 >^^^^^^^^^^^
3 > ^
-4 > ^
-5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+4 > ^^^
+5 > ^
+6 > ^
+7 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^->
1 >
>
2 >export var
3 > x
-4 > ;
+4 > =
+5 > 1
+6 > ;
1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0)
2 >Emitted(1, 12) Source(2, 12) + SourceIndex(0)
3 >Emitted(1, 13) Source(2, 13) + SourceIndex(0)
-4 >Emitted(1, 14) Source(2, 14) + SourceIndex(0)
+4 >Emitted(1, 16) Source(2, 16) + SourceIndex(0)
+5 >Emitted(1, 17) Source(2, 17) + SourceIndex(0)
+6 >Emitted(1, 18) Source(2, 18) + SourceIndex(0)
---
>>>//# sourceMappingURL=isolatedModulesSourceMap.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/isolatedModulesSourceMap.symbols b/tests/baselines/reference/isolatedModulesSourceMap.symbols
new file mode 100644
index 00000000000..d4ae3c34cf1
--- /dev/null
+++ b/tests/baselines/reference/isolatedModulesSourceMap.symbols
@@ -0,0 +1,5 @@
+=== tests/cases/compiler/isolatedModulesSourceMap.ts ===
+
+export var x = 1;
+>x : Symbol(x, Decl(isolatedModulesSourceMap.ts, 1, 10))
+
diff --git a/tests/baselines/reference/isolatedModulesSourceMap.types b/tests/baselines/reference/isolatedModulesSourceMap.types
new file mode 100644
index 00000000000..1955fe5da6e
--- /dev/null
+++ b/tests/baselines/reference/isolatedModulesSourceMap.types
@@ -0,0 +1,6 @@
+=== tests/cases/compiler/isolatedModulesSourceMap.ts ===
+
+export var x = 1;
+>x : number
+>1 : number
+
diff --git a/tests/cases/compiler/isolatedModulesSourceMap.ts b/tests/cases/compiler/isolatedModulesSourceMap.ts
index 31dd4d9f0cf..465941d9a8b 100644
--- a/tests/cases/compiler/isolatedModulesSourceMap.ts
+++ b/tests/cases/compiler/isolatedModulesSourceMap.ts
@@ -3,4 +3,4 @@
// @target: es6
// @filename: file1.ts
-export var x;
\ No newline at end of file
+export var x = 1;
\ No newline at end of file
diff --git a/tests/cases/unittests/transpile.ts b/tests/cases/unittests/transpile.ts
index fcce034b227..1fd8c860d01 100644
--- a/tests/cases/unittests/transpile.ts
+++ b/tests/cases/unittests/transpile.ts
@@ -2,58 +2,120 @@
module ts {
describe("Transpile", () => {
-
- function runTest(input: string, compilerOptions: ts.CompilerOptions = {}, fileName?: string, moduleName?: string, expectedOutput?: string, expectedDiagnosticCodes: number[] = []): void {
- let diagnostics: Diagnostic[] = [];
- let result = transpile(input, compilerOptions, fileName || "file.ts", diagnostics, moduleName);
-
+
+ interface TranspileTestSettings {
+ options?: TranspileOptions;
+ expectedOutput?: string;
+ expectedDiagnosticCodes?: number[];
+ }
+
+ function checkDiagnostics(diagnostics: Diagnostic[], expectedDiagnosticCodes?: number[]) {
+ if(!expectedDiagnosticCodes) {
+ return;
+ }
+
for (let i = 0; i < expectedDiagnosticCodes.length; i++) {
assert.equal(expectedDiagnosticCodes[i], diagnostics[i] && diagnostics[i].code, `Could not find expeced diagnostic.`);
}
- assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
-
- if (expectedOutput !== undefined) {
- assert.equal(result, expectedOutput);
- }
+ assert.equal(diagnostics.length, expectedDiagnosticCodes.length, "Resuting diagnostics count does not match expected");
}
+
+ function test(input: string, testSettings: TranspileTestSettings): void {
+ let diagnostics: Diagnostic[] = [];
+
+ let transpileOptions: TranspileOptions = testSettings.options || {};
+ let transpileResult = transpile(input, transpileOptions.compilerOptions, transpileOptions.fileName, diagnostics, transpileOptions.moduleName);
+
+ transpileOptions.reportDiagnostics = true;
+ let transpileModuleResult = transpileModule(input, transpileOptions);
+
+ checkDiagnostics(diagnostics, testSettings.expectedDiagnosticCodes);
+ checkDiagnostics(transpileModuleResult.diagnostics, testSettings.expectedDiagnosticCodes);
+
+ if (testSettings.expectedOutput !== undefined) {
+ assert.equal(transpileResult, testSettings.expectedOutput);
+ assert.equal(transpileModuleResult.outputText, testSettings.expectedOutput);
+ }
+
+ // check source maps
+ if (!transpileOptions.compilerOptions) {
+ transpileOptions.compilerOptions = {};
+ }
+
+ if (!transpileOptions.fileName) {
+ transpileOptions.fileName = "file.ts";
+ }
+
+ transpileOptions.compilerOptions.sourceMap = true;
+ let transpileModuleResultWithSourceMap = transpileModule(input, transpileOptions);
+ assert.isTrue(transpileModuleResultWithSourceMap.sourceMapText !== undefined);
+
+ let expectedSourceMapFileName = removeFileExtension(transpileOptions.fileName) + ".js.map";
+ let expectedSourceMappingUrlLine = `//# sourceMappingURL=${expectedSourceMapFileName}`;
+
+ if (testSettings.expectedOutput !== undefined) {
+ assert.equal(transpileModuleResultWithSourceMap.outputText, testSettings.expectedOutput + expectedSourceMappingUrlLine);
+ }
+ else {
+ // expected output is not set, just verify that output text has sourceMappingURL as a last line
+ let output = transpileModuleResultWithSourceMap.outputText;
+ assert.isTrue(output.length >= expectedSourceMappingUrlLine.length);
+ if (output.length === expectedSourceMappingUrlLine.length) {
+ assert.equal(output, expectedSourceMappingUrlLine);
+ }
+ else {
+ let suffix = getNewLineCharacter(transpileOptions.compilerOptions) + expectedSourceMappingUrlLine
+ assert.isTrue(output.indexOf(suffix, output.length - suffix.length) !== -1);
+ }
+ }
+ }
+
it("Generates correct compilerOptions diagnostics", () => {
// Expecting 5047: "Option 'isolatedModules' can only be used when either option'--module' is provided or option 'target' is 'ES6' or higher."
- runTest(`var x = 0;`, {}, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [5047]);
+ test(`var x = 0;`, { expectedDiagnosticCodes: [5047] });
});
it("Generates no diagnostics with valid inputs", () => {
// No errors
- runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
+ test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates no diagnostics for missing file references", () => {
- runTest(`///
-var x = 0;`,
- { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
+ test(`///
+var x = 0;`,
+ { options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates no diagnostics for missing module imports", () => {
- runTest(`import {a} from "module2";`,
- { module: ModuleKind.CommonJS }, /*fileName*/ undefined,/*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
+ test(`import {a} from "module2";`,
+ { options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates expected syntactic diagnostics", () => {
- runTest(`a b`,
- { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ [1005]); /// 1005: ';' Expected
+ test(`a b`,
+ { options: { compilerOptions: { module: ModuleKind.CommonJS } }, expectedDiagnosticCodes: [1005] }); /// 1005: ';' Expected
});
it("Does not generate semantic diagnostics", () => {
- runTest(`var x: string = 0;`,
- { module: ModuleKind.CommonJS }, /*fileName*/ undefined, /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/ []);
+ test(`var x: string = 0;`,
+ { options: { compilerOptions: { module: ModuleKind.CommonJS } } });
});
it("Generates module output", () => {
- runTest(`var x = 0;`, { module: ModuleKind.AMD }, /*fileName*/ undefined, /*moduleName*/undefined, `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`);
+ test(`var x = 0;`,
+ {
+ options: { compilerOptions: { module: ModuleKind.AMD } },
+ expectedOutput: `define(["require", "exports"], function (require, exports) {\r\n var x = 0;\r\n});\r\n`
+ });
});
it("Uses correct newLine character", () => {
- runTest(`var x = 0;`, { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, /*moduleName*/undefined, `var x = 0;\n`, /*expectedDiagnosticCodes*/ []);
+ test(`var x = 0;`,
+ {
+ options: { compilerOptions: { module: ModuleKind.CommonJS, newLine: NewLineKind.LineFeed } },
+ expectedOutput: `var x = 0;\n`
+ });
});
it("Sets module name", () => {
@@ -66,12 +128,15 @@ var x = 0;`,
` }\n` +
` }\n` +
`});\n`;
- runTest("var x = 1;", { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, /*fileName*/ undefined, "NamedModule", output)
+ test("var x = 1;",
+ {
+ options: { compilerOptions: { module: ModuleKind.System, newLine: NewLineKind.LineFeed }, moduleName: "NamedModule" },
+ expectedOutput: output
+ })
});
it("No extra errors for file without extension", () => {
- runTest(`var x = 0;`, { module: ModuleKind.CommonJS }, "file", /*moduleName*/undefined, /*expectedOutput*/ undefined, /*expectedDiagnosticCodes*/[]);
+ test(`var x = 0;`, { options: { compilerOptions: { module: ModuleKind.CommonJS }, fileName: "file" } });
});
-
});
}