Skip to content

Commit f23c35f

Browse files
committed
Merge pull request #5728 from Microsoft/pathMappingModuleResolution
Path mapping module resolution
2 parents 2b22a47 + adacad3 commit f23c35f

File tree

81 files changed

+3537
-138
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+3537
-138
lines changed

src/compiler/commandLineParser.ts

Lines changed: 91 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ namespace ts {
255255
name: "moduleResolution",
256256
type: {
257257
"node": ModuleResolutionKind.NodeJs,
258-
"classic": ModuleResolutionKind.Classic
258+
"classic": ModuleResolutionKind.Classic,
259259
},
260260
description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
261261
error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic,
@@ -286,14 +286,40 @@ namespace ts {
286286
description: Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file
287287
},
288288
{
289-
name: "allowSyntheticDefaultImports",
289+
name: "baseUrl",
290+
type: "string",
291+
isFilePath: true,
292+
description: Diagnostics.Base_directory_to_resolve_non_absolute_module_names
293+
},
294+
{
295+
// this option can only be specified in tsconfig.json
296+
// use type = object to copy the value as-is
297+
name: "paths",
298+
type: "object",
299+
isTSConfigOnly: true
300+
},
301+
{
302+
// this option can only be specified in tsconfig.json
303+
// use type = object to copy the value as-is
304+
name: "rootDirs",
305+
type: "object",
306+
isTSConfigOnly: true,
307+
isFilePath: true
308+
},
309+
{
310+
name: "traceModuleResolution",
290311
type: "boolean",
291-
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
312+
description: Diagnostics.Enable_tracing_of_the_module_resolution_process
292313
},
293314
{
294315
name: "allowJs",
295316
type: "boolean",
296317
description: Diagnostics.Allow_javascript_files_to_be_compiled
318+
},
319+
{
320+
name: "allowSyntheticDefaultImports",
321+
type: "boolean",
322+
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
297323
}
298324
];
299325

@@ -355,34 +381,39 @@ namespace ts {
355381
if (hasProperty(optionNameMap, s)) {
356382
const opt = optionNameMap[s];
357383

358-
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
359-
if (!args[i] && opt.type !== "boolean") {
360-
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
384+
if (opt.isTSConfigOnly) {
385+
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name));
361386
}
387+
else {
388+
// Check to see if no argument was provided (e.g. "--locale" is the last command-line argument).
389+
if (!args[i] && opt.type !== "boolean") {
390+
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_expects_an_argument, opt.name));
391+
}
362392

363-
switch (opt.type) {
364-
case "number":
365-
options[opt.name] = parseInt(args[i]);
366-
i++;
367-
break;
368-
case "boolean":
369-
options[opt.name] = true;
370-
break;
371-
case "string":
372-
options[opt.name] = args[i] || "";
373-
i++;
374-
break;
375-
// If not a primitive, the possible types are specified in what is effectively a map of options.
376-
default:
377-
let map = <Map<number>>opt.type;
378-
let key = (args[i] || "").toLowerCase();
379-
i++;
380-
if (hasProperty(map, key)) {
381-
options[opt.name] = map[key];
382-
}
383-
else {
384-
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
385-
}
393+
switch (opt.type) {
394+
case "number":
395+
options[opt.name] = parseInt(args[i]);
396+
i++;
397+
break;
398+
case "boolean":
399+
options[opt.name] = true;
400+
break;
401+
case "string":
402+
options[opt.name] = args[i] || "";
403+
i++;
404+
break;
405+
// If not a primitive, the possible types are specified in what is effectively a map of options.
406+
default:
407+
let map = <Map<number>>opt.type;
408+
let key = (args[i] || "").toLowerCase();
409+
i++;
410+
if (hasProperty(map, key)) {
411+
options[opt.name] = map[key];
412+
}
413+
else {
414+
errors.push(createCompilerDiagnostic((<CommandLineOptionOfCustomType>opt).error));
415+
}
416+
}
386417
}
387418
}
388419
else {
@@ -485,7 +516,6 @@ namespace ts {
485516
return output;
486517
}
487518

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

499529
const options = extend(existingOptions, optionsFromJsonConfigFile);
530+
500531
return {
501532
options,
502533
fileNames: getFileNames(),
@@ -580,7 +611,36 @@ namespace ts {
580611
}
581612
}
582613
if (opt.isFilePath) {
583-
value = normalizePath(combinePaths(basePath, value));
614+
switch (typeof value) {
615+
case "string":
616+
value = normalizePath(combinePaths(basePath, value));
617+
break;
618+
case "object":
619+
// "object" options with 'isFilePath' = true expected to be string arrays
620+
let paths: string[] = [];
621+
let invalidOptionType = false;
622+
if (!isArray(value)) {
623+
invalidOptionType = true;
624+
}
625+
else {
626+
for (const element of <any[]>value) {
627+
if (typeof element === "string") {
628+
paths.push(normalizePath(combinePaths(basePath, element)));
629+
}
630+
else {
631+
invalidOptionType = true;
632+
break;
633+
}
634+
}
635+
}
636+
if (invalidOptionType) {
637+
errors.push(createCompilerDiagnostic(Diagnostics.Option_0_should_have_array_of_strings_as_a_value, opt.name));
638+
}
639+
else {
640+
value = paths;
641+
}
642+
break;
643+
}
584644
if (value === "") {
585645
value = ".";
586646
}

src/compiler/core.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ namespace ts {
7474
GreaterThan = 1
7575
}
7676

77-
export interface StringSet extends Map<any> { }
78-
7977
/**
8078
* Iterates through 'array' by index and performs the callback on each element of array until the callback
8179
* returns a truthy value, then returns that value.
@@ -441,6 +439,17 @@ namespace ts {
441439
};
442440
}
443441

442+
/* internal */
443+
export function formatMessage(dummy: any, message: DiagnosticMessage): string {
444+
let text = getLocaleSpecificMessage(message);
445+
446+
if (arguments.length > 2) {
447+
text = formatStringFromArgs(text, arguments, 2);
448+
}
449+
450+
return text;
451+
}
452+
444453
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic;
445454
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
446455
let text = getLocaleSpecificMessage(message);

src/compiler/diagnosticMessages.json

Lines changed: 129 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,7 +2167,18 @@
21672167
"category": "Error",
21682168
"code": 5059
21692169
},
2170-
2170+
"Option 'paths' cannot be used without specifying '--baseUrl' option.": {
2171+
"category": "Error",
2172+
"code": 5060
2173+
},
2174+
"Pattern '{0}' can have at most one '*' character": {
2175+
"category": "Error",
2176+
"code": 5061
2177+
},
2178+
"Substitution '{0}' in pattern '{1}' in can have at most one '*' character": {
2179+
"category": "Error",
2180+
"code": 5062
2181+
},
21712182
"Concatenate and emit output to single file.": {
21722183
"category": "Message",
21732184
"code": 6001
@@ -2304,10 +2315,10 @@
23042315
"category": "Error",
23052316
"code": 6046
23062317
},
2307-
"Argument for '--target' option must be 'ES3', 'ES5', or 'ES2015'.": {
2308-
"category": "Error",
2309-
"code": 6047
2310-
},
2318+
"Argument for '--target' option must be 'ES3', 'ES5', or 'ES2015'.": {
2319+
"category": "Error",
2320+
"code": 6047
2321+
},
23112322
"Locale must be of the form <language> or <language>-<territory>. For example '{0}' or '{1}'.": {
23122323
"category": "Error",
23132324
"code": 6048
@@ -2368,7 +2379,10 @@
23682379
"category": "Error",
23692380
"code": 6063
23702381
},
2371-
2382+
"Option '{0}' can only be specified in 'tsconfig.json' file.": {
2383+
"category": "Error",
2384+
"code": 6064
2385+
},
23722386
"Enables experimental support for ES7 decorators.": {
23732387
"category": "Message",
23742388
"code": 6065
@@ -2433,15 +2447,122 @@
24332447
"category": "Error",
24342448
"code": 6082
24352449
},
2436-
"Allow javascript files to be compiled.": {
2450+
"Base directory to resolve non-absolute module names.": {
24372451
"category": "Message",
24382452
"code": 6083
24392453
},
24402454
"Specifies the object invoked for createElement and __spread when targeting 'react' JSX emit": {
24412455
"category": "Message",
24422456
"code": 6084
24432457
},
2444-
2458+
"Enable tracing of the module resolution process.": {
2459+
"category": "Message",
2460+
"code": 6085
2461+
},
2462+
"======== Resolving module '{0}' from '{1}'. ========": {
2463+
"category": "Message",
2464+
"code": 6086
2465+
},
2466+
"Explicitly specified module resolution kind: '{0}'.": {
2467+
"category": "Message",
2468+
"code": 6087
2469+
},
2470+
"Module resolution kind is not specified, using '{0}'.": {
2471+
"category": "Message",
2472+
"code": 6088
2473+
},
2474+
"======== Module name '{0}' was successfully resolved to '{1}'. ========": {
2475+
"category": "Message",
2476+
"code": 6089
2477+
},
2478+
"======== Module name '{0}' was not resolved. ========": {
2479+
"category": "Message",
2480+
"code": 6090
2481+
},
2482+
"'paths' option is specified, looking for a pattern to match module name '{0}'.": {
2483+
"category": "Message",
2484+
"code": 6091
2485+
},
2486+
"Module name '{0}', matched pattern '{1}'.": {
2487+
"category": "Message",
2488+
"code": 6092
2489+
},
2490+
"Trying substitution '{0}', candidate module location: '{1}'.": {
2491+
"category": "Message",
2492+
"code": 6093
2493+
},
2494+
"Resolving module name '{0}' relative to base url '{1}' - '{2}'.": {
2495+
"category": "Message",
2496+
"code": 6094
2497+
},
2498+
"Loading module as file / folder, candidate module location '{0}'.": {
2499+
"category": "Message",
2500+
"code": 6095
2501+
},
2502+
"File '{0}' does not exist.": {
2503+
"category": "Message",
2504+
"code": 6096
2505+
},
2506+
"File '{0}' exist - use it as a module resolution result.": {
2507+
"category": "Message",
2508+
"code": 6097
2509+
},
2510+
"Loading module '{0}' from 'node_modules' folder.": {
2511+
"category": "Message",
2512+
"code": 6098
2513+
},
2514+
"Found 'package.json' at '{0}'.": {
2515+
"category": "Message",
2516+
"code": 6099
2517+
},
2518+
"'package.json' does not have 'typings' field.": {
2519+
"category": "Message",
2520+
"code": 6100
2521+
},
2522+
"'package.json' has 'typings' field '{0}' that references '{1}'.": {
2523+
"category": "Message",
2524+
"code": 6101
2525+
},
2526+
"Allow javascript files to be compiled.": {
2527+
"category": "Message",
2528+
"code": 6102
2529+
},
2530+
"Option '{0}' should have array of strings as a value.": {
2531+
"category": "Error",
2532+
"code": 6103
2533+
},
2534+
"Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'.": {
2535+
"category": "Message",
2536+
"code": 6104
2537+
},
2538+
"Expected type of 'typings' field in 'package.json' to be 'string', got '{0}'.": {
2539+
"category": "Message",
2540+
"code": 6105
2541+
},
2542+
"'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'": {
2543+
"category": "Message",
2544+
"code": 6106
2545+
},
2546+
"'rootDirs' option is set, using it to resolve relative module name '{0}'": {
2547+
"category": "Message",
2548+
"code": 6107
2549+
},
2550+
"Longest matching prefix for '{0}' is '{1}'": {
2551+
"category": "Message",
2552+
"code": 6108
2553+
},
2554+
"Loading '{0}' from the root dir '{1}', candidate location '{2}'": {
2555+
"category": "Message",
2556+
"code": 6109
2557+
},
2558+
"Trying other entries in 'rootDirs'": {
2559+
"category": "Message",
2560+
"code": 6110
2561+
},
2562+
"Module resolution using 'rootDirs' has failed": {
2563+
"category": "Message",
2564+
"code": 6111
2565+
},
24452566
"Variable '{0}' implicitly has an '{1}' type.": {
24462567
"category": "Error",
24472568
"code": 7005

0 commit comments

Comments
 (0)