diff --git a/package.json b/package.json index fdb85ea764b..2de37b712ab 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "through2": "latest", "travis-fold": "latest", "ts-node": "latest", - "tslint": "next", + "tslint": "4.0.0-dev.3", "typescript": "next" }, "scripts": { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5246bbfc700..2edfc6a7924 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4612,8 +4612,8 @@ namespace ts { // the modifiers type is T. Otherwise, the modifiers type is {}. const declaredType = getTypeFromMappedTypeNode(type.declaration); const constraint = getConstraintTypeFromMappedType(declaredType); - const extendedConstraint = constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(constraint) : constraint; - type.modifiersType = extendedConstraint.flags & TypeFlags.Index ? instantiateType((extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType; + const extendedConstraint = constraint && constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(constraint) : constraint; + type.modifiersType = extendedConstraint && extendedConstraint.flags & TypeFlags.Index ? instantiateType((extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType; } } return type.modifiersType; @@ -6645,7 +6645,7 @@ namespace ts { // Starting with the parent of the symbol's declaration, check if the mapper maps any of // the type parameters introduced by enclosing declarations. We just pick the first // declaration since multiple declarations will all have the same parent anyway. - let node = symbol.declarations[0].parent; + let node: Node = symbol.declarations[0]; while (node) { switch (node.kind) { case SyntaxKind.FunctionType: @@ -6665,7 +6665,7 @@ namespace ts { case SyntaxKind.ClassExpression: case SyntaxKind.InterfaceDeclaration: case SyntaxKind.TypeAliasDeclaration: - const declaration = node; + const declaration = node as DeclarationWithTypeParameters; if (declaration.typeParameters) { for (const d of declaration.typeParameters) { if (contains(mappedTypes, getDeclaredTypeOfTypeParameter(getSymbolOfNode(d)))) { @@ -6680,6 +6680,14 @@ namespace ts { } } break; + case SyntaxKind.JSDocFunctionType: + const func = node as JSDocFunctionType; + for (const p of func.parameters) { + if (contains(mappedTypes, getTypeOfNode(p))) { + return true; + } + } + break; case SyntaxKind.ModuleDeclaration: case SyntaxKind.SourceFile: return false; @@ -7730,8 +7738,11 @@ namespace ts { } } } - else if (relation !== identityRelation && isEmptyObjectType(resolveStructuredTypeMembers(target))) { - return Ternary.True; + else if (relation !== identityRelation) { + const resolved = resolveStructuredTypeMembers(target); + if (isEmptyObjectType(resolved) || resolved.stringIndexInfo && resolved.stringIndexInfo.type.flags & TypeFlags.Any) { + return Ternary.True; + } } return Ternary.False; } @@ -16888,7 +16899,7 @@ namespace ts { if (!local.isReferenced && !local.exportSymbol) { for (const declaration of local.declarations) { if (!isAmbientModule(declaration)) { - error(declaration.name, Diagnostics._0_is_declared_but_never_used, local.name); + errorUnusedLocal(declaration.name, local.name); } } } @@ -21845,8 +21856,19 @@ namespace ts { function checkGrammarNumericLiteral(node: NumericLiteral): boolean { // Grammar checking - if (node.isOctalLiteral && languageVersion >= ScriptTarget.ES5) { - return grammarErrorOnNode(node, Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher); + if (node.isOctalLiteral) { + let diagnosticMessage: DiagnosticMessage | undefined; + if (languageVersion >= ScriptTarget.ES5) { + diagnosticMessage = Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0; + } + else if (isChildOfLiteralType(node)) { + diagnosticMessage = Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0; + } + if (diagnosticMessage) { + const withMinus = isPrefixUnaryExpression(node.parent) && node.parent.operator === SyntaxKind.MinusToken; + const literal = `${withMinus ? "-" : ""}0o${node.text}`; + return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal); + } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b59921c2948..7b2208e4ca1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -227,7 +227,7 @@ "category": "Error", "code": 1084 }, - "Octal literals are not available when targeting ECMAScript 5 and higher.": { + "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'.": { "category": "Error", "code": 1085 }, @@ -2685,6 +2685,10 @@ "category": "Message", "code": 6080 }, + "File '{0}' has an unsupported extension, so skipping it.": { + "category": "Message", + "code": 6081 + }, "Only 'amd' and 'system' modules are supported alongside --{0}.": { "category": "Error", "code": 6082 @@ -2945,6 +2949,10 @@ "category": "Message", "code": 6146 }, + "Resolution for module '{0}' was found in cache": { + "category": "Message", + "code": 6147 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 @@ -3234,5 +3242,9 @@ "Add {0} to existing import declaration from {1}": { "category": "Message", "code": 90015 + }, + "Octal literal types must use ES2015 syntax. Use the syntax '{0}'.": { + "category": "Error", + "code": 8017 } } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 0daca9156d1..be8f4d6f0cb 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -47,11 +47,6 @@ namespace ts { return resolved.path; } - /** Create Resolved from a file with unknown extension. */ - function resolvedFromAnyFile(path: string): Resolved | undefined { - return { path, extension: extensionFromPath(path) }; - } - /** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */ function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModuleFull { return { resolvedFileName: path, extension, isExternalLibraryImport }; @@ -71,7 +66,8 @@ namespace ts { traceEnabled: boolean; } - function tryReadTypesSection(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string { + /** Reads from "main" or "types"/"typings" depending on `extensions`. */ + function tryReadPackageJsonMainOrTypes(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string { const jsonContent = readJson(packageJsonPath, state.host); switch (extensions) { @@ -153,6 +149,7 @@ namespace ts { if (host.directoryExists(atTypes)) { (typeRoots || (typeRoots = [])).push(atTypes); } + return undefined; }); return typeRoots; } @@ -241,7 +238,8 @@ namespace ts { if (traceEnabled) { trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup); } - resolvedFile = resolvedTypeScriptOnly(loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState)); + const result = loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*cache*/ undefined); + resolvedFile = resolvedTypeScriptOnly(result && result.value); if (!resolvedFile && traceEnabled) { trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); } @@ -293,33 +291,171 @@ namespace ts { return result; } - export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { + /** + * Cached module resolutions per containing directory. + * This assumes that any module id will have the same resolution for sibling files located in the same folder. + */ + export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache { + getOrCreateCacheForDirectory(directoryName: string): Map; + } + + /** + * Stored map from non-relative module name to a table: directory -> result of module lookup in this directory + * We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive. + */ + export interface NonRelativeModuleNameResolutionCache { + getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache; + } + + export interface PerModuleNameCache { + get(directory: string): ResolvedModuleWithFailedLookupLocations; + set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void; + } + + export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache { + const directoryToModuleNameMap = createFileMap>(); + const moduleNameToDirectoryMap = createMap(); + + return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName }; + + function getOrCreateCacheForDirectory(directoryName: string) { + const path = toPath(directoryName, currentDirectory, getCanonicalFileName); + let perFolderCache = directoryToModuleNameMap.get(path); + if (!perFolderCache) { + perFolderCache = createMap(); + directoryToModuleNameMap.set(path, perFolderCache); + } + return perFolderCache; + } + + function getOrCreateCacheForModuleName(nonRelativeModuleName: string) { + if (!moduleHasNonRelativeName(nonRelativeModuleName)) { + return undefined; + } + let perModuleNameCache = moduleNameToDirectoryMap[nonRelativeModuleName]; + if (!perModuleNameCache) { + moduleNameToDirectoryMap[nonRelativeModuleName] = perModuleNameCache = createPerModuleNameCache(); + } + return perModuleNameCache; + } + + function createPerModuleNameCache(): PerModuleNameCache { + const directoryPathMap = createFileMap(); + + return { get, set }; + + function get(directory: string): ResolvedModuleWithFailedLookupLocations { + return directoryPathMap.get(toPath(directory, currentDirectory, getCanonicalFileName)); + } + + /** + * At first this function add entry directory -> module resolution result to the table. + * Then it computes the set of parent folders for 'directory' that should have the same module resolution result + * and for every parent folder in set it adds entry: parent -> module resolution. . + * Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts. + * Set of parent folders that should have the same result will be: + * [ + * /a/b/c/d, /a/b/c, /a/b + * ] + * this means that request for module resolution from file in any of these folder will be immediately found in cache. + */ + function set(directory: string, result: ResolvedModuleWithFailedLookupLocations): void { + const path = toPath(directory, currentDirectory, getCanonicalFileName); + // if entry is already in cache do nothing + if (directoryPathMap.contains(path)) { + return; + } + directoryPathMap.set(path, result); + + const resolvedFileName = result.resolvedModule && result.resolvedModule.resolvedFileName; + // find common prefix between directory and resolved file name + // this common prefix should be the shorted path that has the same resolution + // directory: /a/b/c/d/e + // resolvedFileName: /a/b/foo.d.ts + const commonPrefix = getCommonPrefix(path, resolvedFileName); + let current = path; + while (true) { + const parent = getDirectoryPath(current); + if (parent === current || directoryPathMap.contains(parent)) { + break; + } + directoryPathMap.set(parent, result); + current = parent; + + if (current == commonPrefix) { + break; + } + } + } + + function getCommonPrefix(directory: Path, resolution: string) { + if (resolution === undefined) { + return undefined; + } + const resolutionDirectory = toPath(getDirectoryPath(resolution), currentDirectory, getCanonicalFileName); + + // find first position where directory and resolution differs + let i = 0; + while (i < Math.min(directory.length, resolutionDirectory.length) && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) { + i++; + } + + // find last directory separator before position i + const sep = directory.lastIndexOf(directorySeparator, i); + if (sep < 0) { + return undefined; + } + + return directory.substr(0, sep); + } + } + } + + export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); if (traceEnabled) { trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile); } + const containingDirectory = getDirectoryPath(containingFile); + let perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory); + let result = perFolderCache && perFolderCache[moduleName]; - let moduleResolution = compilerOptions.moduleResolution; - if (moduleResolution === undefined) { - moduleResolution = getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic; + if (result) { if (traceEnabled) { - trace(host, Diagnostics.Module_resolution_kind_is_not_specified_using_0, ModuleResolutionKind[moduleResolution]); + trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } } else { - if (traceEnabled) { - trace(host, Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ModuleResolutionKind[moduleResolution]); + let moduleResolution = compilerOptions.moduleResolution; + if (moduleResolution === undefined) { + moduleResolution = getEmitModuleKind(compilerOptions) === ModuleKind.CommonJS ? ModuleResolutionKind.NodeJs : ModuleResolutionKind.Classic; + if (traceEnabled) { + trace(host, Diagnostics.Module_resolution_kind_is_not_specified_using_0, ModuleResolutionKind[moduleResolution]); + } + } + else { + if (traceEnabled) { + trace(host, Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ModuleResolutionKind[moduleResolution]); + } } - } - let result: ResolvedModuleWithFailedLookupLocations; - switch (moduleResolution) { - case ModuleResolutionKind.NodeJs: - result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host); - break; - case ModuleResolutionKind.Classic: - result = classicNameResolver(moduleName, containingFile, compilerOptions, host); - break; + switch (moduleResolution) { + case ModuleResolutionKind.NodeJs: + result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache); + break; + case ModuleResolutionKind.Classic: + result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache); + break; + } + + if (perFolderCache) { + perFolderCache[moduleName] = result; + // put result in per-module name cache + const perModuleNameCache = cache.getOrCreateCacheForModuleName(moduleName); + if (perModuleNameCache) { + perModuleNameCache.set(containingDirectory, result); + } + } } if (traceEnabled) { @@ -542,7 +678,7 @@ namespace ts { } } - export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { + export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations { const containingDirectory = getDirectoryPath(containingFile); const traceEnabled = isTraceEnabled(compilerOptions, host); @@ -550,30 +686,30 @@ namespace ts { const state: ModuleResolutionState = { compilerOptions, host, traceEnabled }; const result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); - if (result) { - const { resolved, isExternalLibraryImport } = result; + if (result && result.value) { + const { resolved, isExternalLibraryImport } = result.value; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); } return { resolvedModule: undefined, failedLookupLocations }; - function tryResolve(extensions: Extensions): { resolved: Resolved, isExternalLibraryImport: boolean } | undefined { + function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> { const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, state); if (resolved) { - return { resolved, isExternalLibraryImport: false }; + return toSearchResult({ resolved, isExternalLibraryImport: false }); } if (moduleHasNonRelativeName(moduleName)) { if (traceEnabled) { trace(host, Diagnostics.Loading_module_0_from_node_modules_folder, moduleName); } - const resolved = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state); + const resolved = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files. - return resolved && { resolved: { path: realpath(resolved.path, host, traceEnabled), extension: resolved.extension }, isExternalLibraryImport: true }; + return resolved && { value: resolved.value && { resolved: { path: realpath(resolved.value.path, host, traceEnabled), extension: resolved.value.extension }, isExternalLibraryImport: true } }; } else { const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); - return resolved && { resolved, isExternalLibraryImport: false }; + return resolved && toSearchResult({ resolved, isExternalLibraryImport: false }); } } } @@ -678,18 +814,21 @@ namespace ts { if (state.traceEnabled) { trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath); } - const typesFile = tryReadTypesSection(extensions, packageJsonPath, candidate, state); - if (typesFile) { - const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host); + const mainOrTypesFile = tryReadPackageJsonMainOrTypes(extensions, packageJsonPath, candidate, state); + if (mainOrTypesFile) { + const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(mainOrTypesFile), state.host); // A package.json "typings" may specify an exact filename, or may choose to omit an extension. - const fromFile = tryFile(typesFile, failedLookupLocations, onlyRecordFailures, state); - if (fromFile) { - // Note: this would allow a package.json to specify a ".js" file as typings. Maybe that should be forbidden. - return resolvedFromAnyFile(fromFile); + const fromExactFile = tryFile(mainOrTypesFile, failedLookupLocations, onlyRecordFailures, state); + if (fromExactFile) { + const resolved = fromExactFile && resolvedIfExtensionMatches(extensions, fromExactFile); + if (resolved) { + return resolved; + } + trace(state.host, Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromExactFile); } - const x = tryAddingExtensions(typesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state); - if (x) { - return x; + const resolved = tryAddingExtensions(mainOrTypesFile, Extensions.TypeScript, failedLookupLocations, onlyRecordFailures, state); + if (resolved) { + return resolved; } } else { @@ -709,6 +848,24 @@ namespace ts { return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); } + /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ + function resolvedIfExtensionMatches(extensions: Extensions, path: string): Resolved | undefined { + const extension = tryGetExtensionFromPath(path); + return extension !== undefined && extensionIsOk(extensions, extension) ? { path, extension } : undefined; + } + + /** True if `extension` is one of the supported `extensions`. */ + function extensionIsOk(extensions: Extensions, extension: Extension): boolean { + switch (extensions) { + case Extensions.JavaScript: + return extension === Extension.Js || extension === Extension.Jsx; + case Extensions.TypeScript: + return extension === Extension.Ts || extension === Extension.Tsx || extension === Extension.Dts; + case Extensions.DtsOnly: + return extension === Extension.Dts; + } + } + function pathToPackageJson(directory: string): string { return combinePaths(directory, "package.json"); } @@ -722,18 +879,23 @@ namespace ts { loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state); } - function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { - return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false); + function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult { + return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache); } - function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState): Resolved | undefined { + function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState): SearchResult { // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly. - return loadModuleFromNodeModulesWorker(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true); + return loadModuleFromNodeModulesWorker(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true, /*cache*/ undefined); } - function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState, typesOnly: boolean): Resolved | undefined { + function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push, state: ModuleResolutionState, typesOnly: boolean, cache: NonRelativeModuleNameResolutionCache): SearchResult { + const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName); return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => { if (getBaseFileName(ancestorDirectory) !== "node_modules") { - return loadModuleFromNodeModulesOneLevel(extensions, moduleName, ancestorDirectory, failedLookupLocations, state, typesOnly); + const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host); + if (resolutionFromCache) { + return resolutionFromCache; + } + return toSearchResult(loadModuleFromNodeModulesOneLevel(extensions, moduleName, ancestorDirectory, failedLookupLocations, state, typesOnly)); } }); } @@ -749,26 +911,41 @@ namespace ts { } } - export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations { + function tryFindNonRelativeModuleNameInCache(cache: PerModuleNameCache | undefined, moduleName: string, containingDirectory: string, traceEnabled: boolean, host: ModuleResolutionHost): SearchResult { + const result = cache && cache.get(containingDirectory); + if (result) { + if (traceEnabled) { + trace(host, Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName) + } + return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension } }; + } + } + + export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations { const traceEnabled = isTraceEnabled(compilerOptions, host); const state: ModuleResolutionState = { compilerOptions, host, traceEnabled }; const failedLookupLocations: string[] = []; const containingDirectory = getDirectoryPath(containingFile); const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); - return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ false, failedLookupLocations); + return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations); - function tryResolve(extensions: Extensions): Resolved | undefined { + function tryResolve(extensions: Extensions): SearchResult { const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state); if (resolvedUsingSettings) { - return resolvedUsingSettings; + return { value: resolvedUsingSettings }; } + const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName); if (moduleHasNonRelativeName(moduleName)) { // Climb up parent directories looking for a module. const resolved = forEachAncestorDirectory(containingDirectory, directory => { + const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host); + if (resolutionFromCache) { + return resolutionFromCache; + } const searchName = normalizePath(combinePaths(directory, moduleName)); - return loadModuleFromFile(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state); + return toSearchResult(loadModuleFromFile(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state)); }); if (resolved) { return resolved; @@ -780,7 +957,7 @@ namespace ts { } else { const candidate = normalizePath(combinePaths(containingDirectory, moduleName)); - return loadModuleFromFile(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); + return toSearchResult(loadModuleFromFile(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state)); } } } @@ -801,8 +978,28 @@ namespace ts { return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations); } + /** + * Represents result of search. Normally when searching among several alternatives we treat value `undefined` as indicator + * that search fails and we should try another option. + * However this does not allow us to represent final result that should be used instead of further searching (i.e. a final result that was found in cache). + * SearchResult is used to deal with this issue, its values represents following outcomes: + * - undefined - not found, continue searching + * - { value: undefined } - not found - stop searching + * - { value: } - found - stop searching + */ + type SearchResult = { value: T | undefined } | undefined; + + /** + * Wraps value to SearchResult. + * @returns undefined if value is undefined or { value } otherwise + */ + function toSearchResult(value: T | undefined): SearchResult { + return value !== undefined ? { value } : undefined; + } + + /** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */ - function forEachAncestorDirectory(directory: string, callback: (directory: string) => T | undefined): T | undefined { + function forEachAncestorDirectory(directory: string, callback: (directory: string) => SearchResult): SearchResult { while (true) { const result = callback(directory); if (result !== undefined) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 73976d5d02e..4ab709d8455 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -325,6 +325,7 @@ namespace ts { // Map storing if there is emit blocking diagnostics for given input const hasEmitBlockingDiagnostics = createFileMap(getCanonicalFileName); + let moduleResolutionCache: ModuleResolutionCache; let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModuleFull[]; if (host.resolveModuleNames) { resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile).map(resolved => { @@ -338,7 +339,8 @@ namespace ts { }); } else { - const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host).resolvedModule; + moduleResolutionCache = createModuleResolutionCache(currentDirectory, x => host.getCanonicalFileName(x)); + const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule; resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache(moduleNames, containingFile, loader); } @@ -391,6 +393,9 @@ namespace ts { } } + // unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks + moduleResolutionCache = undefined; + // unconditionally set oldProgram to undefined to prevent it from being captured in closure oldProgram = undefined; diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 877131b369c..775f60355d8 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -1555,12 +1555,15 @@ namespace ts { return false; } + type SerializedEntityNameAsExpression = Identifier | BinaryExpression | PropertyAccessExpression; + type SerializedTypeNode = SerializedEntityNameAsExpression | VoidExpression | ConditionalExpression; + /** * Serializes the type of a node for use with decorator type metadata. * * @param node The node that should have its type serialized. */ - function serializeTypeOfNode(node: Node): Expression { + function serializeTypeOfNode(node: Node): SerializedTypeNode { switch (node.kind) { case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: @@ -1582,7 +1585,7 @@ namespace ts { * * @param node The node that should have its parameter types serialized. */ - function serializeParameterTypesOfNode(node: Node, container: ClassLikeDeclaration): Expression { + function serializeParameterTypesOfNode(node: Node, container: ClassLikeDeclaration): ArrayLiteralExpression { const valueDeclaration = isClassLike(node) ? getFirstConstructorWithBody(node) @@ -1590,7 +1593,7 @@ namespace ts { ? node : undefined; - const expressions: Expression[] = []; + const expressions: SerializedTypeNode[] = []; if (valueDeclaration) { const parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container); const numParameters = parameters.length; @@ -1626,7 +1629,7 @@ namespace ts { * * @param node The node that should have its return type serialized. */ - function serializeReturnTypeOfNode(node: Node): Expression { + function serializeReturnTypeOfNode(node: Node): SerializedTypeNode { if (isFunctionLike(node) && node.type) { return serializeTypeNode(node.type); } @@ -1655,13 +1658,16 @@ namespace ts { * * @param node The type node to serialize. */ - function serializeTypeNode(node: TypeNode): Expression { + function serializeTypeNode(node: TypeNode): SerializedTypeNode { if (node === undefined) { return createIdentifier("Object"); } switch (node.kind) { case SyntaxKind.VoidKeyword: + case SyntaxKind.UndefinedKeyword: + case SyntaxKind.NullKeyword: + case SyntaxKind.NeverKeyword: return createVoidZero(); case SyntaxKind.ParenthesizedType: @@ -1713,37 +1719,8 @@ namespace ts { case SyntaxKind.IntersectionType: case SyntaxKind.UnionType: - { - const unionOrIntersection = node; - let serializedUnion: Identifier; - for (const typeNode of unionOrIntersection.types) { - const serializedIndividual = serializeTypeNode(typeNode) as Identifier; - // Non identifier - if (serializedIndividual.kind !== SyntaxKind.Identifier) { - serializedUnion = undefined; - break; - } + return serializeUnionOrIntersectionType(node); - // One of the individual is global object, return immediately - if (serializedIndividual.text === "Object") { - return serializedIndividual; - } - - // Different types - if (serializedUnion && serializedUnion.text !== serializedIndividual.text) { - serializedUnion = undefined; - break; - } - - serializedUnion = serializedIndividual; - } - - // If we were able to find common type - if (serializedUnion) { - return serializedUnion; - } - } - // Fallthrough case SyntaxKind.TypeQuery: case SyntaxKind.TypeOperator: case SyntaxKind.IndexedAccessType: @@ -1761,13 +1738,48 @@ namespace ts { return createIdentifier("Object"); } + function serializeUnionOrIntersectionType(node: UnionOrIntersectionTypeNode): SerializedTypeNode { + let serializedUnion: SerializedTypeNode; + for (const typeNode of node.types) { + const serializedIndividual = serializeTypeNode(typeNode); + + if (isVoidExpression(serializedIndividual)) { + // If we dont have any other type already set, set the initial type + if (!serializedUnion) { + serializedUnion = serializedIndividual; + } + } + else if (isIdentifier(serializedIndividual) && serializedIndividual.text === "Object") { + // One of the individual is global object, return immediately + return serializedIndividual; + } + // If there exists union that is not void 0 expression, check if the the common type is identifier. + // anything more complex and we will just default to Object + else if (serializedUnion && !isVoidExpression(serializedUnion)) { + // Different types + if (!isIdentifier(serializedUnion) || + !isIdentifier(serializedIndividual) || + serializedUnion.text !== serializedIndividual.text) { + return createIdentifier("Object"); + } + } + else { + // Initialize the union type + serializedUnion = serializedIndividual; + } + } + + // If we were able to find common type, use it + return serializedUnion; + } + /** * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with * decorator type metadata. * * @param node The type reference node. */ - function serializeTypeReferenceNode(node: TypeReferenceNode) { + function serializeTypeReferenceNode(node: TypeReferenceNode): SerializedTypeNode { switch (resolver.getTypeReferenceSerializationKind(node.typeName, currentScope)) { case TypeReferenceSerializationKind.Unknown: const serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true); @@ -1822,7 +1834,7 @@ namespace ts { * @param useFallback A value indicating whether to use logical operators to test for the * entity name at runtime. */ - function serializeEntityNameAsExpression(node: EntityName, useFallback: boolean): Expression { + function serializeEntityNameAsExpression(node: EntityName, useFallback: boolean): SerializedEntityNameAsExpression { switch (node.kind) { case SyntaxKind.Identifier: // Create a clone of the name with a new parent, and treat it as if it were @@ -1855,8 +1867,8 @@ namespace ts { * @param useFallback A value indicating whether to use logical operators to test for the * qualified name at runtime. */ - function serializeQualifiedNameAsExpression(node: QualifiedName, useFallback: boolean): Expression { - let left: Expression; + function serializeQualifiedNameAsExpression(node: QualifiedName, useFallback: boolean): PropertyAccessExpression { + let left: SerializedEntityNameAsExpression; if (node.left.kind === SyntaxKind.Identifier) { left = serializeEntityNameAsExpression(node.left, useFallback); } @@ -1881,7 +1893,7 @@ namespace ts { * Gets an expression that points to the global "Symbol" constructor at runtime if it is * available. */ - function getGlobalSymbolNameWithFallback(): Expression { + function getGlobalSymbolNameWithFallback(): ConditionalExpression { return createConditional( createTypeCheck(createIdentifier("Symbol"), "function"), createIdentifier("Symbol"), @@ -2719,7 +2731,7 @@ namespace ts { let blockLocation: TextRange; const body = node.body; if (body.kind === SyntaxKind.ModuleBlock) { - addRange(statements, visitNodes((body).statements, namespaceElementVisitor, isStatement)); + saveStateAndInvoke(body, body => addRange(statements, visitNodes((body).statements, namespaceElementVisitor, isStatement))); statementsLocation = (body).statements; blockLocation = body; } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6f491f6708f..edfbe639d25 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -732,6 +732,20 @@ namespace ts { return false; } + export function isChildOfLiteralType(node: Node): boolean { + while (node) { + if (node.kind === SyntaxKind.LiteralType) { + return true; + } + node = node.parent; + } + return false; + } + + export function isPrefixUnaryExpression(node: Node): node is PrefixUnaryExpression { + return node.kind === SyntaxKind.PrefixUnaryExpression; + } + // Warning: This has the same semantics as the forEach family of functions, // in that traversal terminates in the event that 'visitor' supplies a truthy value. export function forEachReturnStatement(body: Block, visitor: (stmt: ReturnStatement) => T): T { @@ -3581,6 +3595,10 @@ namespace ts { return node.kind === SyntaxKind.Identifier; } + export function isVoidExpression(node: Node): node is VoidExpression { + return node.kind === SyntaxKind.VoidExpression; + } + export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier { // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`. return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 7c7a06db0b6..653b87236fd 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -341,6 +341,7 @@ namespace FourSlash { insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, insertSpaceBeforeAndAfterBinaryOperators: true, + insertSpaceAfterConstructor: false, insertSpaceAfterKeywordsInControlFlowStatements: true, insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 13d8a6bf824..d379b5bbf9c 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1840,6 +1840,41 @@ namespace ts.projectSystem { assert.isFalse(service.externalProjects[0].languageServiceEnabled, "language service should be disabled - 2"); }); + it("files are properly detached when language service is disabled", () => { + const f1 = { + path: "/a/app.js", + content: "var x = 1" + }; + const f2 = { + path: "/a/largefile.js", + content: "" + }; + const f3 = { + path: "/a/lib.js", + content: "var x = 1" + }; + const config = { + path: "/a/tsconfig.json", + content: JSON.stringify({ compilerOptions: { allowJs: true } }) + }; + const host = createServerHost([f1, f2, f3, config]); + const originalGetFileSize = host.getFileSize; + host.getFileSize = (filePath: string) => + filePath === f2.path ? server.maxProgramSizeForNonTsFiles + 1 : originalGetFileSize.call(host, filePath); + + const projectService = createProjectService(host); + projectService.openClientFile(f1.path); + projectService.checkNumberOfProjects({ configuredProjects: 1 }); + + projectService.closeClientFile(f1.path); + projectService.checkNumberOfProjects({}); + + for (const f of [f2, f3]) { + const scriptInfo = projectService.getScriptInfoForNormalizedPath(server.toNormalizedPath(f.path)); + assert.equal(scriptInfo.containingProjects.length, 0, `expect 0 containing projects for '${f.path}'`) + } + }); + it("language service disabled events are triggered", () => { const f1 = { path: "/a/app.js", diff --git a/src/server/project.ts b/src/server/project.ts index 0037a470a49..6085ee05159 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -257,8 +257,9 @@ namespace ts.server { info.detachFromProject(this); } } - else { - // release all root files + if (!this.program || !this.languageServiceEnabled) { + // release all root files either if there is no program or language service is disabled. + // in the latter case set of root files can be larger than the set of files in program. for (const root of this.rootFiles) { root.detachFromProject(this); } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 39012e49fcd..680b81dff99 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -2194,12 +2194,14 @@ namespace ts.server.protocol { insertSpaceAfterCommaDelimiter?: boolean; insertSpaceAfterSemicolonInForStatements?: boolean; insertSpaceBeforeAndAfterBinaryOperators?: boolean; + insertSpaceAfterConstructor?: boolean; insertSpaceAfterKeywordsInControlFlowStatements?: boolean; insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean; insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean; insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; + insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; } diff --git a/src/server/utilities.ts b/src/server/utilities.ts index 839e79268fa..641ca128e63 100644 --- a/src/server/utilities.ts +++ b/src/server/utilities.ts @@ -78,6 +78,7 @@ namespace ts.server { newLineCharacter: host.newLine || "\n", convertTabsToSpaces: true, indentStyle: ts.IndentStyle.Smart, + insertSpaceAfterConstructor: false, insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, insertSpaceBeforeAndAfterBinaryOperators: true, @@ -87,6 +88,7 @@ namespace ts.server { insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, + insertSpaceBeforeFunctionParenthesis: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, }; diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 41630a77935..637bb41bad9 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -488,8 +488,6 @@ namespace ts.formatting { // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent case SyntaxKind.OpenBraceToken: case SyntaxKind.CloseBraceToken: - case SyntaxKind.OpenBracketToken: - case SyntaxKind.CloseBracketToken: case SyntaxKind.OpenParenToken: case SyntaxKind.CloseParenToken: case SyntaxKind.ElseKeyword: @@ -506,6 +504,13 @@ namespace ts.formatting { } break; } + case SyntaxKind.OpenBracketToken: + case SyntaxKind.CloseBracketToken: { + if (container.kind !== SyntaxKind.MappedType) { + return indentation; + } + break; + } } // if token line equals to the line of containing node (this is a first token in the node) - use node indentation return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation; diff --git a/src/services/formatting/rules.ts b/src/services/formatting/rules.ts index 18125932a11..2fac6c05555 100644 --- a/src/services/formatting/rules.ts +++ b/src/services/formatting/rules.ts @@ -87,6 +87,7 @@ namespace ts.formatting { public SpaceAfterLetConstInVariableDeclaration: Rule; public NoSpaceBeforeOpenParenInFuncCall: Rule; public SpaceAfterFunctionInFuncDecl: Rule; + public SpaceBeforeOpenParenInFuncDecl: Rule; public NoSpaceBeforeOpenParenInFuncDecl: Rule; public SpaceAfterVoidOperator: Rule; @@ -112,6 +113,7 @@ namespace ts.formatting { // TypeScript-specific rules // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses + public SpaceAfterConstructor: Rule; public NoSpaceAfterConstructor: Rule; // Use of module as a function call. e.g.: import m2 = module("m2"); @@ -329,6 +331,7 @@ namespace ts.formatting { this.SpaceAfterLetConstInVariableDeclaration = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.LetKeyword, SyntaxKind.ConstKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsStartOfVariableDeclarationList), RuleAction.Space)); this.NoSpaceBeforeOpenParenInFuncCall = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionCallOrNewContext, Rules.IsPreviousTokenNotComma), RuleAction.Delete)); this.SpaceAfterFunctionInFuncDecl = new Rule(RuleDescriptor.create3(SyntaxKind.FunctionKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsFunctionDeclContext), RuleAction.Space)); + this.SpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Space)); this.NoSpaceBeforeOpenParenInFuncDecl = new Rule(RuleDescriptor.create2(Shared.TokenRange.Any, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsFunctionDeclContext), RuleAction.Delete)); this.SpaceAfterVoidOperator = new Rule(RuleDescriptor.create3(SyntaxKind.VoidKeyword, Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext, Rules.IsVoidOpContext), RuleAction.Space)); @@ -352,13 +355,14 @@ namespace ts.formatting { // TypeScript-specific higher priority rules // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses + this.SpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); this.NoSpaceAfterConstructor = new Rule(RuleDescriptor.create1(SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); // Use of module as a function call. e.g.: import m2 = module("m2"); this.NoSpaceAfterModuleImport = new Rule(RuleDescriptor.create2(Shared.TokenRange.FromTokens([SyntaxKind.ModuleKeyword, SyntaxKind.RequireKeyword]), SyntaxKind.OpenParenToken), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Delete)); // Add a space around certain TypeScript keywords - this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); + this.SpaceAfterCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.FromTokens([SyntaxKind.AbstractKeyword, SyntaxKind.ClassKeyword, SyntaxKind.DeclareKeyword, SyntaxKind.DefaultKeyword, SyntaxKind.EnumKeyword, SyntaxKind.ExportKeyword, SyntaxKind.ExtendsKeyword, SyntaxKind.GetKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.ImportKeyword, SyntaxKind.InterfaceKeyword, SyntaxKind.ModuleKeyword, SyntaxKind.NamespaceKeyword, SyntaxKind.PrivateKeyword, SyntaxKind.PublicKeyword, SyntaxKind.ProtectedKeyword, SyntaxKind.ReadonlyKeyword, SyntaxKind.SetKeyword, SyntaxKind.StaticKeyword, SyntaxKind.TypeKeyword, SyntaxKind.FromKeyword, SyntaxKind.KeyOfKeyword]), Shared.TokenRange.Any), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); this.SpaceBeforeCertainTypeScriptKeywords = new Rule(RuleDescriptor.create4(Shared.TokenRange.Any, Shared.TokenRange.FromTokens([SyntaxKind.ExtendsKeyword, SyntaxKind.ImplementsKeyword, SyntaxKind.FromKeyword])), RuleOperation.create2(new RuleOperationContext(Rules.IsNonJsxSameLineTokenContext), RuleAction.Space)); // Treat string literals in module names as identifiers, and add a space between the literal and the opening Brace braces, e.g.: module "m2" { @@ -437,7 +441,7 @@ namespace ts.formatting { this.NoSpaceBeforeEqualInJsxAttribute, this.NoSpaceAfterEqualInJsxAttribute, // TypeScript-specific rules - this.NoSpaceAfterConstructor, this.NoSpaceAfterModuleImport, + this.NoSpaceAfterModuleImport, this.SpaceAfterCertainTypeScriptKeywords, this.SpaceBeforeCertainTypeScriptKeywords, this.SpaceAfterModuleName, this.SpaceBeforeArrow, this.SpaceAfterArrow, @@ -462,7 +466,6 @@ namespace ts.formatting { this.NoSpaceBeforeOpenBracket, this.NoSpaceAfterCloseBracket, this.SpaceAfterSemicolon, - this.NoSpaceBeforeOpenParenInFuncDecl, this.SpaceBetweenStatements, this.SpaceAfterTryFinally ]; @@ -575,6 +578,8 @@ namespace ts.formatting { return context.currentTokenSpan.kind === SyntaxKind.EqualsToken || context.nextTokenSpan.kind === SyntaxKind.EqualsToken; // "in" keyword in for (let x in []) { } case SyntaxKind.ForInStatement: + // "in" keyword in [P in keyof T]: T[P] + case SyntaxKind.TypeParameter: return context.currentTokenSpan.kind === SyntaxKind.InKeyword || context.nextTokenSpan.kind === SyntaxKind.InKeyword; // Technically, "of" is not a binary operator, but format it the same way as "in" case SyntaxKind.ForOfStatement: @@ -836,6 +841,7 @@ namespace ts.formatting { switch (parent.kind) { case SyntaxKind.TypeReference: case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.ClassExpression: case SyntaxKind.InterfaceDeclaration: diff --git a/src/services/formatting/rulesProvider.ts b/src/services/formatting/rulesProvider.ts index 4a2c9d0f155..14e08e4857a 100644 --- a/src/services/formatting/rulesProvider.ts +++ b/src/services/formatting/rulesProvider.ts @@ -38,6 +38,13 @@ namespace ts.formatting { private createActiveRules(options: ts.FormatCodeSettings): Rule[] { let rules = this.globalRules.HighPriorityCommonRules.slice(0); + if (options.insertSpaceAfterConstructor) { + rules.push(this.globalRules.SpaceAfterConstructor); + } + else { + rules.push(this.globalRules.NoSpaceAfterConstructor); + } + if (options.insertSpaceAfterCommaDelimiter) { rules.push(this.globalRules.SpaceAfterComma); } @@ -128,6 +135,13 @@ namespace ts.formatting { rules.push(this.globalRules.NoSpaceAfterBinaryOperator); } + if (options.insertSpaceBeforeFunctionParenthesis) { + rules.push(this.globalRules.SpaceBeforeOpenParenInFuncDecl); + } + else { + rules.push(this.globalRules.NoSpaceBeforeOpenParenInFuncDecl); + } + if (options.placeOpenBraceOnNewLineForControlBlocks) { rules.push(this.globalRules.NewLineBeforeOpenBraceInControl); } diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index 84f83a9c7db..eb9e1ba04c5 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -438,6 +438,7 @@ namespace ts.formatting { case SyntaxKind.ModuleBlock: case SyntaxKind.ObjectLiteralExpression: case SyntaxKind.TypeLiteral: + case SyntaxKind.MappedType: case SyntaxKind.TupleType: case SyntaxKind.CaseBlock: case SyntaxKind.DefaultClause: diff --git a/src/services/types.ts b/src/services/types.ts index 3865fe7fac9..88ffe2950ce 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -418,6 +418,7 @@ namespace ts { InsertSpaceAfterCommaDelimiter: boolean; InsertSpaceAfterSemicolonInForStatements: boolean; InsertSpaceBeforeAndAfterBinaryOperators: boolean; + InsertSpaceAfterConstructor?: boolean; InsertSpaceAfterKeywordsInControlFlowStatements: boolean; InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; @@ -426,6 +427,7 @@ namespace ts { InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: boolean; InsertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; InsertSpaceAfterTypeAssertion?: boolean; + InsertSpaceBeforeFunctionParenthesis?: boolean; PlaceOpenBraceOnNewLineForFunctions: boolean; PlaceOpenBraceOnNewLineForControlBlocks: boolean; } @@ -434,6 +436,7 @@ namespace ts { insertSpaceAfterCommaDelimiter?: boolean; insertSpaceAfterSemicolonInForStatements?: boolean; insertSpaceBeforeAndAfterBinaryOperators?: boolean; + insertSpaceAfterConstructor?: boolean; insertSpaceAfterKeywordsInControlFlowStatements?: boolean; insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean; insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean; @@ -442,6 +445,7 @@ namespace ts { insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean; insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean; insertSpaceAfterTypeAssertion?: boolean; + insertSpaceBeforeFunctionParenthesis?: boolean; placeOpenBraceOnNewLineForFunctions?: boolean; placeOpenBraceOnNewLineForControlBlocks?: boolean; } diff --git a/tests/baselines/reference/cacheResolutions.js b/tests/baselines/reference/cacheResolutions.js new file mode 100644 index 00000000000..1d0f918bf98 --- /dev/null +++ b/tests/baselines/reference/cacheResolutions.js @@ -0,0 +1,27 @@ +//// [tests/cases/compiler/cacheResolutions.ts] //// + +//// [app.ts] + +export let x = 1; + +//// [lib1.ts] +export let x = 1; + +//// [lib2.ts] +export let x = 1; + +//// [app.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.x = 1; +}); +//// [lib1.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.x = 1; +}); +//// [lib2.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.x = 1; +}); diff --git a/tests/baselines/reference/cacheResolutions.symbols b/tests/baselines/reference/cacheResolutions.symbols new file mode 100644 index 00000000000..362ce5c308c --- /dev/null +++ b/tests/baselines/reference/cacheResolutions.symbols @@ -0,0 +1,13 @@ +=== /a/b/c/app.ts === + +export let x = 1; +>x : Symbol(x, Decl(app.ts, 1, 10)) + +=== /a/b/c/lib1.ts === +export let x = 1; +>x : Symbol(x, Decl(lib1.ts, 0, 10)) + +=== /a/b/c/lib2.ts === +export let x = 1; +>x : Symbol(x, Decl(lib2.ts, 0, 10)) + diff --git a/tests/baselines/reference/cacheResolutions.trace.json b/tests/baselines/reference/cacheResolutions.trace.json new file mode 100644 index 00000000000..8e7adfb9898 --- /dev/null +++ b/tests/baselines/reference/cacheResolutions.trace.json @@ -0,0 +1,43 @@ +[ + "======== Resolving module 'tslib' from '/a/b/c/app.ts'. ========", + "Module resolution kind is not specified, using 'Classic'.", + "File '/a/b/c/tslib.ts' does not exist.", + "File '/a/b/c/tslib.tsx' does not exist.", + "File '/a/b/c/tslib.d.ts' does not exist.", + "File '/a/b/tslib.ts' does not exist.", + "File '/a/b/tslib.tsx' does not exist.", + "File '/a/b/tslib.d.ts' does not exist.", + "File '/a/tslib.ts' does not exist.", + "File '/a/tslib.tsx' does not exist.", + "File '/a/tslib.d.ts' does not exist.", + "File '/tslib.ts' does not exist.", + "File '/tslib.tsx' does not exist.", + "File '/tslib.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/tslib.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/tslib/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/tslib/index.d.ts' does not exist.", + "File '/a/b/node_modules/@types/tslib.d.ts' does not exist.", + "File '/a/b/node_modules/@types/tslib/package.json' does not exist.", + "File '/a/b/node_modules/@types/tslib/index.d.ts' does not exist.", + "File '/a/node_modules/@types/tslib.d.ts' does not exist.", + "File '/a/node_modules/@types/tslib/package.json' does not exist.", + "File '/a/node_modules/@types/tslib/index.d.ts' does not exist.", + "File '/node_modules/@types/tslib.d.ts' does not exist.", + "File '/node_modules/@types/tslib/package.json' does not exist.", + "File '/node_modules/@types/tslib/index.d.ts' does not exist.", + "File '/a/b/c/tslib.js' does not exist.", + "File '/a/b/c/tslib.jsx' does not exist.", + "File '/a/b/tslib.js' does not exist.", + "File '/a/b/tslib.jsx' does not exist.", + "File '/a/tslib.js' does not exist.", + "File '/a/tslib.jsx' does not exist.", + "File '/tslib.js' does not exist.", + "File '/tslib.jsx' does not exist.", + "======== Module name 'tslib' was not resolved. ========", + "======== Resolving module 'tslib' from '/a/b/c/lib1.ts'. ========", + "Resolution for module 'tslib' was found in cache", + "======== Module name 'tslib' was not resolved. ========", + "======== Resolving module 'tslib' from '/a/b/c/lib2.ts'. ========", + "Resolution for module 'tslib' was found in cache", + "======== Module name 'tslib' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cacheResolutions.types b/tests/baselines/reference/cacheResolutions.types new file mode 100644 index 00000000000..fdcc0a6c46c --- /dev/null +++ b/tests/baselines/reference/cacheResolutions.types @@ -0,0 +1,16 @@ +=== /a/b/c/app.ts === + +export let x = 1; +>x : number +>1 : 1 + +=== /a/b/c/lib1.ts === +export let x = 1; +>x : number +>1 : 1 + +=== /a/b/c/lib2.ts === +export let x = 1; +>x : number +>1 : 1 + diff --git a/tests/baselines/reference/cachedModuleResolution1.js b/tests/baselines/reference/cachedModuleResolution1.js new file mode 100644 index 00000000000..9071b60d6c1 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution1.js @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/cachedModuleResolution1.ts] //// + +//// [foo.d.ts] + +export declare let x: number + +//// [app.ts] +import {x} from "foo"; + +//// [lib.ts] +import {x} from "foo"; + +//// [app.js] +"use strict"; +//// [lib.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution1.symbols b/tests/baselines/reference/cachedModuleResolution1.symbols new file mode 100644 index 00000000000..f7d3c474a56 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution1.symbols @@ -0,0 +1,13 @@ +=== /a/b/node_modules/foo.d.ts === + +export declare let x: number +>x : Symbol(x, Decl(foo.d.ts, 1, 18)) + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(app.ts, 0, 8)) + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(lib.ts, 0, 8)) + diff --git a/tests/baselines/reference/cachedModuleResolution1.trace.json b/tests/baselines/reference/cachedModuleResolution1.trace.json new file mode 100644 index 00000000000..dbb0e6068be --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution1.trace.json @@ -0,0 +1,46 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/d/e/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo.ts' does not exist.", + "File '/a/b/c/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/foo.ts' does not exist.", + "File '/a/b/node_modules/foo.tsx' does not exist.", + "File '/a/b/node_modules/foo.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'", + "======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========", + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "Resolution for module 'foo' was found in cache", + "Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'", + "======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution1.types b/tests/baselines/reference/cachedModuleResolution1.types new file mode 100644 index 00000000000..c041e8cc340 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution1.types @@ -0,0 +1,13 @@ +=== /a/b/node_modules/foo.d.ts === + +export declare let x: number +>x : number + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : number + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : number + diff --git a/tests/baselines/reference/cachedModuleResolution2.js b/tests/baselines/reference/cachedModuleResolution2.js new file mode 100644 index 00000000000..7c84a92abaf --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution2.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/cachedModuleResolution2.ts] //// + +//// [foo.d.ts] + +export declare let x: number + +//// [lib.ts] +import {x} from "foo"; + +//// [app.ts] +import {x} from "foo"; + + +//// [lib.js] +"use strict"; +//// [app.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution2.symbols b/tests/baselines/reference/cachedModuleResolution2.symbols new file mode 100644 index 00000000000..c8356eadb11 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution2.symbols @@ -0,0 +1,13 @@ +=== /a/b/node_modules/foo.d.ts === + +export declare let x: number +>x : Symbol(x, Decl(foo.d.ts, 1, 18)) + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(lib.ts, 0, 8)) + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(app.ts, 0, 8)) + diff --git a/tests/baselines/reference/cachedModuleResolution2.trace.json b/tests/baselines/reference/cachedModuleResolution2.trace.json new file mode 100644 index 00000000000..1d4b40bbc08 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution2.trace.json @@ -0,0 +1,46 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/node_modules/foo.ts' does not exist.", + "File '/a/b/c/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/foo.ts' does not exist.", + "File '/a/b/node_modules/foo.tsx' does not exist.", + "File '/a/b/node_modules/foo.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'", + "======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========", + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/d/e/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/index.d.ts' does not exist.", + "Resolution for module 'foo' was found in cache", + "Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'", + "======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution2.types b/tests/baselines/reference/cachedModuleResolution2.types new file mode 100644 index 00000000000..c5069e681c4 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution2.types @@ -0,0 +1,13 @@ +=== /a/b/node_modules/foo.d.ts === + +export declare let x: number +>x : number + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : number + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : number + diff --git a/tests/baselines/reference/cachedModuleResolution3.js b/tests/baselines/reference/cachedModuleResolution3.js new file mode 100644 index 00000000000..032c1afee0e --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution3.js @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/cachedModuleResolution3.ts] //// + +//// [foo.d.ts] + +export declare let x: number + +//// [app.ts] +import {x} from "foo"; + +//// [lib.ts] +import {x} from "foo"; + +//// [app.js] +"use strict"; +//// [lib.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution3.symbols b/tests/baselines/reference/cachedModuleResolution3.symbols new file mode 100644 index 00000000000..799ac6d8d84 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution3.symbols @@ -0,0 +1,13 @@ +=== /a/b/foo.d.ts === + +export declare let x: number +>x : Symbol(x, Decl(foo.d.ts, 1, 18)) + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(app.ts, 0, 8)) + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(lib.ts, 0, 8)) + diff --git a/tests/baselines/reference/cachedModuleResolution3.trace.json b/tests/baselines/reference/cachedModuleResolution3.trace.json new file mode 100644 index 00000000000..2dbaea53f47 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution3.trace.json @@ -0,0 +1,21 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "File '/a/b/c/d/e/foo.ts' does not exist.", + "File '/a/b/c/d/e/foo.tsx' does not exist.", + "File '/a/b/c/d/e/foo.d.ts' does not exist.", + "File '/a/b/c/d/foo.ts' does not exist.", + "File '/a/b/c/d/foo.tsx' does not exist.", + "File '/a/b/c/d/foo.d.ts' does not exist.", + "File '/a/b/c/foo.ts' does not exist.", + "File '/a/b/c/foo.tsx' does not exist.", + "File '/a/b/c/foo.d.ts' does not exist.", + "File '/a/b/foo.ts' does not exist.", + "File '/a/b/foo.tsx' does not exist.", + "File '/a/b/foo.d.ts' exist - use it as a name resolution result.", + "======== Module name 'foo' was successfully resolved to '/a/b/foo.d.ts'. ========", + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "Resolution for module 'foo' was found in cache", + "======== Module name 'foo' was successfully resolved to '/a/b/foo.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution3.types b/tests/baselines/reference/cachedModuleResolution3.types new file mode 100644 index 00000000000..f87abf1519e --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution3.types @@ -0,0 +1,13 @@ +=== /a/b/foo.d.ts === + +export declare let x: number +>x : number + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : number + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : number + diff --git a/tests/baselines/reference/cachedModuleResolution4.js b/tests/baselines/reference/cachedModuleResolution4.js new file mode 100644 index 00000000000..6089de9706b --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution4.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/cachedModuleResolution4.ts] //// + +//// [foo.d.ts] + +export declare let x: number + +//// [lib.ts] +import {x} from "foo"; + +//// [app.ts] +import {x} from "foo"; + + +//// [lib.js] +"use strict"; +//// [app.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution4.symbols b/tests/baselines/reference/cachedModuleResolution4.symbols new file mode 100644 index 00000000000..a30e6bf74e5 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution4.symbols @@ -0,0 +1,13 @@ +=== /a/b/foo.d.ts === + +export declare let x: number +>x : Symbol(x, Decl(foo.d.ts, 1, 18)) + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(lib.ts, 0, 8)) + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(app.ts, 0, 8)) + diff --git a/tests/baselines/reference/cachedModuleResolution4.trace.json b/tests/baselines/reference/cachedModuleResolution4.trace.json new file mode 100644 index 00000000000..7249d948e1c --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution4.trace.json @@ -0,0 +1,21 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "File '/a/b/c/foo.ts' does not exist.", + "File '/a/b/c/foo.tsx' does not exist.", + "File '/a/b/c/foo.d.ts' does not exist.", + "File '/a/b/foo.ts' does not exist.", + "File '/a/b/foo.tsx' does not exist.", + "File '/a/b/foo.d.ts' exist - use it as a name resolution result.", + "======== Module name 'foo' was successfully resolved to '/a/b/foo.d.ts'. ========", + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "File '/a/b/c/d/e/foo.ts' does not exist.", + "File '/a/b/c/d/e/foo.tsx' does not exist.", + "File '/a/b/c/d/e/foo.d.ts' does not exist.", + "File '/a/b/c/d/foo.ts' does not exist.", + "File '/a/b/c/d/foo.tsx' does not exist.", + "File '/a/b/c/d/foo.d.ts' does not exist.", + "Resolution for module 'foo' was found in cache", + "======== Module name 'foo' was successfully resolved to '/a/b/foo.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution4.types b/tests/baselines/reference/cachedModuleResolution4.types new file mode 100644 index 00000000000..3689e57ca6d --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution4.types @@ -0,0 +1,13 @@ +=== /a/b/foo.d.ts === + +export declare let x: number +>x : number + +=== /a/b/c/lib.ts === +import {x} from "foo"; +>x : number + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : number + diff --git a/tests/baselines/reference/cachedModuleResolution5.js b/tests/baselines/reference/cachedModuleResolution5.js new file mode 100644 index 00000000000..33561e8eae2 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution5.js @@ -0,0 +1,16 @@ +//// [tests/cases/compiler/cachedModuleResolution5.ts] //// + +//// [foo.d.ts] + +export declare let x: number + +//// [app.ts] +import {x} from "foo"; + +//// [lib.ts] +import {x} from "foo"; + +//// [app.js] +"use strict"; +//// [lib.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution5.symbols b/tests/baselines/reference/cachedModuleResolution5.symbols new file mode 100644 index 00000000000..eb72f0c7a27 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution5.symbols @@ -0,0 +1,13 @@ +=== /a/b/node_modules/foo.d.ts === + +export declare let x: number +>x : Symbol(x, Decl(foo.d.ts, 1, 18)) + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(app.ts, 0, 8)) + +=== /a/b/lib.ts === +import {x} from "foo"; +>x : Symbol(x, Decl(lib.ts, 0, 8)) + diff --git a/tests/baselines/reference/cachedModuleResolution5.trace.json b/tests/baselines/reference/cachedModuleResolution5.trace.json new file mode 100644 index 00000000000..d263465ff12 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution5.trace.json @@ -0,0 +1,46 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/d/e/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo.ts' does not exist.", + "File '/a/b/c/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/foo.ts' does not exist.", + "File '/a/b/node_modules/foo.tsx' does not exist.", + "File '/a/b/node_modules/foo.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'", + "======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========", + "======== Resolving module 'foo' from '/a/b/lib.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "Resolution for module 'foo' was found in cache", + "Resolving real path for '/a/b/node_modules/foo.d.ts', result '/a/b/node_modules/foo.d.ts'", + "======== Module name 'foo' was successfully resolved to '/a/b/node_modules/foo.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution5.types b/tests/baselines/reference/cachedModuleResolution5.types new file mode 100644 index 00000000000..ad2640402f7 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution5.types @@ -0,0 +1,13 @@ +=== /a/b/node_modules/foo.d.ts === + +export declare let x: number +>x : number + +=== /a/b/c/d/e/app.ts === +import {x} from "foo"; +>x : number + +=== /a/b/lib.ts === +import {x} from "foo"; +>x : number + diff --git a/tests/baselines/reference/cachedModuleResolution6.errors.txt b/tests/baselines/reference/cachedModuleResolution6.errors.txt new file mode 100644 index 00000000000..b272ff29b9d --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution6.errors.txt @@ -0,0 +1,14 @@ +/a/b/c/d/e/app.ts(2,17): error TS2307: Cannot find module 'foo'. +/a/b/c/lib.ts(1,17): error TS2307: Cannot find module 'foo'. + + +==== /a/b/c/d/e/app.ts (1 errors) ==== + + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + +==== /a/b/c/lib.ts (1 errors) ==== + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution6.js b/tests/baselines/reference/cachedModuleResolution6.js new file mode 100644 index 00000000000..f21f491a921 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution6.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/cachedModuleResolution6.ts] //// + +//// [app.ts] + +import {x} from "foo"; + +//// [lib.ts] +import {x} from "foo"; + +//// [app.js] +"use strict"; +//// [lib.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution6.trace.json b/tests/baselines/reference/cachedModuleResolution6.trace.json new file mode 100644 index 00000000000..02d52befc94 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution6.trace.json @@ -0,0 +1,102 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/d/e/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo.ts' does not exist.", + "File '/a/b/c/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/foo.ts' does not exist.", + "File '/a/b/node_modules/foo.tsx' does not exist.", + "File '/a/b/node_modules/foo.d.ts' does not exist.", + "File '/a/b/node_modules/foo/package.json' does not exist.", + "File '/a/b/node_modules/foo/index.ts' does not exist.", + "File '/a/b/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/node_modules/foo.ts' does not exist.", + "File '/a/node_modules/foo.tsx' does not exist.", + "File '/a/node_modules/foo.d.ts' does not exist.", + "File '/a/node_modules/foo/package.json' does not exist.", + "File '/a/node_modules/foo/index.ts' does not exist.", + "File '/a/node_modules/foo/index.tsx' does not exist.", + "File '/a/node_modules/foo/index.d.ts' does not exist.", + "File '/a/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/node_modules/@types/foo/package.json' does not exist.", + "File '/a/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/node_modules/foo.ts' does not exist.", + "File '/node_modules/foo.tsx' 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.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' does not exist.", + "File '/node_modules/@types/foo.d.ts' does not exist.", + "File '/node_modules/@types/foo/package.json' does not exist.", + "File '/node_modules/@types/foo/index.d.ts' does not exist.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/d/e/node_modules/foo.js' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.jsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.js' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.jsx' does not exist.", + "File '/a/b/c/d/node_modules/foo.js' does not exist.", + "File '/a/b/c/d/node_modules/foo.jsx' does not exist.", + "File '/a/b/c/d/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.js' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.jsx' does not exist.", + "File '/a/b/c/node_modules/foo.js' does not exist.", + "File '/a/b/c/node_modules/foo.jsx' does not exist.", + "File '/a/b/c/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/foo/index.js' does not exist.", + "File '/a/b/c/node_modules/foo/index.jsx' does not exist.", + "File '/a/b/node_modules/foo.js' does not exist.", + "File '/a/b/node_modules/foo.jsx' does not exist.", + "File '/a/b/node_modules/foo/package.json' does not exist.", + "File '/a/b/node_modules/foo/index.js' does not exist.", + "File '/a/b/node_modules/foo/index.jsx' does not exist.", + "File '/a/node_modules/foo.js' does not exist.", + "File '/a/node_modules/foo.jsx' does not exist.", + "File '/a/node_modules/foo/package.json' does not exist.", + "File '/a/node_modules/foo/index.js' does not exist.", + "File '/a/node_modules/foo/index.jsx' does not exist.", + "File '/node_modules/foo.js' does not exist.", + "File '/node_modules/foo.jsx' does not exist.", + "File '/node_modules/foo/package.json' does not exist.", + "File '/node_modules/foo/index.js' does not exist.", + "File '/node_modules/foo/index.jsx' does not exist.", + "======== Module name 'foo' was not resolved. ========", + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "Resolution for module 'foo' was found in cache", + "======== Module name 'foo' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution7.errors.txt b/tests/baselines/reference/cachedModuleResolution7.errors.txt new file mode 100644 index 00000000000..670c4a665a6 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution7.errors.txt @@ -0,0 +1,15 @@ +/a/b/c/d/e/app.ts(1,17): error TS2307: Cannot find module 'foo'. +/a/b/c/lib.ts(2,17): error TS2307: Cannot find module 'foo'. + + +==== /a/b/c/lib.ts (1 errors) ==== + + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + +==== /a/b/c/d/e/app.ts (1 errors) ==== + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution7.js b/tests/baselines/reference/cachedModuleResolution7.js new file mode 100644 index 00000000000..8b86dcd55af --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution7.js @@ -0,0 +1,14 @@ +//// [tests/cases/compiler/cachedModuleResolution7.ts] //// + +//// [lib.ts] + +import {x} from "foo"; + +//// [app.ts] +import {x} from "foo"; + + +//// [lib.js] +"use strict"; +//// [app.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution7.trace.json b/tests/baselines/reference/cachedModuleResolution7.trace.json new file mode 100644 index 00000000000..ce5bf08861d --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution7.trace.json @@ -0,0 +1,92 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/node_modules/foo.ts' does not exist.", + "File '/a/b/c/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/foo.ts' does not exist.", + "File '/a/b/node_modules/foo.tsx' does not exist.", + "File '/a/b/node_modules/foo.d.ts' does not exist.", + "File '/a/b/node_modules/foo/package.json' does not exist.", + "File '/a/b/node_modules/foo/index.ts' does not exist.", + "File '/a/b/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/node_modules/foo.ts' does not exist.", + "File '/a/node_modules/foo.tsx' does not exist.", + "File '/a/node_modules/foo.d.ts' does not exist.", + "File '/a/node_modules/foo/package.json' does not exist.", + "File '/a/node_modules/foo/index.ts' does not exist.", + "File '/a/node_modules/foo/index.tsx' does not exist.", + "File '/a/node_modules/foo/index.d.ts' does not exist.", + "File '/a/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/node_modules/@types/foo/package.json' does not exist.", + "File '/a/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/node_modules/foo.ts' does not exist.", + "File '/node_modules/foo.tsx' 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.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' does not exist.", + "File '/node_modules/@types/foo.d.ts' does not exist.", + "File '/node_modules/@types/foo/package.json' does not exist.", + "File '/node_modules/@types/foo/index.d.ts' does not exist.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/node_modules/foo.js' does not exist.", + "File '/a/b/c/node_modules/foo.jsx' does not exist.", + "File '/a/b/c/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/foo/index.js' does not exist.", + "File '/a/b/c/node_modules/foo/index.jsx' does not exist.", + "File '/a/b/node_modules/foo.js' does not exist.", + "File '/a/b/node_modules/foo.jsx' does not exist.", + "File '/a/b/node_modules/foo/package.json' does not exist.", + "File '/a/b/node_modules/foo/index.js' does not exist.", + "File '/a/b/node_modules/foo/index.jsx' does not exist.", + "File '/a/node_modules/foo.js' does not exist.", + "File '/a/node_modules/foo.jsx' does not exist.", + "File '/a/node_modules/foo/package.json' does not exist.", + "File '/a/node_modules/foo/index.js' does not exist.", + "File '/a/node_modules/foo/index.jsx' does not exist.", + "File '/node_modules/foo.js' does not exist.", + "File '/node_modules/foo.jsx' does not exist.", + "File '/node_modules/foo/package.json' does not exist.", + "File '/node_modules/foo/index.js' does not exist.", + "File '/node_modules/foo/index.jsx' does not exist.", + "======== Module name 'foo' was not resolved. ========", + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/a/b/c/d/e/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/e/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.ts' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.tsx' does not exist.", + "File '/a/b/c/d/node_modules/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/index.d.ts' does not exist.", + "Resolution for module 'foo' was found in cache", + "======== Module name 'foo' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution8.errors.txt b/tests/baselines/reference/cachedModuleResolution8.errors.txt new file mode 100644 index 00000000000..b272ff29b9d --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution8.errors.txt @@ -0,0 +1,14 @@ +/a/b/c/d/e/app.ts(2,17): error TS2307: Cannot find module 'foo'. +/a/b/c/lib.ts(1,17): error TS2307: Cannot find module 'foo'. + + +==== /a/b/c/d/e/app.ts (1 errors) ==== + + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + +==== /a/b/c/lib.ts (1 errors) ==== + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution8.js b/tests/baselines/reference/cachedModuleResolution8.js new file mode 100644 index 00000000000..1c00b171f21 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution8.js @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/cachedModuleResolution8.ts] //// + +//// [app.ts] + +import {x} from "foo"; + +//// [lib.ts] +import {x} from "foo"; + +//// [app.js] +"use strict"; +//// [lib.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution8.trace.json b/tests/baselines/reference/cachedModuleResolution8.trace.json new file mode 100644 index 00000000000..f833f56d819 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution8.trace.json @@ -0,0 +1,57 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "File '/a/b/c/d/e/foo.ts' does not exist.", + "File '/a/b/c/d/e/foo.tsx' does not exist.", + "File '/a/b/c/d/e/foo.d.ts' does not exist.", + "File '/a/b/c/d/foo.ts' does not exist.", + "File '/a/b/c/d/foo.tsx' does not exist.", + "File '/a/b/c/d/foo.d.ts' does not exist.", + "File '/a/b/c/foo.ts' does not exist.", + "File '/a/b/c/foo.tsx' does not exist.", + "File '/a/b/c/foo.d.ts' does not exist.", + "File '/a/b/foo.ts' does not exist.", + "File '/a/b/foo.tsx' does not exist.", + "File '/a/b/foo.d.ts' does not exist.", + "File '/a/foo.ts' does not exist.", + "File '/a/foo.tsx' does not exist.", + "File '/a/foo.d.ts' does not exist.", + "File '/foo.ts' does not exist.", + "File '/foo.tsx' does not exist.", + "File '/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/e/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/d/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/node_modules/@types/foo/package.json' does not exist.", + "File '/a/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/node_modules/@types/foo.d.ts' does not exist.", + "File '/node_modules/@types/foo/package.json' does not exist.", + "File '/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/d/e/foo.js' does not exist.", + "File '/a/b/c/d/e/foo.jsx' does not exist.", + "File '/a/b/c/d/foo.js' does not exist.", + "File '/a/b/c/d/foo.jsx' does not exist.", + "File '/a/b/c/foo.js' does not exist.", + "File '/a/b/c/foo.jsx' does not exist.", + "File '/a/b/foo.js' does not exist.", + "File '/a/b/foo.jsx' does not exist.", + "File '/a/foo.js' does not exist.", + "File '/a/foo.jsx' does not exist.", + "File '/foo.js' does not exist.", + "File '/foo.jsx' does not exist.", + "======== Module name 'foo' was not resolved. ========", + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "Resolution for module 'foo' was found in cache", + "======== Module name 'foo' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution9.errors.txt b/tests/baselines/reference/cachedModuleResolution9.errors.txt new file mode 100644 index 00000000000..aeec41f0048 --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution9.errors.txt @@ -0,0 +1,16 @@ +/a/b/c/d/e/app.ts(1,17): error TS2307: Cannot find module 'foo'. +/a/b/c/lib.ts(2,17): error TS2307: Cannot find module 'foo'. + + +==== /a/b/c/lib.ts (1 errors) ==== + + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + + +==== /a/b/c/d/e/app.ts (1 errors) ==== + import {x} from "foo"; + ~~~~~ +!!! error TS2307: Cannot find module 'foo'. + \ No newline at end of file diff --git a/tests/baselines/reference/cachedModuleResolution9.js b/tests/baselines/reference/cachedModuleResolution9.js new file mode 100644 index 00000000000..32f8848736c --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution9.js @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/cachedModuleResolution9.ts] //// + +//// [lib.ts] + +import {x} from "foo"; + + +//// [app.ts] +import {x} from "foo"; + + +//// [lib.js] +"use strict"; +//// [app.js] +"use strict"; diff --git a/tests/baselines/reference/cachedModuleResolution9.trace.json b/tests/baselines/reference/cachedModuleResolution9.trace.json new file mode 100644 index 00000000000..10a79576bfc --- /dev/null +++ b/tests/baselines/reference/cachedModuleResolution9.trace.json @@ -0,0 +1,47 @@ +[ + "======== Resolving module 'foo' from '/a/b/c/lib.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "File '/a/b/c/foo.ts' does not exist.", + "File '/a/b/c/foo.tsx' does not exist.", + "File '/a/b/c/foo.d.ts' does not exist.", + "File '/a/b/foo.ts' does not exist.", + "File '/a/b/foo.tsx' does not exist.", + "File '/a/b/foo.d.ts' does not exist.", + "File '/a/foo.ts' does not exist.", + "File '/a/foo.tsx' does not exist.", + "File '/a/foo.d.ts' does not exist.", + "File '/foo.ts' does not exist.", + "File '/foo.tsx' does not exist.", + "File '/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/c/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/c/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/b/node_modules/@types/foo/package.json' does not exist.", + "File '/a/b/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/node_modules/@types/foo.d.ts' does not exist.", + "File '/a/node_modules/@types/foo/package.json' does not exist.", + "File '/a/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/node_modules/@types/foo.d.ts' does not exist.", + "File '/node_modules/@types/foo/package.json' does not exist.", + "File '/node_modules/@types/foo/index.d.ts' does not exist.", + "File '/a/b/c/foo.js' does not exist.", + "File '/a/b/c/foo.jsx' does not exist.", + "File '/a/b/foo.js' does not exist.", + "File '/a/b/foo.jsx' does not exist.", + "File '/a/foo.js' does not exist.", + "File '/a/foo.jsx' does not exist.", + "File '/foo.js' does not exist.", + "File '/foo.jsx' does not exist.", + "======== Module name 'foo' was not resolved. ========", + "======== Resolving module 'foo' from '/a/b/c/d/e/app.ts'. ========", + "Explicitly specified module resolution kind: 'Classic'.", + "File '/a/b/c/d/e/foo.ts' does not exist.", + "File '/a/b/c/d/e/foo.tsx' does not exist.", + "File '/a/b/c/d/e/foo.d.ts' does not exist.", + "File '/a/b/c/d/foo.ts' does not exist.", + "File '/a/b/c/d/foo.tsx' does not exist.", + "File '/a/b/c/d/foo.d.ts' does not exist.", + "Resolution for module 'foo' was found in cache", + "======== Module name 'foo' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/literals.errors.txt b/tests/baselines/reference/literals.errors.txt index d43e89bb4db..6fa1d7d3abd 100644 --- a/tests/baselines/reference/literals.errors.txt +++ b/tests/baselines/reference/literals.errors.txt @@ -2,8 +2,8 @@ tests/cases/conformance/expressions/literals/literals.ts(9,10): error TS2362: Th tests/cases/conformance/expressions/literals/literals.ts(9,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/literals/literals.ts(10,9): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/literals/literals.ts(10,21): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/literals/literals.ts(20,9): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. -tests/cases/conformance/expressions/literals/literals.ts(25,10): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. +tests/cases/conformance/expressions/literals/literals.ts(20,9): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o1'. +tests/cases/conformance/expressions/literals/literals.ts(25,9): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. ==== tests/cases/conformance/expressions/literals/literals.ts (6 errors) ==== @@ -36,14 +36,14 @@ tests/cases/conformance/expressions/literals/literals.ts(25,10): error TS1085: O var n = 1e4; var n = 001; // Error in ES5 ~~~ -!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. +!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o1'. var n = 0x1; var n = -1; var n = -1.0; var n = -1e-4; var n = -003; // Error in ES5 - ~~~ -!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. + ~~~~ +!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. var n = -0x1; var s: string; diff --git a/tests/baselines/reference/mappedTypeErrors.errors.txt b/tests/baselines/reference/mappedTypeErrors.errors.txt index f98a11dbaf9..94644a96af9 100644 --- a/tests/baselines/reference/mappedTypeErrors.errors.txt +++ b/tests/baselines/reference/mappedTypeErrors.errors.txt @@ -45,9 +45,11 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(130,5): error TS2322: T tests/cases/conformance/types/mapped/mappedTypeErrors.ts(131,5): error TS2322: Type '{ a: string; }' is not assignable to type '{ [x: string]: any; a?: number | undefined; }'. Types of property 'a' are incompatible. Type 'string' is not assignable to type 'number | undefined'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(137,16): error TS2322: Type '{}' is not assignable to type 'string'. +tests/cases/conformance/types/mapped/mappedTypeErrors.ts(137,21): error TS2536: Type 'P' cannot be used to index type 'T'. -==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (24 errors) ==== +==== tests/cases/conformance/types/mapped/mappedTypeErrors.ts (26 errors) ==== interface Shape { name: string; @@ -249,4 +251,22 @@ tests/cases/conformance/types/mapped/mappedTypeErrors.ts(131,5): error TS2322: T ~~ !!! error TS2322: Type '{ a: string; }' is not assignable to type '{ [x: string]: any; a?: number | undefined; }'. !!! error TS2322: Types of property 'a' are incompatible. -!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'. \ No newline at end of file +!!! error TS2322: Type 'string' is not assignable to type 'number | undefined'. + + // Repro from #13044 + + type Foo2 = { + pf: {[P in F]?: T[P]}, + pt: {[P in T]?: T[P]}, // note: should be in keyof T + ~ +!!! error TS2322: Type '{}' is not assignable to type 'string'. + ~~~~ +!!! error TS2536: Type 'P' cannot be used to index type 'T'. + }; + type O = {x: number, y: boolean}; + let o: O = {x: 5, y: false}; + let f: Foo2 = { + pf: {x: 7}, + pt: {x: 7, y: false}, + }; + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypeErrors.js b/tests/baselines/reference/mappedTypeErrors.js index 83dc235c705..f194b6193fc 100644 --- a/tests/baselines/reference/mappedTypeErrors.js +++ b/tests/baselines/reference/mappedTypeErrors.js @@ -129,7 +129,21 @@ type T2 = { a?: number, [key: string]: any }; let x1: T2 = { a: 'no' }; // Error let x2: Partial = { a: 'no' }; // Error -let x3: { [P in keyof T2]: T2[P]} = { a: 'no' }; // Error +let x3: { [P in keyof T2]: T2[P]} = { a: 'no' }; // Error + +// Repro from #13044 + +type Foo2 = { + pf: {[P in F]?: T[P]}, + pt: {[P in T]?: T[P]}, // note: should be in keyof T +}; +type O = {x: number, y: boolean}; +let o: O = {x: 5, y: false}; +let f: Foo2 = { + pf: {x: 7}, + pt: {x: 7, y: false}, +}; + //// [mappedTypeErrors.js] function f1(x) { @@ -204,6 +218,11 @@ c.setState({ c: true }); // Error var x1 = { a: 'no' }; // Error var x2 = { a: 'no' }; // Error var x3 = { a: 'no' }; // Error +var o = { x: 5, y: false }; +var f = { + pf: { x: 7 }, + pt: { x: 7, y: false } +}; //// [mappedTypeErrors.d.ts] @@ -268,3 +287,17 @@ declare let x2: Partial; declare let x3: { [P in keyof T2]: T2[P]; }; +declare type Foo2 = { + pf: { + [P in F]?: T[P]; + }; + pt: { + [P in T]?: T[P]; + }; +}; +declare type O = { + x: number; + y: boolean; +}; +declare let o: O; +declare let f: Foo2; diff --git a/tests/baselines/reference/mappedTypesAndObjects.js b/tests/baselines/reference/mappedTypesAndObjects.js new file mode 100644 index 00000000000..53b39209693 --- /dev/null +++ b/tests/baselines/reference/mappedTypesAndObjects.js @@ -0,0 +1,72 @@ +//// [mappedTypesAndObjects.ts] + +function f1(x: Partial, y: Readonly) { + let obj: {}; + obj = x; + obj = y; +} + +function f2(x: Partial, y: Readonly) { + let obj: { [x: string]: any }; + obj = x; + obj = y; +} + +// Repro from #12900 + +interface Base { + foo: { [key: string]: any }; + bar: any; + baz: any; +} + +interface E1 extends Base { + foo: T; +} + +interface Something { name: string, value: string }; +interface E2 extends Base { + foo: Partial; // or other mapped type +} + +interface E3 extends Base { + foo: Partial; // or other mapped type +} + +//// [mappedTypesAndObjects.js] +function f1(x, y) { + var obj; + obj = x; + obj = y; +} +function f2(x, y) { + var obj; + obj = x; + obj = y; +} +; + + +//// [mappedTypesAndObjects.d.ts] +declare function f1(x: Partial, y: Readonly): void; +declare function f2(x: Partial, y: Readonly): void; +interface Base { + foo: { + [key: string]: any; + }; + bar: any; + baz: any; +} +interface E1 extends Base { + foo: T; +} +interface Something { + name: string; + value: string; +} +interface E2 extends Base { + foo: Partial; +} +interface E3 extends Base { + foo: Partial; +} diff --git a/tests/baselines/reference/mappedTypesAndObjects.symbols b/tests/baselines/reference/mappedTypesAndObjects.symbols new file mode 100644 index 00000000000..1690f1b6b04 --- /dev/null +++ b/tests/baselines/reference/mappedTypesAndObjects.symbols @@ -0,0 +1,98 @@ +=== tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts === + +function f1(x: Partial, y: Readonly) { +>f1 : Symbol(f1, Decl(mappedTypesAndObjects.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 1, 12)) +>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 1, 15)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 1, 12)) +>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 1, 29)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 1, 12)) + + let obj: {}; +>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 2, 7)) + + obj = x; +>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 2, 7)) +>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 1, 15)) + + obj = y; +>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 2, 7)) +>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 1, 29)) +} + +function f2(x: Partial, y: Readonly) { +>f2 : Symbol(f2, Decl(mappedTypesAndObjects.ts, 5, 1)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 7, 12)) +>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 7, 15)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 7, 12)) +>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 7, 29)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 7, 12)) + + let obj: { [x: string]: any }; +>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 8, 7)) +>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 8, 16)) + + obj = x; +>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 8, 7)) +>x : Symbol(x, Decl(mappedTypesAndObjects.ts, 7, 15)) + + obj = y; +>obj : Symbol(obj, Decl(mappedTypesAndObjects.ts, 8, 7)) +>y : Symbol(y, Decl(mappedTypesAndObjects.ts, 7, 29)) +} + +// Repro from #12900 + +interface Base { +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) + + foo: { [key: string]: any }; +>foo : Symbol(Base.foo, Decl(mappedTypesAndObjects.ts, 15, 16)) +>key : Symbol(key, Decl(mappedTypesAndObjects.ts, 16, 11)) + + bar: any; +>bar : Symbol(Base.bar, Decl(mappedTypesAndObjects.ts, 16, 31)) + + baz: any; +>baz : Symbol(Base.baz, Decl(mappedTypesAndObjects.ts, 17, 12)) +} + +interface E1 extends Base { +>E1 : Symbol(E1, Decl(mappedTypesAndObjects.ts, 19, 1)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13)) +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) + + foo: T; +>foo : Symbol(E1.foo, Decl(mappedTypesAndObjects.ts, 21, 30)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 21, 13)) +} + +interface Something { name: string, value: string }; +>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1)) +>name : Symbol(Something.name, Decl(mappedTypesAndObjects.ts, 25, 21)) +>value : Symbol(Something.value, Decl(mappedTypesAndObjects.ts, 25, 35)) + +interface E2 extends Base { +>E2 : Symbol(E2, Decl(mappedTypesAndObjects.ts, 25, 52)) +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) + + foo: Partial; // or other mapped type +>foo : Symbol(E2.foo, Decl(mappedTypesAndObjects.ts, 26, 27)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>Something : Symbol(Something, Decl(mappedTypesAndObjects.ts, 23, 1)) +} + +interface E3 extends Base { +>E3 : Symbol(E3, Decl(mappedTypesAndObjects.ts, 28, 1)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13)) +>Base : Symbol(Base, Decl(mappedTypesAndObjects.ts, 11, 1)) + + foo: Partial; // or other mapped type +>foo : Symbol(E3.foo, Decl(mappedTypesAndObjects.ts, 30, 30)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypesAndObjects.ts, 30, 13)) +} diff --git a/tests/baselines/reference/mappedTypesAndObjects.types b/tests/baselines/reference/mappedTypesAndObjects.types new file mode 100644 index 00000000000..e6f8e53f558 --- /dev/null +++ b/tests/baselines/reference/mappedTypesAndObjects.types @@ -0,0 +1,102 @@ +=== tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts === + +function f1(x: Partial, y: Readonly) { +>f1 : (x: Partial, y: Readonly) => void +>T : T +>x : Partial +>Partial : Partial +>T : T +>y : Readonly +>Readonly : Readonly +>T : T + + let obj: {}; +>obj : {} + + obj = x; +>obj = x : Partial +>obj : {} +>x : Partial + + obj = y; +>obj = y : Readonly +>obj : {} +>y : Readonly +} + +function f2(x: Partial, y: Readonly) { +>f2 : (x: Partial, y: Readonly) => void +>T : T +>x : Partial +>Partial : Partial +>T : T +>y : Readonly +>Readonly : Readonly +>T : T + + let obj: { [x: string]: any }; +>obj : { [x: string]: any; } +>x : string + + obj = x; +>obj = x : Partial +>obj : { [x: string]: any; } +>x : Partial + + obj = y; +>obj = y : Readonly +>obj : { [x: string]: any; } +>y : Readonly +} + +// Repro from #12900 + +interface Base { +>Base : Base + + foo: { [key: string]: any }; +>foo : { [key: string]: any; } +>key : string + + bar: any; +>bar : any + + baz: any; +>baz : any +} + +interface E1 extends Base { +>E1 : E1 +>T : T +>Base : Base + + foo: T; +>foo : T +>T : T +} + +interface Something { name: string, value: string }; +>Something : Something +>name : string +>value : string + +interface E2 extends Base { +>E2 : E2 +>Base : Base + + foo: Partial; // or other mapped type +>foo : Partial +>Partial : Partial +>Something : Something +} + +interface E3 extends Base { +>E3 : E3 +>T : T +>Base : Base + + foo: Partial; // or other mapped type +>foo : Partial +>Partial : Partial +>T : T +} diff --git a/tests/baselines/reference/metadataOfClassFromModule.js b/tests/baselines/reference/metadataOfClassFromModule.js new file mode 100644 index 00000000000..8ef120600df --- /dev/null +++ b/tests/baselines/reference/metadataOfClassFromModule.js @@ -0,0 +1,44 @@ +//// [metadataOfClassFromModule.ts] +module MyModule { + + export function inject(target: any, key: string): void { } + + export class Leg { } + + export class Person { + @inject leftLeg: Leg; + } + +} + +//// [metadataOfClassFromModule.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +var MyModule; +(function (MyModule) { + function inject(target, key) { } + MyModule.inject = inject; + var Leg = (function () { + function Leg() { + } + return Leg; + }()); + MyModule.Leg = Leg; + var Person = (function () { + function Person() { + } + return Person; + }()); + __decorate([ + inject, + __metadata("design:type", Leg) + ], Person.prototype, "leftLeg", void 0); + MyModule.Person = Person; +})(MyModule || (MyModule = {})); diff --git a/tests/baselines/reference/metadataOfClassFromModule.symbols b/tests/baselines/reference/metadataOfClassFromModule.symbols new file mode 100644 index 00000000000..f430677f0fa --- /dev/null +++ b/tests/baselines/reference/metadataOfClassFromModule.symbols @@ -0,0 +1,22 @@ +=== tests/cases/compiler/metadataOfClassFromModule.ts === +module MyModule { +>MyModule : Symbol(MyModule, Decl(metadataOfClassFromModule.ts, 0, 0)) + + export function inject(target: any, key: string): void { } +>inject : Symbol(inject, Decl(metadataOfClassFromModule.ts, 0, 17)) +>target : Symbol(target, Decl(metadataOfClassFromModule.ts, 2, 27)) +>key : Symbol(key, Decl(metadataOfClassFromModule.ts, 2, 39)) + + export class Leg { } +>Leg : Symbol(Leg, Decl(metadataOfClassFromModule.ts, 2, 62)) + + export class Person { +>Person : Symbol(Person, Decl(metadataOfClassFromModule.ts, 4, 24)) + + @inject leftLeg: Leg; +>inject : Symbol(inject, Decl(metadataOfClassFromModule.ts, 0, 17)) +>leftLeg : Symbol(Person.leftLeg, Decl(metadataOfClassFromModule.ts, 6, 25)) +>Leg : Symbol(Leg, Decl(metadataOfClassFromModule.ts, 2, 62)) + } + +} diff --git a/tests/baselines/reference/metadataOfClassFromModule.types b/tests/baselines/reference/metadataOfClassFromModule.types new file mode 100644 index 00000000000..eeb24bf82aa --- /dev/null +++ b/tests/baselines/reference/metadataOfClassFromModule.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/metadataOfClassFromModule.ts === +module MyModule { +>MyModule : typeof MyModule + + export function inject(target: any, key: string): void { } +>inject : (target: any, key: string) => void +>target : any +>key : string + + export class Leg { } +>Leg : Leg + + export class Person { +>Person : Person + + @inject leftLeg: Leg; +>inject : (target: any, key: string) => void +>leftLeg : Leg +>Leg : Leg + } + +} diff --git a/tests/baselines/reference/metadataOfUnionWithNull.js b/tests/baselines/reference/metadataOfUnionWithNull.js new file mode 100644 index 00000000000..cc594ae326d --- /dev/null +++ b/tests/baselines/reference/metadataOfUnionWithNull.js @@ -0,0 +1,113 @@ +//// [metadataOfUnionWithNull.ts] +function PropDeco(target: Object, propKey: string | symbol) { } + +class A { +} + +class B { + @PropDeco + x: "foo" | null; + + @PropDeco + y: true | never; + + @PropDeco + z: "foo" | undefined; + + @PropDeco + a: null; + + @PropDeco + b: never; + + @PropDeco + c: undefined; + + @PropDeco + d: undefined | null; + + @PropDeco + e: symbol | null; + + @PropDeco + f: symbol | A; + + @PropDeco + g: A | null; + + @PropDeco + h: null | B; + + @PropDeco + j: null | symbol; +} + +//// [metadataOfUnionWithNull.js] +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __metadata = (this && this.__metadata) || function (k, v) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); +}; +function PropDeco(target, propKey) { } +var A = (function () { + function A() { + } + return A; +}()); +var B = (function () { + function B() { + } + return B; +}()); +__decorate([ + PropDeco, + __metadata("design:type", String) +], B.prototype, "x"); +__decorate([ + PropDeco, + __metadata("design:type", Boolean) +], B.prototype, "y"); +__decorate([ + PropDeco, + __metadata("design:type", String) +], B.prototype, "z"); +__decorate([ + PropDeco, + __metadata("design:type", void 0) +], B.prototype, "a"); +__decorate([ + PropDeco, + __metadata("design:type", void 0) +], B.prototype, "b"); +__decorate([ + PropDeco, + __metadata("design:type", void 0) +], B.prototype, "c"); +__decorate([ + PropDeco, + __metadata("design:type", void 0) +], B.prototype, "d"); +__decorate([ + PropDeco, + __metadata("design:type", typeof Symbol === "function" ? Symbol : Object) +], B.prototype, "e"); +__decorate([ + PropDeco, + __metadata("design:type", Object) +], B.prototype, "f"); +__decorate([ + PropDeco, + __metadata("design:type", A) +], B.prototype, "g"); +__decorate([ + PropDeco, + __metadata("design:type", B) +], B.prototype, "h"); +__decorate([ + PropDeco, + __metadata("design:type", typeof Symbol === "function" ? Symbol : Object) +], B.prototype, "j"); diff --git a/tests/baselines/reference/metadataOfUnionWithNull.symbols b/tests/baselines/reference/metadataOfUnionWithNull.symbols new file mode 100644 index 00000000000..13316bc7cf1 --- /dev/null +++ b/tests/baselines/reference/metadataOfUnionWithNull.symbols @@ -0,0 +1,89 @@ +=== tests/cases/compiler/metadataOfUnionWithNull.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) +>target : Symbol(target, Decl(metadataOfUnionWithNull.ts, 0, 18)) +>Object : Symbol(Object, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>propKey : Symbol(propKey, Decl(metadataOfUnionWithNull.ts, 0, 33)) + +class A { +>A : Symbol(A, Decl(metadataOfUnionWithNull.ts, 0, 63)) +} + +class B { +>B : Symbol(B, Decl(metadataOfUnionWithNull.ts, 3, 1)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + x: "foo" | null; +>x : Symbol(B.x, Decl(metadataOfUnionWithNull.ts, 5, 9)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + y: true | never; +>y : Symbol(B.y, Decl(metadataOfUnionWithNull.ts, 7, 20)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + z: "foo" | undefined; +>z : Symbol(B.z, Decl(metadataOfUnionWithNull.ts, 10, 20)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + a: null; +>a : Symbol(B.a, Decl(metadataOfUnionWithNull.ts, 13, 25)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + b: never; +>b : Symbol(B.b, Decl(metadataOfUnionWithNull.ts, 16, 12)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + c: undefined; +>c : Symbol(B.c, Decl(metadataOfUnionWithNull.ts, 19, 13)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + d: undefined | null; +>d : Symbol(B.d, Decl(metadataOfUnionWithNull.ts, 22, 17)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + e: symbol | null; +>e : Symbol(B.e, Decl(metadataOfUnionWithNull.ts, 25, 24)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + f: symbol | A; +>f : Symbol(B.f, Decl(metadataOfUnionWithNull.ts, 28, 21)) +>A : Symbol(A, Decl(metadataOfUnionWithNull.ts, 0, 63)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + g: A | null; +>g : Symbol(B.g, Decl(metadataOfUnionWithNull.ts, 31, 18)) +>A : Symbol(A, Decl(metadataOfUnionWithNull.ts, 0, 63)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + h: null | B; +>h : Symbol(B.h, Decl(metadataOfUnionWithNull.ts, 34, 16)) +>B : Symbol(B, Decl(metadataOfUnionWithNull.ts, 3, 1)) + + @PropDeco +>PropDeco : Symbol(PropDeco, Decl(metadataOfUnionWithNull.ts, 0, 0)) + + j: null | symbol; +>j : Symbol(B.j, Decl(metadataOfUnionWithNull.ts, 37, 16)) +} diff --git a/tests/baselines/reference/metadataOfUnionWithNull.types b/tests/baselines/reference/metadataOfUnionWithNull.types new file mode 100644 index 00000000000..04a5b162d4c --- /dev/null +++ b/tests/baselines/reference/metadataOfUnionWithNull.types @@ -0,0 +1,97 @@ +=== tests/cases/compiler/metadataOfUnionWithNull.ts === +function PropDeco(target: Object, propKey: string | symbol) { } +>PropDeco : (target: Object, propKey: string | symbol) => void +>target : Object +>Object : Object +>propKey : string | symbol + +class A { +>A : A +} + +class B { +>B : B + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + x: "foo" | null; +>x : "foo" +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + y: true | never; +>y : true +>true : true + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + z: "foo" | undefined; +>z : "foo" + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + a: null; +>a : null +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + b: never; +>b : never + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + c: undefined; +>c : undefined + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + d: undefined | null; +>d : null +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + e: symbol | null; +>e : symbol +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + f: symbol | A; +>f : symbol | A +>A : A + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + g: A | null; +>g : A +>A : A +>null : null + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + h: null | B; +>h : B +>null : null +>B : B + + @PropDeco +>PropDeco : (target: Object, propKey: string | symbol) => void + + j: null | symbol; +>j : symbol +>null : null +} diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.js b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.js new file mode 100644 index 00000000000..b5d4ae20a4d --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/moduleResolutionWithExtensions_unexpected.ts] //// + +//// [normalize.css] +// This tests that a package.json "main" with an unexpected extension is ignored. + +This file is not read. + +//// [package.json] +{ "main": "normalize.css" } + +//// [a.ts] +import "normalize.css"; + + +//// [a.js] +"use strict"; +require("normalize.css"); diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.symbols b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.symbols new file mode 100644 index 00000000000..a73d58fd7d8 --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.symbols @@ -0,0 +1,4 @@ +=== /a.ts === +import "normalize.css"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json new file mode 100644 index 00000000000..84532e8db7b --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.trace.json @@ -0,0 +1,29 @@ +[ + "======== Resolving module 'normalize.css' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'normalize.css' from 'node_modules' folder.", + "File '/node_modules/normalize.css.ts' does not exist.", + "File '/node_modules/normalize.css.tsx' does not exist.", + "File '/node_modules/normalize.css.d.ts' does not exist.", + "Found 'package.json' at '/node_modules/normalize.css/package.json'.", + "'package.json' does not have a 'types' or 'main' field.", + "File '/node_modules/normalize.css/index.ts' does not exist.", + "File '/node_modules/normalize.css/index.tsx' does not exist.", + "File '/node_modules/normalize.css/index.d.ts' does not exist.", + "File '/node_modules/@types/normalize.css.d.ts' does not exist.", + "File '/node_modules/@types/normalize.css/package.json' does not exist.", + "File '/node_modules/@types/normalize.css/index.d.ts' does not exist.", + "Loading module 'normalize.css' from 'node_modules' folder.", + "File '/node_modules/normalize.css.js' does not exist.", + "File '/node_modules/normalize.css.jsx' does not exist.", + "Found 'package.json' at '/node_modules/normalize.css/package.json'.", + "No types specified in 'package.json', so returning 'main' value of 'normalize.css'", + "File '/node_modules/normalize.css/normalize.css' exist - use it as a name resolution result.", + "File '/node_modules/normalize.css/normalize.css' has an unsupported extension, so skipping it.", + "File '/node_modules/normalize.css/normalize.css.ts' does not exist.", + "File '/node_modules/normalize.css/normalize.css.tsx' does not exist.", + "File '/node_modules/normalize.css/normalize.css.d.ts' does not exist.", + "File '/node_modules/normalize.css/index.js' does not exist.", + "File '/node_modules/normalize.css/index.jsx' does not exist.", + "======== Module name 'normalize.css' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.types b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.types new file mode 100644 index 00000000000..a73d58fd7d8 --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected.types @@ -0,0 +1,4 @@ +=== /a.ts === +import "normalize.css"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.js b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.js new file mode 100644 index 00000000000..dc9df79e4df --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.js @@ -0,0 +1,17 @@ +//// [tests/cases/compiler/moduleResolutionWithExtensions_unexpected2.ts] //// + +//// [foo.js] +// This tests that a package.json "types" with an unexpected extension is ignored. + +This file is not read. + +//// [package.json] +{ "types": "foo.js" } + +//// [a.ts] +import "foo"; + + +//// [a.js] +"use strict"; +require("foo"); diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.symbols b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.symbols new file mode 100644 index 00000000000..11c9c72cc69 --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.symbols @@ -0,0 +1,4 @@ +=== /a.ts === +import "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json new file mode 100644 index 00000000000..27c9d2243e5 --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.trace.json @@ -0,0 +1,29 @@ +[ + "======== Resolving module 'foo' from '/a.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/node_modules/foo.ts' does not exist.", + "File '/node_modules/foo.tsx' does not exist.", + "File '/node_modules/foo.d.ts' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "'package.json' has 'types' field 'foo.js' that references '/node_modules/foo/foo.js'.", + "File '/node_modules/foo/foo.js' exist - use it as a name resolution result.", + "File '/node_modules/foo/foo.js' has an unsupported extension, so skipping it.", + "File '/node_modules/foo/foo.js.ts' does not exist.", + "File '/node_modules/foo/foo.js.tsx' does not exist.", + "File '/node_modules/foo/foo.js.d.ts' does not exist.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' does not exist.", + "File '/node_modules/@types/foo.d.ts' does not exist.", + "File '/node_modules/@types/foo/package.json' does not exist.", + "File '/node_modules/@types/foo/index.d.ts' does not exist.", + "Loading module 'foo' from 'node_modules' folder.", + "File '/node_modules/foo.js' does not exist.", + "File '/node_modules/foo.jsx' does not exist.", + "Found 'package.json' at '/node_modules/foo/package.json'.", + "'package.json' does not have a 'types' or 'main' field.", + "File '/node_modules/foo/index.js' does not exist.", + "File '/node_modules/foo/index.jsx' does not exist.", + "======== Module name 'foo' was not resolved. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.types b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.types new file mode 100644 index 00000000000..11c9c72cc69 --- /dev/null +++ b/tests/baselines/reference/moduleResolutionWithExtensions_unexpected2.types @@ -0,0 +1,4 @@ +=== /a.ts === +import "foo"; +No type information for this code. +No type information for this code. \ No newline at end of file diff --git a/tests/baselines/reference/objectLiteralErrors.errors.txt b/tests/baselines/reference/objectLiteralErrors.errors.txt index 234ac24a8fd..03b4b74eacd 100644 --- a/tests/baselines/reference/objectLiteralErrors.errors.txt +++ b/tests/baselines/reference/objectLiteralErrors.errors.txt @@ -12,7 +12,7 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(13,21) tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(14,19): error TS2300: Duplicate identifier '0'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(15,19): error TS2300: Duplicate identifier '0'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(16,19): error TS2300: Duplicate identifier '0x0'. -tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(17,19): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. +tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(17,19): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o0'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(17,19): error TS2300: Duplicate identifier '000'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(18,23): error TS2300: Duplicate identifier '1e2'. tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(19,22): error TS2300: Duplicate identifier '3.2e1'. @@ -125,7 +125,7 @@ tests/cases/conformance/expressions/objectLiterals/objectLiteralErrors.ts(45,55) !!! error TS2300: Duplicate identifier '0x0'. var e14 = { 0: 0, 000: 0 }; ~~~ -!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. +!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o0'. ~~~ !!! error TS2300: Duplicate identifier '000'. var e15 = { "100": 0, 1e2: 0 }; diff --git a/tests/baselines/reference/oldStyleOctalLiteralTypes.errors.txt b/tests/baselines/reference/oldStyleOctalLiteralTypes.errors.txt new file mode 100644 index 00000000000..7d42963b05d --- /dev/null +++ b/tests/baselines/reference/oldStyleOctalLiteralTypes.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/oldStyleOctalLiteralTypes.ts(1,8): error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '0o10'. +tests/cases/compiler/oldStyleOctalLiteralTypes.ts(2,8): error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '-0o20'. + + +==== tests/cases/compiler/oldStyleOctalLiteralTypes.ts (2 errors) ==== + let x: 010; + ~~~ +!!! error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '0o10'. + let y: -020; + ~~~~ +!!! error TS8017: Octal literal types must use ES2015 syntax. Use the syntax '-0o20'. + \ No newline at end of file diff --git a/tests/baselines/reference/oldStyleOctalLiteralTypes.js b/tests/baselines/reference/oldStyleOctalLiteralTypes.js new file mode 100644 index 00000000000..28b275774c3 --- /dev/null +++ b/tests/baselines/reference/oldStyleOctalLiteralTypes.js @@ -0,0 +1,8 @@ +//// [oldStyleOctalLiteralTypes.ts] +let x: 010; +let y: -020; + + +//// [oldStyleOctalLiteralTypes.js] +var x; +var y; diff --git a/tests/baselines/reference/scannerNumericLiteral2.errors.txt b/tests/baselines/reference/scannerNumericLiteral2.errors.txt index 5860be78c1b..faf5429f8b7 100644 --- a/tests/baselines/reference/scannerNumericLiteral2.errors.txt +++ b/tests/baselines/reference/scannerNumericLiteral2.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral2.ts(1,1): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. +tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral2.ts(1,1): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o1'. ==== tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral2.ts (1 errors) ==== 01 ~~ -!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. \ No newline at end of file +!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '0o1'. \ No newline at end of file diff --git a/tests/baselines/reference/scannerNumericLiteral8.errors.txt b/tests/baselines/reference/scannerNumericLiteral8.errors.txt index 94916626fe6..6545050afc2 100644 --- a/tests/baselines/reference/scannerNumericLiteral8.errors.txt +++ b/tests/baselines/reference/scannerNumericLiteral8.errors.txt @@ -1,7 +1,7 @@ -tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral8.ts(1,2): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. +tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral8.ts(1,1): error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. ==== tests/cases/conformance/scanner/ecmascript5/scannerNumericLiteral8.ts (1 errors) ==== -03 - ~~ -!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. \ No newline at end of file + ~~~ +!!! error TS1085: Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '-0o3'. \ No newline at end of file diff --git a/tests/baselines/reference/typeReferenceDirectives12.trace.json b/tests/baselines/reference/typeReferenceDirectives12.trace.json index f232228a351..5f87ab7ea39 100644 --- a/tests/baselines/reference/typeReferenceDirectives12.trace.json +++ b/tests/baselines/reference/typeReferenceDirectives12.trace.json @@ -16,9 +16,7 @@ "Resolving real path for '/types/lib/index.d.ts', result '/types/lib/index.d.ts'", "======== Type reference directive 'lib' was successfully resolved to '/types/lib/index.d.ts', primary: true. ========", "======== Resolving module './main' from '/mod1.ts'. ========", - "Module resolution kind is not specified, using 'NodeJs'.", - "Loading module as file / folder, candidate module location '/main'.", - "File '/main.ts' exist - use it as a name resolution result.", + "Resolution for module './main' was found in cache", "======== Module name './main' was successfully resolved to '/main.ts'. ========", "======== Resolving type reference directive 'lib', containing file '/__inferred type names__.ts', root directory '/types'. ========", "Resolving with primary search path '/types'", diff --git a/tests/baselines/reference/typeReferenceDirectives9.trace.json b/tests/baselines/reference/typeReferenceDirectives9.trace.json index f232228a351..5f87ab7ea39 100644 --- a/tests/baselines/reference/typeReferenceDirectives9.trace.json +++ b/tests/baselines/reference/typeReferenceDirectives9.trace.json @@ -16,9 +16,7 @@ "Resolving real path for '/types/lib/index.d.ts', result '/types/lib/index.d.ts'", "======== Type reference directive 'lib' was successfully resolved to '/types/lib/index.d.ts', primary: true. ========", "======== Resolving module './main' from '/mod1.ts'. ========", - "Module resolution kind is not specified, using 'NodeJs'.", - "Loading module as file / folder, candidate module location '/main'.", - "File '/main.ts' exist - use it as a name resolution result.", + "Resolution for module './main' was found in cache", "======== Module name './main' was successfully resolved to '/main.ts'. ========", "======== Resolving type reference directive 'lib', containing file '/__inferred type names__.ts', root directory '/types'. ========", "Resolving with primary search path '/types'", diff --git a/tests/baselines/reference/unusedLocalsAndObjectSpread2.errors.txt b/tests/baselines/reference/unusedLocalsAndObjectSpread2.errors.txt new file mode 100644 index 00000000000..2d1c36d3cbf --- /dev/null +++ b/tests/baselines/reference/unusedLocalsAndObjectSpread2.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(6,6): error TS6133: 'rest' is declared but never used. +tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(9,10): error TS6133: 'foo' is declared but never used. +tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(13,8): error TS6133: 'rest' is declared but never used. + + +==== tests/cases/compiler/unusedLocalsAndObjectSpread2.ts (3 errors) ==== + + declare let props: any; + const { + children, // here! + active: _a, // here! + ...rest, + ~~~~ +!!! error TS6133: 'rest' is declared but never used. + } = props; + + function foo() { + ~~~ +!!! error TS6133: 'foo' is declared but never used. + const { + children, + active: _a, + ...rest, + ~~~~ +!!! error TS6133: 'rest' is declared but never used. + } = props; + } + + export const asdf = 123; \ No newline at end of file diff --git a/tests/baselines/reference/unusedLocalsAndObjectSpread2.js b/tests/baselines/reference/unusedLocalsAndObjectSpread2.js new file mode 100644 index 00000000000..e6cd890abb7 --- /dev/null +++ b/tests/baselines/reference/unusedLocalsAndObjectSpread2.js @@ -0,0 +1,37 @@ +//// [unusedLocalsAndObjectSpread2.ts] + +declare let props: any; +const { + children, // here! + active: _a, // here! + ...rest, +} = props; + +function foo() { + const { + children, + active: _a, + ...rest, + } = props; +} + +export const asdf = 123; + +//// [unusedLocalsAndObjectSpread2.js] +"use strict"; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; +}; +var children = props.children, // here! +_a = props.active, // here! +rest = __rest(props, ["children", "active"]); +function foo() { + var children = props.children, _a = props.active, rest = __rest(props, ["children", "active"]); +} +exports.asdf = 123; diff --git a/tests/cases/compiler/cacheResolutions.ts b/tests/cases/compiler/cacheResolutions.ts new file mode 100644 index 00000000000..c6962e25db6 --- /dev/null +++ b/tests/cases/compiler/cacheResolutions.ts @@ -0,0 +1,12 @@ +// @module: amd +// @importHelpers: true +// @traceResolution: true + +// @filename: /a/b/c/app.ts +export let x = 1; + +// @filename: /a/b/c/lib1.ts +export let x = 1; + +// @filename: /a/b/c/lib2.ts +export let x = 1; \ No newline at end of file diff --git a/tests/cases/compiler/cachedModuleResolution1.ts b/tests/cases/compiler/cachedModuleResolution1.ts new file mode 100644 index 00000000000..3ef09ea0ea5 --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution1.ts @@ -0,0 +1,11 @@ +// @moduleResolution: node +// @traceResolution: true + +// @filename: /a/b/node_modules/foo.d.ts +export declare let x: number + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; \ No newline at end of file diff --git a/tests/cases/compiler/cachedModuleResolution2.ts b/tests/cases/compiler/cachedModuleResolution2.ts new file mode 100644 index 00000000000..38aaf4e609d --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution2.ts @@ -0,0 +1,11 @@ +// @moduleResolution: node +// @traceResolution: true + +// @filename: /a/b/node_modules/foo.d.ts +export declare let x: number + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; diff --git a/tests/cases/compiler/cachedModuleResolution3.ts b/tests/cases/compiler/cachedModuleResolution3.ts new file mode 100644 index 00000000000..e1e7aebbe86 --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution3.ts @@ -0,0 +1,11 @@ +// @moduleResolution: classic +// @traceResolution: true + +// @filename: /a/b/foo.d.ts +export declare let x: number + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; \ No newline at end of file diff --git a/tests/cases/compiler/cachedModuleResolution4.ts b/tests/cases/compiler/cachedModuleResolution4.ts new file mode 100644 index 00000000000..98cdd14189a --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution4.ts @@ -0,0 +1,11 @@ +// @moduleResolution: classic +// @traceResolution: true + +// @filename: /a/b/foo.d.ts +export declare let x: number + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; diff --git a/tests/cases/compiler/cachedModuleResolution5.ts b/tests/cases/compiler/cachedModuleResolution5.ts new file mode 100644 index 00000000000..e37b14fc1a0 --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution5.ts @@ -0,0 +1,11 @@ +// @moduleResolution: node +// @traceResolution: true + +// @filename: /a/b/node_modules/foo.d.ts +export declare let x: number + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; + +// @filename: /a/b/lib.ts +import {x} from "foo"; \ No newline at end of file diff --git a/tests/cases/compiler/cachedModuleResolution6.ts b/tests/cases/compiler/cachedModuleResolution6.ts new file mode 100644 index 00000000000..2c412e361c6 --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution6.ts @@ -0,0 +1,8 @@ +// @moduleResolution: node +// @traceResolution: true + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; \ No newline at end of file diff --git a/tests/cases/compiler/cachedModuleResolution7.ts b/tests/cases/compiler/cachedModuleResolution7.ts new file mode 100644 index 00000000000..d297e2a8ecd --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution7.ts @@ -0,0 +1,8 @@ +// @moduleResolution: node +// @traceResolution: true + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; diff --git a/tests/cases/compiler/cachedModuleResolution8.ts b/tests/cases/compiler/cachedModuleResolution8.ts new file mode 100644 index 00000000000..52c91be7753 --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution8.ts @@ -0,0 +1,8 @@ +// @moduleResolution: classic +// @traceResolution: true + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; \ No newline at end of file diff --git a/tests/cases/compiler/cachedModuleResolution9.ts b/tests/cases/compiler/cachedModuleResolution9.ts new file mode 100644 index 00000000000..26d71fa86ff --- /dev/null +++ b/tests/cases/compiler/cachedModuleResolution9.ts @@ -0,0 +1,9 @@ +// @moduleResolution: classic +// @traceResolution: true + +// @filename: /a/b/c/lib.ts +import {x} from "foo"; + + +// @filename: /a/b/c/d/e/app.ts +import {x} from "foo"; diff --git a/tests/cases/compiler/metadataOfClassFromModule.ts b/tests/cases/compiler/metadataOfClassFromModule.ts new file mode 100644 index 00000000000..aca356f2247 --- /dev/null +++ b/tests/cases/compiler/metadataOfClassFromModule.ts @@ -0,0 +1,14 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +// @target: es5 +module MyModule { + + export function inject(target: any, key: string): void { } + + export class Leg { } + + export class Person { + @inject leftLeg: Leg; + } + +} \ No newline at end of file diff --git a/tests/cases/compiler/metadataOfUnionWithNull.ts b/tests/cases/compiler/metadataOfUnionWithNull.ts new file mode 100644 index 00000000000..bb4d93189fc --- /dev/null +++ b/tests/cases/compiler/metadataOfUnionWithNull.ts @@ -0,0 +1,44 @@ +// @experimentalDecorators: true +// @emitDecoratorMetadata: true +function PropDeco(target: Object, propKey: string | symbol) { } + +class A { +} + +class B { + @PropDeco + x: "foo" | null; + + @PropDeco + y: true | never; + + @PropDeco + z: "foo" | undefined; + + @PropDeco + a: null; + + @PropDeco + b: never; + + @PropDeco + c: undefined; + + @PropDeco + d: undefined | null; + + @PropDeco + e: symbol | null; + + @PropDeco + f: symbol | A; + + @PropDeco + g: A | null; + + @PropDeco + h: null | B; + + @PropDeco + j: null | symbol; +} \ No newline at end of file diff --git a/tests/cases/compiler/moduleResolutionWithExtensions_unexpected.ts b/tests/cases/compiler/moduleResolutionWithExtensions_unexpected.ts new file mode 100644 index 00000000000..3af02eabb76 --- /dev/null +++ b/tests/cases/compiler/moduleResolutionWithExtensions_unexpected.ts @@ -0,0 +1,12 @@ +// @noImplicitReferences: true +// @traceResolution: true +// This tests that a package.json "main" with an unexpected extension is ignored. + +// @Filename: /node_modules/normalize.css/normalize.css +This file is not read. + +// @Filename: /node_modules/normalize.css/package.json +{ "main": "normalize.css" } + +// @Filename: /a.ts +import "normalize.css"; diff --git a/tests/cases/compiler/moduleResolutionWithExtensions_unexpected2.ts b/tests/cases/compiler/moduleResolutionWithExtensions_unexpected2.ts new file mode 100644 index 00000000000..1c960fa67e9 --- /dev/null +++ b/tests/cases/compiler/moduleResolutionWithExtensions_unexpected2.ts @@ -0,0 +1,12 @@ +// @noImplicitReferences: true +// @traceResolution: true +// This tests that a package.json "types" with an unexpected extension is ignored. + +// @Filename: /node_modules/foo/foo.js +This file is not read. + +// @Filename: /node_modules/foo/package.json +{ "types": "foo.js" } + +// @Filename: /a.ts +import "foo"; diff --git a/tests/cases/compiler/oldStyleOctalLiteralTypes.ts b/tests/cases/compiler/oldStyleOctalLiteralTypes.ts new file mode 100644 index 00000000000..c5a5475e300 --- /dev/null +++ b/tests/cases/compiler/oldStyleOctalLiteralTypes.ts @@ -0,0 +1,3 @@ +// @target: ES3 +let x: 010; +let y: -020; diff --git a/tests/cases/compiler/unusedLocalsAndObjectSpread2.ts b/tests/cases/compiler/unusedLocalsAndObjectSpread2.ts new file mode 100644 index 00000000000..e55c2042a41 --- /dev/null +++ b/tests/cases/compiler/unusedLocalsAndObjectSpread2.ts @@ -0,0 +1,18 @@ +//@noUnusedLocals:true + +declare let props: any; +const { + children, // here! + active: _a, // here! + ...rest, +} = props; + +function foo() { + const { + children, + active: _a, + ...rest, + } = props; +} + +export const asdf = 123; \ No newline at end of file diff --git a/tests/cases/conformance/types/mapped/mappedTypeErrors.ts b/tests/cases/conformance/types/mapped/mappedTypeErrors.ts index 458dbe9caa4..cec1fbf8395 100644 --- a/tests/cases/conformance/types/mapped/mappedTypeErrors.ts +++ b/tests/cases/conformance/types/mapped/mappedTypeErrors.ts @@ -130,4 +130,17 @@ type T2 = { a?: number, [key: string]: any }; let x1: T2 = { a: 'no' }; // Error let x2: Partial = { a: 'no' }; // Error -let x3: { [P in keyof T2]: T2[P]} = { a: 'no' }; // Error \ No newline at end of file +let x3: { [P in keyof T2]: T2[P]} = { a: 'no' }; // Error + +// Repro from #13044 + +type Foo2 = { + pf: {[P in F]?: T[P]}, + pt: {[P in T]?: T[P]}, // note: should be in keyof T +}; +type O = {x: number, y: boolean}; +let o: O = {x: 5, y: false}; +let f: Foo2 = { + pf: {x: 7}, + pt: {x: 7, y: false}, +}; diff --git a/tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts b/tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts new file mode 100644 index 00000000000..8023f6e7d8d --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypesAndObjects.ts @@ -0,0 +1,35 @@ +// @strictNullChecks: true +// @declaration: true + +function f1(x: Partial, y: Readonly) { + let obj: {}; + obj = x; + obj = y; +} + +function f2(x: Partial, y: Readonly) { + let obj: { [x: string]: any }; + obj = x; + obj = y; +} + +// Repro from #12900 + +interface Base { + foo: { [key: string]: any }; + bar: any; + baz: any; +} + +interface E1 extends Base { + foo: T; +} + +interface Something { name: string, value: string }; +interface E2 extends Base { + foo: Partial; // or other mapped type +} + +interface E3 extends Base { + foo: Partial; // or other mapped type +} \ No newline at end of file diff --git a/tests/cases/fourslash/formattingMappedType.ts b/tests/cases/fourslash/formattingMappedType.ts new file mode 100644 index 00000000000..a33d948a9c3 --- /dev/null +++ b/tests/cases/fourslash/formattingMappedType.ts @@ -0,0 +1,12 @@ +/// + +/////*generic*/type t < T > = { +/////*map*/ [ P in keyof T ] : T [ P ] +////}; + + +format.document(); +goTo.marker("generic"); +verify.currentLineContentIs("type t = {"); +goTo.marker("map"); +verify.currentLineContentIs(" [P in keyof T]: T[P]"); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingReadonly.ts b/tests/cases/fourslash/formattingReadonly.ts new file mode 100644 index 00000000000..e9ec9860032 --- /dev/null +++ b/tests/cases/fourslash/formattingReadonly.ts @@ -0,0 +1,12 @@ +/// + +////class C { +//// readonly property1 {};/*1*/ +//// public readonly property2 {};/*2*/ +////} + +format.document(); +goTo.marker("1"); +verify.currentLineContentIs(" readonly property1 {};"); +goTo.marker("2"); +verify.currentLineContentIs(" public readonly property2 {};"); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingSpaceBeforeFunctionParen.ts b/tests/cases/fourslash/formattingSpaceBeforeFunctionParen.ts new file mode 100644 index 00000000000..ce85521879e --- /dev/null +++ b/tests/cases/fourslash/formattingSpaceBeforeFunctionParen.ts @@ -0,0 +1,19 @@ +/// + +/////*1*/function foo() { } +/////*2*/function boo () { } +/////*3*/var bar = function foo() { }; +/////*4*/var foo = { bar() { } }; + +format.setOption("InsertSpaceBeforeFunctionParenthesis", true); + +format.document(); + +goTo.marker('1'); +verify.currentLineContentIs('function foo () { }'); +goTo.marker('2'); +verify.currentLineContentIs('function boo () { }'); +goTo.marker('3'); +verify.currentLineContentIs('var bar = function foo () { };'); +goTo.marker('4'); +verify.currentLineContentIs('var foo = { bar () { } };'); \ No newline at end of file diff --git a/tests/cases/fourslash/formattingSpacesAfterConstructor.ts b/tests/cases/fourslash/formattingSpacesAfterConstructor.ts index 8df762def20..2195d74adbc 100644 --- a/tests/cases/fourslash/formattingSpacesAfterConstructor.ts +++ b/tests/cases/fourslash/formattingSpacesAfterConstructor.ts @@ -3,4 +3,11 @@ /////*1*/class test { constructor () { } } format.document(); goTo.marker("1"); -verify.currentLineContentIs("class test { constructor() { } }"); \ No newline at end of file +verify.currentLineContentIs("class test { constructor() { } }"); + +/////*2*/class test { constructor () { } } +format.setOption("InsertSpaceAfterConstructor", true); + +format.document(); +goTo.marker("2"); +verify.currentLineContentIs("class test { constructor () { } }"); \ No newline at end of file diff --git a/tests/cases/fourslash/jsDocGenerics2.ts b/tests/cases/fourslash/jsDocGenerics2.ts new file mode 100644 index 00000000000..23deb1a6502 --- /dev/null +++ b/tests/cases/fourslash/jsDocGenerics2.ts @@ -0,0 +1,19 @@ +/// +// @allowNonTsExtensions: true +// @Filename: Foo.js + +/////** +//// * @param {T[]} arr +//// * @param {(function(T):T)} valuator +//// * @template T +//// */ +////function SortFilter(arr,valuator) +////{ +//// return arr; +////} +////var a/*1*/ = SortFilter([0, 1, 2], q/*2*/ => q); +////var b/*3*/ = SortFilter([0, 1, 2], undefined); + +verify.quickInfoAt('1', "var a: number[]"); +verify.quickInfoAt('2', '(parameter) q: number'); +verify.quickInfoAt('3', "var b: number[]");