Skip to content

Path mapping module resolution #5728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
Jan 27, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
d2fd643
initial implementation of path mapping based module resolution
vladima Nov 19, 2015
6bed1ba
merge with master
vladima Nov 20, 2015
6844285
verbose module resolution
vladima Nov 20, 2015
cccdd44
merge with master
vladima Nov 25, 2015
25cc97b
addressed PR feedback
vladima Nov 25, 2015
62370a0
addressed PR feedback
vladima Nov 26, 2015
0377e7a
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Nov 26, 2015
4e3cba1
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Nov 26, 2015
cc25f2c
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Nov 28, 2015
0d0de5a
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 1, 2015
f18e203
fix merge issues
vladima Dec 1, 2015
9a9b51f
merge with master
vladima Dec 2, 2015
0130c23
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 4, 2015
bb9498f
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 5, 2015
2dbf621
merge with origin/master, add trace message with type of 'typings' fi…
vladima Dec 7, 2015
6a63c0d
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 9, 2015
a81c875
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 11, 2015
c644fb3
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 12, 2015
57e7615
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 14, 2015
6b4bc43
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 18, 2015
5327868
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 19, 2015
c06be3a
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 21, 2015
a399208
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Dec 22, 2015
39a50fa
merge with origin/master
vladima Jan 4, 2016
635201c
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Jan 5, 2016
73c94d0
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Jan 5, 2016
3d4e220
merge with origin/master
vladima Jan 6, 2016
39ad077
merge with origin/master
vladima Jan 12, 2016
9d828e3
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Jan 20, 2016
cb3e93f
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Jan 25, 2016
2b2b150
Merge remote-tracking branch 'origin/master' into pathMappingModuleRe…
vladima Jan 25, 2016
8a8ed0a
update implementation based on the results of design meeting
vladima Jan 25, 2016
adacad3
addressed PR feedback
vladima Jan 27, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 91 additions & 31 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ namespace ts {
name: "moduleResolution",
type: {
"node": ModuleResolutionKind.NodeJs,
"classic": ModuleResolutionKind.Classic
"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,
Expand Down Expand Up @@ -286,14 +286,40 @@ namespace ts {
description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
},
{
name: "allowSyntheticDefaultImports",
name: "baseUrl",
type: "string",
isFilePath: true,
description: Diagnostics.Base_directory_to_resolve_non_absolute_module_names
},
{
// this option can only be specified in tsconfig.json
// use type = object to copy the value as-is
name: "paths",
type: "object",
isTSConfigOnly: true
},
{
// this option can only be specified in tsconfig.json
// use type = object to copy the value as-is
name: "rootDirs",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave a line note

type: "object",
isTSConfigOnly: true,
isFilePath: true
},
{
name: "traceModuleResolution",
type: "boolean",
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
description: Diagnostics.Enable_tracing_of_the_module_resolution_process
},
{
name: "allowJs",
type: "boolean",
description: Diagnostics.Allow_javascript_files_to_be_compiled
},
{
name: "allowSyntheticDefaultImports",
type: "boolean",
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
}
];

Expand Down Expand Up @@ -355,34 +381,39 @@ namespace ts {
if (hasProperty(optionNameMap, s)) {
const opt = optionNameMap[s];

// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
if (!args[i] && opt.type !== "boolean") {
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
if (opt.isTSConfigOnly) {
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
}
else {
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
if (!args[i] && opt.type !== "boolean") {
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
}

switch (opt.type) {
case "number":
options[opt.name] = parseInt(args[i]);
i++;
break;
case "boolean":
options[opt.name] = true;
break;
case "string":
options[opt.name] = 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();
i++;
if (hasProperty(map, key)) {
options[opt.name] = map[key];
}
else {
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
}
switch (opt.type) {
case "number":
options[opt.name] = parseInt(args[i]);
i++;
break;
case "boolean":
options[opt.name] = true;
break;
case "string":
options[opt.name] = 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();
i++;
if (hasProperty(map, key)) {
options[opt.name] = map[key];
}
else {
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
}
}
}
}
else {
Expand Down Expand Up @@ -485,7 +516,6 @@ namespace ts {
return output;
}


/**
* Parse the contents of a config file (tsconfig.json).
* @param json The contents of the config file to parse
Expand All @@ -497,6 +527,7 @@ namespace ts {
const { options: optionsFromJsonConfigFile, errors } = convertCompilerOptionsFromJson(json["compilerOptions"], basePath, configFileName);

const options = extend(existingOptions, optionsFromJsonConfigFile);

return {
options,
fileNames: getFileNames(),
Expand Down Expand Up @@ -580,7 +611,36 @@ namespace ts {
}
}
if (opt.isFilePath) {
value = normalizePath(combinePaths(basePath, value));
switch (typeof value) {
case "string":
value = normalizePath(combinePaths(basePath, value));
break;
case "object":
// "object" options with 'isFilePath' = true expected to be string arrays
let paths: string[] = [];
let invalidOptionType = false;
if (!isArray(value)) {
invalidOptionType = true;
}
else {
for (const element of <any[]>value) {
if (typeof element === "string") {
paths.push(normalizePath(combinePaths(basePath, element)));
}
else {
invalidOptionType = true;
break;
}
}
}
if (invalidOptionType) {
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_should_have_array_of_strings_as_a_value, opt.name));
}
else {
value = paths;
}
break;
}
if (value === "") {
value = ".";
}
Expand Down
13 changes: 11 additions & 2 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ namespace ts {
GreaterThan = 1
}

export interface StringSet extends Map<any> { }

/**
* Iterates through 'array' by index and performs the callback on each element of array until the callback
* returns a truthy value, then returns that value.
Expand Down Expand Up @@ -441,6 +439,17 @@ namespace ts {
};
}

/* internal */
export function formatMessage(dummy: any, message: DiagnosticMessage): string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need the first argument here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is necessary to skip host argument in the trace function

let text = getLocaleSpecificMessage(message);

if (arguments.length > 2) {
text = formatStringFromArgs(text, arguments, 2);
}

return text;
}

export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic;
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
let text = getLocaleSpecificMessage(message);
Expand Down
137 changes: 129 additions & 8 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2159,7 +2159,18 @@
"category": "Error",
"code": 5059
},

"Option 'paths' cannot be used without specifying '--baseUrl' option.": {
"category": "Error",
"code": 5060
},
"Pattern '{0}' can have at most one '*' character": {
"category": "Error",
"code": 5061
},
"Substitution '{0}' in pattern '{1}' in can have at most one '*' character": {
"category": "Error",
"code": 5062
},
"Concatenate and emit output to single file.": {
"category": "Message",
"code": 6001
Expand Down Expand Up @@ -2296,10 +2307,10 @@
"category": "Error",
"code": 6046
},
"Argument for '--target' option must be 'ES3', 'ES5', or 'ES2015'.": {
"category": "Error",
"code": 6047
},
"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
Expand Down Expand Up @@ -2360,7 +2371,10 @@
"category": "Error",
"code": 6063
},

"Option '{0}' can only be specified in 'tsconfig.json' file.": {
"category": "Error",
"code": 6064
},
"Enables experimental support for ES7 decorators.": {
"category": "Message",
"code": 6065
Expand Down Expand Up @@ -2425,15 +2439,122 @@
"category": "Error",
"code": 6082
},
"Allow javascript files to be compiled.": {
"Base directory to resolve non-absolute module names.": {
"category": "Message",
"code": 6083
},
"Specifies the object invoked for createElement and __spread when targeting 'react' JSX emit": {
"category": "Message",
"code": 6084
},

"Enable tracing of the module resolution process.": {
"category": "Message",
"code": 6085
},
"======== Resolving module '{0}' from '{1}'. ========": {
"category": "Message",
"code": 6086
},
"Explicitly specified module resolution kind: '{0}'.": {
"category": "Message",
"code": 6087
},
"Module resolution kind is not specified, using '{0}'.": {
"category": "Message",
"code": 6088
},
"======== Module name '{0}' was successfully resolved to '{1}'. ========": {
"category": "Message",
"code": 6089
},
"======== Module name '{0}' was not resolved. ========": {
"category": "Message",
"code": 6090
},
"'paths' option is specified, looking for a pattern to match module name '{0}'.": {
"category": "Message",
"code": 6091
},
"Module name '{0}', matched pattern '{1}'.": {
"category": "Message",
"code": 6092
},
"Trying substitution '{0}', candidate module location: '{1}'.": {
"category": "Message",
"code": 6093
},
"Resolving module name '{0}' relative to base url '{1}' - '{2}'.": {
"category": "Message",
"code": 6094
},
"Loading module as file / folder, candidate module location '{0}'.": {
"category": "Message",
"code": 6095
},
"File '{0}' does not exist.": {
"category": "Message",
"code": 6096
},
"File '{0}' exist - use it as a module resolution result.": {
"category": "Message",
"code": 6097
},
"Loading module '{0}' from 'node_modules' folder.": {
"category": "Message",
"code": 6098
},
"Found 'package.json' at '{0}'.": {
"category": "Message",
"code": 6099
},
"'package.json' does not have 'typings' field.": {
"category": "Message",
"code": 6100
},
"'package.json' has 'typings' field '{0}' that references '{1}'.": {
"category": "Message",
"code": 6101
},
"Allow javascript files to be compiled.": {
"category": "Message",
"code": 6102
},
"Option '{0}' should have array of strings as a value.": {
"category": "Error",
"code": 6103
},
"Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'.": {
"category": "Message",
"code": 6104
},
"Expected type of 'typings' field in 'package.json' to be 'string', got '{0}'.": {
"category": "Message",
"code": 6105
},
"'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'": {
"category": "Message",
"code": 6106
},
"'rootDirs' option is set, using it to resolve relative module name '{0}'": {
"category": "Message",
"code": 6107
},
"Longest matching prefix for '{0}' is '{1}'": {
"category": "Message",
"code": 6108
},
"Loading '{0}' from the root dir '{1}', candidate location '{2}'": {
"category": "Message",
"code": 6109
},
"Trying other entries in 'rootDirs'": {
"category": "Message",
"code": 6110
},
"Module resolution using 'rootDirs' has failed": {
"category": "Message",
"code": 6111
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
Expand Down
Loading