mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' of https://github.com/Microsoft/TypeScript into fixLargeProjectTry2
# Conflicts: # src/compiler/types.ts
This commit is contained in:
+4
-1
@@ -150,7 +150,10 @@ var harnessSources = harnessCoreSources.concat([
|
||||
"reuseProgramStructure.ts",
|
||||
"cachingInServerLSHost.ts",
|
||||
"moduleResolution.ts",
|
||||
"tsconfigParsing.ts"
|
||||
"tsconfigParsing.ts",
|
||||
"commandLineParsing.ts",
|
||||
"convertCompilerOptionsFromJson.ts",
|
||||
"convertTypingOptionsFromJson.ts"
|
||||
].map(function (f) {
|
||||
return path.join(unittestsDirectory, f);
|
||||
})).concat([
|
||||
|
||||
+5
-2
@@ -76,8 +76,11 @@ module Commands {
|
||||
fs.mkdirSync(directoryPath);
|
||||
}
|
||||
}
|
||||
function normalizeSlashes(path: string): string {
|
||||
return path.replace(/\\/g, "/");
|
||||
}
|
||||
function transalatePath(outputFolder:string, path: string): string {
|
||||
return outputFolder + directorySeparator + path.replace(":", "");
|
||||
return normalizeSlashes(outputFolder + directorySeparator + path.replace(":", ""));
|
||||
}
|
||||
function fileExists(path: string): boolean {
|
||||
return fs.existsSync(path);
|
||||
@@ -86,7 +89,7 @@ module Commands {
|
||||
var filename = transalatePath(outputFolder, f.path);
|
||||
ensureDirectoriesExist(getDirectoryPath(filename));
|
||||
console.log("writing filename: " + filename);
|
||||
fs.writeFile(filename, f.result.contents, (err) => { });
|
||||
fs.writeFileSync(filename, f.result.contents);
|
||||
});
|
||||
|
||||
console.log("Command: tsc ");
|
||||
|
||||
@@ -13965,7 +13965,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType)) {
|
||||
else if (func.kind !== SyntaxKind.Constructor && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType)) {
|
||||
// The function has a return type, but the return statement doesn't have an expression.
|
||||
error(node, Diagnostics.Not_all_code_paths_return_a_value);
|
||||
}
|
||||
|
||||
+143
-120
@@ -58,12 +58,11 @@ namespace ts {
|
||||
},
|
||||
paramType: Diagnostics.KIND,
|
||||
description: Diagnostics.Specify_JSX_code_generation_Colon_preserve_or_react,
|
||||
error: Diagnostics.Argument_for_jsx_must_be_preserve_or_react
|
||||
},
|
||||
{
|
||||
name: "reactNamespace",
|
||||
type: "string",
|
||||
description: Diagnostics.Specifies_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit
|
||||
description: Diagnostics.Specify_the_object_invoked_for_createElement_and_spread_when_targeting_react_JSX_emit
|
||||
},
|
||||
{
|
||||
name: "listFiles",
|
||||
@@ -77,7 +76,7 @@ namespace ts {
|
||||
name: "mapRoot",
|
||||
type: "string",
|
||||
isFilePath: true,
|
||||
description: Diagnostics.Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
|
||||
description: Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations,
|
||||
paramType: Diagnostics.LOCATION,
|
||||
},
|
||||
{
|
||||
@@ -94,7 +93,6 @@ namespace ts {
|
||||
},
|
||||
description: Diagnostics.Specify_module_code_generation_Colon_commonjs_amd_system_umd_or_es2015,
|
||||
paramType: Diagnostics.KIND,
|
||||
error: Diagnostics.Argument_for_module_option_must_be_commonjs_amd_system_umd_es2015_or_none
|
||||
},
|
||||
{
|
||||
name: "newLine",
|
||||
@@ -102,9 +100,8 @@ namespace ts {
|
||||
"crlf": NewLineKind.CarriageReturnLineFeed,
|
||||
"lf": NewLineKind.LineFeed
|
||||
},
|
||||
description: Diagnostics.Specifies_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
|
||||
description: Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix,
|
||||
paramType: Diagnostics.NEWLINE,
|
||||
error: Diagnostics.Argument_for_newLine_option_must_be_CRLF_or_LF
|
||||
},
|
||||
{
|
||||
name: "noEmit",
|
||||
@@ -186,8 +183,8 @@ namespace ts {
|
||||
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,
|
||||
description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
|
||||
},
|
||||
{
|
||||
name: "isolatedModules",
|
||||
@@ -202,7 +199,7 @@ namespace ts {
|
||||
name: "sourceRoot",
|
||||
type: "string",
|
||||
isFilePath: true,
|
||||
description: Diagnostics.Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
|
||||
description: Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations,
|
||||
paramType: Diagnostics.LOCATION,
|
||||
},
|
||||
{
|
||||
@@ -231,9 +228,8 @@ namespace ts {
|
||||
"es6": ScriptTarget.ES6,
|
||||
"es2015": ScriptTarget.ES2015,
|
||||
},
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015_experimental,
|
||||
description: Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_or_ES2015,
|
||||
paramType: Diagnostics.VERSION,
|
||||
error: Diagnostics.Argument_for_target_option_must_be_ES3_ES5_or_ES2015
|
||||
},
|
||||
{
|
||||
name: "version",
|
||||
@@ -264,8 +260,7 @@ namespace ts {
|
||||
"node": ModuleResolutionKind.NodeJs,
|
||||
"classic": ModuleResolutionKind.Classic,
|
||||
},
|
||||
description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
|
||||
error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic,
|
||||
description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
|
||||
},
|
||||
{
|
||||
name: "allowUnusedLabels",
|
||||
@@ -309,9 +304,13 @@ namespace ts {
|
||||
// this option can only be specified in tsconfig.json
|
||||
// use type = object to copy the value as-is
|
||||
name: "rootDirs",
|
||||
type: "object",
|
||||
type: "list",
|
||||
isTSConfigOnly: true,
|
||||
isFilePath: true
|
||||
element: {
|
||||
name: "rootDirs",
|
||||
type: "string",
|
||||
isFilePath: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "traceModuleResolution",
|
||||
@@ -339,6 +338,30 @@ namespace ts {
|
||||
}
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
export let typingOptionDeclarations: CommandLineOption[] = [
|
||||
{
|
||||
name: "enableAutoDiscovery",
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
name: "include",
|
||||
type: "list",
|
||||
element: {
|
||||
name: "include",
|
||||
type: "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "exclude",
|
||||
type: "list",
|
||||
element: {
|
||||
name: "exclude",
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
export interface OptionNameMap {
|
||||
optionNameMap: Map<CommandLineOption>;
|
||||
@@ -365,6 +388,16 @@ namespace ts {
|
||||
return optionNameMapCache;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic {
|
||||
const namesOfType: string[] = [];
|
||||
forEachKey(opt.type, key => {
|
||||
namesOfType.push(` '${key}'`);
|
||||
});
|
||||
|
||||
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
|
||||
}
|
||||
|
||||
export function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine {
|
||||
const options: CompilerOptions = {};
|
||||
const fileNames: string[] = [];
|
||||
@@ -418,17 +451,15 @@ namespace ts {
|
||||
options[opt.name] = args[i] || "";
|
||||
i++;
|
||||
break;
|
||||
case "list":
|
||||
options[opt.name] = parseListTypeOption(<CommandLineOptionOfListType>opt, args[i]);
|
||||
i++;
|
||||
break;
|
||||
// If not a primitive, the possible types are specified in what is effectively a map of options.
|
||||
default:
|
||||
let map = <Map<number>>opt.type;
|
||||
let key = (args[i] || "").toLowerCase();
|
||||
options[opt.name] = parseCustomTypeOption(<CommandLineOptionOfCustomType>opt, args[i]);
|
||||
i++;
|
||||
if (hasProperty(map, key)) {
|
||||
options[opt.name] = map[key];
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,6 +470,29 @@ namespace ts {
|
||||
else {
|
||||
fileNames.push(s);
|
||||
}
|
||||
|
||||
function parseCustomTypeOption(opt: CommandLineOptionOfCustomType, value: string) {
|
||||
const key = (value || "").trim().toLowerCase();
|
||||
const map = opt.type;
|
||||
if (hasProperty(map, key)) {
|
||||
return map[key];
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
|
||||
}
|
||||
}
|
||||
|
||||
function parseListTypeOption(opt: CommandLineOptionOfListType, value: string): (string | number)[] {
|
||||
const values = (value || "").trim().split(",");
|
||||
switch (opt.element.type) {
|
||||
case "number":
|
||||
return ts.map(values, parseInt);
|
||||
case "string":
|
||||
return ts.map(values, v => v || "");
|
||||
default:
|
||||
return filter(map(values, v => parseCustomTypeOption(<CommandLineOptionOfCustomType>opt.element, v)), v => !!v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,7 +560,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the comments from a json like text.
|
||||
* Comments can be single line comments (starting with # or //) or multiline comments using / * * /
|
||||
@@ -540,21 +593,24 @@ namespace ts {
|
||||
* file to. e.g. outDir
|
||||
*/
|
||||
export function parseJsonConfigFileContent(json: any, host: ParseConfigHost, basePath: string, existingOptions: CompilerOptions = {}, configFileName?: string): ParsedCommandLine {
|
||||
const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath, configFileName);
|
||||
const errors: Diagnostic[] = [];
|
||||
const compilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], basePath, errors, configFileName);
|
||||
const options = extend(existingOptions, compilerOptions);
|
||||
const typingOptions: TypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], basePath, errors, configFileName);
|
||||
|
||||
const options = extend(existingOptions, optionsFromJsonConfigFile);
|
||||
const fileNames = getFileNames(errors);
|
||||
|
||||
return {
|
||||
options,
|
||||
fileNames: getFileNames(),
|
||||
typingOptions: getTypingOptions(),
|
||||
fileNames,
|
||||
typingOptions,
|
||||
errors
|
||||
};
|
||||
|
||||
function getFileNames(): string[] {
|
||||
function getFileNames(errors: Diagnostic[]): string[] {
|
||||
let fileNames: string[] = [];
|
||||
if (hasProperty(json, "files")) {
|
||||
if (json["files"] instanceof Array) {
|
||||
if (isArray(json["files"])) {
|
||||
fileNames = map(<string[]>json["files"], s => combinePaths(basePath, s));
|
||||
}
|
||||
else {
|
||||
@@ -565,7 +621,7 @@ namespace ts {
|
||||
const filesSeen: Map<boolean> = {};
|
||||
|
||||
let exclude: string[] = [];
|
||||
if (json["exclude"] instanceof Array) {
|
||||
if (isArray(json["exclude"])) {
|
||||
exclude = json["exclude"];
|
||||
}
|
||||
else {
|
||||
@@ -612,47 +668,33 @@ namespace ts {
|
||||
}
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
function getTypingOptions(): TypingOptions {
|
||||
const options: TypingOptions = getBaseFileName(configFileName) === "jsconfig.json"
|
||||
? { enableAutoDiscovery: true, include: [], exclude: [] }
|
||||
: { enableAutoDiscovery: false, include: [], exclude: [] };
|
||||
const jsonTypingOptions = json["typingOptions"];
|
||||
if (jsonTypingOptions) {
|
||||
for (const id in jsonTypingOptions) {
|
||||
if (id === "enableAutoDiscovery") {
|
||||
if (typeof jsonTypingOptions[id] === "boolean") {
|
||||
options.enableAutoDiscovery = jsonTypingOptions[id];
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_typing_option_0, id));
|
||||
}
|
||||
}
|
||||
else if (id === "include") {
|
||||
options.include = convertJsonOptionToStringArray(id, jsonTypingOptions[id], errors);
|
||||
}
|
||||
else if (id === "exclude") {
|
||||
options.exclude = convertJsonOptionToStringArray(id, jsonTypingOptions[id], errors);
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_typing_option_0, id));
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
}
|
||||
|
||||
export function convertCompilerOptionsFromJson(jsonOptions: any, basePath: string, configFileName?: string): { options: CompilerOptions, errors: Diagnostic[] } {
|
||||
const options: CompilerOptions = {};
|
||||
const errors: Diagnostic[] = [];
|
||||
/* @internal */
|
||||
export function convertCompilerOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any,
|
||||
basePath: string, errors: Diagnostic[], configFileName?: string): CompilerOptions {
|
||||
|
||||
if (configFileName && getBaseFileName(configFileName) === "jsconfig.json") {
|
||||
options.allowJs = true;
|
||||
}
|
||||
const options: CompilerOptions = getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true } : {};
|
||||
convertOptionsFromJson<CompilerOptions>(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
|
||||
return options;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function convertTypingOptionsFromJson(optionsDeclarations: CommandLineOption[], jsonOptions: any,
|
||||
basePath: string, errors: Diagnostic[], configFileName?: string): TypingOptions {
|
||||
|
||||
const options: TypingOptions = getBaseFileName(configFileName) === "jsconfig.json"
|
||||
? { enableAutoDiscovery: true, include: [], exclude: [] }
|
||||
: { enableAutoDiscovery: false, include: [], exclude: [] };
|
||||
convertOptionsFromJson<TypingOptions>(typingOptionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_typing_option_0, errors);
|
||||
return options;
|
||||
}
|
||||
|
||||
function convertOptionsFromJson<T extends CompilerOptions | TypingOptions>(optionDeclarations: CommandLineOption[], jsonOptions: any, basePath: string,
|
||||
defaultOptions: T, diagnosticMessage: DiagnosticMessage, errors: Diagnostic[]) {
|
||||
|
||||
if (!jsonOptions) {
|
||||
return { options, errors };
|
||||
return ;
|
||||
}
|
||||
|
||||
const optionNameMap = arrayToMap(optionDeclarations, opt => opt.name);
|
||||
@@ -660,69 +702,50 @@ namespace ts {
|
||||
for (const id in jsonOptions) {
|
||||
if (hasProperty(optionNameMap, id)) {
|
||||
const opt = optionNameMap[id];
|
||||
const optType = opt.type;
|
||||
let value = jsonOptions[id];
|
||||
const expectedType = typeof optType === "string" ? optType : "string";
|
||||
if (typeof value === expectedType) {
|
||||
if (typeof optType !== "string") {
|
||||
const key = value.toLowerCase();
|
||||
if (hasProperty(optType, key)) {
|
||||
value = optType[key];
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
if (opt.isFilePath) {
|
||||
switch (typeof value) {
|
||||
case "string":
|
||||
value = normalizePath(combinePaths(basePath, value));
|
||||
break;
|
||||
case "object":
|
||||
// "object" options with 'isFilePath' = true expected to be string arrays
|
||||
value = convertJsonOptionToStringArray(opt.name, value, errors, (element) => normalizePath(combinePaths(basePath, element)));
|
||||
break;
|
||||
}
|
||||
if (value === "") {
|
||||
value = ".";
|
||||
}
|
||||
}
|
||||
options[opt.name] = value;
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, id, expectedType));
|
||||
}
|
||||
defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors);
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Unknown_compiler_option_0, id));
|
||||
errors.push(createCompilerDiagnostic(diagnosticMessage, id));
|
||||
}
|
||||
}
|
||||
|
||||
return { options, errors };
|
||||
}
|
||||
|
||||
function convertJsonOptionToStringArray(optionName: string, optionJson: any, errors: Diagnostic[], func?: (element: string) => string): string[] {
|
||||
const items: string[] = [];
|
||||
let invalidOptionType = false;
|
||||
if (!isArray(optionJson)) {
|
||||
invalidOptionType = true;
|
||||
function convertJsonOption(opt: CommandLineOption, value: any, basePath: string, errors: Diagnostic[]): CompilerOptionsValue {
|
||||
const optType = opt.type;
|
||||
const expectedType = typeof optType === "string" ? optType : "string";
|
||||
if (optType === "list" && isArray(value)) {
|
||||
return convertJsonOptionOfListType(<CommandLineOptionOfListType>opt, value, basePath, errors);
|
||||
}
|
||||
else if (typeof value === expectedType) {
|
||||
if (typeof optType !== "string") {
|
||||
return convertJsonOptionOfCustomType(<CommandLineOptionOfCustomType>opt, value, errors);
|
||||
}
|
||||
else {
|
||||
if (opt.isFilePath) {
|
||||
value = normalizePath(combinePaths(basePath, value));
|
||||
if (value === "") {
|
||||
value = ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
else {
|
||||
for (const element of <any[]>optionJson) {
|
||||
if (typeof element === "string") {
|
||||
const item = func ? func(element) : element;
|
||||
items.push(item);
|
||||
}
|
||||
else {
|
||||
invalidOptionType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, expectedType));
|
||||
}
|
||||
if (invalidOptionType) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_should_have_array_of_strings_as_a_value, optionName));
|
||||
}
|
||||
|
||||
function convertJsonOptionOfCustomType(opt: CommandLineOptionOfCustomType, value: string, errors: Diagnostic[]) {
|
||||
const key = value.toLowerCase();
|
||||
if (hasProperty(opt.type, key)) {
|
||||
return opt.type[key];
|
||||
}
|
||||
return items;
|
||||
else {
|
||||
errors.push(createCompilerDiagnosticForInvalidCustomType(opt));
|
||||
}
|
||||
}
|
||||
|
||||
function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: any[], basePath: string, errors: Diagnostic[]): any[] {
|
||||
return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2240,11 +2240,11 @@
|
||||
"category": "Message",
|
||||
"code": 6002
|
||||
},
|
||||
"Specifies the location where debugger should locate map files instead of generated locations.": {
|
||||
"Specify the location where debugger should locate map files instead of generated locations.": {
|
||||
"category": "Message",
|
||||
"code": 6003
|
||||
},
|
||||
"Specifies the location where debugger should locate TypeScript files instead of source locations.": {
|
||||
"Specify the location where debugger should locate TypeScript files instead of source locations.": {
|
||||
"category": "Message",
|
||||
"code": 6004
|
||||
},
|
||||
@@ -2276,7 +2276,7 @@
|
||||
"category": "Message",
|
||||
"code": 6011
|
||||
},
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015' (experimental)": {
|
||||
"Specify ECMAScript target version: 'ES3' (default), 'ES5', or 'ES2015'": {
|
||||
"category": "Message",
|
||||
"code": 6015
|
||||
},
|
||||
@@ -2364,14 +2364,10 @@
|
||||
"category": "Error",
|
||||
"code": 6045
|
||||
},
|
||||
"Argument for '--module' option must be 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'none'.": {
|
||||
"Argument for '{0}' option must be: {1}": {
|
||||
"category": "Error",
|
||||
"code": 6046
|
||||
},
|
||||
"Argument for '--target' option must be 'ES3', 'ES5', or 'ES2015'.": {
|
||||
"category": "Error",
|
||||
"code": 6047
|
||||
},
|
||||
"Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 6048
|
||||
@@ -2408,7 +2404,7 @@
|
||||
"category": "Message",
|
||||
"code": 6056
|
||||
},
|
||||
"Specifies the root directory of input files. Use to control the output directory structure with --outDir.": {
|
||||
"Specify the root directory of input files. Use to control the output directory structure with --outDir.": {
|
||||
"category": "Message",
|
||||
"code": 6058
|
||||
},
|
||||
@@ -2416,7 +2412,7 @@
|
||||
"category": "Error",
|
||||
"code": 6059
|
||||
},
|
||||
"Specifies the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).": {
|
||||
"Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix).": {
|
||||
"category": "Message",
|
||||
"code": 6060
|
||||
},
|
||||
@@ -2424,14 +2420,6 @@
|
||||
"category": "Message",
|
||||
"code": 6061
|
||||
},
|
||||
"Argument for '--newLine' option must be 'CRLF' or 'LF'.": {
|
||||
"category": "Error",
|
||||
"code": 6062
|
||||
},
|
||||
"Argument for '--moduleResolution' option must be 'node' or 'classic'.": {
|
||||
"category": "Error",
|
||||
"code": 6063
|
||||
},
|
||||
"Option '{0}' can only be specified in 'tsconfig.json' file.": {
|
||||
"category": "Error",
|
||||
"code": 6064
|
||||
@@ -2448,7 +2436,7 @@
|
||||
"category": "Message",
|
||||
"code": 6068
|
||||
},
|
||||
"Specifies module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).": {
|
||||
"Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6).": {
|
||||
"category": "Message",
|
||||
"code": 6069
|
||||
},
|
||||
@@ -2492,10 +2480,6 @@
|
||||
"category": "Message",
|
||||
"code": 6080
|
||||
},
|
||||
"Argument for '--jsx' must be 'preserve' or 'react'.": {
|
||||
"category": "Message",
|
||||
"code": 6081
|
||||
},
|
||||
"Only 'amd' and 'system' modules are supported alongside --{0}.": {
|
||||
"category": "Error",
|
||||
"code": 6082
|
||||
@@ -2504,7 +2488,7 @@
|
||||
"category": "Message",
|
||||
"code": 6083
|
||||
},
|
||||
"Specifies the object invoked for createElement and __spread when targeting 'react' JSX emit": {
|
||||
"Specify the object invoked for createElement and __spread when targeting 'react' JSX emit": {
|
||||
"category": "Message",
|
||||
"code": 6084
|
||||
},
|
||||
|
||||
@@ -604,7 +604,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
write(`//# sourceMappingURL=${sourceMappingURL}`);
|
||||
}
|
||||
|
||||
writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM);
|
||||
writeEmittedFiles(writer.getText(), jsFilePath, sourceMapFilePath, /*writeByteOrderMark*/ compilerOptions.emitBOM, sourceFiles);
|
||||
|
||||
// reset the state
|
||||
sourceMap.reset();
|
||||
@@ -748,16 +748,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
}
|
||||
|
||||
/** Write emitted output to disk */
|
||||
function writeEmittedFiles(emitOutput: string, jsFilePath: string, sourceMapFilePath: string, writeByteOrderMark: boolean) {
|
||||
function writeEmittedFiles(emitOutput: string, jsFilePath: string, sourceMapFilePath: string, writeByteOrderMark: boolean, sourceFiles: SourceFile[]) {
|
||||
if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) {
|
||||
writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false);
|
||||
writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles);
|
||||
}
|
||||
|
||||
if (sourceMapDataList) {
|
||||
sourceMapDataList.push(sourceMap.getSourceMapData());
|
||||
}
|
||||
|
||||
writeFile(host, emitterDiagnostics, jsFilePath, emitOutput, writeByteOrderMark);
|
||||
writeFile(host, emitterDiagnostics, jsFilePath, emitOutput, writeByteOrderMark, sourceFiles);
|
||||
}
|
||||
|
||||
// Create a temporary variable with a unique unused name.
|
||||
|
||||
+2
-19
@@ -933,7 +933,7 @@ namespace ts {
|
||||
getSourceFile: program.getSourceFile,
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
writeFile: writeFileCallback || (
|
||||
(fileName, data, writeByteOrderMark, onError) => host.writeFile(fileName, data, writeByteOrderMark, onError)),
|
||||
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
|
||||
isEmitBlocked,
|
||||
};
|
||||
}
|
||||
@@ -1773,24 +1773,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (options.noEmit) {
|
||||
if (options.out) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "out"));
|
||||
}
|
||||
|
||||
if (options.outFile) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "outFile"));
|
||||
}
|
||||
|
||||
if (options.outDir) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "outDir"));
|
||||
}
|
||||
|
||||
if (options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmit", "declaration"));
|
||||
}
|
||||
}
|
||||
else if (options.allowJs && options.declaration) {
|
||||
if (!options.noEmit && options.allowJs && options.declaration) {
|
||||
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"));
|
||||
}
|
||||
|
||||
|
||||
+16
-6
@@ -1584,7 +1584,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface WriteFileCallback {
|
||||
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void;
|
||||
(fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void, sourceFiles?: SourceFile[]): void;
|
||||
}
|
||||
|
||||
export class OperationCanceledException { }
|
||||
@@ -2381,6 +2381,8 @@ namespace ts {
|
||||
export type PathSubstitutions = Map<string[]>;
|
||||
export type TsConfigOnlyOptions = RootPaths | PathSubstitutions;
|
||||
|
||||
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | TsConfigOnlyOptions;
|
||||
|
||||
export interface CompilerOptions {
|
||||
allowNonTsExtensions?: boolean;
|
||||
charset?: string;
|
||||
@@ -2438,6 +2440,7 @@ namespace ts {
|
||||
allowJs?: boolean;
|
||||
noImplicitUseStrict?: boolean;
|
||||
disableSizeLimit?: boolean;
|
||||
lib?: string[];
|
||||
/* @internal */ stripInternal?: boolean;
|
||||
|
||||
// Skip checking lib.d.ts to help speed up tests.
|
||||
@@ -2445,7 +2448,9 @@ namespace ts {
|
||||
// Do not perform validation of output file name in transpile scenarios
|
||||
/* @internal */ suppressOutputPathCheck?: boolean;
|
||||
|
||||
[option: string]: string | number | boolean | TsConfigOnlyOptions;
|
||||
list?: string[];
|
||||
|
||||
[option: string]: CompilerOptionsValue;
|
||||
}
|
||||
|
||||
export interface TypingOptions {
|
||||
@@ -2530,7 +2535,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface CommandLineOptionBase {
|
||||
name: string;
|
||||
type: "string" | "number" | "boolean" | "object" | Map<number>; // a value of a primitive type, or an object literal mapping named values to actual values
|
||||
type: "string" | "number" | "boolean" | "object" | "list" | Map<number | string>; // a value of a primitive type, or an object literal mapping named values to actual values
|
||||
isFilePath?: boolean; // True if option value is a path or fileName
|
||||
shortName?: string; // A short mnemonic for convenience - for instance, 'h' can be used in place of 'help'
|
||||
description?: DiagnosticMessage; // The message describing what the command line switch does
|
||||
@@ -2546,8 +2551,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export interface CommandLineOptionOfCustomType extends CommandLineOptionBase {
|
||||
type: Map<number>; // an object literal mapping named values to actual values
|
||||
error: DiagnosticMessage; // The error given when the argument does not fit a customized 'type'
|
||||
type: Map<number | string>; // an object literal mapping named values to actual values
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2556,7 +2560,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption;
|
||||
export interface CommandLineOptionOfListType extends CommandLineOptionBase {
|
||||
type: "list";
|
||||
element: CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type CommandLineOption = CommandLineOptionOfCustomType | CommandLineOptionOfPrimitiveType | TsConfigOnlyOption | CommandLineOptionOfListType;
|
||||
|
||||
/* @internal */
|
||||
export const enum CharacterCodes {
|
||||
|
||||
@@ -2110,10 +2110,10 @@ namespace ts {
|
||||
return combinePaths(newDirPath, sourceFilePath);
|
||||
}
|
||||
|
||||
export function writeFile(host: EmitHost, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
export function writeFile(host: EmitHost, diagnostics: DiagnosticCollection, fileName: string, data: string, writeByteOrderMark: boolean, sourceFiles?: SourceFile[]) {
|
||||
host.writeFile(fileName, data, writeByteOrderMark, hostErrorMessage => {
|
||||
diagnostics.add(createCompilerDiagnostic(Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage));
|
||||
});
|
||||
}, sourceFiles);
|
||||
}
|
||||
|
||||
export function getLineOfLocalPosition(currentSourceFile: SourceFile, pos: number) {
|
||||
|
||||
@@ -876,7 +876,7 @@ namespace Harness {
|
||||
useCaseSensitiveFileNames: () => useCaseSensitiveFileNames,
|
||||
getNewLine: () => newLine,
|
||||
fileExists: fileName => getSourceFile(fileName, ts.ScriptTarget.ES5) !== undefined,
|
||||
readFile: (fileName: string): string => { throw new Error("NotYetImplemented"); }
|
||||
readFile: (fileName: string): string => { return Harness.IO.readFile(fileName); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -31,22 +31,20 @@ namespace RWC {
|
||||
let otherFiles: Harness.Compiler.TestFile[] = [];
|
||||
let compilerResult: Harness.Compiler.CompilerResult;
|
||||
let compilerOptions: ts.CompilerOptions;
|
||||
let baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
const baselineOpts: Harness.Baseline.BaselineOptions = {
|
||||
Subfolder: "rwc",
|
||||
Baselinefolder: "internal/baselines"
|
||||
};
|
||||
let baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
|
||||
const baseName = /(.*)\/(.*).json/.exec(ts.normalizeSlashes(jsonPath))[2];
|
||||
let currentDirectory: string;
|
||||
let useCustomLibraryFile: boolean;
|
||||
after(() => {
|
||||
// Mocha holds onto the closure environment of the describe callback even after the test is done.
|
||||
// Therefore we have to clean out large objects after the test is done.
|
||||
inputFiles = undefined;
|
||||
otherFiles = undefined;
|
||||
inputFiles = [];
|
||||
otherFiles = [];
|
||||
compilerResult = undefined;
|
||||
compilerOptions = undefined;
|
||||
baselineOpts = undefined;
|
||||
baseName = undefined;
|
||||
currentDirectory = undefined;
|
||||
// useCustomLibraryFile is a flag specified in the json object to indicate whether to use built/local/lib.d.ts
|
||||
// or to use lib.d.ts inside the json object. If the flag is true, use the lib.d.ts inside json file
|
||||
|
||||
@@ -1353,6 +1353,7 @@ namespace ts.server {
|
||||
else {
|
||||
const defaultOpts = ts.getDefaultCompilerOptions();
|
||||
defaultOpts.allowNonTsExtensions = true;
|
||||
defaultOpts.allowJs = true;
|
||||
this.setCompilerOptions(defaultOpts);
|
||||
}
|
||||
this.languageService = ts.createLanguageService(this.host, this.documentRegistry);
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
/* @internal */
|
||||
namespace ts.NavigationBar {
|
||||
export function getNavigationBarItems(sourceFile: SourceFile, compilerOptions: CompilerOptions): ts.NavigationBarItem[] {
|
||||
// TODO: Handle JS files differently in 'navbar' calls for now, but ideally we should unify
|
||||
// the 'navbar' and 'navto' logic for TypeScript and JavaScript.
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
return getJsNavigationBarItems(sourceFile, compilerOptions);
|
||||
}
|
||||
|
||||
// If the source file has any child items, then it included in the tree
|
||||
// and takes lexical ownership of all other top-level items.
|
||||
let hasGlobalNode = false;
|
||||
@@ -130,7 +136,7 @@ namespace ts.NavigationBar {
|
||||
|
||||
return topLevelNodes;
|
||||
}
|
||||
|
||||
|
||||
function sortNodes(nodes: Node[]): Node[] {
|
||||
return nodes.slice(0).sort((n1: Declaration, n2: Declaration) => {
|
||||
if (n1.name && n2.name) {
|
||||
@@ -147,7 +153,7 @@ namespace ts.NavigationBar {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function addTopLevelNodes(nodes: Node[], topLevelNodes: Node[]): void {
|
||||
nodes = sortNodes(nodes);
|
||||
|
||||
@@ -178,8 +184,8 @@ namespace ts.NavigationBar {
|
||||
|
||||
function isTopLevelFunctionDeclaration(functionDeclaration: FunctionLikeDeclaration) {
|
||||
if (functionDeclaration.kind === SyntaxKind.FunctionDeclaration) {
|
||||
// A function declaration is 'top level' if it contains any function declarations
|
||||
// within it.
|
||||
// A function declaration is 'top level' if it contains any function declarations
|
||||
// within it.
|
||||
if (functionDeclaration.body && functionDeclaration.body.kind === SyntaxKind.Block) {
|
||||
// Proper function declarations can only have identifier names
|
||||
if (forEach((<Block>functionDeclaration.body).statements,
|
||||
@@ -198,7 +204,7 @@ namespace ts.NavigationBar {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[] {
|
||||
let items: ts.NavigationBarItem[] = [];
|
||||
|
||||
@@ -395,19 +401,19 @@ namespace ts.NavigationBar {
|
||||
let result: string[] = [];
|
||||
|
||||
result.push(moduleDeclaration.name.text);
|
||||
|
||||
|
||||
while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) {
|
||||
moduleDeclaration = <ModuleDeclaration>moduleDeclaration.body;
|
||||
|
||||
result.push(moduleDeclaration.name.text);
|
||||
}
|
||||
}
|
||||
|
||||
return result.join(".");
|
||||
}
|
||||
|
||||
function createModuleItem(node: ModuleDeclaration): NavigationBarItem {
|
||||
let moduleName = getModuleName(node);
|
||||
|
||||
|
||||
let childItems = getItemsWorker(getChildNodes((<Block>getInnermostModule(node).body).statements), createChildItem);
|
||||
|
||||
return getNavigationBarItem(moduleName,
|
||||
@@ -534,4 +540,206 @@ namespace ts.NavigationBar {
|
||||
return getTextOfNodeFromSourceText(sourceFile.text, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getJsNavigationBarItems(sourceFile: SourceFile, compilerOptions: CompilerOptions): NavigationBarItem[] {
|
||||
const anonFnText = "<function>";
|
||||
const anonClassText = "<class>";
|
||||
let indent = 0;
|
||||
|
||||
let rootName = isExternalModule(sourceFile) ?
|
||||
"\"" + escapeString(getBaseFileName(removeFileExtension(normalizePath(sourceFile.fileName)))) + "\""
|
||||
: "<global>";
|
||||
|
||||
let sourceFileItem = getNavBarItem(rootName, ScriptElementKind.moduleElement, [getNodeSpan(sourceFile)]);
|
||||
let topItem = sourceFileItem;
|
||||
|
||||
// Walk the whole file, because we want to also find function expressions - which may be in variable initializer,
|
||||
// call arguments, expressions, etc...
|
||||
forEachChild(sourceFile, visitNode);
|
||||
|
||||
function visitNode(node: Node) {
|
||||
const newItem = createNavBarItem(node);
|
||||
|
||||
if (newItem) {
|
||||
topItem.childItems.push(newItem);
|
||||
}
|
||||
|
||||
// Add a level if traversing into a container
|
||||
if (newItem && (isFunctionLike(node) || isClassLike(node))) {
|
||||
const lastTop = topItem;
|
||||
indent++;
|
||||
topItem = newItem;
|
||||
forEachChild(node, visitNode);
|
||||
topItem = lastTop;
|
||||
indent--;
|
||||
|
||||
// If the last item added was an anonymous function expression, and it had no children, discard it.
|
||||
if (newItem && newItem.text === anonFnText && newItem.childItems.length === 0) {
|
||||
topItem.childItems.pop();
|
||||
}
|
||||
}
|
||||
else {
|
||||
forEachChild(node, visitNode);
|
||||
}
|
||||
}
|
||||
|
||||
function createNavBarItem(node: Node) : NavigationBarItem {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
// Only add to the navbar if at the top-level of the file
|
||||
// Note: "const" and "let" are also SyntaxKind.VariableDeclarations
|
||||
if(node.parent/*VariableDeclarationList*/.parent/*VariableStatement*/
|
||||
.parent/*SourceFile*/.kind !== SyntaxKind.SourceFile) {
|
||||
return undefined;
|
||||
}
|
||||
// If it is initialized with a function expression, handle it when we reach the function expression node
|
||||
const varDecl = node as VariableDeclaration;
|
||||
if (varDecl.initializer && (varDecl.initializer.kind === SyntaxKind.FunctionExpression ||
|
||||
varDecl.initializer.kind === SyntaxKind.ArrowFunction ||
|
||||
varDecl.initializer.kind === SyntaxKind.ClassExpression)) {
|
||||
return undefined;
|
||||
}
|
||||
// Fall through
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.Constructor:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
// "export default function().." looks just like a regular function/class declaration, except with the 'default' flag
|
||||
const name = node.flags && (node.flags & NodeFlags.Default) && !(node as (Declaration)).name ? "default" :
|
||||
node.kind === SyntaxKind.Constructor ? "constructor" :
|
||||
declarationNameToString((node as (Declaration)).name);
|
||||
return getNavBarItem(name, getScriptKindForElementKind(node.kind), [getNodeSpan(node)]);
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.ClassExpression:
|
||||
return getDefineModuleItem(node) || getFunctionOrClassExpressionItem(node);
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
const methodDecl = node as MethodDeclaration;
|
||||
return getNavBarItem(declarationNameToString(methodDecl.name),
|
||||
ScriptElementKind.memberFunctionElement,
|
||||
[getNodeSpan(node)]);
|
||||
case SyntaxKind.ExportAssignment:
|
||||
// e.g. "export default <expr>"
|
||||
return getNavBarItem("default", ScriptElementKind.variableElement, [getNodeSpan(node)]);
|
||||
case SyntaxKind.ImportClause: // e.g. 'def' in: import def from 'mod' (in ImportDeclaration)
|
||||
if (!(node as ImportClause).name) {
|
||||
// No default import (this node is still a parent of named & namespace imports, which are handled below)
|
||||
return undefined;
|
||||
}
|
||||
// fall through
|
||||
case SyntaxKind.ImportSpecifier: // e.g. 'id' in: import {id} from 'mod' (in NamedImports, in ImportClause)
|
||||
case SyntaxKind.NamespaceImport: // e.g. '* as ns' in: import * as ns from 'mod' (in ImportClause)
|
||||
case SyntaxKind.ExportSpecifier: // e.g. 'a' or 'b' in: export {a, foo as b} from 'mod'
|
||||
// Export specifiers are only interesting if they are reexports from another module, or renamed, else they are already globals
|
||||
if (node.kind === SyntaxKind.ExportSpecifier) {
|
||||
if (!(node.parent.parent as ExportDeclaration).moduleSpecifier && !(node as ExportSpecifier).propertyName) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
const decl = node as (ImportSpecifier | ImportClause | NamespaceImport | ExportSpecifier);
|
||||
if (!decl.name) {
|
||||
return undefined;
|
||||
}
|
||||
const declName = declarationNameToString(decl.name);
|
||||
return getNavBarItem(declName, ScriptElementKind.constElement, [getNodeSpan(node)]);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getNavBarItem(text: string, kind: string, spans: TextSpan[], kindModifiers = ScriptElementKindModifier.none): NavigationBarItem {
|
||||
return {
|
||||
text, kind, kindModifiers, spans, childItems: [], indent, bolded: false, grayed: false
|
||||
}
|
||||
}
|
||||
|
||||
function getDefineModuleItem(node: Node): NavigationBarItem {
|
||||
if (node.kind !== SyntaxKind.FunctionExpression && node.kind !== SyntaxKind.ArrowFunction) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// No match if this is not a call expression to an identifier named 'define'
|
||||
if (node.parent.kind !== SyntaxKind.CallExpression) {
|
||||
return undefined;
|
||||
}
|
||||
const callExpr = node.parent as CallExpression;
|
||||
if (callExpr.expression.kind !== SyntaxKind.Identifier || callExpr.expression.getText() !== 'define') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Return a module of either the given text in the first argument, or of the source file path
|
||||
let defaultName = node.getSourceFile().fileName;
|
||||
if (callExpr.arguments[0].kind === SyntaxKind.StringLiteral) {
|
||||
defaultName = ((callExpr.arguments[0]) as StringLiteral).text;
|
||||
}
|
||||
return getNavBarItem(defaultName, ScriptElementKind.moduleElement, [getNodeSpan(node.parent)]);
|
||||
}
|
||||
|
||||
function getFunctionOrClassExpressionItem(node: Node): NavigationBarItem {
|
||||
if (node.kind !== SyntaxKind.FunctionExpression &&
|
||||
node.kind !== SyntaxKind.ArrowFunction &&
|
||||
node.kind !== SyntaxKind.ClassExpression) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const fnExpr = node as FunctionExpression | ArrowFunction | ClassExpression;
|
||||
let fnName: string;
|
||||
if (fnExpr.name && getFullWidth(fnExpr.name) > 0) {
|
||||
// The expression has an identifier, so use that as the name
|
||||
fnName = declarationNameToString(fnExpr.name);
|
||||
}
|
||||
else {
|
||||
// See if it is a var initializer. If so, use the var name.
|
||||
if (fnExpr.parent.kind === SyntaxKind.VariableDeclaration) {
|
||||
fnName = declarationNameToString((fnExpr.parent as VariableDeclaration).name);
|
||||
}
|
||||
// See if it is of the form "<expr> = function(){...}". If so, use the text from the left-hand side.
|
||||
else if (fnExpr.parent.kind === SyntaxKind.BinaryExpression &&
|
||||
(fnExpr.parent as BinaryExpression).operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
fnName = (fnExpr.parent as BinaryExpression).left.getText();
|
||||
if (fnName.length > 20) {
|
||||
fnName = fnName.substring(0, 17) + "...";
|
||||
}
|
||||
}
|
||||
// See if it is a property assignment, and if so use the property name
|
||||
else if (fnExpr.parent.kind === SyntaxKind.PropertyAssignment &&
|
||||
(fnExpr.parent as PropertyAssignment).name) {
|
||||
fnName = (fnExpr.parent as PropertyAssignment).name.getText();
|
||||
}
|
||||
else {
|
||||
fnName = node.kind === SyntaxKind.ClassExpression ? anonClassText : anonFnText;
|
||||
}
|
||||
}
|
||||
const scriptKind = node.kind === SyntaxKind.ClassExpression ? ScriptElementKind.classElement : ScriptElementKind.functionElement;
|
||||
return getNavBarItem(fnName, scriptKind, [getNodeSpan(node)]);
|
||||
}
|
||||
|
||||
function getNodeSpan(node: Node) {
|
||||
return node.kind === SyntaxKind.SourceFile
|
||||
? createTextSpanFromBounds(node.getFullStart(), node.getEnd())
|
||||
: createTextSpanFromBounds(node.getStart(), node.getEnd());
|
||||
}
|
||||
|
||||
function getScriptKindForElementKind(kind: SyntaxKind) {
|
||||
switch (kind) {
|
||||
case SyntaxKind.VariableDeclaration:
|
||||
return ScriptElementKind.variableElement;
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
return ScriptElementKind.functionElement;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return ScriptElementKind.classElement;
|
||||
case SyntaxKind.Constructor:
|
||||
return ScriptElementKind.constructorImplementationElement;
|
||||
case SyntaxKind.GetAccessor:
|
||||
return ScriptElementKind.memberGetAccessorElement;
|
||||
case SyntaxKind.SetAccessor:
|
||||
return ScriptElementKind.memberSetAccessorElement;
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
return sourceFileItem.childItems;
|
||||
}
|
||||
}
|
||||
|
||||
+100
-44
@@ -2147,8 +2147,23 @@ namespace ts {
|
||||
export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo {
|
||||
const referencedFiles: FileReference[] = [];
|
||||
const importedFiles: FileReference[] = [];
|
||||
let ambientExternalModules: string[];
|
||||
let ambientExternalModules: { ref: FileReference, depth: number }[];
|
||||
let isNoDefaultLib = false;
|
||||
let braceNesting = 0;
|
||||
// assume that text represent an external module if it contains at least one top level import/export
|
||||
// ambient modules that are found inside external modules are interpreted as module augmentations
|
||||
let externalModule = false;
|
||||
|
||||
function nextToken() {
|
||||
const token = scanner.scan();
|
||||
if (token === SyntaxKind.OpenBraceToken) {
|
||||
braceNesting++;
|
||||
}
|
||||
else if (token === SyntaxKind.CloseBraceToken) {
|
||||
braceNesting--;
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
function processTripleSlashDirectives(): void {
|
||||
const commentRanges = getLeadingCommentRanges(sourceText, 0);
|
||||
@@ -2165,21 +2180,33 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function getFileReference() {
|
||||
const file = scanner.getTokenValue();
|
||||
const pos = scanner.getTokenPos();
|
||||
return {
|
||||
fileName: file,
|
||||
pos: pos,
|
||||
end: pos + file.length
|
||||
};
|
||||
}
|
||||
|
||||
function recordAmbientExternalModule(): void {
|
||||
if (!ambientExternalModules) {
|
||||
ambientExternalModules = [];
|
||||
}
|
||||
ambientExternalModules.push(scanner.getTokenValue());
|
||||
ambientExternalModules.push({ ref: getFileReference(), depth: braceNesting });
|
||||
}
|
||||
|
||||
function recordModuleName() {
|
||||
const importPath = scanner.getTokenValue();
|
||||
const pos = scanner.getTokenPos();
|
||||
importedFiles.push({
|
||||
fileName: importPath,
|
||||
pos: pos,
|
||||
end: pos + importPath.length
|
||||
});
|
||||
importedFiles.push(getFileReference());
|
||||
|
||||
markAsExternalModuleIfTopLevel();
|
||||
}
|
||||
|
||||
function markAsExternalModuleIfTopLevel() {
|
||||
if (braceNesting === 0) {
|
||||
externalModule = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2189,9 +2216,9 @@ namespace ts {
|
||||
let token = scanner.getToken();
|
||||
if (token === SyntaxKind.DeclareKeyword) {
|
||||
// declare module "mod"
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.ModuleKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
recordAmbientExternalModule();
|
||||
}
|
||||
@@ -2208,7 +2235,8 @@ namespace ts {
|
||||
function tryConsumeImport(): boolean {
|
||||
let token = scanner.getToken();
|
||||
if (token === SyntaxKind.ImportKeyword) {
|
||||
token = scanner.scan();
|
||||
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// import "mod";
|
||||
recordModuleName();
|
||||
@@ -2216,9 +2244,9 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
if (token === SyntaxKind.Identifier || isKeyword(token)) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.FromKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// import d from "mod";
|
||||
recordModuleName();
|
||||
@@ -2232,7 +2260,7 @@ namespace ts {
|
||||
}
|
||||
else if (token === SyntaxKind.CommaToken) {
|
||||
// consume comma and keep going
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
}
|
||||
else {
|
||||
// unknown syntax
|
||||
@@ -2241,17 +2269,17 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (token === SyntaxKind.OpenBraceToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
// consume "{ a as B, c, d as D}" clauses
|
||||
// make sure that it stops on EOF
|
||||
while (token !== SyntaxKind.CloseBraceToken && token !== SyntaxKind.EndOfFileToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
}
|
||||
|
||||
if (token === SyntaxKind.CloseBraceToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.FromKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// import {a as A} from "mod";
|
||||
// import d, {a, b as B} from "mod"
|
||||
@@ -2261,13 +2289,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (token === SyntaxKind.AsteriskToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.AsKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.Identifier || isKeyword(token)) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.FromKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// import * as NS from "mod"
|
||||
// import d, * as NS from "mod"
|
||||
@@ -2288,19 +2316,20 @@ namespace ts {
|
||||
function tryConsumeExport(): boolean {
|
||||
let token = scanner.getToken();
|
||||
if (token === SyntaxKind.ExportKeyword) {
|
||||
token = scanner.scan();
|
||||
markAsExternalModuleIfTopLevel();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.OpenBraceToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
// consume "{ a as B, c, d as D}" clauses
|
||||
// make sure it stops on EOF
|
||||
while (token !== SyntaxKind.CloseBraceToken && token !== SyntaxKind.EndOfFileToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
}
|
||||
|
||||
if (token === SyntaxKind.CloseBraceToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.FromKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// export {a as A} from "mod";
|
||||
// export {a, b as B} from "mod"
|
||||
@@ -2310,9 +2339,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (token === SyntaxKind.AsteriskToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.FromKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// export * from "mod"
|
||||
recordModuleName();
|
||||
@@ -2320,9 +2349,9 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (token === SyntaxKind.ImportKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.Identifier || isKeyword(token)) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.EqualsToken) {
|
||||
if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) {
|
||||
return true;
|
||||
@@ -2338,11 +2367,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryConsumeRequireCall(skipCurrentToken: boolean): boolean {
|
||||
let token = skipCurrentToken ? scanner.scan() : scanner.getToken();
|
||||
let token = skipCurrentToken ? nextToken() : scanner.getToken();
|
||||
if (token === SyntaxKind.RequireKeyword) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.OpenParenToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// require("mod");
|
||||
recordModuleName();
|
||||
@@ -2356,17 +2385,17 @@ namespace ts {
|
||||
function tryConsumeDefine(): boolean {
|
||||
let token = scanner.getToken();
|
||||
if (token === SyntaxKind.Identifier && scanner.getTokenValue() === "define") {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token !== SyntaxKind.OpenParenToken) {
|
||||
return true;
|
||||
}
|
||||
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.StringLiteral) {
|
||||
// looks like define ("modname", ... - skip string literal and comma
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
if (token === SyntaxKind.CommaToken) {
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
}
|
||||
else {
|
||||
// unexpected token
|
||||
@@ -2380,7 +2409,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// skip open bracket
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
let i = 0;
|
||||
// scan until ']' or EOF
|
||||
while (token !== SyntaxKind.CloseBracketToken && token !== SyntaxKind.EndOfFileToken) {
|
||||
@@ -2390,7 +2419,7 @@ namespace ts {
|
||||
i++;
|
||||
}
|
||||
|
||||
token = scanner.scan();
|
||||
token = nextToken();
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -2400,7 +2429,7 @@ namespace ts {
|
||||
|
||||
function processImports(): void {
|
||||
scanner.setText(sourceText);
|
||||
scanner.scan();
|
||||
nextToken();
|
||||
// Look for:
|
||||
// import "mod";
|
||||
// import d from "mod"
|
||||
@@ -2427,7 +2456,7 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
scanner.scan();
|
||||
nextToken();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2438,7 +2467,34 @@ namespace ts {
|
||||
processImports();
|
||||
}
|
||||
processTripleSlashDirectives();
|
||||
return { referencedFiles, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules };
|
||||
if (externalModule) {
|
||||
// for external modules module all nested ambient modules are augmentations
|
||||
if (ambientExternalModules) {
|
||||
// move all detected ambient modules to imported files since they need to be resolved
|
||||
for (const decl of ambientExternalModules) {
|
||||
importedFiles.push(decl.ref);
|
||||
}
|
||||
}
|
||||
return { referencedFiles, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: undefined };
|
||||
}
|
||||
else {
|
||||
// for global scripts ambient modules still can have augmentations - look for ambient modules with depth > 0
|
||||
let ambientModuleNames: string[];
|
||||
if (ambientExternalModules) {
|
||||
for (const decl of ambientExternalModules) {
|
||||
if (decl.depth === 0) {
|
||||
if (!ambientModuleNames) {
|
||||
ambientModuleNames = [];
|
||||
}
|
||||
ambientModuleNames.push(decl.ref.fileName);
|
||||
}
|
||||
else {
|
||||
importedFiles.push(decl.ref);
|
||||
}
|
||||
}
|
||||
}
|
||||
return { referencedFiles, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientModuleNames };
|
||||
}
|
||||
}
|
||||
|
||||
/// Helpers
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : Symbol(c, Decl(a.ts, 0, 0))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : c
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : Symbol(c, Decl(a.ts, 0, 0))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : c
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : Symbol(c, Decl(a.ts, 0, 0))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : c
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : Symbol(c, Decl(a.ts, 0, 0))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
|
||||
class c {
|
||||
>c : c
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
//// [noImplicitReturnInConstructors.ts]
|
||||
class C {
|
||||
constructor() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//// [noImplicitReturnInConstructors.js]
|
||||
var C = (function () {
|
||||
function C() {
|
||||
return;
|
||||
}
|
||||
return C;
|
||||
}());
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/noImplicitReturnInConstructors.ts ===
|
||||
class C {
|
||||
>C : Symbol(C, Decl(noImplicitReturnInConstructors.ts, 0, 0))
|
||||
|
||||
constructor() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/noImplicitReturnInConstructors.ts ===
|
||||
class C {
|
||||
>C : C
|
||||
|
||||
constructor() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @declaration: true
|
||||
// @noEmit: true
|
||||
// @fileName: a.ts
|
||||
|
||||
class c {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @out: outDir
|
||||
// @noEmit: true
|
||||
// @fileName: a.ts
|
||||
|
||||
class c {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @outDir: outDir
|
||||
// @noEmit: true
|
||||
// @fileName: a.ts
|
||||
|
||||
class c {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @outFile: a.js
|
||||
// @noEmit: true
|
||||
// @fileName: a.ts
|
||||
|
||||
class c {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @noImplicitReturns: true
|
||||
class C {
|
||||
constructor() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/// <reference path="..\..\..\src\harness\harness.ts" />
|
||||
/// <reference path="..\..\..\src\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe('parseCommandLine', () => {
|
||||
|
||||
function assertParseResult(commandLine: string[], expectedParsedCommandLine: ts.ParsedCommandLine) {
|
||||
const parsed = ts.parseCommandLine(commandLine);
|
||||
const parsedCompilerOptions = JSON.stringify(parsed.options);
|
||||
const expectedCompilerOptions = JSON.stringify(expectedParsedCommandLine.options);
|
||||
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
|
||||
|
||||
const parsedErrors = parsed.errors;
|
||||
const expectedErrors = expectedParsedCommandLine.errors;
|
||||
assert.isTrue(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`);
|
||||
for (let i = 0; i < parsedErrors.length; ++i) {
|
||||
const parsedError = parsedErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(parsedError.code, expectedError.code);
|
||||
assert.equal(parsedError.category, expectedError.category);
|
||||
assert.equal(parsedError.messageText, expectedError.messageText);
|
||||
}
|
||||
|
||||
const parsedFileNames = parsed.fileNames;
|
||||
const expectedFileNames = expectedParsedCommandLine.fileNames;
|
||||
assert.isTrue(parsedFileNames.length === expectedFileNames.length, `Expected fileNames: [${JSON.stringify(expectedFileNames)}]. Actual fileNames: [${JSON.stringify(parsedFileNames)}].`);
|
||||
for (let i = 0; i < parsedFileNames.length; ++i) {
|
||||
const parsedFileName = parsedFileNames[i];
|
||||
const expectedFileName = expectedFileNames[i];
|
||||
assert.equal(parsedFileName, expectedFileName);
|
||||
}
|
||||
}
|
||||
|
||||
it("Parse empty options of --jsx ", () => {
|
||||
// 0.ts --jsx
|
||||
assertParseResult(["0.ts", "--jsx"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Compiler option 'jsx' expects an argument.",
|
||||
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
|
||||
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}],
|
||||
fileNames: ["0.ts"],
|
||||
options: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse empty options of --module ", () => {
|
||||
// 0.ts --
|
||||
assertParseResult(["0.ts", "--module"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Compiler option 'module' expects an argument.",
|
||||
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
|
||||
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}],
|
||||
fileNames: ["0.ts"],
|
||||
options: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse empty options of --newLine ", () => {
|
||||
// 0.ts --newLine
|
||||
assertParseResult(["0.ts", "--newLine"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Compiler option 'newLine' expects an argument.",
|
||||
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
|
||||
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}],
|
||||
fileNames: ["0.ts"],
|
||||
options: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse empty options of --target ", () => {
|
||||
// 0.ts --target
|
||||
assertParseResult(["0.ts", "--target"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Compiler option 'target' expects an argument.",
|
||||
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
|
||||
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}],
|
||||
fileNames: ["0.ts"],
|
||||
options: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse empty options of --moduleResolution ", () => {
|
||||
// 0.ts --moduleResolution
|
||||
assertParseResult(["0.ts", "--moduleResolution"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Compiler option 'moduleResolution' expects an argument.",
|
||||
category: ts.Diagnostics.Compiler_option_0_expects_an_argument.category,
|
||||
code: ts.Diagnostics.Compiler_option_0_expects_an_argument.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}],
|
||||
fileNames: ["0.ts"],
|
||||
options: {}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse multiple compiler flags with input files at the end", () => {
|
||||
// --module commonjs --target es5 0.ts
|
||||
assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts"],
|
||||
{
|
||||
errors: [],
|
||||
fileNames: ["0.ts"],
|
||||
options: {
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
target: ts.ScriptTarget.ES5,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse multiple compiler flags with input files in the middle", () => {
|
||||
// --module commonjs --target es5 0.ts --noImplicitAny
|
||||
assertParseResult(["--module", "commonjs", "--target", "es5", "0.ts", "--noImplicitAny"],
|
||||
{
|
||||
errors: [],
|
||||
fileNames: ["0.ts"],
|
||||
options: {
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
target: ts.ScriptTarget.ES5,
|
||||
noImplicitAny: true,
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
/// <reference path="..\..\..\src\harness\harness.ts" />
|
||||
/// <reference path="..\..\..\src\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe('convertCompilerOptionsFromJson', () => {
|
||||
function assertCompilerOptions(json: any, configFileName: string, expectedResult: { compilerOptions: CompilerOptions, errors: Diagnostic[] }) {
|
||||
const actualErrors: Diagnostic[] = [];
|
||||
const actualCompilerOptions: CompilerOptions = convertCompilerOptionsFromJson(optionDeclarations, json["compilerOptions"], "/apath/", actualErrors, configFileName);
|
||||
|
||||
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
|
||||
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
|
||||
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
|
||||
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
for (let i = 0; i < actualErrors.length; ++i) {
|
||||
const actualError = actualErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code);
|
||||
assert.equal(actualError.category, expectedError.category);
|
||||
assert.equal(actualError.messageText, expectedError.messageText);
|
||||
}
|
||||
}
|
||||
|
||||
// tsconfig.json tests
|
||||
it("Convert correctly format tsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert correctly format tsconfig.json with allowJs is false to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"allowJs": false,
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
allowJs: false,
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert incorrectly option of jsx to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"jsx": ""
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert incorrectly option of module to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert incorrectly option of newLine to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"newLine": "",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert incorrectly option of target to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert incorrectly option of module-resolution to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"moduleResolution": "",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert incorrectly format tsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"modu": "commonjs",
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: {},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Unknown compiler option 'modu'.",
|
||||
code: Diagnostics.Unknown_compiler_option_0.code,
|
||||
category: Diagnostics.Unknown_compiler_option_0.category
|
||||
}]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert default tsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions({}, "tsconfig.json",
|
||||
{
|
||||
compilerOptions: {} as CompilerOptions,
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// jsconfig.json
|
||||
it("Convert correctly format jsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
}
|
||||
}, "jsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
allowJs: true,
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert correctly format jsconfig.json with allowJs is false to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": false,
|
||||
"sourceMap": false,
|
||||
"allowJs": false,
|
||||
}
|
||||
}, "jsconfig.json",
|
||||
{
|
||||
compilerOptions: <CompilerOptions>{
|
||||
allowJs: false,
|
||||
module: ModuleKind.CommonJS,
|
||||
target: ScriptTarget.ES5,
|
||||
noImplicitAny: false,
|
||||
sourceMap: false,
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert incorrectly format jsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions(
|
||||
{
|
||||
"compilerOptions": {
|
||||
"modu": "commonjs",
|
||||
}
|
||||
}, "jsconfig.json",
|
||||
{
|
||||
compilerOptions:
|
||||
{
|
||||
allowJs: true
|
||||
},
|
||||
errors: [{
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Unknown compiler option 'modu'.",
|
||||
code: Diagnostics.Unknown_compiler_option_0.code,
|
||||
category: Diagnostics.Unknown_compiler_option_0.category
|
||||
}]
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("Convert default jsconfig.json to compiler-options ", () => {
|
||||
assertCompilerOptions({}, "jsconfig.json",
|
||||
{
|
||||
compilerOptions:
|
||||
{
|
||||
allowJs: true
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/// <reference path="..\..\..\src\harness\harness.ts" />
|
||||
/// <reference path="..\..\..\src\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
describe('convertTypingOptionsFromJson', () => {
|
||||
function assertTypingOptions(json: any, configFileName: string, expectedResult: { typingOptions: TypingOptions, errors: Diagnostic[] }) {
|
||||
const actualErrors: Diagnostic[] = [];
|
||||
const actualTypingOptions = convertTypingOptionsFromJson(typingOptionDeclarations, json["typingOptions"], "/apath/", actualErrors, configFileName);
|
||||
const parsedTypingOptions = JSON.stringify(actualTypingOptions);
|
||||
const expectedTypingOptions = JSON.stringify(expectedResult.typingOptions);
|
||||
assert.equal(parsedTypingOptions, expectedTypingOptions);
|
||||
|
||||
const expectedErrors = expectedResult.errors;
|
||||
assert.isTrue(expectedResult.errors.length === actualErrors.length, `Expected error: ${JSON.stringify(expectedResult.errors)}. Actual error: ${JSON.stringify(actualErrors)}.`);
|
||||
for (let i = 0; i < actualErrors.length; ++i) {
|
||||
const actualError = actualErrors[i];
|
||||
const expectedError = expectedErrors[i];
|
||||
assert.equal(actualError.code, expectedError.code, `Expected error-code: ${JSON.stringify(expectedError.code)}. Actual error-code: ${JSON.stringify(actualError.code)}.`);
|
||||
assert.equal(actualError.category, expectedError.category, `Expected error-category: ${JSON.stringify(expectedError.category)}. Actual error-category: ${JSON.stringify(actualError.category)}.`);
|
||||
}
|
||||
}
|
||||
|
||||
// tsconfig.json
|
||||
it("Convert correctly format tsconfig.json to typing-options ", () => {
|
||||
assertTypingOptions(
|
||||
{
|
||||
"typingOptions":
|
||||
{
|
||||
"enableAutoDiscovery": true,
|
||||
"include": ["0.d.ts", "1.d.ts"],
|
||||
"exclude": ["0.js", "1.js"]
|
||||
}
|
||||
},
|
||||
"tsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: true,
|
||||
include: ["0.d.ts", "1.d.ts"],
|
||||
exclude: ["0.js", "1.js"]
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
});
|
||||
});
|
||||
|
||||
it("Convert incorrect format tsconfig.json to typing-options ", () => {
|
||||
assertTypingOptions(
|
||||
{
|
||||
"typingOptions":
|
||||
{
|
||||
"enableAutoDiscovy": true,
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: false,
|
||||
include: [],
|
||||
exclude: []
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
category: Diagnostics.Unknown_typing_option_0.category,
|
||||
code: Diagnostics.Unknown_typing_option_0.code,
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: undefined
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it("Convert default tsconfig.json to typing-options ", () => {
|
||||
assertTypingOptions({}, "tsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: false,
|
||||
include: [],
|
||||
exclude: []
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
});
|
||||
});
|
||||
|
||||
it("Convert tsconfig.json with only enableAutoDiscovery property to typing-options ", () => {
|
||||
assertTypingOptions(
|
||||
{
|
||||
"typingOptions":
|
||||
{
|
||||
"enableAutoDiscovery": true
|
||||
}
|
||||
}, "tsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: true,
|
||||
include: [],
|
||||
exclude: []
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
});
|
||||
});
|
||||
|
||||
// jsconfig.json
|
||||
it("Convert jsconfig.json to typing-options ", () => {
|
||||
assertTypingOptions(
|
||||
{
|
||||
"typingOptions":
|
||||
{
|
||||
"enableAutoDiscovery": false,
|
||||
"include": ["0.d.ts"],
|
||||
"exclude": ["0.js"]
|
||||
}
|
||||
}, "jsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: false,
|
||||
include: ["0.d.ts"],
|
||||
exclude: ["0.js"]
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
});
|
||||
});
|
||||
|
||||
it("Convert default jsconfig.json to typing-options ", () => {
|
||||
assertTypingOptions({ }, "jsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: true,
|
||||
include: [],
|
||||
exclude: []
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
});
|
||||
});
|
||||
|
||||
it("Convert incorrect format jsconfig.json to typing-options ", () => {
|
||||
assertTypingOptions(
|
||||
{
|
||||
"typingOptions":
|
||||
{
|
||||
"enableAutoDiscovy": true,
|
||||
}
|
||||
}, "jsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: true,
|
||||
include: [],
|
||||
exclude: []
|
||||
},
|
||||
errors: [
|
||||
{
|
||||
category: Diagnostics.Unknown_compiler_option_0.category,
|
||||
code: Diagnostics.Unknown_typing_option_0.code,
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: undefined
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it("Convert jsconfig.json with only enableAutoDiscovery property to typing-options ", () => {
|
||||
assertTypingOptions(
|
||||
{
|
||||
"typingOptions":
|
||||
{
|
||||
"enableAutoDiscovery": false
|
||||
}
|
||||
}, "jsconfig.json",
|
||||
{
|
||||
typingOptions:
|
||||
{
|
||||
enableAutoDiscovery: false,
|
||||
include: [],
|
||||
exclude: []
|
||||
},
|
||||
errors: <Diagnostic[]>[]
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
/// <reference path="..\..\..\..\src\harness\external\mocha.d.ts" />
|
||||
/// <reference path="..\..\..\..\src\harness\harnessLanguageService.ts" />
|
||||
|
||||
declare namespace chai.assert {
|
||||
function deepEqual(actual: any, expected: any): void;
|
||||
}
|
||||
|
||||
describe('PreProcessFile:', function () {
|
||||
function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void {
|
||||
var resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports);
|
||||
@@ -15,34 +19,30 @@ describe('PreProcessFile:', function () {
|
||||
|
||||
assert.equal(resultIsLibFile, expectedIsLibFile, "Pre-processed file has different value for isLibFile. Expected: " + expectedPreProcess + ". Actual: " + resultIsLibFile);
|
||||
|
||||
assert.equal(resultImportedFiles.length, expectedImportedFiles.length,
|
||||
"Array's length of imported files does not match expected. Expected: " + expectedImportedFiles.length + ". Actual: " + resultImportedFiles.length);
|
||||
checkFileReferenceList("Imported files", expectedImportedFiles, resultImportedFiles);
|
||||
checkFileReferenceList("Referenced files", expectedReferencedFiles, resultReferencedFiles);
|
||||
|
||||
assert.equal(resultReferencedFiles.length, expectedReferencedFiles.length,
|
||||
"Array's length of referenced files does not match expected. Expected: " + expectedReferencedFiles.length + ". Actual: " + resultReferencedFiles.length);
|
||||
assert.deepEqual(resultPreProcess.ambientExternalModules, expectedPreProcess.ambientExternalModules);
|
||||
}
|
||||
|
||||
for (var i = 0; i < expectedImportedFiles.length; ++i) {
|
||||
var resultImportedFile = resultImportedFiles[i];
|
||||
var expectedImportedFile = expectedImportedFiles[i];
|
||||
|
||||
assert.equal(resultImportedFile.fileName, expectedImportedFile.fileName, "Imported file path does not match expected. Expected: " + expectedImportedFile.fileName + ". Actual: " + resultImportedFile.fileName + ".");
|
||||
|
||||
assert.equal(resultImportedFile.pos, expectedImportedFile.pos, "Imported file position does not match expected. Expected: " + expectedImportedFile.pos + ". Actual: " + resultImportedFile.pos + ".");
|
||||
|
||||
assert.equal(resultImportedFile.end, expectedImportedFile.end, "Imported file length does not match expected. Expected: " + expectedImportedFile.end + ". Actual: " + resultImportedFile.end + ".");
|
||||
function checkFileReferenceList(kind: string, expected: ts.FileReference[], actual: ts.FileReference[]) {
|
||||
if (expected === actual) {
|
||||
return;
|
||||
}
|
||||
if (!expected) {
|
||||
assert.isTrue(false, `Expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
|
||||
}
|
||||
assert.equal(actual.length, expected.length, `[${kind}] Actual array's length does not match expected length. Expected files: ${JSON.stringify(expected)}, actual files: ${JSON.stringify(actual)}`);
|
||||
|
||||
for (var i = 0; i < expectedReferencedFiles.length; ++i) {
|
||||
var resultReferencedFile = resultReferencedFiles[i];
|
||||
var expectedReferencedFile = expectedReferencedFiles[i];
|
||||
|
||||
assert.equal(resultReferencedFile.fileName, expectedReferencedFile.fileName, "Referenced file path does not match expected. Expected: " + expectedReferencedFile.fileName + ". Actual: " + resultReferencedFile.fileName + ".");
|
||||
|
||||
assert.equal(resultReferencedFile.pos, expectedReferencedFile.pos, "Referenced file position does not match expected. Expected: " + expectedReferencedFile.pos + ". Actual: " + resultReferencedFile.pos + ".");
|
||||
|
||||
assert.equal(resultReferencedFile.end, expectedReferencedFile.end, "Referenced file length does not match expected. Expected: " + expectedReferencedFile.end + ". Actual: " + resultReferencedFile.end + ".");
|
||||
for (var i = 0; i < expected.length; ++i) {
|
||||
var actualReference = actual[i];
|
||||
var expectedReference = expected[i];
|
||||
assert.equal(actualReference.fileName, expectedReference.fileName, `[${kind}] actual file path does not match expected. Expected: "${expectedReference.fileName}". Actual: "${actualReference.fileName}".`);
|
||||
assert.equal(actualReference.pos, expectedReference.pos, `[${kind}] actual file start position does not match expected. Expected: "${expectedReference.pos}". Actual: "${actualReference.pos}".`);
|
||||
assert.equal(actualReference.end, expectedReference.end, `[${kind}] actual file end pos does not match expected. Expected: "${expectedReference.end}". Actual: "${actualReference.end}".`);
|
||||
}
|
||||
}
|
||||
|
||||
describe("Test preProcessFiles,", function () {
|
||||
it("Correctly return referenced files from triple slash", function () {
|
||||
test("///<reference path = \"refFile1.ts\" />" + "\n" + "///<reference path =\"refFile2.ts\"/>" + "\n" + "///<reference path=\"refFile3.ts\" />" + "\n" + "///<reference path= \"..\\refFile4d.ts\" />",
|
||||
@@ -183,7 +183,7 @@ describe('PreProcessFile:', function () {
|
||||
function foo() {
|
||||
}
|
||||
`,
|
||||
/* readImports */ false,
|
||||
/* readImports */ true,
|
||||
/* detectJavaScriptImports */ false,
|
||||
|
||||
{
|
||||
@@ -262,6 +262,165 @@ describe('PreProcessFile:', function () {
|
||||
isLibFile: false
|
||||
})
|
||||
});
|
||||
it("correctly handles augmentations in external modules - 1", () => {
|
||||
test(`
|
||||
declare module "../Observable" {
|
||||
interface I {}
|
||||
}
|
||||
|
||||
export {}
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "../Observable", "pos": 28, "end": 41 }
|
||||
],
|
||||
ambientExternalModules: undefined,
|
||||
isLibFile: false
|
||||
})
|
||||
});
|
||||
it("correctly handles augmentations in external modules - 2", () => {
|
||||
test(`
|
||||
declare module "../Observable" {
|
||||
interface I {}
|
||||
}
|
||||
|
||||
import * as x from "m";
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "m", "pos": 135, "end": 136 },
|
||||
{ "fileName": "../Observable", "pos": 28, "end": 41 }
|
||||
],
|
||||
ambientExternalModules: undefined,
|
||||
isLibFile: false
|
||||
})
|
||||
});
|
||||
it("correctly handles augmentations in external modules - 3", () => {
|
||||
test(`
|
||||
declare module "../Observable" {
|
||||
interface I {}
|
||||
}
|
||||
|
||||
import m = require("m");
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "m", "pos": 135, "end": 136 },
|
||||
{ "fileName": "../Observable", "pos": 28, "end": 41 }
|
||||
],
|
||||
ambientExternalModules: undefined,
|
||||
isLibFile: false
|
||||
})
|
||||
});
|
||||
it("correctly handles augmentations in external modules - 4", () => {
|
||||
test(`
|
||||
declare module "../Observable" {
|
||||
interface I {}
|
||||
}
|
||||
namespace N {}
|
||||
export = N;
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "../Observable", "pos": 28, "end": 41 }
|
||||
],
|
||||
ambientExternalModules: undefined,
|
||||
isLibFile: false
|
||||
})
|
||||
});
|
||||
it("correctly handles augmentations in external modules - 5", () => {
|
||||
test(`
|
||||
declare module "../Observable" {
|
||||
interface I {}
|
||||
}
|
||||
namespace N {}
|
||||
export import IN = N;
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "../Observable", "pos": 28, "end": 41 }
|
||||
],
|
||||
ambientExternalModules: undefined,
|
||||
isLibFile: false
|
||||
})
|
||||
});
|
||||
it("correctly handles augmentations in external modules - 6", () => {
|
||||
test(`
|
||||
declare module "../Observable" {
|
||||
interface I {}
|
||||
}
|
||||
export let x = 1;
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "../Observable", "pos": 28, "end": 41 }
|
||||
],
|
||||
ambientExternalModules: undefined,
|
||||
isLibFile: false
|
||||
})
|
||||
});
|
||||
it ("correctly handles augmentations in ambient external modules - 1", () => {
|
||||
test(`
|
||||
declare module "m1" {
|
||||
export * from "m2";
|
||||
declare module "augmentation" {
|
||||
interface I {}
|
||||
}
|
||||
}
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "m2", "pos": 65, "end": 67 },
|
||||
{ "fileName": "augmentation", "pos": 102, "end": 114 }
|
||||
],
|
||||
ambientExternalModules: ["m1"],
|
||||
isLibFile: false
|
||||
});
|
||||
});
|
||||
it ("correctly handles augmentations in ambient external modules - 2", () => {
|
||||
test(`
|
||||
namespace M { var x; }
|
||||
import IM = M;
|
||||
declare module "m1" {
|
||||
export * from "m2";
|
||||
declare module "augmentation" {
|
||||
interface I {}
|
||||
}
|
||||
}
|
||||
`,
|
||||
/*readImportFile*/ true,
|
||||
/*detectJavaScriptImports*/ false,
|
||||
{
|
||||
referencedFiles: [],
|
||||
importedFiles: [
|
||||
{ "fileName": "m2", "pos": 127, "end": 129 },
|
||||
{ "fileName": "augmentation", "pos": 164, "end": 176 }
|
||||
],
|
||||
ambientExternalModules: ["m1"],
|
||||
isLibFile: false
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -82,5 +82,25 @@ namespace ts {
|
||||
it("returns object with error when json is invalid", () => {
|
||||
assertParseError("invalid");
|
||||
});
|
||||
|
||||
it("returns object when users correctly specify library", () => {
|
||||
assertParseResult(
|
||||
`{
|
||||
"compilerOptions": {
|
||||
"lib": "es5"
|
||||
}
|
||||
}`, {
|
||||
config: { compilerOptions: { lib: "es5" } }
|
||||
});
|
||||
|
||||
assertParseResult(
|
||||
`{
|
||||
"compilerOptions": {
|
||||
"lib": "es5,es6"
|
||||
}
|
||||
}`, {
|
||||
config: { compilerOptions: { lib: "es5,es6" } }
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user