Merge branch 'master' into watchImprovements

This commit is contained in:
Sheetal Nandi
2017-08-07 11:04:11 -07:00
431 changed files with 235021 additions and 212978 deletions

View File

@@ -728,12 +728,12 @@ namespace ts {
}
/* @internal */
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
export function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string, errors: Push<Diagnostic>) {
return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors);
}
/* @internal */
export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Diagnostic[]): (string | number)[] | undefined {
export function parseListTypeOption(opt: CommandLineOptionOfListType, value = "", errors: Push<Diagnostic>): (string | number)[] | undefined {
value = trimString(value);
if (startsWith(value, "-")) {
return undefined;
@@ -752,7 +752,7 @@ namespace ts {
}
}
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string | undefined): ParsedCommandLine {
export function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine {
const options: CompilerOptions = {};
const fileNames: string[] = [];
const errors: Diagnostic[] = [];
@@ -764,7 +764,7 @@ namespace ts {
errors
};
function parseStrings(args: string[]) {
function parseStrings(args: ReadonlyArray<string>) {
let i = 0;
while (i < args.length) {
const s = args[i];
@@ -916,7 +916,7 @@ namespace ts {
return text === undefined ? createCompilerDiagnostic(Diagnostics.The_specified_path_does_not_exist_Colon_0, fileName) : text;
}
function commandLineOptionsToMap(options: CommandLineOption[]) {
function commandLineOptionsToMap(options: ReadonlyArray<CommandLineOption>) {
return arrayToMap(options, option => option.name);
}
@@ -1007,7 +1007,7 @@ namespace ts {
/**
* Convert the json syntax tree into the json value
*/
export function convertToObject(sourceFile: JsonSourceFile, errors: Diagnostic[]): any {
export function convertToObject(sourceFile: JsonSourceFile, errors: Push<Diagnostic>): any {
return convertToObjectWorker(sourceFile, errors, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined);
}
@@ -1016,7 +1016,7 @@ namespace ts {
*/
function convertToObjectWorker(
sourceFile: JsonSourceFile,
errors: Diagnostic[],
errors: Push<Diagnostic>,
knownRootOptions: Map<CommandLineOption> | undefined,
jsonConversionNotifier: JsonConversionNotifier | undefined): any {
if (!sourceFile.jsonObject) {
@@ -1085,11 +1085,7 @@ namespace ts {
elements: NodeArray<Expression>,
elementOption: CommandLineOption | undefined
): any[] {
const result: any[] = [];
for (const element of elements) {
result.push(convertPropertyValueToJson(element, elementOption));
}
return result;
return elements.map(element => convertPropertyValueToJson(element, elementOption));
}
function convertPropertyValueToJson(valueExpression: Expression, option: CommandLineOption): any {
@@ -1202,17 +1198,9 @@ namespace ts {
* @param fileNames array of filenames to be generated into tsconfig.json
*/
/* @internal */
export function generateTSConfig(options: CompilerOptions, fileNames: string[], newLine: string): string {
export function generateTSConfig(options: CompilerOptions, fileNames: ReadonlyArray<string>, newLine: string): string {
const compilerOptions = extend(options, defaultInitCompilerOptions);
const configurations: { compilerOptions: MapLike<CompilerOptionsValue>; files?: string[] } = {
compilerOptions: serializeCompilerOptions(compilerOptions)
};
if (fileNames && fileNames.length) {
// only set the files property if we have at least one file
configurations.files = fileNames;
}
const compilerOptionsMap = serializeCompilerOptions(compilerOptions);
return writeConfigurations();
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
@@ -1237,8 +1225,8 @@ namespace ts {
});
}
function serializeCompilerOptions(options: CompilerOptions): MapLike<CompilerOptionsValue> {
const result: ts.MapLike<CompilerOptionsValue> = {};
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValue> {
const result = createMap<CompilerOptionsValue>();
const optionsNameMap = getOptionNameMap().optionNameMap;
for (const name in options) {
@@ -1255,19 +1243,15 @@ namespace ts {
if (!customTypeMap) {
// There is no map associated with this compiler option then use the value as-is
// This is the case if the value is expect to be string, number, boolean or list of string
result[name] = value;
result.set(name, value);
}
else {
if (optionDefinition.type === "list") {
const convertedValue: string[] = [];
for (const element of value as (string | number)[]) {
convertedValue.push(getNameOfCompilerOptionValue(element, customTypeMap));
}
result[name] = convertedValue;
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)));
}
else {
// There is a typeMap associated with this command-line option so use it to map value back to its name
result[name] = getNameOfCompilerOptionValue(value, customTypeMap);
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
}
}
}
@@ -1299,33 +1283,30 @@ namespace ts {
function writeConfigurations() {
// Filter applicable options to place in the file
const categorizedOptions = reduceLeft(
filter(optionDeclarations, o => o.category !== Diagnostics.Command_line_Options && o.category !== Diagnostics.Advanced_Options),
(memo, value) => {
if (value.category) {
const name = getLocaleSpecificMessage(value.category);
(memo[name] || (memo[name] = [])).push(value);
}
return memo;
}, <MapLike<CommandLineOption[]>>{});
const categorizedOptions = createMultiMap<CommandLineOption>();
for (const option of optionDeclarations) {
const { category } = option;
if (category !== undefined && category !== Diagnostics.Command_line_Options && category !== Diagnostics.Advanced_Options) {
categorizedOptions.add(getLocaleSpecificMessage(category), option);
}
}
// Serialize all options and thier descriptions
// Serialize all options and their descriptions
let marginLength = 0;
let seenKnownKeys = 0;
const nameColumn: string[] = [];
const descriptionColumn: string[] = [];
const knownKeysCount = getOwnKeys(configurations.compilerOptions).length;
for (const category in categorizedOptions) {
categorizedOptions.forEach((options, category) => {
if (nameColumn.length !== 0) {
nameColumn.push("");
descriptionColumn.push("");
}
nameColumn.push(`/* ${category} */`);
descriptionColumn.push("");
for (const option of categorizedOptions[category]) {
for (const option of options) {
let optionName;
if (hasProperty(configurations.compilerOptions, option.name)) {
optionName = `"${option.name}": ${JSON.stringify(configurations.compilerOptions[option.name])}${(seenKnownKeys += 1) === knownKeysCount ? "" : ","}`;
if (compilerOptionsMap.has(option.name)) {
optionName = `"${option.name}": ${JSON.stringify(compilerOptionsMap.get(option.name))}${(seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ","}`;
}
else {
optionName = `// "${option.name}": ${JSON.stringify(getDefaultValueForOption(option))},`;
@@ -1334,7 +1315,7 @@ namespace ts {
descriptionColumn.push(`/* ${option.description && getLocaleSpecificMessage(option.description) || option.name} */`);
marginLength = Math.max(optionName.length, marginLength);
}
}
});
// Write the output
const tab = makePadding(2);
@@ -1347,11 +1328,11 @@ namespace ts {
const description = descriptionColumn[i];
result.push(optionName && `${tab}${tab}${optionName}${ description && (makePadding(marginLength - optionName.length + 2) + description)}`);
}
if (configurations.files && configurations.files.length) {
if (fileNames.length) {
result.push(`${tab}},`);
result.push(`${tab}"files": [`);
for (let i = 0; i < configurations.files.length; i++) {
result.push(`${tab}${tab}${JSON.stringify(configurations.files[i])}${i === configurations.files.length - 1 ? "" : ","}`);
for (let i = 0; i < fileNames.length; i++) {
result.push(`${tab}${tab}${JSON.stringify(fileNames[i])}${i === fileNames.length - 1 ? "" : ","}`);
}
result.push(`${tab}]`);
}
@@ -1371,7 +1352,7 @@ namespace ts {
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: JsFileExtensionInfo[]): ParsedCommandLine {
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>): ParsedCommandLine {
return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
}
@@ -1382,7 +1363,7 @@ namespace ts {
* @param basePath A root directory to resolve relative path entries in the config
* file to. e.g. outDir
*/
export function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: JsFileExtensionInfo[]): ParsedCommandLine {
export function parseJsonSourceFileConfigFileContent(sourceFile: JsonSourceFile, host: ParseConfigHost, basePath: string, existingOptions?: CompilerOptions, configFileName?: string, resolutionStack?: Path[], extraFileExtensions?: ReadonlyArray<JsFileExtensionInfo>): ParsedCommandLine {
return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions);
}
@@ -1410,7 +1391,7 @@ namespace ts {
existingOptions: CompilerOptions = {},
configFileName?: string,
resolutionStack: Path[] = [],
extraFileExtensions: JsFileExtensionInfo[] = [],
extraFileExtensions: ReadonlyArray<JsFileExtensionInfo> = [],
): ParsedCommandLine {
Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined));
const errors: Diagnostic[] = [];
@@ -1434,10 +1415,10 @@ namespace ts {
};
function getFileNames(): ExpandResult {
let filesSpecs: string[];
let filesSpecs: ReadonlyArray<string>;
if (hasProperty(raw, "files")) {
if (isArray(raw["files"])) {
filesSpecs = <string[]>raw["files"];
filesSpecs = <ReadonlyArray<string>>raw["files"];
if (filesSpecs.length === 0) {
createCompilerDiagnosticOnlyIfJson(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json");
}
@@ -1447,20 +1428,20 @@ namespace ts {
}
}
let includeSpecs: string[];
let includeSpecs: ReadonlyArray<string>;
if (hasProperty(raw, "include")) {
if (isArray(raw["include"])) {
includeSpecs = <string[]>raw["include"];
includeSpecs = <ReadonlyArray<string>>raw["include"];
}
else {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array");
}
}
let excludeSpecs: string[];
let excludeSpecs: ReadonlyArray<string>;
if (hasProperty(raw, "exclude")) {
if (isArray(raw["exclude"])) {
excludeSpecs = <string[]>raw["exclude"];
excludeSpecs = <ReadonlyArray<string>>raw["exclude"];
}
else {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array");
@@ -1468,12 +1449,13 @@ namespace ts {
}
else {
// If no includes were specified, exclude common package folders and the outDir
excludeSpecs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"];
const specs = includeSpecs ? [] : ["node_modules", "bower_components", "jspm_packages"];
const outDir = raw["compilerOptions"] && raw["compilerOptions"]["outDir"];
if (outDir) {
excludeSpecs.push(outDir);
specs.push(outDir);
}
excludeSpecs = specs;
}
if (filesSpecs === undefined && includeSpecs === undefined) {
@@ -1527,7 +1509,7 @@ namespace ts {
configFileName: string,
getCanonicalFileName: (fileName: string) => string,
resolutionStack: Path[],
errors: Diagnostic[],
errors: Push<Diagnostic>,
): ParsedTsconfig {
basePath = normalizeSlashes(basePath);
const resolvedPath = toPath(configFileName || "", basePath, getCanonicalFileName);
@@ -1575,7 +1557,7 @@ namespace ts {
basePath: string,
getCanonicalFileName: (fileName: string) => string,
configFileName: string,
errors: Diagnostic[]
errors: Push<Diagnostic>
): ParsedTsconfig {
if (hasProperty(json, "excludes")) {
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_option_excludes_Did_you_mean_exclude));
@@ -1605,7 +1587,7 @@ namespace ts {
basePath: string,
getCanonicalFileName: (fileName: string) => string,
configFileName: string,
errors: Diagnostic[]
errors: Push<Diagnostic>
): ParsedTsconfig {
const options = getDefaultCompilerOptions(configFileName);
let typeAcquisition: TypeAcquisition, typingOptionstypeAcquisition: TypeAcquisition;
@@ -1636,7 +1618,7 @@ namespace ts {
);
return;
case "files":
if ((<string[]>value).length === 0) {
if ((<ReadonlyArray<string>>value).length === 0) {
errors.push(createDiagnosticForNodeInSourceFile(sourceFile, valueNode, Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
}
return;
@@ -1672,7 +1654,7 @@ namespace ts {
host: ParseConfigHost,
basePath: string,
getCanonicalFileName: (fileName: string) => string,
errors: Diagnostic[],
errors: Push<Diagnostic>,
createDiagnostic: (message: DiagnosticMessage, arg1?: string) => Diagnostic) {
extendedConfig = normalizeSlashes(extendedConfig);
// If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
@@ -1698,7 +1680,7 @@ namespace ts {
basePath: string,
getCanonicalFileName: (fileName: string) => string,
resolutionStack: Path[],
errors: Diagnostic[],
errors: Push<Diagnostic>,
): ParsedTsconfig | undefined {
const extendedResult = readJsonConfigFile(extendedConfigPath, path => host.readFile(path));
if (sourceFile) {
@@ -1735,7 +1717,7 @@ namespace ts {
return extendedConfig;
}
function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Diagnostic[]): boolean {
function convertCompileOnSaveOptionFromJson(jsonOption: any, basePath: string, errors: Push<Diagnostic>): boolean {
if (!hasProperty(jsonOption, compileOnSaveCommandLineOption.name)) {
return undefined;
}
@@ -1766,7 +1748,7 @@ namespace ts {
}
function convertCompilerOptionsFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
basePath: string, errors: Push<Diagnostic>, configFileName?: string): CompilerOptions {
const options = getDefaultCompilerOptions(configFileName);
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
@@ -1779,7 +1761,7 @@ namespace ts {
}
function convertTypeAcquisitionFromJsonWorker(jsonOptions: any,
basePath: string, errors: Diagnostic[], configFileName?: string): TypeAcquisition {
basePath: string, errors: Push<Diagnostic>, configFileName?: string): TypeAcquisition {
const options = getDefaultTypeAcquisition(configFileName);
const typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions);
@@ -1788,8 +1770,8 @@ namespace ts {
return options;
}
function convertOptionsFromJson(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string,
defaultOptions: CompilerOptions | TypeAcquisition, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) {
function convertOptionsFromJson(optionDeclarations: ReadonlyArray<CommandLineOption>, jsonOptions: any, basePath: string,
defaultOptions: CompilerOptions | TypeAcquisition, diagnosticMessage: DiagnosticMessage, errors: Push<Diagnostic>) {
if (!jsonOptions) {
return;
@@ -1808,7 +1790,7 @@ namespace ts {
}
}
function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Diagnostic[]): CompilerOptionsValue {
function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Push<Diagnostic>): CompilerOptionsValue {
if (isCompilerOptionsValue(opt, value)) {
const optType = opt.type;
if (optType === "list" && isArray(value)) {
@@ -1848,7 +1830,7 @@ namespace ts {
return value;
}
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Push<Diagnostic>) {
const key = value.toLowerCase();
const val = opt.type.get(key);
if (val !== undefined) {
@@ -1859,7 +1841,7 @@ namespace ts {
}
}
function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: any[], basePath: string, errors: Diagnostic[]): any[] {
function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: ReadonlyArray<any>, basePath: string, errors: Push<Diagnostic>): any[] {
return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v);
}
@@ -1950,9 +1932,19 @@ namespace ts {
* @param host The host used to resolve files and directories.
* @param errors An array for diagnostic reporting.
*/
function matchFileNames(filesSpecs: string[], includeSpecs: string[], excludeSpecs: string[], basePath: string, options: CompilerOptions, host: ParseConfigHost, errors: Diagnostic[], extraFileExtensions: JsFileExtensionInfo[], jsonSourceFile: JsonSourceFile): ExpandResult {
function matchFileNames(
filesSpecs: ReadonlyArray<string>,
includeSpecs: ReadonlyArray<string>,
excludeSpecs: ReadonlyArray<string>,
basePath: string,
options: CompilerOptions,
host: ParseConfigHost,
errors: Push<Diagnostic>,
extraFileExtensions: ReadonlyArray<JsFileExtensionInfo>,
jsonSourceFile: JsonSourceFile
): ExpandResult {
basePath = normalizePath(basePath);
let validatedIncludeSpecs: string[], validatedExcludeSpecs: string[];
let validatedIncludeSpecs: ReadonlyArray<string>, validatedExcludeSpecs: ReadonlyArray<string>;
// The exclude spec list is converted into a regular expression, which allows us to quickly
// test whether a file or directory should be excluded before recursively traversing the
@@ -1987,7 +1979,7 @@ namespace ts {
* @param host The host used to resolve files and directories.
* @param errors An array for diagnostic reporting.
*/
export function getFileNamesFromConfigSpecs(spec: ConfigFileSpecs, basePath: string, options: CompilerOptions, host: ParseConfigHost, extraFileExtensions: JsFileExtensionInfo[]): ExpandResult {
export function getFileNamesFromConfigSpecs(spec: ConfigFileSpecs, basePath: string, options: CompilerOptions, host: ParseConfigHost, extraFileExtensions: ReadonlyArray<JsFileExtensionInfo>): ExpandResult {
basePath = normalizePath(basePath);
const keyMapper = host.useCaseSensitiveFileNames ? caseSensitiveKeyMapper : caseInsensitiveKeyMapper;
@@ -2051,7 +2043,7 @@ namespace ts {
};
}
function validateSpecs(specs: string[], errors: Diagnostic[], allowTrailingRecursion: boolean, jsonSourceFile: JsonSourceFile, specKey: string) {
function validateSpecs(specs: ReadonlyArray<string>, errors: Push<Diagnostic>, allowTrailingRecursion: boolean, jsonSourceFile: JsonSourceFile, specKey: string): ReadonlyArray<string> {
const validSpecs: string[] = [];
for (const spec of specs) {
if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
@@ -2075,7 +2067,7 @@ namespace ts {
for (const property of getPropertyAssignment(jsonSourceFile.jsonObject, specKey)) {
if (isArrayLiteralExpression(property.initializer)) {
for (const element of property.initializer.elements) {
if (element.kind === SyntaxKind.StringLiteral && (<StringLiteral>element).text === spec) {
if (isStringLiteral(element) && element.text === spec) {
return createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec);
}
}
@@ -2089,7 +2081,7 @@ namespace ts {
/**
* Gets directories in a set of include patterns that should be watched for changes.
*/
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): MapLike<WatchDirectoryFlags> {
function getWildcardDirectories(include: ReadonlyArray<string>, exclude: ReadonlyArray<string>, path: string, useCaseSensitiveFileNames: boolean): MapLike<WatchDirectoryFlags> {
// We watch a directory recursively if it contains a wildcard anywhere in a directory segment
// of the pattern:
//