diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts
index 8169421ca1763..47f0594a76e65 100644
--- a/src/compiler/commandLineParser.ts
+++ b/src/compiler/commandLineParser.ts
@@ -110,6 +110,13 @@ module ts {
type: "boolean",
description: Diagnostics.Do_not_emit_comments_to_output,
},
+ {
+ name: "rootDir",
+ type: "string",
+ isFilePath: true,
+ description: Diagnostics.Specifies_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
+ paramType: Diagnostics.LOCATION,
+ },
{
name: "separateCompilation",
type: "boolean",
diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts
index f3e9c325da611..90f0ed0a0dfce 100644
--- a/src/compiler/diagnosticInformationMap.generated.ts
+++ b/src/compiler/diagnosticInformationMap.generated.ts
@@ -496,6 +496,8 @@ module ts {
Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: { code: 6055, category: DiagnosticCategory.Message, key: "Suppress noImplicitAny errors for indexing objects lacking index signatures." },
Do_not_emit_declarations_for_code_that_has_an_internal_annotation: { code: 6056, category: DiagnosticCategory.Message, key: "Do not emit declarations for code that has an '@internal' annotation." },
Preserve_new_lines_when_emitting_code: { code: 6057, category: DiagnosticCategory.Message, key: "Preserve new-lines when emitting code." },
+ Specifies_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir: { code: 6058, category: DiagnosticCategory.Message, key: "Specifies the root directory of input files. Use to control the output directory structure with --outDir." },
+ File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files: { code: 6059, category: DiagnosticCategory.Error, key: "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." },
diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json
index 61ce23c316bd5..48ef245c76612 100644
--- a/src/compiler/diagnosticMessages.json
+++ b/src/compiler/diagnosticMessages.json
@@ -1972,6 +1972,15 @@
"category": "Message",
"code": 6057
},
+ "Specifies the root directory of input files. Use to control the output directory structure with --outDir.": {
+ "category": "Message",
+ "code": 6058
+ },
+ "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files.": {
+ "category": "Error",
+ "code": 6059
+ },
+
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
diff --git a/src/compiler/program.ts b/src/compiler/program.ts
index a27f943dc7e5f..d49e01bd45d68 100644
--- a/src/compiler/program.ts
+++ b/src/compiler/program.ts
@@ -455,6 +455,66 @@ module ts {
}
}
+ function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string {
+ let commonPathComponents: string[];
+ let currentDirectory = host.getCurrentDirectory();
+ forEach(files, sourceFile => {
+ // Each file contributes into common source file path
+ if (isDeclarationFile(sourceFile)) {
+ return;
+ }
+
+ let sourcePathComponents = getNormalizedPathComponents(sourceFile.fileName, currentDirectory);
+ sourcePathComponents.pop(); // The base file name is not part of the common directory path
+
+ if (!commonPathComponents) {
+ // first file
+ commonPathComponents = sourcePathComponents;
+ return;
+ }
+
+ for (let i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); i < n; i++) {
+ if (commonPathComponents[i] !== sourcePathComponents[i]) {
+ if (i === 0) {
+ diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
+ return;
+ }
+
+ // New common path found that is 0 -> i-1
+ commonPathComponents.length = i;
+ break;
+ }
+ }
+
+ // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents
+ if (sourcePathComponents.length < commonPathComponents.length) {
+ commonPathComponents.length = sourcePathComponents.length;
+ }
+ });
+
+ return getNormalizedPathFromPathComponents(commonPathComponents);
+ }
+
+ function checkSourceFilesBelongToPath(sourceFiles: SourceFile[], rootDirectory: string): boolean {
+ let allFilesBelongToPath = true;
+ if (sourceFiles) {
+ let currentDirectory = host.getCurrentDirectory();
+ let absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
+
+ for (var sourceFile of sourceFiles) {
+ if (!isDeclarationFile(sourceFile)) {
+ let absoluteSourceFilePath = host.getCanonicalFileName(getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory));
+ if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) {
+ diagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir));
+ allFilesBelongToPath = false;
+ }
+ }
+ }
+ }
+
+ return allFilesBelongToPath;
+ }
+
function verifyCompilerOptions() {
if (options.separateCompilation) {
if (options.sourceMap) {
@@ -517,41 +577,16 @@ module ts {
(options.mapRoot && // there is --mapRoot specified and there would be multiple js files generated
(!options.out || firstExternalModuleSourceFile !== undefined))) {
- let commonPathComponents: string[];
- forEach(files, sourceFile => {
- // Each file contributes into common source file path
- if (!(sourceFile.flags & NodeFlags.DeclarationFile)
- && !fileExtensionIs(sourceFile.fileName, ".js")) {
- let sourcePathComponents = getNormalizedPathComponents(sourceFile.fileName, host.getCurrentDirectory());
- sourcePathComponents.pop(); // FileName is not part of directory
- if (commonPathComponents) {
- for (let i = 0; i < Math.min(commonPathComponents.length, sourcePathComponents.length); i++) {
- if (commonPathComponents[i] !== sourcePathComponents[i]) {
- if (i === 0) {
- diagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files));
- return;
- }
-
- // New common path found that is 0 -> i-1
- commonPathComponents.length = i;
- break;
- }
- }
-
- // If the fileComponent path completely matched and less than already found update the length
- if (sourcePathComponents.length < commonPathComponents.length) {
- commonPathComponents.length = sourcePathComponents.length;
- }
- }
- else {
- // first file
- commonPathComponents = sourcePathComponents;
- }
- }
- });
+ if (options.rootDir && checkSourceFilesBelongToPath(files, options.rootDir)) {
+ // If a rootDir is specified and is valid use it as the commonSourceDirectory
+ commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, host.getCurrentDirectory());
+ }
+ else {
+ // Compute the commonSourceDirectory from the input files
+ commonSourceDirectory = computeCommonSourceDirectory(files);
+ }
- commonSourceDirectory = getNormalizedPathFromPathComponents(commonPathComponents);
- if (commonSourceDirectory) {
+ if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
// Make sure directory path ends with directory separator so this string can directly
// used to replace with "" to get the relative path of the source file and the relative path doesn't
// start with / making it rooted path
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 9191a6999bf50..bff15a1ab9d03 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -1654,6 +1654,7 @@ module ts {
preserveConstEnums?: boolean;
project?: string;
removeComments?: boolean;
+ rootDir?: string;
sourceMap?: boolean;
sourceRoot?: string;
suppressImplicitAnyIndexErrors?: boolean;
diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts
index 3291128a7a543..6823bfafac28a 100644
--- a/src/harness/projectsRunner.ts
+++ b/src/harness/projectsRunner.ts
@@ -18,6 +18,7 @@ interface ProjectRunnerTestCase {
runTest?: boolean; // Run the resulting test
bug?: string; // If there is any bug associated with this test case
noResolve?: boolean;
+ rootDir?: string; // --rootDir
}
interface ProjectRunnerTestCaseResolutionInfo extends ProjectRunnerTestCase {
@@ -160,7 +161,8 @@ class ProjectRunner extends RunnerBase {
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? ts.sys.resolvePath(testCase.mapRoot) : testCase.mapRoot,
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? ts.sys.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
module: moduleKind,
- noResolve: testCase.noResolve
+ noResolve: testCase.noResolve,
+ rootDir: testCase.rootDir
};
}
@@ -344,6 +346,7 @@ class ProjectRunner extends RunnerBase {
baselineCheck: testCase.baselineCheck,
runTest: testCase.runTest,
bug: testCase.bug,
+ rootDir: testCase.rootDir,
resolvedInputFiles: ts.map(compilerResult.program.getSourceFiles(), inputFile => inputFile.fileName),
emittedFiles: ts.map(compilerResult.outputFiles, outputFile => outputFile.emittedFileName)
};
diff --git a/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.d.ts b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.d.ts
new file mode 100644
index 0000000000000..8147620b2111b
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.d.ts
@@ -0,0 +1,2 @@
+declare class C {
+}
diff --git a/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.js b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.js
new file mode 100644
index 0000000000000..8840c2117cfd2
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.js
@@ -0,0 +1,6 @@
+var C = (function () {
+ function C() {
+ }
+ return C;
+})();
+//# sourceMappingURL=fileC.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.js.map b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.js.map
new file mode 100644
index 0000000000000..de54805ee5425
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/FolderC/fileC.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileC.js","sourceRoot":"","sources":["../../../../FolderA/FolderB/FolderC/fileC.ts"],"names":["C","C.constructor"],"mappings":"AAAA;IAAAA;IACAC,CAACA;IAADD,QAACA;AAADA,CAACA,AADD,IACC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.d.ts b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.d.ts
new file mode 100644
index 0000000000000..4ff813c3839e8
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.d.ts
@@ -0,0 +1,4 @@
+///
+declare class B {
+ c: C;
+}
diff --git a/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.js b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.js
new file mode 100644
index 0000000000000..84af55d2d89e1
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.js
@@ -0,0 +1,7 @@
+///
+var B = (function () {
+ function B() {
+ }
+ return B;
+})();
+//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.js.map b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.js.map
new file mode 100644
index 0000000000000..d1c844d32478d
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/outdir/simple/FolderB/fileB.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileB.js","sourceRoot":"","sources":["../../../FolderA/FolderB/fileB.ts"],"names":["B","B.constructor"],"mappings":"AACA,AADA,wCAAwC;;IACxCA;IAEAC,CAACA;IAADD,QAACA;AAADA,CAACA,AAFD,IAEC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/amd/rootDirectory.json b/tests/baselines/reference/project/rootDirectory/amd/rootDirectory.json
new file mode 100644
index 0000000000000..2ec18b3ac5acf
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/rootDirectory.json
@@ -0,0 +1,25 @@
+{
+ "scenario": "rootDirectory: specify rootDirectory",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "sourceMap": true,
+ "declaration": true,
+ "baselineCheck": true,
+ "rootDir": "FolderA",
+ "resolvedInputFiles": [
+ "lib.d.ts",
+ "FolderA/FolderB/FolderC/fileC.ts",
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "emittedFiles": [
+ "outdir/simple/FolderB/FolderC/fileC.js.map",
+ "outdir/simple/FolderB/FolderC/fileC.js",
+ "outdir/simple/FolderB/FolderC/fileC.d.ts",
+ "outdir/simple/FolderB/fileB.js.map",
+ "outdir/simple/FolderB/fileB.js",
+ "outdir/simple/FolderB/fileB.d.ts"
+ ]
+}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/amd/rootDirectory.sourcemap.txt b/tests/baselines/reference/project/rootDirectory/amd/rootDirectory.sourcemap.txt
new file mode 100644
index 0000000000000..83ee3b40181b4
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/amd/rootDirectory.sourcemap.txt
@@ -0,0 +1,123 @@
+===================================================================
+JsFile: fileC.js
+mapUrl: fileC.js.map
+sourceRoot:
+sources: ../../../../FolderA/FolderB/FolderC/fileC.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/FolderC/fileC.js
+sourceFile:../../../../FolderA/FolderB/FolderC/fileC.ts
+-------------------------------------------------------------------
+>>>var C = (function () {
+1 >
+2 >^^^^^^^^^^^^^^^^^^^->
+1 >
+1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+---
+>>> function C() {
+1->^^^^
+2 > ^^->
+1->
+1->Emitted(2, 5) Source(1, 1) + SourceIndex(0) name (C)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class C {
+ >
+2 > }
+1->Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (C.constructor)
+2 >Emitted(3, 6) Source(2, 2) + SourceIndex(0) name (C.constructor)
+---
+>>> return C;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(4, 5) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(4, 13) Source(2, 2) + SourceIndex(0) name (C)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class C {
+ > }
+1 >Emitted(5, 1) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(5, 2) Source(2, 2) + SourceIndex(0) name (C)
+3 >Emitted(5, 2) Source(1, 1) + SourceIndex(0)
+4 >Emitted(5, 6) Source(2, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileC.js.map===================================================================
+JsFile: fileB.js
+mapUrl: fileB.js.map
+sourceRoot:
+sources: ../../../FolderA/FolderB/fileB.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/fileB.js
+sourceFile:../../../FolderA/FolderB/fileB.ts
+-------------------------------------------------------------------
+>>>///
+1 >
+2 >
+3 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1 >///
+ >
+2 >
+3 >///
+1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0)
+2 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+3 >Emitted(1, 41) Source(1, 41) + SourceIndex(0)
+---
+>>>var B = (function () {
+>>> function B() {
+1 >^^^^
+2 > ^^->
+1 >
+ >
+1 >Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (B)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class B {
+ > public c: C;
+ >
+2 > }
+1->Emitted(4, 5) Source(4, 1) + SourceIndex(0) name (B.constructor)
+2 >Emitted(4, 6) Source(4, 2) + SourceIndex(0) name (B.constructor)
+---
+>>> return B;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(5, 5) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(5, 13) Source(4, 2) + SourceIndex(0) name (B)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class B {
+ > public c: C;
+ > }
+1 >Emitted(6, 1) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(6, 2) Source(4, 2) + SourceIndex(0) name (B)
+3 >Emitted(6, 2) Source(2, 1) + SourceIndex(0)
+4 >Emitted(6, 6) Source(4, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.d.ts b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.d.ts
new file mode 100644
index 0000000000000..8147620b2111b
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.d.ts
@@ -0,0 +1,2 @@
+declare class C {
+}
diff --git a/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.js b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.js
new file mode 100644
index 0000000000000..8840c2117cfd2
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.js
@@ -0,0 +1,6 @@
+var C = (function () {
+ function C() {
+ }
+ return C;
+})();
+//# sourceMappingURL=fileC.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.js.map b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.js.map
new file mode 100644
index 0000000000000..de54805ee5425
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/FolderC/fileC.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileC.js","sourceRoot":"","sources":["../../../../FolderA/FolderB/FolderC/fileC.ts"],"names":["C","C.constructor"],"mappings":"AAAA;IAAAA;IACAC,CAACA;IAADD,QAACA;AAADA,CAACA,AADD,IACC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.d.ts b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.d.ts
new file mode 100644
index 0000000000000..4ff813c3839e8
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.d.ts
@@ -0,0 +1,4 @@
+///
+declare class B {
+ c: C;
+}
diff --git a/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.js b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.js
new file mode 100644
index 0000000000000..84af55d2d89e1
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.js
@@ -0,0 +1,7 @@
+///
+var B = (function () {
+ function B() {
+ }
+ return B;
+})();
+//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.js.map b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.js.map
new file mode 100644
index 0000000000000..d1c844d32478d
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/outdir/simple/FolderB/fileB.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileB.js","sourceRoot":"","sources":["../../../FolderA/FolderB/fileB.ts"],"names":["B","B.constructor"],"mappings":"AACA,AADA,wCAAwC;;IACxCA;IAEAC,CAACA;IAADD,QAACA;AAADA,CAACA,AAFD,IAEC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/node/rootDirectory.json b/tests/baselines/reference/project/rootDirectory/node/rootDirectory.json
new file mode 100644
index 0000000000000..2ec18b3ac5acf
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/rootDirectory.json
@@ -0,0 +1,25 @@
+{
+ "scenario": "rootDirectory: specify rootDirectory",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "sourceMap": true,
+ "declaration": true,
+ "baselineCheck": true,
+ "rootDir": "FolderA",
+ "resolvedInputFiles": [
+ "lib.d.ts",
+ "FolderA/FolderB/FolderC/fileC.ts",
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "emittedFiles": [
+ "outdir/simple/FolderB/FolderC/fileC.js.map",
+ "outdir/simple/FolderB/FolderC/fileC.js",
+ "outdir/simple/FolderB/FolderC/fileC.d.ts",
+ "outdir/simple/FolderB/fileB.js.map",
+ "outdir/simple/FolderB/fileB.js",
+ "outdir/simple/FolderB/fileB.d.ts"
+ ]
+}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectory/node/rootDirectory.sourcemap.txt b/tests/baselines/reference/project/rootDirectory/node/rootDirectory.sourcemap.txt
new file mode 100644
index 0000000000000..83ee3b40181b4
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectory/node/rootDirectory.sourcemap.txt
@@ -0,0 +1,123 @@
+===================================================================
+JsFile: fileC.js
+mapUrl: fileC.js.map
+sourceRoot:
+sources: ../../../../FolderA/FolderB/FolderC/fileC.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/FolderC/fileC.js
+sourceFile:../../../../FolderA/FolderB/FolderC/fileC.ts
+-------------------------------------------------------------------
+>>>var C = (function () {
+1 >
+2 >^^^^^^^^^^^^^^^^^^^->
+1 >
+1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+---
+>>> function C() {
+1->^^^^
+2 > ^^->
+1->
+1->Emitted(2, 5) Source(1, 1) + SourceIndex(0) name (C)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class C {
+ >
+2 > }
+1->Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (C.constructor)
+2 >Emitted(3, 6) Source(2, 2) + SourceIndex(0) name (C.constructor)
+---
+>>> return C;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(4, 5) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(4, 13) Source(2, 2) + SourceIndex(0) name (C)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class C {
+ > }
+1 >Emitted(5, 1) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(5, 2) Source(2, 2) + SourceIndex(0) name (C)
+3 >Emitted(5, 2) Source(1, 1) + SourceIndex(0)
+4 >Emitted(5, 6) Source(2, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileC.js.map===================================================================
+JsFile: fileB.js
+mapUrl: fileB.js.map
+sourceRoot:
+sources: ../../../FolderA/FolderB/fileB.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/fileB.js
+sourceFile:../../../FolderA/FolderB/fileB.ts
+-------------------------------------------------------------------
+>>>///
+1 >
+2 >
+3 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1 >///
+ >
+2 >
+3 >///
+1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0)
+2 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+3 >Emitted(1, 41) Source(1, 41) + SourceIndex(0)
+---
+>>>var B = (function () {
+>>> function B() {
+1 >^^^^
+2 > ^^->
+1 >
+ >
+1 >Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (B)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class B {
+ > public c: C;
+ >
+2 > }
+1->Emitted(4, 5) Source(4, 1) + SourceIndex(0) name (B.constructor)
+2 >Emitted(4, 6) Source(4, 2) + SourceIndex(0) name (B.constructor)
+---
+>>> return B;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(5, 5) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(5, 13) Source(4, 2) + SourceIndex(0) name (B)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class B {
+ > public c: C;
+ > }
+1 >Emitted(6, 1) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(6, 2) Source(4, 2) + SourceIndex(0) name (B)
+3 >Emitted(6, 2) Source(2, 1) + SourceIndex(0)
+4 >Emitted(6, 6) Source(4, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/FolderC/fileC.d.ts b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/FolderC/fileC.d.ts
new file mode 100644
index 0000000000000..8147620b2111b
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/FolderC/fileC.d.ts
@@ -0,0 +1,2 @@
+declare class C {
+}
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/FolderC/fileC.js b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/FolderC/fileC.js
new file mode 100644
index 0000000000000..325ac60ee3288
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/FolderC/fileC.js
@@ -0,0 +1,5 @@
+var C = (function () {
+ function C() {
+ }
+ return C;
+})();
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/fileB.d.ts b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/fileB.d.ts
new file mode 100644
index 0000000000000..4ff813c3839e8
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/fileB.d.ts
@@ -0,0 +1,4 @@
+///
+declare class B {
+ c: C;
+}
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/fileB.js b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/fileB.js
new file mode 100644
index 0000000000000..99199ca1742b3
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/amd/outdir/simple/fileB.js
@@ -0,0 +1,6 @@
+///
+var B = (function () {
+ function B() {
+ }
+ return B;
+})();
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/amd/rootDirectoryErrors.errors.txt b/tests/baselines/reference/project/rootDirectoryErrors/amd/rootDirectoryErrors.errors.txt
new file mode 100644
index 0000000000000..dfbdd67968588
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/amd/rootDirectoryErrors.errors.txt
@@ -0,0 +1,14 @@
+error TS6059: File 'FolderA/FolderB/fileB.ts' is not under 'rootDir' 'FolderA/FolderB/FolderC'. 'rootDir' is expected to contain all source files.
+
+
+!!! error TS6059: File 'fileB.ts' is not under 'rootDir' 'FolderA/FolderB/FolderC'. 'rootDir' is expected to contain all source files.
+==== FolderA/FolderB/FolderC/fileC.ts (0 errors) ====
+ class C {
+ }
+
+==== FolderA/FolderB/fileB.ts (0 errors) ====
+ ///
+ class B {
+ public c: C;
+ }
+
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/amd/rootDirectoryErrors.json b/tests/baselines/reference/project/rootDirectoryErrors/amd/rootDirectoryErrors.json
new file mode 100644
index 0000000000000..fdde42592ca8d
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/amd/rootDirectoryErrors.json
@@ -0,0 +1,22 @@
+{
+ "scenario": "rootDirectory: Files outside the rootDirectory",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "declaration": true,
+ "baselineCheck": true,
+ "rootDir": "FolderA/FolderB/FolderC",
+ "resolvedInputFiles": [
+ "lib.d.ts",
+ "FolderA/FolderB/FolderC/fileC.ts",
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "emittedFiles": [
+ "outdir/simple/FolderC/fileC.js",
+ "outdir/simple/FolderC/fileC.d.ts",
+ "outdir/simple/fileB.js",
+ "outdir/simple/fileB.d.ts"
+ ]
+}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/FolderC/fileC.d.ts b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/FolderC/fileC.d.ts
new file mode 100644
index 0000000000000..8147620b2111b
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/FolderC/fileC.d.ts
@@ -0,0 +1,2 @@
+declare class C {
+}
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/FolderC/fileC.js b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/FolderC/fileC.js
new file mode 100644
index 0000000000000..325ac60ee3288
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/FolderC/fileC.js
@@ -0,0 +1,5 @@
+var C = (function () {
+ function C() {
+ }
+ return C;
+})();
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/fileB.d.ts b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/fileB.d.ts
new file mode 100644
index 0000000000000..4ff813c3839e8
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/fileB.d.ts
@@ -0,0 +1,4 @@
+///
+declare class B {
+ c: C;
+}
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/fileB.js b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/fileB.js
new file mode 100644
index 0000000000000..99199ca1742b3
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/node/outdir/simple/fileB.js
@@ -0,0 +1,6 @@
+///
+var B = (function () {
+ function B() {
+ }
+ return B;
+})();
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/node/rootDirectoryErrors.errors.txt b/tests/baselines/reference/project/rootDirectoryErrors/node/rootDirectoryErrors.errors.txt
new file mode 100644
index 0000000000000..dfbdd67968588
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/node/rootDirectoryErrors.errors.txt
@@ -0,0 +1,14 @@
+error TS6059: File 'FolderA/FolderB/fileB.ts' is not under 'rootDir' 'FolderA/FolderB/FolderC'. 'rootDir' is expected to contain all source files.
+
+
+!!! error TS6059: File 'fileB.ts' is not under 'rootDir' 'FolderA/FolderB/FolderC'. 'rootDir' is expected to contain all source files.
+==== FolderA/FolderB/FolderC/fileC.ts (0 errors) ====
+ class C {
+ }
+
+==== FolderA/FolderB/fileB.ts (0 errors) ====
+ ///
+ class B {
+ public c: C;
+ }
+
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryErrors/node/rootDirectoryErrors.json b/tests/baselines/reference/project/rootDirectoryErrors/node/rootDirectoryErrors.json
new file mode 100644
index 0000000000000..fdde42592ca8d
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryErrors/node/rootDirectoryErrors.json
@@ -0,0 +1,22 @@
+{
+ "scenario": "rootDirectory: Files outside the rootDirectory",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "declaration": true,
+ "baselineCheck": true,
+ "rootDir": "FolderA/FolderB/FolderC",
+ "resolvedInputFiles": [
+ "lib.d.ts",
+ "FolderA/FolderB/FolderC/fileC.ts",
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "emittedFiles": [
+ "outdir/simple/FolderC/fileC.js",
+ "outdir/simple/FolderC/fileC.d.ts",
+ "outdir/simple/fileB.js",
+ "outdir/simple/fileB.d.ts"
+ ]
+}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/FolderC/fileC.js b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/FolderC/fileC.js
new file mode 100644
index 0000000000000..8840c2117cfd2
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/FolderC/fileC.js
@@ -0,0 +1,6 @@
+var C = (function () {
+ function C() {
+ }
+ return C;
+})();
+//# sourceMappingURL=fileC.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/FolderC/fileC.js.map b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/FolderC/fileC.js.map
new file mode 100644
index 0000000000000..9a35f3fbc3ecc
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/FolderC/fileC.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileC.js","sourceRoot":"SourceRootPath/","sources":["FolderB/FolderC/fileC.ts"],"names":["C","C.constructor"],"mappings":"AAAA;IAAAA;IACAC,CAACA;IAADD,QAACA;AAADA,CAACA,AADD,IACC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/fileB.js b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/fileB.js
new file mode 100644
index 0000000000000..84af55d2d89e1
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/fileB.js
@@ -0,0 +1,7 @@
+///
+var B = (function () {
+ function B() {
+ }
+ return B;
+})();
+//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/fileB.js.map b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/fileB.js.map
new file mode 100644
index 0000000000000..16a4538542059
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/outdir/simple/FolderB/fileB.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileB.js","sourceRoot":"SourceRootPath/","sources":["FolderB/fileB.ts"],"names":["B","B.constructor"],"mappings":"AACA,AADA,wCAAwC;;IACxCA;IAEAC,CAACA;IAADD,QAACA;AAADA,CAACA,AAFD,IAEC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/rootDirectoryWithSourceRoot.json b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/rootDirectoryWithSourceRoot.json
new file mode 100644
index 0000000000000..deb12150736aa
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/rootDirectoryWithSourceRoot.json
@@ -0,0 +1,23 @@
+{
+ "scenario": "rootDirectory: specify rootDirectory with sourceRoot",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "sourceMap": true,
+ "sourceRoot": "SourceRootPath",
+ "baselineCheck": true,
+ "rootDir": "FolderA",
+ "resolvedInputFiles": [
+ "lib.d.ts",
+ "FolderA/FolderB/FolderC/fileC.ts",
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "emittedFiles": [
+ "outdir/simple/FolderB/FolderC/fileC.js.map",
+ "outdir/simple/FolderB/FolderC/fileC.js",
+ "outdir/simple/FolderB/fileB.js.map",
+ "outdir/simple/FolderB/fileB.js"
+ ]
+}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/rootDirectoryWithSourceRoot.sourcemap.txt b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/rootDirectoryWithSourceRoot.sourcemap.txt
new file mode 100644
index 0000000000000..7c5843bdd3433
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/amd/rootDirectoryWithSourceRoot.sourcemap.txt
@@ -0,0 +1,123 @@
+===================================================================
+JsFile: fileC.js
+mapUrl: fileC.js.map
+sourceRoot: SourceRootPath/
+sources: FolderB/FolderC/fileC.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/FolderC/fileC.js
+sourceFile:FolderB/FolderC/fileC.ts
+-------------------------------------------------------------------
+>>>var C = (function () {
+1 >
+2 >^^^^^^^^^^^^^^^^^^^->
+1 >
+1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+---
+>>> function C() {
+1->^^^^
+2 > ^^->
+1->
+1->Emitted(2, 5) Source(1, 1) + SourceIndex(0) name (C)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class C {
+ >
+2 > }
+1->Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (C.constructor)
+2 >Emitted(3, 6) Source(2, 2) + SourceIndex(0) name (C.constructor)
+---
+>>> return C;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(4, 5) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(4, 13) Source(2, 2) + SourceIndex(0) name (C)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class C {
+ > }
+1 >Emitted(5, 1) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(5, 2) Source(2, 2) + SourceIndex(0) name (C)
+3 >Emitted(5, 2) Source(1, 1) + SourceIndex(0)
+4 >Emitted(5, 6) Source(2, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileC.js.map===================================================================
+JsFile: fileB.js
+mapUrl: fileB.js.map
+sourceRoot: SourceRootPath/
+sources: FolderB/fileB.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/fileB.js
+sourceFile:FolderB/fileB.ts
+-------------------------------------------------------------------
+>>>///
+1 >
+2 >
+3 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1 >///
+ >
+2 >
+3 >///
+1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0)
+2 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+3 >Emitted(1, 41) Source(1, 41) + SourceIndex(0)
+---
+>>>var B = (function () {
+>>> function B() {
+1 >^^^^
+2 > ^^->
+1 >
+ >
+1 >Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (B)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class B {
+ > public c: C;
+ >
+2 > }
+1->Emitted(4, 5) Source(4, 1) + SourceIndex(0) name (B.constructor)
+2 >Emitted(4, 6) Source(4, 2) + SourceIndex(0) name (B.constructor)
+---
+>>> return B;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(5, 5) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(5, 13) Source(4, 2) + SourceIndex(0) name (B)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class B {
+ > public c: C;
+ > }
+1 >Emitted(6, 1) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(6, 2) Source(4, 2) + SourceIndex(0) name (B)
+3 >Emitted(6, 2) Source(2, 1) + SourceIndex(0)
+4 >Emitted(6, 6) Source(4, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/FolderC/fileC.js b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/FolderC/fileC.js
new file mode 100644
index 0000000000000..8840c2117cfd2
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/FolderC/fileC.js
@@ -0,0 +1,6 @@
+var C = (function () {
+ function C() {
+ }
+ return C;
+})();
+//# sourceMappingURL=fileC.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/FolderC/fileC.js.map b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/FolderC/fileC.js.map
new file mode 100644
index 0000000000000..9a35f3fbc3ecc
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/FolderC/fileC.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileC.js","sourceRoot":"SourceRootPath/","sources":["FolderB/FolderC/fileC.ts"],"names":["C","C.constructor"],"mappings":"AAAA;IAAAA;IACAC,CAACA;IAADD,QAACA;AAADA,CAACA,AADD,IACC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/fileB.js b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/fileB.js
new file mode 100644
index 0000000000000..84af55d2d89e1
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/fileB.js
@@ -0,0 +1,7 @@
+///
+var B = (function () {
+ function B() {
+ }
+ return B;
+})();
+//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/fileB.js.map b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/fileB.js.map
new file mode 100644
index 0000000000000..16a4538542059
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/outdir/simple/FolderB/fileB.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"fileB.js","sourceRoot":"SourceRootPath/","sources":["FolderB/fileB.ts"],"names":["B","B.constructor"],"mappings":"AACA,AADA,wCAAwC;;IACxCA;IAEAC,CAACA;IAADD,QAACA;AAADA,CAACA,AAFD,IAEC"}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/rootDirectoryWithSourceRoot.json b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/rootDirectoryWithSourceRoot.json
new file mode 100644
index 0000000000000..deb12150736aa
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/rootDirectoryWithSourceRoot.json
@@ -0,0 +1,23 @@
+{
+ "scenario": "rootDirectory: specify rootDirectory with sourceRoot",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "sourceMap": true,
+ "sourceRoot": "SourceRootPath",
+ "baselineCheck": true,
+ "rootDir": "FolderA",
+ "resolvedInputFiles": [
+ "lib.d.ts",
+ "FolderA/FolderB/FolderC/fileC.ts",
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "emittedFiles": [
+ "outdir/simple/FolderB/FolderC/fileC.js.map",
+ "outdir/simple/FolderB/FolderC/fileC.js",
+ "outdir/simple/FolderB/fileB.js.map",
+ "outdir/simple/FolderB/fileB.js"
+ ]
+}
\ No newline at end of file
diff --git a/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/rootDirectoryWithSourceRoot.sourcemap.txt b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/rootDirectoryWithSourceRoot.sourcemap.txt
new file mode 100644
index 0000000000000..7c5843bdd3433
--- /dev/null
+++ b/tests/baselines/reference/project/rootDirectoryWithSourceRoot/node/rootDirectoryWithSourceRoot.sourcemap.txt
@@ -0,0 +1,123 @@
+===================================================================
+JsFile: fileC.js
+mapUrl: fileC.js.map
+sourceRoot: SourceRootPath/
+sources: FolderB/FolderC/fileC.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/FolderC/fileC.js
+sourceFile:FolderB/FolderC/fileC.ts
+-------------------------------------------------------------------
+>>>var C = (function () {
+1 >
+2 >^^^^^^^^^^^^^^^^^^^->
+1 >
+1 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+---
+>>> function C() {
+1->^^^^
+2 > ^^->
+1->
+1->Emitted(2, 5) Source(1, 1) + SourceIndex(0) name (C)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class C {
+ >
+2 > }
+1->Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (C.constructor)
+2 >Emitted(3, 6) Source(2, 2) + SourceIndex(0) name (C.constructor)
+---
+>>> return C;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(4, 5) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(4, 13) Source(2, 2) + SourceIndex(0) name (C)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class C {
+ > }
+1 >Emitted(5, 1) Source(2, 1) + SourceIndex(0) name (C)
+2 >Emitted(5, 2) Source(2, 2) + SourceIndex(0) name (C)
+3 >Emitted(5, 2) Source(1, 1) + SourceIndex(0)
+4 >Emitted(5, 6) Source(2, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileC.js.map===================================================================
+JsFile: fileB.js
+mapUrl: fileB.js.map
+sourceRoot: SourceRootPath/
+sources: FolderB/fileB.ts
+===================================================================
+-------------------------------------------------------------------
+emittedFile:outdir/simple/FolderB/fileB.js
+sourceFile:FolderB/fileB.ts
+-------------------------------------------------------------------
+>>>///
+1 >
+2 >
+3 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1 >///
+ >
+2 >
+3 >///
+1 >Emitted(1, 1) Source(2, 1) + SourceIndex(0)
+2 >Emitted(1, 1) Source(1, 1) + SourceIndex(0)
+3 >Emitted(1, 41) Source(1, 41) + SourceIndex(0)
+---
+>>>var B = (function () {
+>>> function B() {
+1 >^^^^
+2 > ^^->
+1 >
+ >
+1 >Emitted(3, 5) Source(2, 1) + SourceIndex(0) name (B)
+---
+>>> }
+1->^^^^
+2 > ^
+3 > ^^^^^^^^^->
+1->class B {
+ > public c: C;
+ >
+2 > }
+1->Emitted(4, 5) Source(4, 1) + SourceIndex(0) name (B.constructor)
+2 >Emitted(4, 6) Source(4, 2) + SourceIndex(0) name (B.constructor)
+---
+>>> return B;
+1->^^^^
+2 > ^^^^^^^^
+1->
+2 > }
+1->Emitted(5, 5) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(5, 13) Source(4, 2) + SourceIndex(0) name (B)
+---
+>>>})();
+1 >
+2 >^
+3 >
+4 > ^^^^
+5 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^->
+1 >
+2 >}
+3 >
+4 > class B {
+ > public c: C;
+ > }
+1 >Emitted(6, 1) Source(4, 1) + SourceIndex(0) name (B)
+2 >Emitted(6, 2) Source(4, 2) + SourceIndex(0) name (B)
+3 >Emitted(6, 2) Source(2, 1) + SourceIndex(0)
+4 >Emitted(6, 6) Source(4, 2) + SourceIndex(0)
+---
+>>>//# sourceMappingURL=fileB.js.map
\ No newline at end of file
diff --git a/tests/cases/project/rootDirectory.json b/tests/cases/project/rootDirectory.json
new file mode 100644
index 0000000000000..6dad3982f93ad
--- /dev/null
+++ b/tests/cases/project/rootDirectory.json
@@ -0,0 +1,12 @@
+{
+ "scenario": "rootDirectory: specify rootDirectory",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "rootDir": "FolderA",
+ "sourceMap": true,
+ "declaration": true,
+ "baselineCheck": true
+}
\ No newline at end of file
diff --git a/tests/cases/project/rootDirectoryErrors.json b/tests/cases/project/rootDirectoryErrors.json
new file mode 100644
index 0000000000000..18a256486d026
--- /dev/null
+++ b/tests/cases/project/rootDirectoryErrors.json
@@ -0,0 +1,11 @@
+{
+ "scenario": "rootDirectory: Files outside the rootDirectory",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "rootDir": "FolderA/FolderB/FolderC",
+ "declaration": true,
+ "baselineCheck": true
+}
\ No newline at end of file
diff --git a/tests/cases/project/rootDirectoryWithSourceRoot.json b/tests/cases/project/rootDirectoryWithSourceRoot.json
new file mode 100644
index 0000000000000..227b55c13fd9d
--- /dev/null
+++ b/tests/cases/project/rootDirectoryWithSourceRoot.json
@@ -0,0 +1,12 @@
+{
+ "scenario": "rootDirectory: specify rootDirectory with sourceRoot",
+ "projectRoot": "tests/cases/projects/rootDirectory",
+ "inputFiles": [
+ "FolderA/FolderB/fileB.ts"
+ ],
+ "outDir": "outdir/simple",
+ "rootDir": "FolderA",
+ "sourceMap": true,
+ "sourceRoot": "SourceRootPath",
+ "baselineCheck": true
+}
\ No newline at end of file
diff --git a/tests/cases/projects/rootDirectory/FolderA/FolderB/FolderC/fileC.ts b/tests/cases/projects/rootDirectory/FolderA/FolderB/FolderC/fileC.ts
new file mode 100644
index 0000000000000..f4885b3ca74d4
--- /dev/null
+++ b/tests/cases/projects/rootDirectory/FolderA/FolderB/FolderC/fileC.ts
@@ -0,0 +1,2 @@
+class C {
+}
diff --git a/tests/cases/projects/rootDirectory/FolderA/FolderB/fileB.ts b/tests/cases/projects/rootDirectory/FolderA/FolderB/fileB.ts
new file mode 100644
index 0000000000000..03e0f4ad3327d
--- /dev/null
+++ b/tests/cases/projects/rootDirectory/FolderA/FolderB/fileB.ts
@@ -0,0 +1,4 @@
+///
+class B {
+ public c: C;
+}