Merge pull request #4744 from Microsoft/Port-4738
Ports PR-4738 into release-1.6
This commit is contained in:
commit
fa7a59fdcf
|
@ -976,8 +976,8 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
let fileName = getResolvedModuleFileName(getSourceFile(location), moduleReferenceLiteral.text);
|
||||
let sourceFile = fileName && host.getSourceFile(fileName);
|
||||
let resolvedModule = getResolvedModule(getSourceFile(location), moduleReferenceLiteral.text);
|
||||
let sourceFile = resolvedModule && host.getSourceFile(resolvedModule.resolvedFileName);
|
||||
if (sourceFile) {
|
||||
if (sourceFile.symbol) {
|
||||
return sourceFile.symbol;
|
||||
|
|
|
@ -427,6 +427,8 @@ namespace ts {
|
|||
Cannot_emit_namespaced_JSX_elements_in_React: { code: 2650, category: DiagnosticCategory.Error, key: "Cannot emit namespaced JSX elements in React" },
|
||||
A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: { code: 2651, category: DiagnosticCategory.Error, key: "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums." },
|
||||
Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: { code: 2652, category: DiagnosticCategory.Error, key: "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead." },
|
||||
Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition: { code: 2654, category: DiagnosticCategory.Error, key: "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition." },
|
||||
Exported_external_package_typings_can_only_be_in_d_ts_files_Please_contact_the_package_author_to_update_the_package_definition: { code: 2655, category: DiagnosticCategory.Error, key: "Exported external package typings can only be in '.d.ts' files. Please contact the package author to update the package definition." },
|
||||
Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." },
|
||||
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." },
|
||||
|
|
|
@ -1697,6 +1697,14 @@
|
|||
"category": "Error",
|
||||
"code": 2652
|
||||
},
|
||||
"Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.": {
|
||||
"category": "Error",
|
||||
"code": 2654
|
||||
},
|
||||
"Exported external package typings can only be in '.d.ts' files. Please contact the package author to update the package definition.": {
|
||||
"category": "Error",
|
||||
"code": 2655
|
||||
},
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace ts {
|
|||
return normalizePath(referencedFileName);
|
||||
}
|
||||
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule {
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
let moduleResolution = compilerOptions.moduleResolution !== undefined
|
||||
? compilerOptions.moduleResolution
|
||||
: compilerOptions.module === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic;
|
||||
|
@ -47,7 +47,7 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModule {
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
let containingDirectory = getDirectoryPath(containingFile);
|
||||
|
||||
if (getRootLength(moduleName) !== 0 || nameStartsWithDotSlashOrDotDotSlash(moduleName)) {
|
||||
|
@ -56,11 +56,13 @@ namespace ts {
|
|||
let resolvedFileName = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ false, failedLookupLocations, host);
|
||||
|
||||
if (resolvedFileName) {
|
||||
return { resolvedFileName, failedLookupLocations };
|
||||
return { resolvedModule: { resolvedFileName }, failedLookupLocations };
|
||||
}
|
||||
|
||||
resolvedFileName = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ false, failedLookupLocations, host);
|
||||
return { resolvedFileName, failedLookupLocations };
|
||||
return resolvedFileName
|
||||
? { resolvedModule: { resolvedFileName }, failedLookupLocations }
|
||||
: { resolvedModule: undefined, failedLookupLocations };
|
||||
}
|
||||
else {
|
||||
return loadModuleFromNodeModules(moduleName, containingDirectory, host);
|
||||
|
@ -117,7 +119,7 @@ namespace ts {
|
|||
return loadNodeModuleFromFile(combinePaths(candidate, "index"), loadOnlyDts, failedLookupLocation, host);
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModule {
|
||||
function loadModuleFromNodeModules(moduleName: string, directory: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
let failedLookupLocations: string[] = [];
|
||||
directory = normalizeSlashes(directory);
|
||||
while (true) {
|
||||
|
@ -127,12 +129,12 @@ namespace ts {
|
|||
let candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
|
||||
let result = loadNodeModuleFromFile(candidate, /* loadOnlyDts */ true, failedLookupLocations, host);
|
||||
if (result) {
|
||||
return { resolvedFileName: result, failedLookupLocations };
|
||||
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
|
||||
}
|
||||
|
||||
result = loadNodeModuleFromDirectory(candidate, /* loadOnlyDts */ true, failedLookupLocations, host);
|
||||
if (result) {
|
||||
return { resolvedFileName: result, failedLookupLocations };
|
||||
return { resolvedModule: { resolvedFileName: result, isExternalLibraryImport: true }, failedLookupLocations };
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,47 +146,19 @@ namespace ts {
|
|||
directory = parentPath;
|
||||
}
|
||||
|
||||
return { resolvedFileName: undefined, failedLookupLocations };
|
||||
}
|
||||
|
||||
export function baseUrlModuleNameResolver(moduleName: string, containingFile: string, baseUrl: string, host: ModuleResolutionHost): ResolvedModule {
|
||||
Debug.assert(baseUrl !== undefined);
|
||||
|
||||
let normalizedModuleName = normalizeSlashes(moduleName);
|
||||
let basePart = useBaseUrl(moduleName) ? baseUrl : getDirectoryPath(containingFile);
|
||||
let candidate = normalizePath(combinePaths(basePart, moduleName));
|
||||
|
||||
let failedLookupLocations: string[] = [];
|
||||
|
||||
return forEach(supportedExtensions, ext => tryLoadFile(candidate + ext)) || { resolvedFileName: undefined, failedLookupLocations };
|
||||
|
||||
function tryLoadFile(location: string): ResolvedModule {
|
||||
if (host.fileExists(location)) {
|
||||
return { resolvedFileName: location, failedLookupLocations };
|
||||
}
|
||||
else {
|
||||
failedLookupLocations.push(location);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return { resolvedModule: undefined, failedLookupLocations };
|
||||
}
|
||||
|
||||
function nameStartsWithDotSlashOrDotDotSlash(name: string) {
|
||||
let i = name.lastIndexOf("./", 1);
|
||||
return i === 0 || (i === 1 && name.charCodeAt(0) === CharacterCodes.dot);
|
||||
}
|
||||
|
||||
function useBaseUrl(moduleName: string): boolean {
|
||||
// path is not rooted
|
||||
// module name does not start with './' or '../'
|
||||
return getRootLength(moduleName) === 0 && !nameStartsWithDotSlashOrDotDotSlash(moduleName);
|
||||
}
|
||||
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModule {
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
|
||||
// module names that contain '!' are used to reference resources and are not resolved to actual files on disk
|
||||
if (moduleName.indexOf('!') != -1) {
|
||||
return { resolvedFileName: undefined, failedLookupLocations: [] };
|
||||
return { resolvedModule: undefined, failedLookupLocations: [] };
|
||||
}
|
||||
|
||||
let searchPath = getDirectoryPath(containingFile);
|
||||
|
@ -222,7 +196,9 @@ namespace ts {
|
|||
searchPath = parentPath;
|
||||
}
|
||||
|
||||
return { resolvedFileName: referencedSourceFile, failedLookupLocations };
|
||||
return referencedSourceFile
|
||||
? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations }
|
||||
: { resolvedModule: undefined, failedLookupLocations };
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
@ -372,9 +348,9 @@ namespace ts {
|
|||
|
||||
host = host || createCompilerHost(options);
|
||||
|
||||
const resolveModuleNamesWorker =
|
||||
host.resolveModuleNames ||
|
||||
((moduleNames, containingFile) => map(moduleNames, moduleName => resolveModuleName(moduleName, containingFile, options, host).resolvedFileName));
|
||||
const resolveModuleNamesWorker = host.resolveModuleNames
|
||||
? ((moduleNames: string[], containingFile: string) => host.resolveModuleNames(moduleNames, containingFile))
|
||||
: ((moduleNames: string[], containingFile: string) => map(moduleNames, moduleName => resolveModuleName(moduleName, containingFile, options, host).resolvedModule));
|
||||
|
||||
let filesByName = createFileMap<SourceFile>(fileName => host.getCanonicalFileName(fileName));
|
||||
|
||||
|
@ -494,10 +470,17 @@ namespace ts {
|
|||
let resolutions = resolveModuleNamesWorker(moduleNames, newSourceFile.fileName);
|
||||
// ensure that module resolution results are still correct
|
||||
for (let i = 0; i < moduleNames.length; ++i) {
|
||||
let oldResolution = getResolvedModuleFileName(oldSourceFile, moduleNames[i]);
|
||||
if (oldResolution !== resolutions[i]) {
|
||||
let newResolution = resolutions[i];
|
||||
let oldResolution = getResolvedModule(oldSourceFile, moduleNames[i]);
|
||||
let resolutionChanged = oldResolution
|
||||
? !newResolution ||
|
||||
oldResolution.resolvedFileName !== newResolution.resolvedFileName ||
|
||||
!!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport
|
||||
: newResolution;
|
||||
|
||||
if (resolutionChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// pass the cache of module resolutions from the old source file
|
||||
|
@ -874,9 +857,23 @@ namespace ts {
|
|||
let resolutions = resolveModuleNamesWorker(moduleNames, file.fileName);
|
||||
for (let i = 0; i < file.imports.length; ++i) {
|
||||
let resolution = resolutions[i];
|
||||
setResolvedModuleName(file, moduleNames[i], resolution);
|
||||
setResolvedModule(file, moduleNames[i], resolution);
|
||||
if (resolution && !options.noResolve) {
|
||||
findModuleSourceFile(resolution, file.imports[i]);
|
||||
const importedFile = findModuleSourceFile(resolution.resolvedFileName, file.imports[i]);
|
||||
if (importedFile && resolution.isExternalLibraryImport) {
|
||||
if (!isExternalModule(importedFile)) {
|
||||
let start = getTokenPosOfNode(file.imports[i], file)
|
||||
fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.File_0_is_not_a_module, importedFile.fileName));
|
||||
}
|
||||
else if (!fileExtensionIs(importedFile.fileName, ".d.ts")) {
|
||||
let start = getTokenPosOfNode(file.imports[i], file)
|
||||
fileProcessingDiagnostics.add(createFileDiagnostic(file, start, file.imports[i].end - start, Diagnostics.Exported_external_package_typings_can_only_be_in_d_ts_files_Please_contact_the_package_author_to_update_the_package_definition));
|
||||
}
|
||||
else if (importedFile.referencedFiles.length) {
|
||||
let firstRef = importedFile.referencedFiles[0];
|
||||
fileProcessingDiagnostics.add(createFileDiagnostic(importedFile, firstRef.pos, firstRef.end - firstRef.pos, Diagnostics.Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1284,7 +1284,7 @@ namespace ts {
|
|||
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
|
||||
// It is used to resolve module names in the checker.
|
||||
// Content of this fiels should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
/* @internal */ resolvedModules: Map<string>;
|
||||
/* @internal */ resolvedModules: Map<ResolvedModule>;
|
||||
/* @internal */ imports: LiteralExpression[];
|
||||
}
|
||||
|
||||
|
@ -2283,11 +2283,20 @@ namespace ts {
|
|||
|
||||
export interface ResolvedModule {
|
||||
resolvedFileName: string;
|
||||
/*
|
||||
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be proper external module:
|
||||
* - be a .d.ts file
|
||||
* - use top level imports\exports
|
||||
* - don't use tripleslash references
|
||||
*/
|
||||
isExternalLibraryImport?: boolean;
|
||||
}
|
||||
|
||||
export interface ResolvedModuleWithFailedLookupLocations {
|
||||
resolvedModule: ResolvedModule;
|
||||
failedLookupLocations: string[];
|
||||
}
|
||||
|
||||
export type ModuleNameResolver = (moduleName: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => ResolvedModule;
|
||||
|
||||
export interface CompilerHost extends ModuleResolutionHost {
|
||||
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile;
|
||||
getCancellationToken?(): CancellationToken;
|
||||
|
@ -2305,7 +2314,7 @@ namespace ts {
|
|||
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
|
||||
* 'throw new Error("NotImplemented")'
|
||||
*/
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string): string[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
|
||||
}
|
||||
|
||||
export interface TextSpan {
|
||||
|
|
|
@ -99,20 +99,20 @@ namespace ts {
|
|||
return true;
|
||||
}
|
||||
|
||||
export function hasResolvedModuleName(sourceFile: SourceFile, moduleNameText: string): boolean {
|
||||
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
|
||||
return sourceFile.resolvedModules && hasProperty(sourceFile.resolvedModules, moduleNameText);
|
||||
}
|
||||
|
||||
export function getResolvedModuleFileName(sourceFile: SourceFile, moduleNameText: string): string {
|
||||
return hasResolvedModuleName(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
|
||||
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModule {
|
||||
return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
|
||||
}
|
||||
|
||||
export function setResolvedModuleName(sourceFile: SourceFile, moduleNameText: string, resolvedFileName: string): void {
|
||||
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModule): void {
|
||||
if (!sourceFile.resolvedModules) {
|
||||
sourceFile.resolvedModules = {};
|
||||
}
|
||||
|
||||
sourceFile.resolvedModules[moduleNameText] = resolvedFileName;
|
||||
sourceFile.resolvedModules[moduleNameText] = resolvedModule;
|
||||
}
|
||||
|
||||
// Returns true if this node contains a parse error anywhere underneath it.
|
||||
|
|
|
@ -225,8 +225,8 @@ module Harness.LanguageService {
|
|||
let imports: ts.Map<string> = {};
|
||||
for (let module of preprocessInfo.importedFiles) {
|
||||
let resolutionInfo = ts.resolveModuleName(module.fileName, fileName, compilerOptions, moduleResolutionHost);
|
||||
if (resolutionInfo.resolvedFileName) {
|
||||
imports[module.fileName] = resolutionInfo.resolvedFileName;
|
||||
if (resolutionInfo.resolvedModule) {
|
||||
imports[module.fileName] = resolutionInfo.resolvedModule.resolvedFileName;
|
||||
}
|
||||
}
|
||||
return JSON.stringify(imports);
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace ts.server {
|
|||
}
|
||||
}
|
||||
|
||||
interface TimestampedResolvedModule extends ResolvedModule {
|
||||
interface TimestampedResolvedModule extends ResolvedModuleWithFailedLookupLocations {
|
||||
lastCheckTime: number;
|
||||
}
|
||||
|
||||
|
@ -99,11 +99,11 @@ namespace ts.server {
|
|||
}
|
||||
}
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string): string[] {
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] {
|
||||
let currentResolutionsInFile = this.resolvedModuleNames.get(containingFile);
|
||||
|
||||
let newResolutions: Map<TimestampedResolvedModule> = {};
|
||||
let resolvedFileNames: string[] = [];
|
||||
let resolvedModules: ResolvedModule[] = [];
|
||||
|
||||
let compilerOptions = this.getCompilationSettings();
|
||||
|
||||
|
@ -119,25 +119,25 @@ namespace ts.server {
|
|||
else {
|
||||
resolution = <TimestampedResolvedModule>resolveModuleName(moduleName, containingFile, compilerOptions, this.moduleResolutionHost);
|
||||
resolution.lastCheckTime = Date.now();
|
||||
newResolutions[moduleName] = resolution;
|
||||
newResolutions[moduleName] = resolution;
|
||||
}
|
||||
}
|
||||
|
||||
ts.Debug.assert(resolution !== undefined);
|
||||
|
||||
resolvedFileNames.push(resolution.resolvedFileName);
|
||||
resolvedModules.push(resolution.resolvedModule);
|
||||
}
|
||||
|
||||
// replace old results with a new one
|
||||
this.resolvedModuleNames.set(containingFile, newResolutions);
|
||||
return resolvedFileNames;
|
||||
return resolvedModules;
|
||||
|
||||
function moduleResolutionIsValid(resolution: TimestampedResolvedModule): boolean {
|
||||
if (!resolution) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resolution.resolvedFileName) {
|
||||
if (resolution.resolvedModule) {
|
||||
// TODO: consider checking failedLookupLocations
|
||||
// TODO: use lastCheckTime to track expiration for module name resolution
|
||||
return true;
|
||||
|
|
|
@ -802,7 +802,7 @@ namespace ts {
|
|||
public languageVariant: LanguageVariant;
|
||||
public identifiers: Map<string>;
|
||||
public nameTable: Map<string>;
|
||||
public resolvedModules: Map<string>;
|
||||
public resolvedModules: Map<ResolvedModule>;
|
||||
public imports: LiteralExpression[];
|
||||
private namedDeclarations: Map<Declaration[]>;
|
||||
|
||||
|
@ -1022,7 +1022,7 @@ namespace ts {
|
|||
* if implementation is omitted then language service will use built-in module resolution logic and get answers to
|
||||
* host specific questions using 'getScriptSnapshot'.
|
||||
*/
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string): string[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[];
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -273,7 +273,7 @@ namespace ts {
|
|||
private loggingEnabled = false;
|
||||
private tracingEnabled = false;
|
||||
|
||||
public resolveModuleNames: (moduleName: string[], containingFile: string) => string[];
|
||||
public resolveModuleNames: (moduleName: string[], containingFile: string) => ResolvedModule[];
|
||||
|
||||
constructor(private shimHost: LanguageServiceShimHost) {
|
||||
// if shimHost is a COM object then property check will become method call with no arguments.
|
||||
|
@ -281,7 +281,10 @@ namespace ts {
|
|||
if ("getModuleResolutionsForFile" in this.shimHost) {
|
||||
this.resolveModuleNames = (moduleNames: string[], containingFile: string) => {
|
||||
let resolutionsInFile = <Map<string>>JSON.parse(this.shimHost.getModuleResolutionsForFile(containingFile));
|
||||
return map(moduleNames, name => lookUp(resolutionsInFile, name));
|
||||
return map(moduleNames, name => {
|
||||
const result = lookUp(resolutionsInFile, name);
|
||||
return result ? { resolvedFileName: result } : undefined;
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -942,7 +945,11 @@ namespace ts {
|
|||
public resolveModuleName(fileName: string, moduleName: string, compilerOptionsJson: string): string {
|
||||
return this.forwardJSONCall(`resolveModuleName('${fileName}')`, () => {
|
||||
let compilerOptions = <CompilerOptions>JSON.parse(compilerOptionsJson);
|
||||
return resolveModuleName(moduleName, normalizeSlashes(fileName), compilerOptions, this.host);
|
||||
const result = resolveModuleName(moduleName, normalizeSlashes(fileName), compilerOptions, this.host);
|
||||
return {
|
||||
resolvedFileName: result.resolvedModule ? result.resolvedModule.resolvedFileName: undefined,
|
||||
failedLookupLocations: result.failedLookupLocations
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
17
tests/baselines/reference/nodeResolution4.js
Normal file
17
tests/baselines/reference/nodeResolution4.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
//// [tests/cases/compiler/nodeResolution4.ts] ////
|
||||
|
||||
//// [ref.ts]
|
||||
|
||||
var x = 1;
|
||||
|
||||
//// [a.ts]
|
||||
/// <reference path="ref.ts"/>
|
||||
export var y;
|
||||
|
||||
//// [b.ts]
|
||||
import y = require("./a");
|
||||
|
||||
//// [ref.js]
|
||||
var x = 1;
|
||||
//// [a.js]
|
||||
//// [b.js]
|
14
tests/baselines/reference/nodeResolution4.symbols
Normal file
14
tests/baselines/reference/nodeResolution4.symbols
Normal file
|
@ -0,0 +1,14 @@
|
|||
=== tests/cases/compiler/b.ts ===
|
||||
import y = require("./a");
|
||||
>y : Symbol(y, Decl(b.ts, 0, 0))
|
||||
|
||||
=== tests/cases/compiler/ref.ts ===
|
||||
|
||||
var x = 1;
|
||||
>x : Symbol(x, Decl(ref.ts, 1, 3))
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
/// <reference path="ref.ts"/>
|
||||
export var y;
|
||||
>y : Symbol(y, Decl(a.ts, 1, 10))
|
||||
|
15
tests/baselines/reference/nodeResolution4.types
Normal file
15
tests/baselines/reference/nodeResolution4.types
Normal file
|
@ -0,0 +1,15 @@
|
|||
=== tests/cases/compiler/b.ts ===
|
||||
import y = require("./a");
|
||||
>y : typeof y
|
||||
|
||||
=== tests/cases/compiler/ref.ts ===
|
||||
|
||||
var x = 1;
|
||||
>x : number
|
||||
>1 : number
|
||||
|
||||
=== tests/cases/compiler/a.ts ===
|
||||
/// <reference path="ref.ts"/>
|
||||
export var y;
|
||||
>y : any
|
||||
|
14
tests/baselines/reference/nodeResolution5.errors.txt
Normal file
14
tests/baselines/reference/nodeResolution5.errors.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
tests/cases/compiler/b.ts(1,20): error TS2306: File 'tests/cases/compiler/node_modules/a.d.ts' is not a module.
|
||||
|
||||
|
||||
==== tests/cases/compiler/b.ts (1 errors) ====
|
||||
import y = require("a");
|
||||
~~~
|
||||
!!! error TS2306: File 'a.d.ts' is not a module.
|
||||
|
||||
==== tests/cases/compiler/node_modules/a.d.ts (0 errors) ====
|
||||
|
||||
declare module "a" {
|
||||
var x: number;
|
||||
}
|
||||
|
13
tests/baselines/reference/nodeResolution5.js
Normal file
13
tests/baselines/reference/nodeResolution5.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
//// [tests/cases/compiler/nodeResolution5.ts] ////
|
||||
|
||||
//// [a.d.ts]
|
||||
|
||||
declare module "a" {
|
||||
var x: number;
|
||||
}
|
||||
|
||||
//// [b.ts]
|
||||
import y = require("a");
|
||||
|
||||
|
||||
//// [b.js]
|
17
tests/baselines/reference/nodeResolution6.errors.txt
Normal file
17
tests/baselines/reference/nodeResolution6.errors.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
tests/cases/compiler/node_modules/a.d.ts(1,1): error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.
|
||||
|
||||
|
||||
==== tests/cases/compiler/b.ts (0 errors) ====
|
||||
import y = require("a");
|
||||
|
||||
==== tests/cases/compiler/node_modules/ref.ts (0 errors) ====
|
||||
|
||||
var x = 1;
|
||||
|
||||
==== tests/cases/compiler/node_modules/a.d.ts (1 errors) ====
|
||||
/// <reference path="ref.ts"/>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.
|
||||
export declare var y;
|
||||
|
||||
|
18
tests/baselines/reference/nodeResolution6.js
Normal file
18
tests/baselines/reference/nodeResolution6.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
//// [tests/cases/compiler/nodeResolution6.ts] ////
|
||||
|
||||
//// [ref.ts]
|
||||
|
||||
var x = 1;
|
||||
|
||||
//// [a.d.ts]
|
||||
/// <reference path="ref.ts"/>
|
||||
export declare var y;
|
||||
|
||||
|
||||
//// [b.ts]
|
||||
import y = require("a");
|
||||
|
||||
|
||||
//// [ref.js]
|
||||
var x = 1;
|
||||
//// [b.js]
|
14
tests/baselines/reference/nodeResolution7.errors.txt
Normal file
14
tests/baselines/reference/nodeResolution7.errors.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
tests/cases/compiler/b.ts(1,20): error TS2306: File 'tests/cases/compiler/node_modules/a/index.d.ts' is not a module.
|
||||
|
||||
|
||||
==== tests/cases/compiler/b.ts (1 errors) ====
|
||||
import y = require("a");
|
||||
~~~
|
||||
!!! error TS2306: File 'index.d.ts' is not a module.
|
||||
|
||||
==== tests/cases/compiler/node_modules/a/index.d.ts (0 errors) ====
|
||||
|
||||
declare module "a" {
|
||||
var x: number;
|
||||
}
|
||||
|
13
tests/baselines/reference/nodeResolution7.js
Normal file
13
tests/baselines/reference/nodeResolution7.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
//// [tests/cases/compiler/nodeResolution7.ts] ////
|
||||
|
||||
//// [index.d.ts]
|
||||
|
||||
declare module "a" {
|
||||
var x: number;
|
||||
}
|
||||
|
||||
//// [b.ts]
|
||||
import y = require("a");
|
||||
|
||||
|
||||
//// [b.js]
|
16
tests/baselines/reference/nodeResolution8.errors.txt
Normal file
16
tests/baselines/reference/nodeResolution8.errors.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
tests/cases/compiler/node_modules/a/index.d.ts(1,1): error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.
|
||||
|
||||
|
||||
==== tests/cases/compiler/b.ts (0 errors) ====
|
||||
import y = require("a");
|
||||
==== tests/cases/compiler/node_modules/a/ref.ts (0 errors) ====
|
||||
|
||||
var x = 1;
|
||||
|
||||
==== tests/cases/compiler/node_modules/a/index.d.ts (1 errors) ====
|
||||
/// <reference path="ref.ts"/>
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2654: Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.
|
||||
export declare var y;
|
||||
|
||||
|
17
tests/baselines/reference/nodeResolution8.js
Normal file
17
tests/baselines/reference/nodeResolution8.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
//// [tests/cases/compiler/nodeResolution8.ts] ////
|
||||
|
||||
//// [ref.ts]
|
||||
|
||||
var x = 1;
|
||||
|
||||
//// [index.d.ts]
|
||||
/// <reference path="ref.ts"/>
|
||||
export declare var y;
|
||||
|
||||
|
||||
//// [b.ts]
|
||||
import y = require("a");
|
||||
|
||||
//// [ref.js]
|
||||
var x = 1;
|
||||
//// [b.js]
|
12
tests/cases/compiler/nodeResolution4.ts
Normal file
12
tests/cases/compiler/nodeResolution4.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// @module: commonjs
|
||||
// @moduleResolution: node
|
||||
|
||||
// @filename: ref.ts
|
||||
var x = 1;
|
||||
|
||||
// @filename: a.ts
|
||||
/// <reference path="ref.ts"/>
|
||||
export var y;
|
||||
|
||||
// @filename: b.ts
|
||||
import y = require("./a");
|
10
tests/cases/compiler/nodeResolution5.ts
Normal file
10
tests/cases/compiler/nodeResolution5.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @module: commonjs
|
||||
// @moduleResolution: node
|
||||
|
||||
// @filename: node_modules/a.d.ts
|
||||
declare module "a" {
|
||||
var x: number;
|
||||
}
|
||||
|
||||
// @filename: b.ts
|
||||
import y = require("a");
|
13
tests/cases/compiler/nodeResolution6.ts
Normal file
13
tests/cases/compiler/nodeResolution6.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// @module: commonjs
|
||||
// @moduleResolution: node
|
||||
|
||||
// @filename: node_modules/ref.ts
|
||||
var x = 1;
|
||||
|
||||
// @filename: node_modules/a.d.ts
|
||||
/// <reference path="ref.ts"/>
|
||||
export declare var y;
|
||||
|
||||
|
||||
// @filename: b.ts
|
||||
import y = require("a");
|
10
tests/cases/compiler/nodeResolution7.ts
Normal file
10
tests/cases/compiler/nodeResolution7.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @module: commonjs
|
||||
// @moduleResolution: node
|
||||
|
||||
// @filename: node_modules/a/index.d.ts
|
||||
declare module "a" {
|
||||
var x: number;
|
||||
}
|
||||
|
||||
// @filename: b.ts
|
||||
import y = require("a");
|
13
tests/cases/compiler/nodeResolution8.ts
Normal file
13
tests/cases/compiler/nodeResolution8.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// @module: commonjs
|
||||
// @moduleResolution: node
|
||||
|
||||
// @filename: node_modules/a/ref.ts
|
||||
var x = 1;
|
||||
|
||||
// @filename: node_modules/a/index.d.ts
|
||||
/// <reference path="ref.ts"/>
|
||||
export declare var y;
|
||||
|
||||
|
||||
// @filename: b.ts
|
||||
import y = require("a");
|
|
@ -40,8 +40,9 @@ module ts {
|
|||
let containingFile = { name: containingFileName }
|
||||
let moduleFile = { name: moduleFileNameNoExt + ext }
|
||||
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedFileName, moduleFile.name);
|
||||
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
|
||||
let failedLookupLocations: string[] = [];
|
||||
let dir = getDirectoryPath(containingFileName);
|
||||
for (let e of supportedExtensions) {
|
||||
|
@ -78,7 +79,8 @@ module ts {
|
|||
let packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
|
||||
let moduleFile = { name: moduleFileName };
|
||||
let resolution = nodeModuleNameResolver(moduleName, containingFile.name, createModuleResolutionHost(containingFile, packageJson, moduleFile));
|
||||
assert.equal(resolution.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
// expect three failed lookup location - attempt to load module as file with all supported extensions
|
||||
assert.equal(resolution.failedLookupLocations.length, 3);
|
||||
}
|
||||
|
@ -95,7 +97,8 @@ module ts {
|
|||
let packageJson = {name: "/a/b/foo/package.json", content: JSON.stringify({main: "/c/d"})};
|
||||
let indexFile = { name: "/a/b/foo/index.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("./foo", containingFile.name, createModuleResolutionHost(containingFile, packageJson, indexFile));
|
||||
assert.equal(resolution.resolvedFileName, indexFile.name);
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/b/foo.ts",
|
||||
"/a/b/foo.tsx",
|
||||
|
@ -111,7 +114,7 @@ module ts {
|
|||
let containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
let moduleFile = { name: "/a/b/node_modules/foo.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedFileName, undefined);
|
||||
assert.equal(resolution.resolvedModule, undefined);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/b/c/d/node_modules/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
|
@ -135,14 +138,16 @@ module ts {
|
|||
let containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
let moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
});
|
||||
|
||||
it("load module as directory", () => {
|
||||
let containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
|
||||
let moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
|
||||
let resolution = nodeModuleNameResolver("foo", containingFile.name, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
|
@ -158,64 +163,4 @@ module ts {
|
|||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("BaseUrl mode", () => {
|
||||
|
||||
it ("load module as relative url", () => {
|
||||
function test(containingFileName: string, moduleFileName: string, moduleName: string): void {
|
||||
let containingFile = {name: containingFileName };
|
||||
let moduleFile = { name: moduleFileName };
|
||||
let resolution = baseUrlModuleNameResolver(moduleName, containingFile.name, "<some-value>", createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedFileName, moduleFile.name);
|
||||
let expectedFailedLookupLocations: string[] = [];
|
||||
|
||||
let moduleNameHasExt = forEach(supportedExtensions, e => fileExtensionIs(moduleName, e));
|
||||
if (!moduleNameHasExt) {
|
||||
let dir = getDirectoryPath(containingFileName);
|
||||
|
||||
// add candidates with extensions that precede extension of the actual module name file in the list of supportd extensions
|
||||
for (let ext of supportedExtensions) {
|
||||
|
||||
let hasExtension = ext !== ".ts"
|
||||
? fileExtensionIs(moduleFileName, ext)
|
||||
: fileExtensionIs(moduleFileName, ".ts") && !fileExtensionIs(moduleFileName, ".d.ts");
|
||||
|
||||
if (hasExtension) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
expectedFailedLookupLocations.push(normalizePath(combinePaths(dir, moduleName + ext)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert.deepEqual(resolution.failedLookupLocations, expectedFailedLookupLocations)
|
||||
}
|
||||
|
||||
test("/a/b/c/d.ts", "/foo.ts", "/foo");
|
||||
test("/a/b/c/d.ts", "/foo.d.ts", "/foo");
|
||||
test("/a/b/c/d.ts", "/foo.tsx", "/foo");
|
||||
|
||||
test("/a/b/c/d.ts", "/a/b/c/foo.ts", "./foo");
|
||||
test("/a/b/c/d.ts", "/a/b/c/foo.d.ts", "./foo");
|
||||
test("/a/b/c/d.ts", "/a/b/c/foo.tsx", "./foo");
|
||||
|
||||
test("/a/b/c/d.ts", "/a/b/foo.ts", "../foo");
|
||||
test("/a/b/c/d.ts", "/a/b/foo.d.ts", "../foo");
|
||||
test("/a/b/c/d.ts", "/a/b/foo.tsx", "../foo");
|
||||
});
|
||||
|
||||
it ("load module using base url", () => {
|
||||
function test(containingFileName: string, moduleFileName: string, moduleName: string, baseUrl: string): void {
|
||||
let containingFile = { name: containingFileName };
|
||||
let moduleFile = { name: moduleFileName };
|
||||
let resolution = baseUrlModuleNameResolver(moduleName, containingFileName, baseUrl, createModuleResolutionHost(containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedFileName, moduleFile.name);
|
||||
}
|
||||
|
||||
test("/a/base/c/d.ts", "/a/base/c/d/e.ts", "c/d/e", "/a/base");
|
||||
test("/a/base/c/d.ts", "/a/base/c/d/e.d.ts", "c/d/e", "/a/base");
|
||||
test("/a/base/c/d.ts", "/a/base/c/d/e.tsx", "c/d/e", "/a/base");
|
||||
});
|
||||
});
|
||||
}
|
|
@ -160,7 +160,7 @@ module ts {
|
|||
return size;
|
||||
}
|
||||
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map<string>): void {
|
||||
function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map<ResolvedModule>): void {
|
||||
let file = program.getSourceFile(fileName);
|
||||
assert.isTrue(file !== undefined, `cannot find file ${fileName}`);
|
||||
if (expectedContent === undefined) {
|
||||
|
@ -175,7 +175,16 @@ module ts {
|
|||
for (let id in expectedContent) {
|
||||
if (hasProperty(expectedContent, id)) {
|
||||
assert.isTrue(hasProperty(file.resolvedModules, id), `expected ${id} to be found in resolved modules`);
|
||||
assert.isTrue(expectedContent[id] === file.resolvedModules[id], `expected '${expectedContent[id]}' to be equal to '${file.resolvedModules[id]}'`);
|
||||
if (expectedContent[id]) {
|
||||
const expected = expectedContent[id];
|
||||
const actual = file.resolvedModules[id];
|
||||
assert.isTrue(actual !== undefined);
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'shouldBeProperExternalModule': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
|
||||
}
|
||||
else {
|
||||
assert.isTrue(file.resolvedModules[id] === undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +246,7 @@ module ts {
|
|||
var options: CompilerOptions = { target };
|
||||
|
||||
var program_1 = newProgram(files, ["a.ts"], options);
|
||||
checkResolvedModulesCache(program_1, "a.ts", { "b": "b.ts" });
|
||||
checkResolvedModulesCache(program_1, "a.ts", { "b": { resolvedFileName: "b.ts" } });
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
|
||||
var program_2 = updateProgram(program_1, ["a.ts"], options, files => {
|
||||
|
@ -246,7 +255,7 @@ module ts {
|
|||
assert.isTrue(program_1.structureIsReused);
|
||||
|
||||
// content of resolution cache should not change
|
||||
checkResolvedModulesCache(program_1, "a.ts", { "b": "b.ts" });
|
||||
checkResolvedModulesCache(program_1, "a.ts", { "b": { resolvedFileName: "b.ts" } });
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
|
||||
// imports has changed - program is not reused
|
||||
|
@ -263,7 +272,7 @@ module ts {
|
|||
files[0].text = files[0].text.updateImportsAndExports(newImports);
|
||||
});
|
||||
assert.isTrue(!program_3.structureIsReused);
|
||||
checkResolvedModulesCache(program_4, "a.ts", { "b": "b.ts", "c": undefined });
|
||||
checkResolvedModulesCache(program_4, "a.ts", { "b": { resolvedFileName: "b.ts" }, "c": undefined });
|
||||
});
|
||||
})
|
||||
}
|
Loading…
Reference in a new issue