Add rootDir option

This commit is contained in:
Mohamed Hegazy 2015-04-14 22:11:25 -07:00
parent e7895c59d4
commit 261adffe50
6 changed files with 81 additions and 30 deletions

View File

@ -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",

View File

@ -495,6 +495,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." },

View File

@ -1968,6 +1968,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",

View File

@ -455,47 +455,62 @@ 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 (!(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;
}
if (isDeclarationFile(sourceFile)) {
return;
}
// New common path found that is 0 -> i-1
commonPathComponents.length = i;
break;
let sourcePathComponents = getNormalizedPathComponents(sourceFile.fileName, currentDirectory);
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;
}
}
// If the fileComponent path completely matched and less than already found update the length
if (sourcePathComponents.length < commonPathComponents.length) {
commonPathComponents.length = sourcePathComponents.length;
// New common path found that is 0 -> i-1
commonPathComponents.length = i;
break;
}
}
else {
// first file
commonPathComponents = sourcePathComponents;
// 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;
}
});
let commonSourceDirectory = getNormalizedPathFromPathComponents(commonPathComponents);
if (commonSourceDirectory) {
// 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
commonSourceDirectory += directorySeparator;
return getNormalizedPathFromPathComponents(commonPathComponents);
}
function checkSourceFilesBelongToPath(soruceFiles: SourceFile[], rootDirectory: string): boolean {
let allFilesBelongToPath = true;
if (files) {
let currentDirectory = host.getCurrentDirectory();
let absoluteRootDirectoryPath = host.getCanonicalFileName(getNormalizedAbsolutePath(rootDirectory, currentDirectory));
for (var sourceFile of files) {
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 commonSourceDirectory;
return allFilesBelongToPath;
}
function verifyCompilerOptions() {
@ -560,7 +575,21 @@ module ts {
(options.mapRoot && // there is --mapRoot specified and there would be multiple js files generated
(!options.out || firstExternalModuleSourceFile !== undefined))) {
commonSourceDirectory = computecommonSourceDirectory(files);
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);
}
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
commonSourceDirectory += directorySeparator;
}
}
if (options.noEmit) {

View File

@ -1648,6 +1648,7 @@ module ts {
preserveConstEnums?: boolean;
project?: string;
removeComments?: boolean;
rootDir?: string;
sourceMap?: boolean;
sourceRoot?: string;
suppressImplicitAnyIndexErrors?: boolean;

View File

@ -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)
};