diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 59482af12e14e..bd9373e2d3f3f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -317,9 +317,32 @@ namespace ts { } }, { - name: "traceModuleResolution", + name: "typesSearchPaths", + type: "list", + isTSConfigOnly: true, + element: { + name: "typesSearchPaths", + type: "string", + isFilePath: true + } + }, + { + name: "typesRoot", + type: "string" + }, + { + name: "types", + type: "list", + element: { + name: "types", + type: "string" + }, + description: Diagnostics.Type_declaration_files_to_be_included_in_compilation + }, + { + name: "traceResolution", type: "boolean", - description: Diagnostics.Enable_tracing_of_the_module_resolution_process + description: Diagnostics.Enable_tracing_of_the_name_resolution_process }, { name: "allowJs", @@ -641,6 +664,7 @@ namespace ts { const compilerOptions: CompilerOptions = convertCompilerOptionsFromJsonWorker(json["compilerOptions"], basePath, errors, configFileName); const options = extend(existingOptions, compilerOptions); const typingOptions: TypingOptions = convertTypingOptionsFromJsonWorker(json["typingOptions"], basePath, errors, configFileName); + options.configFilePath = configFileName; const fileNames = getFileNames(errors); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 505442eb99384..793118d008b8d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1903,10 +1903,10 @@ "category": "Error", "code": 2684 }, - "The 'this' types of each signature are incompatible.": { - "category": "Error", - "code": 2685 - }, + "The 'this' types of each signature are incompatible.": { + "category": "Error", + "code": 2685 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", "code": 4000 @@ -2187,6 +2187,11 @@ "category": "Error", "code": 4082 }, + "Conflicting library definitions for '{0}' found at '{1}' and '{2}'. Copy the correct file to the 'typings' folder to resolve this conflict.": { + "category": "Message", + "code": 4090 + }, + "The current host does not support the '{0}' option.": { "category": "Error", "code": 5001 @@ -2540,7 +2545,7 @@ "category": "Message", "code": 6084 }, - "Enable tracing of the module resolution process.": { + "Enable tracing of the name resolution process.": { "category": "Message", "code": 6085 }, @@ -2588,7 +2593,7 @@ "category": "Message", "code": 6096 }, - "File '{0}' exist - use it as a module resolution result.": { + "File '{0}' exist - use it as a name resolution result.": { "category": "Message", "code": 6097 }, @@ -2600,11 +2605,11 @@ "category": "Message", "code": 6099 }, - "'package.json' does not have 'typings' field.": { + "'package.json' does not have 'types' field.": { "category": "Message", "code": 6100 }, - "'package.json' has 'typings' field '{0}' that references '{1}'.": { + "'package.json' has '{0}' field '{1}' that references '{2}'.": { "category": "Message", "code": 6101 }, @@ -2620,7 +2625,7 @@ "category": "Message", "code": 6104 }, - "Expected type of 'typings' field in 'package.json' to be 'string', got '{0}'.": { + "Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'.": { "category": "Message", "code": 6105 }, @@ -2662,8 +2667,60 @@ }, "Raise error on 'this' expressions with an implied 'any' type.": { "category": "Message", - "code": 6115 - }, + "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 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5119358d8d049..38a341eaa5af7 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5509,6 +5509,7 @@ namespace ts { function processReferenceComments(sourceFile: SourceFile): void { const triviaScanner = createScanner(sourceFile.languageVersion, /*skipTrivia*/false, LanguageVariant.Standard, sourceText); const referencedFiles: FileReference[] = []; + const typeReferenceDirectives: FileReference[] = []; const amdDependencies: { path: string; name: string }[] = []; let amdModuleName: string; @@ -5535,7 +5536,12 @@ namespace ts { sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; const diagnosticMessage = referencePathMatchResult.diagnosticMessage; if (fileReference) { - referencedFiles.push(fileReference); + if (referencePathMatchResult.isTypeReferenceDirective) { + typeReferenceDirectives.push(fileReference); + } + else { + referencedFiles.push(fileReference); + } } if (diagnosticMessage) { parseDiagnostics.push(createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); @@ -5567,6 +5573,7 @@ namespace ts { } sourceFile.referencedFiles = referencedFiles; + sourceFile.typeReferenceDirectives = typeReferenceDirectives; sourceFile.amdDependencies = amdDependencies; sourceFile.moduleName = amdModuleName; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 0c4d6bc8ffbbb..58ae0e3faf963 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -12,6 +12,12 @@ namespace ts { const emptyArray: any[] = []; + const defaultLibrarySearchPaths = [ + "types/", + "node_modules/", + "node_modules/@types/", + ]; + export const version = "1.9.0"; export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean): string { @@ -35,13 +41,58 @@ namespace ts { return normalizePath(referencedFileName); } + /* @internal */ + export function computeCommonSourceDirectoryOfFilenames(fileNames: string[], currentDirectory: string, getCanonicalFileName: (fileName: string) => string): string { + let commonPathComponents: string[]; + const failed = forEach(fileNames, sourceFile => { + // Each file contributes into common source file path + const sourcePathComponents = getNormalizedPathComponents(sourceFile, currentDirectory); + sourcePathComponents.pop(); // The base file name is not part of the common directory path + + if (!commonPathComponents) { + // first file + commonPathComponents = sourcePathComponents; + return; + } + + for (let i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); i < n; i++) { + if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) { + if (i === 0) { + // Failed to find any common path component + return true; + } + + // New common path found that is 0 -> i-1 + commonPathComponents.length = i; + break; + } + } + + // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents + if (sourcePathComponents.length < commonPathComponents.length) { + commonPathComponents.length = sourcePathComponents.length; + } + }); + + // A common path can not be found when paths span multiple drives on windows, for example + if (failed) { + return ""; + } + + if (!commonPathComponents) { // Can happen when all input files are .d.ts files + return currentDirectory; + } + + return getNormalizedPathFromPathComponents(commonPathComponents); + } + function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void; function trace(host: ModuleResolutionHost, message: DiagnosticMessage): void { host.trace(formatMessage.apply(undefined, arguments)); } function isTraceEnabled(compilerOptions: CompilerOptions, host: ModuleResolutionHost): boolean { - return compilerOptions.traceModuleResolution && host.trace !== undefined; + return compilerOptions.traceResolution && host.trace !== undefined; } function hasZeroOrOneAsteriskCharacter(str: string): boolean { @@ -82,6 +133,160 @@ namespace ts { skipTsx: boolean; } + function tryReadTypesSection(packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string { + let jsonContent: { typings?: string, types?: string }; + try { + const jsonText = state.host.readFile(packageJsonPath); + jsonContent = jsonText ? <{ typings?: string, types?: string }>JSON.parse(jsonText) : {}; + } + catch (e) { + // gracefully handle if readFile fails or returns not JSON + jsonContent = {}; + } + + let typesFile: string; + let fieldName: string; + // first try to read content of 'typings' section (backward compatibility) + if (jsonContent.typings) { + if (typeof jsonContent.typings === "string") { + fieldName = "typings"; + typesFile = jsonContent.typings; + } + else { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, "typings", typeof jsonContent.typings); + } + } + } + // then read 'types' + if (!typesFile && jsonContent.types) { + if (typeof jsonContent.types === "string") { + fieldName = "types"; + typesFile = jsonContent.types; + } + else { + if (state.traceEnabled) { + trace(state.host, Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, "types", typeof jsonContent.types); + } + } + } + if (typesFile) { + const typesFilePath = normalizePath(combinePaths(baseDirectory, typesFile)); + if (state.traceEnabled) { + trace(state.host, Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, typesFile, typesFilePath); + } + return typesFilePath; + } + return undefined; + } + + const typeReferenceExtensions = [".d.ts"]; + + /** + * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown. + * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups + * is assumed to be the same as root directory of the project. + */ + export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations { + const traceEnabled = isTraceEnabled(options, host); + const moduleResolutionState: ModuleResolutionState = { + compilerOptions: options, + host: host, + skipTsx: true, + traceEnabled + }; + + // use typesRoot and fallback to directory that contains tsconfig if typesRoot is not set + const rootDir = options.typesRoot || (options.configFilePath ? getDirectoryPath(options.configFilePath) : undefined); + + if (traceEnabled) { + if (containingFile === undefined) { + if (rootDir === undefined) { + trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName); + } + else { + trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, rootDir); + } + } + else { + if (rootDir === undefined) { + trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile); + } + else { + trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, rootDir); + } + } + } + + const failedLookupLocations: string[] = []; + + // Check primary library paths + if (rootDir !== undefined) { + const effectivePrimarySearchPaths = options.typesSearchPaths || defaultLibrarySearchPaths; + for (const searchPath of effectivePrimarySearchPaths) { + const primaryPath = combinePaths(rootDir, searchPath); + if (traceEnabled) { + trace(host, Diagnostics.Resolving_with_primary_search_path_0, primaryPath); + } + const candidate = combinePaths(primaryPath, typeReferenceDirectiveName); + const candidateDirectory = getDirectoryPath(candidate); + const resolvedFile = loadNodeModuleFromDirectory(typeReferenceExtensions, candidate, failedLookupLocations, + !directoryProbablyExists(candidateDirectory, host), moduleResolutionState); + + if (resolvedFile) { + if (traceEnabled) { + trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, true); + } + return { + resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolvedFile }, + failedLookupLocations + }; + } + } + } + else { + if (traceEnabled) { + trace(host, Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths); + } + } + + let resolvedFile: string; + let initialLocationForSecondaryLookup: string; + if (containingFile) { + initialLocationForSecondaryLookup = getDirectoryPath(containingFile); + } + else { + initialLocationForSecondaryLookup = rootDir; + } + + if (initialLocationForSecondaryLookup !== undefined) { + // check secondary locations + if (traceEnabled) { + trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup); + } + resolvedFile = loadModuleFromNodeModules(typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState); + if (traceEnabled) { + if (resolvedFile) { + trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, false); + } + else { + trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); + } + } + } + else { + if (traceEnabled) { + trace(host, Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder); + } + } + return { + resolvedTypeReferenceDirective: resolvedFile + ? { primary: false, resolvedFileName: resolvedFile } + : undefined, + failedLookupLocations + }; + } + export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); if (traceEnabled) { @@ -361,7 +566,7 @@ namespace ts { const traceEnabled = isTraceEnabled(compilerOptions, host); const failedLookupLocations: string[] = []; - const state = {compilerOptions, host, traceEnabled, skipTsx: false}; + const state = { compilerOptions, host, traceEnabled, skipTsx: false }; let resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, supportedExtensions, state); @@ -397,7 +602,7 @@ namespace ts { } /* @internal */ - export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean } ): boolean { + export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean { // if host does not support 'directoryExists' assume that directory will exist return !host.directoryExists || host.directoryExists(directoryName); } @@ -407,6 +612,13 @@ namespace ts { * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. */ function loadModuleFromFile(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string { + if (!onlyRecordFailures) { + // check if containig folder exists - if it doesn't then just record failures for all supported extensions without disk probing + const directory = getDirectoryPath(candidate); + if (directory) { + onlyRecordFailures = !directoryProbablyExists(directory, state.host); + } + } return forEach(extensions, tryLoad); function tryLoad(ext: string): string { @@ -416,7 +628,7 @@ namespace ts { const fileName = fileExtensionIs(candidate, ext) ? candidate : candidate + ext; if (!onlyRecordFailures && state.host.fileExists(fileName)) { if (state.traceEnabled) { - trace(state.host, Diagnostics.File_0_exist_use_it_as_a_module_resolution_result, fileName); + trace(state.host, Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } return fileName; } @@ -437,36 +649,16 @@ namespace ts { if (state.traceEnabled) { trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath); } - - let jsonContent: { typings?: string }; - - try { - const jsonText = state.host.readFile(packageJsonPath); - jsonContent = jsonText ? <{ typings?: string }>JSON.parse(jsonText) : { typings: 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, extensions, 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_typings_field); + trace(state.host, Diagnostics.package_json_does_not_have_types_field); } } } @@ -481,20 +673,31 @@ namespace ts { return loadModuleFromFile(combinePaths(candidate, "index"), extensions, failedLookupLocation, !directoryExists, state); } + function loadModuleFromNodeModulesFolder(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string { + 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); + if (result) { + return result; + } + result = loadNodeModuleFromDirectory(supportedTypeScriptExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); + if (result) { + return result; + } + } + function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string { directory = normalizeSlashes(directory); 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)); - // Load only typescript files irrespective of allowJs option if loading from node modules - let result = loadModuleFromFile(candidate, supportedTypeScriptExtensions, failedLookupLocations, !nodeModulesFolderExists, state); - if (result) { - return result; - } - result = loadNodeModuleFromDirectory(supportedTypeScriptExtensions, 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; } @@ -544,7 +747,7 @@ namespace ts { return referencedSourceFile - ? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations } + ? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations } : { resolvedModule: undefined, failedLookupLocations }; } @@ -689,9 +892,9 @@ namespace ts { export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] { let diagnostics = program.getOptionsDiagnostics(cancellationToken).concat( - program.getSyntacticDiagnostics(sourceFile, cancellationToken), - program.getGlobalDiagnostics(cancellationToken), - program.getSemanticDiagnostics(sourceFile, cancellationToken)); + program.getSyntacticDiagnostics(sourceFile, cancellationToken), + program.getGlobalDiagnostics(cancellationToken), + program.getSemanticDiagnostics(sourceFile, cancellationToken)); if (program.getCompilerOptions().declaration) { diagnostics = diagnostics.concat(program.getDeclarationDiagnostics(sourceFile, cancellationToken)); @@ -726,68 +929,80 @@ namespace ts { } } + function loadWithLocalCache(names: string[], containingFile: string, loader: (name: string, containingFile: string) => T): T[] { + if (names.length === 0) { + return []; + } + const resolutions: T[] = []; + const cache: Map = {}; + for (const name of names) { + let result: T; + if (hasProperty(cache, name)) { + result = cache[name]; + } + else { + result = loader(name, containingFile); + cache[name] = result; + } + resolutions.push(result); + } + return resolutions; + } + export function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program { let program: Program; let files: SourceFile[] = []; - let fileProcessingDiagnostics = createDiagnosticCollection(); - const programDiagnostics = createDiagnosticCollection(); - let commonSourceDirectory: string; let diagnosticsProducingTypeChecker: TypeChecker; let noDiagnosticsTypeChecker: TypeChecker; let classifiableNames: Map; + let resolvedTypeReferenceDirectives: Map = {}; + let fileProcessingDiagnostics = createDiagnosticCollection(); let skipDefaultLib = options.noLib; + const programDiagnostics = createDiagnosticCollection(); + const currentDirectory = host.getCurrentDirectory(); const supportedExtensions = getSupportedExtensions(options); const start = new Date().getTime(); host = host || createCompilerHost(options); + // Map storing if there is emit blocking diagnostics for given input const hasEmitBlockingDiagnostics = createFileMap(getCanonicalFileName); - const currentDirectory = host.getCurrentDirectory(); - const resolveModuleNamesWorker = host.resolveModuleNames - ? ((moduleNames: string[], containingFile: string) => host.resolveModuleNames(moduleNames, containingFile)) - : ((moduleNames: string[], containingFile: string) => { - const resolvedModuleNames: ResolvedModule[] = []; - // resolveModuleName does not store any results between calls. - // lookup is a local cache to avoid resolving the same module name several times - const lookup: Map = {}; - for (const moduleName of moduleNames) { - let resolvedName: ResolvedModule; - if (hasProperty(lookup, moduleName)) { - resolvedName = lookup[moduleName]; - } - else { - resolvedName = resolveModuleName(moduleName, containingFile, options, host).resolvedModule; - lookup[moduleName] = resolvedName; - } - resolvedModuleNames.push(resolvedName); - } - return resolvedModuleNames; - }); + let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModule[]; + if (host.resolveModuleNames) { + resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile); + } + else { + const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host).resolvedModule; + resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache(moduleNames, containingFile, loader); + } + + let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string) => ResolvedTypeReferenceDirective[]; + if (host.resolveTypeReferenceDirectives) { + resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile); + } + else { + const loader = (typesRef: string, containingFile: string) => resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; + resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache(typeReferenceDirectiveNames, containingFile, loader); + } const filesByName = createFileMap(); // stores 'filename -> file association' ignoring case // used to track cases when two file names differ only in casing const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createFileMap(fileName => fileName.toLowerCase()) : undefined; - if (oldProgram) { - // check properties that can affect structure of the program or module resolution strategy - // if any of these properties has changed - structure cannot be reused - const oldOptions = oldProgram.getCompilerOptions(); - if ((oldOptions.module !== options.module) || - (oldOptions.noResolve !== options.noResolve) || - (oldOptions.target !== options.target) || - (oldOptions.noLib !== options.noLib) || - (oldOptions.jsx !== options.jsx) || - (oldOptions.allowJs !== options.allowJs)) { - oldProgram = undefined; + if (!tryReuseStructureFromOldProgram()) { + // load type declarations specified via 'types' argument + if (options.types && options.types.length) { + const resolutions = resolveTypeReferenceDirectiveNamesWorker(options.types, /*containingFile*/ undefined); + for (let i = 0; i < options.types.length; i++) { + processTypeReferenceDirective(options.types[i], resolutions[i]); + } } - } - if (!tryReuseStructureFromOldProgram()) { forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false)); // Do not process the default library if: // - The '--noLib' flag is used. @@ -831,7 +1046,8 @@ namespace ts { getIdentifierCount: () => getDiagnosticsProducingTypeChecker().getIdentifierCount(), getSymbolCount: () => getDiagnosticsProducingTypeChecker().getSymbolCount(), getTypeCount: () => getDiagnosticsProducingTypeChecker().getTypeCount(), - getFileProcessingDiagnostics: () => fileProcessingDiagnostics + getFileProcessingDiagnostics: () => fileProcessingDiagnostics, + resolvedTypeReferenceDirectives }; verifyCompilerOptions(); @@ -878,6 +1094,21 @@ namespace ts { return false; } + // check properties that can affect structure of the program or module resolution strategy + // if any of these properties has changed - structure cannot be reused + const oldOptions = oldProgram.getCompilerOptions(); + if ((oldOptions.module !== options.module) || + (oldOptions.noResolve !== options.noResolve) || + (oldOptions.target !== options.target) || + (oldOptions.noLib !== options.noLib) || + (oldOptions.jsx !== options.jsx) || + (oldOptions.allowJs !== options.allowJs) || + (oldOptions.rootDir !== options.rootDir) || + (oldOptions.typesSearchPaths !== options.typesSearchPaths) || + (oldOptions.configFilePath !== options.configFilePath)) { + return false; + } + Debug.assert(!oldProgram.structureIsReused); // there is an old program, check if we can reuse its structure @@ -886,6 +1117,10 @@ namespace ts { return false; } + if (!arrayIsEqualTo(options.types, oldOptions.types)) { + return false; + } + // check if program source files has changed in the way that can affect structure of the program const newSourceFiles: SourceFile[] = []; const filePaths: Path[] = []; @@ -924,26 +1159,33 @@ namespace ts { return false; } + if (!arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) { + // 'types' references has changed + return false; + } + + const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory); if (resolveModuleNamesWorker) { const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral); - const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory)); + const resolutions = resolveModuleNamesWorker(moduleNames, newSourceFilePath); // ensure that module resolution results are still correct - for (let i = 0; i < moduleNames.length; i++) { - const newResolution = resolutions[i]; - const oldResolution = getResolvedModule(oldSourceFile, moduleNames[i]); - const resolutionChanged = oldResolution - ? !newResolution || - oldResolution.resolvedFileName !== newResolution.resolvedFileName || - !!oldResolution.isExternalLibraryImport !== !!newResolution.isExternalLibraryImport - : newResolution; - - if (resolutionChanged) { - return false; - } + const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo); + if (resolutionsChanged) { + return false; } } - // pass the cache of module resolutions from the old source file + if (resolveTypeReferenceDirectiveNamesWorker) { + const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, x => x.fileName); + const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath); + // ensure that types resolutions are still correct + const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo); + if (resolutionsChanged) { + return false; + } + } + // pass the cache of module/types resolutions from the old source file newSourceFile.resolvedModules = oldSourceFile.resolvedModules; + newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames; modifiedSourceFiles.push(newSourceFile); } else { @@ -966,6 +1208,7 @@ namespace ts { for (const modifiedFile of modifiedSourceFiles) { fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile); } + resolvedTypeReferenceDirectives = oldProgram.resolvedTypeReferenceDirectives; oldProgram.structureIsReused = true; return true; @@ -1058,9 +1301,9 @@ namespace ts { } function getDiagnosticsHelper( - sourceFile: SourceFile, - getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[], - cancellationToken: CancellationToken): Diagnostic[] { + sourceFile: SourceFile, + getDiagnostics: (sourceFile: SourceFile, cancellationToken: CancellationToken) => Diagnostic[], + cancellationToken: CancellationToken): Diagnostic[] { if (sourceFile) { return getDiagnostics(sourceFile, cancellationToken); } @@ -1534,7 +1777,8 @@ namespace ts { const basePath = getDirectoryPath(fileName); if (!options.noResolve) { - processReferencedFiles(file, basePath, /*isDefaultLib*/ isDefaultLib); + processReferencedFiles(file, basePath, isDefaultLib); + processTypeReferenceDirectives(file); } // always process imported modules to record module name resolutions @@ -1558,6 +1802,73 @@ namespace ts { }); } + function processTypeReferenceDirectives(file: SourceFile) { + const typeDirectives = map(file.typeReferenceDirectives, l => l.fileName); + const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName); + + for (let i = 0; i < typeDirectives.length; i++) { + const ref = file.typeReferenceDirectives[i]; + const resolvedTypeReferenceDirective = resolutions[i]; + // store resolved type directive on the file + setResolvedTypeReferenceDirective(file, ref.fileName, resolvedTypeReferenceDirective); + processTypeReferenceDirective(ref.fileName, resolvedTypeReferenceDirective, file, ref.pos, ref.end); + } + } + + function processTypeReferenceDirective(typeReferenceDirective: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective, + refFile?: SourceFile, refPos?: number, refEnd?: number): void { + + // If we already found this library as a primary reference - nothing to do + const previousResolution = resolvedTypeReferenceDirectives[typeReferenceDirective]; + if (previousResolution && previousResolution.primary) { + return; + } + let saveResolution = true; + if (resolvedTypeReferenceDirective) { + if (resolvedTypeReferenceDirective.primary) { + // resolved from the primary path + processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd); + } + else { + // If we already resolved to this file, it must have been a secondary reference. Check file contents + // for sameness and possibly issue an error + if (previousResolution) { + const otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName); + if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) { + fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, + Diagnostics.Conflicting_library_definitions_for_0_found_at_1_and_2_Copy_the_correct_file_to_the_typings_folder_to_resolve_this_conflict, + typeReferenceDirective, + resolvedTypeReferenceDirective.resolvedFileName, + previousResolution.resolvedFileName + )); + } + // don't overwrite previous resolution result + saveResolution = false; + } + else { + // First resolution of this library + processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd); + } + } + } + else { + fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, Diagnostics.Cannot_find_name_0, typeReferenceDirective)); + } + + if (saveResolution) { + resolvedTypeReferenceDirectives[typeReferenceDirective] = resolvedTypeReferenceDirective; + } + } + + function createDiagnostic(refFile: SourceFile, refPos: number, refEnd: number, message: DiagnosticMessage, ...args: any[]): Diagnostic { + if (refFile === undefined || refPos === undefined || refEnd === undefined) { + return createCompilerDiagnostic(message, ...args); + } + else { + return createFileDiagnostic(refFile, refPos, refEnd - refPos, message, ...args); + } + } + function getCanonicalFileName(fileName: string): string { return host.getCanonicalFileName(fileName); } @@ -1605,51 +1916,13 @@ namespace ts { } function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string { - let commonPathComponents: string[]; - const failed = forEach(files, sourceFile => { - // Each file contributes into common source file path - if (isDeclarationFile(sourceFile)) { - return; + const fileNames: string[] = []; + for (const file of sourceFiles) { + if (!file.isDeclarationFile) { + fileNames.push(file.fileName); } - - const sourcePathComponents = getNormalizedPathComponents(sourceFile.fileName, currentDirectory); - sourcePathComponents.pop(); // The base file name is not part of the common directory path - - if (!commonPathComponents) { - // first file - commonPathComponents = sourcePathComponents; - return; - } - - for (let i = 0, n = Math.min(commonPathComponents.length, sourcePathComponents.length); i < n; i++) { - if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) { - if (i === 0) { - // Failed to find any common path component - return true; - } - - // New common path found that is 0 -> i-1 - commonPathComponents.length = i; - break; - } - } - - // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents - if (sourcePathComponents.length < commonPathComponents.length) { - commonPathComponents.length = sourcePathComponents.length; - } - }); - - // A common path can not be found when paths span multiple drives on windows, for example - if (failed) { - return ""; } - - if (!commonPathComponents) { // Can happen when all input files are .d.ts files - return currentDirectory; - } - - return getNormalizedPathFromPathComponents(commonPathComponents); + return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName); } function checkSourceFilesBelongToPath(sourceFiles: SourceFile[], rootDirectory: string): boolean { @@ -1797,7 +2070,7 @@ namespace ts { // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure if (options.outDir && dir === "" && forEach(files, file => getRootLength(file.fileName) > 1)) { - programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files)); + programDiagnostics.add(createCompilerDiagnostic(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files)); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 4968766c2d021..75255ff2f6d2d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1537,6 +1537,7 @@ namespace ts { amdDependencies: AmdDependency[]; moduleName: string; referencedFiles: FileReference[]; + typeReferenceDirectives: FileReference[]; languageVariant: LanguageVariant; isDeclarationFile: boolean; @@ -1584,6 +1585,7 @@ namespace ts { // It is used to resolve module names in the checker. // Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead /* @internal */ resolvedModules: Map; + /* @internal */ resolvedTypeReferenceDirectiveNames: Map; /* @internal */ imports: LiteralExpression[]; /* @internal */ moduleAugmentations: LiteralExpression[]; } @@ -1660,6 +1662,7 @@ namespace ts { /* @internal */ getTypeCount(): number; /* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection; + /* @internal */ resolvedTypeReferenceDirectives: Map; // For testing purposes only. /* @internal */ structureIsReused?: boolean; } @@ -2418,6 +2421,7 @@ namespace ts { jsx?: JsxEmit; reactNamespace?: string; listFiles?: boolean; + typesSearchPaths?: string[]; locale?: string; mapRoot?: string; module?: ModuleKind; @@ -2457,7 +2461,7 @@ namespace ts { baseUrl?: string; paths?: PathSubstitutions; rootDirs?: RootPaths; - traceModuleResolution?: boolean; + traceResolution?: boolean; allowSyntheticDefaultImports?: boolean; allowJs?: boolean; noImplicitUseStrict?: boolean; @@ -2471,8 +2475,15 @@ namespace ts { // Do not perform validation of output file name in transpile scenarios /* @internal */ suppressOutputPathCheck?: boolean; - list?: string[]; + /* @internal */ + // When options come from a config file, its path is recorded here + configFilePath?: string; + /* @internal */ + // Path used to used to compute primary search locations + typesRoot?: string; + types?: string[]; + list?: string[]; [option: string]: CompilerOptionsValue; } @@ -2753,6 +2764,18 @@ namespace ts { failedLookupLocations: string[]; } + export interface ResolvedTypeReferenceDirective { + // True if the type declaration file was found in a primary lookup location + primary: boolean; + // The location of the .d.ts file we located, or undefined if resolution failed + resolvedFileName?: string; + } + + export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations { + resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective; + failedLookupLocations: string[]; + } + export interface CompilerHost extends ModuleResolutionHost { getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile; getCancellationToken?(): CancellationToken; @@ -2772,6 +2795,10 @@ namespace ts { * 'throw new Error("NotImplemented")' */ resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[]; + /** + * This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files + */ + resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; } export interface TextSpan { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 780a6d615efd6..660f12b99e089 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6,6 +6,7 @@ namespace ts { fileReference?: FileReference; diagnosticMessage?: DiagnosticMessage; isNoDefaultLib?: boolean; + isTypeReferenceDirective?: boolean; } export interface SynthesizedNode extends Node { @@ -118,6 +119,43 @@ namespace ts { sourceFile.resolvedModules[moduleNameText] = resolvedModule; } + export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective): void { + if (!sourceFile.resolvedTypeReferenceDirectiveNames) { + sourceFile.resolvedTypeReferenceDirectiveNames = {}; + } + + sourceFile.resolvedTypeReferenceDirectiveNames[typeReferenceDirectiveName] = resolvedTypeReferenceDirective; + } + + /* @internal */ + export function moduleResolutionIsEqualTo(oldResolution: ResolvedModule, newResolution: ResolvedModule): boolean { + return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport; + } + + /* @internal */ + export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirective, newResolution: ResolvedTypeReferenceDirective): boolean { + return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; + } + + /* @internal */ + export function hasChangesInResolutions(names: string[], newResolutions: T[], oldResolutions: Map, comparer: (oldResolution: T, newResolution: T) => boolean): boolean { + if (names.length !== newResolutions.length) { + return false; + } + for (let i = 0; i < names.length; i++) { + const newResolution = newResolutions[i]; + const oldResolution = oldResolutions && hasProperty(oldResolutions, names[i]) ? oldResolutions[names[i]] : undefined; + const changed = + oldResolution + ? !newResolution || !comparer(oldResolution, newResolution) + : newResolution; + if (changed) { + return true; + } + } + return false; + } + // Returns true if this node contains a parse error anywhere underneath it. export function containsParseError(node: Node): boolean { aggregateChildData(node); @@ -541,6 +579,7 @@ namespace ts { } export let fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; + export let fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; export let fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; export function isTypeNode(node: Node): boolean { @@ -1591,25 +1630,26 @@ namespace ts { }; } else { - const matchResult = fullTripleSlashReferencePathRegEx.exec(comment); - if (matchResult) { + const refMatchResult = fullTripleSlashReferencePathRegEx.exec(comment); + const refLibResult = !refMatchResult && fullTripleSlashReferenceTypeReferenceDirectiveRegEx.exec(comment); + if (refMatchResult || refLibResult) { const start = commentRange.pos; const end = commentRange.end; return { fileReference: { pos: start, end: end, - fileName: matchResult[3] + fileName: (refMatchResult || refLibResult)[3] }, - isNoDefaultLib: false - }; - } - else { - return { - diagnosticMessage: Diagnostics.Invalid_reference_directive_syntax, - isNoDefaultLib: false + isNoDefaultLib: false, + isTypeReferenceDirective: !!refLibResult }; } + + return { + diagnosticMessage: Diagnostics.Invalid_reference_directive_syntax, + isNoDefaultLib: false + }; } } diff --git a/src/harness/compilerRunner.ts b/src/harness/compilerRunner.ts index 3362cb1d375be..ea0877c42b204 100644 --- a/src/harness/compilerRunner.ts +++ b/src/harness/compilerRunner.ts @@ -102,6 +102,10 @@ class CompilerBaselineRunner extends RunnerBase { }); } + if (tsConfigOptions && tsConfigOptions.configFilePath !== undefined) { + tsConfigOptions.configFilePath = ts.combinePaths(rootDir, tsConfigOptions.configFilePath); + } + const output = Harness.Compiler.compileFiles( toBeCompiled, otherFiles, harnessSettings, /*options*/ tsConfigOptions, /*currentDirectory*/ undefined); @@ -140,7 +144,7 @@ class CompilerBaselineRunner extends RunnerBase { }); it (`Correct module resolution tracing for ${fileName}`, () => { - if (options.traceModuleResolution) { + if (options.traceResolution) { Harness.Baseline.runBaseline("Correct sourcemap content for " + fileName, justName.replace(/\.tsx?$/, ".trace.json"), () => { return JSON.stringify(result.traceResults || [], undefined, 4); }); diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 44057cad3276d..f7039fb1fe929 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -222,7 +222,7 @@ namespace FourSlash { function tryAdd(path: string) { const inputFile = inputFiles[path]; if (inputFile && !Harness.isDefaultLibraryFile(path)) { - languageServiceAdapterHost.addScript(path, inputFile); + languageServiceAdapterHost.addScript(path, inputFile, /*isRootFile*/ true); return true; } } @@ -247,6 +247,10 @@ namespace FourSlash { // Create a new Services Adapter this.cancellationToken = new TestCancellationToken(); const compilationOptions = convertGlobalOptionsToCompilerOptions(this.testData.globalOptions); + if (compilationOptions.typesRoot) { + compilationOptions.typesRoot = ts.getNormalizedAbsolutePath(compilationOptions.typesRoot, this.basePath); + } + const languageServiceAdapter = this.getLanguageServiceAdapter(testType, this.cancellationToken, compilationOptions); this.languageServiceAdapterHost = languageServiceAdapter.getHost(); this.languageService = languageServiceAdapter.getLanguageService(); @@ -268,7 +272,7 @@ namespace FourSlash { if (startResolveFileRef) { // Add the entry-point file itself into the languageServiceShimHost - this.languageServiceAdapterHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content); + this.languageServiceAdapterHost.addScript(startResolveFileRef.fileName, startResolveFileRef.content, /*isRootFile*/ true); const resolvedResult = languageServiceAdapter.getPreProcessedFileInfo(startResolveFileRef.fileName, startResolveFileRef.content); const referencedFiles: ts.FileReference[] = resolvedResult.referencedFiles; @@ -292,18 +296,18 @@ namespace FourSlash { // Check if no-default-lib flag is false and if so add default library if (!resolvedResult.isLibFile) { this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName, - Harness.Compiler.getDefaultLibrarySourceFile().text); + Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false); } } else { // resolveReference file-option is not specified then do not resolve any files and include all inputFiles ts.forEachKey(this.inputFiles, fileName => { if (!Harness.isDefaultLibraryFile(fileName)) { - this.languageServiceAdapterHost.addScript(fileName, this.inputFiles[fileName]); + this.languageServiceAdapterHost.addScript(fileName, this.inputFiles[fileName], /*isRootFile*/ true); } }); this.languageServiceAdapterHost.addScript(Harness.Compiler.defaultLibFileName, - Harness.Compiler.getDefaultLibrarySourceFile().text); + Harness.Compiler.getDefaultLibrarySourceFile().text, /*isRootFile*/ false); } this.formatCodeOptions = { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d519156641329..7c6ff20302ade 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -65,6 +65,11 @@ namespace Utils { return Buffer ? (new Buffer(s)).toString("utf8") : s; } + export function byteLength(s: string, encoding?: string): number { + // stub implementation if Buffer is not available (in-browser case) + return Buffer ? Buffer.byteLength(s, encoding) : s.length; + } + export function evalFile(fileContents: string, fileName: string, nodeContext?: any) { const environment = getExecutionEnvironment(); switch (environment) { @@ -835,7 +840,7 @@ namespace Harness { export let fourslashSourceFile: ts.SourceFile; export function getCanonicalFileName(fileName: string): string { - return Harness.IO.useCaseSensitiveFileNames() ? fileName : fileName.toLowerCase(); + return fileName; } export function createCompilerHost( @@ -883,6 +888,7 @@ namespace Harness { newLineKind === ts.NewLineKind.LineFeed ? lineFeed : Harness.IO.newLine(); + return { getCurrentDirectory: () => currentDirectory, getSourceFile, @@ -891,8 +897,12 @@ namespace Harness { getCanonicalFileName, useCaseSensitiveFileNames: () => useCaseSensitiveFileNames, getNewLine: () => newLine, - fileExists: fileName => getSourceFile(fileName, ts.ScriptTarget.ES5) !== undefined, - readFile: (fileName: string): string => { return Harness.IO.readFile(fileName); } + fileExists: fileName => { + return fileMap.contains(ts.toPath(fileName, currentDirectory, getCanonicalFileName)); + }, + readFile: (fileName: string): string => { + return fileMap.get(ts.toPath(fileName, currentDirectory, getCanonicalFileName)).getText(); + } }; } @@ -1033,7 +1043,7 @@ namespace Harness { options.newLine); let traceResults: string[]; - if (options.traceModuleResolution) { + if (options.traceResolution) { traceResults = []; compilerHost.trace = text => traceResults.push(text); } @@ -1479,6 +1489,7 @@ namespace Harness { baseDir = ts.getNormalizedAbsolutePath(baseDir, rootDir); } tsConfig = ts.parseJsonConfigFileContent(configJson.config, parseConfigHost, baseDir); + tsConfig.options.configFilePath = data.name; // delete entry from the list testUnitData.splice(i, 1); diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 12bb6a470e4f7..b27d746390b9b 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -9,7 +9,7 @@ namespace Harness.LanguageService { public editRanges: { length: number; textChangeRange: ts.TextChangeRange; }[] = []; private lineMap: number[] = undefined; - constructor(public fileName: string, public content: string) { + constructor(public fileName: string, public content: string, public isRootFile: boolean) { this.setContent(content); } @@ -135,7 +135,13 @@ namespace Harness.LanguageService { public getFilenames(): string[] { const fileNames: string[] = []; - ts.forEachKey(this.fileNameToScript, (fileName) => { fileNames.push(fileName); }); + ts.forEachValue(this.fileNameToScript, (scriptInfo) => { + if (scriptInfo.isRootFile) { + // only include root files here + // usually it means that we won't include lib.d.ts in the list of root files so it won't mess the computation of compilation root dir. + fileNames.push(scriptInfo.fileName); + } + }); return fileNames; } @@ -143,8 +149,8 @@ namespace Harness.LanguageService { return ts.lookUp(this.fileNameToScript, fileName); } - public addScript(fileName: string, content: string): void { - this.fileNameToScript[fileName] = new ScriptInfo(fileName, content); + public addScript(fileName: string, content: string, isRootFile: boolean): void { + this.fileNameToScript[fileName] = new ScriptInfo(fileName, content, isRootFile); } public editScript(fileName: string, start: number, end: number, newText: string) { @@ -177,7 +183,7 @@ namespace Harness.LanguageService { getCompilationSettings() { return this.settings; } getCancellationToken() { return this.cancellationToken; } getCurrentDirectory(): string { return ""; } - getDefaultLibFileName(): string { return ""; } + getDefaultLibFileName(): string { return Harness.Compiler.defaultLibFileName; } getScriptFileNames(): string[] { return this.getFilenames(); } getScriptSnapshot(fileName: string): ts.IScriptSnapshot { const script = this.getScriptInfo(fileName); @@ -210,6 +216,7 @@ namespace Harness.LanguageService { private nativeHost: NativeLanguageServiceHost; public getModuleResolutionsForFile: (fileName: string) => string; + public getTypeReferenceDirectiveResolutionsForFile: (fileName: string) => string; constructor(preprocessToResolve: boolean, cancellationToken?: ts.HostCancellationToken, options?: ts.CompilerOptions) { super(cancellationToken, options); @@ -236,12 +243,25 @@ namespace Harness.LanguageService { } return JSON.stringify(imports); }; + this.getTypeReferenceDirectiveResolutionsForFile = (fileName) => { + const scriptInfo = this.getScriptInfo(fileName); + const preprocessInfo = ts.preProcessFile(scriptInfo.content, /*readImportFiles*/ false); + const resolutions: ts.Map = {}; + const settings = this.nativeHost.getCompilationSettings(); + for (const typeReferenceDirective of preprocessInfo.typeReferenceDirectives) { + const resolutionInfo = ts.resolveTypeReferenceDirective(typeReferenceDirective.fileName, fileName, settings, moduleResolutionHost); + if (resolutionInfo.resolvedTypeReferenceDirective.resolvedFileName) { + resolutions[typeReferenceDirective.fileName] = resolutionInfo.resolvedTypeReferenceDirective; + } + } + return JSON.stringify(resolutions); + }; } } getFilenames(): string[] { return this.nativeHost.getFilenames(); } getScriptInfo(fileName: string): ScriptInfo { return this.nativeHost.getScriptInfo(fileName); } - addScript(fileName: string, content: string): void { this.nativeHost.addScript(fileName, content); } + addScript(fileName: string, content: string, isRootFile: boolean): void { this.nativeHost.addScript(fileName, content, isRootFile); } editScript(fileName: string, start: number, end: number, newText: string): void { this.nativeHost.editScript(fileName, start, end, newText); } positionToLineAndCharacter(fileName: string, position: number): ts.LineAndCharacter { return this.nativeHost.positionToLineAndCharacter(fileName, position); } @@ -442,6 +462,7 @@ namespace Harness.LanguageService { getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { let shimResult: { referencedFiles: ts.IFileReference[]; + typeReferenceDirectives: ts.IFileReference[]; importedFiles: ts.IFileReference[]; isLibFile: boolean; }; @@ -453,7 +474,8 @@ namespace Harness.LanguageService { referencedFiles: [], importedFiles: [], ambientExternalModules: [], - isLibFile: shimResult.isLibFile + isLibFile: shimResult.isLibFile, + typeReferenceDirectives: [] }; ts.forEach(shimResult.referencedFiles, refFile => { @@ -472,6 +494,13 @@ namespace Harness.LanguageService { }); }); + ts.forEach(shimResult.typeReferenceDirectives, typeRefDirective => { + convertResult.importedFiles.push({ + fileName: typeRefDirective.path, + pos: typeRefDirective.position, + end: typeRefDirective.position + typeRefDirective.length + }); + }); return convertResult; } } diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 4b9f17798c8e6..4c054664a1838 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -81,8 +81,14 @@ namespace ts.server { } } - interface TimestampedResolvedModule extends ResolvedModuleWithFailedLookupLocations { - lastCheckTime: number; + interface Timestamped { + lastCheckTime?: number; + } + + interface TimestampedResolvedModule extends ResolvedModuleWithFailedLookupLocations, Timestamped { + } + + interface TimestampedResolvedTypeReferenceDirective extends ResolvedTypeReferenceDirectiveWithFailedLookupLocations, Timestamped { } export class LSHost implements ts.LanguageServiceHost { @@ -90,13 +96,16 @@ namespace ts.server { compilationSettings: ts.CompilerOptions; filenameToScript: ts.FileMap; roots: ScriptInfo[] = []; + private resolvedModuleNames: ts.FileMap>; + private resolvedTypeReferenceDirectives: ts.FileMap>; private moduleResolutionHost: ts.ModuleResolutionHost; private getCanonicalFileName: (fileName: string) => string; constructor(public host: ServerHost, public project: Project) { this.getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames); this.resolvedModuleNames = createFileMap>(); + this.resolvedTypeReferenceDirectives = createFileMap>(); this.filenameToScript = createFileMap(); this.moduleResolutionHost = { fileExists: fileName => this.fileExists(fileName), @@ -105,46 +114,51 @@ namespace ts.server { }; } - resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] { - const path = toPath(containingFile, this.host.getCurrentDirectory(), this.getCanonicalFileName); - const currentResolutionsInFile = this.resolvedModuleNames.get(path); + private resolveNamesWithLocalCache( + names: string[], + containingFile: string, + cache: ts.FileMap>, + loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => T, + getResult: (s: T) => R): R[] { - const newResolutions: Map = {}; - const resolvedModules: ResolvedModule[] = []; + const path = toPath(containingFile, this.host.getCurrentDirectory(), this.getCanonicalFileName); + const currentResolutionsInFile = cache.get(path); + const newResolutions: Map = {}; + const resolvedModules: R[] = []; const compilerOptions = this.getCompilationSettings(); - for (const moduleName of moduleNames) { + for (const name of names) { // check if this is a duplicate entry in the list - let resolution = lookUp(newResolutions, moduleName); + let resolution = lookUp(newResolutions, name); if (!resolution) { - const existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, moduleName); + const existingResolution = currentResolutionsInFile && ts.lookUp(currentResolutionsInFile, name); if (moduleResolutionIsValid(existingResolution)) { - // ok, it is safe to use existing module resolution results + // ok, it is safe to use existing name resolution results resolution = existingResolution; } else { - resolution = resolveModuleName(moduleName, containingFile, compilerOptions, this.moduleResolutionHost); + resolution = loader(name, containingFile, compilerOptions, this.moduleResolutionHost); resolution.lastCheckTime = Date.now(); - newResolutions[moduleName] = resolution; + newResolutions[name] = resolution; } } ts.Debug.assert(resolution !== undefined); - resolvedModules.push(resolution.resolvedModule); + resolvedModules.push(getResult(resolution)); } // replace old results with a new one - this.resolvedModuleNames.set(path, newResolutions); + cache.set(path, newResolutions); return resolvedModules; - function moduleResolutionIsValid(resolution: TimestampedResolvedModule): boolean { + function moduleResolutionIsValid(resolution: T): boolean { if (!resolution) { return false; } - if (resolution.resolvedModule) { + if (getResult(resolution)) { // TODO: consider checking failedLookupLocations // TODO: use lastCheckTime to track expiration for module name resolution return true; @@ -156,6 +170,14 @@ namespace ts.server { } } + resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] { + return this.resolveNamesWithLocalCache(typeDirectiveNames, containingFile, this.resolvedTypeReferenceDirectives, resolveTypeReferenceDirective, m => m.resolvedTypeReferenceDirective); + } + + resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] { + return this.resolveNamesWithLocalCache(moduleNames, containingFile, this.resolvedModuleNames, resolveModuleName, m => m.resolvedModule); + } + getDefaultLibFileName() { const nodeModuleBinDir = ts.getDirectoryPath(ts.normalizePath(this.host.getExecutingFilePath())); return ts.combinePaths(nodeModuleBinDir, ts.getDefaultLibFileName(this.compilationSettings)); @@ -172,6 +194,7 @@ namespace ts.server { this.compilationSettings = opt; // conservatively assume that changing compiler options might affect module resolution strategy this.resolvedModuleNames.clear(); + this.resolvedTypeReferenceDirectives.clear(); } lineAffectsRefs(filename: string, line: number) { @@ -212,6 +235,7 @@ namespace ts.server { if (!info.isOpen) { this.filenameToScript.remove(info.path); this.resolvedModuleNames.remove(info.path); + this.resolvedTypeReferenceDirectives.remove(info.path); } } @@ -239,6 +263,7 @@ namespace ts.server { this.filenameToScript.remove(info.path); this.roots = copyListRemovingItem(info, this.roots); this.resolvedModuleNames.remove(info.path); + this.resolvedTypeReferenceDirectives.remove(info.path); } } diff --git a/src/services/services.ts b/src/services/services.ts index 3aa07fe4e410a..37339037c75c5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -125,6 +125,7 @@ namespace ts { } export interface PreProcessedFileInfo { referencedFiles: FileReference[]; + typeReferenceDirectives: FileReference[]; importedFiles: FileReference[]; ambientExternalModules: string[]; isLibFile: boolean; @@ -793,6 +794,7 @@ namespace ts { public amdDependencies: { name: string; path: string }[]; public moduleName: string; public referencedFiles: FileReference[]; + public typeReferenceDirectives: FileReference[]; public syntacticDiagnostics: Diagnostic[]; public referenceDiagnostics: Diagnostic[]; @@ -814,6 +816,7 @@ namespace ts { public identifiers: Map; public nameTable: Map; public resolvedModules: Map; + public resolvedTypeReferenceDirectiveNames: Map; public imports: LiteralExpression[]; public moduleAugmentations: LiteralExpression[]; private namedDeclarations: Map; @@ -1040,6 +1043,7 @@ namespace ts { * host specific questions using 'getScriptSnapshot'. */ resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[]; + resolveTypeReferenceDirectives?(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[]; directoryExists?(directoryName: string): boolean; } @@ -2147,6 +2151,7 @@ namespace ts { export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo { const referencedFiles: FileReference[] = []; + const typeReferenceDirectives: FileReference[] = []; const importedFiles: FileReference[] = []; let ambientExternalModules: { ref: FileReference, depth: number }[]; let isNoDefaultLib = false; @@ -2175,7 +2180,11 @@ namespace ts { isNoDefaultLib = referencePathMatchResult.isNoDefaultLib; const fileReference = referencePathMatchResult.fileReference; if (fileReference) { - referencedFiles.push(fileReference); + const collection = referencePathMatchResult.isTypeReferenceDirective + ? typeReferenceDirectives + : referencedFiles; + + collection.push(fileReference); } } }); @@ -2476,7 +2485,7 @@ namespace ts { importedFiles.push(decl.ref); } } - return { referencedFiles, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: undefined }; + return { referencedFiles, typeReferenceDirectives, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: undefined }; } else { // for global scripts ambient modules still can have augmentations - look for ambient modules with depth > 0 @@ -2494,7 +2503,7 @@ namespace ts { } } } - return { referencedFiles, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientModuleNames }; + return { referencedFiles, typeReferenceDirectives, importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientModuleNames }; } } @@ -2831,7 +2840,7 @@ namespace ts { getCurrentDirectory: () => currentDirectory, fileExists: (fileName): boolean => { // stub missing host functionality - Debug.assert(!host.resolveModuleNames); + Debug.assert(!host.resolveModuleNames || !host.resolveTypeReferenceDirectives); return hostCache.getOrCreateEntry(fileName) !== undefined; }, readFile: (fileName): string => { @@ -2840,7 +2849,7 @@ namespace ts { return entry && entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); }, directoryExists: directoryName => { - Debug.assert(!host.resolveModuleNames); + Debug.assert(!host.resolveModuleNames || !host.resolveTypeReferenceDirectives); return directoryProbablyExists(directoryName, host); } }; @@ -2851,6 +2860,11 @@ namespace ts { if (host.resolveModuleNames) { compilerHost.resolveModuleNames = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile); } + if (host.resolveTypeReferenceDirectives) { + compilerHost.resolveTypeReferenceDirectives = (typeReferenceDirectiveNames, containingFile) => { + return host.resolveTypeReferenceDirectives(typeReferenceDirectiveNames, containingFile); + }; + } const newProgram = createProgram(hostCache.getRootFileNames(), newSettings, compilerHost, program); @@ -4683,6 +4697,26 @@ namespace ts { } } + function findReferenceInPosition(refs: FileReference[], pos: number): FileReference { + for (const ref of refs) { + if (ref.pos <= pos && pos < ref.end) { + return ref; + } + } + return undefined; + } + + function getDefinitionInfoForFileReference(name: string, targetFileName: string): DefinitionInfo { + return { + fileName: targetFileName, + textSpan: createTextSpanFromBounds(0, 0), + kind: ScriptElementKind.scriptElement, + name: name, + containerName: undefined, + containerKind: undefined + }; + } + /// Goto definition function getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[] { synchronizeHostData(); @@ -4702,18 +4736,20 @@ namespace ts { } /// Triple slash reference comments - const comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); + const comment = findReferenceInPosition(sourceFile.referencedFiles, position); if (comment) { const referenceFile = tryResolveScriptReference(program, sourceFile, comment); if (referenceFile) { - return [{ - fileName: referenceFile.fileName, - textSpan: createTextSpanFromBounds(0, 0), - kind: ScriptElementKind.scriptElement, - name: comment.fileName, - containerName: undefined, - containerKind: undefined - }]; + return [getDefinitionInfoForFileReference(comment.fileName, referenceFile.fileName)]; + } + return undefined; + } + // Type reference directives + const typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); + if (typeReferenceDirective) { + const referenceFile = lookUp(program.resolvedTypeReferenceDirectives, typeReferenceDirective.fileName); + if (referenceFile && referenceFile.resolvedFileName) { + return [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)]; } return undefined; } diff --git a/src/services/shims.ts b/src/services/shims.ts index ecfcd6f84dab4..9155c057ef2f2 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -67,6 +67,7 @@ namespace ts { useCaseSensitiveFileNames?(): boolean; getModuleResolutionsForFile?(fileName: string): string; + getTypeReferenceDirectiveResolutionsForFile?(fileName: string): string; directoryExists(directoryName: string): boolean; } @@ -281,6 +282,7 @@ namespace ts { private tracingEnabled = false; public resolveModuleNames: (moduleName: string[], containingFile: string) => ResolvedModule[]; + public resolveTypeReferenceDirectives: (typeDirectiveNames: string[], containingFile: string) => ResolvedTypeReferenceDirective[]; public directoryExists: (directoryName: string) => boolean; constructor(private shimHost: LanguageServiceShimHost) { @@ -298,6 +300,12 @@ namespace ts { if ("directoryExists" in this.shimHost) { this.directoryExists = directoryName => this.shimHost.directoryExists(directoryName); } + if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) { + this.resolveTypeReferenceDirectives = (typeDirectiveNames: string[], containingFile: string) => { + const typeDirectivesForFile = >JSON.parse(this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile)); + return map(typeDirectiveNames, name => lookUp(typeDirectivesForFile, name)); + }; + } } public log(s: string): void { @@ -919,36 +927,47 @@ namespace ts { }); } + public resolveTypeReferenceDirective(fileName: string, typeReferenceDirective: string, compilerOptionsJson: string): string { + return this.forwardJSONCall(`resolveTypeReferenceDirective(${fileName})`, () => { + const compilerOptions = JSON.parse(compilerOptionsJson); + const result = resolveTypeReferenceDirective(typeReferenceDirective, normalizeSlashes(fileName), compilerOptions, this.host); + return { + resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined, + primary: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.primary : true, + failedLookupLocations: result.failedLookupLocations + }; + }); + } + public getPreProcessedFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string { return this.forwardJSONCall( "getPreProcessedFileInfo('" + fileName + "')", () => { // for now treat files as JavaScript const result = preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true); - const convertResult = { - referencedFiles: [], - importedFiles: [], + return { + referencedFiles: this.convertFileReferences(result.referencedFiles), + importedFiles: this.convertFileReferences(result.importedFiles), ambientExternalModules: result.ambientExternalModules, - isLibFile: result.isLibFile + isLibFile: result.isLibFile, + typeReferenceDirectives: this.convertFileReferences(result.typeReferenceDirectives) }; + }); + } - forEach(result.referencedFiles, refFile => { - convertResult.referencedFiles.push({ - path: normalizePath(refFile.fileName), - position: refFile.pos, - length: refFile.end - refFile.pos - }); - }); - - forEach(result.importedFiles, importedFile => { - convertResult.importedFiles.push({ - path: normalizeSlashes(importedFile.fileName), - position: importedFile.pos, - length: importedFile.end - importedFile.pos - }); - }); - return convertResult; + private convertFileReferences(refs: FileReference[]): IFileReference[] { + if (!refs) { + return undefined; + } + const result: IFileReference[] = []; + for (const ref of refs) { + result.push({ + path: normalizeSlashes(ref.fileName), + position: ref.pos, + length: ref.end - ref.pos }); + } + return result; } public getTSConfigFileInfo(fileName: string, sourceTextSnapshot: IScriptSnapshot): string { diff --git a/tests/baselines/reference/library-reference-1.js b/tests/baselines/reference/library-reference-1.js new file mode 100644 index 0000000000000..e709db72deabf --- /dev/null +++ b/tests/baselines/reference/library-reference-1.js @@ -0,0 +1,17 @@ +//// [tests/cases/conformance/references/library-reference-1.ts] //// + +//// [index.d.ts] + +// We can find typings in the ./types folder + +declare var $: { foo(): void }; + + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-1.symbols b/tests/baselines/reference/library-reference-1.symbols new file mode 100644 index 0000000000000..0e848c626c541 --- /dev/null +++ b/tests/baselines/reference/library-reference-1.symbols @@ -0,0 +1,16 @@ +=== /consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(index.d.ts, 3, 16)) +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + +=== /types/jquery/index.d.ts === + +// We can find typings in the ./types folder + +declare var $: { foo(): void }; +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + + diff --git a/tests/baselines/reference/library-reference-1.trace.json b/tests/baselines/reference/library-reference-1.trace.json new file mode 100644 index 0000000000000..1b8c237dff15a --- /dev/null +++ b/tests/baselines/reference/library-reference-1.trace.json @@ -0,0 +1,7 @@ +[ + "======== Resolving type reference directive 'jquery', containing file '/consumer.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "File '/types/jquery/package.json' does not exist.", + "File '/types/jquery/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/types/jquery/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-1.types b/tests/baselines/reference/library-reference-1.types new file mode 100644 index 0000000000000..99133f2f8df9a --- /dev/null +++ b/tests/baselines/reference/library-reference-1.types @@ -0,0 +1,17 @@ +=== /consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /types/jquery/index.d.ts === + +// We can find typings in the ./types folder + +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-10.js b/tests/baselines/reference/library-reference-10.js new file mode 100644 index 0000000000000..a6dbdfce6106e --- /dev/null +++ b/tests/baselines/reference/library-reference-10.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/references/library-reference-10.ts] //// + +//// [package.json] + +// package.json in a primary reference can refer to another file + +{ + "typings": "jquery.d.ts" +} + +//// [jquery.d.ts] +declare var $: { foo(): void }; + + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-10.symbols b/tests/baselines/reference/library-reference-10.symbols new file mode 100644 index 0000000000000..9d0f7e4781e35 --- /dev/null +++ b/tests/baselines/reference/library-reference-10.symbols @@ -0,0 +1,13 @@ +=== /consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + +=== /types/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + + diff --git a/tests/baselines/reference/library-reference-10.trace.json b/tests/baselines/reference/library-reference-10.trace.json new file mode 100644 index 0000000000000..e6a1918a44653 --- /dev/null +++ b/tests/baselines/reference/library-reference-10.trace.json @@ -0,0 +1,8 @@ +[ + "======== Resolving type reference directive 'jquery', containing file '/consumer.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "Found 'package.json' at '/types/jquery/package.json'.", + "'package.json' has 'typings' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", + "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/types/jquery/jquery.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-10.types b/tests/baselines/reference/library-reference-10.types new file mode 100644 index 0000000000000..42d78f72865c3 --- /dev/null +++ b/tests/baselines/reference/library-reference-10.types @@ -0,0 +1,14 @@ +=== /consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /types/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-11.js b/tests/baselines/reference/library-reference-11.js new file mode 100644 index 0000000000000..773fe5a890a89 --- /dev/null +++ b/tests/baselines/reference/library-reference-11.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/references/library-reference-11.ts] //// + +//// [package.json] + +// package.json in a secondary reference can refer to another file + +{ + "typings": "jquery.d.ts" +} + +//// [jquery.d.ts] +declare var $: { foo(): void }; + + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-11.symbols b/tests/baselines/reference/library-reference-11.symbols new file mode 100644 index 0000000000000..22b8bdf1b449c --- /dev/null +++ b/tests/baselines/reference/library-reference-11.symbols @@ -0,0 +1,13 @@ +=== /a/b/consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + +=== /a/node_modules/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + + diff --git a/tests/baselines/reference/library-reference-11.trace.json b/tests/baselines/reference/library-reference-11.trace.json new file mode 100644 index 0000000000000..e0af1e39c5ac8 --- /dev/null +++ b/tests/baselines/reference/library-reference-11.trace.json @@ -0,0 +1,21 @@ +[ + "======== Resolving type reference directive 'jquery', containing file '/a/b/consumer.ts', root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Looking up in 'node_modules' folder, initial location '/a/b'", + "File '/a/b/node_modules/jquery.ts' does not exist.", + "File '/a/b/node_modules/jquery.d.ts' does not exist.", + "File '/a/b/node_modules/jquery/package.json' does not exist.", + "File '/a/b/node_modules/jquery/index.ts' does not exist.", + "File '/a/b/node_modules/jquery/index.d.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery.d.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery/package.json' does not exist.", + "File '/a/b/node_modules/@types/jquery/index.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery/index.d.ts' does not exist.", + "File '/a/node_modules/jquery.ts' does not exist.", + "File '/a/node_modules/jquery.d.ts' does not exist.", + "Found 'package.json' at '/a/node_modules/jquery/package.json'.", + "'package.json' has 'typings' field 'jquery.d.ts' that references '/a/node_modules/jquery/jquery.d.ts'.", + "File '/a/node_modules/jquery/jquery.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/a/node_modules/jquery/jquery.d.ts', primary: false. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-11.types b/tests/baselines/reference/library-reference-11.types new file mode 100644 index 0000000000000..267ee08e6d6e8 --- /dev/null +++ b/tests/baselines/reference/library-reference-11.types @@ -0,0 +1,14 @@ +=== /a/b/consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /a/node_modules/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-12.js b/tests/baselines/reference/library-reference-12.js new file mode 100644 index 0000000000000..42d0f650b50d1 --- /dev/null +++ b/tests/baselines/reference/library-reference-12.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/references/library-reference-12.ts] //// + +//// [package.json] + +// package.json in a secondary reference can refer to another file + +{ + "types": "dist/jquery.d.ts" +} + +//// [jquery.d.ts] +declare var $: { foo(): void }; + + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-12.symbols b/tests/baselines/reference/library-reference-12.symbols new file mode 100644 index 0000000000000..2e25588bf77f6 --- /dev/null +++ b/tests/baselines/reference/library-reference-12.symbols @@ -0,0 +1,13 @@ +=== /a/b/consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + +=== /a/node_modules/jquery/dist/jquery.d.ts === +declare var $: { foo(): void }; +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + + diff --git a/tests/baselines/reference/library-reference-12.trace.json b/tests/baselines/reference/library-reference-12.trace.json new file mode 100644 index 0000000000000..2cdf1f5f20ace --- /dev/null +++ b/tests/baselines/reference/library-reference-12.trace.json @@ -0,0 +1,21 @@ +[ + "======== Resolving type reference directive 'jquery', containing file '/a/b/consumer.ts', root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Looking up in 'node_modules' folder, initial location '/a/b'", + "File '/a/b/node_modules/jquery.ts' does not exist.", + "File '/a/b/node_modules/jquery.d.ts' does not exist.", + "File '/a/b/node_modules/jquery/package.json' does not exist.", + "File '/a/b/node_modules/jquery/index.ts' does not exist.", + "File '/a/b/node_modules/jquery/index.d.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery.d.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery/package.json' does not exist.", + "File '/a/b/node_modules/@types/jquery/index.ts' does not exist.", + "File '/a/b/node_modules/@types/jquery/index.d.ts' does not exist.", + "File '/a/node_modules/jquery.ts' does not exist.", + "File '/a/node_modules/jquery.d.ts' does not exist.", + "Found 'package.json' at '/a/node_modules/jquery/package.json'.", + "'package.json' has 'types' field 'dist/jquery.d.ts' that references '/a/node_modules/jquery/dist/jquery.d.ts'.", + "File '/a/node_modules/jquery/dist/jquery.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/a/node_modules/jquery/dist/jquery.d.ts', primary: false. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-12.types b/tests/baselines/reference/library-reference-12.types new file mode 100644 index 0000000000000..2ab9fb8ba95e8 --- /dev/null +++ b/tests/baselines/reference/library-reference-12.types @@ -0,0 +1,14 @@ +=== /a/b/consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /a/node_modules/jquery/dist/jquery.d.ts === +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-13.js b/tests/baselines/reference/library-reference-13.js new file mode 100644 index 0000000000000..be52aba1a39c7 --- /dev/null +++ b/tests/baselines/reference/library-reference-13.js @@ -0,0 +1,12 @@ +//// [tests/cases/conformance/references/library-reference-13.ts] //// + +//// [index.d.ts] +declare var $: { foo(): void }; + + +//// [consumer.ts] +$.foo(); + + +//// [consumer.js] +$.foo(); diff --git a/tests/baselines/reference/library-reference-13.symbols b/tests/baselines/reference/library-reference-13.symbols new file mode 100644 index 0000000000000..04d50373caae0 --- /dev/null +++ b/tests/baselines/reference/library-reference-13.symbols @@ -0,0 +1,12 @@ +=== /a/b/consumer.ts === +$.foo(); +>$.foo : Symbol(foo, Decl(index.d.ts, 0, 16)) +>$ : Symbol($, Decl(index.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 0, 16)) + +=== /a/types/jquery/index.d.ts === +declare var $: { foo(): void }; +>$ : Symbol($, Decl(index.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 0, 16)) + + diff --git a/tests/baselines/reference/library-reference-13.trace.json b/tests/baselines/reference/library-reference-13.trace.json new file mode 100644 index 0000000000000..2133414f41424 --- /dev/null +++ b/tests/baselines/reference/library-reference-13.trace.json @@ -0,0 +1,7 @@ +[ + "======== Resolving type reference directive 'jquery', containing file not set, root directory '/a'. ========", + "Resolving with primary search path '/a/types/'", + "File '/a/types/jquery/package.json' does not exist.", + "File '/a/types/jquery/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/a/types/jquery/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-13.types b/tests/baselines/reference/library-reference-13.types new file mode 100644 index 0000000000000..b00d778c5b2a2 --- /dev/null +++ b/tests/baselines/reference/library-reference-13.types @@ -0,0 +1,13 @@ +=== /a/b/consumer.ts === +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /a/types/jquery/index.d.ts === +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-14.js b/tests/baselines/reference/library-reference-14.js new file mode 100644 index 0000000000000..0fb5ff04fb9be --- /dev/null +++ b/tests/baselines/reference/library-reference-14.js @@ -0,0 +1,13 @@ +//// [tests/cases/conformance/references/library-reference-14.ts] //// + +//// [index.d.ts] + +declare var $: { foo(): void }; + + +//// [consumer.ts] +$.foo(); + + +//// [consumer.js] +$.foo(); diff --git a/tests/baselines/reference/library-reference-14.symbols b/tests/baselines/reference/library-reference-14.symbols new file mode 100644 index 0000000000000..162afc50ca785 --- /dev/null +++ b/tests/baselines/reference/library-reference-14.symbols @@ -0,0 +1,13 @@ +=== /a/b/consumer.ts === +$.foo(); +>$.foo : Symbol(foo, Decl(index.d.ts, 1, 16)) +>$ : Symbol($, Decl(index.d.ts, 1, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 1, 16)) + +=== /a/types/jquery/index.d.ts === + +declare var $: { foo(): void }; +>$ : Symbol($, Decl(index.d.ts, 1, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 1, 16)) + + diff --git a/tests/baselines/reference/library-reference-14.trace.json b/tests/baselines/reference/library-reference-14.trace.json new file mode 100644 index 0000000000000..2133414f41424 --- /dev/null +++ b/tests/baselines/reference/library-reference-14.trace.json @@ -0,0 +1,7 @@ +[ + "======== Resolving type reference directive 'jquery', containing file not set, root directory '/a'. ========", + "Resolving with primary search path '/a/types/'", + "File '/a/types/jquery/package.json' does not exist.", + "File '/a/types/jquery/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/a/types/jquery/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-14.types b/tests/baselines/reference/library-reference-14.types new file mode 100644 index 0000000000000..f4196e10744e2 --- /dev/null +++ b/tests/baselines/reference/library-reference-14.types @@ -0,0 +1,14 @@ +=== /a/b/consumer.ts === +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /a/types/jquery/index.d.ts === + +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-15.errors.txt b/tests/baselines/reference/library-reference-15.errors.txt new file mode 100644 index 0000000000000..a311633ca76d5 --- /dev/null +++ b/tests/baselines/reference/library-reference-15.errors.txt @@ -0,0 +1,15 @@ +error TS2304: Cannot find name 'jquery'. +/a/b/consumer.ts(1,1): error TS2304: Cannot find name '$'. + + +!!! error TS2304: Cannot find name 'jquery'. +==== /a/b/consumer.ts (1 errors) ==== + $.foo(); + ~ +!!! error TS2304: Cannot find name '$'. + +==== /a/types/jquery/index.d.ts (0 errors) ==== + + declare var $: { foo(): void }; + + \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-15.js b/tests/baselines/reference/library-reference-15.js new file mode 100644 index 0000000000000..f9aa7038d539d --- /dev/null +++ b/tests/baselines/reference/library-reference-15.js @@ -0,0 +1,13 @@ +//// [tests/cases/conformance/references/library-reference-15.ts] //// + +//// [index.d.ts] + +declare var $: { foo(): void }; + + +//// [consumer.ts] +$.foo(); + + +//// [consumer.js] +$.foo(); diff --git a/tests/baselines/reference/library-reference-15.trace.json b/tests/baselines/reference/library-reference-15.trace.json new file mode 100644 index 0000000000000..9a19d75ffacb1 --- /dev/null +++ b/tests/baselines/reference/library-reference-15.trace.json @@ -0,0 +1,5 @@ +[ + "======== Resolving type reference directive 'jquery', containing file not set, root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder." +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-2.js b/tests/baselines/reference/library-reference-2.js new file mode 100644 index 0000000000000..20729db6c6032 --- /dev/null +++ b/tests/baselines/reference/library-reference-2.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/references/library-reference-2.ts] //// + +//// [package.json] + +// package.json in a primary reference can refer to another file + +{ + "types": "jquery.d.ts" +} + +//// [jquery.d.ts] +declare var $: { foo(): void }; + + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-2.symbols b/tests/baselines/reference/library-reference-2.symbols new file mode 100644 index 0000000000000..9d0f7e4781e35 --- /dev/null +++ b/tests/baselines/reference/library-reference-2.symbols @@ -0,0 +1,13 @@ +=== /consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + +=== /types/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : Symbol($, Decl(jquery.d.ts, 0, 11)) +>foo : Symbol(foo, Decl(jquery.d.ts, 0, 16)) + + diff --git a/tests/baselines/reference/library-reference-2.trace.json b/tests/baselines/reference/library-reference-2.trace.json new file mode 100644 index 0000000000000..b5ef5f3e2089a --- /dev/null +++ b/tests/baselines/reference/library-reference-2.trace.json @@ -0,0 +1,8 @@ +[ + "======== Resolving type reference directive 'jquery', containing file '/consumer.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "Found 'package.json' at '/types/jquery/package.json'.", + "'package.json' has 'types' field 'jquery.d.ts' that references '/types/jquery/jquery.d.ts'.", + "File '/types/jquery/jquery.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/types/jquery/jquery.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-2.types b/tests/baselines/reference/library-reference-2.types new file mode 100644 index 0000000000000..42d78f72865c3 --- /dev/null +++ b/tests/baselines/reference/library-reference-2.types @@ -0,0 +1,14 @@ +=== /consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /types/jquery/jquery.d.ts === +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + + diff --git a/tests/baselines/reference/library-reference-3.js b/tests/baselines/reference/library-reference-3.js new file mode 100644 index 0000000000000..6f9ad2d43d2cb --- /dev/null +++ b/tests/baselines/reference/library-reference-3.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/references/library-reference-3.ts] //// + +//// [index.d.ts] + +// Secondary references are possible + +declare var $: { foo(): void }; + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-3.symbols b/tests/baselines/reference/library-reference-3.symbols new file mode 100644 index 0000000000000..a1785fd77c9a5 --- /dev/null +++ b/tests/baselines/reference/library-reference-3.symbols @@ -0,0 +1,15 @@ +=== /src/consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(index.d.ts, 3, 16)) +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + +=== /src/node_modules/jquery/index.d.ts === + +// Secondary references are possible + +declare var $: { foo(): void }; +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + diff --git a/tests/baselines/reference/library-reference-3.trace.json b/tests/baselines/reference/library-reference-3.trace.json new file mode 100644 index 0000000000000..30dbbc3fca4d2 --- /dev/null +++ b/tests/baselines/reference/library-reference-3.trace.json @@ -0,0 +1,10 @@ +[ + "======== Resolving type reference directive 'jquery', containing file '/src/consumer.ts', root directory '/src'. ========", + "Resolving with primary search path '/src/types/'", + "File '/src/types/jquery/package.json' does not exist.", + "File '/src/types/jquery/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/'", + "File '/src/node_modules/jquery/package.json' does not exist.", + "File '/src/node_modules/jquery/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/src/node_modules/jquery/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-3.types b/tests/baselines/reference/library-reference-3.types new file mode 100644 index 0000000000000..ed7da59525f32 --- /dev/null +++ b/tests/baselines/reference/library-reference-3.types @@ -0,0 +1,16 @@ +=== /src/consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /src/node_modules/jquery/index.d.ts === + +// Secondary references are possible + +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + diff --git a/tests/baselines/reference/library-reference-4.js b/tests/baselines/reference/library-reference-4.js new file mode 100644 index 0000000000000..39e4b1d73a57a --- /dev/null +++ b/tests/baselines/reference/library-reference-4.js @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/references/library-reference-4.ts] //// + +//// [index.d.ts] + +// Secondary references may be duplicated if they agree in content + +/// +declare var foo: any; + +//// [index.d.ts] +declare var alpha: any; + +//// [index.d.ts] +/// +declare var bar: any; + +//// [index.d.ts] +declare var alpha: any; + +//// [root.ts] +/// +/// + + +//// [root.js] +/// +/// diff --git a/tests/baselines/reference/library-reference-4.symbols b/tests/baselines/reference/library-reference-4.symbols new file mode 100644 index 0000000000000..f7c082a946d1a --- /dev/null +++ b/tests/baselines/reference/library-reference-4.symbols @@ -0,0 +1,21 @@ +=== /src/root.ts === +/// +No type information for this code./// +No type information for this code. +No type information for this code.=== /node_modules/foo/index.d.ts === + +// Secondary references may be duplicated if they agree in content + +/// +declare var foo: any; +>foo : Symbol(foo, Decl(index.d.ts, 4, 11)) + +=== /node_modules/foo/node_modules/alpha/index.d.ts === +declare var alpha: any; +>alpha : Symbol(alpha, Decl(index.d.ts, 0, 11)) + +=== /node_modules/bar/index.d.ts === +/// +declare var bar: any; +>bar : Symbol(bar, Decl(index.d.ts, 1, 11)) + diff --git a/tests/baselines/reference/library-reference-4.trace.json b/tests/baselines/reference/library-reference-4.trace.json new file mode 100644 index 0000000000000..90b6eb7b01d74 --- /dev/null +++ b/tests/baselines/reference/library-reference-4.trace.json @@ -0,0 +1,90 @@ +[ + "======== Resolving type reference directive 'foo', containing file '/src/root.ts', root directory '/src'. ========", + "Resolving with primary search path '/src/types/'", + "File '/src/types/foo/package.json' does not exist.", + "File '/src/types/foo/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/'", + "File '/src/node_modules/foo/package.json' does not exist.", + "File '/src/node_modules/foo/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/@types/'", + "File '/src/node_modules/@types/foo/package.json' does not exist.", + "File '/src/node_modules/@types/foo/index.d.ts' does not exist.", + "Looking up in 'node_modules' folder, initial location '/src'", + "File '/src/node_modules/foo.ts' does not exist.", + "File '/src/node_modules/foo.d.ts' does not exist.", + "File '/src/node_modules/foo/package.json' does not exist.", + "File '/src/node_modules/foo/index.ts' does not exist.", + "File '/src/node_modules/foo/index.d.ts' does not exist.", + "File '/src/node_modules/@types/foo.ts' does not exist.", + "File '/src/node_modules/@types/foo.d.ts' does not exist.", + "File '/src/node_modules/@types/foo/package.json' does not exist.", + "File '/src/node_modules/@types/foo/index.ts' does not exist.", + "File '/src/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/node_modules/foo.ts' does not exist.", + "File '/node_modules/foo.d.ts' does not exist.", + "File '/node_modules/foo/package.json' does not exist.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'foo' was successfully resolved to '/node_modules/foo/index.d.ts', primary: false. ========", + "======== Resolving type reference directive 'bar', containing file '/src/root.ts', root directory '/src'. ========", + "Resolving with primary search path '/src/types/'", + "File '/src/types/bar/package.json' does not exist.", + "File '/src/types/bar/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/'", + "File '/src/node_modules/bar/package.json' does not exist.", + "File '/src/node_modules/bar/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/@types/'", + "File '/src/node_modules/@types/bar/package.json' does not exist.", + "File '/src/node_modules/@types/bar/index.d.ts' does not exist.", + "Looking up in 'node_modules' folder, initial location '/src'", + "File '/src/node_modules/bar.ts' does not exist.", + "File '/src/node_modules/bar.d.ts' does not exist.", + "File '/src/node_modules/bar/package.json' does not exist.", + "File '/src/node_modules/bar/index.ts' does not exist.", + "File '/src/node_modules/bar/index.d.ts' does not exist.", + "File '/src/node_modules/@types/bar.ts' does not exist.", + "File '/src/node_modules/@types/bar.d.ts' does not exist.", + "File '/src/node_modules/@types/bar/package.json' does not exist.", + "File '/src/node_modules/@types/bar/index.ts' does not exist.", + "File '/src/node_modules/@types/bar/index.d.ts' does not exist.", + "File '/node_modules/bar.ts' does not exist.", + "File '/node_modules/bar.d.ts' does not exist.", + "File '/node_modules/bar/package.json' does not exist.", + "File '/node_modules/bar/index.ts' does not exist.", + "File '/node_modules/bar/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'bar' was successfully resolved to '/node_modules/bar/index.d.ts', primary: false. ========", + "======== Resolving type reference directive 'alpha', containing file '/node_modules/foo/index.d.ts', root directory '/src'. ========", + "Resolving with primary search path '/src/types/'", + "File '/src/types/alpha/package.json' does not exist.", + "File '/src/types/alpha/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/'", + "File '/src/node_modules/alpha/package.json' does not exist.", + "File '/src/node_modules/alpha/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/@types/'", + "File '/src/node_modules/@types/alpha/package.json' does not exist.", + "File '/src/node_modules/@types/alpha/index.d.ts' does not exist.", + "Looking up in 'node_modules' folder, initial location '/node_modules/foo'", + "File '/node_modules/foo/node_modules/alpha.ts' does not exist.", + "File '/node_modules/foo/node_modules/alpha.d.ts' does not exist.", + "File '/node_modules/foo/node_modules/alpha/package.json' does not exist.", + "File '/node_modules/foo/node_modules/alpha/index.ts' does not exist.", + "File '/node_modules/foo/node_modules/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/node_modules/foo/node_modules/alpha/index.d.ts', primary: false. ========", + "======== Resolving type reference directive 'alpha', containing file '/node_modules/bar/index.d.ts', root directory '/src'. ========", + "Resolving with primary search path '/src/types/'", + "File '/src/types/alpha/package.json' does not exist.", + "File '/src/types/alpha/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/'", + "File '/src/node_modules/alpha/package.json' does not exist.", + "File '/src/node_modules/alpha/index.d.ts' does not exist.", + "Resolving with primary search path '/src/node_modules/@types/'", + "File '/src/node_modules/@types/alpha/package.json' does not exist.", + "File '/src/node_modules/@types/alpha/index.d.ts' does not exist.", + "Looking up in 'node_modules' folder, initial location '/node_modules/bar'", + "File '/node_modules/bar/node_modules/alpha.ts' does not exist.", + "File '/node_modules/bar/node_modules/alpha.d.ts' does not exist.", + "File '/node_modules/bar/node_modules/alpha/package.json' does not exist.", + "File '/node_modules/bar/node_modules/alpha/index.ts' does not exist.", + "File '/node_modules/bar/node_modules/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/node_modules/bar/node_modules/alpha/index.d.ts', primary: false. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-4.types b/tests/baselines/reference/library-reference-4.types new file mode 100644 index 0000000000000..a0a7d370b4cdf --- /dev/null +++ b/tests/baselines/reference/library-reference-4.types @@ -0,0 +1,21 @@ +=== /src/root.ts === +/// +No type information for this code./// +No type information for this code. +No type information for this code.=== /node_modules/foo/index.d.ts === + +// Secondary references may be duplicated if they agree in content + +/// +declare var foo: any; +>foo : any + +=== /node_modules/foo/node_modules/alpha/index.d.ts === +declare var alpha: any; +>alpha : any + +=== /node_modules/bar/index.d.ts === +/// +declare var bar: any; +>bar : any + diff --git a/tests/baselines/reference/library-reference-5.errors.txt b/tests/baselines/reference/library-reference-5.errors.txt new file mode 100644 index 0000000000000..ea571cad1a3c5 --- /dev/null +++ b/tests/baselines/reference/library-reference-5.errors.txt @@ -0,0 +1,26 @@ +/node_modules/bar/index.d.ts(1,1): message TS4090: Conflicting library definitions for 'alpha' found at '/node_modules/bar/node_modules/alpha/index.d.ts' and '/node_modules/foo/node_modules/alpha/index.d.ts'. Copy the correct file to the 'typings' folder to resolve this conflict. + + +==== /src/root.ts (0 errors) ==== + /// + /// + +==== /node_modules/foo/index.d.ts (0 errors) ==== + + // Secondary references may not be duplicated if they disagree in content + + /// + declare var foo: any; + +==== /node_modules/foo/node_modules/alpha/index.d.ts (0 errors) ==== + declare var alpha: any; + +==== /node_modules/bar/index.d.ts (1 errors) ==== + /// + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! message TS4090: Conflicting library definitions for 'alpha' found at 'index.d.ts' and 'index.d.ts'. Copy the correct file to the 'typings' folder to resolve this conflict. + declare var bar: any; + +==== /node_modules/bar/node_modules/alpha/index.d.ts (0 errors) ==== + declare var alpha: {}; + \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-5.js b/tests/baselines/reference/library-reference-5.js new file mode 100644 index 0000000000000..40d2131920e3a --- /dev/null +++ b/tests/baselines/reference/library-reference-5.js @@ -0,0 +1,27 @@ +//// [tests/cases/conformance/references/library-reference-5.ts] //// + +//// [index.d.ts] + +// Secondary references may not be duplicated if they disagree in content + +/// +declare var foo: any; + +//// [index.d.ts] +declare var alpha: any; + +//// [index.d.ts] +/// +declare var bar: any; + +//// [index.d.ts] +declare var alpha: {}; + +//// [root.ts] +/// +/// + + +//// [root.js] +/// +/// diff --git a/tests/baselines/reference/library-reference-5.trace.json b/tests/baselines/reference/library-reference-5.trace.json new file mode 100644 index 0000000000000..272009782b5ce --- /dev/null +++ b/tests/baselines/reference/library-reference-5.trace.json @@ -0,0 +1,58 @@ +[ + "======== Resolving type reference directive 'foo', containing file '/src/root.ts', root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Looking up in 'node_modules' folder, initial location '/src'", + "File '/src/node_modules/foo.ts' does not exist.", + "File '/src/node_modules/foo.d.ts' does not exist.", + "File '/src/node_modules/foo/package.json' does not exist.", + "File '/src/node_modules/foo/index.ts' does not exist.", + "File '/src/node_modules/foo/index.d.ts' does not exist.", + "File '/src/node_modules/@types/foo.ts' does not exist.", + "File '/src/node_modules/@types/foo.d.ts' does not exist.", + "File '/src/node_modules/@types/foo/package.json' does not exist.", + "File '/src/node_modules/@types/foo/index.ts' does not exist.", + "File '/src/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/node_modules/foo.ts' does not exist.", + "File '/node_modules/foo.d.ts' does not exist.", + "File '/node_modules/foo/package.json' does not exist.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'foo' was successfully resolved to '/node_modules/foo/index.d.ts', primary: false. ========", + "======== Resolving type reference directive 'bar', containing file '/src/root.ts', root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Looking up in 'node_modules' folder, initial location '/src'", + "File '/src/node_modules/bar.ts' does not exist.", + "File '/src/node_modules/bar.d.ts' does not exist.", + "File '/src/node_modules/bar/package.json' does not exist.", + "File '/src/node_modules/bar/index.ts' does not exist.", + "File '/src/node_modules/bar/index.d.ts' does not exist.", + "File '/src/node_modules/@types/bar.ts' does not exist.", + "File '/src/node_modules/@types/bar.d.ts' does not exist.", + "File '/src/node_modules/@types/bar/package.json' does not exist.", + "File '/src/node_modules/@types/bar/index.ts' does not exist.", + "File '/src/node_modules/@types/bar/index.d.ts' does not exist.", + "File '/node_modules/bar.ts' does not exist.", + "File '/node_modules/bar.d.ts' does not exist.", + "File '/node_modules/bar/package.json' does not exist.", + "File '/node_modules/bar/index.ts' does not exist.", + "File '/node_modules/bar/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'bar' was successfully resolved to '/node_modules/bar/index.d.ts', primary: false. ========", + "======== Resolving type reference directive 'alpha', containing file '/node_modules/foo/index.d.ts', root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Looking up in 'node_modules' folder, initial location '/node_modules/foo'", + "File '/node_modules/foo/node_modules/alpha.ts' does not exist.", + "File '/node_modules/foo/node_modules/alpha.d.ts' does not exist.", + "File '/node_modules/foo/node_modules/alpha/package.json' does not exist.", + "File '/node_modules/foo/node_modules/alpha/index.ts' does not exist.", + "File '/node_modules/foo/node_modules/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/node_modules/foo/node_modules/alpha/index.d.ts', primary: false. ========", + "======== Resolving type reference directive 'alpha', containing file '/node_modules/bar/index.d.ts', root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Looking up in 'node_modules' folder, initial location '/node_modules/bar'", + "File '/node_modules/bar/node_modules/alpha.ts' does not exist.", + "File '/node_modules/bar/node_modules/alpha.d.ts' does not exist.", + "File '/node_modules/bar/node_modules/alpha/package.json' does not exist.", + "File '/node_modules/bar/node_modules/alpha/index.ts' does not exist.", + "File '/node_modules/bar/node_modules/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/node_modules/bar/node_modules/alpha/index.d.ts', primary: false. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-6.js b/tests/baselines/reference/library-reference-6.js new file mode 100644 index 0000000000000..d78a3a131a1ce --- /dev/null +++ b/tests/baselines/reference/library-reference-6.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/references/library-reference-6.ts] //// + +//// [index.d.ts] + +// The primary lookup folder is relative to tsconfig.json, if present + +declare var alpha: { a: string }; + +//// [foo.ts] +/// +var x: string = alpha.a; + + +//// [foo.js] +/// +var x = alpha.a; diff --git a/tests/baselines/reference/library-reference-6.symbols b/tests/baselines/reference/library-reference-6.symbols new file mode 100644 index 0000000000000..328842f804c56 --- /dev/null +++ b/tests/baselines/reference/library-reference-6.symbols @@ -0,0 +1,16 @@ +=== /src/foo.ts === +/// +var x: string = alpha.a; +>x : Symbol(x, Decl(foo.ts, 1, 3)) +>alpha.a : Symbol(a, Decl(index.d.ts, 3, 20)) +>alpha : Symbol(alpha, Decl(index.d.ts, 3, 11)) +>a : Symbol(a, Decl(index.d.ts, 3, 20)) + +=== /types/alpha/index.d.ts === + +// The primary lookup folder is relative to tsconfig.json, if present + +declare var alpha: { a: string }; +>alpha : Symbol(alpha, Decl(index.d.ts, 3, 11)) +>a : Symbol(a, Decl(index.d.ts, 3, 20)) + diff --git a/tests/baselines/reference/library-reference-6.trace.json b/tests/baselines/reference/library-reference-6.trace.json new file mode 100644 index 0000000000000..426214fdcfc7f --- /dev/null +++ b/tests/baselines/reference/library-reference-6.trace.json @@ -0,0 +1,7 @@ +[ + "======== Resolving type reference directive 'alpha', containing file '/src/foo.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "File '/types/alpha/package.json' does not exist.", + "File '/types/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/types/alpha/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-6.types b/tests/baselines/reference/library-reference-6.types new file mode 100644 index 0000000000000..2f6c1e49b891f --- /dev/null +++ b/tests/baselines/reference/library-reference-6.types @@ -0,0 +1,16 @@ +=== /src/foo.ts === +/// +var x: string = alpha.a; +>x : string +>alpha.a : string +>alpha : { a: string; } +>a : string + +=== /types/alpha/index.d.ts === + +// The primary lookup folder is relative to tsconfig.json, if present + +declare var alpha: { a: string }; +>alpha : { a: string; } +>a : string + diff --git a/tests/baselines/reference/library-reference-7.js b/tests/baselines/reference/library-reference-7.js new file mode 100644 index 0000000000000..f1ef6ca4eab8a --- /dev/null +++ b/tests/baselines/reference/library-reference-7.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/references/library-reference-7.ts] //// + +//// [index.d.ts] + +// Secondary references are possible + +declare var $: { foo(): void }; + +//// [consumer.ts] +/// +$.foo(); + + +//// [consumer.js] +/// +$.foo(); diff --git a/tests/baselines/reference/library-reference-7.symbols b/tests/baselines/reference/library-reference-7.symbols new file mode 100644 index 0000000000000..a1785fd77c9a5 --- /dev/null +++ b/tests/baselines/reference/library-reference-7.symbols @@ -0,0 +1,15 @@ +=== /src/consumer.ts === +/// +$.foo(); +>$.foo : Symbol(foo, Decl(index.d.ts, 3, 16)) +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + +=== /src/node_modules/jquery/index.d.ts === + +// Secondary references are possible + +declare var $: { foo(): void }; +>$ : Symbol($, Decl(index.d.ts, 3, 11)) +>foo : Symbol(foo, Decl(index.d.ts, 3, 16)) + diff --git a/tests/baselines/reference/library-reference-7.trace.json b/tests/baselines/reference/library-reference-7.trace.json new file mode 100644 index 0000000000000..419fe6d055d72 --- /dev/null +++ b/tests/baselines/reference/library-reference-7.trace.json @@ -0,0 +1,11 @@ +[ + "======== Resolving type reference directive 'jquery', containing file '/src/consumer.ts', root directory not set. ========", + "Root directory cannot be determined, skipping primary search paths.", + "Looking up in 'node_modules' folder, initial location '/src'", + "File '/src/node_modules/jquery.ts' does not exist.", + "File '/src/node_modules/jquery.d.ts' does not exist.", + "File '/src/node_modules/jquery/package.json' does not exist.", + "File '/src/node_modules/jquery/index.ts' does not exist.", + "File '/src/node_modules/jquery/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'jquery' was successfully resolved to '/src/node_modules/jquery/index.d.ts', primary: false. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-7.types b/tests/baselines/reference/library-reference-7.types new file mode 100644 index 0000000000000..ed7da59525f32 --- /dev/null +++ b/tests/baselines/reference/library-reference-7.types @@ -0,0 +1,16 @@ +=== /src/consumer.ts === +/// +$.foo(); +>$.foo() : void +>$.foo : () => void +>$ : { foo(): void; } +>foo : () => void + +=== /src/node_modules/jquery/index.d.ts === + +// Secondary references are possible + +declare var $: { foo(): void }; +>$ : { foo(): void; } +>foo : () => void + diff --git a/tests/baselines/reference/library-reference-8.js b/tests/baselines/reference/library-reference-8.js new file mode 100644 index 0000000000000..a48b226cb62fc --- /dev/null +++ b/tests/baselines/reference/library-reference-8.js @@ -0,0 +1,24 @@ +//// [tests/cases/conformance/references/library-reference-8.ts] //// + +//// [index.d.ts] + +// Don't crash in circular library reference situations + +/// +declare var alpha: { a: string }; + +//// [index.d.ts] +/// +declare var beta: { b: string }; + +//// [foo.ts] +/// +/// +var x: string = alpha.a + beta.b; + + + +//// [foo.js] +/// +/// +var x = alpha.a + beta.b; diff --git a/tests/baselines/reference/library-reference-8.symbols b/tests/baselines/reference/library-reference-8.symbols new file mode 100644 index 0000000000000..299a60f1b1dcb --- /dev/null +++ b/tests/baselines/reference/library-reference-8.symbols @@ -0,0 +1,28 @@ +=== /foo.ts === +/// +/// +var x: string = alpha.a + beta.b; +>x : Symbol(x, Decl(foo.ts, 2, 3)) +>alpha.a : Symbol(a, Decl(index.d.ts, 4, 20)) +>alpha : Symbol(alpha, Decl(index.d.ts, 4, 11)) +>a : Symbol(a, Decl(index.d.ts, 4, 20)) +>beta.b : Symbol(b, Decl(index.d.ts, 1, 19)) +>beta : Symbol(beta, Decl(index.d.ts, 1, 11)) +>b : Symbol(b, Decl(index.d.ts, 1, 19)) + + +=== /types/alpha/index.d.ts === + +// Don't crash in circular library reference situations + +/// +declare var alpha: { a: string }; +>alpha : Symbol(alpha, Decl(index.d.ts, 4, 11)) +>a : Symbol(a, Decl(index.d.ts, 4, 20)) + +=== /types/beta/index.d.ts === +/// +declare var beta: { b: string }; +>beta : Symbol(beta, Decl(index.d.ts, 1, 11)) +>b : Symbol(b, Decl(index.d.ts, 1, 19)) + diff --git a/tests/baselines/reference/library-reference-8.trace.json b/tests/baselines/reference/library-reference-8.trace.json new file mode 100644 index 0000000000000..b1dc64786880d --- /dev/null +++ b/tests/baselines/reference/library-reference-8.trace.json @@ -0,0 +1,22 @@ +[ + "======== Resolving type reference directive 'alpha', containing file '/foo.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "File '/types/alpha/package.json' does not exist.", + "File '/types/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/types/alpha/index.d.ts', primary: true. ========", + "======== Resolving type reference directive 'beta', containing file '/foo.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "File '/types/beta/package.json' does not exist.", + "File '/types/beta/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'beta' was successfully resolved to '/types/beta/index.d.ts', primary: true. ========", + "======== Resolving type reference directive 'beta', containing file '/types/alpha/index.d.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "File '/types/beta/package.json' does not exist.", + "File '/types/beta/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'beta' was successfully resolved to '/types/beta/index.d.ts', primary: true. ========", + "======== Resolving type reference directive 'alpha', containing file '/types/beta/index.d.ts', root directory '/'. ========", + "Resolving with primary search path '/types/'", + "File '/types/alpha/package.json' does not exist.", + "File '/types/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/types/alpha/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-8.types b/tests/baselines/reference/library-reference-8.types new file mode 100644 index 0000000000000..b0780d90f63ac --- /dev/null +++ b/tests/baselines/reference/library-reference-8.types @@ -0,0 +1,29 @@ +=== /foo.ts === +/// +/// +var x: string = alpha.a + beta.b; +>x : string +>alpha.a + beta.b : string +>alpha.a : string +>alpha : { a: string; } +>a : string +>beta.b : string +>beta : { b: string; } +>b : string + + +=== /types/alpha/index.d.ts === + +// Don't crash in circular library reference situations + +/// +declare var alpha: { a: string }; +>alpha : { a: string; } +>a : string + +=== /types/beta/index.d.ts === +/// +declare var beta: { b: string }; +>beta : { b: string; } +>b : string + diff --git a/tests/baselines/reference/library-reference-9.js b/tests/baselines/reference/library-reference-9.js new file mode 100644 index 0000000000000..ccb3b3213a9f1 --- /dev/null +++ b/tests/baselines/reference/library-reference-9.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/references/library-reference-9.ts] //// + +//// [index.d.ts] + +// Use types search path + +declare var alpha: { a: string }; + +//// [foo.ts] +/// +var x: string = alpha.a; + + +//// [foo.js] +/// +var x = alpha.a; diff --git a/tests/baselines/reference/library-reference-9.symbols b/tests/baselines/reference/library-reference-9.symbols new file mode 100644 index 0000000000000..62cde2117dff6 --- /dev/null +++ b/tests/baselines/reference/library-reference-9.symbols @@ -0,0 +1,16 @@ +=== /base/src/foo.ts === +/// +var x: string = alpha.a; +>x : Symbol(x, Decl(foo.ts, 1, 3)) +>alpha.a : Symbol(a, Decl(index.d.ts, 3, 20)) +>alpha : Symbol(alpha, Decl(index.d.ts, 3, 11)) +>a : Symbol(a, Decl(index.d.ts, 3, 20)) + +=== /share/typelib/alpha/index.d.ts === + +// Use types search path + +declare var alpha: { a: string }; +>alpha : Symbol(alpha, Decl(index.d.ts, 3, 11)) +>a : Symbol(a, Decl(index.d.ts, 3, 20)) + diff --git a/tests/baselines/reference/library-reference-9.trace.json b/tests/baselines/reference/library-reference-9.trace.json new file mode 100644 index 0000000000000..e2fdfdc05500c --- /dev/null +++ b/tests/baselines/reference/library-reference-9.trace.json @@ -0,0 +1,7 @@ +[ + "======== Resolving type reference directive 'alpha', containing file '/base/src/foo.ts', root directory '/'. ========", + "Resolving with primary search path '/share/typelib'", + "File '/share/typelib/alpha/package.json' does not exist.", + "File '/share/typelib/alpha/index.d.ts' exist - use it as a name resolution result.", + "======== Type reference directive 'alpha' was successfully resolved to '/share/typelib/alpha/index.d.ts', primary: true. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/library-reference-9.types b/tests/baselines/reference/library-reference-9.types new file mode 100644 index 0000000000000..8df2179e24995 --- /dev/null +++ b/tests/baselines/reference/library-reference-9.types @@ -0,0 +1,16 @@ +=== /base/src/foo.ts === +/// +var x: string = alpha.a; +>x : string +>alpha.a : string +>alpha : { a: string; } +>a : string + +=== /share/typelib/alpha/index.d.ts === + +// Use types search path + +declare var alpha: { a: string }; +>alpha : { a: string; } +>a : string + diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution3_classic.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution3_classic.trace.json index 513198c50b0c4..8b003e05e8f04 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution3_classic.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution3_classic.trace.json @@ -3,11 +3,11 @@ "Explicitly specified module resolution kind: 'Classic'.", "'baseUrl' option is set to 'c:/root', using this value to resolve non-relative module name 'folder2/file2'", "Resolving module name 'folder2/file2' relative to base url 'c:/root' - 'c:/root/folder2/file2'.", - "File 'c:/root/folder2/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file2.ts' exist - use it as a name resolution result.", "======== Module name 'folder2/file2' was successfully resolved to 'c:/root/folder2/file2.ts'. ========", "======== Resolving module './file3' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", - "File 'c:/root/folder2/file3.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file3.ts' exist - use it as a name resolution result.", "======== Module name './file3' was successfully resolved to 'c:/root/folder2/file3.ts'. ========", "======== Resolving module 'file4' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", @@ -19,6 +19,6 @@ "File 'c:/root/folder2/file4.d.ts' does not exist.", "File 'c:/root/file4.ts' does not exist.", "File 'c:/root/file4.d.ts' does not exist.", - "File 'c:/file4.ts' exist - use it as a module resolution result.", + "File 'c:/file4.ts' exist - use it as a name resolution result.", "======== Module name 'file4' was successfully resolved to 'c:/file4.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution3_node.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution3_node.trace.json index 6d0de807bc03c..af5e20a3cc30c 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution3_node.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution3_node.trace.json @@ -4,12 +4,12 @@ "'baseUrl' option is set to 'c:/root', using this value to resolve non-relative module name 'folder2/file2'", "Resolving module name 'folder2/file2' relative to base url 'c:/root' - 'c:/root/folder2/file2'.", "Loading module as file / folder, candidate module location 'c:/root/folder2/file2'.", - "File 'c:/root/folder2/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file2.ts' exist - use it as a name resolution result.", "======== Module name 'folder2/file2' was successfully resolved to 'c:/root/folder2/file2.ts'. ========", "======== Resolving module './file3' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", "Loading module as file / folder, candidate module location 'c:/root/folder2/file3'.", - "File 'c:/root/folder2/file3.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file3.ts' exist - use it as a name resolution result.", "======== Module name './file3' was successfully resolved to 'c:/root/folder2/file3.ts'. ========", "======== Resolving module 'file4' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", @@ -31,6 +31,13 @@ "File 'c:/root/folder2/node_modules/file4/index.ts' does not exist.", "File 'c:/root/folder2/node_modules/file4/index.tsx' does not exist.", "File 'c:/root/folder2/node_modules/file4/index.d.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4.tsx' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4.d.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/package.json' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/index.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/index.tsx' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/index.d.ts' does not exist.", "File 'c:/root/node_modules/file4.ts' does not exist.", "File 'c:/root/node_modules/file4.tsx' does not exist.", "File 'c:/root/node_modules/file4.d.ts' does not exist.", @@ -38,12 +45,19 @@ "File 'c:/root/node_modules/file4/index.ts' does not exist.", "File 'c:/root/node_modules/file4/index.tsx' does not exist.", "File 'c:/root/node_modules/file4/index.d.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4.tsx' does not exist.", + "File 'c:/root/node_modules/@types/file4.d.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4/package.json' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.tsx' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.d.ts' does not exist.", "File 'c:/node_modules/file4.ts' does not exist.", "File 'c:/node_modules/file4.tsx' does not exist.", "File 'c:/node_modules/file4.d.ts' does not exist.", "File 'c:/node_modules/file4/package.json' does not exist.", "File 'c:/node_modules/file4/index.ts' does not exist.", "File 'c:/node_modules/file4/index.tsx' does not exist.", - "File 'c:/node_modules/file4/index.d.ts' exist - use it as a module resolution result.", + "File 'c:/node_modules/file4/index.d.ts' exist - use it as a name resolution result.", "======== Module name 'file4' was successfully resolved to 'c:/node_modules/file4/index.d.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution4_classic.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution4_classic.trace.json index 513198c50b0c4..8b003e05e8f04 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution4_classic.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution4_classic.trace.json @@ -3,11 +3,11 @@ "Explicitly specified module resolution kind: 'Classic'.", "'baseUrl' option is set to 'c:/root', using this value to resolve non-relative module name 'folder2/file2'", "Resolving module name 'folder2/file2' relative to base url 'c:/root' - 'c:/root/folder2/file2'.", - "File 'c:/root/folder2/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file2.ts' exist - use it as a name resolution result.", "======== Module name 'folder2/file2' was successfully resolved to 'c:/root/folder2/file2.ts'. ========", "======== Resolving module './file3' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", - "File 'c:/root/folder2/file3.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file3.ts' exist - use it as a name resolution result.", "======== Module name './file3' was successfully resolved to 'c:/root/folder2/file3.ts'. ========", "======== Resolving module 'file4' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'Classic'.", @@ -19,6 +19,6 @@ "File 'c:/root/folder2/file4.d.ts' does not exist.", "File 'c:/root/file4.ts' does not exist.", "File 'c:/root/file4.d.ts' does not exist.", - "File 'c:/file4.ts' exist - use it as a module resolution result.", + "File 'c:/file4.ts' exist - use it as a name resolution result.", "======== Module name 'file4' was successfully resolved to 'c:/file4.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution4_node.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution4_node.trace.json index 6d0de807bc03c..af5e20a3cc30c 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution4_node.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution4_node.trace.json @@ -4,12 +4,12 @@ "'baseUrl' option is set to 'c:/root', using this value to resolve non-relative module name 'folder2/file2'", "Resolving module name 'folder2/file2' relative to base url 'c:/root' - 'c:/root/folder2/file2'.", "Loading module as file / folder, candidate module location 'c:/root/folder2/file2'.", - "File 'c:/root/folder2/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file2.ts' exist - use it as a name resolution result.", "======== Module name 'folder2/file2' was successfully resolved to 'c:/root/folder2/file2.ts'. ========", "======== Resolving module './file3' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", "Loading module as file / folder, candidate module location 'c:/root/folder2/file3'.", - "File 'c:/root/folder2/file3.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file3.ts' exist - use it as a name resolution result.", "======== Module name './file3' was successfully resolved to 'c:/root/folder2/file3.ts'. ========", "======== Resolving module 'file4' from 'c:/root/folder2/file2.ts'. ========", "Explicitly specified module resolution kind: 'NodeJs'.", @@ -31,6 +31,13 @@ "File 'c:/root/folder2/node_modules/file4/index.ts' does not exist.", "File 'c:/root/folder2/node_modules/file4/index.tsx' does not exist.", "File 'c:/root/folder2/node_modules/file4/index.d.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4.tsx' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4.d.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/package.json' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/index.ts' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/index.tsx' does not exist.", + "File 'c:/root/folder2/node_modules/@types/file4/index.d.ts' does not exist.", "File 'c:/root/node_modules/file4.ts' does not exist.", "File 'c:/root/node_modules/file4.tsx' does not exist.", "File 'c:/root/node_modules/file4.d.ts' does not exist.", @@ -38,12 +45,19 @@ "File 'c:/root/node_modules/file4/index.ts' does not exist.", "File 'c:/root/node_modules/file4/index.tsx' does not exist.", "File 'c:/root/node_modules/file4/index.d.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4.tsx' does not exist.", + "File 'c:/root/node_modules/@types/file4.d.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4/package.json' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.tsx' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.d.ts' does not exist.", "File 'c:/node_modules/file4.ts' does not exist.", "File 'c:/node_modules/file4.tsx' does not exist.", "File 'c:/node_modules/file4.d.ts' does not exist.", "File 'c:/node_modules/file4/package.json' does not exist.", "File 'c:/node_modules/file4/index.ts' does not exist.", "File 'c:/node_modules/file4/index.tsx' does not exist.", - "File 'c:/node_modules/file4/index.d.ts' exist - use it as a module resolution result.", + "File 'c:/node_modules/file4/index.d.ts' exist - use it as a name resolution result.", "======== Module name 'file4' was successfully resolved to 'c:/node_modules/file4/index.d.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution5_classic.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution5_classic.trace.json index 099acae2aca50..d1709c82dc676 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution5_classic.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution5_classic.trace.json @@ -5,7 +5,7 @@ "'paths' option is specified, looking for a pattern to match module name 'folder2/file1'.", "Module name 'folder2/file1', matched pattern '*'.", "Trying substitution '*', candidate module location: 'folder2/file1'.", - "File 'c:/root/folder2/file1.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file1.ts' exist - use it as a name resolution result.", "======== Module name 'folder2/file1' was successfully resolved to 'c:/root/folder2/file1.ts'. ========", "======== Resolving module 'folder3/file2' from 'c:/root/folder1/file1.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -16,7 +16,7 @@ "File 'c:/root/folder3/file2.ts' does not exist.", "File 'c:/root/folder3/file2.d.ts' does not exist.", "Trying substitution 'generated/*', candidate module location: 'generated/folder3/file2'.", - "File 'c:/root/generated/folder3/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/folder3/file2.ts' exist - use it as a name resolution result.", "======== Module name 'folder3/file2' was successfully resolved to 'c:/root/generated/folder3/file2.ts'. ========", "======== Resolving module 'components/file3' from 'c:/root/folder1/file1.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -24,7 +24,7 @@ "'paths' option is specified, looking for a pattern to match module name 'components/file3'.", "Module name 'components/file3', matched pattern 'components/*'.", "Trying substitution 'shared/components/*', candidate module location: 'shared/components/file3'.", - "File 'c:/root/shared/components/file3.ts' exist - use it as a module resolution result.", + "File 'c:/root/shared/components/file3.ts' exist - use it as a name resolution result.", "======== Module name 'components/file3' was successfully resolved to 'c:/root/shared/components/file3.ts'. ========", "======== Resolving module 'file4' from 'c:/root/folder1/file1.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -41,6 +41,6 @@ "File 'c:/root/folder1/file4.d.ts' does not exist.", "File 'c:/root/file4.ts' does not exist.", "File 'c:/root/file4.d.ts' does not exist.", - "File 'c:/file4.ts' exist - use it as a module resolution result.", + "File 'c:/file4.ts' exist - use it as a name resolution result.", "======== Module name 'file4' was successfully resolved to 'c:/file4.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution5_node.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution5_node.trace.json index 398d15839de92..cebd59f01b41a 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution5_node.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution5_node.trace.json @@ -6,7 +6,7 @@ "Module name 'folder2/file1', matched pattern '*'.", "Trying substitution '*', candidate module location: 'folder2/file1'.", "Loading module as file / folder, candidate module location 'c:/root/folder2/file1'.", - "File 'c:/root/folder2/file1.ts' exist - use it as a module resolution result.", + "File 'c:/root/folder2/file1.ts' exist - use it as a name resolution result.", "======== Module name 'folder2/file1' was successfully resolved to 'c:/root/folder2/file1.ts'. ========", "======== Resolving module 'folder3/file2' from 'c:/root/folder1/file1.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -24,7 +24,7 @@ "File 'c:/root/folder3/file2/index.d.ts' does not exist.", "Trying substitution 'generated/*', candidate module location: 'generated/folder3/file2'.", "Loading module as file / folder, candidate module location 'c:/root/generated/folder3/file2'.", - "File 'c:/root/generated/folder3/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/folder3/file2.ts' exist - use it as a name resolution result.", "======== Module name 'folder3/file2' was successfully resolved to 'c:/root/generated/folder3/file2.ts'. ========", "======== Resolving module 'components/file3' from 'c:/root/folder1/file1.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -39,7 +39,7 @@ "File 'c:/root/shared/components/file3/package.json' does not exist.", "File 'c:/root/shared/components/file3/index.ts' does not exist.", "File 'c:/root/shared/components/file3/index.tsx' does not exist.", - "File 'c:/root/shared/components/file3/index.d.ts' exist - use it as a module resolution result.", + "File 'c:/root/shared/components/file3/index.d.ts' exist - use it as a name resolution result.", "======== Module name 'components/file3' was successfully resolved to 'c:/root/shared/components/file3/index.d.ts'. ========", "======== Resolving module 'file4' from 'c:/root/folder1/file1.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -72,6 +72,13 @@ "File 'c:/root/folder1/node_modules/file4/index.ts' does not exist.", "File 'c:/root/folder1/node_modules/file4/index.tsx' does not exist.", "File 'c:/root/folder1/node_modules/file4/index.d.ts' does not exist.", + "File 'c:/root/folder1/node_modules/@types/file4.ts' does not exist.", + "File 'c:/root/folder1/node_modules/@types/file4.tsx' does not exist.", + "File 'c:/root/folder1/node_modules/@types/file4.d.ts' does not exist.", + "File 'c:/root/folder1/node_modules/@types/file4/package.json' does not exist.", + "File 'c:/root/folder1/node_modules/@types/file4/index.ts' does not exist.", + "File 'c:/root/folder1/node_modules/@types/file4/index.tsx' does not exist.", + "File 'c:/root/folder1/node_modules/@types/file4/index.d.ts' does not exist.", "File 'c:/root/node_modules/file4.ts' does not exist.", "File 'c:/root/node_modules/file4.tsx' does not exist.", "File 'c:/root/node_modules/file4.d.ts' does not exist.", @@ -79,6 +86,13 @@ "File 'c:/root/node_modules/file4/index.ts' does not exist.", "File 'c:/root/node_modules/file4/index.tsx' does not exist.", "File 'c:/root/node_modules/file4/index.d.ts' does not exist.", - "File 'c:/node_modules/file4.ts' exist - use it as a module resolution result.", + "File 'c:/root/node_modules/@types/file4.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4.tsx' does not exist.", + "File 'c:/root/node_modules/@types/file4.d.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4/package.json' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.ts' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.tsx' does not exist.", + "File 'c:/root/node_modules/@types/file4/index.d.ts' does not exist.", + "File 'c:/node_modules/file4.ts' exist - use it as a name resolution result.", "======== Module name 'file4' was successfully resolved to 'c:/node_modules/file4.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution6_classic.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution6_classic.trace.json index 0493e9c216b3c..20fc416ccd479 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution6_classic.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution6_classic.trace.json @@ -10,7 +10,7 @@ "File 'c:/root/src/project/file3.d.ts' does not exist.", "Trying other entries in 'rootDirs'", "Loading 'project/file3' from the root dir 'c:/root/generated/src', candidate location 'c:/root/generated/src/project/file3'", - "File 'c:/root/generated/src/project/file3.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/src/project/file3.ts' exist - use it as a name resolution result.", "======== Module name './project/file3' was successfully resolved to 'c:/root/generated/src/project/file3.ts'. ========", "======== Resolving module '../file2' from 'c:/root/generated/src/project/file3.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -24,6 +24,6 @@ "Trying other entries in 'rootDirs'", "Loading 'file2' from the root dir 'c:/root/src', candidate location 'c:/root/src/file2'", "File 'c:/root/src/file2.ts' does not exist.", - "File 'c:/root/src/file2.d.ts' exist - use it as a module resolution result.", + "File 'c:/root/src/file2.d.ts' exist - use it as a name resolution result.", "======== Module name '../file2' was successfully resolved to 'c:/root/src/file2.d.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution6_node.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution6_node.trace.json index 4ea2f12a63c35..7c5e76a28474e 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution6_node.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution6_node.trace.json @@ -17,7 +17,7 @@ "Trying other entries in 'rootDirs'", "Loading 'project/file3' from the root dir 'c:/root/generated/src', candidate location 'c:/root/generated/src/project/file3'", "Loading module as file / folder, candidate module location 'c:/root/generated/src/project/file3'.", - "File 'c:/root/generated/src/project/file3.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/src/project/file3.ts' exist - use it as a name resolution result.", "======== Module name './project/file3' was successfully resolved to 'c:/root/generated/src/project/file3.ts'. ========", "======== Resolving module '../file2' from 'c:/root/generated/src/project/file3.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -43,6 +43,6 @@ "File 'c:/root/src/file2/package.json' does not exist.", "File 'c:/root/src/file2/index.ts' does not exist.", "File 'c:/root/src/file2/index.tsx' does not exist.", - "File 'c:/root/src/file2/index.d.ts' exist - use it as a module resolution result.", + "File 'c:/root/src/file2/index.d.ts' exist - use it as a name resolution result.", "======== Module name '../file2' was successfully resolved to 'c:/root/src/file2/index.d.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution7_classic.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution7_classic.trace.json index b45cd4754c7ef..2d72108210e21 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution7_classic.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution7_classic.trace.json @@ -10,7 +10,7 @@ "File 'c:/root/src/project/file2.d.ts' does not exist.", "Trying other entries in 'rootDirs'", "Loading 'project/file2' from the root dir 'c:/root/generated/src', candidate location 'c:/root/generated/src/project/file2'", - "File 'c:/root/generated/src/project/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/src/project/file2.ts' exist - use it as a name resolution result.", "======== Module name './project/file2' was successfully resolved to 'c:/root/generated/src/project/file2.ts'. ========", "======== Resolving module 'module3' from 'c:/root/src/file1.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -28,7 +28,7 @@ "File 'c:/root/module3.ts' does not exist.", "File 'c:/root/module3.d.ts' does not exist.", "File 'c:/module3.ts' does not exist.", - "File 'c:/module3.d.ts' exist - use it as a module resolution result.", + "File 'c:/module3.d.ts' exist - use it as a name resolution result.", "======== Module name 'module3' was successfully resolved to 'c:/module3.d.ts'. ========", "======== Resolving module 'module1' from 'c:/root/generated/src/project/file2.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -40,7 +40,7 @@ "File 'c:/root/module1.d.ts' does not exist.", "Trying substitution 'c:/shared/*', candidate module location: 'c:/shared/module1'.", "File 'c:/shared/module1.ts' does not exist.", - "File 'c:/shared/module1.d.ts' exist - use it as a module resolution result.", + "File 'c:/shared/module1.d.ts' exist - use it as a name resolution result.", "======== Module name 'module1' was successfully resolved to 'c:/shared/module1.d.ts'. ========", "======== Resolving module 'templates/module2' from 'c:/root/generated/src/project/file2.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -48,7 +48,7 @@ "'paths' option is specified, looking for a pattern to match module name 'templates/module2'.", "Module name 'templates/module2', matched pattern 'templates/*'.", "Trying substitution 'generated/src/templates/*', candidate module location: 'generated/src/templates/module2'.", - "File 'c:/root/generated/src/templates/module2.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/src/templates/module2.ts' exist - use it as a name resolution result.", "======== Module name 'templates/module2' was successfully resolved to 'c:/root/generated/src/templates/module2.ts'. ========", "======== Resolving module '../file3' from 'c:/root/generated/src/project/file2.ts'. ========", "Module resolution kind is not specified, using 'Classic'.", @@ -62,6 +62,6 @@ "Trying other entries in 'rootDirs'", "Loading 'file3' from the root dir 'c:/root/src', candidate location 'c:/root/src/file3'", "File 'c:/root/src/file3.ts' does not exist.", - "File 'c:/root/src/file3.d.ts' exist - use it as a module resolution result.", + "File 'c:/root/src/file3.d.ts' exist - use it as a name resolution result.", "======== Module name '../file3' was successfully resolved to 'c:/root/src/file3.d.ts'. ========" ] \ No newline at end of file diff --git a/tests/baselines/reference/pathMappingBasedModuleResolution7_node.trace.json b/tests/baselines/reference/pathMappingBasedModuleResolution7_node.trace.json index 39d5c25c92a12..99d4bf244db23 100644 --- a/tests/baselines/reference/pathMappingBasedModuleResolution7_node.trace.json +++ b/tests/baselines/reference/pathMappingBasedModuleResolution7_node.trace.json @@ -17,7 +17,7 @@ "Trying other entries in 'rootDirs'", "Loading 'project/file2' from the root dir 'c:/root/generated/src', candidate location 'c:/root/generated/src/project/file2'", "Loading module as file / folder, candidate module location 'c:/root/generated/src/project/file2'.", - "File 'c:/root/generated/src/project/file2.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/src/project/file2.ts' exist - use it as a name resolution result.", "======== Module name './project/file2' was successfully resolved to 'c:/root/generated/src/project/file2.ts'. ========", "======== Resolving module 'module3' from 'c:/root/src/file1.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -50,6 +50,13 @@ "File 'c:/root/src/node_modules/module3/index.ts' does not exist.", "File 'c:/root/src/node_modules/module3/index.tsx' does not exist.", "File 'c:/root/src/node_modules/module3/index.d.ts' does not exist.", + "File 'c:/root/src/node_modules/@types/module3.ts' does not exist.", + "File 'c:/root/src/node_modules/@types/module3.tsx' does not exist.", + "File 'c:/root/src/node_modules/@types/module3.d.ts' does not exist.", + "File 'c:/root/src/node_modules/@types/module3/package.json' does not exist.", + "File 'c:/root/src/node_modules/@types/module3/index.ts' does not exist.", + "File 'c:/root/src/node_modules/@types/module3/index.tsx' does not exist.", + "File 'c:/root/src/node_modules/@types/module3/index.d.ts' does not exist.", "File 'c:/root/node_modules/module3.ts' does not exist.", "File 'c:/root/node_modules/module3.tsx' does not exist.", "File 'c:/root/node_modules/module3.d.ts' does not exist.", @@ -57,9 +64,16 @@ "File 'c:/root/node_modules/module3/index.ts' does not exist.", "File 'c:/root/node_modules/module3/index.tsx' does not exist.", "File 'c:/root/node_modules/module3/index.d.ts' does not exist.", + "File 'c:/root/node_modules/@types/module3.ts' does not exist.", + "File 'c:/root/node_modules/@types/module3.tsx' does not exist.", + "File 'c:/root/node_modules/@types/module3.d.ts' does not exist.", + "File 'c:/root/node_modules/@types/module3/package.json' does not exist.", + "File 'c:/root/node_modules/@types/module3/index.ts' does not exist.", + "File 'c:/root/node_modules/@types/module3/index.tsx' does not exist.", + "File 'c:/root/node_modules/@types/module3/index.d.ts' does not exist.", "File 'c:/node_modules/module3.ts' does not exist.", "File 'c:/node_modules/module3.tsx' does not exist.", - "File 'c:/node_modules/module3.d.ts' exist - use it as a module resolution result.", + "File 'c:/node_modules/module3.d.ts' exist - use it as a name resolution result.", "======== Module name 'module3' was successfully resolved to 'c:/node_modules/module3.d.ts'. ========", "======== Resolving module 'module1' from 'c:/root/generated/src/project/file2.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -83,7 +97,7 @@ "File 'c:/shared/module1/package.json' does not exist.", "File 'c:/shared/module1/index.ts' does not exist.", "File 'c:/shared/module1/index.tsx' does not exist.", - "File 'c:/shared/module1/index.d.ts' exist - use it as a module resolution result.", + "File 'c:/shared/module1/index.d.ts' exist - use it as a name resolution result.", "======== Module name 'module1' was successfully resolved to 'c:/shared/module1/index.d.ts'. ========", "======== Resolving module 'templates/module2' from 'c:/root/generated/src/project/file2.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -92,7 +106,7 @@ "Module name 'templates/module2', matched pattern 'templates/*'.", "Trying substitution 'generated/src/templates/*', candidate module location: 'generated/src/templates/module2'.", "Loading module as file / folder, candidate module location 'c:/root/generated/src/templates/module2'.", - "File 'c:/root/generated/src/templates/module2.ts' exist - use it as a module resolution result.", + "File 'c:/root/generated/src/templates/module2.ts' exist - use it as a name resolution result.", "======== Module name 'templates/module2' was successfully resolved to 'c:/root/generated/src/templates/module2.ts'. ========", "======== Resolving module '../file3' from 'c:/root/generated/src/project/file2.ts'. ========", "Module resolution kind is not specified, using 'NodeJs'.", @@ -118,6 +132,6 @@ "File 'c:/root/src/file3/package.json' does not exist.", "File 'c:/root/src/file3/index.ts' does not exist.", "File 'c:/root/src/file3/index.tsx' does not exist.", - "File 'c:/root/src/file3/index.d.ts' exist - use it as a module resolution result.", + "File 'c:/root/src/file3/index.d.ts' exist - use it as a name resolution result.", "======== Module name '../file3' was successfully resolved to 'c:/root/src/file3/index.d.ts'. ========" ] \ No newline at end of file diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution1_classic.ts b/tests/cases/compiler/pathMappingBasedModuleResolution1_classic.ts index 20845a49372ab..054d6ed8a0b68 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution1_classic.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution1_classic.ts @@ -1,5 +1,5 @@ // @module: amd -// @traceModuleResolution: true +// @traceResolution: true // paths should error in the absence of baseurl diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution1_node.ts b/tests/cases/compiler/pathMappingBasedModuleResolution1_node.ts index 392e85bd7c39c..a0ce95f2c1a7f 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution1_node.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution1_node.ts @@ -1,5 +1,5 @@ // @module: commonjs -// @traceModuleResolution: true +// @traceResolution: true // paths should error in the absence of baseurl // @filename: c:/root/tsconfig.json diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution2_classic.ts b/tests/cases/compiler/pathMappingBasedModuleResolution2_classic.ts index 6c84a197eeb13..f24e857fa416f 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution2_classic.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution2_classic.ts @@ -1,5 +1,5 @@ // @module: amd -// @traceModuleResolution: true +// @traceResolution: true // baseurl is defined in tsconfig.json // paths has errors diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution2_node.ts b/tests/cases/compiler/pathMappingBasedModuleResolution2_node.ts index 78ef7215e737e..ac4d51bacf50d 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution2_node.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution2_node.ts @@ -1,5 +1,5 @@ // @module: commonjs -// @traceModuleResolution: true +// @traceResolution: true // baseurl is defined in tsconfig.json // paths has errors diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution3_classic.ts b/tests/cases/compiler/pathMappingBasedModuleResolution3_classic.ts index d46308d089fb0..350346adebcf0 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution3_classic.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution3_classic.ts @@ -1,7 +1,7 @@ // @moduleResolution: classic // @module: amd // @baseUrl: c:/root -// @traceModuleResolution: true +// @traceResolution: true // baseUrl set via command line diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution3_node.ts b/tests/cases/compiler/pathMappingBasedModuleResolution3_node.ts index 30e95c9303ee6..6cab1df06b064 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution3_node.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution3_node.ts @@ -1,7 +1,7 @@ // @moduleResolution: node // @module: commonjs // @baseUrl: c:/root -// @traceModuleResolution: true +// @traceResolution: true // baseUrl set via command line diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution4_classic.ts b/tests/cases/compiler/pathMappingBasedModuleResolution4_classic.ts index 723de05b70c14..fbf11e6171646 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution4_classic.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution4_classic.ts @@ -1,6 +1,6 @@ // @moduleResolution: classic // @module: amd -// @traceModuleResolution: true +// @traceResolution: true // baseUrl set via command line diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution4_node.ts b/tests/cases/compiler/pathMappingBasedModuleResolution4_node.ts index e68635e205e57..cfb90ca1cc5c0 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution4_node.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution4_node.ts @@ -1,6 +1,6 @@ // @moduleResolution: node // @module: commonjs -// @traceModuleResolution: true +// @traceResolution: true // baseUrl set via command line diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution5_classic.ts b/tests/cases/compiler/pathMappingBasedModuleResolution5_classic.ts index a7662688e373a..9779f0ca64494 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution5_classic.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution5_classic.ts @@ -1,5 +1,5 @@ // @module: amd -// @traceModuleResolution: true +// @traceResolution: true // paths is defined in tsconfig.json // @filename: c:/root/tsconfig.json diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution5_node.ts b/tests/cases/compiler/pathMappingBasedModuleResolution5_node.ts index ef5ef0afd6a52..3606ab08cd10c 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution5_node.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution5_node.ts @@ -1,5 +1,5 @@ // @module: commonjs -// @traceModuleResolution: true +// @traceResolution: true // paths is defined in tsconfig.json // @filename: c:/root/tsconfig.json diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution6_classic.ts b/tests/cases/compiler/pathMappingBasedModuleResolution6_classic.ts index adaba8478c997..5ce4bd2a18f54 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution6_classic.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution6_classic.ts @@ -1,5 +1,5 @@ // @module: amd -// @traceModuleResolution: true +// @traceResolution: true // @filename: c:/root/src/tsconfig.json { diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution6_node.ts b/tests/cases/compiler/pathMappingBasedModuleResolution6_node.ts index a3d0feadf7c9e..29a82e5412d9e 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution6_node.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution6_node.ts @@ -1,5 +1,5 @@ // @module: commonjs -// @traceModuleResolution: true +// @traceResolution: true // @filename: c:/root/src/tsconfig.json { diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution7_classic.ts b/tests/cases/compiler/pathMappingBasedModuleResolution7_classic.ts index af092df5ce95f..81c2328df670f 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution7_classic.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution7_classic.ts @@ -1,5 +1,5 @@ // @module: amd -// @traceModuleResolution: true +// @traceResolution: true // @filename: c:/root/src/tsconfig.json { diff --git a/tests/cases/compiler/pathMappingBasedModuleResolution7_node.ts b/tests/cases/compiler/pathMappingBasedModuleResolution7_node.ts index faecbe4adb91e..1ba9630e0cfab 100644 --- a/tests/cases/compiler/pathMappingBasedModuleResolution7_node.ts +++ b/tests/cases/compiler/pathMappingBasedModuleResolution7_node.ts @@ -1,5 +1,5 @@ // @module: commonjs -// @traceModuleResolution: true +// @traceResolution: true // @filename: c:/root/src/tsconfig.json { diff --git a/tests/cases/conformance/references/library-reference-1.ts b/tests/cases/conformance/references/library-reference-1.ts new file mode 100644 index 0000000000000..ca25441521fcc --- /dev/null +++ b/tests/cases/conformance/references/library-reference-1.ts @@ -0,0 +1,13 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @typesRoot: / + +// We can find typings in the ./types folder + +// @filename: /types/jquery/index.d.ts +declare var $: { foo(): void }; + + +// @filename: /consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-10.ts b/tests/cases/conformance/references/library-reference-10.ts new file mode 100644 index 0000000000000..11e065b0a7db9 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-10.ts @@ -0,0 +1,18 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @typesRoot: / + +// package.json in a primary reference can refer to another file + +// @filename: /types/jquery/package.json +{ + "typings": "jquery.d.ts" +} + +// @filename: /types/jquery/jquery.d.ts +declare var $: { foo(): void }; + + +// @filename: /consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-11.ts b/tests/cases/conformance/references/library-reference-11.ts new file mode 100644 index 0000000000000..39c8af5654311 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-11.ts @@ -0,0 +1,17 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// package.json in a secondary reference can refer to another file + +// @filename: /a/node_modules/jquery/package.json +{ + "typings": "jquery.d.ts" +} + +// @filename: /a/node_modules/jquery/jquery.d.ts +declare var $: { foo(): void }; + + +// @filename: /a/b/consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-12.ts b/tests/cases/conformance/references/library-reference-12.ts new file mode 100644 index 0000000000000..c61d6d916ff16 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-12.ts @@ -0,0 +1,17 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// package.json in a secondary reference can refer to another file + +// @filename: /a/node_modules/jquery/package.json +{ + "types": "dist/jquery.d.ts" +} + +// @filename: /a/node_modules/jquery/dist/jquery.d.ts +declare var $: { foo(): void }; + + +// @filename: /a/b/consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-13.ts b/tests/cases/conformance/references/library-reference-13.ts new file mode 100644 index 0000000000000..a96437f9b2c3b --- /dev/null +++ b/tests/cases/conformance/references/library-reference-13.ts @@ -0,0 +1,18 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// load type declarations from types section of tsconfig + +// @filename: /a/tsconfig.json +{ + "compilerOptions": { + "types": [ "jquery" ] + } +} + +// @filename: /a/types/jquery/index.d.ts +declare var $: { foo(): void }; + + +// @filename: /a/b/consumer.ts +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-14.ts b/tests/cases/conformance/references/library-reference-14.ts new file mode 100644 index 0000000000000..53bca2ab40d16 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-14.ts @@ -0,0 +1,11 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @types: jquery +// @typesRoot: /a + +// @filename: /a/types/jquery/index.d.ts +declare var $: { foo(): void }; + + +// @filename: /a/b/consumer.ts +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-15.ts b/tests/cases/conformance/references/library-reference-15.ts new file mode 100644 index 0000000000000..92c96e74c9795 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-15.ts @@ -0,0 +1,10 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @types: jquery + +// @filename: /a/types/jquery/index.d.ts +declare var $: { foo(): void }; + + +// @filename: /a/b/consumer.ts +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-2.ts b/tests/cases/conformance/references/library-reference-2.ts new file mode 100644 index 0000000000000..d8975664428cb --- /dev/null +++ b/tests/cases/conformance/references/library-reference-2.ts @@ -0,0 +1,18 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @typesRoot: / + +// package.json in a primary reference can refer to another file + +// @filename: /types/jquery/package.json +{ + "types": "jquery.d.ts" +} + +// @filename: /types/jquery/jquery.d.ts +declare var $: { foo(): void }; + + +// @filename: /consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-3.ts b/tests/cases/conformance/references/library-reference-3.ts new file mode 100644 index 0000000000000..1af6df89d19d6 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-3.ts @@ -0,0 +1,12 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @typesRoot: /src + +// Secondary references are possible + +// @filename: /src/node_modules/jquery/index.d.ts +declare var $: { foo(): void }; + +// @filename: /src/consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-4.ts b/tests/cases/conformance/references/library-reference-4.ts new file mode 100644 index 0000000000000..92f1b4008beb6 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-4.ts @@ -0,0 +1,23 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @typesRoot: /src + +// Secondary references may be duplicated if they agree in content + +// @filename: /node_modules/foo/index.d.ts +/// +declare var foo: any; + +// @filename: /node_modules/foo/node_modules/alpha/index.d.ts +declare var alpha: any; + +// @filename: /node_modules/bar/index.d.ts +/// +declare var bar: any; + +// @filename: /node_modules/bar/node_modules/alpha/index.d.ts +declare var alpha: any; + +// @filename: /src/root.ts +/// +/// diff --git a/tests/cases/conformance/references/library-reference-5.ts b/tests/cases/conformance/references/library-reference-5.ts new file mode 100644 index 0000000000000..4660da00a2a20 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-5.ts @@ -0,0 +1,22 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// Secondary references may not be duplicated if they disagree in content + +// @filename: /node_modules/foo/index.d.ts +/// +declare var foo: any; + +// @filename: /node_modules/foo/node_modules/alpha/index.d.ts +declare var alpha: any; + +// @filename: /node_modules/bar/index.d.ts +/// +declare var bar: any; + +// @filename: /node_modules/bar/node_modules/alpha/index.d.ts +declare var alpha: {}; + +// @filename: /src/root.ts +/// +/// diff --git a/tests/cases/conformance/references/library-reference-6.ts b/tests/cases/conformance/references/library-reference-6.ts new file mode 100644 index 0000000000000..a746262dd73b1 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-6.ts @@ -0,0 +1,15 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// The primary lookup folder is relative to tsconfig.json, if present + +// @filename: /types/alpha/index.d.ts +declare var alpha: { a: string }; + +// @filename: /src/foo.ts +/// +var x: string = alpha.a; + +// @filename: /tsconfig.json +{ +} diff --git a/tests/cases/conformance/references/library-reference-7.ts b/tests/cases/conformance/references/library-reference-7.ts new file mode 100644 index 0000000000000..e938aef7d3a68 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-7.ts @@ -0,0 +1,11 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// Secondary references are possible + +// @filename: /src/node_modules/jquery/index.d.ts +declare var $: { foo(): void }; + +// @filename: /src/consumer.ts +/// +$.foo(); diff --git a/tests/cases/conformance/references/library-reference-8.ts b/tests/cases/conformance/references/library-reference-8.ts new file mode 100644 index 0000000000000..9de93776989b5 --- /dev/null +++ b/tests/cases/conformance/references/library-reference-8.ts @@ -0,0 +1,19 @@ +// @noImplicitReferences: true +// @traceResolution: true +// @typesRoot: / + +// Don't crash in circular library reference situations + +// @filename: /types/alpha/index.d.ts +/// +declare var alpha: { a: string }; + +// @filename: /types/beta/index.d.ts +/// +declare var beta: { b: string }; + +// @filename: /foo.ts +/// +/// +var x: string = alpha.a + beta.b; + diff --git a/tests/cases/conformance/references/library-reference-9.ts b/tests/cases/conformance/references/library-reference-9.ts new file mode 100644 index 0000000000000..a187d3c23b91f --- /dev/null +++ b/tests/cases/conformance/references/library-reference-9.ts @@ -0,0 +1,20 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// Use types search path + +// @filename: /share/typelib/alpha/index.d.ts +declare var alpha: { a: string }; + +// @filename: /base/src/foo.ts +/// +var x: string = alpha.a; + +// @filename: /tsconfig.json +{ + "compilerOptions": { + "typesSearchPaths": [ + "./share/typelib" + ] + } +} diff --git a/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts new file mode 100644 index 0000000000000..3aaa3ab980f08 --- /dev/null +++ b/tests/cases/fourslash/goToDefinitionTypeReferenceDirective.ts @@ -0,0 +1,13 @@ +/// + +// @typesRoot: src +// @Filename: src/types/lib/index.d.ts +/////*0*/declare let $: {x: number}; + +// @Filename: src/app.ts +//// /// +//// $.x; + +goTo.marker("1"); +goTo.definition(); +verify.caretAtMarker("0"); \ No newline at end of file diff --git a/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts new file mode 100644 index 0000000000000..3aaa3ab980f08 --- /dev/null +++ b/tests/cases/fourslash/shims-pp/goToDefinitionTypeReferenceDirective.ts @@ -0,0 +1,13 @@ +/// + +// @typesRoot: src +// @Filename: src/types/lib/index.d.ts +/////*0*/declare let $: {x: number}; + +// @Filename: src/app.ts +//// /// +//// $.x; + +goTo.marker("1"); +goTo.definition(); +verify.caretAtMarker("0"); \ No newline at end of file diff --git a/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts b/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts new file mode 100644 index 0000000000000..3aaa3ab980f08 --- /dev/null +++ b/tests/cases/fourslash/shims/goToDefinitionTypeReferenceDirective.ts @@ -0,0 +1,13 @@ +/// + +// @typesRoot: src +// @Filename: src/types/lib/index.d.ts +/////*0*/declare let $: {x: number}; + +// @Filename: src/app.ts +//// /// +//// $.x; + +goTo.marker("1"); +goTo.definition(); +verify.caretAtMarker("0"); \ No newline at end of file diff --git a/tests/cases/unittests/convertToBase64.ts b/tests/cases/unittests/convertToBase64.ts index 76f56f7747779..c73d7531c405b 100644 --- a/tests/cases/unittests/convertToBase64.ts +++ b/tests/cases/unittests/convertToBase64.ts @@ -8,26 +8,28 @@ module ts { assert.equal(actual, expected, "Encoded string using convertToBase64 does not match buffer.toString('base64')"); } - it("Converts ASCII charaters correctly", () => { - runTest(" !\"#$ %&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); - }); + if (Buffer) { + it("Converts ASCII charaters correctly", () => { + runTest(" !\"#$ %&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"); + }); - it("Converts escape sequences correctly", () => { - runTest("\t\n\r\\\"\'\u0062"); - }); + it("Converts escape sequences correctly", () => { + runTest("\t\n\r\\\"\'\u0062"); + }); - it("Converts simple unicode characters correctly", () => { - runTest("ΠΣ ٵپ औठ ⺐⺠"); - }); + it("Converts simple unicode characters correctly", () => { + runTest("ΠΣ ٵپ औठ ⺐⺠"); + }); - it("Converts simple code snippet correctly", () => { - runTest(`/// + it("Converts simple code snippet correctly", () => { + runTest(`/// var x: string = "string"; console.log(x);`); - }); + }); - it("Converts simple code snippet with unicode characters correctly", () => { - runTest(`var Π = 3.1415; console.log(Π);`); - }); + it("Converts simple code snippet with unicode characters correctly", () => { + runTest(`var Π = 3.1415; console.log(Π);`); + }); + } }); } diff --git a/tests/cases/unittests/moduleResolution.ts b/tests/cases/unittests/moduleResolution.ts index 9a52d9896e490..29fde3318928d 100644 --- a/tests/cases/unittests/moduleResolution.ts +++ b/tests/cases/unittests/moduleResolution.ts @@ -204,6 +204,13 @@ module ts { "/a/b/c/d/node_modules/foo/index.ts", "/a/b/c/d/node_modules/foo/index.tsx", "/a/b/c/d/node_modules/foo/index.d.ts", + "/a/b/c/d/node_modules/@types/foo.ts", + "/a/b/c/d/node_modules/@types/foo.tsx", + "/a/b/c/d/node_modules/@types/foo.d.ts", + "/a/b/c/d/node_modules/@types/foo/package.json", + "/a/b/c/d/node_modules/@types/foo/index.ts", + "/a/b/c/d/node_modules/@types/foo/index.tsx", + "/a/b/c/d/node_modules/@types/foo/index.d.ts", "/a/b/c/node_modules/foo.ts", "/a/b/c/node_modules/foo.tsx", "/a/b/c/node_modules/foo.d.ts", @@ -211,6 +218,13 @@ module ts { "/a/b/c/node_modules/foo/index.ts", "/a/b/c/node_modules/foo/index.tsx", "/a/b/c/node_modules/foo/index.d.ts", + "/a/b/c/node_modules/@types/foo.ts", + "/a/b/c/node_modules/@types/foo.tsx", + "/a/b/c/node_modules/@types/foo.d.ts", + "/a/b/c/node_modules/@types/foo/package.json", + "/a/b/c/node_modules/@types/foo/index.ts", + "/a/b/c/node_modules/@types/foo/index.tsx", + "/a/b/c/node_modules/@types/foo/index.d.ts", ]) } }); @@ -246,6 +260,13 @@ module ts { "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts", "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx", "/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts", + "/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.ts", + "/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.tsx", + "/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts", + "/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/package.json", + "/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.ts", + "/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.tsx", + "/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.d.ts", "/a/node_modules/b/c/node_modules/foo.ts", "/a/node_modules/b/c/node_modules/foo.tsx", "/a/node_modules/b/c/node_modules/foo.d.ts", @@ -253,6 +274,13 @@ module ts { "/a/node_modules/b/c/node_modules/foo/index.ts", "/a/node_modules/b/c/node_modules/foo/index.tsx", "/a/node_modules/b/c/node_modules/foo/index.d.ts", + "/a/node_modules/b/c/node_modules/@types/foo.ts", + "/a/node_modules/b/c/node_modules/@types/foo.tsx", + "/a/node_modules/b/c/node_modules/@types/foo.d.ts", + "/a/node_modules/b/c/node_modules/@types/foo/package.json", + "/a/node_modules/b/c/node_modules/@types/foo/index.ts", + "/a/node_modules/b/c/node_modules/@types/foo/index.tsx", + "/a/node_modules/b/c/node_modules/@types/foo/index.d.ts", "/a/node_modules/b/node_modules/foo.ts", "/a/node_modules/b/node_modules/foo.tsx", "/a/node_modules/b/node_modules/foo.d.ts", @@ -260,6 +288,13 @@ module ts { "/a/node_modules/b/node_modules/foo/index.ts", "/a/node_modules/b/node_modules/foo/index.tsx", "/a/node_modules/b/node_modules/foo/index.d.ts", + "/a/node_modules/b/node_modules/@types/foo.ts", + "/a/node_modules/b/node_modules/@types/foo.tsx", + "/a/node_modules/b/node_modules/@types/foo.d.ts", + "/a/node_modules/b/node_modules/@types/foo/package.json", + "/a/node_modules/b/node_modules/@types/foo/index.ts", + "/a/node_modules/b/node_modules/@types/foo/index.tsx", + "/a/node_modules/b/node_modules/@types/foo/index.d.ts", "/a/node_modules/foo.ts", "/a/node_modules/foo.tsx", "/a/node_modules/foo.d.ts", @@ -267,7 +302,6 @@ module ts { "/a/node_modules/foo/index.ts", "/a/node_modules/foo/index.tsx" ]); - } }); }); @@ -664,6 +698,13 @@ import b = require("./moduleB.ts"); "/root/folder1/node_modules/file6/index.ts", "/root/folder1/node_modules/file6/index.tsx", "/root/folder1/node_modules/file6/index.d.ts", + "/root/folder1/node_modules/@types/file6.ts", + "/root/folder1/node_modules/@types/file6.tsx", + "/root/folder1/node_modules/@types/file6.d.ts", + "/root/folder1/node_modules/@types/file6/package.json", + "/root/folder1/node_modules/@types/file6/index.ts", + "/root/folder1/node_modules/@types/file6/index.tsx", + "/root/folder1/node_modules/@types/file6/index.d.ts" // success on /root/node_modules/file6.ts ]); @@ -913,4 +954,119 @@ import b = require("./moduleB.ts"); assert(!result.resolvedModule); }); }); + + describe("Type reference directive resolution: ", () => { + function test(typesRoot: string, typeDirective: string, primary: boolean, initialFile: File, targetFile: File, ...otherFiles: File[]) { + const host = createModuleResolutionHost(false, ...[initialFile, targetFile].concat(...otherFiles)); + const result = resolveTypeReferenceDirective(typeDirective, initialFile.name, {typesRoot}, host); + assert(result.resolvedTypeReferenceDirective.resolvedFileName !== undefined, "expected type directive to be resolved"); + assert.equal(result.resolvedTypeReferenceDirective.resolvedFileName, targetFile.name, "unexpected result of type reference resolution"); + assert.equal(result.resolvedTypeReferenceDirective.primary, primary, "unexpected 'primary' value"); + } + + it("Can be resolved from primary location", () => { + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/src/types/lib/index.d.ts" }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/src/types/lib/typings/lib.d.ts" }; + const package = { name: "/root/src/types/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, package); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/src/node_modules/lib/index.d.ts" }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/src/node_modules/lib/typings/lib.d.ts" }; + const package = { name: "/root/src/node_modules/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, package); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/src/node_modules/@types/lib/index.d.ts" }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/src/node_modules/@types/lib/typings/lib.d.ts" }; + const package = { name: "/root/src/node_modules/@types/lib/package.json", content: JSON.stringify({types: "typings/lib.d.ts"}) }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, package); + } + }); + it("Can be resolved from secondary location", () => { + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/node_modules/lib.d.ts" }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/node_modules/lib/index.d.ts" }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/node_modules/lib/typings/lib.d.ts" }; + const package = { name: "/root/node_modules/lib/package.json", content: JSON.stringify({typings: "typings/lib.d.ts"}) }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2, package); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/node_modules/@types/lib/index.d.ts" }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2); + } + { + const f1 = { name: "/root/src/app.ts" } + const f2 = { name: "/root/node_modules/@types/lib/typings/lib.d.ts" }; + const package = { name: "/root/node_modules/@types/lib/package.json", content: JSON.stringify({typings: "typings/lib.d.ts"}) }; + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ false, f1, f2, package); + } + }); + it("Primary resolution overrides secondary resolutions", () => { + { + const f1 = { name: "/root/src/a/b/c/app.ts" }; + const f2 = { name: "/root/src/types/lib/index.d.ts" }; + const f3 = { name: "/root/src/a/b/node_modules/lib.d.ts" } + test(/*typesRoot*/"/root/src", /* typeDirective */"lib", /*primary*/ true, f1, f2, f3); + } + }) + it("Reused program keeps errors", () => { + const f1 = { name: "/root/src/a/b/c/d/e/app.ts", content: `/// ` }; + const f2 = { name: "/root/src/a/b/c/d/node_modules/lib/index.d.ts", content: `declare var x: number;` }; + const f3 = { name: "/root/src/a/b/c/d/f/g/app.ts", content: `/// ` }; + const f4 = { name: "/root/src/a/b/c/d/f/node_modules/lib/index.d.ts", content: `declare var x: number;` }; + const files = [f1, f2, f3, f4]; + + const names = map(files, f => f.name); + const sourceFiles = arrayToMap(map(files, f => createSourceFile(f.name, f.content, ScriptTarget.ES6)), f => f.fileName); + const compilerHost: CompilerHost = { + fileExists : fileName => hasProperty(sourceFiles, fileName), + getSourceFile: fileName => sourceFiles[fileName], + getDefaultLibFileName: () => "lib.d.ts", + writeFile(file, text) { + throw new Error("NYI"); + }, + getCurrentDirectory: () => "/", + getCanonicalFileName: f => f.toLowerCase(), + getNewLine: () => "\r\n", + useCaseSensitiveFileNames: () => false, + readFile: fileName => hasProperty(sourceFiles, fileName) ? sourceFiles[fileName].text : undefined + }; + const program1 = createProgram(names, {}, compilerHost); + const diagnostics1 = program1.getFileProcessingDiagnostics().getDiagnostics(); + assert.equal(diagnostics1.length, 1, "expected one diagnostic"); + + const program2 = createProgram(names, {}, compilerHost, program1); + assert.isTrue(program1.structureIsReused); + const diagnostics2 = program1.getFileProcessingDiagnostics().getDiagnostics(); + assert.equal(diagnostics2.length, 1, "expected one diagnostic"); + assert.equal(diagnostics1[0].messageText, diagnostics2[0].messageText, "expected one diagnostic"); + }) + }); } \ No newline at end of file diff --git a/tests/cases/unittests/reuseProgramStructure.ts b/tests/cases/unittests/reuseProgramStructure.ts index 5f313eeae2b32..036a58e0c99bd 100644 --- a/tests/cases/unittests/reuseProgramStructure.ts +++ b/tests/cases/unittests/reuseProgramStructure.ts @@ -118,13 +118,13 @@ module ts { return ""; }, getCanonicalFileName(fileName): string { - return sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); + return sys && sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); }, useCaseSensitiveFileNames(): boolean { - return sys.useCaseSensitiveFileNames; + return sys && sys.useCaseSensitiveFileNames; }, getNewLine(): string { - return sys.newLine; + return sys ? sys.newLine : newLine; }, fileExists: fileName => hasProperty(files, fileName), readFile: fileName => { @@ -160,36 +160,55 @@ module ts { return size; } - function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map): void { + function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): void { + 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, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`); + } + + function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): void { + assert.isTrue(actual !== undefined); + assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`); + assert.isTrue(expected.primary === actual.primary, `'primary': expected '${expected.primary}' to be equal to '${actual.primary}'`); + } + + function checkCache(caption: string, program: Program, fileName: string, expectedContent: Map, getCache: (f: SourceFile) => Map, entryChecker: (expected: T, original:T) => void): void { let file = program.getSourceFile(fileName); assert.isTrue(file !== undefined, `cannot find file ${fileName}`); + const cache = getCache(file) if (expectedContent === undefined) { - assert.isTrue(file.resolvedModules === undefined, "expected resolvedModules to be undefined"); + assert.isTrue(cache === undefined, `expected ${caption} to be undefined`); } else { - assert.isTrue(file.resolvedModules !== undefined, "expected resolvedModuled to be set"); - let actualCacheSize = getSizeOfMap(file.resolvedModules); + assert.isTrue(cache !== undefined, `expected ${caption} to be set`); + let actualCacheSize = getSizeOfMap(cache); let expectedSize = getSizeOfMap(expectedContent); assert.isTrue(actualCacheSize === expectedSize, `expected actual size: ${actualCacheSize} to be equal to ${expectedSize}`); for (let id in expectedContent) { if (hasProperty(expectedContent, id)) { - assert.isTrue(hasProperty(file.resolvedModules, id), `expected ${id} to be found in resolved modules`); + 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); + const actual = cache[id]; + entryChecker(expected, actual); } } + else { + assert.isTrue(cache[id] === undefined); + } } } } + function checkResolvedModulesCache(program: Program, fileName: string, expectedContent: Map): void { + checkCache("resolved modules", program, fileName, expectedContent, f => f.resolvedModules, checkResolvedModule); + } + + function checkResolvedTypeDirectivesCache(program: Program, fileName: string, expectedContent: Map): void { + checkCache("resolved type directives", program, fileName, expectedContent, f => f.resolvedTypeReferenceDirectiveNames, checkResolvedTypeDirective); + } + describe("Reuse program structure", () => { let target = ScriptTarget.Latest; let files = [ @@ -197,9 +216,11 @@ module ts { ` /// /// +/// `, "",`var x = 1`) }, { name: "b.ts", text: SourceText.New(`/// `, "", `var y = 2`) }, { name: "c.ts", text: SourceText.New("", "", `var z = 1;`) }, + { name: "types/typerefs/index.d.ts", text: SourceText.New("", "", `declare let z: number;`) }, ] it("successful if change does not affect imports", () => { @@ -213,6 +234,17 @@ module ts { assert.equal(program1Diagnostics.length, program2Diagnostics.length); }); + it("successful if change does not affect type reference directives", () => { + var program_1 = newProgram(files, ["a.ts"], { target }); + var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => { + files[0].text = files[0].text.updateProgram("var x = 100"); + }); + assert.isTrue(program_1.structureIsReused); + let program1Diagnostics = program_1.getSemanticDiagnostics(program_1.getSourceFile("a.ts")) + let program2Diagnostics = program_2.getSemanticDiagnostics(program_1.getSourceFile("a.ts")) + assert.equal(program1Diagnostics.length, program2Diagnostics.length); + }); + it("fails if change affects tripleslash references", () => { var program_1 = newProgram(files, ["a.ts"], { target }); var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => { @@ -232,11 +264,35 @@ module ts { assert.isTrue(!program_1.structureIsReused); }); + it("fails if change affects type directives", () => { + var program_1 = newProgram(files, ["a.ts"], { target }); + var program_2 = updateProgram(program_1, ["a.ts"], { target }, files => { + let newReferences = ` +/// +/// +/// `; + files[0].text = files[0].text.updateReferences(newReferences); + }); + assert.isTrue(!program_1.structureIsReused); + }); + it("fails if module kind changes", () => { var program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS }); var program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, files => void 0); assert.isTrue(!program_1.structureIsReused); }); + + it("fails if rootdir changes", () => { + var program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" }); + var program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, files => void 0); + assert.isTrue(!program_1.structureIsReused); + }); + + it("fails if config path changes", () => { + var program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" }); + var program_2 = updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, files => void 0); + assert.isTrue(!program_1.structureIsReused); + }); it("resolution cache follows imports", () => { let files = [ @@ -274,5 +330,43 @@ module ts { assert.isTrue(!program_3.structureIsReused); checkResolvedModulesCache(program_4, "a.ts", { "b": { resolvedFileName: "b.ts" }, "c": undefined }); }); + + it("resolved type directives cache follows type directives", () => { + let files = [ + { name: "/a.ts", text: SourceText.New("/// ", "", "var x = $") }, + { name: "/types/typedefs/index.d.ts", text: SourceText.New("", "", "declare var $: number") }, + ]; + var options: CompilerOptions = { target, typesRoot: "/" }; + + var program_1 = newProgram(files, ["/a.ts"], options); + checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }); + checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined); + + var program_2 = updateProgram(program_1, ["/a.ts"], options, files => { + files[0].text = files[0].text.updateProgram("var x = 2"); + }); + assert.isTrue(program_1.structureIsReused); + + // content of resolution cache should not change + checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }); + checkResolvedTypeDirectivesCache(program_1, "/types/typedefs/index.d.ts", undefined); + + // type reference directives has changed - program is not reused + var program_3 = updateProgram(program_2, ["/a.ts"], options, files => { + files[0].text = files[0].text.updateReferences(""); + }); + + assert.isTrue(!program_2.structureIsReused); + checkResolvedTypeDirectivesCache(program_3, "/a.ts", undefined); + + var program_4 = updateProgram(program_3, ["/a.ts"], options, files => { + let newReferences = `/// + /// + `; + files[0].text = files[0].text.updateReferences(newReferences); + }); + assert.isTrue(!program_3.structureIsReused); + checkResolvedTypeDirectivesCache(program_1, "/a.ts", { "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }); + }); }) } \ No newline at end of file diff --git a/tests/cases/unittests/services/preProcessFile.ts b/tests/cases/unittests/services/preProcessFile.ts index a648a3c4b26fb..7fa25b440c557 100644 --- a/tests/cases/unittests/services/preProcessFile.ts +++ b/tests/cases/unittests/services/preProcessFile.ts @@ -9,18 +9,11 @@ describe('PreProcessFile:', function () { function test(sourceText: string, readImportFile: boolean, detectJavaScriptImports: boolean, expectedPreProcess: ts.PreProcessedFileInfo): void { var resultPreProcess = ts.preProcessFile(sourceText, readImportFile, detectJavaScriptImports); - var resultIsLibFile = resultPreProcess.isLibFile; - var resultImportedFiles = resultPreProcess.importedFiles; - var resultReferencedFiles = resultPreProcess.referencedFiles; + assert.equal(resultPreProcess.isLibFile, expectedPreProcess.isLibFile, "Pre-processed file has different value for isLibFile. Expected: " + expectedPreProcess.isLibFile + ". Actual: " + resultPreProcess.isLibFile); - var expectedIsLibFile = expectedPreProcess.isLibFile; - var expectedImportedFiles = expectedPreProcess.importedFiles; - var expectedReferencedFiles = expectedPreProcess.referencedFiles; - - assert.equal(resultIsLibFile, expectedIsLibFile, "Pre-processed file has different value for isLibFile. Expected: " + expectedPreProcess + ". Actual: " + resultIsLibFile); - - checkFileReferenceList("Imported files", expectedImportedFiles, resultImportedFiles); - checkFileReferenceList("Referenced files", expectedReferencedFiles, resultReferencedFiles); + checkFileReferenceList("Imported files", expectedPreProcess.importedFiles, resultPreProcess.importedFiles); + checkFileReferenceList("Referenced files", expectedPreProcess.referencedFiles, resultPreProcess.referencedFiles); + checkFileReferenceList("Type reference directives", expectedPreProcess.typeReferenceDirectives, resultPreProcess.typeReferenceDirectives); assert.deepEqual(resultPreProcess.ambientExternalModules, expectedPreProcess.ambientExternalModules); } @@ -52,6 +45,7 @@ describe('PreProcessFile:', function () { referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 37 }, { fileName: "refFile2.ts", pos: 38, end: 73 }, { fileName: "refFile3.ts", pos: 74, end: 109 }, { fileName: "..\\refFile4d.ts", pos: 110, end: 150 }], importedFiles: [], + typeReferenceDirectives: [], ambientExternalModules: undefined, isLibFile: false }); @@ -64,6 +58,7 @@ describe('PreProcessFile:', function () { { referencedFiles: [], importedFiles: [], + typeReferenceDirectives: [], ambientExternalModules: undefined, isLibFile: false }); @@ -75,6 +70,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [{ fileName: "r1.ts", pos: 20, end: 25 }, { fileName: "r2.ts", pos: 49, end: 54 }, { fileName: "r3.ts", pos: 78, end: 83 }, { fileName: "r4.ts", pos: 106, end: 111 }, { fileName: "r5.ts", pos: 138, end: 143 }], ambientExternalModules: undefined, @@ -88,6 +84,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [], ambientExternalModules: undefined, isLibFile: false @@ -100,6 +97,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [{ fileName: "r3.ts", pos: 73, end: 78 }], ambientExternalModules: undefined, isLibFile: false @@ -112,6 +110,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }, { fileName: "refFile2.ts", pos: 36, end: 71 }], + typeReferenceDirectives: [], importedFiles: [{ fileName: "r1.ts", pos: 92, end: 97 }, { fileName: "r2.ts", pos: 121, end: 126 }], ambientExternalModules: undefined, isLibFile: false @@ -124,6 +123,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [{ fileName: "refFile1.ts", pos: 0, end: 35 }], + typeReferenceDirectives: [], importedFiles: [{ fileName: "r1.ts", pos: 91, end: 96 }, { fileName: "r3.ts", pos: 148, end: 153 }], ambientExternalModules: undefined, isLibFile: false @@ -142,6 +142,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { fileName: "m1", pos: 20, end: 22 }, { fileName: "m2", pos: 51, end: 53 }, @@ -165,6 +166,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { fileName: "m1", pos: 14, end: 16 }, { fileName: "m2", pos: 36, end: 38 }, @@ -188,6 +190,7 @@ describe('PreProcessFile:', function () { { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [], ambientExternalModules: ["B"], isLibFile: false @@ -200,6 +203,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { fileName: "m1", pos: 26, end: 28 } ], @@ -218,6 +222,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ true, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { fileName: "m1", pos: 39, end: 41 }, { fileName: "m2", pos: 74, end: 76 }, @@ -237,6 +242,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ true, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { fileName: "mod1", pos: 21, end: 25 }, { fileName: "mod2", pos: 29, end: 33 }, @@ -254,6 +260,7 @@ describe('PreProcessFile:', function () { /* detectJavaScriptImports */ true, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { fileName: "mod1", pos: 28, end: 32 }, { fileName: "mod2", pos: 36, end: 40 }, @@ -274,6 +281,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "../Observable", "pos": 28, "end": 41 } ], @@ -293,6 +301,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "m", "pos": 135, "end": 136 }, { "fileName": "../Observable", "pos": 28, "end": 41 } @@ -313,6 +322,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "m", "pos": 135, "end": 136 }, { "fileName": "../Observable", "pos": 28, "end": 41 } @@ -333,6 +343,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "../Observable", "pos": 28, "end": 41 } ], @@ -352,6 +363,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "../Observable", "pos": 28, "end": 41 } ], @@ -370,6 +382,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "../Observable", "pos": 28, "end": 41 } ], @@ -390,6 +403,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "m2", "pos": 65, "end": 67 }, { "fileName": "augmentation", "pos": 102, "end": 114 } @@ -413,6 +427,7 @@ describe('PreProcessFile:', function () { /*detectJavaScriptImports*/ false, { referencedFiles: [], + typeReferenceDirectives: [], importedFiles: [ { "fileName": "m2", "pos": 127, "end": 129 }, { "fileName": "augmentation", "pos": 164, "end": 176 } @@ -420,7 +435,30 @@ describe('PreProcessFile:', function () { ambientExternalModules: ["m1"], isLibFile: false }); - }); + }); + it ("correctly recognizes type reference directives", () => { + test(` + /// + /// + /// + /// + `, + /*readImportFile*/ true, + /*detectJavaScriptImports*/ false, + { + referencedFiles: [ + { "pos": 13, "end": 38, "fileName": "a" }, + { "pos": 91, "end": 117, "fileName": "a2" } + ], + typeReferenceDirectives: [ + { "pos": 51, "end": 78, "fileName": "a1" }, + { "pos": 130, "end": 157, "fileName": "a3" } + ], + importedFiles: [], + ambientExternalModules: undefined, + isLibFile: false + }); + }) }); }); diff --git a/tests/cases/unittests/session.ts b/tests/cases/unittests/session.ts index 41f4bc599f65d..ee9742482cd5e 100644 --- a/tests/cases/unittests/session.ts +++ b/tests/cases/unittests/session.ts @@ -36,7 +36,7 @@ namespace ts.server { let lastSent: protocol.Message; beforeEach(() => { - session = new Session(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + session = new Session(mockHost, Utils.byteLength, process.hrtime, mockLogger); session.send = (msg: protocol.Message) => { lastSent = msg; }; @@ -161,7 +161,7 @@ namespace ts.server { it("is an overrideable handle which sends protocol messages over the wire", () => { const msg = {seq: 0, type: "none"}; const strmsg = JSON.stringify(msg); - const len = 1 + Buffer.byteLength(strmsg, "utf8"); + const len = 1 + Utils.byteLength(strmsg, "utf8"); const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`; session.send = Session.prototype.send; @@ -253,7 +253,7 @@ namespace ts.server { lastSent: protocol.Message; customHandler = "testhandler"; constructor() { - super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + super(mockHost, Utils.byteLength, process.hrtime, mockLogger); this.addProtocolHandler(this.customHandler, () => { return {response: undefined, responseRequired: true}; }); @@ -311,7 +311,7 @@ namespace ts.server { class InProcSession extends Session { private queue: protocol.Request[] = []; constructor(private client: InProcClient) { - super(mockHost, Buffer.byteLength, process.hrtime, mockLogger); + super(mockHost, Utils.byteLength, process.hrtime, mockLogger); this.addProtocolHandler("echo", (req: protocol.Request) => ({ response: req.arguments, responseRequired: true