Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'upstream/master' into loadJsFromModules
  • Loading branch information
billti committed May 24, 2016
commit c76dc72b402d292f90ba51e90ff2b7b3739262e9
66 changes: 66 additions & 0 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,72 @@ namespace ts {
name: "maxNodeModuleJsDepth",
type: "number",
description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
},
{
name: "listEmittedFiles",
type: "boolean"
},
{
name: "lib",
type: "list",
element: {
name: "lib",
type: {
// JavaScript only
"es5": "lib.es5.d.ts",
"es6": "lib.es2015.d.ts",
"es2015": "lib.es2015.d.ts",
"es7": "lib.es2016.d.ts",
"es2016": "lib.es2016.d.ts",
"es2017": "lib.es2017.d.ts",
// Host only
"dom": "lib.dom.d.ts",
"webworker": "lib.webworker.d.ts",
"scripthost": "lib.scripthost.d.ts",
// ES2015 Or ESNext By-feature options
"es2015.core": "lib.es2015.core.d.ts",
"es2015.collection": "lib.es2015.collection.d.ts",
"es2015.generator": "lib.es2015.generator.d.ts",
"es2015.iterable": "lib.es2015.iterable.d.ts",
"es2015.promise": "lib.es2015.promise.d.ts",
"es2015.proxy": "lib.es2015.proxy.d.ts",
"es2015.reflect": "lib.es2015.reflect.d.ts",
"es2015.symbol": "lib.es2015.symbol.d.ts",
"es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts",
"es2016.array.include": "lib.es2016.array.include.d.ts",
"es2017.object": "lib.es2017.object.d.ts"
},
},
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon
},
{
name: "strictNullChecks",
type: "boolean",
description: Diagnostics.Enable_strict_null_checks
}
];

/* @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"
}
}
];

Expand Down
79 changes: 77 additions & 2 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2680,11 +2680,86 @@
"category": "Message",
"code": 6112
},
"The maximum dependency depth to search under node_modules and load JavaScript files": {
"Enable strict null checks.": {
"category": "Message",
"code": 6113
},

"Unknown option 'excludes'. Did you mean 'exclude'?": {
"category": "Error",
"code": 6114
},
"Raise error on 'this' expressions with an implied 'any' type.": {
"category": "Message",
"code": 6115
},
"======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========": {
"category": "Message",
"code": 6116
},
"Resolving using primary search paths...": {
"category": "Message",
"code": 6117
},
"Resolving from node_modules folder...": {
"category": "Message",
"code": 6118
},
"======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========": {
"category": "Message",
"code": 6119
},
"======== Type reference directive '{0}' was not resolved. ========": {
"category": "Message",
"code": 6120
},
"Resolving with primary search path '{0}'": {
"category": "Message",
"code": 6121
},
"Root directory cannot be determined, skipping primary search paths.": {
"category": "Message",
"code": 6122
},
"======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========": {
"category": "Message",
"code": 6123
},
"Type declaration files to be included in compilation.": {
"category": "Message",
"code": 6124
},
"Looking up in 'node_modules' folder, initial location '{0}'": {
"category": "Message",
"code": 6125
},
"Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder.": {
"category": "Message",
"code": 6126
},
"======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========": {
"category": "Message",
"code": 6127
},
"======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========": {
"category": "Message",
"code": 6128
},
"The config file '{0}' found doesn't contain any source files.": {
"category": "Error",
"code": 6129
},
"Resolving real path for '{0}', result '{1}'": {
"category": "Message",
"code": 6130
},
"The maximum dependency depth to search under node_modules and load JavaScript files": {
"category": "Message",
"code": 6131
},
"No types specified in 'package.json' and is 'allowJs' set. Returning package 'main' value of '{0}' for module": {
"category": "Message",
"code": 6132
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
Expand Down
102 changes: 44 additions & 58 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ namespace ts {
/* @internal */ export let ioWriteTime = 0;

/** The version of the TypeScript compiler release */
export const version = "1.9.0";

const emptyArray: any[] = [];
const startsWithDotSlashOrDotDotSlash = /^(\.\/|\.\.\/)/;

const defaultLibrarySearchPaths = [
"types/",
"node_modules/",
"node_modules/@types/",
];

export const version = "1.9.0";

export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean): string {
while (true) {
Expand Down Expand Up @@ -114,7 +120,9 @@ namespace ts {
return false;
}

return !startsWithDotSlashOrDotDotSlash.test(moduleName);
const i = moduleName.lastIndexOf("./", 1);
const startsWithDotSlashOrDotDotSlash = i === 0 || (i === 1 && moduleName.charCodeAt(0) === CharacterCodes.dot);
return !startsWithDotSlashOrDotDotSlash;
}

interface ModuleResolutionState {
Expand All @@ -126,10 +134,10 @@ namespace ts {
}

function tryReadTypesSection(packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
let jsonContent: { typings?: string, types?: string };
let jsonContent: { typings?: string, types?: string, main?: string };
try {
const jsonText = state.host.readFile(packageJsonPath);
jsonContent = jsonText ? <{ typings?: string, types?: string }>JSON.parse(jsonText) : {};
jsonContent = jsonText ? <{ typings?: string, types?: string, main?: string }>JSON.parse(jsonText) : {};
}
catch (e) {
// gracefully handle if readFile fails or returns not JSON
Expand Down Expand Up @@ -169,6 +177,14 @@ namespace ts {
}
return typesFilePath;
}
// Use the main module for inferring types if no types package specified and the allowJs is set
if (state.compilerOptions.allowJs && jsonContent.main && typeof jsonContent.main === "string") {
if (state.traceEnabled) {
trace(state.host, Diagnostics.No_types_specified_in_package_json_and_is_allowJs_set_Returning_package_main_value_of_0_for_module, jsonContent.main);
}
const mainFilePath = normalizePath(combinePaths(baseDirectory, jsonContent.main));
return mainFilePath;
}
return undefined;
}

Expand Down Expand Up @@ -563,7 +579,7 @@ namespace ts {
failedLookupLocations, supportedExtensions, state);

let isExternalLibraryImport = false;
if (!resolvedFileName) {
if (!resolvedFileName) {
if (moduleHasNonRelativeName(moduleName)) {
if (traceEnabled) {
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder, moduleName);
Expand Down Expand Up @@ -621,7 +637,7 @@ namespace ts {
return forEach(extensions, tryLoad);

function tryLoad(ext: string): string {
if (ext === ".tsx" && state.skipTsx) {
if ((ext === ".tsx" || ext === ".jsx") && state.skipTsx) {
return undefined;
}
const fileName = fileExtensionIs(candidate, ext) ? candidate : candidate + ext;
Expand All @@ -648,47 +664,18 @@ namespace ts {
if (state.traceEnabled) {
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
}

let jsonContent: { typings?: string; main?: string };

try {
const jsonText = state.host.readFile(packageJsonPath);
jsonContent = jsonText ? <{ typings?: string; main?: string }>JSON.parse(jsonText) : { typings: undefined, main: undefined };
}
catch (e) {
// gracefully handle if readFile fails or returns not JSON
jsonContent = { typings: undefined };
}

if (jsonContent.typings) {
if (typeof jsonContent.typings === "string") {
const typingsFile = normalizePath(combinePaths(candidate, jsonContent.typings));
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_has_typings_field_0_that_references_1, jsonContent.typings, typingsFile);
}
const result = loadModuleFromFile(typingsFile, /* don't add extension */ [""], failedLookupLocation, !directoryProbablyExists(getDirectoryPath(typingsFile), state.host), state);
if (result) {
return result;
}
}
else if (state.traceEnabled) {
trace(state.host, Diagnostics.Expected_type_of_typings_field_in_package_json_to_be_string_got_0, typeof jsonContent.typings);
const typesFile = tryReadTypesSection(packageJsonPath, candidate, state);
if (typesFile) {
const result = loadModuleFromFile(typesFile, extensions, failedLookupLocation, !directoryProbablyExists(getDirectoryPath(typesFile), state.host), state);
if (result) {
return result;
}
}
else {
if (state.traceEnabled) {
trace(state.host, Diagnostics.package_json_does_not_have_types_field);
}
}
// TODO (billti): tracing as per above
if (typeof jsonContent.main === "string") {
// If 'main' points to 'foo.js', we still want to try and load 'foo.d.ts' and 'foo.ts' first (and only 'foo.js' if 'allowJs' is set).
const mainFile = normalizePath(combinePaths(candidate, removeFileExtension(jsonContent.main)));
const result = loadModuleFromFile(mainFile, extensions, failedLookupLocation, !directoryProbablyExists(getDirectoryPath(mainFile), state.host), state);
if (result) {
return result;
}
}
}
else {
if (state.traceEnabled) {
Expand All @@ -705,12 +692,13 @@ namespace ts {
const nodeModulesFolder = combinePaths(directory, "node_modules");
const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
// Load only typescript files irrespective of allowJs option if loading from node modules
let result = loadModuleFromFile(candidate, supportedTypeScriptExtensions, failedLookupLocations, !nodeModulesFolderExists, state);
const supportedExtensions = getSupportedExtensions(state.compilerOptions);

let result = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, !nodeModulesFolderExists, state);
if (result) {
return result;
}
result = loadNodeModuleFromDirectory(supportedTypeScriptExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
if (result) {
return result;
}
Expand All @@ -721,16 +709,11 @@ namespace ts {
while (true) {
const baseName = getBaseFileName(directory);
if (baseName !== "node_modules") {
const nodeModulesFolder = combinePaths(directory, "node_modules");
const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));

const supportedExtensions = getSupportedExtensions(state.compilerOptions);
let result = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, !nodeModulesFolderExists, state);
if (result) {
return result;
}
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
const result =
// first: try to load module as-is
loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state) ||
// second: try to load module from the scope '@types'
loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
if (result) {
return result;
}
Expand Down Expand Up @@ -1779,7 +1762,7 @@ namespace ts {
}

// Get source file from normalized fileName
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number, isFileFromNodeSearch?: boolean): SourceFile {
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number, isFileFromNodeSearch?: boolean): SourceFile {
if (filesByName.contains(path)) {
const file = filesByName.get(path);
// try to check if we've already seen this file but with a different casing in path
Expand All @@ -1788,13 +1771,16 @@ namespace ts {
reportFileNamesDifferOnlyInCasingError(fileName, file.fileName, refFile, refPos, refEnd);
}

if (file) {
file.wasReferenced = file.wasReferenced || isReference;
}

// If this was a file found by a node_modules search, set the nodeModuleSearchDistance to parent distance + 1.
if (isFileFromNodeSearch) {
const newDistance = (refFile && refFile.nodeModuleSearchDistance) === undefined ? 1 : refFile.nodeModuleSearchDistance + 1;
// If already set on the file, don't overwrite if it was already found closer (which may be '0' if added as a root file)
file.nodeModuleSearchDistance = (typeof file.nodeModuleSearchDistance === "number") ? Math.min(file.nodeModuleSearchDistance, newDistance) : newDistance;
}

return file;
}

Expand Down Expand Up @@ -1945,7 +1931,7 @@ namespace ts {
// add file to program only if:
// - resolution was successful
// - noResolve is falsy
// - module name come from the list fo imports
// - module name comes from the list of imports
// - it's not a top level JavaScript module that exceeded the search max
const exceedsJsSearchDepth = resolution && resolution.isExternalLibraryImport &&
hasJavaScriptFileExtension(resolution.resolvedFileName) &&
Expand All @@ -1955,7 +1941,7 @@ namespace ts {
if (shouldAddFile) {
const importedFile = findSourceFile(resolution.resolvedFileName,
toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
/*isDefaultLib*/ false,
/*isDefaultLib*/ false, /*isReference*/ false,
file,
skipTrivia(file.text, file.imports[i].pos),
file.imports[i].end,
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,8 @@ namespace ts {
/* @internal */ commonJsModuleIndicator: Node;
// The number of times node_modules was searched to locate the package containing this file
/* @internal */ nodeModuleSearchDistance?: number;
// True if the file was a root file in a compilation or a /// reference targets
/* @internal */ wasReferenced?: boolean;

/* @internal */ identifiers: Map<string>;
/* @internal */ nodeCount: number;
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.