diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 5b48a69fa04..8b6ff01dd20 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1698,6 +1698,7 @@ namespace ts { symbol.parent = container.symbol; } addDeclarationToSymbol(symbol, node, symbolFlags); + return symbol; } function bindBlockScopedDeclaration(node: Declaration, symbolFlags: SymbolFlags, symbolExcludes: SymbolFlags) { @@ -2317,13 +2318,11 @@ namespace ts { // expression is the declaration setCommonJsModuleIndicator(node); const lhs = node.left as PropertyAccessEntityNameExpression; - const symbol = forEachIdentifierInEntityName(lhs.expression, (id, original) => { - if (!original) { - return undefined; + const symbol = forEachIdentifierInEntityName(lhs.expression, /*parent*/ undefined, (id, symbol) => { + if (symbol) { + addDeclarationToSymbol(symbol, id, SymbolFlags.Module | SymbolFlags.JSContainer); } - const s = getJSInitializerSymbol(original)!; - addDeclarationToSymbol(s, id, SymbolFlags.Module | SymbolFlags.JSContainer); - return s; + return symbol; }); if (symbol) { const flags = isClassExpression(node.right) ? @@ -2359,12 +2358,12 @@ namespace ts { switch (thisContainer.kind) { case SyntaxKind.FunctionDeclaration: case SyntaxKind.FunctionExpression: - let constructorSymbol = thisContainer.symbol; + let constructorSymbol: Symbol | undefined = thisContainer.symbol; // For `f.prototype.m = function() { this.x = 0; }`, `this.x = 0` should modify `f`'s members, not the function expression. if (isBinaryExpression(thisContainer.parent) && thisContainer.parent.operatorToken.kind === SyntaxKind.EqualsToken) { const l = thisContainer.parent.left; if (isPropertyAccessEntityNameExpression(l) && isPrototypeAccess(l.expression)) { - constructorSymbol = getJSInitializerSymbolFromName(l.expression.expression, thisParentContainer)!; + constructorSymbol = lookupSymbolForPropertyAccess(l.expression.expression, thisParentContainer); } } @@ -2463,46 +2462,68 @@ namespace ts { bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false); } - function getJSInitializerSymbolFromName(name: EntityNameExpression, lookupContainer?: Node): Symbol | undefined { - return getJSInitializerSymbol(lookupSymbolForPropertyAccess(name, lookupContainer)); - } - function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) { - let symbol = getJSInitializerSymbolFromName(name); + let namespaceSymbol = lookupSymbolForPropertyAccess(name); const isToplevelNamespaceableInitializer = isBinaryExpression(propertyAccess.parent) ? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile && !!getJavascriptInitializer(getInitializerOfBinaryExpression(propertyAccess.parent), isPrototypeAccess(propertyAccess.parent.left)) : propertyAccess.parent.parent.kind === SyntaxKind.SourceFile; - if (!isPrototypeProperty && (!symbol || !(symbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) { + if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) { // make symbols or add declarations for intermediate containers const flags = SymbolFlags.Module | SymbolFlags.JSContainer; const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer; - forEachIdentifierInEntityName(propertyAccess.expression, (id, original) => { - if (original) { - // Note: add declaration to original symbol, not the special-syntax's symbol, so that namespaces work for type lookup - addDeclarationToSymbol(original, id, flags); - return original; + namespaceSymbol = forEachIdentifierInEntityName(propertyAccess.expression, namespaceSymbol, (id, symbol, parent) => { + if (symbol) { + addDeclarationToSymbol(symbol, id, flags); + return symbol; } else { - return symbol = declareSymbol(symbol ? symbol.exports! : container.locals!, symbol, id, flags, excludeFlags); + return declareSymbol(parent ? parent.exports! : container.locals!, parent, id, flags, excludeFlags); } }); } - if (!symbol || !(symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.NamespaceModule | SymbolFlags.ObjectLiteral))) { + if (!namespaceSymbol || !isJavascriptContainer(namespaceSymbol)) { return; } // Set up the members collection if it doesn't exist already const symbolTable = isPrototypeProperty ? - (symbol.members || (symbol.members = createSymbolTable())) : - (symbol.exports || (symbol.exports = createSymbolTable())); + (namespaceSymbol.members || (namespaceSymbol.members = createSymbolTable())) : + (namespaceSymbol.exports || (namespaceSymbol.exports = createSymbolTable())); // Declare the method/property const jsContainerFlag = isToplevelNamespaceableInitializer ? SymbolFlags.JSContainer : 0; - const isMethod = isFunctionLikeDeclaration(getAssignedJavascriptInitializer(propertyAccess)!); // TODO: GH#18217 + const isMethod = isFunctionLikeDeclaration(getAssignedJavascriptInitializer(propertyAccess)!); const symbolFlags = (isMethod ? SymbolFlags.Method : SymbolFlags.Property) | jsContainerFlag; const symbolExcludes = (isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes) & ~jsContainerFlag; - declareSymbol(symbolTable, symbol, propertyAccess, symbolFlags, symbolExcludes); + declareSymbol(symbolTable, namespaceSymbol, propertyAccess, symbolFlags, symbolExcludes); + } + + /** + * Javascript containers are: + * - Functions + * - classes + * - namespaces + * - variables initialized with function expressions + * - with class expressions + * - with empty object literals + * - with non-empty object literals if assigned to the prototype property + */ + function isJavascriptContainer(symbol: Symbol): boolean { + if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Class | SymbolFlags.NamespaceModule)) { + return true; + } + const node = symbol.valueDeclaration; + const init = !node ? undefined : + isVariableDeclaration(node) ? node.initializer : + isBinaryExpression(node) ? node.right : + isPropertyAccessExpression(node) && isBinaryExpression(node.parent) ? node.parent.right : + undefined; + if (init) { + const isPrototypeAssignment = isPrototypeAccess(isVariableDeclaration(node) ? node.name : isBinaryExpression(node) ? node.left : node); + return !!getJavascriptInitializer(isBinaryExpression(init) && init.operatorToken.kind === SyntaxKind.BarBarToken ? init.right : init, isPrototypeAssignment); + } + return false; } function getParentOfBinaryExpression(expr: BinaryExpression) { @@ -2517,22 +2538,22 @@ namespace ts { return lookupSymbolForNameWorker(lookupContainer, node.escapedText); } else { - const symbol = getJSInitializerSymbol(lookupSymbolForPropertyAccess(node.expression)); + const symbol = lookupSymbolForPropertyAccess(node.expression); return symbol && symbol.exports && symbol.exports.get(node.name.escapedText); } } - function forEachIdentifierInEntityName(e: EntityNameExpression, action: (e: Identifier, symbol: Symbol | undefined) => Symbol | undefined): Symbol | undefined { + function forEachIdentifierInEntityName(e: EntityNameExpression, parent: Symbol | undefined, action: (e: Identifier, symbol: Symbol | undefined, parent: Symbol | undefined) => Symbol | undefined): Symbol | undefined { if (isExportsOrModuleExportsOrAlias(file, e)) { return file.symbol; } else if (isIdentifier(e)) { - return action(e, lookupSymbolForPropertyAccess(e)); + return action(e, lookupSymbolForPropertyAccess(e), parent); } else { - const s = getJSInitializerSymbol(forEachIdentifierInEntityName(e.expression, action)); + const s = forEachIdentifierInEntityName(e.expression, parent, action); if (!s || !s.exports) return Debug.fail(); - return action(e.name, s.exports.get(e.name.escapedText)); + return action(e.name, s.exports.get(e.name.escapedText), s); } } @@ -2596,7 +2617,7 @@ namespace ts { bindBlockScopedVariableDeclaration(node); } else if (isParameterDeclaration(node)) { - // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration + // It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration // because its parent chain has already been set up, since parents are set before descending into children. // // If node is a binding element in parameter declaration, we need to use ParameterExcludes. diff --git a/src/compiler/builder.ts b/src/compiler/builder.ts index a4f3bbefac2..fc52559a318 100644 --- a/src/compiler/builder.ts +++ b/src/compiler/builder.ts @@ -549,8 +549,8 @@ namespace ts { * Create the builder to manage semantic diagnostics and cache them */ export function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; - export function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; - export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray) { + export function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; + export function createSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray | SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray) { return createBuilderProgram(BuilderProgramKind.SemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics)); } @@ -559,8 +559,8 @@ namespace ts { * to emit the those files and manage semantic diagnostics cache as well */ export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; - export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; - export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray) { + export function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; + export function createEmitAndSemanticDiagnosticsBuilderProgram(newProgramOrRootNames: Program | ReadonlyArray | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray | EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray) { return createBuilderProgram(BuilderProgramKind.EmitAndSemanticDiagnosticsBuilderProgram, getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics)); } @@ -568,8 +568,8 @@ namespace ts { * Creates a builder thats just abstraction over program and can be used with watch */ export function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; - export function createAbstractBuilder(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; - export function createAbstractBuilder(newProgramOrRootNames: Program | ReadonlyArray, hostOrOptions: BuilderProgramHost | CompilerOptions, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram { + export function createAbstractBuilder(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; + export function createAbstractBuilder(newProgramOrRootNames: Program | ReadonlyArray | undefined, hostOrOptions: BuilderProgramHost | CompilerOptions | undefined, oldProgramOrHost?: CompilerHost | BuilderProgram, configFileParsingDiagnosticsOrOldProgram?: ReadonlyArray | BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram { const { newProgram: program } = getBuilderCreationParameters(newProgramOrRootNames, hostOrOptions, oldProgramOrHost, configFileParsingDiagnosticsOrOldProgram, configFileParsingDiagnostics); return { // Only return program, all other methods are not implemented diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2a7c8768506..5903de5fa73 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -310,21 +310,34 @@ namespace ts { const node = getParseTreeNode(nodeIn, isTypeNode); return node && getTypeArgumentConstraint(node); }, + getSuggestionDiagnostics: (file, ct) => { + let diagnostics: DiagnosticWithLocation[] | undefined; + try { + // Record the cancellation token so it can be checked later on during checkSourceElement. + // Do this in a finally block so we can ensure that it gets reset back to nothing after + // this call is done. + cancellationToken = ct; - getSuggestionDiagnostics: file => { - return (suggestionDiagnostics.get(file.fileName) || emptyArray).concat(getUnusedDiagnostics()); - function getUnusedDiagnostics(): ReadonlyArray { - if (file.isDeclarationFile) return emptyArray; - + // Ensure file is type checked checkSourceFile(file); - const diagnostics: DiagnosticWithLocation[] = []; Debug.assert(!!(getNodeLinks(file).flags & NodeCheckFlags.TypeChecked)); + + diagnostics = addRange(diagnostics, suggestionDiagnostics.get(file.fileName)); + if (!file.isDeclarationFile && (!unusedIsError(UnusedKind.Local) || !unusedIsError(UnusedKind.Parameter))) { + addUnusedDiagnostics(); + } + return diagnostics || emptyArray; + } + finally { + cancellationToken = undefined; + } + + function addUnusedDiagnostics() { checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (kind, diag) => { if (!unusedIsError(kind)) { - diagnostics.push({ ...diag, category: DiagnosticCategory.Suggestion }); + (diagnostics || (diagnostics = [])).push({ ...diag, category: DiagnosticCategory.Suggestion }); } }); - return diagnostics; } }, @@ -889,11 +902,17 @@ namespace ts { return result; } - function mergeSymbol(target: Symbol, source: Symbol) { + /** + * Note: if target is transient, then it is mutable, and mergeSymbol with both mutate and return it. + * If target is not transient, mergeSymbol will produce a transient clone, mutate that and return it. + */ + function mergeSymbol(target: Symbol, source: Symbol): Symbol { if (!(target.flags & getExcludedSymbolFlags(source.flags)) || (source.flags | target.flags) & SymbolFlags.JSContainer) { - const targetValueDeclaration = target.valueDeclaration; - Debug.assert(!!(target.flags & SymbolFlags.Transient)); + Debug.assert(source !== target); + if (!(target.flags & SymbolFlags.Transient)) { + target = cloneSymbol(target); + } // Javascript static-property-assignment declarations always merge, even though they are also values if (source.flags & SymbolFlags.ValueModule && target.flags & SymbolFlags.ValueModule && target.constEnumOnlyModule && !source.constEnumOnlyModule) { // reset flag when merging instantiated module into value module that has only const enums @@ -915,18 +934,6 @@ namespace ts { if (!target.exports) target.exports = createSymbolTable(); mergeSymbolTable(target.exports, source.exports); } - if ((source.flags | target.flags) & SymbolFlags.JSContainer) { - const sourceInitializer = getJSInitializerSymbol(source)!; - const init = getDeclaredJavascriptInitializer(targetValueDeclaration) || getAssignedJavascriptInitializer(targetValueDeclaration); - let targetInitializer = init && init.symbol ? init.symbol : target; - if (!(targetInitializer.flags & SymbolFlags.Transient)) { - const mergedInitializer = getMergedSymbol(targetInitializer); - targetInitializer = mergedInitializer === targetInitializer ? cloneSymbol(targetInitializer) : mergedInitializer; - } - if (sourceInitializer !== source || targetInitializer !== target) { - mergeSymbol(targetInitializer, sourceInitializer); - } - } recordMergedSymbol(target, source); } else if (target.flags & SymbolFlags.NamespaceModule) { @@ -947,11 +954,12 @@ namespace ts { error(errorNode, message, symbolToString(source)); }); } + return target; } function combineSymbolTables(first: SymbolTable | undefined, second: SymbolTable | undefined): SymbolTable | undefined { - if (!first || first.size === 0) return second; - if (!second || second.size === 0) return first; + if (!hasEntries(first)) return second; + if (!hasEntries(second)) return first; const combined = createSymbolTable(); mergeSymbolTable(combined, first); mergeSymbolTable(combined, second); @@ -960,17 +968,7 @@ namespace ts { function mergeSymbolTable(target: SymbolTable, source: SymbolTable) { source.forEach((sourceSymbol, id) => { - let targetSymbol = target.get(id); - if (!targetSymbol) { - target.set(id, sourceSymbol); - } - else { - if (!(targetSymbol.flags & SymbolFlags.Transient)) { - targetSymbol = cloneSymbol(targetSymbol); - target.set(id, targetSymbol); - } - mergeSymbol(targetSymbol, sourceSymbol); - } + target.set(id, target.has(id) ? mergeSymbol(target.get(id)!, sourceSymbol) : sourceSymbol); }); } @@ -1000,10 +998,7 @@ namespace ts { // obtain item referenced by 'export=' mainModule = resolveExternalModuleSymbol(mainModule); if (mainModule.flags & SymbolFlags.Namespace) { - // if module symbol has already been merged - it is safe to use it. - // otherwise clone it - mainModule = mainModule.flags & SymbolFlags.Transient ? mainModule : cloneSymbol(mainModule); - mergeSymbol(mainModule, moduleAugmentation.symbol); + mainModule = mergeSymbol(mainModule, moduleAugmentation.symbol); } else { // moduleName will be a StringLiteral since this is not `declare global`. @@ -1463,9 +1458,8 @@ namespace ts { case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocCallbackTag: // js type aliases do not resolve names from their host, so skip past it - lastLocation = location; - location = getJSDocHost(location).parent; - continue; + location = getJSDocHost(location); + break; } if (isSelfReferenceLocation(location)) { lastSelfReferenceLocation = location; @@ -1789,7 +1783,7 @@ namespace ts { } function isSyntacticDefault(node: Node) { - return ((isExportAssignment(node) && !node.isExportEquals) || hasModifier(node, ModifierFlags.Default)); + return ((isExportAssignment(node) && !node.isExportEquals) || hasModifier(node, ModifierFlags.Default) || isExportSpecifier(node)); } function canHaveSyntheticDefault(file: SourceFile | undefined, moduleSymbol: Symbol, dontResolveAlias: boolean) { @@ -2124,14 +2118,6 @@ namespace ts { return namespace; } if (isInJavaScriptFile(name)) { - const initializer = getDeclaredJavascriptInitializer(namespace.valueDeclaration) || getAssignedJavascriptInitializer(namespace.valueDeclaration); - if (initializer) { - namespace = getSymbolOfNode(initializer)!; - } - // Currently, IIFEs may not have a symbol and we don't know about their contents. Give up in this case. - if (!namespace) { - return undefined; - } if (namespace.valueDeclaration && isVariableDeclaration(namespace.valueDeclaration) && namespace.valueDeclaration.initializer && @@ -2324,14 +2310,7 @@ namespace ts { } moduleSymbol.exports!.forEach((s, name) => { if (name === InternalSymbolName.ExportEquals) return; - if (!merged.exports!.has(name)) { - merged.exports!.set(name, s); - } - else { - const ms = cloneSymbol(merged.exports!.get(name)!); - mergeSymbol(ms, s); - merged.exports!.set(name, ms); - } + merged.exports!.set(name, merged.exports!.has(name) ? mergeSymbol(merged.exports!.get(name)!, s) : s); }); return merged; } @@ -4966,6 +4945,8 @@ namespace ts { else if (isJSDocPropertyLikeTag(declaration) || isPropertyAccessExpression(declaration) || isIdentifier(declaration) + || isClassDeclaration(declaration) + || isFunctionDeclaration(declaration) || (isMethodDeclaration(declaration) && !isObjectLiteralMethod(declaration)) || isMethodSignature(declaration)) { @@ -4995,7 +4976,7 @@ namespace ts { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true); } else { - return Debug.fail("Unhandled declaration kind! " + Debug.showSyntaxKind(declaration)); + return Debug.fail("Unhandled declaration kind! " + Debug.showSyntaxKind(declaration) + " for " + Debug.showSymbol(symbol)); } if (!popTypeResolution()) { @@ -5097,8 +5078,25 @@ namespace ts { } function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { - const links = getSymbolLinks(symbol); + let links = getSymbolLinks(symbol); if (!links.type) { + const jsDeclaration = getDeclarationOfJSInitializer(symbol.valueDeclaration); + if (jsDeclaration) { + const jsSymbol = getSymbolOfNode(jsDeclaration); + if (jsSymbol && (hasEntries(jsSymbol.exports) || hasEntries(jsSymbol.members))) { + symbol = cloneSymbol(symbol); + // note:we overwrite links because we just cloned the symbol + links = symbol as TransientSymbol; + if (hasEntries(jsSymbol.exports)) { + symbol.exports = symbol.exports || createSymbolTable(); + mergeSymbolTable(symbol.exports, jsSymbol.exports); + } + if (hasEntries(jsSymbol.members)) { + symbol.members = symbol.members || createSymbolTable(); + mergeSymbolTable(symbol.members, jsSymbol.members); + } + } + } if (symbol.flags & SymbolFlags.Module && isShorthandAmbientModuleSymbol(symbol)) { links.type = anyType; } @@ -7446,18 +7444,17 @@ namespace ts { const result: Signature[] = []; for (let i = 0; i < symbol.declarations.length; i++) { const decl = symbol.declarations[i]; - const node = isPropertyAccessExpression(decl) ? getAssignedJavascriptInitializer(decl)! : decl; // TODO: GH#18217 - if (!isFunctionLike(node)) continue; + if (!isFunctionLike(decl)) continue; // Don't include signature if node is the implementation of an overloaded function. A node is considered // an implementation node if it has a body and the previous node is of the same kind and immediately // precedes the implementation node (i.e. has the same parent and ends where the implementation starts). - if (i > 0 && (node as FunctionLikeDeclaration).body) { + if (i > 0 && (decl as FunctionLikeDeclaration).body) { const previous = symbol.declarations[i - 1]; - if (node.parent === previous.parent && node.kind === previous.kind && node.pos === previous.end) { + if (decl.parent === previous.parent && decl.kind === previous.kind && decl.pos === previous.end) { continue; } } - result.push(getSignatureFromDeclaration(node)); + result.push(getSignatureFromDeclaration(decl)); } return result; } @@ -8884,7 +8881,9 @@ namespace ts { return type.simplified === circularConstraintType ? type : type.simplified; } type.simplified = circularConstraintType; - const objectType = type.objectType; + // We recursively simplify the object type as it may in turn be an indexed access type. For example, with + // '{ [P in T]: { [Q in U]: number } }[T][U]' we want to first simplify the inner indexed access type. + const objectType = getSimplifiedType(type.objectType); if (objectType.flags & TypeFlags.Intersection && isGenericObjectType(objectType)) { // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a @@ -14115,11 +14114,14 @@ namespace ts { if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) { assumeTrue = !assumeTrue; } + if (type.flags & TypeFlags.Any && literal.text === "function") { + return type; + } if (assumeTrue && !(type.flags & TypeFlags.Union)) { // We narrow a non-union type to an exact primitive type if the non-union type // is a supertype of that primitive type. For example, type 'any' can be narrowed // to one of the primitive types. - const targetType = typeofTypesByName.get(literal.text); + const targetType = literal.text === "function" ? globalFunctionType : typeofTypesByName.get(literal.text); if (targetType) { if (isTypeSubtypeOf(targetType, type)) { return targetType; @@ -15299,7 +15301,7 @@ namespace ts { // expression has no contextual type, the right operand is contextually typed by the type of the left operand, // except for the special case of Javascript declarations of the form `namespace.prop = namespace.prop || {}` const type = getContextualType(binaryExpression); - return !type && node === right && !getDeclaredJavascriptInitializer(binaryExpression.parent) && !getAssignedJavascriptInitializer(binaryExpression) ? + return !type && node === right && !isDefaultedJavascriptInitializer(binaryExpression) ? getTypeOfExpression(left) : type; case SyntaxKind.AmpersandAmpersandToken: case SyntaxKind.CommaToken: @@ -15308,6 +15310,7 @@ namespace ts { return undefined; } } + // In an assignment expression, the right operand is contextually typed by the type of the left operand. // Don't do this for special property assignments to avoid circularity. function isContextSensitiveAssignment(binaryExpression: BinaryExpression): boolean { @@ -15975,13 +15978,16 @@ namespace ts { let hasComputedStringProperty = false; let hasComputedNumberProperty = false; - if (isInJSFile && node.properties.length === 0) { - // an empty JS object literal that nonetheless has members is a JS namespace - const symbol = getSymbolOfNode(node); - if (symbol.exports) { - propertiesTable = symbol.exports; - symbol.exports.forEach(symbol => propertiesArray.push(getMergedSymbol(symbol))); - return createObjectLiteralType(); + if (isInJSFile) { + const decl = getDeclarationOfJSInitializer(node); + if (decl) { + // a JS object literal whose declaration's symbol has exports is a JS namespace + const symbol = getMergedSymbol(decl.symbol); + if (symbol && hasEntries(symbol.exports)) { + propertiesTable = symbol.exports; + symbol.exports.forEach(symbol => propertiesArray.push(getMergedSymbol(symbol))); + return createObjectLiteralType(); + } } } propertiesTable = createSymbolTable(); @@ -18599,6 +18605,7 @@ namespace ts { if (node.expression.kind === SyntaxKind.SuperKeyword) { const superType = checkSuperExpression(node.expression); if (isTypeAny(superType)) { + forEach(node.arguments, checkExpression); // Still visit arguments so they get marked for visibility, etc return anySignature; } if (superType !== errorType) { @@ -19006,10 +19013,6 @@ namespace ts { } function getJavaScriptClassType(symbol: Symbol): Type | undefined { - const initializer = getDeclaredJavascriptInitializer(symbol.valueDeclaration); - if (initializer) { - symbol = getSymbolOfNode(initializer)!; - } let inferred: Type | undefined; if (isJavaScriptConstructor(symbol.valueDeclaration)) { inferred = getInferredClassType(symbol); @@ -19120,7 +19123,17 @@ namespace ts { if (returnType.flags & TypeFlags.ESSymbolLike && isSymbolOrSymbolForCall(node)) { return getESSymbolLikeTypeForNode(walkUpParenthesizedExpressions(node.parent)); } - return returnType; + let jsAssignmentType: Type | undefined; + if (isInJavaScriptFile(node)) { + const decl = getDeclarationOfJSInitializer(node); + if (decl) { + const jsSymbol = getSymbolOfNode(decl); + if (jsSymbol && hasEntries(jsSymbol.exports)) { + jsAssignmentType = createAnonymousType(jsSymbol, jsSymbol.exports, emptyArray, emptyArray, jsObjectLiteralIndexInfo, undefined); + } + } + } + return jsAssignmentType ? getIntersectionType([returnType, jsAssignmentType]) : returnType; } function isSymbolOrSymbolForCall(node: Node) { @@ -20616,13 +20629,12 @@ namespace ts { } function checkDeclarationInitializer(declaration: HasExpressionInitializer) { - const inJs = isInJavaScriptFile(declaration); - const initializer = inJs && getDeclaredJavascriptInitializer(declaration) || declaration.initializer!; + const initializer = getEffectiveInitializer(declaration)!; const type = getTypeOfExpression(initializer, /*cache*/ true); const widened = getCombinedNodeFlags(declaration) & NodeFlags.Const || (getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration)) || isTypeAssertion(initializer) ? type : getWidenedLiteralType(type); - if (inJs) { + if (isInJavaScriptFile(declaration)) { if (widened.flags & TypeFlags.Nullable) { if (noImplicitAny) { reportImplicitAnyError(declaration, anyType); @@ -22700,7 +22712,7 @@ namespace ts { function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) { const node = getNameOfDeclaration(declaration) || declaration; const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read; - addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, message, name)); + addDiagnostic(UnusedKind.Local, createDiagnosticForNode(node, message, name)); } function parameterNameStartsWithUnderscore(parameterName: DeclarationName) { @@ -23248,8 +23260,8 @@ namespace ts { if (node === symbol.valueDeclaration) { // Node is the primary declaration of the symbol, just validate the initializer // Don't validate for-in initializer as it is already an error - if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) { - const initializer = isInJavaScriptFile(node) && getDeclaredJavascriptInitializer(node) || node.initializer; + const initializer = getEffectiveInitializer(node); + if (initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) { checkTypeAssignableTo(checkExpressionCached(initializer), type, node, /*headMessage*/ undefined); checkParameterInitializer(node); } @@ -28332,9 +28344,9 @@ namespace ts { } function checkGrammarConstructorTypeParameters(node: ConstructorDeclaration) { - const typeParameters = getEffectiveTypeParameterDeclarations(node); - if (isNodeArray(typeParameters)) { - const { pos, end } = typeParameters; + const jsdocTypeParameters = isInJavaScriptFile(node) && getJSDocTypeParameterDeclarations(node); + if (node.typeParameters || jsdocTypeParameters && jsdocTypeParameters.length) { + const { pos, end } = node.typeParameters || jsdocTypeParameters && jsdocTypeParameters[0] || node; return grammarErrorAtPos(node, pos, end - pos, Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration); } } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index c0e64078ab5..b9149d76d7a 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -42,6 +42,7 @@ namespace ts { ["es2018.promise", "lib.es2018.promise.d.ts"], ["es2018.regexp", "lib.es2018.regexp.d.ts"], ["esnext.array", "lib.esnext.array.d.ts"], + ["esnext.symbol", "lib.esnext.symbol.d.ts"], ["esnext.asynciterable", "lib.esnext.asynciterable.d.ts"], ]; @@ -952,7 +953,8 @@ namespace ts { } } - function getOptionFromName(optionName: string, allowShort = false): CommandLineOption | undefined { + /** @internal */ + export function getOptionFromName(optionName: string, allowShort = false): CommandLineOption | undefined { optionName = optionName.toLowerCase(); const { optionNameMap, shortOptionNames } = getOptionNameMap(); // Try to translate short option names to their full equivalents. diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 76a51a9f072..0ec284d1882 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -177,6 +177,10 @@ namespace ts { return array ? array.length : 0; } + export function hasEntries(map: ReadonlyUnderscoreEscapedMap | undefined): map is ReadonlyUnderscoreEscapedMap { + return !!map && !!map.size; + } + /** * Iterates through 'array' by index and performs the callback on each element of array until the callback * returns a truthy value, then returns that value. @@ -2693,6 +2697,22 @@ namespace ts { return startsWith(str, prefix) ? str.substr(prefix.length) : str; } + export function tryRemovePrefix(str: string, prefix: string): string | undefined { + return startsWith(str, prefix) ? str.substring(prefix.length) : undefined; + } + + export function tryRemoveDirectoryPrefix(path: string, dirPath: string): string | undefined { + const a = tryRemovePrefix(path, dirPath); + if (a === undefined) return undefined; + switch (a.charCodeAt(0)) { + case CharacterCodes.slash: + case CharacterCodes.backslash: + return a.slice(1); + default: + return undefined; + } + } + export function endsWith(str: string, suffix: string): boolean { const expectedPos = str.length - suffix.length; return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; @@ -2702,6 +2722,10 @@ namespace ts { return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : str; } + export function tryRemoveSuffix(str: string, suffix: string): string | undefined { + return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : undefined; + } + export function stringContains(str: string, substring: string): boolean { return str.indexOf(substring) !== -1; } @@ -2902,6 +2926,7 @@ namespace ts { basePaths: ReadonlyArray; } + /** @param path directory of the tsconfig.json */ export function getFileMatcherPatterns(path: string, excludes: ReadonlyArray | undefined, includes: ReadonlyArray | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); @@ -2916,16 +2941,20 @@ namespace ts { }; } + export function getRegexFromPattern(pattern: string, useCaseSensitiveFileNames: boolean): RegExp { + return new RegExp(pattern, useCaseSensitiveFileNames ? "" : "i"); + } + + /** @param path directory of the tsconfig.json */ export function matchFiles(path: string, extensions: ReadonlyArray | undefined, excludes: ReadonlyArray | undefined, includes: ReadonlyArray | undefined, useCaseSensitiveFileNames: boolean, currentDirectory: string, depth: number | undefined, getFileSystemEntries: (path: string) => FileSystemEntries): string[] { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); - const regexFlag = useCaseSensitiveFileNames ? "" : "i"; - const includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(pattern => new RegExp(pattern, regexFlag)); - const includeDirectoryRegex = patterns.includeDirectoryPattern && new RegExp(patterns.includeDirectoryPattern, regexFlag); - const excludeRegex = patterns.excludePattern && new RegExp(patterns.excludePattern, regexFlag); + const includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(pattern => getRegexFromPattern(pattern, useCaseSensitiveFileNames)); + const includeDirectoryRegex = patterns.includeDirectoryPattern && getRegexFromPattern(patterns.includeDirectoryPattern, useCaseSensitiveFileNames); + const excludeRegex = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, useCaseSensitiveFileNames); // Associate an array of results with each include regex. This keeps results in order of the "include" order. // If there are no "includes", then just put everything in results[0]. diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0411b89c456..f2a10a08fde 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -219,6 +219,10 @@ "category": "Error", "code": 1068 }, + "Unexpected token. A type parameter name was expected without curly braces.": { + "category": "Error", + "code": 1069 + }, "'{0}' modifier cannot appear on a type member.": { "category": "Error", "code": 1070 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5e53605decf..90ec1c793a3 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -50,7 +50,7 @@ namespace ts { } else { const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options)); - const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); + const sourceMapFilePath = isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options); // For legacy reasons (ie, we have baselines capturing the behavior), js files don't report a .d.ts output path - this would only matter if `declaration` and `allowJs` were both on, which is currently an error const isJs = isSourceFileJavaScript(sourceFile); const declarationFilePath = ((forceDtsPaths || options.declaration) && !isJs) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; @@ -1458,7 +1458,7 @@ namespace ts { } const preferNewLine = node.multiLine ? ListFormat.PreferNewLine : ListFormat.None; - const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 ? ListFormat.AllowTrailingComma : ListFormat.None; + const allowTrailingComma = currentSourceFile.languageVersion >= ScriptTarget.ES5 && !isJsonSourceFile(currentSourceFile) ? ListFormat.AllowTrailingComma : ListFormat.None; emitList(node, node.properties, ListFormat.ObjectLiteralExpressionProperties | allowTrailingComma | preferNewLine); if (indentedFlag) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 97d9bbd735e..74ec3d85931 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -717,6 +717,7 @@ namespace ts { initializeState(sourceText, languageVersion, syntaxCursor, ScriptKind.JSON); // Set source file so that errors will be reported with this file name sourceFile = createSourceFile(fileName, ScriptTarget.ES2015, ScriptKind.JSON, /*isDeclaration*/ false); + sourceFile.flags = contextFlags; // Prime the scanner. nextToken(); @@ -4147,27 +4148,6 @@ namespace ts { return finishNode(node); } - function tagNamesAreEquivalent(lhs: JsxTagNameExpression, rhs: JsxTagNameExpression): boolean { - if (lhs.kind !== rhs.kind) { - return false; - } - - if (lhs.kind === SyntaxKind.Identifier) { - return (lhs).escapedText === (rhs).escapedText; - } - - if (lhs.kind === SyntaxKind.ThisKeyword) { - return true; - } - - // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only - // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression - // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element - return (lhs).name.escapedText === (rhs).name.escapedText && - tagNamesAreEquivalent((lhs).expression as JsxTagNameExpression, (rhs).expression as JsxTagNameExpression); - } - - function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement | JsxFragment { const opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); let result: JsxElement | JsxSelfClosingElement | JsxFragment; @@ -6385,17 +6365,14 @@ namespace ts { indent += text.length; } - let t = nextJSDocToken(); - while (t === SyntaxKind.WhitespaceTrivia) { - t = nextJSDocToken(); - } - if (t === SyntaxKind.NewLineTrivia) { + nextJSDocToken(); + while (parseOptionalJsdoc(SyntaxKind.WhitespaceTrivia)); + if (parseOptionalJsdoc(SyntaxKind.NewLineTrivia)) { state = JSDocState.BeginningOfLine; indent = 0; - t = nextJSDocToken(); } loop: while (true) { - switch (t) { + switch (token()) { case SyntaxKind.AtToken: if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) { removeTrailingNewlines(comments); @@ -6455,12 +6432,11 @@ namespace ts { pushComment(scanner.getTokenText()); break; } - t = nextJSDocToken(); + nextJSDocToken(); } removeLeadingNewlines(comments); removeTrailingNewlines(comments); result = createJSDocComment(); - }); return result; @@ -6897,8 +6873,7 @@ namespace ts { jsdocSignature.parameters = append(jsdocSignature.parameters as MutableNodeArray, child); } const returnTag = tryParse(() => { - if (token() === SyntaxKind.AtToken) { - nextJSDocToken(); + if (parseOptionalJsdoc(SyntaxKind.AtToken)) { const tag = parseTag(indent); if (tag && tag.kind === SyntaxKind.JSDocReturnTag) { return tag as JSDocReturnTag; @@ -7013,35 +6988,29 @@ namespace ts { } function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag | undefined { - if (some(tags, isJSDocTemplateTag)) { - parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText); + // the template tag looks like '@template {Constraint} T,U,V' + let constraint: JSDocTypeExpression | undefined; + if (token() === SyntaxKind.OpenBraceToken) { + constraint = parseJSDocTypeExpression(); } - // Type parameter list looks like '@template T,U,V' const typeParameters = []; const typeParametersPos = getNodePos(); - - while (true) { - const typeParameter = createNode(SyntaxKind.TypeParameter); - const name = parseJSDocIdentifierNameWithOptionalBraces(); + do { skipWhitespace(); - if (!name) { - parseErrorAtPosition(scanner.getStartPos(), 0, Diagnostics.Identifier_expected); + const typeParameter = createNode(SyntaxKind.TypeParameter); + if (!tokenIsIdentifierOrKeyword(token())) { + parseErrorAtCurrentToken(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces); return undefined; } - - typeParameter.name = name; + typeParameter.name = parseJSDocIdentifierName()!; + skipWhitespace(); finishNode(typeParameter); - typeParameters.push(typeParameter); + } while (parseOptionalJsdoc(SyntaxKind.CommaToken)); - if (token() === SyntaxKind.CommaToken) { - nextJSDocToken(); - skipWhitespace(); - } - else { - break; - } + if (constraint) { + first(typeParameters).constraint = constraint.type; } const result = createNode(SyntaxKind.JSDocTemplateTag, atToken.pos); @@ -7052,19 +7021,18 @@ namespace ts { return result; } - function parseJSDocIdentifierNameWithOptionalBraces(): Identifier | undefined { - const parsedBrace = parseOptional(SyntaxKind.OpenBraceToken); - const res = parseJSDocIdentifierName(); - if (parsedBrace) { - parseExpected(SyntaxKind.CloseBraceToken); - } - return res; - } - function nextJSDocToken(): JsDocSyntaxKind { return currentToken = scanner.scanJSDocToken(); } + function parseOptionalJsdoc(t: JsDocSyntaxKind): boolean { + if (token() === t) { + nextJSDocToken(); + return true; + } + return false; + } + function parseJSDocEntityName(): EntityName { let entity: EntityName = parseJSDocIdentifierName(/*createIfMissing*/ true); if (parseOptional(SyntaxKind.OpenBracketToken)) { @@ -7912,4 +7880,25 @@ namespace ts { } return argMap; } + + /** @internal */ + export function tagNamesAreEquivalent(lhs: JsxTagNameExpression, rhs: JsxTagNameExpression): boolean { + if (lhs.kind !== rhs.kind) { + return false; + } + + if (lhs.kind === SyntaxKind.Identifier) { + return (lhs).escapedText === (rhs).escapedText; + } + + if (lhs.kind === SyntaxKind.ThisKeyword) { + return true; + } + + // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only + // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression + // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element + return (lhs).name.escapedText === (rhs).name.escapedText && + tagNamesAreEquivalent((lhs).expression as JsxTagNameExpression, (rhs).expression as JsxTagNameExpression); + } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index accd394fffe..bc675899d60 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -488,6 +488,17 @@ namespace ts { }; } + /** + * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' + * that represent a compilation unit. + * + * Creating a program proceeds from a set of root files, expanding the set of inputs by following imports and + * triple-slash-reference-path directives transitively. '@types' and triple-slash-reference-types are also pulled in. + * + * @param createProgramOptions - The options for creating a program. + * @returns A 'Program' object. + */ + export function createProgram(createProgramOptions: CreateProgramOptions): Program; /** * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' * that represent a compilation unit. @@ -502,7 +513,6 @@ namespace ts { * @param configFileParsingDiagnostics - error during config file parsing * @returns A 'Program' object. */ - export function createProgram(createProgramOptions: CreateProgramOptions): Program; export function createProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray): Program; export function createProgram(rootNamesOrOptions: ReadonlyArray | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: ReadonlyArray): Program { const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options!, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions; // TODO: GH#18217 @@ -690,6 +700,7 @@ namespace ts { getOptionsDiagnostics, getGlobalDiagnostics, getSemanticDiagnostics, + getSuggestionDiagnostics, getDeclarationDiagnostics, getTypeChecker, getClassifiableNames, @@ -1450,6 +1461,12 @@ namespace ts { }); } + function getSuggestionDiagnostics(sourceFile: SourceFile, cancellationToken: CancellationToken): ReadonlyArray { + return runWithCancellationToken(() => { + return getDiagnosticsProducingTypeChecker().getSuggestionDiagnostics(sourceFile, cancellationToken); + }); + } + /** * Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines */ diff --git a/src/compiler/sourcemap.ts b/src/compiler/sourcemap.ts index a274404f320..9229e2daa0e 100644 --- a/src/compiler/sourcemap.ts +++ b/src/compiler/sourcemap.ts @@ -125,7 +125,7 @@ namespace ts { * @param sourceFileOrBundle The input source file or bundle for the program. */ function initialize(filePath: string, sourceMapFilePath: string, sourceFileOrBundle: SourceFile | Bundle, outputSourceMapDataList?: SourceMapData[]) { - if (disabled) { + if (disabled || fileExtensionIs(filePath, Extension.Json)) { return; } @@ -270,7 +270,7 @@ namespace ts { * @param pos The position. */ function emitPos(pos: number) { - if (disabled || positionIsSynthesized(pos)) { + if (disabled || positionIsSynthesized(pos) || isJsonSourceMapSource(currentSource)) { return; } @@ -328,7 +328,7 @@ namespace ts { * @param emitCallback The callback used to emit the node. */ function emitNodeWithSourceMap(hint: EmitHint, node: Node, emitCallback: (hint: EmitHint, node: Node) => void) { - if (disabled) { + if (disabled || isInJsonFile(node)) { return emitCallback(hint, node); } @@ -381,7 +381,7 @@ namespace ts { * @param emitCallback The callback used to emit the token. */ function emitTokenWithSourceMap(node: Node, token: SyntaxKind, writer: (s: string) => void, tokenPos: number, emitCallback: (token: SyntaxKind, writer: (s: string) => void, tokenStartPos: number) => number) { - if (disabled) { + if (disabled || isInJsonFile(node)) { return emitCallback(token, writer, tokenPos); } @@ -404,6 +404,10 @@ namespace ts { return tokenPos; } + function isJsonSourceMapSource(sourceFile: SourceMapSource) { + return fileExtensionIs(sourceFile.fileName, Extension.Json); + } + /** * Set the current source file. * @@ -417,6 +421,10 @@ namespace ts { currentSource = sourceFile; currentSourceText = currentSource.text; + if (isJsonSourceMapSource(sourceFile)) { + return; + } + // Add the file to tsFilePaths // If sourceroot option: Use the relative path corresponding to the common directory path // otherwise source locations relative to map file location @@ -446,7 +454,7 @@ namespace ts { * Gets the text for the source map. */ function getText() { - if (disabled) { + if (disabled || isJsonSourceMapSource(currentSource)) { return undefined!; // TODO: GH#18217 } @@ -467,7 +475,7 @@ namespace ts { * Gets the SourceMappingURL for the source map. */ function getSourceMappingURL() { - if (disabled) { + if (disabled || isJsonSourceMapSource(currentSource)) { return undefined!; // TODO: GH#18217 } @@ -519,4 +527,4 @@ namespace ts { return encodedStr; } -} \ No newline at end of file +} diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index cc244d92204..076645a14d8 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -552,7 +552,9 @@ namespace ts { function visitSourceFile(node: SourceFile) { const alwaysStrict = getStrictOptionValue(compilerOptions, "alwaysStrict") && - !(isExternalModule(node) && moduleKind >= ModuleKind.ES2015); + !(isExternalModule(node) && moduleKind >= ModuleKind.ES2015) && + !isJsonSourceFile(node); + return updateSourceFileNode( node, visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict)); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f0e72a88656..93162944fce 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2756,6 +2756,7 @@ namespace ts { getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; getConfigFileParsingDiagnostics(): ReadonlyArray; + /* @internal */ getSuggestionDiagnostics(sourceFile: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; /** * Gets a type checker that can be used to semantically analyze source files in the program. @@ -3078,7 +3079,7 @@ namespace ts { * Does *not* get *all* suggestion diagnostics, just the ones that were convenient to report in the checker. * Others are added in computeSuggestionDiagnostics. */ - /* @internal */ getSuggestionDiagnostics(file: SourceFile): ReadonlyArray; + /* @internal */ getSuggestionDiagnostics(file: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray; /** * Depending on the operation performed, it may be appropriate to throw away the checker diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 426c0d8d1da..e2e2de985bc 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -641,11 +641,6 @@ namespace ts { return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3); } - export function createDiagnosticForNodeSpan(sourceFile: SourceFile, startNode: Node, endNode: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { - const start = skipTrivia(sourceFile.text, startNode.pos); - return createFileDiagnostic(sourceFile, start, endNode.end - start, message, arg0, arg1, arg2, arg3); - } - export function createDiagnosticForNodeFromMessageChain(node: Node, messageChain: DiagnosticMessageChain): DiagnosticWithLocation { const sourceFile = getSourceFileOfNode(node); const span = getErrorSpanForNode(sourceFile, node); @@ -1088,7 +1083,7 @@ namespace ts { } export function getPropertyAssignment(objectLiteral: ObjectLiteralExpression, key: string, key2?: string): ReadonlyArray { - return filter(objectLiteral.properties, (property): property is PropertyAssignment => { + return objectLiteral.properties.filter((property): property is PropertyAssignment => { if (property.kind === SyntaxKind.PropertyAssignment) { const propName = getTextOfPropertyName(property.name); return key === propName || (!!key2 && key2 === propName); @@ -1105,12 +1100,15 @@ namespace ts { } export function getTsConfigPropArrayElementValue(tsConfigSourceFile: TsConfigSourceFile | undefined, propKey: string, elementValue: string): StringLiteral | undefined { + return firstDefined(getTsConfigPropArray(tsConfigSourceFile, propKey), property => + isArrayLiteralExpression(property.initializer) ? + find(property.initializer.elements, (element): element is StringLiteral => isStringLiteral(element) && element.text === elementValue) : + undefined); + } + + export function getTsConfigPropArray(tsConfigSourceFile: TsConfigSourceFile | undefined, propKey: string): ReadonlyArray { const jsonObjectLiteral = getTsConfigObjectLiteralExpression(tsConfigSourceFile); - return jsonObjectLiteral && - firstDefined(getPropertyAssignment(jsonObjectLiteral, propKey), property => - isArrayLiteralExpression(property.initializer) ? - find(property.initializer.elements, (element): element is StringLiteral => isStringLiteral(element) && element.text === elementValue) : - undefined); + return jsonObjectLiteral ? getPropertyAssignment(jsonObjectLiteral, propKey) : emptyArray; } export function getContainingFunction(node: Node): SignatureDeclaration | undefined { @@ -1560,28 +1558,49 @@ namespace ts { return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === CharacterCodes.doubleQuote; } - /** - * Given the symbol of a declaration, find the symbol of its Javascript container-like initializer, - * if it has one. Otherwise just return the original symbol. - * - * Container-like initializer behave like namespaces, so the binder needs to add contained symbols - * to their exports. An example is a function with assignments to `this` inside. - */ - export function getJSInitializerSymbol(symbol: Symbol | undefined) { - if (!symbol || !symbol.valueDeclaration) { - return symbol; + export function getDeclarationOfJSInitializer(node: Node): Node | undefined { + if (!isInJavaScriptFile(node) || !node.parent) { + return undefined; } - const declaration = symbol.valueDeclaration; - const e = getDeclaredJavascriptInitializer(declaration) || getAssignedJavascriptInitializer(declaration); - return e && e.symbol ? e.symbol : symbol; + let name: Expression | BindingName | undefined; + let decl: Node | undefined; + if (isVariableDeclaration(node.parent) && node.parent.initializer === node) { + name = node.parent.name; + decl = node.parent; + } + else if (isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken && node.parent.right === node) { + name = node.parent.left; + decl = name; + } + else if (isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.BarBarToken) { + if (isVariableDeclaration(node.parent.parent) && node.parent.parent.initializer === node.parent) { + name = node.parent.parent.name; + decl = node.parent.parent; + } + else if (isBinaryExpression(node.parent.parent) && node.parent.parent.operatorToken.kind === SyntaxKind.EqualsToken && node.parent.parent.right === node.parent) { + name = node.parent.parent.left; + decl = name; + } + + if (!name || !isEntityNameExpression(name) || !isSameEntityName(name, node.parent.left)) { + return undefined; + } + } + + if (!name || !getJavascriptInitializer(node, isPrototypeAccess(name))) { + return undefined; + } + return decl; } - /** Get the declaration initializer, when the initializer is container-like (See getJavascriptInitializer) */ - export function getDeclaredJavascriptInitializer(node: Node) { - if (node && isVariableDeclaration(node) && node.initializer) { - return getJavascriptInitializer(node.initializer, /*isPrototypeAssignment*/ false) || - isIdentifier(node.name) && getDefaultedJavascriptInitializer(node.name, node.initializer, /*isPrototypeAssignment*/ false); + /** Get the initializer, taking into account defaulted Javascript initializers */ + export function getEffectiveInitializer(node: HasExpressionInitializer) { + if (isInJavaScriptFile(node) && node.initializer && + isBinaryExpression(node.initializer) && node.initializer.operatorToken.kind === SyntaxKind.BarBarToken && + node.name && isEntityNameExpression(node.name) && isSameEntityName(node.name, node.initializer.left)) { + return node.initializer.right; } + return node.initializer; } /** @@ -1636,6 +1655,13 @@ namespace ts { } } + export function isDefaultedJavascriptInitializer(node: BinaryExpression) { + const name = isVariableDeclaration(node.parent) ? node.parent.name : + isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken ? node.parent.left : + undefined; + return name && getJavascriptInitializer(node.right, isPrototypeAccess(name)) && isEntityNameExpression(name) && isSameEntityName(name, node.left); + } + /** Given a Javascript initializer, return the outer name. That is, the lhs of the assignment or the declaration name. */ export function getOuterNameOfJsInitializer(node: Declaration): DeclarationName | undefined { if (isBinaryExpression(node.parent)) { @@ -1658,7 +1684,7 @@ namespace ts { * var min = window.min || {} * my.app = self.my.app || class { } */ - function isSameEntityName(name: EntityNameExpression, initializer: EntityNameExpression): boolean { + function isSameEntityName(name: Expression, initializer: Expression): boolean { if (isIdentifier(name) && isIdentifier(initializer)) { return name.escapedText === initializer.escapedText; } @@ -3138,21 +3164,18 @@ namespace ts { } if (isJSDocTypeAlias(node)) { Debug.assert(node.parent.kind === SyntaxKind.JSDocComment); - const templateTags = flatMap(filter(node.parent.tags, isJSDocTemplateTag), tag => tag.typeParameters) as ReadonlyArray; - const templateTagNodes = templateTags as NodeArray; - templateTagNodes.pos = templateTagNodes.length > 0 ? first(templateTagNodes).pos : node.pos; - templateTagNodes.end = templateTagNodes.length > 0 ? last(templateTagNodes).end : node.end; - templateTagNodes.hasTrailingComma = false; - return templateTagNodes; + return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray; } return node.typeParameters || (isInJavaScriptFile(node) ? getJSDocTypeParameterDeclarations(node) : emptyArray); } export function getJSDocTypeParameterDeclarations(node: DeclarationWithTypeParameters): ReadonlyArray { - // template tags are only available when a typedef isn't already using them - const tag = find(getJSDocTags(node), (tag): tag is JSDocTemplateTag => - isJSDocTemplateTag(tag) && !(tag.parent.kind === SyntaxKind.JSDocComment && tag.parent.tags!.some(isJSDocTypeAlias))); - return (tag && tag.typeParameters) || emptyArray; + return flatMap(getJSDocTags(node), tag => isNonTypeAliasTemplate(tag) ? tag.typeParameters : undefined); + } + + /** template tags are only available when a typedef isn't already using them */ + function isNonTypeAliasTemplate(tag: JSDocTag): tag is JSDocTemplateTag { + return isJSDocTemplateTag(tag) && !(tag.parent.kind === SyntaxKind.JSDocComment && tag.parent.tags!.some(isJSDocTypeAlias)); } /** @@ -3648,15 +3671,15 @@ namespace ts { return output; } - export function base64encode(host: { base64encode?(input: string): string }, input: string): string { - if (host.base64encode) { + export function base64encode(host: { base64encode?(input: string): string } | undefined, input: string): string { + if (host && host.base64encode) { return host.base64encode(input); } return convertToBase64(input); } - export function base64decode(host: { base64decode?(input: string): string }, input: string): string { - if (host.base64decode) { + export function base64decode(host: { base64decode?(input: string): string } | undefined, input: string): string { + if (host && host.base64decode) { return host.base64decode(input); } const length = input.length; diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index 5f35a3027dc..cda3158afeb 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -1468,7 +1468,7 @@ namespace ts { } return isNodeArray(statements) - ? setTextRange(createNodeArray(concatenate(declarations, statements)), statements) + ? setTextRange(createNodeArray(prependStatements(statements.slice(), declarations)), statements) : prependStatements(statements, declarations); } diff --git a/src/harness/compiler.ts b/src/harness/compiler.ts index 95a7d85fe58..1290bbb4be8 100644 --- a/src/harness/compiler.ts +++ b/src/harness/compiler.ts @@ -183,7 +183,7 @@ namespace compiler { public getSourceMapRecord(): string | undefined { if (this.result!.sourceMaps && this.result!.sourceMaps!.length > 0) { - return Harness.SourceMapRecorder.getSourceMapRecord(this.result!.sourceMaps!, this.program!, Array.from(this.js.values()), Array.from(this.dts.values())); + return Harness.SourceMapRecorder.getSourceMapRecord(this.result!.sourceMaps!, this.program!, Array.from(this.js.values()).filter(d => !ts.fileExtensionIs(d.file, ts.Extension.Json)), Array.from(this.dts.values())); } } @@ -216,6 +216,16 @@ namespace compiler { } return vpath.changeExtension(path, ext); } + + public getNumberOfJsFiles() { + let count = this.js.size; + this.js.forEach(document => { + if (ts.fileExtensionIs(document.file, ts.Extension.Json)) { + count--; + } + }); + return count; + } } export function compileFiles(host: fakes.CompilerHost, rootFiles: string[] | undefined, compilerOptions: ts.CompilerOptions): CompilationResult { diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f6214d4c719..d2aaeecbb92 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2743,6 +2743,14 @@ Actual: ${stringify(fullActual)}`); } } + public verifyJsxClosingTag(map: { [markerName: string]: ts.JsxClosingTagInfo | undefined }): void { + for (const markerName in map) { + this.goToMarker(markerName); + const actual = this.languageService.getJsxClosingTagAtPosition(this.activeFile.fileName, this.currentCaretPosition); + assert.deepEqual(actual, map[markerName]); + } + } + public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) { const actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition); @@ -3131,8 +3139,12 @@ Actual: ${stringify(fullActual)}`); assert(action.name === "Move to a new file" && action.description === "Move to a new file"); const editInfo = this.languageService.getEditsForRefactor(this.activeFile.fileName, this.formatCodeSettings, range, refactor.name, action.name, options.preferences || ts.defaultPreferences)!; - for (const edit of editInfo.edits) { - const newContent = options.newFileContents[edit.fileName]; + this.testNewFileContents(editInfo.edits, options.newFileContents); + } + + private testNewFileContents(edits: ReadonlyArray, newFileContents: { [fileName: string]: string }): void { + for (const edit of edits) { + const newContent = newFileContents[edit.fileName]; if (newContent === undefined) { this.raiseError(`There was an edit in ${edit.fileName} but new content was not specified.`); } @@ -3149,8 +3161,8 @@ Actual: ${stringify(fullActual)}`); } } - for (const fileName in options.newFileContents) { - assert(editInfo.edits.some(e => e.fileName === fileName)); + for (const fileName in newFileContents) { + assert(edits.some(e => e.fileName === fileName)); } } @@ -3360,12 +3372,8 @@ Actual: ${stringify(fullActual)}`); } public getEditsForFileRename(options: FourSlashInterface.GetEditsForFileRenameOptions): void { - const changes = this.languageService.getEditsForFileRename(options.oldPath, options.newPath, this.formatCodeSettings); - this.applyChanges(changes); - for (const fileName in options.newFileContents) { - this.openFile(fileName); - this.verifyCurrentFileContent(options.newFileContents[fileName]); - } + const changes = this.languageService.getEditsForFileRename(options.oldPath, options.newPath, this.formatCodeSettings, ts.defaultPreferences); + this.testNewFileContents(changes, options.newFileContents); } private getApplicableRefactors(positionOrRange: number | ts.TextRange, preferences = ts.defaultPreferences): ReadonlyArray { @@ -4079,6 +4087,10 @@ namespace FourSlashInterface { this.state.verifyBraceCompletionAtPosition(this.negative, openingBrace); } + public jsxClosingTag(map: { [markerName: string]: ts.JsxClosingTagInfo | undefined }): void { + this.state.verifyJsxClosingTag(map); + } + public isInCommentAtPosition(onlyMultiLineDiverges?: boolean) { this.state.verifySpanOfEnclosingComment(this.negative, onlyMultiLineDiverges); } diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d57de0cb910..d325883fc11 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -1270,7 +1270,7 @@ namespace Harness { throw new Error("Only declaration files should be generated when emitDeclarationOnly:true"); } } - else if (result.dts.size !== result.js.size) { + else if (result.dts.size !== result.getNumberOfJsFiles()) { throw new Error("There were no errors and declFiles generated did not match number of js files generated"); } } @@ -1645,7 +1645,7 @@ namespace Harness { return; } else if (options.sourceMap || declMaps) { - if (result.maps.size !== (result.js.size * (declMaps && options.sourceMap ? 2 : 1))) { + if (result.maps.size !== (result.getNumberOfJsFiles() * (declMaps && options.sourceMap ? 2 : 1))) { throw new Error("Number of sourcemap files should be same as js files."); } diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index cc05f433eab..b2f24175e29 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -509,6 +509,9 @@ namespace Harness.LanguageService { isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean { return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace)); } + getJsxClosingTagAtPosition(): never { + throw new Error("Not supported on the shim."); + } getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): ts.TextSpan { return unwrapJSONCallResult(this.shim.getSpanOfEnclosingComment(fileName, position, onlyMultiLine)); } @@ -795,7 +798,7 @@ namespace Harness.LanguageService { const proxy = makeDefaultProxy(info); proxy.getSemanticDiagnostics = filename => { const prev = info.languageService.getSemanticDiagnostics(filename); - const sourceFile: ts.SourceFile = info.languageService.getSourceFile(filename); + const sourceFile: ts.SourceFile = info.project.getSourceFile(ts.toPath(filename, /*basePath*/ undefined, ts.createGetCanonicalFileName(info.serverHost.useCaseSensitiveFileNames)))!; prev.push({ category: ts.DiagnosticCategory.Warning, file: sourceFile, diff --git a/src/harness/unittests/cancellableLanguageServiceOperations.ts b/src/harness/unittests/cancellableLanguageServiceOperations.ts index 161b45841f3..a198210f76b 100644 --- a/src/harness/unittests/cancellableLanguageServiceOperations.ts +++ b/src/harness/unittests/cancellableLanguageServiceOperations.ts @@ -56,9 +56,19 @@ namespace ts { r => assert.exists(r.displayParts) ); }); + + it("can cancel suggestion diagnostics mid-request", () => { + verifyOperationCancelledAfter(file, 1, service => // The LS doesn't do any top-level checks on the token for suggestion diagnostics, so the first check is within the checker + service.getSuggestionDiagnostics("file.js"), + r => assert.notEqual(r.length, 0), + "file.js", + "function foo() { let a = 10; }", + { allowJs: true } + ); + }); }); - function verifyOperationCancelledAfter(content: string, cancelAfter: number, operation: (service: LanguageService) => T, validator: (arg: T) => void) { + function verifyOperationCancelledAfter(content: string, cancelAfter: number, operation: (service: LanguageService) => T, validator: (arg: T) => void, fileName?: string, fileContent?: string, options?: CompilerOptions) { let checks = 0; const token: HostCancellationToken = { isCancellationRequested() { @@ -70,9 +80,9 @@ namespace ts { return result; } }; - const adapter = new Harness.LanguageService.NativeLanguageServiceAdapter(token); + const adapter = new Harness.LanguageService.NativeLanguageServiceAdapter(token, options); const host = adapter.getHost(); - host.addScript("file.ts", content, /*isRootFile*/ true); + host.addScript(fileName || "file.ts", fileContent || content, /*isRootFile*/ true); const service = adapter.getLanguageService(); assertCancelled(() => operation(service)); validator(operation(service)); @@ -92,4 +102,4 @@ namespace ts { assert.exists(caught, "Expected operation to be cancelled, but was not"); assert.instanceOf(caught, OperationCanceledException); } -} \ No newline at end of file +} diff --git a/src/harness/unittests/commandLineParsing.ts b/src/harness/unittests/commandLineParsing.ts index 3d5efea3b62..4f71d414249 100644 --- a/src/harness/unittests/commandLineParsing.ts +++ b/src/harness/unittests/commandLineParsing.ts @@ -60,7 +60,7 @@ namespace ts { assertParseResult(["--lib", "es5,invalidOption", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, @@ -262,7 +262,7 @@ namespace ts { assertParseResult(["--lib", "es5,", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, @@ -281,7 +281,7 @@ namespace ts { assertParseResult(["--lib", "es5, ", "es7", "0.ts"], { errors: [{ - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, diff --git a/src/harness/unittests/convertCompilerOptionsFromJson.ts b/src/harness/unittests/convertCompilerOptionsFromJson.ts index a63e74cdf50..b2b07fc8825 100644 --- a/src/harness/unittests/convertCompilerOptionsFromJson.ts +++ b/src/harness/unittests/convertCompilerOptionsFromJson.ts @@ -268,7 +268,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -299,7 +299,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -330,7 +330,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -361,7 +361,7 @@ namespace ts { file: undefined, start: 0, length: 0, - messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.asynciterable'.", + messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] diff --git a/src/harness/unittests/session.ts b/src/harness/unittests/session.ts index 5e0b44fb5f0..cdb6e818d7b 100644 --- a/src/harness/unittests/session.ts +++ b/src/harness/unittests/session.ts @@ -224,6 +224,7 @@ namespace ts.server { CommandNames.Occurrences, CommandNames.DocumentHighlights, CommandNames.DocumentHighlightsFull, + CommandNames.JsxClosingTag, CommandNames.Open, CommandNames.Quickinfo, CommandNames.QuickinfoFull, diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 4518a740a85..aa1f4143fc8 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -8400,15 +8400,23 @@ new C();` path: "/user.ts", content: 'import { x } from "./old";', }; + const newTs: File = { + path: "/new.ts", + content: "export const x = 0;", + }; + const tsconfig: File = { + path: "/tsconfig.json", + content: "{}", + }; - const host = createServerHost([userTs]); + const host = createServerHost([userTs, newTs, tsconfig]); const projectService = createProjectService(host); projectService.openClientFile(userTs.path); - const project = first(projectService.inferredProjects); + const project = projectService.configuredProjects.get(tsconfig.path)!; Debug.assert(!!project.resolveModuleNames); - const edits = project.getLanguageService().getEditsForFileRename("/old.ts", "/new.ts", testFormatOptions); + const edits = project.getLanguageService().getEditsForFileRename("/old.ts", "/new.ts", testFormatOptions, defaultPreferences); assert.deepEqual>(edits, [{ fileName: "/user.ts", textChanges: [{ diff --git a/src/harness/unittests/typingsInstaller.ts b/src/harness/unittests/typingsInstaller.ts index 34176e8563c..0b355d5aa89 100644 --- a/src/harness/unittests/typingsInstaller.ts +++ b/src/harness/unittests/typingsInstaller.ts @@ -1340,6 +1340,27 @@ namespace ts.projectSystem { assert.deepEqual(result.newTypingNames, ["bar"]); }); + it("should gracefully handle packages that have been removed from the types-registry", () => { + const f = { + path: "/a/b/app.js", + content: "" + }; + const node = { + path: "/a/b/node.d.ts", + content: "" + }; + const host = createServerHost([f, node]); + const cache = createMapFromTemplate({ node: { typingLocation: node.path, version: Semver.parse("1.3.0") } }); + const logger = trackingLogger(); + const result = JsTyping.discoverTypings(host, logger.log, [f.path], getDirectoryPath(f.path), emptySafeList, cache, { enable: true }, ["fs", "bar"], emptyMap); + assert.deepEqual(logger.finish(), [ + 'Inferred typings from unresolved imports: ["node","bar"]', + 'Result: {"cachedTypingPaths":[],"newTypingNames":["node","bar"],"filesToWatch":["/a/b/bower_components","/a/b/node_modules"]}', + ]); + assert.deepEqual(result.cachedTypingPaths, []); + assert.deepEqual(result.newTypingNames, ["node", "bar"]); + }); + it("should search only 2 levels deep", () => { const app = { path: "/app.js", diff --git a/src/lib/esnext.array.d.ts b/src/lib/esnext.array.d.ts index ddba47badaa..b602e8cc0e8 100644 --- a/src/lib/esnext.array.d.ts +++ b/src/lib/esnext.array.d.ts @@ -3,7 +3,7 @@ interface ReadonlyArray { /** * Calls a defined callback function on each element of an array. Then, flattens the result into * a new array. - * This is identical to a map followed by a flatten of depth 1. + * This is identical to a map followed by flat with depth 1. * * @param callback A function that accepts up to three arguments. The flatMap method calls the * callback function one time for each element in the array. @@ -22,7 +22,7 @@ interface ReadonlyArray { * * @param depth The maximum recursion depth */ - flatten(this: + flat(this: ReadonlyArray | ReadonlyArray> | @@ -51,7 +51,7 @@ interface ReadonlyArray { * * @param depth The maximum recursion depth */ - flatten(this: + flat(this: ReadonlyArray | ReadonlyArray[][]> | @@ -71,7 +71,7 @@ interface ReadonlyArray { * * @param depth The maximum recursion depth */ - flatten(this: + flat(this: ReadonlyArray | ReadonlyArray> | @@ -86,7 +86,7 @@ interface ReadonlyArray { * * @param depth The maximum recursion depth */ - flatten(this: + flat(this: ReadonlyArray | ReadonlyArray>, depth?: 1 @@ -98,18 +98,18 @@ interface ReadonlyArray { * * @param depth The maximum recursion depth */ - flatten(this: + flat(this: ReadonlyArray, depth: 0 ): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * specified depth. If no depth is provided, flat method defaults to the depth of 1. * * @param depth The maximum recursion depth */ - flatten(depth?: number): any[]; + flat(depth?: number): any[]; } interface Array { @@ -117,7 +117,7 @@ interface Array { /** * Calls a defined callback function on each element of an array. Then, flattens the result into * a new array. - * This is identical to a map followed by a flatten of depth 1. + * This is identical to a map followed by flat with depth 1. * * @param callback A function that accepts up to three arguments. The flatMap method calls the * callback function one time for each element in the array. @@ -135,7 +135,7 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[][][][][][][][], depth: 7): U[]; + flat(this: U[][][][][][][][], depth: 7): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the @@ -143,7 +143,7 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[][][][][][][], depth: 6): U[]; + flat(this: U[][][][][][][], depth: 6): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the @@ -151,7 +151,7 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[][][][][][], depth: 5): U[]; + flat(this: U[][][][][][], depth: 5): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the @@ -159,7 +159,7 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[][][][][], depth: 4): U[]; + flat(this: U[][][][][], depth: 4): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the @@ -167,7 +167,7 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[][][][], depth: 3): U[]; + flat(this: U[][][][], depth: 3): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the @@ -175,7 +175,7 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[][][], depth: 2): U[]; + flat(this: U[][][], depth: 2): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the @@ -183,7 +183,7 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[][], depth?: 1): U[]; + flat(this: U[][], depth?: 1): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the @@ -191,13 +191,13 @@ interface Array { * * @param depth The maximum recursion depth */ - flatten(this: U[], depth: 0): U[]; + flat(this: U[], depth: 0): U[]; /** * Returns a new array with all sub-array elements concatenated into it recursively up to the - * specified depth. If no depth is provided, flatten method defaults to the depth of 1. + * specified depth. If no depth is provided, flat method defaults to the depth of 1. * * @param depth The maximum recursion depth */ - flatten(depth?: number): any[]; + flat(depth?: number): any[]; } diff --git a/src/lib/esnext.d.ts b/src/lib/esnext.d.ts index 50b179191ad..99e71158f6a 100644 --- a/src/lib/esnext.d.ts +++ b/src/lib/esnext.d.ts @@ -1,3 +1,4 @@ /// /// /// +/// diff --git a/src/lib/esnext.symbol.d.ts b/src/lib/esnext.symbol.d.ts new file mode 100644 index 00000000000..9da5b779405 --- /dev/null +++ b/src/lib/esnext.symbol.d.ts @@ -0,0 +1,6 @@ +interface Symbol { + /** + * expose the [[Description]] internal slot of a symbol directly + */ + readonly description: string; +} diff --git a/src/lib/libs.json b/src/lib/libs.json index d3803464818..445a4b6e325 100644 --- a/src/lib/libs.json +++ b/src/lib/libs.json @@ -34,6 +34,7 @@ "es2018.intl", "esnext.asynciterable", "esnext.array", + "esnext.symbol", // Default libraries "es5.full", "es2015.full", diff --git a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl index 7581c49286b..22e99039884 100644 --- a/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/chs/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2619,6 +2619,24 @@ + + + + + + + + + + + + + + + + + + @@ -5433,6 +5451,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 0d661980ba6..25dd803be2c 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2619,6 +2619,24 @@ + + + + + + + + + + + + + + + + + + @@ -5433,6 +5451,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl index fc9952d3b43..c5bb7599859 100644 --- a/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/csy/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2628,6 +2628,24 @@ + + + + + + + + + + + + + + + + + + @@ -5442,6 +5460,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl index 3688383b060..6be145f0c21 100644 --- a/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/esn/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2406,6 +2406,15 @@ + + + + + + + + + @@ -2571,6 +2580,9 @@ + + + @@ -2619,6 +2631,24 @@ + + + + + + + + + + + + + + + + + + @@ -5433,6 +5463,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl index 0ea5759d00d..01118e162e7 100644 --- a/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/fra/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2631,6 +2631,24 @@ + + + + + + + + + + + + + + + + + + @@ -5445,6 +5463,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl index b49cfdfe469..5448bdd5957 100644 --- a/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ita/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2619,6 +2619,24 @@ + + + + + + + + + + + + + + + + + + @@ -5433,6 +5451,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl index e61caabaf99..b0d68c1af91 100644 --- a/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/kor/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2619,6 +2619,24 @@ + + + + + + + + + + + + + + + + + + @@ -5433,6 +5451,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 63032699b0e..2400d397683 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2609,6 +2609,24 @@ + + + + + + + + + + + + + + + + + + @@ -5423,6 +5441,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 339ed012ebb..5c86135cbf9 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2612,6 +2612,24 @@ + + + + + + + + + + + + + + + + + + @@ -5426,6 +5444,15 @@ + + + + + + + + + diff --git a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl index c9be251b033..9e0ffcb8f8f 100644 --- a/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/rus/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -2618,6 +2618,24 @@ + + + + + + + + + + + + + + + + + + @@ -5432,6 +5450,15 @@ + + + + + + + + + diff --git a/src/server/client.ts b/src/server/client.ts index a7e76fb06a8..e797cadb8ca 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -552,6 +552,10 @@ namespace ts.server { return notImplemented(); } + getJsxClosingTagAtPosition(_fileName: string, _position: number): never { + return notImplemented(); + } + getSpanOfEnclosingComment(_fileName: string, _position: number, _onlyMultiLine: boolean): TextSpan { return notImplemented(); } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 9c34130bdef..be1a6247fb0 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -6,6 +6,7 @@ namespace ts.server.protocol { // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. export const enum CommandTypes { + JsxClosingTag = "jsxClosingTag", Brace = "brace", /* @internal */ BraceFull = "brace-full", @@ -890,6 +891,17 @@ namespace ts.server.protocol { openingBrace: string; } + export interface JsxClosingTagRequest extends FileLocationRequest { + readonly command: CommandTypes.JsxClosingTag; + readonly arguments: JsxClosingTagRequestArgs; + } + + export interface JsxClosingTagRequestArgs extends FileLocationRequestArgs {} + + export interface JsxClosingTagResponse extends Response { + readonly body: TextInsertion; + } + /** * @deprecated * Get occurrences request; value of command field is diff --git a/src/server/session.ts b/src/server/session.ts index 191982a7cd4..3a368587d4b 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -818,6 +818,13 @@ namespace ts.server { return this.getDiagnosticsWorker(args, /*isSemantic*/ true, (project, file) => project.getLanguageService().getSuggestionDiagnostics(file), !!args.includeLinePosition); } + private getJsxClosingTag(args: protocol.JsxClosingTagRequestArgs): TextInsertion | undefined { + const { file, project } = this.getFileAndProject(args); + const position = this.getPositionInFile(args, file); + const tag = project.getLanguageService().getJsxClosingTagAtPosition(file, position); + return tag === undefined ? undefined : { newText: tag.newText, caretOffset: 0 }; + } + private getDocumentHighlights(args: protocol.DocumentHighlightsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { const { file, project } = this.getFileAndProject(args); const position = this.getPositionInFile(args, file); @@ -1692,7 +1699,7 @@ namespace ts.server { private getEditsForFileRename(args: protocol.GetEditsForFileRenameRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { const { file, project } = this.getFileAndProject(args); - const changes = project.getLanguageService().getEditsForFileRename(args.oldFilePath, args.newFilePath, this.getFormatOptions(file)); + const changes = project.getLanguageService().getEditsForFileRename(args.oldFilePath, args.newFilePath, this.getFormatOptions(file), this.getPreferences(file)); return simplifiedResult ? this.mapTextChangesToCodeEdits(project, changes) : changes; } @@ -2130,6 +2137,9 @@ namespace ts.server { this.projectService.reloadProjects(); return this.notRequired(); }, + [CommandNames.JsxClosingTag]: (request: protocol.JsxClosingTagRequest) => { + return this.requiredResponse(this.getJsxClosingTag(request.arguments)); + }, [CommandNames.GetCodeFixes]: (request: protocol.CodeFixRequest) => { return this.requiredResponse(this.getCodeFixes(request.arguments, /*simplifiedResult*/ true)); }, diff --git a/src/server/typingsInstaller/nodeTypingsInstaller.ts b/src/server/typingsInstaller/nodeTypingsInstaller.ts index 6de5d9e1e0c..d2c7269f9bf 100644 --- a/src/server/typingsInstaller/nodeTypingsInstaller.ts +++ b/src/server/typingsInstaller/nodeTypingsInstaller.ts @@ -106,7 +106,7 @@ namespace ts.server.typingsInstaller { if (this.log.isEnabled()) { this.log.writeLine(`Updating ${typesRegistryPackageName} npm package...`); } - this.execSyncAndLog(`${this.npmPath} install --ignore-scripts ${typesRegistryPackageName}`, { cwd: globalTypingsCacheLocation }); + this.execSyncAndLog(`${this.npmPath} install --ignore-scripts ${typesRegistryPackageName}@${this.latestDistTag}`, { cwd: globalTypingsCacheLocation }); if (this.log.isEnabled()) { this.log.writeLine(`Updated ${typesRegistryPackageName} npm package`); } diff --git a/src/server/typingsInstaller/typingsInstaller.ts b/src/server/typingsInstaller/typingsInstaller.ts index 5c1fcda6184..66e8e6fe3b8 100644 --- a/src/server/typingsInstaller/typingsInstaller.ts +++ b/src/server/typingsInstaller/typingsInstaller.ts @@ -350,7 +350,7 @@ namespace ts.server.typingsInstaller { // packageName is guaranteed to exist in typesRegistry by filterTypings const distTags = this.typesRegistry.get(packageName)!; - const newVersion = Semver.parse(distTags[`ts${versionMajorMinor}`] || distTags[latestDistTag]); + const newVersion = Semver.parse(distTags[`ts${versionMajorMinor}`] || distTags[this.latestDistTag]); const newTyping: JsTyping.CachedTyping = { typingLocation: typingFile, version: newVersion }; this.packageNameToTypingLocation.set(packageName, newTyping); installedTypingFiles.push(typingFile); @@ -523,12 +523,12 @@ namespace ts.server.typingsInstaller { protected abstract installWorker(requestId: number, packageNames: string[], cwd: string, onRequestCompleted: RequestCompletedAction): void; protected abstract sendResponse(response: SetTypings | InvalidateCachedTypings | BeginInstallTypes | EndInstallTypes): void; + + protected readonly latestDistTag = "latest"; } /* @internal */ export function typingsName(packageName: string): string { return `@types/${packageName}@ts${versionMajorMinor}`; } - - const latestDistTag = "latest"; } diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index 31b766d3bf5..4dbdc23041e 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -86,8 +86,8 @@ namespace ts { return createCombinedCodeActions(changes, commands.length === 0 ? undefined : commands); } - function eachDiagnostic({ program, sourceFile }: CodeFixAllContext, errorCodes: number[], cb: (diag: DiagnosticWithLocation) => void): void { - for (const diag of program.getSemanticDiagnostics(sourceFile).concat(computeSuggestionDiagnostics(sourceFile, program))) { + function eachDiagnostic({ program, sourceFile, cancellationToken }: CodeFixAllContext, errorCodes: number[], cb: (diag: DiagnosticWithLocation) => void): void { + for (const diag of program.getSemanticDiagnostics(sourceFile, cancellationToken).concat(computeSuggestionDiagnostics(sourceFile, program, cancellationToken))) { if (contains(errorCodes, diag.code)) { cb(diag as DiagnosticWithLocation); } diff --git a/src/services/codefixes/convertFunctionToEs6Class.ts b/src/services/codefixes/convertFunctionToEs6Class.ts index cd1baeb14a0..0d75de3e79b 100644 --- a/src/services/codefixes/convertFunctionToEs6Class.ts +++ b/src/services/codefixes/convertFunctionToEs6Class.ts @@ -176,7 +176,7 @@ namespace ts.codefix { return undefined; } - const memberElements = createClassElementsFromSymbol(initializer.symbol); + const memberElements = createClassElementsFromSymbol(node.symbol); if (initializer.body) { memberElements.unshift(createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); } diff --git a/src/services/codefixes/moduleSpecifiers.ts b/src/services/codefixes/moduleSpecifiers.ts index 5a08f7d3dea..be92b917273 100644 --- a/src/services/codefixes/moduleSpecifiers.ts +++ b/src/services/codefixes/moduleSpecifiers.ts @@ -1,6 +1,14 @@ // Used by importFixes to synthesize import module specifiers. /* @internal */ namespace ts.moduleSpecifiers { + // Note: fromSourceFile is just for usesJsExtensionOnImports + export function getModuleSpecifier(program: Program, fromSourceFile: SourceFile, fromSourceFileName: string, toFileName: string, host: LanguageServiceHost, preferences: UserPreferences) { + const info = getInfo(program.getCompilerOptions(), fromSourceFile, fromSourceFileName, host); + const compilerOptions = program.getCompilerOptions(); + return getGlobalModuleSpecifier(toFileName, info, host, compilerOptions) || + first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences)); + } + // For each symlink/original for a module, returns a list of ways to import that file. export function getModuleSpecifiers( moduleSymbol: Symbol, @@ -9,84 +17,110 @@ namespace ts.moduleSpecifiers { host: LanguageServiceHost, preferences: UserPreferences, ): ReadonlyArray> { - const compilerOptions = program.getCompilerOptions(); - const { baseUrl, paths, rootDirs } = compilerOptions; - const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); - const addJsExtension = usesJsExtensionOnImports(importingSourceFile); - const getCanonicalFileName = hostGetCanonicalFileName(host); - const sourceDirectory = getDirectoryPath(importingSourceFile.fileName); - const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol); if (ambient) return [[ambient]]; + const compilerOptions = program.getCompilerOptions(); + const info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.fileName, host); const modulePaths = getAllModulePaths(program, moduleSymbol.valueDeclaration.getSourceFile()); - const global = mapDefined(modulePaths, moduleFileName => - tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) || - tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) || - rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName)); - if (global.length) return global.map(g => [g]); + const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)); + return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName => + getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences)); + } - return modulePaths.map(moduleFileName => { - const relativePath = removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); - if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { - return [relativePath]; + interface Info { + readonly moduleResolutionKind: ModuleResolutionKind; + readonly addJsExtension: boolean; + readonly getCanonicalFileName: GetCanonicalFileName; + readonly sourceDirectory: string; + } + // importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path + function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: string, host: LanguageServiceHost): Info { + const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions); + const addJsExtension = usesJsExtensionOnImports(importingSourceFile); + const getCanonicalFileName = hostGetCanonicalFileName(host); + const sourceDirectory = getDirectoryPath(importingSourceFileName); + return { moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory }; + } + + function getGlobalModuleSpecifier( + moduleFileName: string, + { addJsExtension, getCanonicalFileName, sourceDirectory }: Info, + host: LanguageServiceHost, + compilerOptions: CompilerOptions, + ) { + return tryGetModuleNameFromTypeRoots(compilerOptions, host, getCanonicalFileName, moduleFileName, addJsExtension) + || tryGetModuleNameAsNodeModule(compilerOptions, moduleFileName, host, getCanonicalFileName, sourceDirectory) + || compilerOptions.rootDirs && tryGetModuleNameFromRootDirs(compilerOptions.rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); + } + + function getLocalModuleSpecifiers( + moduleFileName: string, + { moduleResolutionKind, addJsExtension, getCanonicalFileName, sourceDirectory }: Info, + compilerOptions: CompilerOptions, + preferences: UserPreferences, + ) { + const { baseUrl, paths } = compilerOptions; + + const relativePath = removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), moduleResolutionKind, addJsExtension); + if (!baseUrl || preferences.importModuleSpecifierPreference === "relative") { + return [relativePath]; + } + + const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); + if (!relativeToBaseUrl) { + return [relativePath]; + } + + const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); + if (paths) { + const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); + if (fromPaths) { + return [fromPaths]; } + } - const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); - if (!relativeToBaseUrl) { - return [relativePath]; - } + if (preferences.importModuleSpecifierPreference === "non-relative") { + return [importRelativeToBaseUrl]; + } - const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, moduleResolutionKind, addJsExtension); - if (paths) { - const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); - if (fromPaths) { - return [fromPaths]; - } - } + if (preferences.importModuleSpecifierPreference !== undefined) Debug.assertNever(preferences.importModuleSpecifierPreference); - if (preferences.importModuleSpecifierPreference === "non-relative") { - return [importRelativeToBaseUrl]; - } + if (isPathRelativeToParent(relativeToBaseUrl)) { + return [relativePath]; + } - if (preferences.importModuleSpecifierPreference !== undefined) Debug.assertNever(preferences.importModuleSpecifierPreference); + /* + Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. - if (isPathRelativeToParent(relativeToBaseUrl)) { - return [relativePath]; - } + Suppose we have: + baseUrl = /base + sourceDirectory = /base/a/b + moduleFileName = /base/foo/bar + Then: + relativePath = ../../foo/bar + getRelativePathNParents(relativePath) = 2 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 2 < 2 = false + In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". - /* - Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/a/b - moduleFileName = /base/foo/bar - Then: - relativePath = ../../foo/bar - getRelativePathNParents(relativePath) = 2 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 2 < 2 = false - In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". - - Suppose we have: - baseUrl = /base - sourceDirectory = /base/foo/a - moduleFileName = /base/foo/bar - Then: - relativePath = ../a - getRelativePathNParents(relativePath) = 1 - pathFromSourceToBaseUrl = ../../ - getRelativePathNParents(pathFromSourceToBaseUrl) = 2 - 1 < 2 = true - In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". - */ - const pathFromSourceToBaseUrl = ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); - const relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); - return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; - }); + Suppose we have: + baseUrl = /base + sourceDirectory = /base/foo/a + moduleFileName = /base/foo/bar + Then: + relativePath = ../a + getRelativePathNParents(relativePath) = 1 + pathFromSourceToBaseUrl = ../../ + getRelativePathNParents(pathFromSourceToBaseUrl) = 2 + 1 < 2 = true + In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". + */ + const pathFromSourceToBaseUrl = ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName)); + const relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl); + return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; } function usesJsExtensionOnImports({ imports }: SourceFile): boolean { diff --git a/src/services/completions.ts b/src/services/completions.ts index 522950e87ef..9f1a7cf0688 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -633,7 +633,7 @@ namespace ts.Completions { } const { moduleSymbol } = symbolOriginInfo; - const exportedSymbol = skipAlias(symbol.exportSymbol || symbol, checker); + const exportedSymbol = checker.getMergedSymbol(skipAlias(symbol.exportSymbol || symbol, checker)); const { moduleSpecifier, codeAction } = codefix.getImportCompletionAction( exportedSymbol, moduleSymbol, diff --git a/src/services/documentHighlights.ts b/src/services/documentHighlights.ts index afae01e0c68..d4199d80d85 100644 --- a/src/services/documentHighlights.ts +++ b/src/services/documentHighlights.ts @@ -78,6 +78,8 @@ namespace ts.DocumentHighlights { return useParent(node.parent, isAwaitExpression, getAsyncAndAwaitOccurrences); case SyntaxKind.AsyncKeyword: return highlightSpans(getAsyncAndAwaitOccurrences(node)); + case SyntaxKind.YieldKeyword: + return highlightSpans(getYieldOccurrences(node)); default: return isModifierKind(node.kind) && (isDeclaration(node.parent) || isVariableStatement(node.parent)) ? highlightSpans(getModifierOccurrences(node.kind, node.parent)) @@ -170,7 +172,7 @@ namespace ts.DocumentHighlights { if (statement.kind === SyntaxKind.ContinueStatement) { return false; } - // falls through + // falls through case SyntaxKind.ForStatement: case SyntaxKind.ForInStatement: case SyntaxKind.ForOfStatement: @@ -237,7 +239,7 @@ namespace ts.DocumentHighlights { } } - function pushKeywordIf(keywordList: Push, token: Node, ...expected: SyntaxKind[]): boolean { + function pushKeywordIf(keywordList: Push, token: Node | undefined, ...expected: SyntaxKind[]): boolean { if (token && contains(expected, token.kind)) { keywordList.push(token); return true; @@ -384,18 +386,42 @@ namespace ts.DocumentHighlights { }); } - forEachChild(func, aggregate); + forEachChild(func, child => { + traverseWithoutCrossingFunction(child, node => { + if (isAwaitExpression(node)) { + pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.AwaitKeyword); + } + }); + }); + return keywords; + } - function aggregate(node: Node): void { - if (isAwaitExpression(node)) { - pushKeywordIf(keywords, node.getFirstToken()!, SyntaxKind.AwaitKeyword); - } - // Do not cross function boundaries. - if (!isFunctionLike(node) && !isClassLike(node) && !isInterfaceDeclaration(node) && !isModuleDeclaration(node) && !isTypeAliasDeclaration(node) && !isTypeNode(node)) { - forEachChild(node, aggregate); - } + function getYieldOccurrences(node: Node): Node[] | undefined { + const func = getContainingFunction(node) as FunctionDeclaration; + if (!func) { + return undefined; + } + + const keywords: Node[] = []; + + forEachChild(func, child => { + traverseWithoutCrossingFunction(child, node => { + if (isYieldExpression(node)) { + pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.YieldKeyword); + } + }); + }); + + return keywords; + } + + // Do not cross function/class/interface/module/type boundaries. + function traverseWithoutCrossingFunction(node: Node, cb: (node: Node) => void) { + cb(node); + if (!isFunctionLike(node) && !isClassLike(node) && !isInterfaceDeclaration(node) && !isModuleDeclaration(node) && !isTypeAliasDeclaration(node) && !isTypeNode(node)) { + forEachChild(node, child => traverseWithoutCrossingFunction(child, cb)); } } diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index de1510943c3..c87bdb5e925 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -24,7 +24,7 @@ namespace ts.FindAllReferences { textSpan: TextSpan; } export function nodeEntry(node: Node, isInString?: true): NodeEntry { - return { type: "node", node, isInString }; + return { type: "node", node: (node as NamedDeclaration).name || node, isInString }; } export interface Options { @@ -1096,7 +1096,7 @@ namespace ts.FindAllReferences.Core { function addImplementationReferences(refNode: Node, addReference: (node: Node) => void, state: State): void { // Check if we found a function/propertyAssignment/method with an implementation or initializer if (isDeclarationName(refNode) && isImplementation(refNode.parent)) { - addReference(refNode.parent); + addReference(refNode); return; } diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 1726f5e0681..4bac4a2516d 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -1,68 +1,189 @@ /* @internal */ namespace ts { - export function getEditsForFileRename(program: Program, oldFilePath: string, newFilePath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext): ReadonlyArray { - const pathUpdater = getPathUpdater(oldFilePath, newFilePath, host); + export function getEditsForFileRename(program: Program, oldFileOrDirPath: string, newFileOrDirPath: string, host: LanguageServiceHost, formatContext: formatting.FormatContext, preferences: UserPreferences): ReadonlyArray { + const useCaseSensitiveFileNames = hostUsesCaseSensitiveFileNames(host); + const getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames); + const oldToNew = getPathUpdater(oldFileOrDirPath, newFileOrDirPath, getCanonicalFileName); + const newToOld = getPathUpdater(newFileOrDirPath, oldFileOrDirPath, getCanonicalFileName); return textChanges.ChangeTracker.with({ host, formatContext }, changeTracker => { - updateTsconfigFiles(program, changeTracker, oldFilePath, newFilePath); - for (const { sourceFile, toUpdate } of getImportsToUpdate(program, oldFilePath, host)) { - const newPath = pathUpdater(isRef(toUpdate) ? toUpdate.fileName : toUpdate.text); - if (newPath !== undefined) { - const range = isRef(toUpdate) ? toUpdate : createStringRange(toUpdate, sourceFile); - changeTracker.replaceRangeWithText(sourceFile, range, isRef(toUpdate) ? newPath : removeFileExtension(newPath)); - } - } + updateTsconfigFiles(program, changeTracker, oldToNew, newFileOrDirPath, host.getCurrentDirectory(), useCaseSensitiveFileNames); + updateImports(program, changeTracker, oldToNew, newToOld, host, getCanonicalFileName, preferences); }); } - function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldFilePath: string, newFilePath: string): void { - const configFile = program.getCompilerOptions().configFile; - if (!configFile) return; - const oldFile = getTsConfigPropArrayElementValue(configFile, "files", oldFilePath); - if (oldFile) { - changeTracker.replaceRangeWithText(configFile, createStringRange(oldFile, configFile), newFilePath); - } - } - - interface ToUpdate { - readonly sourceFile: SourceFile; - readonly toUpdate: StringLiteralLike | FileReference; - } - function isRef(toUpdate: StringLiteralLike | FileReference): toUpdate is FileReference { - return "fileName" in toUpdate; - } - - function getImportsToUpdate(program: Program, oldFilePath: string, host: LanguageServiceHost): ReadonlyArray { - const result: ToUpdate[] = []; - for (const sourceFile of program.getSourceFiles()) { - for (const ref of sourceFile.referencedFiles) { - if (resolveTripleslashReference(ref.fileName, sourceFile.fileName) === oldFilePath) { - result.push({ sourceFile, toUpdate: ref }); - } - } - - for (const importStringLiteral of sourceFile.imports) { - const resolved = host.resolveModuleNames - ? host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importStringLiteral.text, sourceFile.fileName) - : program.getResolvedModuleWithFailedLookupLocationsFromCache(importStringLiteral.text, sourceFile.fileName); - // We may or may not have picked up on the file being renamed, so maybe successfully resolved to oldFilePath, or maybe that's in failedLookupLocations - if (resolved && contains(resolved.resolvedModule ? [resolved.resolvedModule.resolvedFileName] : resolved.failedLookupLocations, oldFilePath)) { - result.push({ sourceFile, toUpdate: importStringLiteral }); - } - } - } - return result; - } - - function getPathUpdater(oldFilePath: string, newFilePath: string, host: LanguageServiceHost): (oldPath: string) => string | undefined { - // Get the relative path from old to new location, and append it on to the end of imports and normalize. - const rel = getRelativePathFromFile(oldFilePath, newFilePath, createGetCanonicalFileName(hostUsesCaseSensitiveFileNames(host))); - return oldPath => { - if (!pathIsRelative(oldPath)) return; - return ensurePathIsNonModuleName(normalizePath(combinePaths(getDirectoryPath(oldPath), rel))); + /** If 'path' refers to an old directory, returns path in the new directory. */ + type PathUpdater = (path: string) => string | undefined; + function getPathUpdater(oldFileOrDirPath: string, newFileOrDirPath: string, getCanonicalFileName: GetCanonicalFileName): PathUpdater { + const canonicalOldPath = getCanonicalFileName(oldFileOrDirPath); + return path => { + const canonicalPath = getCanonicalFileName(path); + if (canonicalPath === canonicalOldPath) return newFileOrDirPath; + const suffix = tryRemoveDirectoryPrefix(canonicalPath, canonicalOldPath); + return suffix === undefined ? undefined : newFileOrDirPath + "/" + suffix; }; } + function updateTsconfigFiles(program: Program, changeTracker: textChanges.ChangeTracker, oldToNew: PathUpdater, newFileOrDirPath: string, currentDirectory: string, useCaseSensitiveFileNames: boolean): void { + const { configFile } = program.getCompilerOptions(); + if (!configFile) return; + const configDir = getDirectoryPath(configFile.fileName); + + const jsonObjectLiteral = getTsConfigObjectLiteralExpression(configFile); + if (!jsonObjectLiteral) return; + + forEachProperty(jsonObjectLiteral, (property, propertyName) => { + switch (propertyName) { + case "files": + case "include": + case "exclude": { + const foundExactMatch = updatePaths(property); + if (!foundExactMatch && propertyName === "include" && isArrayLiteralExpression(property.initializer)) { + const includes = mapDefined(property.initializer.elements, e => isStringLiteral(e) ? e.text : undefined); + const matchers = getFileMatcherPatterns(configDir, /*excludes*/ [], includes, useCaseSensitiveFileNames, currentDirectory); + // If there isn't some include for this, add a new one. + if (!getRegexFromPattern(Debug.assertDefined(matchers.includeFilePattern), useCaseSensitiveFileNames).test(newFileOrDirPath)) { + changeTracker.insertNodeAfter(configFile, last(property.initializer.elements), createStringLiteral(relativePath(newFileOrDirPath))); + } + } + break; + } + case "compilerOptions": + forEachProperty(property.initializer, (property, propertyName) => { + const option = getOptionFromName(propertyName); + if (option && (option.isFilePath || option.type === "list" && (option as CommandLineOptionOfListType).element.isFilePath)) { + updatePaths(property); + } + else if (propertyName === "paths") { + forEachProperty(property.initializer, (pathsProperty) => { + if (!isArrayLiteralExpression(pathsProperty.initializer)) return; + for (const e of pathsProperty.initializer.elements) { + tryUpdateString(e); + } + }); + } + }); + break; + } + }); + + function updatePaths(property: PropertyAssignment): boolean { + // Type annotation needed due to #7294 + const elements: ReadonlyArray = isArrayLiteralExpression(property.initializer) ? property.initializer.elements : [property.initializer]; + let foundExactMatch = false; + for (const element of elements) { + foundExactMatch = tryUpdateString(element) || foundExactMatch; + } + return foundExactMatch; + } + + function tryUpdateString(element: Expression): boolean { + if (!isStringLiteral(element)) return false; + const elementFileName = combinePathsSafe(configDir, element.text); + + const updated = oldToNew(elementFileName); + if (updated !== undefined) { + changeTracker.replaceRangeWithText(configFile!, createStringRange(element, configFile!), relativePath(updated)); + return true; + } + return false; + } + + function relativePath(path: string): string { + return getRelativePathFromDirectory(configDir, path, /*ignoreCase*/ !useCaseSensitiveFileNames); + } + } + + function updateImports( + program: Program, + changeTracker: textChanges.ChangeTracker, + oldToNew: PathUpdater, + newToOld: PathUpdater, + host: LanguageServiceHost, + getCanonicalFileName: GetCanonicalFileName, + preferences: UserPreferences, + ): void { + for (const sourceFile of program.getSourceFiles()) { + const newImportFromPath = oldToNew(sourceFile.fileName) || sourceFile.fileName; + const newImportFromDirectory = getDirectoryPath(newImportFromPath); + + const oldFromNew: string | undefined = newToOld(sourceFile.fileName); + const oldImportFromPath: string = oldFromNew || sourceFile.fileName; + const oldImportFromDirectory = getDirectoryPath(oldImportFromPath); + + updateImportsWorker(sourceFile, changeTracker, + referenceText => { + if (!pathIsRelative(referenceText)) return undefined; + const oldAbsolute = combinePathsSafe(oldImportFromDirectory, referenceText); + const newAbsolute = oldToNew(oldAbsolute); + return newAbsolute === undefined ? undefined : ensurePathIsNonModuleName(getRelativePathFromDirectory(newImportFromDirectory, newAbsolute, getCanonicalFileName)); + }, + importLiteral => { + const toImport = oldFromNew !== undefined + // If we're at the new location (file was already renamed), need to redo module resolution starting from the old location. + // TODO:GH#18217 + ? getSourceFileToImportFromResolved(resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host as ModuleResolutionHost), oldToNew, program) + : getSourceFileToImport(importLiteral, sourceFile, program, host, oldToNew); + return toImport === undefined ? undefined : moduleSpecifiers.getModuleSpecifier(program, sourceFile, newImportFromPath, toImport, host, preferences); + }); + } + } + + function combineNormal(pathA: string, pathB: string): string { + return normalizePath(combinePaths(pathA, pathB)); + } + function combinePathsSafe(pathA: string, pathB: string): string { + return ensurePathIsNonModuleName(combineNormal(pathA, pathB)); + } + + function getSourceFileToImport(importLiteral: StringLiteralLike, importingSourceFile: SourceFile, program: Program, host: LanguageServiceHost, oldToNew: PathUpdater): string | undefined { + const symbol = program.getTypeChecker().getSymbolAtLocation(importLiteral); + if (symbol) { + if (symbol.declarations.some(d => isAmbientModule(d))) return undefined; // No need to update if it's an ambient module + const oldFileName = find(symbol.declarations, isSourceFile)!.fileName; + return oldToNew(oldFileName) || oldFileName; + } + else { + const resolved = host.resolveModuleNames + ? host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName) + : program.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName); + return getSourceFileToImportFromResolved(resolved, oldToNew, program); + } + } + + function getSourceFileToImportFromResolved(resolved: ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater, program: Program): string | undefined { + return resolved && ( + (resolved.resolvedModule && getIfInProgram(resolved.resolvedModule.resolvedFileName)) || firstDefined(resolved.failedLookupLocations, getIfInProgram)); + + function getIfInProgram(oldLocation: string): string | undefined { + const newLocation = oldToNew(oldLocation); + return program.getSourceFile(oldLocation) || newLocation !== undefined && program.getSourceFile(newLocation) + ? newLocation || oldLocation + : undefined; + } + } + + function updateImportsWorker(sourceFile: SourceFile, changeTracker: textChanges.ChangeTracker, updateRef: (refText: string) => string | undefined, updateImport: (importLiteral: StringLiteralLike) => string | undefined) { + for (const ref of sourceFile.referencedFiles) { + const updated = updateRef(ref.fileName); + if (updated !== undefined && updated !== sourceFile.text.slice(ref.pos, ref.end)) changeTracker.replaceRangeWithText(sourceFile, ref, updated); + } + + for (const importStringLiteral of sourceFile.imports) { + const updated = updateImport(importStringLiteral); + if (updated !== undefined && updated !== importStringLiteral.text) changeTracker.replaceRangeWithText(sourceFile, createStringRange(importStringLiteral, sourceFile), updated); + } + } + function createStringRange(node: StringLiteralLike, sourceFile: SourceFileLike): TextRange { return createTextRange(node.getStart(sourceFile) + 1, node.end - 1); } + + function forEachProperty(objectLiteral: Expression, cb: (property: PropertyAssignment, propertyName: string) => void) { + if (!isObjectLiteralExpression(objectLiteral)) return; + for (const property of objectLiteral.properties) { + if (isPropertyAssignment(property) && isStringLiteral(property.name)) { + cb(property, property.name.text); + } + } + } } diff --git a/src/services/jsTyping.ts b/src/services/jsTyping.ts index 539099510f1..e9c96ba2bf6 100644 --- a/src/services/jsTyping.ts +++ b/src/services/jsTyping.ts @@ -160,7 +160,8 @@ namespace ts.JsTyping { } // Add the cached typing locations for inferred typings that are already installed packageNameToTypingLocation.forEach((typing, name) => { - if (inferredTypings.has(name) && inferredTypings.get(name) === undefined && isTypingUpToDate(typing, typesRegistry.get(name)!)) { + const registryEntry = typesRegistry.get(name); + if (inferredTypings.has(name) && inferredTypings.get(name) === undefined && registryEntry !== undefined && isTypingUpToDate(typing, registryEntry)) { inferredTypings.set(name, typing.typingLocation); } }); diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 48e361c1b01..c1f1ec1fd5e 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -153,6 +153,8 @@ namespace ts.refactor { if (sourceFile === oldFile) continue; for (const statement of sourceFile.statements) { forEachImportInStatement(statement, importNode => { + if (checker.getSymbolAtLocation(moduleSpecifierFromImport(importNode)) !== oldFile.symbol) return; + const shouldMove = (name: Identifier): boolean => { const symbol = isBindingElement(name.parent) ? getPropertySymbolFromBindingElement(checker, name.parent as BindingElement & { name: Identifier }) @@ -163,11 +165,76 @@ namespace ts.refactor { const newModuleSpecifier = combinePaths(getDirectoryPath(moduleSpecifierFromImport(importNode).text), newModuleName); const newImportDeclaration = filterImport(importNode, createLiteral(newModuleSpecifier), shouldMove); if (newImportDeclaration) changes.insertNodeAfter(sourceFile, statement, newImportDeclaration); + + const ns = getNamespaceLikeImport(importNode); + if (ns) updateNamespaceLikeImport(changes, sourceFile, checker, movedSymbols, newModuleName, newModuleSpecifier, ns, importNode); }); } } } + function getNamespaceLikeImport(node: SupportedImport): Identifier | undefined { + switch (node.kind) { + case SyntaxKind.ImportDeclaration: + return node.importClause && node.importClause.namedBindings && node.importClause.namedBindings.kind === SyntaxKind.NamespaceImport ? + node.importClause.namedBindings.name : undefined; + case SyntaxKind.ImportEqualsDeclaration: + return node.name; + case SyntaxKind.VariableDeclaration: + return tryCast(node.name, isIdentifier); + default: + return Debug.assertNever(node); + } + } + + function updateNamespaceLikeImport( + changes: textChanges.ChangeTracker, + sourceFile: SourceFile, + checker: TypeChecker, + movedSymbols: ReadonlySymbolSet, + newModuleName: string, + newModuleSpecifier: string, + oldImportId: Identifier, + oldImportNode: SupportedImport, + ): void { + const preferredNewNamespaceName = codefix.moduleSpecifierToValidIdentifier(newModuleName, ScriptTarget.ESNext); + let needUniqueName = false; + const toChange: Identifier[] = []; + FindAllReferences.Core.eachSymbolReferenceInFile(oldImportId, checker, sourceFile, ref => { + if (!isPropertyAccessExpression(ref.parent)) return; + needUniqueName = needUniqueName || !!checker.resolveName(preferredNewNamespaceName, ref, SymbolFlags.All, /*excludeGlobals*/ true); + if (movedSymbols.has(checker.getSymbolAtLocation(ref.parent.name)!)) { + toChange.push(ref); + } + }); + + if (toChange.length) { + const newNamespaceName = needUniqueName ? getUniqueName(preferredNewNamespaceName, sourceFile) : preferredNewNamespaceName; + for (const ref of toChange) { + changes.replaceNode(sourceFile, ref, createIdentifier(newNamespaceName)); + } + changes.insertNodeAfter(sourceFile, oldImportNode, updateNamespaceLikeImportNode(oldImportNode, newModuleName, newModuleSpecifier)); + } + } + + function updateNamespaceLikeImportNode(node: SupportedImport, newNamespaceName: string, newModuleSpecifier: string): Node { + const newNamespaceId = createIdentifier(newNamespaceName); + const newModuleString = createLiteral(newModuleSpecifier); + switch (node.kind) { + case SyntaxKind.ImportDeclaration: + return createImportDeclaration( + /*decorators*/ undefined, /*modifiers*/ undefined, + createImportClause(/*name*/ undefined, createNamespaceImport(newNamespaceId)), + newModuleString); + case SyntaxKind.ImportEqualsDeclaration: + return createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newNamespaceId, createExternalModuleReference(newModuleString)); + case SyntaxKind.VariableDeclaration: + return createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString)); + default: + return Debug.assertNever(node); + } + } + function moduleSpecifierFromImport(i: SupportedImport): StringLiteralLike { return (i.kind === SyntaxKind.ImportDeclaration ? i.moduleSpecifier : i.kind === SyntaxKind.ImportEqualsDeclaration ? i.moduleReference.expression @@ -404,7 +471,7 @@ namespace ts.refactor { if (isInImport(decl)) { oldImportsNeededByNewFile.add(symbol); } - else if (isTopLevelDeclaration(decl) && !movedSymbols.has(symbol)) { + else if (isTopLevelDeclaration(decl) && sourceFileOfTopLevelDeclaration(decl) === oldFile && !movedSymbols.has(symbol)) { newFileImportsFromOldFile.add(symbol); } } @@ -546,7 +613,11 @@ namespace ts.refactor { interface TopLevelVariableDeclaration extends VariableDeclaration { parent: VariableDeclarationList & { parent: VariableStatement; }; } type TopLevelDeclaration = NonVariableTopLevelDeclaration | TopLevelVariableDeclaration; function isTopLevelDeclaration(node: Node): node is TopLevelDeclaration { - return isNonVariableTopLevelDeclaration(node) || isVariableDeclaration(node) && isSourceFile(node.parent.parent.parent); + return isNonVariableTopLevelDeclaration(node) && isSourceFile(node.parent) || isVariableDeclaration(node) && isSourceFile(node.parent.parent.parent); + } + + function sourceFileOfTopLevelDeclaration(node: TopLevelDeclaration): Node { + return isVariableDeclaration(node) ? node.parent.parent.parent : node.parent; } function isTopLevelDeclarationStatement(node: Node): node is TopLevelDeclarationStatement { diff --git a/src/services/services.ts b/src/services/services.ts index 5ab3bd120fc..44beeccac65 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1416,7 +1416,7 @@ namespace ts { function getSuggestionDiagnostics(fileName: string): DiagnosticWithLocation[] { synchronizeHostData(); - return computeSuggestionDiagnostics(getValidSourceFile(fileName), program); + return computeSuggestionDiagnostics(getValidSourceFile(fileName), program, cancellationToken); } function getCompilerOptionsDiagnostics() { @@ -1781,10 +1781,6 @@ namespace ts { return syntaxTreeCache.getCurrentSourceFile(fileName); } - function getSourceFile(fileName: string): SourceFile { - return getNonBoundSourceFile(fileName); - } - function getNameOrDottedNameSpan(fileName: string, startPos: number, _endPos: number): TextSpan | undefined { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); @@ -1986,8 +1982,8 @@ namespace ts { return OrganizeImports.organizeImports(sourceFile, formatContext, host, program, preferences); } - function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray { - return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions)); + function getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences = defaultPreferences): ReadonlyArray { + return ts.getEditsForFileRename(getProgram()!, oldFilePath, newFilePath, host, formatting.getFormatContext(formatOptions), preferences); } function applyCodeActionCommand(action: CodeActionCommand): Promise; @@ -2052,6 +2048,17 @@ namespace ts { return true; } + function getJsxClosingTagAtPosition(fileName: string, position: number): JsxClosingTagInfo | undefined { + const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); + const token = findPrecedingToken(position, sourceFile); + if (!token) return undefined; + const element = token.kind === SyntaxKind.GreaterThanToken && isJsxOpeningElement(token.parent) ? token.parent.parent + : isJsxText(token) ? token.parent : undefined; + if (element && !tagNamesAreEquivalent(element.openingElement.tagName, element.closingElement.tagName)) { + return { newText: `` }; + } + } + function getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined { const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); const range = formatting.getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine); @@ -2284,6 +2291,7 @@ namespace ts { getFormattingEditsAfterKeystroke, getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition, + getJsxClosingTagAtPosition, getSpanOfEnclosingComment, getCodeFixesAtPosition, getCombinedCodeFix, @@ -2292,7 +2300,6 @@ namespace ts { getEditsForFileRename, getEmitOutput, getNonBoundSourceFile, - getSourceFile, getProgram, getApplicableRefactors, getEditsForRefactor, diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 4e09b97fec8..1f4ced61191 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -1,8 +1,7 @@ /* @internal */ namespace ts { - export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program): DiagnosticWithLocation[] { - program.getSemanticDiagnostics(sourceFile); - const checker = program.getDiagnosticsProducingTypeChecker(); + export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] { + program.getSemanticDiagnostics(sourceFile, cancellationToken); const diags: DiagnosticWithLocation[] = []; if (sourceFile.commonJsModuleIndicator && @@ -13,39 +12,8 @@ namespace ts { const isJsFile = isSourceFileJavaScript(sourceFile); - function check(node: Node) { - switch (node.kind) { - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - if (isJsFile) { - if (node.symbol.members && (node.symbol.members.size > 0)) { - diags.push(createDiagnosticForNode(isVariableDeclaration(node.parent) ? node.parent.name : node, Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration)); - } - } - break; - } - - if (!isJsFile && codefix.parameterShouldGetTypeFromJSDoc(node)) { - diags.push(createDiagnosticForNode(node.name || node, Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types)); - } - - node.forEachChild(check); - } check(sourceFile); - if (!isJsFile) { - for (const statement of sourceFile.statements) { - if (isVariableStatement(statement) && - statement.declarationList.flags & NodeFlags.Const && - statement.declarationList.declarations.length === 1) { - const init = statement.declarationList.declarations[0].initializer; - if (init && isRequireCall(init, /*checkArgumentIsStringLiteralLike*/ true)) { - diags.push(createDiagnosticForNode(init, Diagnostics.require_call_may_be_converted_to_an_import)); - } - } - } - } - if (getAllowSyntheticDefaultImports(program.getCompilerOptions())) { for (const moduleSpecifier of sourceFile.imports) { const importNode = importFromModuleSpecifier(moduleSpecifier); @@ -60,7 +28,48 @@ namespace ts { } addRange(diags, sourceFile.bindSuggestionDiagnostics); - return diags.concat(checker.getSuggestionDiagnostics(sourceFile)).sort((d1, d2) => d1.start - d2.start); + addRange(diags, program.getSuggestionDiagnostics(sourceFile, cancellationToken)); + return diags.sort((d1, d2) => d1.start - d2.start); + + function check(node: Node) { + if (isJsFile) { + switch (node.kind) { + case SyntaxKind.FunctionExpression: + const decl = getDeclarationOfJSInitializer(node); + if (decl) { + const symbol = decl.symbol; + if (symbol && (symbol.exports && symbol.exports.size || symbol.members && symbol.members.size)) { + diags.push(createDiagnosticForNode(isVariableDeclaration(node.parent) ? node.parent.name : node, Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration)); + break; + } + } + // falls through if no diagnostic was created + case SyntaxKind.FunctionDeclaration: + const symbol = node.symbol; + if (symbol.members && (symbol.members.size > 0)) { + diags.push(createDiagnosticForNode(isVariableDeclaration(node.parent) ? node.parent.name : node, Diagnostics.This_constructor_function_may_be_converted_to_a_class_declaration)); + } + break; + } + } + else { + if (isVariableStatement(node) && + node.parent === sourceFile && + node.declarationList.flags & NodeFlags.Const && + node.declarationList.declarations.length === 1) { + const init = node.declarationList.declarations[0].initializer; + if (init && isRequireCall(init, /*checkArgumentIsStringLiteralLike*/ true)) { + diags.push(createDiagnosticForNode(init, Diagnostics.require_call_may_be_converted_to_an_import)); + } + } + + if (codefix.parameterShouldGetTypeFromJSDoc(node)) { + diags.push(createDiagnosticForNode(node.name || node, Diagnostics.JSDoc_types_may_be_moved_to_TypeScript_types)); + } + } + + node.forEachChild(check); + } } // convertToEs6Module only works on top-level, so don't trigger it if commonjs code only appears in nested scopes. diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 528ec8268b2..02c29b0568d 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -496,7 +496,7 @@ namespace ts.textChanges { else if (isStatement(node) || isClassOrTypeElement(node)) { return { suffix: this.newLineCharacter }; } - else if (isVariableDeclaration(node)) { + else if (isVariableDeclaration(node) || isStringLiteral(node)) { return { prefix: ", " }; } else if (isPropertyAssignment(node)) { diff --git a/src/services/types.ts b/src/services/types.ts index e4144dd5afd..4ac439b56cc 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -325,6 +325,11 @@ namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion | undefined; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; + /** + * This will return a defined result if the position is after the `>` of the opening tag, or somewhere in the text, of a JSXElement with no closing tag. + * Editors should call this after `>` is typed. + */ + getJsxClosingTagAtPosition(fileName: string, position: number): JsxClosingTagInfo | undefined; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined; @@ -344,7 +349,7 @@ namespace ts { getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; - getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; + getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; @@ -352,15 +357,13 @@ namespace ts { /* @internal */ getNonBoundSourceFile(fileName: string): SourceFile; - /** - * @internal - * @deprecated Use ts.createSourceFile instead. - */ - getSourceFile(fileName: string): SourceFile; - dispose(): void; } + export interface JsxClosingTagInfo { + readonly newText: string; + } + export interface CombinedCodeFixScope { type: "file"; fileName: string; } export type OrganizeImportsScope = CombinedCodeFixScope; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index fbccd72c2aa..fa795f359ff 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1196,6 +1196,7 @@ namespace ts { SyntaxKind.VoidKeyword, SyntaxKind.UndefinedKeyword, SyntaxKind.UniqueKeyword, + SyntaxKind.UnknownKeyword, ]; export function isTypeKeyword(kind: SyntaxKind): boolean { diff --git a/tests/baselines/reference/APISample_Watch.js b/tests/baselines/reference/APISample_Watch.js new file mode 100644 index 00000000000..5e3a67e827d --- /dev/null +++ b/tests/baselines/reference/APISample_Watch.js @@ -0,0 +1,133 @@ +//// [APISample_Watch.ts] +/* + * Note: This test is a public API sample. The sample sources can be found + at: https://github.com/Microsoft/TypeScript-wiki/blob/master/Using-the-Compiler-API.md#writing-an-incremental-program-watcher + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ + +declare var process: any; +declare var console: any; +declare var os: any; + +import ts = require("typescript"); + +const formatHost: ts.FormatDiagnosticsHost = { + getCanonicalFileName: path => path, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getNewLine: () => ts.sys.newLine, +} + +function watchMain() { + const configPath = ts.findConfigFile(/*searchPath*/ "./", ts.sys.fileExists, "tsconfig.json"); + if (!configPath) { + throw new Error("Could not find a valid 'tsconfig.json'."); + } + + // TypeScript can use several different program creation "strategies": + // * ts.createEmitAndSemanticDiagnosticsBuilderProgram, + // * ts.createSemanticDiagnosticsBuilderProgram + // * ts.createAbstractBuilder + // The first two produce "builder programs". These use an incremental strategy to only re-check and emit files whose + // contents may have changed, or whose dependencies may have changes which may impact change the result of prior type-check and emit. + // The last uses an ordinary program which does a full type check after every change. + // Between `createEmitAndSemanticDiagnosticsBuilderProgram` and `createSemanticDiagnosticsBuilderProgram`, the only difference is emit. + // For pure type-checking scenarios, or when another tool/process handles emit, using `createSemanticDiagnosticsBuilderProgram` may be more desirable. + + // Note that there is another overload for `createWatchCompilerHost` that takes a set of root files. + const host = ts.createWatchCompilerHost(configPath, {}, ts.sys, + ts.createSemanticDiagnosticsBuilderProgram, + reportDiagnostic, + reportWatchStatusChanged, + ); + + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + const origCreateProgram = host.createProgram; + host.createProgram = (rootNames: ReadonlyArray, options, host, oldProgram) => { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + } + const origPostProgramCreate = host.afterProgramCreate; + + host.afterProgramCreate = program => { + console.log("** We finished making the program! **"); + origPostProgramCreate!(program); + }; + + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} + +function reportDiagnostic(diagnostic: ts.Diagnostic) { + console.error("Error", diagnostic.code, ":", + ts.flattenDiagnosticMessageText(diagnostic.messageText, formatHost.getNewLine()) + ); +} + +/** + * Prints a diagnostic every time the watch status changes. + * This is mainly for messages like "Starting compilation" or "Compilation completed". + */ +function reportWatchStatusChanged(diagnostic: ts.Diagnostic) { + console.info(ts.formatDiagnostic(diagnostic, formatHost)); +} + +watchMain(); + + +//// [APISample_Watch.js] +"use strict"; +/* + * Note: This test is a public API sample. The sample sources can be found + at: https://github.com/Microsoft/TypeScript-wiki/blob/master/Using-the-Compiler-API.md#writing-an-incremental-program-watcher + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ +exports.__esModule = true; +var ts = require("typescript"); +var formatHost = { + getCanonicalFileName: function (path) { return path; }, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getNewLine: function () { return ts.sys.newLine; } +}; +function watchMain() { + var configPath = ts.findConfigFile(/*searchPath*/ "./", ts.sys.fileExists, "tsconfig.json"); + if (!configPath) { + throw new Error("Could not find a valid 'tsconfig.json'."); + } + // TypeScript can use several different program creation "strategies": + // * ts.createEmitAndSemanticDiagnosticsBuilderProgram, + // * ts.createSemanticDiagnosticsBuilderProgram + // * ts.createAbstractBuilder + // The first two produce "builder programs". These use an incremental strategy to only re-check and emit files whose + // contents may have changed, or whose dependencies may have changes which may impact change the result of prior type-check and emit. + // The last uses an ordinary program which does a full type check after every change. + // Between `createEmitAndSemanticDiagnosticsBuilderProgram` and `createSemanticDiagnosticsBuilderProgram`, the only difference is emit. + // For pure type-checking scenarios, or when another tool/process handles emit, using `createSemanticDiagnosticsBuilderProgram` may be more desirable. + // Note that there is another overload for `createWatchCompilerHost` that takes a set of root files. + var host = ts.createWatchCompilerHost(configPath, {}, ts.sys, ts.createSemanticDiagnosticsBuilderProgram, reportDiagnostic, reportWatchStatusChanged); + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + var origCreateProgram = host.createProgram; + host.createProgram = function (rootNames, options, host, oldProgram) { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + }; + var origPostProgramCreate = host.afterProgramCreate; + host.afterProgramCreate = function (program) { + console.log("** We finished making the program! **"); + origPostProgramCreate(program); + }; + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} +function reportDiagnostic(diagnostic) { + console.error("Error", diagnostic.code, ":", ts.flattenDiagnosticMessageText(diagnostic.messageText, formatHost.getNewLine())); +} +/** + * Prints a diagnostic every time the watch status changes. + * This is mainly for messages like "Starting compilation" or "Compilation completed". + */ +function reportWatchStatusChanged(diagnostic) { + console.info(ts.formatDiagnostic(diagnostic, formatHost)); +} +watchMain(); diff --git a/tests/baselines/reference/APISample_WatchWithDefaults.js b/tests/baselines/reference/APISample_WatchWithDefaults.js new file mode 100644 index 00000000000..493bef221f6 --- /dev/null +++ b/tests/baselines/reference/APISample_WatchWithDefaults.js @@ -0,0 +1,90 @@ +//// [APISample_WatchWithDefaults.ts] +/* + * Note: This test is a public API sample. This uses default sys interface without having to pass anything + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ + +declare var console: any; + +import ts = require("typescript"); + +function watchMain() { + const configPath = ts.findConfigFile(/*searchPath*/ "./", ts.sys.fileExists, "tsconfig.json"); + if (!configPath) { + throw new Error("Could not find a valid 'tsconfig.json'."); + } + + // TypeScript can use several different program creation "strategies": + // * ts.createEmitAndSemanticDiagnosticsBuilderProgram, + // * ts.createSemanticDiagnosticsBuilderProgram + // * ts.createAbstractBuilder + // The first two produce "builder programs". These use an incremental strategy to only re-check and emit files whose + // contents may have changed, or whose dependencies may have changes which may impact change the result of prior type-check and emit. + // The last uses an ordinary program which does a full type check after every change. + // Between `createEmitAndSemanticDiagnosticsBuilderProgram` and `createSemanticDiagnosticsBuilderProgram`, the only difference is emit. + // For pure type-checking scenarios, or when another tool/process handles emit, using `createSemanticDiagnosticsBuilderProgram` may be more desirable. + + // Note that there is another overload for `createWatchCompilerHost` that takes a set of root files. + const host = ts.createWatchCompilerHost(configPath, {}, ts.sys); + + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + const origCreateProgram = host.createProgram; + host.createProgram = (rootNames, options, host, oldProgram) => { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + } + const origPostProgramCreate = host.afterProgramCreate; + + host.afterProgramCreate = program => { + console.log("** We finished making the program! **"); + origPostProgramCreate!(program); + }; + + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} + +watchMain(); + + +//// [APISample_WatchWithDefaults.js] +"use strict"; +/* + * Note: This test is a public API sample. This uses default sys interface without having to pass anything + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ +exports.__esModule = true; +var ts = require("typescript"); +function watchMain() { + var configPath = ts.findConfigFile(/*searchPath*/ "./", ts.sys.fileExists, "tsconfig.json"); + if (!configPath) { + throw new Error("Could not find a valid 'tsconfig.json'."); + } + // TypeScript can use several different program creation "strategies": + // * ts.createEmitAndSemanticDiagnosticsBuilderProgram, + // * ts.createSemanticDiagnosticsBuilderProgram + // * ts.createAbstractBuilder + // The first two produce "builder programs". These use an incremental strategy to only re-check and emit files whose + // contents may have changed, or whose dependencies may have changes which may impact change the result of prior type-check and emit. + // The last uses an ordinary program which does a full type check after every change. + // Between `createEmitAndSemanticDiagnosticsBuilderProgram` and `createSemanticDiagnosticsBuilderProgram`, the only difference is emit. + // For pure type-checking scenarios, or when another tool/process handles emit, using `createSemanticDiagnosticsBuilderProgram` may be more desirable. + // Note that there is another overload for `createWatchCompilerHost` that takes a set of root files. + var host = ts.createWatchCompilerHost(configPath, {}, ts.sys); + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + var origCreateProgram = host.createProgram; + host.createProgram = function (rootNames, options, host, oldProgram) { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + }; + var origPostProgramCreate = host.afterProgramCreate; + host.afterProgramCreate = function (program) { + console.log("** We finished making the program! **"); + origPostProgramCreate(program); + }; + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} +watchMain(); diff --git a/tests/baselines/reference/APISample_WatchWithOwnWatchHost.js b/tests/baselines/reference/APISample_WatchWithOwnWatchHost.js new file mode 100644 index 00000000000..95f6df3fb51 --- /dev/null +++ b/tests/baselines/reference/APISample_WatchWithOwnWatchHost.js @@ -0,0 +1,102 @@ +//// [APISample_WatchWithOwnWatchHost.ts] +/* + * Note: This test is a public API sample. This sample verifies creating abstract builder to watch list of root files + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ + +declare var console: any; + +import ts = require("typescript"); + +function watchMain() { + // get list of files and compiler options somehow + const files: string[] = []; + const options: ts.CompilerOptions = {}; + + const host: ts.WatchCompilerHostOfFilesAndCompilerOptions = { + rootFiles: files, + options, + + useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, + getNewLine: () => ts.sys.newLine, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getDefaultLibFileName: options => ts.getDefaultLibFilePath(options), + + fileExists: ts.sys.fileExists, + readFile: ts.sys.readFile, + directoryExists: ts.sys.directoryExists, + getDirectories: ts.sys.getDirectories, + readDirectory: ts.sys.readDirectory, + realpath: ts.sys.realpath, + + watchFile: ts.sys.watchFile!, + watchDirectory: ts.sys.watchDirectory!, + createProgram: ts.createAbstractBuilder + }; + + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + const origCreateProgram = host.createProgram; + host.createProgram = (rootNames, options, host, oldProgram) => { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + } + const origPostProgramCreate = host.afterProgramCreate; + + host.afterProgramCreate = program => { + console.log("** We finished making the program! **"); + origPostProgramCreate!(program); + }; + + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} + +watchMain(); + + +//// [APISample_WatchWithOwnWatchHost.js] +"use strict"; +/* + * Note: This test is a public API sample. This sample verifies creating abstract builder to watch list of root files + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ +exports.__esModule = true; +var ts = require("typescript"); +function watchMain() { + // get list of files and compiler options somehow + var files = []; + var options = {}; + var host = { + rootFiles: files, + options: options, + useCaseSensitiveFileNames: function () { return ts.sys.useCaseSensitiveFileNames; }, + getNewLine: function () { return ts.sys.newLine; }, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getDefaultLibFileName: function (options) { return ts.getDefaultLibFilePath(options); }, + fileExists: ts.sys.fileExists, + readFile: ts.sys.readFile, + directoryExists: ts.sys.directoryExists, + getDirectories: ts.sys.getDirectories, + readDirectory: ts.sys.readDirectory, + realpath: ts.sys.realpath, + watchFile: ts.sys.watchFile, + watchDirectory: ts.sys.watchDirectory, + createProgram: ts.createAbstractBuilder + }; + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + var origCreateProgram = host.createProgram; + host.createProgram = function (rootNames, options, host, oldProgram) { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + }; + var origPostProgramCreate = host.afterProgramCreate; + host.afterProgramCreate = function (program) { + console.log("** We finished making the program! **"); + origPostProgramCreate(program); + }; + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} +watchMain(); diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e38f87e08af..bf6db412bf8 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4023,6 +4023,17 @@ declare namespace ts { function formatDiagnosticsWithColorAndContext(diagnostics: ReadonlyArray, host: FormatDiagnosticsHost): string; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain | undefined, newLine: string): string; function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray; + /** + * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' + * that represent a compilation unit. + * + * Creating a program proceeds from a set of root files, expanding the set of inputs by following imports and + * triple-slash-reference-path directives transitively. '@types' and triple-slash-reference-types are also pulled in. + * + * @param createProgramOptions - The options for creating a program. + * @returns A 'Program' object. + */ + function createProgram(createProgramOptions: CreateProgramOptions): Program; /** * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' * that represent a compilation unit. @@ -4037,7 +4048,6 @@ declare namespace ts { * @param configFileParsingDiagnostics - error during config file parsing * @returns A 'Program' object. */ - function createProgram(createProgramOptions: CreateProgramOptions): Program; function createProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray): Program; } declare namespace ts { @@ -4163,18 +4173,18 @@ declare namespace ts { * Create the builder to manage semantic diagnostics and cache them */ function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; - function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; + function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; /** * Create the builder that can handle the changes in program and iterate through changed files * to emit the those files and manage semantic diagnostics cache as well */ function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; - function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; + function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; /** * Creates a builder thats just abstraction over program and can be used with watch */ function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; - function createAbstractBuilder(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; + function createAbstractBuilder(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; } declare namespace ts { type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; @@ -4558,6 +4568,11 @@ declare namespace ts { getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[]; getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion | undefined; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; + /** + * This will return a defined result if the position is after the `>` of the opening tag, or somewhere in the text, of a JSXElement with no closing tag. + * Editors should call this after `>` is typed. + */ + getJsxClosingTagAtPosition(fileName: string, position: number): JsxClosingTagInfo | undefined; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined; toLineColumnOffset?(fileName: string, position: number): LineAndCharacter; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray; @@ -4574,11 +4589,14 @@ declare namespace ts { getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; - getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; + getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program | undefined; dispose(): void; } + interface JsxClosingTagInfo { + readonly newText: string; + } interface CombinedCodeFixScope { type: "file"; fileName: string; @@ -5508,6 +5526,7 @@ declare namespace ts.server { */ declare namespace ts.server.protocol { enum CommandTypes { + JsxClosingTag = "jsxClosingTag", Brace = "brace", BraceCompletion = "braceCompletion", GetSpanOfEnclosingComment = "getSpanOfEnclosingComment", @@ -6177,6 +6196,15 @@ declare namespace ts.server.protocol { */ openingBrace: string; } + interface JsxClosingTagRequest extends FileLocationRequest { + readonly command: CommandTypes.JsxClosingTag; + readonly arguments: JsxClosingTagRequestArgs; + } + interface JsxClosingTagRequestArgs extends FileLocationRequestArgs { + } + interface JsxClosingTagResponse extends Response { + readonly body: TextInsertion; + } /** * @deprecated * Get occurrences request; value of command field is @@ -8465,6 +8493,7 @@ declare namespace ts.server { private getSyntacticDiagnosticsSync; private getSemanticDiagnosticsSync; private getSuggestionDiagnosticsSync; + private getJsxClosingTag; private getDocumentHighlights; private setCompilerOptionsForInferredProjects; private getProjectInfo; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b9d91130b46..32316e23f12 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4023,6 +4023,17 @@ declare namespace ts { function formatDiagnosticsWithColorAndContext(diagnostics: ReadonlyArray, host: FormatDiagnosticsHost): string; function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain | undefined, newLine: string): string; function getConfigFileParsingDiagnostics(configFileParseResult: ParsedCommandLine): ReadonlyArray; + /** + * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' + * that represent a compilation unit. + * + * Creating a program proceeds from a set of root files, expanding the set of inputs by following imports and + * triple-slash-reference-path directives transitively. '@types' and triple-slash-reference-types are also pulled in. + * + * @param createProgramOptions - The options for creating a program. + * @returns A 'Program' object. + */ + function createProgram(createProgramOptions: CreateProgramOptions): Program; /** * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' * that represent a compilation unit. @@ -4037,7 +4048,6 @@ declare namespace ts { * @param configFileParsingDiagnostics - error during config file parsing * @returns A 'Program' object. */ - function createProgram(createProgramOptions: CreateProgramOptions): Program; function createProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray): Program; } declare namespace ts { @@ -4163,18 +4173,18 @@ declare namespace ts { * Create the builder to manage semantic diagnostics and cache them */ function createSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; - function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; + function createSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: SemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): SemanticDiagnosticsBuilderProgram; /** * Create the builder that can handle the changes in program and iterate through changed files * to emit the those files and manage semantic diagnostics cache as well */ function createEmitAndSemanticDiagnosticsBuilderProgram(newProgram: Program, host: BuilderProgramHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; - function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; + function createEmitAndSemanticDiagnosticsBuilderProgram(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: EmitAndSemanticDiagnosticsBuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): EmitAndSemanticDiagnosticsBuilderProgram; /** * Creates a builder thats just abstraction over program and can be used with watch */ function createAbstractBuilder(newProgram: Program, host: BuilderProgramHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; - function createAbstractBuilder(rootNames: ReadonlyArray, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; + function createAbstractBuilder(rootNames: ReadonlyArray | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray): BuilderProgram; } declare namespace ts { type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void; @@ -4558,6 +4568,11 @@ declare namespace ts { getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[]; getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion | undefined; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; + /** + * This will return a defined result if the position is after the `>` of the opening tag, or somewhere in the text, of a JSXElement with no closing tag. + * Editors should call this after `>` is typed. + */ + getJsxClosingTagAtPosition(fileName: string, position: number): JsxClosingTagInfo | undefined; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan | undefined; toLineColumnOffset?(fileName: string, position: number): LineAndCharacter; getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray; @@ -4574,11 +4589,14 @@ declare namespace ts { getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined): ApplicableRefactorInfo[]; getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined): RefactorEditInfo | undefined; organizeImports(scope: OrganizeImportsScope, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; - getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings): ReadonlyArray; + getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): ReadonlyArray; getEmitOutput(fileName: string, emitOnlyDtsFiles?: boolean): EmitOutput; getProgram(): Program | undefined; dispose(): void; } + interface JsxClosingTagInfo { + readonly newText: string; + } interface CombinedCodeFixScope { type: "file"; fileName: string; diff --git a/tests/baselines/reference/chainedPrototypeAssignment.symbols b/tests/baselines/reference/chainedPrototypeAssignment.symbols index f4a8c01b6bf..800915e5316 100644 --- a/tests/baselines/reference/chainedPrototypeAssignment.symbols +++ b/tests/baselines/reference/chainedPrototypeAssignment.symbols @@ -62,12 +62,12 @@ exports.B = B >B : Symbol(B, Decl(mod.js, 4, 3), Decl(mod.js, 9, 13)) A.prototype = B.prototype = { ->A.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>A.prototype : Symbol(A.prototype, Decl(mod.js, 8, 13)) >A : Symbol(A, Decl(mod.js, 1, 3), Decl(mod.js, 8, 13)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) ->B.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(A.prototype, Decl(mod.js, 8, 13)) +>B.prototype : Symbol(B.prototype, Decl(mod.js, 9, 13)) >B : Symbol(B, Decl(mod.js, 4, 3), Decl(mod.js, 9, 13)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(B.prototype, Decl(mod.js, 9, 13)) /** @param {number} n */ m(n) { diff --git a/tests/baselines/reference/chainedPrototypeAssignment.types b/tests/baselines/reference/chainedPrototypeAssignment.types index e49e1a89980..a893ae63022 100644 --- a/tests/baselines/reference/chainedPrototypeAssignment.types +++ b/tests/baselines/reference/chainedPrototypeAssignment.types @@ -82,13 +82,13 @@ exports.B = B A.prototype = B.prototype = { >A.prototype = B.prototype = { /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; } ->A.prototype : any +>A.prototype : { [x: string]: any; m(n: number): number; } >A : typeof A ->prototype : any +>prototype : { [x: string]: any; m(n: number): number; } >B.prototype = { /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; } ->B.prototype : any +>B.prototype : { [x: string]: any; m(n: number): number; } >B : typeof B ->prototype : any +>prototype : { [x: string]: any; m(n: number): number; } >{ /** @param {number} n */ m(n) { return n + 1 }} : { [x: string]: any; m(n: number): number; } /** @param {number} n */ diff --git a/tests/baselines/reference/destructuringTempOccursAfterPrologue.js b/tests/baselines/reference/destructuringTempOccursAfterPrologue.js new file mode 100644 index 00000000000..a7390708560 --- /dev/null +++ b/tests/baselines/reference/destructuringTempOccursAfterPrologue.js @@ -0,0 +1,12 @@ +//// [destructuringTempOccursAfterPrologue.ts] +function test(p: any) { + 'use strict'; + p = { prop: p } = p; +} + +//// [destructuringTempOccursAfterPrologue.js] +function test(p) { + 'use strict'; + var _a; + p = (_a = p, p = _a.prop, _a); +} diff --git a/tests/baselines/reference/destructuringTempOccursAfterPrologue.symbols b/tests/baselines/reference/destructuringTempOccursAfterPrologue.symbols new file mode 100644 index 00000000000..0e68259e6cf --- /dev/null +++ b/tests/baselines/reference/destructuringTempOccursAfterPrologue.symbols @@ -0,0 +1,12 @@ +=== tests/cases/compiler/destructuringTempOccursAfterPrologue.ts === +function test(p: any) { +>test : Symbol(test, Decl(destructuringTempOccursAfterPrologue.ts, 0, 0)) +>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14)) + + 'use strict'; + p = { prop: p } = p; +>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14)) +>prop : Symbol(prop, Decl(destructuringTempOccursAfterPrologue.ts, 2, 9)) +>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14)) +>p : Symbol(p, Decl(destructuringTempOccursAfterPrologue.ts, 0, 14)) +} diff --git a/tests/baselines/reference/destructuringTempOccursAfterPrologue.types b/tests/baselines/reference/destructuringTempOccursAfterPrologue.types new file mode 100644 index 00000000000..8a62e25b685 --- /dev/null +++ b/tests/baselines/reference/destructuringTempOccursAfterPrologue.types @@ -0,0 +1,17 @@ +=== tests/cases/compiler/destructuringTempOccursAfterPrologue.ts === +function test(p: any) { +>test : (p: any) => void +>p : any + + 'use strict'; +>'use strict' : "use strict" + + p = { prop: p } = p; +>p = { prop: p } = p : any +>p : any +>{ prop: p } = p : any +>{ prop: p } : { prop: any; } +>prop : any +>p : any +>p : any +} diff --git a/tests/baselines/reference/dynamicNames.symbols b/tests/baselines/reference/dynamicNames.symbols index fac6046d3c2..cfed2817d1d 100644 --- a/tests/baselines/reference/dynamicNames.symbols +++ b/tests/baselines/reference/dynamicNames.symbols @@ -7,7 +7,7 @@ export const c1 = 1; export const s0 = Symbol(); >s0 : Symbol(s0, Decl(module.ts, 2, 12)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) export interface T0 { >T0 : Symbol(T0, Decl(module.ts, 2, 27)) diff --git a/tests/baselines/reference/dynamicNamesErrors.symbols b/tests/baselines/reference/dynamicNamesErrors.symbols index 3b9808dc01b..de0d98df453 100644 --- a/tests/baselines/reference/dynamicNamesErrors.symbols +++ b/tests/baselines/reference/dynamicNamesErrors.symbols @@ -62,19 +62,19 @@ t2 = t1; const x = Symbol(); >x : Symbol(x, Decl(dynamicNamesErrors.ts, 26, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) const y = Symbol(); >y : Symbol(y, Decl(dynamicNamesErrors.ts, 27, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) const z = Symbol(); >z : Symbol(z, Decl(dynamicNamesErrors.ts, 28, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) const w = Symbol(); >w : Symbol(w, Decl(dynamicNamesErrors.ts, 29, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) export interface InterfaceMemberVisibility { >InterfaceMemberVisibility : Symbol(InterfaceMemberVisibility, Decl(dynamicNamesErrors.ts, 29, 19)) diff --git a/tests/baselines/reference/exportNestedNamespaces.symbols b/tests/baselines/reference/exportNestedNamespaces.symbols index fbd22e0dea3..e5fc5db16d9 100644 --- a/tests/baselines/reference/exportNestedNamespaces.symbols +++ b/tests/baselines/reference/exportNestedNamespaces.symbols @@ -1,18 +1,18 @@ === tests/cases/conformance/salsa/mod.js === exports.n = {}; ->exports.n : Symbol(n, Decl(mod.js, 0, 0)) ->exports : Symbol(n, Decl(mod.js, 0, 0)) ->n : Symbol(n, Decl(mod.js, 0, 0)) +>exports.n : Symbol(n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 8)) +>exports : Symbol(n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 8)) +>n : Symbol(n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 8)) exports.n.K = function () { ->exports.n.K : Symbol(K, Decl(mod.js, 0, 15)) ->exports.n : Symbol(K, Decl(mod.js, 0, 15)) +>exports.n.K : Symbol(n.K, Decl(mod.js, 0, 15)) +>exports.n : Symbol(n.K, Decl(mod.js, 0, 15)) >exports : Symbol("tests/cases/conformance/salsa/mod", Decl(mod.js, 0, 0)) ->n : Symbol(n, Decl(mod.js, 0, 0)) ->K : Symbol(K, Decl(mod.js, 0, 15)) +>n : Symbol(n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 8)) +>K : Symbol(n.K, Decl(mod.js, 0, 15)) this.x = 10; ->this : Symbol(__object, Decl(mod.js, 0, 11), Decl(mod.js, 1, 8)) +>this : Symbol(__object, Decl(mod.js, 0, 11)) >x : Symbol(K.x, Decl(mod.js, 1, 27)) } exports.Classic = class { @@ -34,11 +34,11 @@ import * as s from './mod' var k = new s.n.K() >k : Symbol(k, Decl(use.js, 2, 3)) ->s.n.K : Symbol(K, Decl(mod.js, 0, 15)) ->s.n : Symbol(s.n, Decl(mod.js, 0, 0)) +>s.n.K : Symbol(s.n.K, Decl(mod.js, 0, 15)) +>s.n : Symbol(s.n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 8)) >s : Symbol(s, Decl(use.js, 0, 6)) ->n : Symbol(s.n, Decl(mod.js, 0, 0)) ->K : Symbol(K, Decl(mod.js, 0, 15)) +>n : Symbol(s.n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 8)) +>K : Symbol(s.n.K, Decl(mod.js, 0, 15)) k.x >k.x : Symbol(K.x, Decl(mod.js, 1, 27)) diff --git a/tests/baselines/reference/exportNestedNamespaces.types b/tests/baselines/reference/exportNestedNamespaces.types index a887f0697a8..b6b701bc05f 100644 --- a/tests/baselines/reference/exportNestedNamespaces.types +++ b/tests/baselines/reference/exportNestedNamespaces.types @@ -1,24 +1,24 @@ === tests/cases/conformance/salsa/mod.js === exports.n = {}; ->exports.n = {} : typeof __object ->exports.n : typeof __object +>exports.n = {} : { [x: string]: any; K: typeof K; } +>exports.n : { [x: string]: any; K: typeof K; } >exports : typeof import("tests/cases/conformance/salsa/mod") ->n : typeof __object ->{} : typeof __object +>n : { [x: string]: any; K: typeof K; } +>{} : { [x: string]: any; K: typeof K; } exports.n.K = function () { >exports.n.K = function () { this.x = 10;} : typeof K >exports.n.K : typeof K ->exports.n : typeof __object +>exports.n : { [x: string]: any; K: typeof K; } >exports : typeof import("tests/cases/conformance/salsa/mod") ->n : typeof __object +>n : { [x: string]: any; K: typeof K; } >K : typeof K >function () { this.x = 10;} : typeof K this.x = 10; >this.x = 10 : 10 >this.x : any ->this : typeof __object +>this : { [x: string]: any; K: typeof K; } >x : any >10 : 10 } @@ -47,9 +47,9 @@ var k = new s.n.K() >k : K >new s.n.K() : K >s.n.K : typeof K ->s.n : typeof __object +>s.n : { [x: string]: any; K: typeof K; } >s : typeof s ->n : typeof __object +>n : { [x: string]: any; K: typeof K; } >K : typeof K k.x diff --git a/tests/baselines/reference/importNotElidedWhenNotFound.errors.txt b/tests/baselines/reference/importNotElidedWhenNotFound.errors.txt new file mode 100644 index 00000000000..51e1fe9b44d --- /dev/null +++ b/tests/baselines/reference/importNotElidedWhenNotFound.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/importNotElidedWhenNotFound.ts(1,15): error TS2307: Cannot find module 'file'. +tests/cases/compiler/importNotElidedWhenNotFound.ts(2,15): error TS2307: Cannot find module 'other_file'. + + +==== tests/cases/compiler/importNotElidedWhenNotFound.ts (2 errors) ==== + import X from 'file'; + ~~~~~~ +!!! error TS2307: Cannot find module 'file'. + import Z from 'other_file'; + ~~~~~~~~~~~~ +!!! error TS2307: Cannot find module 'other_file'. + + class Y extends Z { + constructor() { + super(X); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/importNotElidedWhenNotFound.js b/tests/baselines/reference/importNotElidedWhenNotFound.js new file mode 100644 index 00000000000..303e5df8f22 --- /dev/null +++ b/tests/baselines/reference/importNotElidedWhenNotFound.js @@ -0,0 +1,32 @@ +//// [importNotElidedWhenNotFound.ts] +import X from 'file'; +import Z from 'other_file'; + +class Y extends Z { + constructor() { + super(X); + } +} + +//// [importNotElidedWhenNotFound.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var file_1 = require("file"); +var other_file_1 = require("other_file"); +var Y = /** @class */ (function (_super) { + __extends(Y, _super); + function Y() { + return _super.call(this, file_1["default"]) || this; + } + return Y; +}(other_file_1["default"])); diff --git a/tests/baselines/reference/importNotElidedWhenNotFound.symbols b/tests/baselines/reference/importNotElidedWhenNotFound.symbols new file mode 100644 index 00000000000..37558d6be3d --- /dev/null +++ b/tests/baselines/reference/importNotElidedWhenNotFound.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/importNotElidedWhenNotFound.ts === +import X from 'file'; +>X : Symbol(X, Decl(importNotElidedWhenNotFound.ts, 0, 6)) + +import Z from 'other_file'; +>Z : Symbol(Z, Decl(importNotElidedWhenNotFound.ts, 1, 6)) + +class Y extends Z { +>Y : Symbol(Y, Decl(importNotElidedWhenNotFound.ts, 1, 27)) +>Z : Symbol(Z, Decl(importNotElidedWhenNotFound.ts, 1, 6)) + + constructor() { + super(X); +>X : Symbol(X, Decl(importNotElidedWhenNotFound.ts, 0, 6)) + } +} diff --git a/tests/baselines/reference/importNotElidedWhenNotFound.types b/tests/baselines/reference/importNotElidedWhenNotFound.types new file mode 100644 index 00000000000..02304b6e2d2 --- /dev/null +++ b/tests/baselines/reference/importNotElidedWhenNotFound.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/importNotElidedWhenNotFound.ts === +import X from 'file'; +>X : any + +import Z from 'other_file'; +>Z : any + +class Y extends Z { +>Y : Y +>Z : any + + constructor() { + super(X); +>super(X) : void +>super : any +>X : any + } +} diff --git a/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols b/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols index 5716e73a5fe..1c82d05c019 100644 --- a/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols +++ b/tests/baselines/reference/inferringClassStaticMembersFromAssignments.symbols @@ -81,11 +81,11 @@ var n = a.C1.staticProp; var n = a.C2.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) ->a.C2.staticProp : Symbol(C2.staticProp, Decl(a.js, 6, 26)) +>a.C2.staticProp : Symbol(a.C2.staticProp, Decl(a.js, 6, 26)) >a.C2 : Symbol(a.C2, Decl(a.js, 6, 10)) >a : Symbol(a, Decl(b.ts, 0, 6)) >C2 : Symbol(a.C2, Decl(a.js, 6, 10)) ->staticProp : Symbol(C2.staticProp, Decl(a.js, 6, 26)) +>staticProp : Symbol(a.C2.staticProp, Decl(a.js, 6, 26)) var n = a.F1.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) @@ -97,11 +97,11 @@ var n = a.F1.staticProp; var n = a.F2.staticProp; >n : Symbol(n, Decl(b.ts, 1, 3), Decl(b.ts, 3, 3), Decl(b.ts, 4, 3), Decl(b.ts, 5, 3), Decl(b.ts, 6, 3) ... and 4 more) ->a.F2.staticProp : Symbol(F2.staticProp, Decl(a.js, 9, 32)) +>a.F2.staticProp : Symbol(a.F2.staticProp, Decl(a.js, 9, 32)) >a.F2 : Symbol(a.F2, Decl(a.js, 9, 10)) >a : Symbol(a, Decl(b.ts, 0, 6)) >F2 : Symbol(a.F2, Decl(a.js, 9, 10)) ->staticProp : Symbol(F2.staticProp, Decl(a.js, 9, 32)) +>staticProp : Symbol(a.F2.staticProp, Decl(a.js, 9, 32)) var n = C3.staticProp; diff --git a/tests/baselines/reference/jsContainerMergeJsContainer.symbols b/tests/baselines/reference/jsContainerMergeJsContainer.symbols index 1f4728d50de..7063bdca204 100644 --- a/tests/baselines/reference/jsContainerMergeJsContainer.symbols +++ b/tests/baselines/reference/jsContainerMergeJsContainer.symbols @@ -4,15 +4,15 @@ const a = {}; >a : Symbol(a, Decl(a.js, 1, 5), Decl(a.js, 1, 13), Decl(b.js, 0, 0)) a.d = function() {}; ->a.d : Symbol(d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) +>a.d : Symbol(a.d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) >a : Symbol(a, Decl(a.js, 1, 5), Decl(a.js, 1, 13), Decl(b.js, 0, 0)) ->d : Symbol(d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) +>d : Symbol(a.d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) === tests/cases/conformance/salsa/b.js === a.d.prototype = {}; ->a.d.prototype : Symbol(d.prototype, Decl(b.js, 0, 0)) ->a.d : Symbol(d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) +>a.d.prototype : Symbol(a.d.prototype, Decl(b.js, 0, 0)) +>a.d : Symbol(a.d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) >a : Symbol(a, Decl(a.js, 1, 5), Decl(a.js, 1, 13), Decl(b.js, 0, 0)) ->d : Symbol(d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) ->prototype : Symbol(d.prototype, Decl(b.js, 0, 0)) +>d : Symbol(a.d, Decl(a.js, 1, 13), Decl(b.js, 0, 2)) +>prototype : Symbol(a.d.prototype, Decl(b.js, 0, 0)) diff --git a/tests/baselines/reference/jsContainerMergeJsContainer.types b/tests/baselines/reference/jsContainerMergeJsContainer.types index fa5c74f5b05..6d25fb4608a 100644 --- a/tests/baselines/reference/jsContainerMergeJsContainer.types +++ b/tests/baselines/reference/jsContainerMergeJsContainer.types @@ -1,23 +1,23 @@ === tests/cases/conformance/salsa/a.js === // #24131 const a = {}; ->a : { [x: string]: any; d: typeof d; } ->{} : { [x: string]: any; d: typeof d; } +>a : { [x: string]: any; d: { (): void; prototype: { [x: string]: any; }; }; } +>{} : { [x: string]: any; d: { (): void; prototype: { [x: string]: any; }; }; } a.d = function() {}; ->a.d = function() {} : typeof d ->a.d : typeof d ->a : { [x: string]: any; d: typeof d; } ->d : typeof d ->function() {} : typeof d +>a.d = function() {} : { (): void; prototype: { [x: string]: any; }; } +>a.d : { (): void; prototype: { [x: string]: any; }; } +>a : { [x: string]: any; d: { (): void; prototype: { [x: string]: any; }; }; } +>d : { (): void; prototype: { [x: string]: any; }; } +>function() {} : { (): void; prototype: { [x: string]: any; }; } === tests/cases/conformance/salsa/b.js === a.d.prototype = {}; >a.d.prototype = {} : { [x: string]: any; } >a.d.prototype : { [x: string]: any; } ->a.d : typeof d ->a : { [x: string]: any; d: typeof d; } ->d : typeof d +>a.d : { (): void; prototype: { [x: string]: any; }; } +>a : { [x: string]: any; d: { (): void; prototype: { [x: string]: any; }; }; } +>d : { (): void; prototype: { [x: string]: any; }; } >prototype : { [x: string]: any; } >{} : { [x: string]: any; } diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration.errors.txt b/tests/baselines/reference/jsContainerMergeTsDeclaration.errors.txt deleted file mode 100644 index eb9ea6e9f53..00000000000 --- a/tests/baselines/reference/jsContainerMergeTsDeclaration.errors.txt +++ /dev/null @@ -1,22 +0,0 @@ -error TS5055: Cannot write file 'tests/cases/conformance/salsa/a.js' because it would overwrite input file. - Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. -tests/cases/conformance/salsa/a.js(1,10): error TS2300: Duplicate identifier 'x'. -tests/cases/conformance/salsa/b.ts(1,5): error TS2300: Duplicate identifier 'x'. - - -!!! error TS5055: Cannot write file 'tests/cases/conformance/salsa/a.js' because it would overwrite input file. -!!! error TS5055: Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig. -==== tests/cases/conformance/salsa/a.js (1 errors) ==== - var /*1*/x = function foo() { - ~ -!!! error TS2300: Duplicate identifier 'x'. - } - x.a = function bar() { - } -==== tests/cases/conformance/salsa/b.ts (1 errors) ==== - var x = function () { - ~ -!!! error TS2300: Duplicate identifier 'x'. - return 1; - }(); - \ No newline at end of file diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration.js b/tests/baselines/reference/jsContainerMergeTsDeclaration.js deleted file mode 100644 index 9e81ff2e536..00000000000 --- a/tests/baselines/reference/jsContainerMergeTsDeclaration.js +++ /dev/null @@ -1,17 +0,0 @@ -//// [tests/cases/conformance/salsa/jsContainerMergeTsDeclaration.ts] //// - -//// [a.js] -var /*1*/x = function foo() { -} -x.a = function bar() { -} -//// [b.ts] -var x = function () { - return 1; -}(); - - -//// [b.js] -var x = function () { - return 1; -}(); diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration.symbols b/tests/baselines/reference/jsContainerMergeTsDeclaration.symbols index 080cf745cba..81c51d9ed89 100644 --- a/tests/baselines/reference/jsContainerMergeTsDeclaration.symbols +++ b/tests/baselines/reference/jsContainerMergeTsDeclaration.symbols @@ -4,9 +4,9 @@ var /*1*/x = function foo() { >foo : Symbol(foo, Decl(a.js, 0, 12)) } x.a = function bar() { ->x.a : Symbol(foo.a, Decl(a.js, 1, 1)) +>x.a : Symbol(x.a, Decl(a.js, 1, 1)) >x : Symbol(x, Decl(a.js, 0, 3), Decl(a.js, 1, 1), Decl(b.ts, 0, 3)) ->a : Symbol(foo.a, Decl(a.js, 1, 1)) +>a : Symbol(x.a, Decl(a.js, 1, 1)) >bar : Symbol(bar, Decl(a.js, 2, 5)) } === tests/cases/conformance/salsa/b.ts === diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration2.errors.txt b/tests/baselines/reference/jsContainerMergeTsDeclaration2.errors.txt new file mode 100644 index 00000000000..7078de12816 --- /dev/null +++ b/tests/baselines/reference/jsContainerMergeTsDeclaration2.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/salsa/b.js(2,1): error TS2322: Type '2' is not assignable to type '() => void'. + + +==== tests/cases/conformance/salsa/a.d.ts (0 errors) ==== + declare namespace C { + function bar(): void + } +==== tests/cases/conformance/salsa/b.js (1 errors) ==== + C.prototype = {}; + C.bar = 2; + ~~~~~ +!!! error TS2322: Type '2' is not assignable to type '() => void'. + \ No newline at end of file diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration2.symbols b/tests/baselines/reference/jsContainerMergeTsDeclaration2.symbols new file mode 100644 index 00000000000..4f5f86e8e67 --- /dev/null +++ b/tests/baselines/reference/jsContainerMergeTsDeclaration2.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/salsa/a.d.ts === +declare namespace C { +>C : Symbol(C, Decl(a.d.ts, 0, 0), Decl(b.js, 0, 0)) + + function bar(): void +>bar : Symbol(bar, Decl(a.d.ts, 0, 21), Decl(b.js, 0, 17)) +} +=== tests/cases/conformance/salsa/b.js === +C.prototype = {}; +>C.prototype : Symbol(C.prototype, Decl(b.js, 0, 0)) +>C : Symbol(C, Decl(a.d.ts, 0, 0), Decl(b.js, 0, 0)) +>prototype : Symbol(C.prototype, Decl(b.js, 0, 0)) + +C.bar = 2; +>C.bar : Symbol(C.bar, Decl(a.d.ts, 0, 21), Decl(b.js, 0, 17)) +>C : Symbol(C, Decl(a.d.ts, 0, 0), Decl(b.js, 0, 0)) +>bar : Symbol(C.bar, Decl(a.d.ts, 0, 21), Decl(b.js, 0, 17)) + diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration2.types b/tests/baselines/reference/jsContainerMergeTsDeclaration2.types new file mode 100644 index 00000000000..aec24cb7f5e --- /dev/null +++ b/tests/baselines/reference/jsContainerMergeTsDeclaration2.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/salsa/a.d.ts === +declare namespace C { +>C : typeof C + + function bar(): void +>bar : () => void +} +=== tests/cases/conformance/salsa/b.js === +C.prototype = {}; +>C.prototype = {} : { [x: string]: any; } +>C.prototype : { [x: string]: any; } +>C : typeof C +>prototype : { [x: string]: any; } +>{} : { [x: string]: any; } + +C.bar = 2; +>C.bar = 2 : 2 +>C.bar : () => void +>C : typeof C +>bar : () => void +>2 : 2 + diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration3.symbols b/tests/baselines/reference/jsContainerMergeTsDeclaration3.symbols new file mode 100644 index 00000000000..df0c7e06fd2 --- /dev/null +++ b/tests/baselines/reference/jsContainerMergeTsDeclaration3.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/salsa/a.d.ts === +declare class A {} +>A : Symbol(A, Decl(a.d.ts, 0, 0), Decl(b.js, 0, 5), Decl(b.js, 0, 14)) + +=== tests/cases/conformance/salsa/b.js === +const A = { }; +>A : Symbol(A, Decl(a.d.ts, 0, 0), Decl(b.js, 0, 5), Decl(b.js, 0, 14)) + +A.d = { }; +>A.d : Symbol(A.d, Decl(b.js, 0, 14)) +>A : Symbol(A, Decl(a.d.ts, 0, 0), Decl(b.js, 0, 5), Decl(b.js, 0, 14)) +>d : Symbol(A.d, Decl(b.js, 0, 14)) + diff --git a/tests/baselines/reference/jsContainerMergeTsDeclaration3.types b/tests/baselines/reference/jsContainerMergeTsDeclaration3.types new file mode 100644 index 00000000000..1a29cab2538 --- /dev/null +++ b/tests/baselines/reference/jsContainerMergeTsDeclaration3.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/salsa/a.d.ts === +declare class A {} +>A : A + +=== tests/cases/conformance/salsa/b.js === +const A = { }; +>A : typeof A +>{ } : { [x: string]: any; prototype: A; d: { [x: string]: any; }; } + +A.d = { }; +>A.d = { } : { [x: string]: any; } +>A.d : { [x: string]: any; } +>A : typeof A +>d : { [x: string]: any; } +>{ } : { [x: string]: any; } + diff --git a/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols b/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols index 57e05c273b4..231d9fa60b2 100644 --- a/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols +++ b/tests/baselines/reference/jsObjectsMarkedAsOpenEnded.symbols @@ -3,9 +3,9 @@ var variable = {}; >variable : Symbol(variable, Decl(a.js, 0, 3)) variable.a = 0; ->variable.a : Symbol(a, Decl(a.js, 0, 18)) +>variable.a : Symbol(variable.a, Decl(a.js, 0, 18)) >variable : Symbol(variable, Decl(a.js, 0, 3)) ->a : Symbol(a, Decl(a.js, 0, 18)) +>a : Symbol(variable.a, Decl(a.js, 0, 18)) class C { >C : Symbol(C, Decl(a.js, 1, 15)) @@ -51,9 +51,9 @@ function getObj() { === tests/cases/conformance/salsa/b.ts === variable.a = 1; ->variable.a : Symbol(a, Decl(a.js, 0, 18)) +>variable.a : Symbol(variable.a, Decl(a.js, 0, 18)) >variable : Symbol(variable, Decl(a.js, 0, 3)) ->a : Symbol(a, Decl(a.js, 0, 18)) +>a : Symbol(variable.a, Decl(a.js, 0, 18)) (new C()).member.a = 1; >(new C()).member : Symbol(C.member, Decl(a.js, 5, 19)) diff --git a/tests/baselines/reference/jsdocResolveNameFailureInTypedef.errors.txt b/tests/baselines/reference/jsdocResolveNameFailureInTypedef.errors.txt new file mode 100644 index 00000000000..220be597bdb --- /dev/null +++ b/tests/baselines/reference/jsdocResolveNameFailureInTypedef.errors.txt @@ -0,0 +1,15 @@ +/a.js(7,14): error TS2304: Cannot find name 'CantResolveThis'. + + +==== /a.js (1 errors) ==== + /** + * @param {Ty} x + */ + function f(x) {} + + /** + * @typedef {CantResolveThis} Ty + ~~~~~~~~~~~~~~~ +!!! error TS2304: Cannot find name 'CantResolveThis'. + */ + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocResolveNameFailureInTypedef.symbols b/tests/baselines/reference/jsdocResolveNameFailureInTypedef.symbols new file mode 100644 index 00000000000..36d8565cf01 --- /dev/null +++ b/tests/baselines/reference/jsdocResolveNameFailureInTypedef.symbols @@ -0,0 +1,12 @@ +=== /a.js === +/** + * @param {Ty} x + */ +function f(x) {} +>f : Symbol(f, Decl(a.js, 0, 0)) +>x : Symbol(x, Decl(a.js, 3, 11)) + +/** + * @typedef {CantResolveThis} Ty + */ + diff --git a/tests/baselines/reference/jsdocResolveNameFailureInTypedef.types b/tests/baselines/reference/jsdocResolveNameFailureInTypedef.types new file mode 100644 index 00000000000..4d88a942fe9 --- /dev/null +++ b/tests/baselines/reference/jsdocResolveNameFailureInTypedef.types @@ -0,0 +1,12 @@ +=== /a.js === +/** + * @param {Ty} x + */ +function f(x) {} +>f : (x: any) => void +>x : any + +/** + * @typedef {CantResolveThis} Ty + */ + diff --git a/tests/baselines/reference/jsdocTemplateClass.errors.txt b/tests/baselines/reference/jsdocTemplateClass.errors.txt index 402992c34bd..372fee6fd5a 100644 --- a/tests/baselines/reference/jsdocTemplateClass.errors.txt +++ b/tests/baselines/reference/jsdocTemplateClass.errors.txt @@ -3,7 +3,7 @@ tests/cases/conformance/jsdoc/templateTagOnClasses.js(25,1): error TS2322: Type ==== tests/cases/conformance/jsdoc/templateTagOnClasses.js (1 errors) ==== /** - * @template {T} + * @template T * @typedef {(t: T) => T} Id */ /** @template T */ diff --git a/tests/baselines/reference/jsdocTemplateClass.symbols b/tests/baselines/reference/jsdocTemplateClass.symbols index b82cd8038e5..a2da2f051cd 100644 --- a/tests/baselines/reference/jsdocTemplateClass.symbols +++ b/tests/baselines/reference/jsdocTemplateClass.symbols @@ -1,6 +1,6 @@ === tests/cases/conformance/jsdoc/templateTagOnClasses.js === /** - * @template {T} + * @template T * @typedef {(t: T) => T} Id */ /** @template T */ diff --git a/tests/baselines/reference/jsdocTemplateClass.types b/tests/baselines/reference/jsdocTemplateClass.types index 9c028a96ff1..40b73bc7002 100644 --- a/tests/baselines/reference/jsdocTemplateClass.types +++ b/tests/baselines/reference/jsdocTemplateClass.types @@ -1,6 +1,6 @@ === tests/cases/conformance/jsdoc/templateTagOnClasses.js === /** - * @template {T} + * @template T * @typedef {(t: T) => T} Id */ /** @template T */ diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt b/tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt index 9e735b780a0..1153424c8db 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.errors.txt @@ -3,12 +3,12 @@ tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js(24,1): error ==== tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js (1 errors) ==== /** - * @template {U} + * @template U * @typedef {(u: U) => U} Id */ /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { /** @type {T} */ diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols index 86b2780f1ee..6a8a948cba8 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.symbols @@ -1,11 +1,11 @@ === tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js === /** - * @template {U} + * @template U * @typedef {(u: U) => U} Id */ /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { >Zet : Symbol(Zet, Decl(templateTagOnConstructorFunctions.js, 0, 0)) diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.types b/tests/baselines/reference/jsdocTemplateConstructorFunction.types index 121cf846a0e..4c0237aedeb 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction.types +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.types @@ -1,11 +1,11 @@ === tests/cases/conformance/jsdoc/templateTagOnConstructorFunctions.js === /** - * @template {U} + * @template U * @typedef {(u: U) => U} Id */ /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { >Zet : typeof Zet diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt index cdcc9a056eb..d7222f11ee2 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt @@ -5,7 +5,7 @@ tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(26,15): error ==== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js (2 errors) ==== /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { /** @type {T} */ diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols index 7afb9629b67..703e23c5af8 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols @@ -1,7 +1,7 @@ === tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js === /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { >Zet : Symbol(Zet, Decl(templateTagWithNestedTypeLiteral.js, 0, 0)) diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.types b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types index 14407a5a0c9..91c820ce094 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.types +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types @@ -1,7 +1,7 @@ === tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js === /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { >Zet : typeof Zet diff --git a/tests/baselines/reference/jsdocTemplateTag3.errors.txt b/tests/baselines/reference/jsdocTemplateTag3.errors.txt new file mode 100644 index 00000000000..a85024e1499 --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag3.errors.txt @@ -0,0 +1,47 @@ +tests/cases/conformance/jsdoc/a.js(14,29): error TS2339: Property 'a' does not exist on type 'U'. +tests/cases/conformance/jsdoc/a.js(14,35): error TS2339: Property 'b' does not exist on type 'U'. +tests/cases/conformance/jsdoc/a.js(21,3): error TS2345: Argument of type '{ a: number; }' is not assignable to parameter of type '{ a: number; b: string; }'. + Property 'b' is missing in type '{ a: number; }'. +tests/cases/conformance/jsdoc/a.js(25,2): error TS1069: Unexpected token. A type parameter name was expected without curly braces. + + +==== tests/cases/conformance/jsdoc/a.js (4 errors) ==== + /** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @param {T} t + * @param {U} u + * @param {V} v + * @param {W} w + * @param {X} x + * @return {W | X} + */ + function f(t, u, v, w, x) { + if(t.a + t.b.length > u.a - u.b.length && v.c) { + ~ +!!! error TS2339: Property 'a' does not exist on type 'U'. + ~ +!!! error TS2339: Property 'b' does not exist on type 'U'. + return w; + } + return x; + } + + f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope'); + f({ a: 12 }, undefined, undefined, 101, 'nope'); + ~~~~~~~~~~ +!!! error TS2345: Argument of type '{ a: number; }' is not assignable to parameter of type '{ a: number; b: string; }'. +!!! error TS2345: Property 'b' is missing in type '{ a: number; }'. + + /** + * @template {NoLongerAllowed} + * @template T preceding line's syntax is no longer allowed + ~ +!!! error TS1069: Unexpected token. A type parameter name was expected without curly braces. + * @param {T} x + */ + function g(x) { } + + \ No newline at end of file diff --git a/tests/baselines/reference/jsdocTemplateTag3.symbols b/tests/baselines/reference/jsdocTemplateTag3.symbols new file mode 100644 index 00000000000..ecd08d784cc --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag3.symbols @@ -0,0 +1,70 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @param {T} t + * @param {U} u + * @param {V} v + * @param {W} w + * @param {X} x + * @return {W | X} + */ +function f(t, u, v, w, x) { +>f : Symbol(f, Decl(a.js, 0, 0)) +>t : Symbol(t, Decl(a.js, 12, 11)) +>u : Symbol(u, Decl(a.js, 12, 13)) +>v : Symbol(v, Decl(a.js, 12, 16)) +>w : Symbol(w, Decl(a.js, 12, 19)) +>x : Symbol(x, Decl(a.js, 12, 22)) + + if(t.a + t.b.length > u.a - u.b.length && v.c) { +>t.a : Symbol(a, Decl(a.js, 1, 15)) +>t : Symbol(t, Decl(a.js, 12, 11)) +>a : Symbol(a, Decl(a.js, 1, 15)) +>t.b.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>t.b : Symbol(b, Decl(a.js, 1, 26)) +>t : Symbol(t, Decl(a.js, 12, 11)) +>b : Symbol(b, Decl(a.js, 1, 26)) +>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --)) +>u : Symbol(u, Decl(a.js, 12, 13)) +>u : Symbol(u, Decl(a.js, 12, 13)) +>v.c : Symbol(c, Decl(a.js, 2, 15)) +>v : Symbol(v, Decl(a.js, 12, 16)) +>c : Symbol(c, Decl(a.js, 2, 15)) + + return w; +>w : Symbol(w, Decl(a.js, 12, 19)) + } + return x; +>x : Symbol(x, Decl(a.js, 12, 22)) +} + +f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope'); +>f : Symbol(f, Decl(a.js, 0, 0)) +>a : Symbol(a, Decl(a.js, 19, 3)) +>b : Symbol(b, Decl(a.js, 19, 10)) +>c : Symbol(c, Decl(a.js, 19, 19)) +>undefined : Symbol(undefined) +>c : Symbol(c, Decl(a.js, 19, 43)) +>d : Symbol(d, Decl(a.js, 19, 53)) +>b : Symbol(b, Decl(a.js, 19, 60)) +>undefined : Symbol(undefined) + +f({ a: 12 }, undefined, undefined, 101, 'nope'); +>f : Symbol(f, Decl(a.js, 0, 0)) +>a : Symbol(a, Decl(a.js, 20, 3)) +>undefined : Symbol(undefined) +>undefined : Symbol(undefined) + +/** + * @template {NoLongerAllowed} + * @template T preceding line's syntax is no longer allowed + * @param {T} x + */ +function g(x) { } +>g : Symbol(g, Decl(a.js, 20, 49)) +>x : Symbol(x, Decl(a.js, 27, 11)) + + diff --git a/tests/baselines/reference/jsdocTemplateTag3.types b/tests/baselines/reference/jsdocTemplateTag3.types new file mode 100644 index 00000000000..63e8498d84a --- /dev/null +++ b/tests/baselines/reference/jsdocTemplateTag3.types @@ -0,0 +1,95 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @param {T} t + * @param {U} u + * @param {V} v + * @param {W} w + * @param {X} x + * @return {W | X} + */ +function f(t, u, v, w, x) { +>f : (t: T, u: U, v: V, w: W, x: X) => W | X +>t : T +>u : U +>v : V +>w : W +>x : X + + if(t.a + t.b.length > u.a - u.b.length && v.c) { +>t.a + t.b.length > u.a - u.b.length && v.c : boolean +>t.a + t.b.length > u.a - u.b.length : boolean +>t.a + t.b.length : number +>t.a : number +>t : T +>a : number +>t.b.length : number +>t.b : string +>t : T +>b : string +>length : number +>u.a - u.b.length : number +>u.a : any +>u : U +>a : any +>u.b.length : any +>u.b : any +>u : U +>b : any +>length : any +>v.c : boolean +>v : V +>c : boolean + + return w; +>w : W + } + return x; +>x : X +} + +f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope'); +>f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope') : string | number +>f : (t: T, u: U, v: V, w: W, x: X) => W | X +>{ a: 12, b: 'hi', c: null } : { a: number; b: string; c: null; } +>a : number +>12 : 12 +>b : string +>'hi' : "hi" +>c : null +>null : null +>undefined : undefined +>{ c: false, d: 12, b: undefined } : { c: false; d: number; b: undefined; } +>c : false +>false : false +>d : number +>12 : 12 +>b : undefined +>undefined : undefined +>101 : 101 +>'nope' : "nope" + +f({ a: 12 }, undefined, undefined, 101, 'nope'); +>f({ a: 12 }, undefined, undefined, 101, 'nope') : any +>f : (t: T, u: U, v: V, w: W, x: X) => W | X +>{ a: 12 } : { a: number; } +>a : number +>12 : 12 +>undefined : undefined +>undefined : undefined +>101 : 101 +>'nope' : "nope" + +/** + * @template {NoLongerAllowed} + * @template T preceding line's syntax is no longer allowed + * @param {T} x + */ +function g(x) { } +>g : (x: T) => void +>x : T + + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.js b/tests/baselines/reference/keyofAndIndexedAccess.js index c23f10f3e68..3667a30f92c 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.js +++ b/tests/baselines/reference/keyofAndIndexedAccess.js @@ -635,6 +635,20 @@ interface I7 { } type Foo7 = T; declare function f7(type: K): Foo7; + +// Repro from #21770 + +type Dict = { [key in T]: number }; +type DictDict = { [key in V]: Dict }; + +function ff1(dd: DictDict, k1: V, k2: T): number { + return dd[k1][k2]; +} + +function ff2(dd: DictDict, k1: V, k2: T): number { + const d: Dict = dd[k1]; + return d[k2]; +} //// [keyofAndIndexedAccess.js] @@ -1054,6 +1068,13 @@ var Unbounded = /** @class */ (function () { }; return Unbounded; }()); +function ff1(dd, k1, k2) { + return dd[k1][k2]; +} +function ff2(dd, k1, k2) { + var d = dd[k1]; + return d[k2]; +} //// [keyofAndIndexedAccess.d.ts] @@ -1381,3 +1402,11 @@ interface I7 { } declare type Foo7 = T; declare function f7(type: K): Foo7; +declare type Dict = { + [key in T]: number; +}; +declare type DictDict = { + [key in V]: Dict; +}; +declare function ff1(dd: DictDict, k1: V, k2: T): number; +declare function ff2(dd: DictDict, k1: V, k2: T): number; diff --git a/tests/baselines/reference/keyofAndIndexedAccess.symbols b/tests/baselines/reference/keyofAndIndexedAccess.symbols index 5a3d94102d4..c8bb9f14da7 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess.symbols @@ -2258,3 +2258,64 @@ declare function f7(type: K): Foo7; >I7 : Symbol(I7, Decl(keyofAndIndexedAccess.ts, 627, 1)) >K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 635, 20)) +// Repro from #21770 + +type Dict = { [key in T]: number }; +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess.ts, 635, 62)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 639, 10)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 639, 33)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 639, 10)) + +type DictDict = { [key in V]: Dict }; +>DictDict : Symbol(DictDict, Decl(keyofAndIndexedAccess.ts, 639, 53)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 640, 14)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 640, 31)) +>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 640, 55)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 640, 14)) +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess.ts, 635, 62)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 640, 31)) + +function ff1(dd: DictDict, k1: V, k2: T): number { +>ff1 : Symbol(ff1, Decl(keyofAndIndexedAccess.ts, 640, 76)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 642, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 642, 30)) +>dd : Symbol(dd, Decl(keyofAndIndexedAccess.ts, 642, 49)) +>DictDict : Symbol(DictDict, Decl(keyofAndIndexedAccess.ts, 639, 53)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 642, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 642, 30)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess.ts, 642, 68)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 642, 13)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess.ts, 642, 75)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 642, 30)) + + return dd[k1][k2]; +>dd : Symbol(dd, Decl(keyofAndIndexedAccess.ts, 642, 49)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess.ts, 642, 68)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess.ts, 642, 75)) +} + +function ff2(dd: DictDict, k1: V, k2: T): number { +>ff2 : Symbol(ff2, Decl(keyofAndIndexedAccess.ts, 644, 1)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 646, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 646, 30)) +>dd : Symbol(dd, Decl(keyofAndIndexedAccess.ts, 646, 49)) +>DictDict : Symbol(DictDict, Decl(keyofAndIndexedAccess.ts, 639, 53)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 646, 13)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 646, 30)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess.ts, 646, 68)) +>V : Symbol(V, Decl(keyofAndIndexedAccess.ts, 646, 13)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess.ts, 646, 75)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 646, 30)) + + const d: Dict = dd[k1]; +>d : Symbol(d, Decl(keyofAndIndexedAccess.ts, 647, 9)) +>Dict : Symbol(Dict, Decl(keyofAndIndexedAccess.ts, 635, 62)) +>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 646, 30)) +>dd : Symbol(dd, Decl(keyofAndIndexedAccess.ts, 646, 49)) +>k1 : Symbol(k1, Decl(keyofAndIndexedAccess.ts, 646, 68)) + + return d[k2]; +>d : Symbol(d, Decl(keyofAndIndexedAccess.ts, 647, 9)) +>k2 : Symbol(k2, Decl(keyofAndIndexedAccess.ts, 646, 75)) +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess.types b/tests/baselines/reference/keyofAndIndexedAccess.types index a85b34d707b..1a65dbb0389 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.types +++ b/tests/baselines/reference/keyofAndIndexedAccess.types @@ -2614,3 +2614,68 @@ declare function f7(type: K): Foo7; >I7 : I7 >K : K +// Repro from #21770 + +type Dict = { [key in T]: number }; +>Dict : Dict +>T : T +>key : key +>T : T + +type DictDict = { [key in V]: Dict }; +>DictDict : DictDict +>V : V +>T : T +>key : key +>V : V +>Dict : Dict +>T : T + +function ff1(dd: DictDict, k1: V, k2: T): number { +>ff1 : (dd: DictDict, k1: V, k2: T) => number +>V : V +>T : T +>dd : DictDict +>DictDict : DictDict +>V : V +>T : T +>k1 : V +>V : V +>k2 : T +>T : T + + return dd[k1][k2]; +>dd[k1][k2] : DictDict[V][T] +>dd[k1] : DictDict[V] +>dd : DictDict +>k1 : V +>k2 : T +} + +function ff2(dd: DictDict, k1: V, k2: T): number { +>ff2 : (dd: DictDict, k1: V, k2: T) => number +>V : V +>T : T +>dd : DictDict +>DictDict : DictDict +>V : V +>T : T +>k1 : V +>V : V +>k2 : T +>T : T + + const d: Dict = dd[k1]; +>d : Dict +>Dict : Dict +>T : T +>dd[k1] : DictDict[V] +>dd : DictDict +>k1 : V + + return d[k2]; +>d[k2] : Dict[T] +>d : Dict +>k2 : T +} + diff --git a/tests/baselines/reference/moduleExportNestedNamespaces.symbols b/tests/baselines/reference/moduleExportNestedNamespaces.symbols index 2128a6efb60..566221b3a56 100644 --- a/tests/baselines/reference/moduleExportNestedNamespaces.symbols +++ b/tests/baselines/reference/moduleExportNestedNamespaces.symbols @@ -1,13 +1,13 @@ === tests/cases/conformance/salsa/mod.js === module.exports.n = {}; ->module.exports : Symbol(n, Decl(mod.js, 0, 0)) +>module.exports : Symbol(n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 15)) >module : Symbol(module) ->n : Symbol(n, Decl(mod.js, 0, 0)) +>n : Symbol(n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 15)) module.exports.n.K = function C() { ->module.exports.n : Symbol(K, Decl(mod.js, 0, 22)) +>module.exports.n : Symbol(n.K, Decl(mod.js, 0, 22)) >module : Symbol(module) ->K : Symbol(K, Decl(mod.js, 0, 22)) +>K : Symbol(n.K, Decl(mod.js, 0, 22)) >C : Symbol(C, Decl(mod.js, 1, 20)) this.x = 10; @@ -32,11 +32,11 @@ import * as s from './mod' var k = new s.n.K() >k : Symbol(k, Decl(use.js, 2, 3)) ->s.n.K : Symbol(K, Decl(mod.js, 0, 22)) ->s.n : Symbol(s.n, Decl(mod.js, 0, 0)) +>s.n.K : Symbol(s.n.K, Decl(mod.js, 0, 22)) +>s.n : Symbol(s.n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 15)) >s : Symbol(s, Decl(use.js, 0, 6)) ->n : Symbol(s.n, Decl(mod.js, 0, 0)) ->K : Symbol(K, Decl(mod.js, 0, 22)) +>n : Symbol(s.n, Decl(mod.js, 0, 0), Decl(mod.js, 1, 15)) +>K : Symbol(s.n.K, Decl(mod.js, 0, 22)) k.x >k.x : Symbol(C.x, Decl(mod.js, 1, 35)) diff --git a/tests/baselines/reference/moduleExportNestedNamespaces.types b/tests/baselines/reference/moduleExportNestedNamespaces.types index bad23cab949..92dd4f14e69 100644 --- a/tests/baselines/reference/moduleExportNestedNamespaces.types +++ b/tests/baselines/reference/moduleExportNestedNamespaces.types @@ -1,12 +1,12 @@ === tests/cases/conformance/salsa/mod.js === module.exports.n = {}; ->module.exports.n = {} : typeof __object +>module.exports.n = {} : { [x: string]: any; K: typeof C; } >module.exports.n : any >module.exports : any >module : any >exports : any >n : any ->{} : typeof __object +>{} : { [x: string]: any; K: typeof C; } module.exports.n.K = function C() { >module.exports.n.K = function C() { this.x = 10;} : typeof C @@ -54,9 +54,9 @@ var k = new s.n.K() >k : C >new s.n.K() : C >s.n.K : typeof C ->s.n : typeof __object +>s.n : { [x: string]: any; K: typeof C; } >s : typeof s ->n : typeof __object +>n : { [x: string]: any; K: typeof C; } >K : typeof C k.x diff --git a/tests/baselines/reference/nestedPrototypeAssignment.symbols b/tests/baselines/reference/nestedPrototypeAssignment.symbols new file mode 100644 index 00000000000..870baefae11 --- /dev/null +++ b/tests/baselines/reference/nestedPrototypeAssignment.symbols @@ -0,0 +1,16 @@ +=== tests/cases/conformance/salsa/mod.js === +// #24111 -- shouldn't assert +C.prototype = {} +>C.prototype : Symbol(C.prototype, Decl(mod.js, 0, 0), Decl(mod.js, 2, 2)) +>C : Symbol(C, Decl(mod.js, 0, 0), Decl(mod.js, 1, 16)) +>prototype : Symbol(C.prototype, Decl(mod.js, 0, 0), Decl(mod.js, 2, 2)) + +C.prototype.bar.foo = {}; +>C.prototype.bar.foo : Symbol(C.prototype.bar.foo, Decl(mod.js, 1, 16)) +>C.prototype.bar : Symbol(C.prototype.bar, Decl(mod.js, 2, 12)) +>C.prototype : Symbol(C.prototype, Decl(mod.js, 0, 0), Decl(mod.js, 2, 2)) +>C : Symbol(C, Decl(mod.js, 0, 0), Decl(mod.js, 1, 16)) +>prototype : Symbol(C.prototype, Decl(mod.js, 0, 0), Decl(mod.js, 2, 2)) +>bar : Symbol(C.prototype.bar, Decl(mod.js, 2, 12)) +>foo : Symbol(C.prototype.bar.foo, Decl(mod.js, 1, 16)) + diff --git a/tests/baselines/reference/nestedPrototypeAssignment.types b/tests/baselines/reference/nestedPrototypeAssignment.types new file mode 100644 index 00000000000..620ca215f6d --- /dev/null +++ b/tests/baselines/reference/nestedPrototypeAssignment.types @@ -0,0 +1,20 @@ +=== tests/cases/conformance/salsa/mod.js === +// #24111 -- shouldn't assert +C.prototype = {} +>C.prototype = {} : { [x: string]: any; bar: typeof C.prototype.bar; } +>C.prototype : { [x: string]: any; bar: typeof C.prototype.bar; } +>C : typeof C +>prototype : { [x: string]: any; bar: typeof C.prototype.bar; } +>{} : { [x: string]: any; bar: typeof C.prototype.bar; } + +C.prototype.bar.foo = {}; +>C.prototype.bar.foo = {} : { [x: string]: any; } +>C.prototype.bar.foo : { [x: string]: any; } +>C.prototype.bar : typeof C.prototype.bar +>C.prototype : { [x: string]: any; bar: typeof C.prototype.bar; } +>C : typeof C +>prototype : { [x: string]: any; bar: typeof C.prototype.bar; } +>bar : typeof C.prototype.bar +>foo : { [x: string]: any; } +>{} : { [x: string]: any; } + diff --git a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt index ff2291c84d6..edb5049bbbf 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt +++ b/tests/baselines/reference/noUnusedLocals_selfReference.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/noUnusedLocals_selfReference.ts(3,1): error TS6133: 'f' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(5,5): error TS6133: 'g' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference.ts(9,1): error TS6196: 'C' is declared but never used. -tests/cases/compiler/noUnusedLocals_selfReference.ts(12,1): error TS6196: 'E' is declared but never used. -tests/cases/compiler/noUnusedLocals_selfReference.ts(13,1): error TS6196: 'I' is declared but never used. -tests/cases/compiler/noUnusedLocals_selfReference.ts(14,1): error TS6196: 'T' is declared but never used. -tests/cases/compiler/noUnusedLocals_selfReference.ts(15,1): error TS6133: 'N' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(3,10): error TS6133: 'f' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(5,14): error TS6133: 'g' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference.ts(9,7): error TS6196: 'C' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(12,6): error TS6196: 'E' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(13,11): error TS6196: 'I' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(14,6): error TS6196: 'T' is declared but never used. +tests/cases/compiler/noUnusedLocals_selfReference.ts(15,11): error TS6133: 'N' is declared but its value is never read. tests/cases/compiler/noUnusedLocals_selfReference.ts(22,19): error TS6133: 'm' is declared but its value is never read. @@ -12,31 +12,31 @@ tests/cases/compiler/noUnusedLocals_selfReference.ts(22,19): error TS6133: 'm' i export {}; // Make this a module scope, so these are local variables. function f() { - ~~~~~~~~~~ + ~ !!! error TS6133: 'f' is declared but its value is never read. f; function g() { - ~~~~~~~~~~ + ~ !!! error TS6133: 'g' is declared but its value is never read. g; } } class C { - ~~~~~~~ + ~ !!! error TS6196: 'C' is declared but never used. m() { C; } } enum E { A = 0, B = E.A } - ~~~~~~ + ~ !!! error TS6196: 'E' is declared but never used. interface I { x: I }; - ~~~~~~~~~~~ + ~ !!! error TS6196: 'I' is declared but never used. type T = { x: T }; - ~~~~~~ + ~ !!! error TS6196: 'T' is declared but never used. namespace N { N; } - ~~~~~~~~~~~ + ~ !!! error TS6133: 'N' is declared but its value is never read. // Avoid a false positive. diff --git a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt index f99b2522f14..9ea0147978a 100644 --- a/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt +++ b/tests/baselines/reference/noUnusedLocals_selfReference_skipsBlockLocations.errors.txt @@ -1,12 +1,12 @@ -tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(2,5): error TS6133: 'f' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(8,13): error TS6133: 'g' is declared but its value is never read. -tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(12,13): error TS6133: 'h' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(2,14): error TS6133: 'f' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(8,22): error TS6133: 'g' is declared but its value is never read. +tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(12,22): error TS6133: 'h' is declared but its value is never read. ==== tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts (3 errors) ==== namespace n { function f() { - ~~~~~~~~~~ + ~ !!! error TS6133: 'f' is declared but its value is never read. f; } @@ -14,13 +14,13 @@ tests/cases/compiler/noUnusedLocals_selfReference_skipsBlockLocations.ts(12,13): switch (0) { case 0: function g() { - ~~~~~~~~~~ + ~ !!! error TS6133: 'g' is declared but its value is never read. g; } default: function h() { - ~~~~~~~~~~ + ~ !!! error TS6133: 'h' is declared but its value is never read. h; } diff --git a/tests/baselines/reference/objectLiteralPropertyImplicitlyAny.symbols b/tests/baselines/reference/objectLiteralPropertyImplicitlyAny.symbols index dd070aabde2..ae29ff8bb9e 100644 --- a/tests/baselines/reference/objectLiteralPropertyImplicitlyAny.symbols +++ b/tests/baselines/reference/objectLiteralPropertyImplicitlyAny.symbols @@ -2,7 +2,7 @@ const foo = Symbol.for("foo"); >foo : Symbol(foo, Decl(objectLiteralPropertyImplicitlyAny.ts, 0, 5)) >Symbol.for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) >for : Symbol(SymbolConstructor.for, Decl(lib.es2015.symbol.d.ts, --, --)) const o = { [foo]: undefined }; diff --git a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols new file mode 100644 index 00000000000..f8d01ae6981 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.symbols @@ -0,0 +1,11 @@ +=== tests/cases/conformance/salsa/mod1.js === +export var hurk = {} +>hurk : Symbol(hurk, Decl(mod1.js, 0, 10)) + +=== tests/cases/conformance/salsa/bug24658.js === +import { hurk } from './mod1' +>hurk : Symbol(hurk, Decl(bug24658.js, 0, 8)) + +hurk.expando = 4 +>hurk : Symbol(hurk, Decl(bug24658.js, 0, 8)) + diff --git a/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types new file mode 100644 index 00000000000..c14617911d1 --- /dev/null +++ b/tests/baselines/reference/propertyAssignmentOnImportedSymbol.types @@ -0,0 +1,16 @@ +=== tests/cases/conformance/salsa/mod1.js === +export var hurk = {} +>hurk : { [x: string]: any; } +>{} : { [x: string]: any; } + +=== tests/cases/conformance/salsa/bug24658.js === +import { hurk } from './mod1' +>hurk : { [x: string]: any; } + +hurk.expando = 4 +>hurk.expando = 4 : 4 +>hurk.expando : any +>hurk : { [x: string]: any; } +>expando : any +>4 : 4 + diff --git a/tests/baselines/reference/quickInfoJsDocTags.baseline b/tests/baselines/reference/quickInfoJsDocTags.baseline index 6019419e489..b022204dd69 100644 --- a/tests/baselines/reference/quickInfoJsDocTags.baseline +++ b/tests/baselines/reference/quickInfoJsDocTags.baseline @@ -2,13 +2,13 @@ { "marker": { "fileName": "/tests/cases/fourslash/quickInfoJsDocTags.ts", - "position": 258 + "position": 256 }, "quickInfo": { "kind": "function", "kindModifiers": "", "textSpan": { - "start": 258, + "start": 256, "length": 3 }, "displayParts": [ @@ -78,7 +78,7 @@ }, { "name": "template", - "text": "{T} A template" + "text": "T A template" }, { "name": "type", diff --git a/tests/baselines/reference/reexportDefaultIsCallable.js b/tests/baselines/reference/reexportDefaultIsCallable.js new file mode 100644 index 00000000000..a4b557883de --- /dev/null +++ b/tests/baselines/reference/reexportDefaultIsCallable.js @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/reexportDefaultIsCallable.ts] //// + +//// [schema.d.ts] +export default class Schema {} +//// [reexporter.d.ts] +export { default } from "./schema"; +//// [usage.ts] +import Base from "./reexporter"; +export default class Mine extends Base {} + + +//// [usage.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +exports.__esModule = true; +var reexporter_1 = __importDefault(require("./reexporter")); +var Mine = /** @class */ (function (_super) { + __extends(Mine, _super); + function Mine() { + return _super !== null && _super.apply(this, arguments) || this; + } + return Mine; +}(reexporter_1["default"])); +exports["default"] = Mine; diff --git a/tests/baselines/reference/reexportDefaultIsCallable.symbols b/tests/baselines/reference/reexportDefaultIsCallable.symbols new file mode 100644 index 00000000000..8d6841aeb3f --- /dev/null +++ b/tests/baselines/reference/reexportDefaultIsCallable.symbols @@ -0,0 +1,16 @@ +=== tests/cases/compiler/schema.d.ts === +export default class Schema {} +>Schema : Symbol(Schema, Decl(schema.d.ts, 0, 0)) + +=== tests/cases/compiler/reexporter.d.ts === +export { default } from "./schema"; +>default : Symbol(default, Decl(reexporter.d.ts, 0, 8)) + +=== tests/cases/compiler/usage.ts === +import Base from "./reexporter"; +>Base : Symbol(Base, Decl(usage.ts, 0, 6)) + +export default class Mine extends Base {} +>Mine : Symbol(Mine, Decl(usage.ts, 0, 32)) +>Base : Symbol(Base, Decl(usage.ts, 0, 6)) + diff --git a/tests/baselines/reference/reexportDefaultIsCallable.types b/tests/baselines/reference/reexportDefaultIsCallable.types new file mode 100644 index 00000000000..ba33aeef0fa --- /dev/null +++ b/tests/baselines/reference/reexportDefaultIsCallable.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/schema.d.ts === +export default class Schema {} +>Schema : Schema + +=== tests/cases/compiler/reexporter.d.ts === +export { default } from "./schema"; +>default : typeof import("tests/cases/compiler/schema").default + +=== tests/cases/compiler/usage.ts === +import Base from "./reexporter"; +>Base : typeof Base + +export default class Mine extends Base {} +>Mine : Mine +>Base : Base + diff --git a/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.js b/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.js new file mode 100644 index 00000000000..700d5f9c927 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/requireOfJsonFileWithAlwaysStrictWithoutErrors.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} +//// [file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.symbols b/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.symbols new file mode 100644 index 00000000000..a8f82b6b145 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.types b/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.types new file mode 100644 index 00000000000..c718c429408 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithAlwaysStrictWithoutErrors.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { "a": boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { "a": boolean; "b": string; } +>a : boolean + +import b2 = require('./b.json'); +>b2 : { "a": boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { "a": boolean; "b": string; } +>b : string +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileWithDeclaration.js b/tests/baselines/reference/requireOfJsonFileWithDeclaration.js new file mode 100644 index 00000000000..2cb5085ffb7 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithDeclaration.js @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/requireOfJsonFileWithDeclaration.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [out/b.json] +{ + "a": true, + "b": "hello" +} +//// [out/file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} + + +//// [out/file1.d.ts] +export {}; diff --git a/tests/baselines/reference/requireOfJsonFileWithDeclaration.symbols b/tests/baselines/reference/requireOfJsonFileWithDeclaration.symbols new file mode 100644 index 00000000000..a8f82b6b145 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithDeclaration.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithDeclaration.types b/tests/baselines/reference/requireOfJsonFileWithDeclaration.types new file mode 100644 index 00000000000..c718c429408 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithDeclaration.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { "a": boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { "a": boolean; "b": string; } +>a : boolean + +import b2 = require('./b.json'); +>b2 : { "a": boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { "a": boolean; "b": string; } +>b : string +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileWithSourceMap.js b/tests/baselines/reference/requireOfJsonFileWithSourceMap.js new file mode 100644 index 00000000000..2a6b929f662 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithSourceMap.js @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/requireOfJsonFileWithSourceMap.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello" +} + +//// [out/b.json] +{ + "a": true, + "b": "hello" +} +//// [out/file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} +//# sourceMappingURL=file1.js.map \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithSourceMap.js.map b/tests/baselines/reference/requireOfJsonFileWithSourceMap.js.map new file mode 100644 index 00000000000..d0848a65469 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithSourceMap.js.map @@ -0,0 +1,2 @@ +//// [out/file1.js.map] +{"version":3,"file":"file1.js","sourceRoot":"","sources":["../tests/cases/compiler/file1.ts"],"names":[],"mappings":";;AAAA,6BAAgC;AAChC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACb,6BAAgC;AAChC,IAAI,CAAC,EAAE;IACH,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACb,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;CACpB"} \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithSourceMap.sourcemap.txt b/tests/baselines/reference/requireOfJsonFileWithSourceMap.sourcemap.txt new file mode 100644 index 00000000000..ac39c3d7464 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithSourceMap.sourcemap.txt @@ -0,0 +1,145 @@ +=================================================================== +JsFile: file1.js +mapUrl: file1.js.map +sourceRoot: +sources: ../tests/cases/compiler/file1.ts +=================================================================== +------------------------------------------------------------------- +emittedFile:out/file1.js +sourceFile:../tests/cases/compiler/file1.ts +------------------------------------------------------------------- +>>>"use strict"; +>>>exports.__esModule = true; +>>>var b1 = require("./b.json"); +1 > +2 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1 > +2 >import b1 = require('./b.json'); +1 >Emitted(3, 1) Source(1, 1) + SourceIndex(0) +2 >Emitted(3, 30) Source(1, 33) + SourceIndex(0) +--- +>>>var x = b1.a; +1 > +2 >^^^^ +3 > ^ +4 > ^^^ +5 > ^^ +6 > ^ +7 > ^ +8 > ^ +9 > ^^^^^^^^^^^^^^^^^-> +1 > + > +2 >let +3 > x +4 > = +5 > b1 +6 > . +7 > a +8 > ; +1 >Emitted(4, 1) Source(2, 1) + SourceIndex(0) +2 >Emitted(4, 5) Source(2, 5) + SourceIndex(0) +3 >Emitted(4, 6) Source(2, 6) + SourceIndex(0) +4 >Emitted(4, 9) Source(2, 9) + SourceIndex(0) +5 >Emitted(4, 11) Source(2, 11) + SourceIndex(0) +6 >Emitted(4, 12) Source(2, 12) + SourceIndex(0) +7 >Emitted(4, 13) Source(2, 13) + SourceIndex(0) +8 >Emitted(4, 14) Source(2, 14) + SourceIndex(0) +--- +>>>var b2 = require("./b.json"); +1-> +2 >^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +1-> + > +2 >import b2 = require('./b.json'); +1->Emitted(5, 1) Source(3, 1) + SourceIndex(0) +2 >Emitted(5, 30) Source(3, 33) + SourceIndex(0) +--- +>>>if (x) { +1 > +2 >^^^^ +3 > ^ +4 > ^^ +5 > ^^^^^^^^^^^-> +1 > + > +2 >if ( +3 > x +4 > ) +1 >Emitted(6, 1) Source(4, 1) + SourceIndex(0) +2 >Emitted(6, 5) Source(4, 5) + SourceIndex(0) +3 >Emitted(6, 6) Source(4, 6) + SourceIndex(0) +4 >Emitted(6, 8) Source(4, 8) + SourceIndex(0) +--- +>>> var b = b2.b; +1->^^^^ +2 > ^^^^ +3 > ^ +4 > ^^^ +5 > ^^ +6 > ^ +7 > ^ +8 > ^ +9 > ^^^^^-> +1->{ + > +2 > let +3 > b +4 > = +5 > b2 +6 > . +7 > b +8 > ; +1->Emitted(7, 5) Source(5, 5) + SourceIndex(0) +2 >Emitted(7, 9) Source(5, 9) + SourceIndex(0) +3 >Emitted(7, 10) Source(5, 10) + SourceIndex(0) +4 >Emitted(7, 13) Source(5, 13) + SourceIndex(0) +5 >Emitted(7, 15) Source(5, 15) + SourceIndex(0) +6 >Emitted(7, 16) Source(5, 16) + SourceIndex(0) +7 >Emitted(7, 17) Source(5, 17) + SourceIndex(0) +8 >Emitted(7, 18) Source(5, 18) + SourceIndex(0) +--- +>>> x = (b1.b === b); +1->^^^^ +2 > ^ +3 > ^^^ +4 > ^ +5 > ^^ +6 > ^ +7 > ^ +8 > ^^^^^ +9 > ^ +10> ^ +11> ^ +1-> + > +2 > x +3 > = +4 > ( +5 > b1 +6 > . +7 > b +8 > === +9 > b +10> ) +11> ; +1->Emitted(8, 5) Source(6, 5) + SourceIndex(0) +2 >Emitted(8, 6) Source(6, 6) + SourceIndex(0) +3 >Emitted(8, 9) Source(6, 9) + SourceIndex(0) +4 >Emitted(8, 10) Source(6, 10) + SourceIndex(0) +5 >Emitted(8, 12) Source(6, 12) + SourceIndex(0) +6 >Emitted(8, 13) Source(6, 13) + SourceIndex(0) +7 >Emitted(8, 14) Source(6, 14) + SourceIndex(0) +8 >Emitted(8, 19) Source(6, 19) + SourceIndex(0) +9 >Emitted(8, 20) Source(6, 20) + SourceIndex(0) +10>Emitted(8, 21) Source(6, 21) + SourceIndex(0) +11>Emitted(8, 22) Source(6, 22) + SourceIndex(0) +--- +>>>} +1 >^ +2 > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-> +1 > + >} +1 >Emitted(9, 2) Source(7, 2) + SourceIndex(0) +--- +>>>//# sourceMappingURL=file1.js.map \ No newline at end of file diff --git a/tests/baselines/reference/requireOfJsonFileWithSourceMap.symbols b/tests/baselines/reference/requireOfJsonFileWithSourceMap.symbols new file mode 100644 index 00000000000..a8f82b6b145 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithSourceMap.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello" +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithSourceMap.types b/tests/baselines/reference/requireOfJsonFileWithSourceMap.types new file mode 100644 index 00000000000..c718c429408 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithSourceMap.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { "a": boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { "a": boolean; "b": string; } +>a : boolean + +import b2 = require('./b.json'); +>b2 : { "a": boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { "a": boolean; "b": string; } +>b : string +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello"} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello" +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/requireOfJsonFileWithTraillingComma.js b/tests/baselines/reference/requireOfJsonFileWithTraillingComma.js new file mode 100644 index 00000000000..332112b3560 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithTraillingComma.js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/requireOfJsonFileWithTraillingComma.ts] //// + +//// [file1.ts] +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +//// [b.json] +{ + "a": true, + "b": "hello", +} + +//// [out/b.json] +{ + "a": true, + "b": "hello" +} +//// [out/file1.js] +"use strict"; +exports.__esModule = true; +var b1 = require("./b.json"); +var x = b1.a; +var b2 = require("./b.json"); +if (x) { + var b = b2.b; + x = (b1.b === b); +} diff --git a/tests/baselines/reference/requireOfJsonFileWithTraillingComma.symbols b/tests/baselines/reference/requireOfJsonFileWithTraillingComma.symbols new file mode 100644 index 00000000000..79eac57c9f6 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithTraillingComma.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) + +let x = b1.a; +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.a : Symbol("a", Decl(b.json, 0, 1)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>a : Symbol("a", Decl(b.json, 0, 1)) + +import b2 = require('./b.json'); +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) + +if (x) { +>x : Symbol(x, Decl(file1.ts, 1, 3)) + + let b = b2.b; +>b : Symbol(b, Decl(file1.ts, 4, 7)) +>b2.b : Symbol("b", Decl(b.json, 1, 14)) +>b2 : Symbol(b2, Decl(file1.ts, 1, 13)) +>b : Symbol("b", Decl(b.json, 1, 14)) + + x = (b1.b === b); +>x : Symbol(x, Decl(file1.ts, 1, 3)) +>b1.b : Symbol("b", Decl(b.json, 1, 14)) +>b1 : Symbol(b1, Decl(file1.ts, 0, 0)) +>b : Symbol("b", Decl(b.json, 1, 14)) +>b : Symbol(b, Decl(file1.ts, 4, 7)) +} + +=== tests/cases/compiler/b.json === +{ + "a": true, +>"a" : Symbol("a", Decl(b.json, 0, 1)) + + "b": "hello", +>"b" : Symbol("b", Decl(b.json, 1, 14)) +} diff --git a/tests/baselines/reference/requireOfJsonFileWithTraillingComma.types b/tests/baselines/reference/requireOfJsonFileWithTraillingComma.types new file mode 100644 index 00000000000..17e637a6df8 --- /dev/null +++ b/tests/baselines/reference/requireOfJsonFileWithTraillingComma.types @@ -0,0 +1,45 @@ +=== tests/cases/compiler/file1.ts === +import b1 = require('./b.json'); +>b1 : { "a": boolean; "b": string; } + +let x = b1.a; +>x : boolean +>b1.a : boolean +>b1 : { "a": boolean; "b": string; } +>a : boolean + +import b2 = require('./b.json'); +>b2 : { "a": boolean; "b": string; } + +if (x) { +>x : boolean + + let b = b2.b; +>b : string +>b2.b : string +>b2 : { "a": boolean; "b": string; } +>b : string + + x = (b1.b === b); +>x = (b1.b === b) : boolean +>x : boolean +>(b1.b === b) : boolean +>b1.b === b : boolean +>b1.b : string +>b1 : { "a": boolean; "b": string; } +>b : string +>b : string +} + +=== tests/cases/compiler/b.json === +{ +>{ "a": true, "b": "hello",} : { "a": boolean; "b": string; } + + "a": true, +>"a" : boolean +>true : true + + "b": "hello", +>"b" : string +>"hello" : "hello" +} diff --git a/tests/baselines/reference/typeFromPropertyAssignment.symbols b/tests/baselines/reference/typeFromPropertyAssignment.symbols index 56237a1358b..f58a6620264 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment.symbols @@ -9,9 +9,9 @@ var Outer = class O { >y : Symbol(y, Decl(a.js, 1, 8)) } Outer.Inner = class I { ->Outer.Inner : Symbol(O.Inner, Decl(a.js, 2, 1)) +>Outer.Inner : Symbol(Outer.Inner, Decl(a.js, 2, 1)) >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 2, 1)) ->Inner : Symbol(O.Inner, Decl(a.js, 2, 1)) +>Inner : Symbol(Outer.Inner, Decl(a.js, 2, 1)) >I : Symbol(I, Decl(a.js, 3, 13)) n(a, b) { } diff --git a/tests/baselines/reference/typeFromPropertyAssignment10.symbols b/tests/baselines/reference/typeFromPropertyAssignment10.symbols index 8b0f00481c2..9b0af678352 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment10.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment10.symbols @@ -4,19 +4,19 @@ var Outer = Outer || {}; >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) Outer.app = Outer.app || {}; ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) === tests/cases/conformance/salsa/someview.js === Outer.app.SomeView = (function () { >Outer.app.SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) var SomeView = function() { @@ -31,9 +31,9 @@ Outer.app.SomeView = (function () { })(); Outer.app.Inner = class { >Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) constructor() { @@ -47,9 +47,9 @@ Outer.app.Inner = class { var example = new Outer.app.Inner(); >example : Symbol(example, Decl(someview.js, 12, 3)) >Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) example.y; @@ -60,9 +60,9 @@ example.y; /** @param {number} k */ Outer.app.statische = function (k) { >Outer.app.statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) >k : Symbol(k, Decl(someview.js, 15, 32)) @@ -72,11 +72,11 @@ Outer.app.statische = function (k) { } === tests/cases/conformance/salsa/application.js === Outer.app.Application = (function () { ->Outer.app.Application : Symbol(app.Application, Decl(application.js, 0, 0)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app.Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) ->Application : Symbol(app.Application, Decl(application.js, 0, 0)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) /** * Application main class. @@ -91,9 +91,9 @@ Outer.app.Application = (function () { me.view = new Outer.app.SomeView(); >me : Symbol(me, Decl(application.js, 7, 11)) >Outer.app.SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >SomeView : Symbol(Outer.app.SomeView, Decl(someview.js, 0, 0)) }; @@ -104,18 +104,18 @@ Outer.app.Application = (function () { === tests/cases/conformance/salsa/main.js === var app = new Outer.app.Application(); >app : Symbol(app, Decl(main.js, 0, 3)) ->Outer.app.Application : Symbol(app.Application, Decl(application.js, 0, 0)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app.Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) ->Application : Symbol(app.Application, Decl(application.js, 0, 0)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Application : Symbol(Outer.app.Application, Decl(application.js, 0, 0)) var inner = new Outer.app.Inner(); >inner : Symbol(inner, Decl(main.js, 1, 3)) >Outer.app.Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Inner : Symbol(Outer.app.Inner, Decl(someview.js, 5, 5)) inner.y; @@ -134,8 +134,8 @@ x.y; Outer.app.statische(101); // Infinity, duh >Outer.app.statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) ->Outer.app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>Outer.app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 24), Decl(someview.js, 0, 0), Decl(application.js, 0, 0)) ->app : Symbol(app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) +>app : Symbol(Outer.app, Decl(module.js, 0, 24), Decl(someview.js, 0, 6), Decl(application.js, 0, 6)) >statische : Symbol(Outer.app.statische, Decl(someview.js, 13, 10)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment11.symbols b/tests/baselines/reference/typeFromPropertyAssignment11.symbols index 93d79e2de1c..fe41bc09c23 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment11.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment11.symbols @@ -3,9 +3,9 @@ var Inner = function() {} >Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25)) Inner.prototype = { ->Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>Inner.prototype : Symbol(Inner.prototype, Decl(module.js, 0, 25)) >Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(Inner.prototype, Decl(module.js, 0, 25)) m() { }, >m : Symbol(m, Decl(module.js, 1, 19)) @@ -17,14 +17,14 @@ Inner.prototype = { Inner.prototype.j = 2 >Inner.prototype : Symbol(Inner.j, Decl(module.js, 4, 1)) >Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(Inner.prototype, Decl(module.js, 0, 25)) >j : Symbol(Inner.j, Decl(module.js, 4, 1)) /** @type {string} */ Inner.prototype.k; ->Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>Inner.prototype : Symbol(Inner.prototype, Decl(module.js, 0, 25)) >Inner : Symbol(Inner, Decl(module.js, 0, 3), Decl(module.js, 0, 25)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(Inner.prototype, Decl(module.js, 0, 25)) var inner = new Inner() >inner : Symbol(inner, Decl(module.js, 9, 3)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment11.types b/tests/baselines/reference/typeFromPropertyAssignment11.types index 949ba93570f..8c90e824f23 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment11.types +++ b/tests/baselines/reference/typeFromPropertyAssignment11.types @@ -5,9 +5,9 @@ var Inner = function() {} Inner.prototype = { >Inner.prototype = { m() { }, i: 1} : { [x: string]: any; m(): void; i: number; } ->Inner.prototype : any +>Inner.prototype : { [x: string]: any; m(): void; i: number; } >Inner : typeof Inner ->prototype : any +>prototype : { [x: string]: any; m(): void; i: number; } >{ m() { }, i: 1} : { [x: string]: any; m(): void; i: number; } m() { }, @@ -21,18 +21,18 @@ Inner.prototype = { Inner.prototype.j = 2 >Inner.prototype.j = 2 : 2 >Inner.prototype.j : any ->Inner.prototype : any +>Inner.prototype : { [x: string]: any; m(): void; i: number; } >Inner : typeof Inner ->prototype : any +>prototype : { [x: string]: any; m(): void; i: number; } >j : any >2 : 2 /** @type {string} */ Inner.prototype.k; >Inner.prototype.k : any ->Inner.prototype : any +>Inner.prototype : { [x: string]: any; m(): void; i: number; } >Inner : typeof Inner ->prototype : any +>prototype : { [x: string]: any; m(): void; i: number; } >k : any var inner = new Inner() diff --git a/tests/baselines/reference/typeFromPropertyAssignment12.symbols b/tests/baselines/reference/typeFromPropertyAssignment12.symbols index cd25c16a13d..321fc4124e6 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment12.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment12.symbols @@ -28,8 +28,8 @@ var pos = new Outer.Pos(1, 'x'); >Pos : Symbol(Outer.Pos, Decl(usage.js, 0, 0)) pos.line; ->pos.line : Symbol(Pos.line, Decl(usage.js, 1, 35)) +>pos.line : Symbol(Outer.Pos.line, Decl(usage.js, 1, 35)) >pos : Symbol(pos, Decl(usage.js, 4, 3)) ->line : Symbol(Pos.line, Decl(usage.js, 1, 35)) +>line : Symbol(Outer.Pos.line, Decl(usage.js, 1, 35)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment12.types b/tests/baselines/reference/typeFromPropertyAssignment12.types index 60e69008868..21b8dd7e32c 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment12.types +++ b/tests/baselines/reference/typeFromPropertyAssignment12.types @@ -1,7 +1,7 @@ === tests/cases/conformance/salsa/module.js === var Outer = function(element, config) {}; ->Outer : typeof Outer ->function(element, config) {} : typeof Outer +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } +>function(element, config) {} : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >element : any >config : any @@ -10,7 +10,7 @@ var Outer = function(element, config) {}; Outer.Pos = function (line, ch) {}; >Outer.Pos = function (line, ch) {} : typeof Pos >Outer.Pos : typeof Pos ->Outer : typeof Outer +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >Pos : typeof Pos >function (line, ch) {} : typeof Pos >line : any @@ -21,7 +21,7 @@ Outer.Pos.prototype.line; >Outer.Pos.prototype.line : any >Outer.Pos.prototype : any >Outer.Pos : typeof Pos ->Outer : typeof Outer +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >Pos : typeof Pos >prototype : any >line : any @@ -30,7 +30,7 @@ var pos = new Outer.Pos(1, 'x'); >pos : Pos >new Outer.Pos(1, 'x') : Pos >Outer.Pos : typeof Pos ->Outer : typeof Outer +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >Pos : typeof Pos >1 : 1 >'x' : "x" diff --git a/tests/baselines/reference/typeFromPropertyAssignment13.symbols b/tests/baselines/reference/typeFromPropertyAssignment13.symbols index c0c05635b03..1fd8f13f835 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment13.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment13.symbols @@ -3,16 +3,16 @@ var Outer = {} >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 14), Decl(module.js, 1, 27)) Outer.Inner = function() {} ->Outer.Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>Outer.Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 14), Decl(module.js, 1, 27)) ->Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) Outer.Inner.prototype = { ->Outer.Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) ->Outer.Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>Outer.Inner.prototype : Symbol(Outer.Inner.prototype, Decl(module.js, 1, 27)) +>Outer.Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 14), Decl(module.js, 1, 27)) ->Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>prototype : Symbol(Outer.Inner.prototype, Decl(module.js, 1, 27)) m() { }, >m : Symbol(m, Decl(module.js, 2, 25)) @@ -22,26 +22,26 @@ Outer.Inner.prototype = { } // incremental assignments still work Outer.Inner.prototype.j = 2 ->Outer.Inner.prototype : Symbol(Inner.j, Decl(module.js, 5, 1)) ->Outer.Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>Outer.Inner.prototype : Symbol(Outer.Inner.j, Decl(module.js, 5, 1)) +>Outer.Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 14), Decl(module.js, 1, 27)) ->Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) ->j : Symbol(Inner.j, Decl(module.js, 5, 1)) +>Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>prototype : Symbol(Outer.Inner.prototype, Decl(module.js, 1, 27)) +>j : Symbol(Outer.Inner.j, Decl(module.js, 5, 1)) /** @type {string} */ Outer.Inner.prototype.k; ->Outer.Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) ->Outer.Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>Outer.Inner.prototype : Symbol(Outer.Inner.prototype, Decl(module.js, 1, 27)) +>Outer.Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 14), Decl(module.js, 1, 27)) ->Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>prototype : Symbol(Outer.Inner.prototype, Decl(module.js, 1, 27)) var inner = new Outer.Inner() >inner : Symbol(inner, Decl(module.js, 10, 3)) ->Outer.Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>Outer.Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) >Outer : Symbol(Outer, Decl(module.js, 0, 3), Decl(module.js, 0, 14), Decl(module.js, 1, 27)) ->Inner : Symbol(Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) +>Inner : Symbol(Outer.Inner, Decl(module.js, 0, 14), Decl(module.js, 2, 6)) inner.m() >inner.m : Symbol(m, Decl(module.js, 2, 25)) @@ -54,12 +54,12 @@ inner.i >i : Symbol(i, Decl(module.js, 3, 12)) inner.j ->inner.j : Symbol(Inner.j, Decl(module.js, 5, 1)) +>inner.j : Symbol(Outer.Inner.j, Decl(module.js, 5, 1)) >inner : Symbol(inner, Decl(module.js, 10, 3)) ->j : Symbol(Inner.j, Decl(module.js, 5, 1)) +>j : Symbol(Outer.Inner.j, Decl(module.js, 5, 1)) inner.k ->inner.k : Symbol(Inner.k, Decl(module.js, 7, 27)) +>inner.k : Symbol(Outer.Inner.k, Decl(module.js, 7, 27)) >inner : Symbol(inner, Decl(module.js, 10, 3)) ->k : Symbol(Inner.k, Decl(module.js, 7, 27)) +>k : Symbol(Outer.Inner.k, Decl(module.js, 7, 27)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment13.types b/tests/baselines/reference/typeFromPropertyAssignment13.types index 92feec7d5c5..c5370aebc56 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment13.types +++ b/tests/baselines/reference/typeFromPropertyAssignment13.types @@ -1,22 +1,22 @@ === tests/cases/conformance/salsa/module.js === var Outer = {} ->Outer : { [x: string]: any; Inner(): void; } ->{} : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: typeof Inner; } +>{} : { [x: string]: any; Inner: typeof Inner; } Outer.Inner = function() {} >Outer.Inner = function() {} : typeof Inner >Outer.Inner : typeof Inner ->Outer : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: typeof Inner; } >Inner : typeof Inner >function() {} : typeof Inner Outer.Inner.prototype = { >Outer.Inner.prototype = { m() { }, i: 1} : { [x: string]: any; m(): void; i: number; } ->Outer.Inner.prototype : any +>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; } >Outer.Inner : typeof Inner ->Outer : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: typeof Inner; } >Inner : typeof Inner ->prototype : any +>prototype : { [x: string]: any; m(): void; i: number; } >{ m() { }, i: 1} : { [x: string]: any; m(): void; i: number; } m() { }, @@ -30,29 +30,29 @@ Outer.Inner.prototype = { Outer.Inner.prototype.j = 2 >Outer.Inner.prototype.j = 2 : 2 >Outer.Inner.prototype.j : any ->Outer.Inner.prototype : any +>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; } >Outer.Inner : typeof Inner ->Outer : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: typeof Inner; } >Inner : typeof Inner ->prototype : any +>prototype : { [x: string]: any; m(): void; i: number; } >j : any >2 : 2 /** @type {string} */ Outer.Inner.prototype.k; >Outer.Inner.prototype.k : any ->Outer.Inner.prototype : any +>Outer.Inner.prototype : { [x: string]: any; m(): void; i: number; } >Outer.Inner : typeof Inner ->Outer : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: typeof Inner; } >Inner : typeof Inner ->prototype : any +>prototype : { [x: string]: any; m(): void; i: number; } >k : any var inner = new Outer.Inner() >inner : Inner & { [x: string]: any; m(): void; i: number; } >new Outer.Inner() : Inner & { [x: string]: any; m(): void; i: number; } >Outer.Inner : typeof Inner ->Outer : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: typeof Inner; } >Inner : typeof Inner inner.m() diff --git a/tests/baselines/reference/typeFromPropertyAssignment14.symbols b/tests/baselines/reference/typeFromPropertyAssignment14.symbols index 6740513f4d6..aa5aba6eea4 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment14.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment14.symbols @@ -9,11 +9,11 @@ Outer.Inner = function () {} >Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) Outer.Inner.prototype = { ->Outer.Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>Outer.Inner.prototype : Symbol(Outer.Inner.prototype, Decl(work.js, 0, 28)) >Outer.Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) >Outer : Symbol(Outer, Decl(def.js, 0, 3), Decl(work.js, 0, 0), Decl(work.js, 0, 28)) >Inner : Symbol(Outer.Inner, Decl(work.js, 0, 0), Decl(work.js, 1, 6)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(Outer.Inner.prototype, Decl(work.js, 0, 28)) x: 1, >x : Symbol(x, Decl(work.js, 1, 25)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment14.types b/tests/baselines/reference/typeFromPropertyAssignment14.types index 0416d2de952..65838ccacc1 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment14.types +++ b/tests/baselines/reference/typeFromPropertyAssignment14.types @@ -1,23 +1,23 @@ === tests/cases/conformance/salsa/def.js === var Outer = {}; ->Outer : { [x: string]: any; Inner(): void; } ->{} : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>{} : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } === tests/cases/conformance/salsa/work.js === Outer.Inner = function () {} ->Outer.Inner = function () {} : () => void ->Outer.Inner : () => void ->Outer : { [x: string]: any; Inner(): void; } ->Inner : () => void ->function () {} : () => void +>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } Outer.Inner.prototype = { >Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } ->Outer.Inner.prototype : any ->Outer.Inner : () => void ->Outer : { [x: string]: any; Inner(): void; } ->Inner : () => void ->prototype : any +>Outer.Inner.prototype : { [x: string]: any; x: number; m(): void; } +>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>prototype : { [x: string]: any; x: number; m(): void; } >{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } x: 1, @@ -47,9 +47,9 @@ inner.m() var inno = new Outer.Inner() >inno : { [x: string]: any; x: number; m(): void; } >new Outer.Inner() : { [x: string]: any; x: number; m(): void; } ->Outer.Inner : () => void ->Outer : { [x: string]: any; Inner(): void; } ->Inner : () => void +>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } inno.x >inno.x : number diff --git a/tests/baselines/reference/typeFromPropertyAssignment15.symbols b/tests/baselines/reference/typeFromPropertyAssignment15.symbols index f649c3e9e63..ce9a3205857 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment15.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment15.symbols @@ -3,9 +3,9 @@ var Outer = {}; >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15)) Outer.Inner = class { ->Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15)) +>Outer.Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15)) >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15)) ->Inner : Symbol(Inner, Decl(a.js, 0, 15)) +>Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15)) constructor() { this.x = 1 @@ -33,9 +33,9 @@ inner.m() var inno = new Outer.Inner() >inno : Symbol(inno, Decl(a.js, 13, 3)) ->Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15)) +>Outer.Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15)) >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15)) ->Inner : Symbol(Inner, Decl(a.js, 0, 15)) +>Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15)) inno.x >inno.x : Symbol(Inner.x, Decl(a.js, 3, 19)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment16.symbols b/tests/baselines/reference/typeFromPropertyAssignment16.symbols index cf73cbd40aa..c5b41ad4f95 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment16.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment16.symbols @@ -3,16 +3,16 @@ var Outer = {}; >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) Outer.Inner = function () {} ->Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Outer.Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) ->Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) Outer.Inner.prototype = { ->Outer.Inner.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) ->Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Outer.Inner.prototype : Symbol(Outer.Inner.prototype, Decl(a.js, 2, 28)) +>Outer.Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) ->Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) ->prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>prototype : Symbol(Outer.Inner.prototype, Decl(a.js, 2, 28)) x: 1, >x : Symbol(x, Decl(a.js, 3, 25)) @@ -37,9 +37,9 @@ inner.m() var inno = new Outer.Inner() >inno : Symbol(inno, Decl(a.js, 12, 3)) ->Outer.Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Outer.Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 0, 15), Decl(a.js, 2, 28)) ->Inner : Symbol(Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) +>Inner : Symbol(Outer.Inner, Decl(a.js, 0, 15), Decl(a.js, 3, 6)) inno.x >inno.x : Symbol(x, Decl(a.js, 3, 25)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment16.types b/tests/baselines/reference/typeFromPropertyAssignment16.types index 95fc42ca434..76076e74d93 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment16.types +++ b/tests/baselines/reference/typeFromPropertyAssignment16.types @@ -1,22 +1,22 @@ === tests/cases/conformance/salsa/a.js === var Outer = {}; ->Outer : { [x: string]: any; Inner(): void; } ->{} : { [x: string]: any; Inner(): void; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>{} : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } Outer.Inner = function () {} ->Outer.Inner = function () {} : () => void ->Outer.Inner : () => void ->Outer : { [x: string]: any; Inner(): void; } ->Inner : () => void ->function () {} : () => void +>Outer.Inner = function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>function () {} : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } Outer.Inner.prototype = { >Outer.Inner.prototype = { x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } ->Outer.Inner.prototype : any ->Outer.Inner : () => void ->Outer : { [x: string]: any; Inner(): void; } ->Inner : () => void ->prototype : any +>Outer.Inner.prototype : { [x: string]: any; x: number; m(): void; } +>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>prototype : { [x: string]: any; x: number; m(): void; } >{ x: 1, m() { }} : { [x: string]: any; x: number; m(): void; } x: 1, @@ -45,9 +45,9 @@ inner.m() var inno = new Outer.Inner() >inno : { [x: string]: any; x: number; m(): void; } >new Outer.Inner() : { [x: string]: any; x: number; m(): void; } ->Outer.Inner : () => void ->Outer : { [x: string]: any; Inner(): void; } ->Inner : () => void +>Outer.Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } +>Outer : { [x: string]: any; Inner: { (): void; prototype: { [x: string]: any; x: number; m(): void; }; }; } +>Inner : { (): void; prototype: { [x: string]: any; x: number; m(): void; }; } inno.x >inno.x : number diff --git a/tests/baselines/reference/typeFromPropertyAssignment18.symbols b/tests/baselines/reference/typeFromPropertyAssignment18.symbols index b4342c29394..19fc0068c91 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment18.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment18.symbols @@ -12,16 +12,16 @@ GLOBSTAR.p = 1 >GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3)) m.GLOBSTAR.q = 2 ->m.GLOBSTAR.q : Symbol(q, Decl(a.js, 3, 14)) +>m.GLOBSTAR.q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) >m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) >m : Symbol(m, Decl(a.js, 0, 30)) >GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) ->q : Symbol(q, Decl(a.js, 3, 14)) +>q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) GLOBSTAR.q ->GLOBSTAR.q : Symbol(q, Decl(a.js, 3, 14)) +>GLOBSTAR.q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) >GLOBSTAR : Symbol(GLOBSTAR, Decl(a.js, 0, 3)) ->q : Symbol(q, Decl(a.js, 3, 14)) +>q : Symbol(m.GLOBSTAR.q, Decl(a.js, 3, 14)) m.GLOBSTAR.p >m.GLOBSTAR : Symbol(m.GLOBSTAR, Decl(a.js, 0, 14)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment3.symbols b/tests/baselines/reference/typeFromPropertyAssignment3.symbols index bd78393be05..b3353e034ad 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment3.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment3.symbols @@ -7,9 +7,9 @@ var Outer = function O() { >y : Symbol(O.y, Decl(a.js, 0, 26)) } Outer.Inner = class I { ->Outer.Inner : Symbol(O.Inner, Decl(a.js, 2, 1)) +>Outer.Inner : Symbol(Outer.Inner, Decl(a.js, 2, 1)) >Outer : Symbol(Outer, Decl(a.js, 0, 3), Decl(a.js, 2, 1)) ->Inner : Symbol(O.Inner, Decl(a.js, 2, 1)) +>Inner : Symbol(Outer.Inner, Decl(a.js, 2, 1)) >I : Symbol(I, Decl(a.js, 3, 13)) constructor() { diff --git a/tests/baselines/reference/typeFromPropertyAssignment7.symbols b/tests/baselines/reference/typeFromPropertyAssignment7.symbols index 1aa0e047523..44ffff7860b 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment7.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment7.symbols @@ -3,16 +3,16 @@ var obj = {}; >obj : Symbol(obj, Decl(a.js, 0, 3), Decl(a.js, 0, 13)) obj.method = function (hunch) { ->obj.method : Symbol(method, Decl(a.js, 0, 13)) +>obj.method : Symbol(obj.method, Decl(a.js, 0, 13)) >obj : Symbol(obj, Decl(a.js, 0, 3), Decl(a.js, 0, 13)) ->method : Symbol(method, Decl(a.js, 0, 13)) +>method : Symbol(obj.method, Decl(a.js, 0, 13)) >hunch : Symbol(hunch, Decl(a.js, 1, 23)) return true; } var b = obj.method(); >b : Symbol(b, Decl(a.js, 4, 3)) ->obj.method : Symbol(method, Decl(a.js, 0, 13)) +>obj.method : Symbol(obj.method, Decl(a.js, 0, 13)) >obj : Symbol(obj, Decl(a.js, 0, 3), Decl(a.js, 0, 13)) ->method : Symbol(method, Decl(a.js, 0, 13)) +>method : Symbol(obj.method, Decl(a.js, 0, 13)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment8.symbols b/tests/baselines/reference/typeFromPropertyAssignment8.symbols index ba7d2a37379..a1450d21a1f 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment8.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment8.symbols @@ -4,19 +4,19 @@ var my = my || {}; >my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) my.app = my.app || {}; ->my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) >my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) ->app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) ->my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) >my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) ->app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) my.app.Application = (function () { ->my.app.Application : Symbol(Application, Decl(a.js, 1, 22)) ->my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my.app.Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) >my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) ->app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) ->Application : Symbol(Application, Decl(a.js, 1, 22)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) var Application = function () { >Application : Symbol(Application, Decl(a.js, 4, 3)) @@ -28,11 +28,11 @@ return Application; })(); my.app.Application() ->my.app.Application : Symbol(Application, Decl(a.js, 1, 22)) ->my.app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>my.app.Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) +>my.app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) >my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 1, 22)) ->app : Symbol(app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) ->Application : Symbol(Application, Decl(a.js, 1, 22)) +>app : Symbol(my.app, Decl(a.js, 0, 18), Decl(a.js, 3, 3)) +>Application : Symbol(my.app.Application, Decl(a.js, 1, 22)) === tests/cases/conformance/salsa/b.js === var min = window.min || {}; @@ -40,19 +40,19 @@ var min = window.min || {}; >window : Symbol(window, Decl(lib.dom.d.ts, --, --)) min.app = min.app || {}; ->min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) >min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) ->app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) ->min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) >min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) ->app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) min.app.Application = (function () { ->min.app.Application : Symbol(Application, Decl(b.js, 1, 24)) ->min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min.app.Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) >min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) ->app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) ->Application : Symbol(Application, Decl(b.js, 1, 24)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) var Application = function () { >Application : Symbol(Application, Decl(b.js, 4, 3)) @@ -64,9 +64,9 @@ return Application; })(); min.app.Application() ->min.app.Application : Symbol(Application, Decl(b.js, 1, 24)) ->min.app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>min.app.Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) +>min.app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) >min : Symbol(min, Decl(b.js, 0, 3), Decl(b.js, 0, 27), Decl(b.js, 1, 24)) ->app : Symbol(app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) ->Application : Symbol(Application, Decl(b.js, 1, 24)) +>app : Symbol(min.app, Decl(b.js, 0, 27), Decl(b.js, 3, 4)) +>Application : Symbol(min.app.Application, Decl(b.js, 1, 24)) diff --git a/tests/baselines/reference/typeFromPropertyAssignment9.symbols b/tests/baselines/reference/typeFromPropertyAssignment9.symbols index a45debb849c..72dd84e4d64 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment9.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignment9.symbols @@ -1,42 +1,42 @@ === tests/cases/conformance/salsa/a.js === var my = my || {}; ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) /** @param {number} n */ my.method = function(n) { ->my.method : Symbol(method, Decl(a.js, 0, 18)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->method : Symbol(method, Decl(a.js, 0, 18)) +>my.method : Symbol(my.method, Decl(a.js, 0, 18)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>method : Symbol(my.method, Decl(a.js, 0, 18)) >n : Symbol(n, Decl(a.js, 2, 21)) return n + 1; >n : Symbol(n, Decl(a.js, 2, 21)) } my.number = 1; ->my.number : Symbol(number, Decl(a.js, 4, 1)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->number : Symbol(number, Decl(a.js, 4, 1)) +>my.number : Symbol(my.number, Decl(a.js, 4, 1)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>number : Symbol(my.number, Decl(a.js, 4, 1)) my.object = {}; ->my.object : Symbol(object, Decl(a.js, 5, 14)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->object : Symbol(object, Decl(a.js, 5, 14)) +>my.object : Symbol(my.object, Decl(a.js, 5, 14)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>object : Symbol(my.object, Decl(a.js, 5, 14)) my.predicate = my.predicate || {}; ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) my.predicate.query = function () { ->my.predicate.query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) var me = this; >me : Symbol(me, Decl(a.js, 9, 7)) @@ -48,46 +48,46 @@ my.predicate.query = function () { }; var q = new my.predicate.query(); >q : Symbol(q, Decl(a.js, 12, 3)) ->my.predicate.query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) my.predicate.query.another = function () { ->my.predicate.query.another : Symbol(query.another, Decl(a.js, 12, 33)) ->my.predicate.query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) ->another : Symbol(query.another, Decl(a.js, 12, 33)) +>my.predicate.query.another : Symbol(my.predicate.query.another, Decl(a.js, 12, 33)) +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>another : Symbol(my.predicate.query.another, Decl(a.js, 12, 33)) return 1; } my.predicate.query.result = 'none' ->my.predicate.query.result : Symbol(query.result, Decl(a.js, 15, 1)) ->my.predicate.query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->query : Symbol(query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) ->result : Symbol(query.result, Decl(a.js, 15, 1)) +>my.predicate.query.result : Symbol(my.predicate.query.result, Decl(a.js, 15, 1)) +>my.predicate.query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>query : Symbol(my.predicate.query, Decl(a.js, 7, 34), Decl(a.js, 13, 13)) +>result : Symbol(my.predicate.query.result, Decl(a.js, 15, 1)) /** @param {number} first * @param {number} second */ my.predicate.sort = my.predicate.sort || function (first, second) { ->my.predicate.sort : Symbol(sort, Decl(a.js, 16, 34)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->sort : Symbol(sort, Decl(a.js, 16, 34)) ->my.predicate.sort : Symbol(sort, Decl(a.js, 16, 34)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->sort : Symbol(sort, Decl(a.js, 16, 34)) +>my.predicate.sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) +>my.predicate.sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>sort : Symbol(my.predicate.sort, Decl(a.js, 16, 34)) >first : Symbol(first, Decl(a.js, 20, 51)) >second : Symbol(second, Decl(a.js, 20, 57)) @@ -98,11 +98,11 @@ my.predicate.sort = my.predicate.sort || function (first, second) { >second : Symbol(second, Decl(a.js, 20, 57)) } my.predicate.type = class { ->my.predicate.type : Symbol(type, Decl(a.js, 22, 1)) ->my.predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 5, 14), Decl(a.js, 6, 15), Decl(a.js, 7, 34) ... and 3 more) ->predicate : Symbol(predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3), Decl(a.js, 20, 3), Decl(a.js, 23, 3)) ->type : Symbol(type, Decl(a.js, 22, 1)) +>my.predicate.type : Symbol(my.predicate.type, Decl(a.js, 22, 1)) +>my.predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>my : Symbol(my, Decl(a.js, 0, 3), Decl(a.js, 0, 18), Decl(a.js, 7, 34), Decl(a.js, 12, 33)) +>predicate : Symbol(my.predicate, Decl(a.js, 6, 15), Decl(a.js, 8, 3), Decl(a.js, 13, 3)) +>type : Symbol(my.predicate.type, Decl(a.js, 22, 1)) m() { return 101; } >m : Symbol(type.m, Decl(a.js, 23, 27)) @@ -111,24 +111,24 @@ my.predicate.type = class { // global-ish prefixes var min = window.min || {}; ->min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44)) >window : Symbol(window, Decl(lib.dom.d.ts, --, --)) min.nest = this.min.nest || function () { }; ->min.nest : Symbol(nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) ->min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) ->nest : Symbol(nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>min.nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44)) +>nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) min.nest.other = self.min.nest.other || class { }; ->min.nest.other : Symbol(nest.other, Decl(a.js, 30, 44)) ->min.nest : Symbol(nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) ->min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) ->nest : Symbol(nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) ->other : Symbol(nest.other, Decl(a.js, 30, 44)) +>min.nest.other : Symbol(min.nest.other, Decl(a.js, 30, 44)) +>min.nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44)) +>nest : Symbol(min.nest, Decl(a.js, 29, 27), Decl(a.js, 31, 4)) +>other : Symbol(min.nest.other, Decl(a.js, 30, 44)) >self : Symbol(self, Decl(lib.dom.d.ts, --, --)) min.property = global.min.property || {}; ->min.property : Symbol(property, Decl(a.js, 31, 50)) ->min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44), Decl(a.js, 31, 50)) ->property : Symbol(property, Decl(a.js, 31, 50)) +>min.property : Symbol(min.property, Decl(a.js, 31, 50)) +>min : Symbol(min, Decl(a.js, 29, 3), Decl(a.js, 29, 27), Decl(a.js, 30, 44)) +>property : Symbol(min.property, Decl(a.js, 31, 50)) diff --git a/tests/baselines/reference/typeFromPropertyAssignmentOutOfOrder.symbols b/tests/baselines/reference/typeFromPropertyAssignmentOutOfOrder.symbols index bb187808b32..59b42c24737 100644 --- a/tests/baselines/reference/typeFromPropertyAssignmentOutOfOrder.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignmentOutOfOrder.symbols @@ -1,24 +1,24 @@ === tests/cases/conformance/salsa/index.js === Common.Item = class I {} >Common.Item : Symbol(Common.Item, Decl(index.js, 0, 0)) ->Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3), Decl(roots.js, 0, 12)) +>Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3)) >Item : Symbol(Common.Item, Decl(index.js, 0, 0)) >I : Symbol(I, Decl(index.js, 0, 13)) Common.Object = class extends Common.Item {} >Common.Object : Symbol(Common.Object, Decl(index.js, 0, 24)) ->Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3), Decl(roots.js, 0, 12)) +>Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3)) >Object : Symbol(Common.Object, Decl(index.js, 0, 24)) >Common.Item : Symbol(Common.Item, Decl(index.js, 0, 0)) ->Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3), Decl(roots.js, 0, 12)) +>Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3)) >Item : Symbol(Common.Item, Decl(index.js, 0, 0)) Workspace.Object = class extends Common.Object {} >Workspace.Object : Symbol(Workspace.Object, Decl(index.js, 1, 44)) ->Workspace : Symbol(Workspace, Decl(index.js, 1, 44), Decl(roots.js, 1, 3), Decl(roots.js, 1, 15)) +>Workspace : Symbol(Workspace, Decl(index.js, 1, 44), Decl(roots.js, 1, 3)) >Object : Symbol(Workspace.Object, Decl(index.js, 1, 44)) >Common.Object : Symbol(Common.Object, Decl(index.js, 0, 24)) ->Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3), Decl(roots.js, 0, 12)) +>Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3)) >Object : Symbol(Common.Object, Decl(index.js, 0, 24)) /** @type {Workspace.Object} */ @@ -27,8 +27,8 @@ var am; === tests/cases/conformance/salsa/roots.js === var Common = {}; ->Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3), Decl(roots.js, 0, 12)) +>Common : Symbol(Common, Decl(index.js, 0, 0), Decl(roots.js, 0, 3)) var Workspace = {}; ->Workspace : Symbol(Workspace, Decl(index.js, 1, 44), Decl(roots.js, 1, 3), Decl(roots.js, 1, 15)) +>Workspace : Symbol(Workspace, Decl(index.js, 1, 44), Decl(roots.js, 1, 3)) diff --git a/tests/baselines/reference/typeFromPropertyAssignmentWithExport.symbols b/tests/baselines/reference/typeFromPropertyAssignmentWithExport.symbols index 8120c3bbaef..6dcf8532f1e 100644 --- a/tests/baselines/reference/typeFromPropertyAssignmentWithExport.symbols +++ b/tests/baselines/reference/typeFromPropertyAssignmentWithExport.symbols @@ -2,16 +2,16 @@ // this is a javascript file... export const Adapter = {}; ->Adapter : Symbol(Adapter, Decl(a.js, 2, 12), Decl(a.js, 2, 26), Decl(a.js, 4, 18)) +>Adapter : Symbol(Adapter, Decl(a.js, 2, 12), Decl(a.js, 2, 26)) Adapter.prop = {}; ->Adapter.prop : Symbol(prop, Decl(a.js, 2, 26)) ->Adapter : Symbol(Adapter, Decl(a.js, 2, 12), Decl(a.js, 2, 26), Decl(a.js, 4, 18)) ->prop : Symbol(prop, Decl(a.js, 2, 26)) +>Adapter.prop : Symbol(Adapter.prop, Decl(a.js, 2, 26)) +>Adapter : Symbol(Adapter, Decl(a.js, 2, 12), Decl(a.js, 2, 26)) +>prop : Symbol(Adapter.prop, Decl(a.js, 2, 26)) // comment this out, and it works Adapter.asyncMethod = function() {} ->Adapter.asyncMethod : Symbol(asyncMethod, Decl(a.js, 4, 18)) ->Adapter : Symbol(Adapter, Decl(a.js, 2, 12), Decl(a.js, 2, 26), Decl(a.js, 4, 18)) ->asyncMethod : Symbol(asyncMethod, Decl(a.js, 4, 18)) +>Adapter.asyncMethod : Symbol(Adapter.asyncMethod, Decl(a.js, 4, 18)) +>Adapter : Symbol(Adapter, Decl(a.js, 2, 12), Decl(a.js, 2, 26)) +>asyncMethod : Symbol(Adapter.asyncMethod, Decl(a.js, 4, 18)) diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfFunction.js b/tests/baselines/reference/typeGuardOfFormTypeOfFunction.js new file mode 100644 index 00000000000..2dfff84c36b --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormTypeOfFunction.js @@ -0,0 +1,139 @@ +//// [typeGuardOfFormTypeOfFunction.ts] +function f1(x: any) { + if (typeof x === "function") { + x; // any + } +} + +function f2(x: unknown) { + if (typeof x === "function") { + x; // Function + } +} + +function f3(x: {}) { + if (typeof x === "function") { + x; // Function + } +} + +function f4(x: T) { + if (typeof x === "function") { + x; // T & Function + } +} + +function f5(x: { s: string }) { + if (typeof x === "function") { + x; // never + } +} + +function f6(x: () => string) { + if (typeof x === "function") { + x; // () => string + } +} + +function f10(x: string | (() => string)) { + if (typeof x === "function") { + x; // () => string + } + else { + x; // string + } +} + +function f11(x: { s: string } | (() => string)) { + if (typeof x === "function") { + x; // () => string + } + else { + x; // { s: string } + } +} + +function f12(x: { s: string } | { n: number }) { + if (typeof x === "function") { + x; // never + } + else { + x; // { s: string } | { n: number } + } +} + +// Repro from #18238 + +function f100(obj: T, keys: K[]) : void { + for (const k of keys) { + const item = obj[k]; + if (typeof item == 'function') + item.call(obj); + } +} + + +//// [typeGuardOfFormTypeOfFunction.js] +function f1(x) { + if (typeof x === "function") { + x; // any + } +} +function f2(x) { + if (typeof x === "function") { + x; // Function + } +} +function f3(x) { + if (typeof x === "function") { + x; // Function + } +} +function f4(x) { + if (typeof x === "function") { + x; // T & Function + } +} +function f5(x) { + if (typeof x === "function") { + x; // never + } +} +function f6(x) { + if (typeof x === "function") { + x; // () => string + } +} +function f10(x) { + if (typeof x === "function") { + x; // () => string + } + else { + x; // string + } +} +function f11(x) { + if (typeof x === "function") { + x; // () => string + } + else { + x; // { s: string } + } +} +function f12(x) { + if (typeof x === "function") { + x; // never + } + else { + x; // { s: string } | { n: number } + } +} +// Repro from #18238 +function f100(obj, keys) { + for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) { + var k = keys_1[_i]; + var item = obj[k]; + if (typeof item == 'function') + item.call(obj); + } +} diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfFunction.symbols b/tests/baselines/reference/typeGuardOfFormTypeOfFunction.symbols new file mode 100644 index 00000000000..fa9e9ff515b --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormTypeOfFunction.symbols @@ -0,0 +1,159 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfFunction.ts === +function f1(x: any) { +>f1 : Symbol(f1, Decl(typeGuardOfFormTypeOfFunction.ts, 0, 0)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 0, 12)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 0, 12)) + + x; // any +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 0, 12)) + } +} + +function f2(x: unknown) { +>f2 : Symbol(f2, Decl(typeGuardOfFormTypeOfFunction.ts, 4, 1)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 6, 12)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 6, 12)) + + x; // Function +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 6, 12)) + } +} + +function f3(x: {}) { +>f3 : Symbol(f3, Decl(typeGuardOfFormTypeOfFunction.ts, 10, 1)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 12, 12)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 12, 12)) + + x; // Function +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 12, 12)) + } +} + +function f4(x: T) { +>f4 : Symbol(f4, Decl(typeGuardOfFormTypeOfFunction.ts, 16, 1)) +>T : Symbol(T, Decl(typeGuardOfFormTypeOfFunction.ts, 18, 12)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 18, 15)) +>T : Symbol(T, Decl(typeGuardOfFormTypeOfFunction.ts, 18, 12)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 18, 15)) + + x; // T & Function +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 18, 15)) + } +} + +function f5(x: { s: string }) { +>f5 : Symbol(f5, Decl(typeGuardOfFormTypeOfFunction.ts, 22, 1)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 24, 12)) +>s : Symbol(s, Decl(typeGuardOfFormTypeOfFunction.ts, 24, 16)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 24, 12)) + + x; // never +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 24, 12)) + } +} + +function f6(x: () => string) { +>f6 : Symbol(f6, Decl(typeGuardOfFormTypeOfFunction.ts, 28, 1)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 30, 12)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 30, 12)) + + x; // () => string +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 30, 12)) + } +} + +function f10(x: string | (() => string)) { +>f10 : Symbol(f10, Decl(typeGuardOfFormTypeOfFunction.ts, 34, 1)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 36, 13)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 36, 13)) + + x; // () => string +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 36, 13)) + } + else { + x; // string +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 36, 13)) + } +} + +function f11(x: { s: string } | (() => string)) { +>f11 : Symbol(f11, Decl(typeGuardOfFormTypeOfFunction.ts, 43, 1)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 45, 13)) +>s : Symbol(s, Decl(typeGuardOfFormTypeOfFunction.ts, 45, 17)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 45, 13)) + + x; // () => string +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 45, 13)) + } + else { + x; // { s: string } +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 45, 13)) + } +} + +function f12(x: { s: string } | { n: number }) { +>f12 : Symbol(f12, Decl(typeGuardOfFormTypeOfFunction.ts, 52, 1)) +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 54, 13)) +>s : Symbol(s, Decl(typeGuardOfFormTypeOfFunction.ts, 54, 17)) +>n : Symbol(n, Decl(typeGuardOfFormTypeOfFunction.ts, 54, 33)) + + if (typeof x === "function") { +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 54, 13)) + + x; // never +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 54, 13)) + } + else { + x; // { s: string } | { n: number } +>x : Symbol(x, Decl(typeGuardOfFormTypeOfFunction.ts, 54, 13)) + } +} + +// Repro from #18238 + +function f100(obj: T, keys: K[]) : void { +>f100 : Symbol(f100, Decl(typeGuardOfFormTypeOfFunction.ts, 61, 1)) +>T : Symbol(T, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 14)) +>K : Symbol(K, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 16)) +>T : Symbol(T, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 14)) +>obj : Symbol(obj, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 36)) +>T : Symbol(T, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 14)) +>keys : Symbol(keys, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 43)) +>K : Symbol(K, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 16)) + + for (const k of keys) { +>k : Symbol(k, Decl(typeGuardOfFormTypeOfFunction.ts, 66, 14)) +>keys : Symbol(keys, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 43)) + + const item = obj[k]; +>item : Symbol(item, Decl(typeGuardOfFormTypeOfFunction.ts, 67, 13)) +>obj : Symbol(obj, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 36)) +>k : Symbol(k, Decl(typeGuardOfFormTypeOfFunction.ts, 66, 14)) + + if (typeof item == 'function') +>item : Symbol(item, Decl(typeGuardOfFormTypeOfFunction.ts, 67, 13)) + + item.call(obj); +>item.call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>item : Symbol(item, Decl(typeGuardOfFormTypeOfFunction.ts, 67, 13)) +>call : Symbol(Function.call, Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(typeGuardOfFormTypeOfFunction.ts, 65, 36)) + } +} + diff --git a/tests/baselines/reference/typeGuardOfFormTypeOfFunction.types b/tests/baselines/reference/typeGuardOfFormTypeOfFunction.types new file mode 100644 index 00000000000..1aa667abdcc --- /dev/null +++ b/tests/baselines/reference/typeGuardOfFormTypeOfFunction.types @@ -0,0 +1,191 @@ +=== tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfFunction.ts === +function f1(x: any) { +>f1 : (x: any) => void +>x : any + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : any +>"function" : "function" + + x; // any +>x : any + } +} + +function f2(x: unknown) { +>f2 : (x: unknown) => void +>x : unknown + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : unknown +>"function" : "function" + + x; // Function +>x : Function + } +} + +function f3(x: {}) { +>f3 : (x: {}) => void +>x : {} + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : {} +>"function" : "function" + + x; // Function +>x : Function + } +} + +function f4(x: T) { +>f4 : (x: T) => void +>T : T +>x : T +>T : T + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : T +>"function" : "function" + + x; // T & Function +>x : T & Function + } +} + +function f5(x: { s: string }) { +>f5 : (x: { s: string; }) => void +>x : { s: string; } +>s : string + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : { s: string; } +>"function" : "function" + + x; // never +>x : never + } +} + +function f6(x: () => string) { +>f6 : (x: () => string) => void +>x : () => string + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : () => string +>"function" : "function" + + x; // () => string +>x : () => string + } +} + +function f10(x: string | (() => string)) { +>f10 : (x: string | (() => string)) => void +>x : string | (() => string) + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : string | (() => string) +>"function" : "function" + + x; // () => string +>x : () => string + } + else { + x; // string +>x : string + } +} + +function f11(x: { s: string } | (() => string)) { +>f11 : (x: { s: string; } | (() => string)) => void +>x : { s: string; } | (() => string) +>s : string + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : { s: string; } | (() => string) +>"function" : "function" + + x; // () => string +>x : () => string + } + else { + x; // { s: string } +>x : { s: string; } + } +} + +function f12(x: { s: string } | { n: number }) { +>f12 : (x: { s: string; } | { n: number; }) => void +>x : { s: string; } | { n: number; } +>s : string +>n : number + + if (typeof x === "function") { +>typeof x === "function" : boolean +>typeof x : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>x : { s: string; } | { n: number; } +>"function" : "function" + + x; // never +>x : never + } + else { + x; // { s: string } | { n: number } +>x : { s: string; } | { n: number; } + } +} + +// Repro from #18238 + +function f100(obj: T, keys: K[]) : void { +>f100 : (obj: T, keys: K[]) => void +>T : T +>K : K +>T : T +>obj : T +>T : T +>keys : K[] +>K : K + + for (const k of keys) { +>k : K +>keys : K[] + + const item = obj[k]; +>item : T[K] +>obj[k] : T[K] +>obj : T +>k : K + + if (typeof item == 'function') +>typeof item == 'function' : boolean +>typeof item : "string" | "number" | "boolean" | "symbol" | "undefined" | "object" | "function" +>item : T[K] +>'function' : "function" + + item.call(obj); +>item.call(obj) : any +>item.call : (this: Function, thisArg: any, ...argArray: any[]) => any +>item : T[K] & Function +>call : (this: Function, thisArg: any, ...argArray: any[]) => any +>obj : T + } +} + diff --git a/tests/baselines/reference/typeLookupInIIFE.errors.txt b/tests/baselines/reference/typeLookupInIIFE.errors.txt new file mode 100644 index 00000000000..9e95cb4f11a --- /dev/null +++ b/tests/baselines/reference/typeLookupInIIFE.errors.txt @@ -0,0 +1,11 @@ +tests/cases/conformance/salsa/a.js(3,15): error TS2694: Namespace 'ns' has no exported member 'NotFound'. + + +==== tests/cases/conformance/salsa/a.js (1 errors) ==== + // #22973 + var ns = (function() {})(); + /** @type {ns.NotFound} */ + ~~~~~~~~ +!!! error TS2694: Namespace 'ns' has no exported member 'NotFound'. + var crash; + \ No newline at end of file diff --git a/tests/baselines/reference/typedefCrossModule3.symbols b/tests/baselines/reference/typedefCrossModule3.symbols index 3e1c8a55535..b41b278b0c3 100644 --- a/tests/baselines/reference/typedefCrossModule3.symbols +++ b/tests/baselines/reference/typedefCrossModule3.symbols @@ -4,9 +4,9 @@ const ns = {}; >ns : Symbol(ns, Decl(mod2.js, 1, 5), Decl(mod2.js, 1, 14)) ns.Foo = class {} ->ns.Foo : Symbol(Foo, Decl(mod2.js, 1, 14)) +>ns.Foo : Symbol(ns.Foo, Decl(mod2.js, 1, 14)) >ns : Symbol(ns, Decl(mod2.js, 1, 5), Decl(mod2.js, 1, 14)) ->Foo : Symbol(Foo, Decl(mod2.js, 1, 14)) +>Foo : Symbol(ns.Foo, Decl(mod2.js, 1, 14)) module.exports = ns; >module : Symbol(export=, Decl(mod2.js, 2, 17)) diff --git a/tests/baselines/reference/typedefMultipleTypeParameters.errors.txt b/tests/baselines/reference/typedefMultipleTypeParameters.errors.txt new file mode 100644 index 00000000000..e8d0e52ba0f --- /dev/null +++ b/tests/baselines/reference/typedefMultipleTypeParameters.errors.txt @@ -0,0 +1,32 @@ +tests/cases/conformance/jsdoc/a.js(16,12): error TS2314: Generic type 'Everything' requires 5 type argument(s). +tests/cases/conformance/jsdoc/test.ts(1,34): error TS2344: Type '{ a: number; }' does not satisfy the constraint '{ a: number; b: string; }'. + Property 'b' is missing in type '{ a: number; }'. + + +==== tests/cases/conformance/jsdoc/a.js (1 errors) ==== + /** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @typedef {{ t: T, u: U, v: V, w: W, x: X }} Everything + */ + + /** @type {Everything<{ a: number, b: 'hi', c: never }, undefined, { c: true, d: 1 }, number, string>} */ + var tuvwx; + + // TODO: will error when #24592 is fixed + /** @type {Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>} */ + var wrong; + + /** @type {Everything<{ a: number }>} */ + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2314: Generic type 'Everything' requires 5 type argument(s). + var insufficient; + +==== tests/cases/conformance/jsdoc/test.ts (1 errors) ==== + declare var actually: Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>; + ~~~~~~~~~~~~~~ +!!! error TS2344: Type '{ a: number; }' does not satisfy the constraint '{ a: number; b: string; }'. +!!! error TS2344: Property 'b' is missing in type '{ a: number; }'. + \ No newline at end of file diff --git a/tests/baselines/reference/typedefMultipleTypeParameters.symbols b/tests/baselines/reference/typedefMultipleTypeParameters.symbols new file mode 100644 index 00000000000..9acd30fea1b --- /dev/null +++ b/tests/baselines/reference/typedefMultipleTypeParameters.symbols @@ -0,0 +1,30 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @typedef {{ t: T, u: U, v: V, w: W, x: X }} Everything + */ + +/** @type {Everything<{ a: number, b: 'hi', c: never }, undefined, { c: true, d: 1 }, number, string>} */ +var tuvwx; +>tuvwx : Symbol(tuvwx, Decl(a.js, 9, 3)) + +// TODO: will error when #24592 is fixed +/** @type {Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>} */ +var wrong; +>wrong : Symbol(wrong, Decl(a.js, 13, 3)) + +/** @type {Everything<{ a: number }>} */ +var insufficient; +>insufficient : Symbol(insufficient, Decl(a.js, 16, 3)) + +=== tests/cases/conformance/jsdoc/test.ts === +declare var actually: Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>; +>actually : Symbol(actually, Decl(test.ts, 0, 11)) +>Everything : Symbol(Everything, Decl(a.js, 5, 3)) +>a : Symbol(a, Decl(test.ts, 0, 34)) +>c : Symbol(c, Decl(test.ts, 0, 61)) +>d : Symbol(d, Decl(test.ts, 0, 67)) + diff --git a/tests/baselines/reference/typedefMultipleTypeParameters.types b/tests/baselines/reference/typedefMultipleTypeParameters.types new file mode 100644 index 00000000000..5bc38bb835b --- /dev/null +++ b/tests/baselines/reference/typedefMultipleTypeParameters.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/jsdoc/a.js === +/** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @typedef {{ t: T, u: U, v: V, w: W, x: X }} Everything + */ + +/** @type {Everything<{ a: number, b: 'hi', c: never }, undefined, { c: true, d: 1 }, number, string>} */ +var tuvwx; +>tuvwx : { t: { a: number; b: "hi"; c: never; }; u: undefined; v: { c: true; d: 1; }; w: number; x: string; } + +// TODO: will error when #24592 is fixed +/** @type {Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>} */ +var wrong; +>wrong : { t: { a: number; }; u: undefined; v: { c: 1; d: 1; }; w: number; x: string; } + +/** @type {Everything<{ a: number }>} */ +var insufficient; +>insufficient : any + +=== tests/cases/conformance/jsdoc/test.ts === +declare var actually: Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>; +>actually : { t: { a: number; }; u: undefined; v: { c: 1; d: 1; }; w: number; x: string; } +>Everything : { t: T; u: U; v: V; w: W; x: X; } +>a : number +>c : 1 +>d : 1 + diff --git a/tests/baselines/reference/uniqueSymbols.symbols b/tests/baselines/reference/uniqueSymbols.symbols index e4c84dd12ff..6fef1873082 100644 --- a/tests/baselines/reference/uniqueSymbols.symbols +++ b/tests/baselines/reference/uniqueSymbols.symbols @@ -2,15 +2,15 @@ // declarations with call initializer const constCall = Symbol(); >constCall : Symbol(constCall, Decl(uniqueSymbols.ts, 1, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) let letCall = Symbol(); >letCall : Symbol(letCall, Decl(uniqueSymbols.ts, 2, 3)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) var varCall = Symbol(); >varCall : Symbol(varCall, Decl(uniqueSymbols.ts, 3, 3)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) // ambient declaration with type declare const constType: unique symbol; @@ -19,7 +19,7 @@ declare const constType: unique symbol; // declaration with type and call initializer const constTypeAndCall: unique symbol = Symbol(); >constTypeAndCall : Symbol(constTypeAndCall, Decl(uniqueSymbols.ts, 9, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) // declaration from initializer const constInitToConstCall = constCall; @@ -152,26 +152,26 @@ class C { static readonly readonlyStaticCall = Symbol(); >readonlyStaticCall : Symbol(C.readonlyStaticCall, Decl(uniqueSymbols.ts, 56, 9)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) static readonly readonlyStaticType: unique symbol; >readonlyStaticType : Symbol(C.readonlyStaticType, Decl(uniqueSymbols.ts, 57, 50)) static readonly readonlyStaticTypeAndCall: unique symbol = Symbol(); >readonlyStaticTypeAndCall : Symbol(C.readonlyStaticTypeAndCall, Decl(uniqueSymbols.ts, 58, 54)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) static readwriteStaticCall = Symbol(); >readwriteStaticCall : Symbol(C.readwriteStaticCall, Decl(uniqueSymbols.ts, 59, 72)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) readonly readonlyCall = Symbol(); >readonlyCall : Symbol(C.readonlyCall, Decl(uniqueSymbols.ts, 60, 42)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) readwriteCall = Symbol(); >readwriteCall : Symbol(C.readwriteCall, Decl(uniqueSymbols.ts, 62, 37)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) } declare const c: C; >c : Symbol(c, Decl(uniqueSymbols.ts, 65, 13)) diff --git a/tests/baselines/reference/uniqueSymbolsDeclarations.symbols b/tests/baselines/reference/uniqueSymbolsDeclarations.symbols index eecee05a306..485b31af0fd 100644 --- a/tests/baselines/reference/uniqueSymbolsDeclarations.symbols +++ b/tests/baselines/reference/uniqueSymbolsDeclarations.symbols @@ -2,15 +2,15 @@ // declarations with call initializer const constCall = Symbol(); >constCall : Symbol(constCall, Decl(uniqueSymbolsDeclarations.ts, 1, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) let letCall = Symbol(); >letCall : Symbol(letCall, Decl(uniqueSymbolsDeclarations.ts, 2, 3)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) var varCall = Symbol(); >varCall : Symbol(varCall, Decl(uniqueSymbolsDeclarations.ts, 3, 3)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) // ambient declaration with type declare const constType: unique symbol; @@ -19,7 +19,7 @@ declare const constType: unique symbol; // declaration with type and call initializer const constTypeAndCall: unique symbol = Symbol(); >constTypeAndCall : Symbol(constTypeAndCall, Decl(uniqueSymbolsDeclarations.ts, 9, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) // declaration from initializer const constInitToConstCall = constCall; @@ -152,26 +152,26 @@ class C { static readonly readonlyStaticCall = Symbol(); >readonlyStaticCall : Symbol(C.readonlyStaticCall, Decl(uniqueSymbolsDeclarations.ts, 56, 9)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) static readonly readonlyStaticType: unique symbol; >readonlyStaticType : Symbol(C.readonlyStaticType, Decl(uniqueSymbolsDeclarations.ts, 57, 50)) static readonly readonlyStaticTypeAndCall: unique symbol = Symbol(); >readonlyStaticTypeAndCall : Symbol(C.readonlyStaticTypeAndCall, Decl(uniqueSymbolsDeclarations.ts, 58, 54)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) static readwriteStaticCall = Symbol(); >readwriteStaticCall : Symbol(C.readwriteStaticCall, Decl(uniqueSymbolsDeclarations.ts, 59, 72)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) readonly readonlyCall = Symbol(); >readonlyCall : Symbol(C.readonlyCall, Decl(uniqueSymbolsDeclarations.ts, 60, 42)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) readwriteCall = Symbol(); >readwriteCall : Symbol(C.readwriteCall, Decl(uniqueSymbolsDeclarations.ts, 62, 37)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) } declare const c: C; >c : Symbol(c, Decl(uniqueSymbolsDeclarations.ts, 65, 13)) diff --git a/tests/baselines/reference/uniqueSymbolsErrors.symbols b/tests/baselines/reference/uniqueSymbolsErrors.symbols index 8f47912956e..affcd6f096b 100644 --- a/tests/baselines/reference/uniqueSymbolsErrors.symbols +++ b/tests/baselines/reference/uniqueSymbolsErrors.symbols @@ -238,5 +238,5 @@ declare const invalidIntersection: unique symbol | unique symbol; // https://github.com/Microsoft/TypeScript/issues/21584 const shouldNotBeAssignable: string = Symbol(); >shouldNotBeAssignable : Symbol(shouldNotBeAssignable, Decl(uniqueSymbolsErrors.ts, 86, 5)) ->Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.esnext.symbol.d.ts, --, --)) diff --git a/tests/baselines/reference/unusedClassesinModule1.errors.txt b/tests/baselines/reference/unusedClassesinModule1.errors.txt index 488c434c537..663955b2750 100644 --- a/tests/baselines/reference/unusedClassesinModule1.errors.txt +++ b/tests/baselines/reference/unusedClassesinModule1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedClassesinModule1.ts(2,5): error TS6196: 'Calculator' is declared but never used. +tests/cases/compiler/unusedClassesinModule1.ts(2,11): error TS6196: 'Calculator' is declared but never used. ==== tests/cases/compiler/unusedClassesinModule1.ts (1 errors) ==== module A { class Calculator { - ~~~~~~~~~~~~~~~~ + ~~~~~~~~~~ !!! error TS6196: 'Calculator' is declared but never used. public handelChar() { } diff --git a/tests/baselines/reference/unusedClassesinNamespace1.errors.txt b/tests/baselines/reference/unusedClassesinNamespace1.errors.txt index 44050f75b54..10a2d2b1204 100644 --- a/tests/baselines/reference/unusedClassesinNamespace1.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedClassesinNamespace1.ts(2,5): error TS6196: 'c1' is declared but never used. +tests/cases/compiler/unusedClassesinNamespace1.ts(2,11): error TS6196: 'c1' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace1.ts (1 errors) ==== namespace Validation { class c1 { - ~~~~~~~~ + ~~ !!! error TS6196: 'c1' is declared but never used. } diff --git a/tests/baselines/reference/unusedClassesinNamespace2.errors.txt b/tests/baselines/reference/unusedClassesinNamespace2.errors.txt index 6c6f5f815b6..d69339f212e 100644 --- a/tests/baselines/reference/unusedClassesinNamespace2.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace2.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedClassesinNamespace2.ts(2,5): error TS6196: 'c1' is declared but never used. +tests/cases/compiler/unusedClassesinNamespace2.ts(2,11): error TS6196: 'c1' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace2.ts (1 errors) ==== namespace Validation { class c1 { - ~~~~~~~~ + ~~ !!! error TS6196: 'c1' is declared but never used. } diff --git a/tests/baselines/reference/unusedClassesinNamespace4.errors.txt b/tests/baselines/reference/unusedClassesinNamespace4.errors.txt index 209654569c9..ad869daed7d 100644 --- a/tests/baselines/reference/unusedClassesinNamespace4.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace4.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6196: 'c3' is declared but never used. +tests/cases/compiler/unusedClassesinNamespace4.ts(10,11): error TS6196: 'c3' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace4.ts (1 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/unusedClassesinNamespace4.ts(10,5): error TS6196: 'c3' is d } class c3 extends c1 { - ~~~~~~~~ + ~~ !!! error TS6196: 'c3' is declared but never used. } diff --git a/tests/baselines/reference/unusedClassesinNamespace5.errors.txt b/tests/baselines/reference/unusedClassesinNamespace5.errors.txt index 58cfa661603..cc4798de010 100644 --- a/tests/baselines/reference/unusedClassesinNamespace5.errors.txt +++ b/tests/baselines/reference/unusedClassesinNamespace5.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6196: 'c3' is declared but never used. +tests/cases/compiler/unusedClassesinNamespace5.ts(10,11): error TS6196: 'c3' is declared but never used. ==== tests/cases/compiler/unusedClassesinNamespace5.ts (1 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/unusedClassesinNamespace5.ts(10,5): error TS6196: 'c3' is d } class c3 { - ~~~~~~~~ + ~~ !!! error TS6196: 'c3' is declared but never used. public x: c1; } diff --git a/tests/baselines/reference/unusedDestructuring.errors.txt b/tests/baselines/reference/unusedDestructuring.errors.txt index 67b97697323..14f71a459ab 100644 --- a/tests/baselines/reference/unusedDestructuring.errors.txt +++ b/tests/baselines/reference/unusedDestructuring.errors.txt @@ -3,7 +3,7 @@ tests/cases/compiler/unusedDestructuring.ts(4,9): error TS6133: 'c' is declared tests/cases/compiler/unusedDestructuring.ts(6,7): error TS6133: 'e' is declared but its value is never read. tests/cases/compiler/unusedDestructuring.ts(7,7): error TS6133: 'g' is declared but its value is never read. tests/cases/compiler/unusedDestructuring.ts(8,1): error TS6199: All variables are unused. -tests/cases/compiler/unusedDestructuring.ts(10,1): error TS6133: 'f' is declared but its value is never read. +tests/cases/compiler/unusedDestructuring.ts(10,10): error TS6133: 'f' is declared but its value is never read. tests/cases/compiler/unusedDestructuring.ts(10,12): error TS6198: All destructured elements are unused. tests/cases/compiler/unusedDestructuring.ts(10,24): error TS6133: 'c' is declared but its value is never read. tests/cases/compiler/unusedDestructuring.ts(10,32): error TS6133: 'e' is declared but its value is never read. @@ -30,7 +30,7 @@ tests/cases/compiler/unusedDestructuring.ts(10,32): error TS6133: 'e' is declare !!! error TS6199: All variables are unused. function f({ a, b }, { c, d }, { e }) { - ~~~~~~~~~~ + ~ !!! error TS6133: 'f' is declared but its value is never read. ~~~~~~~~ !!! error TS6198: All destructured elements are unused. diff --git a/tests/baselines/reference/unusedFunctionsinNamespaces1.errors.txt b/tests/baselines/reference/unusedFunctionsinNamespaces1.errors.txt index 7dee9ad0723..202977c6fb7 100644 --- a/tests/baselines/reference/unusedFunctionsinNamespaces1.errors.txt +++ b/tests/baselines/reference/unusedFunctionsinNamespaces1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedFunctionsinNamespaces1.ts(2,5): error TS6133: 'function1' is declared but its value is never read. +tests/cases/compiler/unusedFunctionsinNamespaces1.ts(2,14): error TS6133: 'function1' is declared but its value is never read. ==== tests/cases/compiler/unusedFunctionsinNamespaces1.ts (1 errors) ==== namespace Validation { function function1() { - ~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~ !!! error TS6133: 'function1' is declared but its value is never read. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedFunctionsinNamespaces5.errors.txt b/tests/baselines/reference/unusedFunctionsinNamespaces5.errors.txt index 07f22fa39dc..8f7f617e559 100644 --- a/tests/baselines/reference/unusedFunctionsinNamespaces5.errors.txt +++ b/tests/baselines/reference/unusedFunctionsinNamespaces5.errors.txt @@ -1,5 +1,5 @@ -tests/cases/compiler/unusedFunctionsinNamespaces5.ts(9,5): error TS6133: 'function3' is declared but its value is never read. -tests/cases/compiler/unusedFunctionsinNamespaces5.ts(13,5): error TS6133: 'function4' is declared but its value is never read. +tests/cases/compiler/unusedFunctionsinNamespaces5.ts(9,14): error TS6133: 'function3' is declared but its value is never read. +tests/cases/compiler/unusedFunctionsinNamespaces5.ts(13,14): error TS6133: 'function4' is declared but its value is never read. ==== tests/cases/compiler/unusedFunctionsinNamespaces5.ts (2 errors) ==== @@ -12,13 +12,13 @@ tests/cases/compiler/unusedFunctionsinNamespaces5.ts(13,5): error TS6133: 'funct } function function3() { - ~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~ !!! error TS6133: 'function3' is declared but its value is never read. function1(); } function function4() { - ~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~ !!! error TS6133: 'function4' is declared but its value is never read. } diff --git a/tests/baselines/reference/unusedFunctionsinNamespaces6.errors.txt b/tests/baselines/reference/unusedFunctionsinNamespaces6.errors.txt index fe84d72524e..de5f7ae4d87 100644 --- a/tests/baselines/reference/unusedFunctionsinNamespaces6.errors.txt +++ b/tests/baselines/reference/unusedFunctionsinNamespaces6.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedFunctionsinNamespaces6.ts(13,5): error TS6133: 'function4' is declared but its value is never read. +tests/cases/compiler/unusedFunctionsinNamespaces6.ts(13,14): error TS6133: 'function4' is declared but its value is never read. ==== tests/cases/compiler/unusedFunctionsinNamespaces6.ts (1 errors) ==== @@ -15,7 +15,7 @@ tests/cases/compiler/unusedFunctionsinNamespaces6.ts(13,5): error TS6133: 'funct } function function4() { - ~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~ !!! error TS6133: 'function4' is declared but its value is never read. } diff --git a/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt b/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt index 3ddd1f12b1b..c100fed6949 100644 --- a/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt +++ b/tests/baselines/reference/unusedIdentifiersConsolidated1.errors.txt @@ -10,11 +10,11 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(17,13): error TS6133: 'un tests/cases/compiler/unusedIdentifiersConsolidated1.ts(24,13): error TS6133: 'unUsedPrivateFunction' is declared but its value is never read. tests/cases/compiler/unusedIdentifiersConsolidated1.ts(37,11): error TS6133: 'numberRegexp' is declared but its value is never read. tests/cases/compiler/unusedIdentifiersConsolidated1.ts(44,17): error TS6133: 'unUsedPrivateFunction' is declared but its value is never read. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(57,5): error TS6196: 'usedLocallyInterface2' is declared but never used. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(64,5): error TS6196: 'dummy' is declared but never used. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(67,5): error TS6196: 'unusedInterface' is declared but never used. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(79,5): error TS6196: 'class3' is declared but never used. -tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6196: 'interface5' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(57,15): error TS6196: 'usedLocallyInterface2' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(64,11): error TS6196: 'dummy' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(67,15): error TS6196: 'unusedInterface' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(79,11): error TS6196: 'class3' is declared but never used. +tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,15): error TS6196: 'interface5' is declared but never used. ==== tests/cases/compiler/unusedIdentifiersConsolidated1.ts (17 errors) ==== @@ -99,7 +99,7 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6196: 'int } interface usedLocallyInterface2 { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~~~~~~~ !!! error TS6196: 'usedLocallyInterface2' is declared but never used. someFunction(s1: string): void; } @@ -108,12 +108,12 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6196: 'int } class dummy implements usedLocallyInterface { - ~~~~~~~~~~~ + ~~~~~ !!! error TS6196: 'dummy' is declared but never used. } interface unusedInterface { - ~~~~~~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~~~~~~ !!! error TS6196: 'unusedInterface' is declared but never used. } } @@ -127,7 +127,7 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6196: 'int } class class3 { - ~~~~~~~~~~~~ + ~~~~~~ !!! error TS6196: 'class3' is declared but never used. } @@ -149,7 +149,7 @@ tests/cases/compiler/unusedIdentifiersConsolidated1.ts(99,5): error TS6196: 'int export let a: interface3; interface interface5 { - ~~~~~~~~~~~~~~~~~~~~ + ~~~~~~~~~~ !!! error TS6196: 'interface5' is declared but never used. } } \ No newline at end of file diff --git a/tests/baselines/reference/unusedImports10.errors.txt b/tests/baselines/reference/unusedImports10.errors.txt index e6c405d221c..b9688a01185 100644 --- a/tests/baselines/reference/unusedImports10.errors.txt +++ b/tests/baselines/reference/unusedImports10.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedImports10.ts(9,5): error TS6133: 'a' is declared but its value is never read. +tests/cases/compiler/unusedImports10.ts(9,12): error TS6133: 'a' is declared but its value is never read. ==== tests/cases/compiler/unusedImports10.ts (1 errors) ==== @@ -11,6 +11,6 @@ tests/cases/compiler/unusedImports10.ts(9,5): error TS6133: 'a' is declared but module B { import a = A; - ~~~~~~~~ + ~ !!! error TS6133: 'a' is declared but its value is never read. } \ No newline at end of file diff --git a/tests/baselines/reference/unusedImports12.errors.txt b/tests/baselines/reference/unusedImports12.errors.txt index 5bdd99d6044..e3b6da00db8 100644 --- a/tests/baselines/reference/unusedImports12.errors.txt +++ b/tests/baselines/reference/unusedImports12.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/a.ts(1,1): error TS6133: 'Member' is declared but its value is never read. tests/cases/compiler/a.ts(2,1): error TS6192: All imports in import declaration are unused. tests/cases/compiler/a.ts(3,1): error TS6133: 'ns' is declared but its value is never read. -tests/cases/compiler/a.ts(4,1): error TS6133: 'r' is declared but its value is never read. +tests/cases/compiler/a.ts(4,8): error TS6133: 'r' is declared but its value is never read. ==== tests/cases/compiler/a.ts (4 errors) ==== @@ -15,7 +15,7 @@ tests/cases/compiler/a.ts(4,1): error TS6133: 'r' is declared but its value is n ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS6133: 'ns' is declared but its value is never read. import r = require("./b"); - ~~~~~~~~ + ~ !!! error TS6133: 'r' is declared but its value is never read. ==== tests/cases/compiler/b.ts (0 errors) ==== diff --git a/tests/baselines/reference/unusedImports8.errors.txt b/tests/baselines/reference/unusedImports8.errors.txt index 5cac8a8ee15..a6cbaae8ff6 100644 --- a/tests/baselines/reference/unusedImports8.errors.txt +++ b/tests/baselines/reference/unusedImports8.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/file2.ts(1,41): error TS6133: 't2' is declared but its value is never read. +tests/cases/compiler/file2.ts(1,50): error TS6133: 't2' is declared but its value is never read. ==== tests/cases/compiler/file1.ts (0 errors) ==== @@ -16,7 +16,7 @@ tests/cases/compiler/file2.ts(1,41): error TS6133: 't2' is declared but its valu ==== tests/cases/compiler/file2.ts (1 errors) ==== import {Calculator as calc, test as t1, test2 as t2} from "./file1" - ~~~~~~~~~~~ + ~~ !!! error TS6133: 't2' is declared but its value is never read. var x = new calc(); diff --git a/tests/baselines/reference/unusedImports9.errors.txt b/tests/baselines/reference/unusedImports9.errors.txt index 02bee34686e..2452962b289 100644 --- a/tests/baselines/reference/unusedImports9.errors.txt +++ b/tests/baselines/reference/unusedImports9.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/file2.ts(1,1): error TS6133: 'c' is declared but its value is never read. +tests/cases/compiler/file2.ts(1,8): error TS6133: 'c' is declared but its value is never read. ==== tests/cases/compiler/file2.ts (1 errors) ==== import c = require('./file1') - ~~~~~~~~ + ~ !!! error TS6133: 'c' is declared but its value is never read. ==== tests/cases/compiler/file1.ts (0 errors) ==== export class Calculator { diff --git a/tests/baselines/reference/unusedImports_entireImportDeclaration.errors.txt b/tests/baselines/reference/unusedImports_entireImportDeclaration.errors.txt index cd58ce714b0..d0418446be3 100644 --- a/tests/baselines/reference/unusedImports_entireImportDeclaration.errors.txt +++ b/tests/baselines/reference/unusedImports_entireImportDeclaration.errors.txt @@ -1,8 +1,8 @@ /b.ts(1,1): error TS6192: All imports in import declaration are unused. /b.ts(2,1): error TS6192: All imports in import declaration are unused. -/b.ts(4,14): error TS6133: 'a2' is declared but its value is never read. -/b.ts(4,23): error TS6133: 'b2' is declared but its value is never read. -/b.ts(6,12): error TS6133: 'ns2' is declared but its value is never read. +/b.ts(4,19): error TS6133: 'a2' is declared but its value is never read. +/b.ts(4,28): error TS6133: 'b2' is declared but its value is never read. +/b.ts(6,17): error TS6133: 'ns2' is declared but its value is never read. /b.ts(8,8): error TS6133: 'd5' is declared but its value is never read. @@ -20,13 +20,13 @@ !!! error TS6192: All imports in import declaration are unused. import d3, { a as a2, b as b2 } from "./a"; - ~~~~~~~ + ~~ !!! error TS6133: 'a2' is declared but its value is never read. - ~~~~~~~ + ~~ !!! error TS6133: 'b2' is declared but its value is never read. d3; import d4, * as ns2 from "./a"; - ~~~~~~~~ + ~~~ !!! error TS6133: 'ns2' is declared but its value is never read. d4; import d5, * as ns3 from "./a"; diff --git a/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt index 0fe77374c4d..0c134508ea7 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace1.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedInterfaceinNamespace1.ts(2,5): error TS6196: 'i1' is declared but never used. +tests/cases/compiler/unusedInterfaceinNamespace1.ts(2,15): error TS6196: 'i1' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace1.ts (1 errors) ==== namespace Validation { interface i1 { - ~~~~~~~~~~~~ + ~~ !!! error TS6196: 'i1' is declared but never used. } diff --git a/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt index 40e224358af..312e2db0aa2 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace2.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedInterfaceinNamespace2.ts(2,5): error TS6196: 'i1' is declared but never used. +tests/cases/compiler/unusedInterfaceinNamespace2.ts(2,15): error TS6196: 'i1' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace2.ts (1 errors) ==== namespace Validation { interface i1 { - ~~~~~~~~~~~~ + ~~ !!! error TS6196: 'i1' is declared but never used. } diff --git a/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt b/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt index 206dd51c3e5..7647932305f 100644 --- a/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt +++ b/tests/baselines/reference/unusedInterfaceinNamespace3.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6196: 'i3' is declared but never used. +tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,15): error TS6196: 'i3' is declared but never used. ==== tests/cases/compiler/unusedInterfaceinNamespace3.ts (1 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/unusedInterfaceinNamespace3.ts(10,5): error TS6196: 'i3' is } interface i3 extends i1 { - ~~~~~~~~~~~~ + ~~ !!! error TS6196: 'i3' is declared but never used. } diff --git a/tests/baselines/reference/unusedLocalsAndObjectSpread2.errors.txt b/tests/baselines/reference/unusedLocalsAndObjectSpread2.errors.txt index 100f86468ad..d675747fd04 100644 --- a/tests/baselines/reference/unusedLocalsAndObjectSpread2.errors.txt +++ b/tests/baselines/reference/unusedLocalsAndObjectSpread2.errors.txt @@ -1,5 +1,5 @@ tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(5,6): error TS6133: 'rest' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(8,1): error TS6133: 'foo' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(8,10): error TS6133: 'foo' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(12,12): error TS6133: 'rest' is declared but its value is never read. @@ -14,7 +14,7 @@ tests/cases/compiler/unusedLocalsAndObjectSpread2.ts(12,12): error TS6133: 'rest } = props; function foo() { - ~~~~~~~~~~~~ + ~~~ !!! error TS6133: 'foo' is declared but its value is never read. const { children, diff --git a/tests/baselines/reference/unusedLocalsAndParameters.errors.txt b/tests/baselines/reference/unusedLocalsAndParameters.errors.txt index e9656c6f669..2b07a5fac52 100644 --- a/tests/baselines/reference/unusedLocalsAndParameters.errors.txt +++ b/tests/baselines/reference/unusedLocalsAndParameters.errors.txt @@ -2,7 +2,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(4,12): error TS6133: 'a' is de tests/cases/compiler/unusedLocalsAndParameters.ts(9,22): error TS6133: 'a' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(15,5): error TS6133: 'farrow' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(15,15): error TS6133: 'a' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndParameters.ts(18,1): error TS6196: 'C' is declared but never used. +tests/cases/compiler/unusedLocalsAndParameters.ts(18,7): error TS6196: 'C' is declared but never used. tests/cases/compiler/unusedLocalsAndParameters.ts(20,12): error TS6133: 'a' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(23,9): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher. tests/cases/compiler/unusedLocalsAndParameters.ts(23,11): error TS6133: 'v' is declared but its value is never read. @@ -20,7 +20,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(63,11): error TS6133: 'c' is d tests/cases/compiler/unusedLocalsAndParameters.ts(68,11): error TS6133: 'a' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(71,11): error TS6133: 'c' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(74,11): error TS6133: 'c' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndParameters.ts(79,1): error TS6133: 'N' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParameters.ts(79,11): error TS6133: 'N' is declared but its value is never read. tests/cases/compiler/unusedLocalsAndParameters.ts(80,9): error TS6133: 'x' is declared but its value is never read. @@ -51,7 +51,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(80,9): error TS6133: 'x' is de }; class C { - ~~~~~~~ + ~ !!! error TS6196: 'C' is declared but never used. // Method declaration paramter method(a) { @@ -148,7 +148,7 @@ tests/cases/compiler/unusedLocalsAndParameters.ts(80,9): error TS6133: 'x' is de // in a namespace namespace N { - ~~~~~~~~~~~ + ~ !!! error TS6133: 'N' is declared but its value is never read. var x; ~ diff --git a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt index f86ec0d1cc7..de03f17fa46 100644 --- a/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt +++ b/tests/baselines/reference/unusedLocalsAndParametersTypeAliases2.errors.txt @@ -1,20 +1,20 @@ -tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(2,1): error TS6196: 'handler1' is declared but never used. -tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(5,1): error TS6133: 'foo' is declared but its value is never read. -tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,5): error TS6196: 'handler2' is declared but never used. +tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(2,6): error TS6196: 'handler1' is declared but never used. +tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(5,10): error TS6133: 'foo' is declared but its value is never read. +tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts(6,10): error TS6196: 'handler2' is declared but never used. ==== tests/cases/compiler/unusedLocalsAndParametersTypeAliases2.ts (3 errors) ==== // unused type handler1 = () => void; - ~~~~~~~~~~~~~ + ~~~~~~~~ !!! error TS6196: 'handler1' is declared but never used. function foo() { - ~~~~~~~~~~~~ + ~~~ !!! error TS6133: 'foo' is declared but its value is never read. type handler2 = () => void; - ~~~~~~~~~~~~~ + ~~~~~~~~ !!! error TS6196: 'handler2' is declared but never used. foo(); } diff --git a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.errors.txt b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.errors.txt index ccfecf77634..da5bc7382e3 100644 --- a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.errors.txt +++ b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.ts(1,18): error TS6133: 'person' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.ts(1,34): error TS6133: 'person2' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.ts(2,9): error TS6133: 'unused' is declared but its value is never read. -tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.ts(3,5): error TS6133: 'maker' is declared but its value is never read. +tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.ts(3,14): error TS6133: 'maker' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.ts(3,20): error TS6133: 'child' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1.ts(4,13): error TS6133: 'unused2' is declared but its value is never read. @@ -16,7 +16,7 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration1 ~~~~~~ !!! error TS6133: 'unused' is declared but its value is never read. function maker(child: string): void { - ~~~~~~~~~~~~~~ + ~~~~~ !!! error TS6133: 'maker' is declared but its value is never read. ~~~~~ !!! error TS6133: 'child' is declared but its value is never read. diff --git a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.errors.txt b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.errors.txt index dcd5b75ea86..e5326d2c41f 100644 --- a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.errors.txt +++ b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.ts(1,18): error TS6133: 'person' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.ts(2,9): error TS6133: 'unused' is declared but its value is never read. -tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.ts(3,5): error TS6133: 'maker' is declared but its value is never read. +tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.ts(3,14): error TS6133: 'maker' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.ts(3,20): error TS6133: 'child' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.ts(4,13): error TS6133: 'unused2' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2.ts(6,21): error TS6133: 'child2' is declared but its value is never read. @@ -15,7 +15,7 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionDeclaration2 ~~~~~~ !!! error TS6133: 'unused' is declared but its value is never read. function maker(child: string): void { - ~~~~~~~~~~~~~~ + ~~~~~ !!! error TS6133: 'maker' is declared but its value is never read. ~~~~~ !!! error TS6133: 'child' is declared but its value is never read. diff --git a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.errors.txt b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.errors.txt index d8b92c7d71d..ac9b5c8632c 100644 --- a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.errors.txt +++ b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.ts(1,25): error TS6133: 'person' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.ts(1,41): error TS6133: 'person2' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.ts(2,9): error TS6133: 'unused' is declared but its value is never read. -tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.ts(3,5): error TS6133: 'maker' is declared but its value is never read. +tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.ts(3,14): error TS6133: 'maker' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.ts(3,20): error TS6133: 'child' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1.ts(4,13): error TS6133: 'unused2' is declared but its value is never read. @@ -16,7 +16,7 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression1. ~~~~~~ !!! error TS6133: 'unused' is declared but its value is never read. function maker(child: string): void { - ~~~~~~~~~~~~~~ + ~~~~~ !!! error TS6133: 'maker' is declared but its value is never read. ~~~~~ !!! error TS6133: 'child' is declared but its value is never read. diff --git a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.errors.txt b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.errors.txt index 4b5da962c00..c709d189d17 100644 --- a/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.errors.txt +++ b/tests/baselines/reference/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.ts(1,25): error TS6133: 'person' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.ts(2,9): error TS6133: 'unused' is declared but its value is never read. -tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.ts(3,5): error TS6133: 'maker' is declared but its value is never read. +tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.ts(3,14): error TS6133: 'maker' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.ts(3,20): error TS6133: 'child' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.ts(4,13): error TS6133: 'unused2' is declared but its value is never read. tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2.ts(6,21): error TS6133: 'child2' is declared but its value is never read. @@ -15,7 +15,7 @@ tests/cases/compiler/unusedLocalsOnFunctionDeclarationWithinFunctionExpression2. ~~~~~~ !!! error TS6133: 'unused' is declared but its value is never read. function maker(child: string): void { - ~~~~~~~~~~~~~~ + ~~~~~ !!! error TS6133: 'maker' is declared but its value is never read. ~~~~~ !!! error TS6133: 'child' is declared but its value is never read. diff --git a/tests/baselines/reference/unusedModuleInModule.errors.txt b/tests/baselines/reference/unusedModuleInModule.errors.txt index eb3aa944797..bd8040ce590 100644 --- a/tests/baselines/reference/unusedModuleInModule.errors.txt +++ b/tests/baselines/reference/unusedModuleInModule.errors.txt @@ -1,9 +1,9 @@ -tests/cases/compiler/unusedModuleInModule.ts(2,5): error TS6133: 'B' is declared but its value is never read. +tests/cases/compiler/unusedModuleInModule.ts(2,12): error TS6133: 'B' is declared but its value is never read. ==== tests/cases/compiler/unusedModuleInModule.ts (1 errors) ==== module A { module B {} - ~~~~~~~~ + ~ !!! error TS6133: 'B' is declared but its value is never read. } \ No newline at end of file diff --git a/tests/baselines/reference/unusedNamespaceInModule.errors.txt b/tests/baselines/reference/unusedNamespaceInModule.errors.txt index 9cce14e295a..afc118b094a 100644 --- a/tests/baselines/reference/unusedNamespaceInModule.errors.txt +++ b/tests/baselines/reference/unusedNamespaceInModule.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedNamespaceInModule.ts(2,5): error TS6133: 'B' is declared but its value is never read. +tests/cases/compiler/unusedNamespaceInModule.ts(2,15): error TS6133: 'B' is declared but its value is never read. ==== tests/cases/compiler/unusedNamespaceInModule.ts (1 errors) ==== module A { namespace B { } - ~~~~~~~~~~~ + ~ !!! error TS6133: 'B' is declared but its value is never read. export namespace C {} } \ No newline at end of file diff --git a/tests/baselines/reference/unusedNamespaceInNamespace.errors.txt b/tests/baselines/reference/unusedNamespaceInNamespace.errors.txt index 0988b749fd4..ff031f5af41 100644 --- a/tests/baselines/reference/unusedNamespaceInNamespace.errors.txt +++ b/tests/baselines/reference/unusedNamespaceInNamespace.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/unusedNamespaceInNamespace.ts(2,5): error TS6133: 'B' is declared but its value is never read. +tests/cases/compiler/unusedNamespaceInNamespace.ts(2,15): error TS6133: 'B' is declared but its value is never read. ==== tests/cases/compiler/unusedNamespaceInNamespace.ts (1 errors) ==== namespace A { namespace B { } - ~~~~~~~~~~~ + ~ !!! error TS6133: 'B' is declared but its value is never read. export namespace C {} } \ No newline at end of file diff --git a/tests/cases/compiler/APISample_Watch.ts b/tests/cases/compiler/APISample_Watch.ts new file mode 100644 index 00000000000..e1506676426 --- /dev/null +++ b/tests/cases/compiler/APISample_Watch.ts @@ -0,0 +1,80 @@ +// @module: commonjs +// @skipLibCheck: true +// @includebuiltfile: typescript_standalone.d.ts +// @noImplicitAny:true +// @strictNullChecks:true + +/* + * Note: This test is a public API sample. The sample sources can be found + at: https://github.com/Microsoft/TypeScript-wiki/blob/master/Using-the-Compiler-API.md#writing-an-incremental-program-watcher + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ + +declare var process: any; +declare var console: any; +declare var os: any; + +import ts = require("typescript"); + +const formatHost: ts.FormatDiagnosticsHost = { + getCanonicalFileName: path => path, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getNewLine: () => ts.sys.newLine, +} + +function watchMain() { + const configPath = ts.findConfigFile(/*searchPath*/ "./", ts.sys.fileExists, "tsconfig.json"); + if (!configPath) { + throw new Error("Could not find a valid 'tsconfig.json'."); + } + + // TypeScript can use several different program creation "strategies": + // * ts.createEmitAndSemanticDiagnosticsBuilderProgram, + // * ts.createSemanticDiagnosticsBuilderProgram + // * ts.createAbstractBuilder + // The first two produce "builder programs". These use an incremental strategy to only re-check and emit files whose + // contents may have changed, or whose dependencies may have changes which may impact change the result of prior type-check and emit. + // The last uses an ordinary program which does a full type check after every change. + // Between `createEmitAndSemanticDiagnosticsBuilderProgram` and `createSemanticDiagnosticsBuilderProgram`, the only difference is emit. + // For pure type-checking scenarios, or when another tool/process handles emit, using `createSemanticDiagnosticsBuilderProgram` may be more desirable. + + // Note that there is another overload for `createWatchCompilerHost` that takes a set of root files. + const host = ts.createWatchCompilerHost(configPath, {}, ts.sys, + ts.createSemanticDiagnosticsBuilderProgram, + reportDiagnostic, + reportWatchStatusChanged, + ); + + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + const origCreateProgram = host.createProgram; + host.createProgram = (rootNames: ReadonlyArray, options, host, oldProgram) => { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + } + const origPostProgramCreate = host.afterProgramCreate; + + host.afterProgramCreate = program => { + console.log("** We finished making the program! **"); + origPostProgramCreate!(program); + }; + + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} + +function reportDiagnostic(diagnostic: ts.Diagnostic) { + console.error("Error", diagnostic.code, ":", + ts.flattenDiagnosticMessageText(diagnostic.messageText, formatHost.getNewLine()) + ); +} + +/** + * Prints a diagnostic every time the watch status changes. + * This is mainly for messages like "Starting compilation" or "Compilation completed". + */ +function reportWatchStatusChanged(diagnostic: ts.Diagnostic) { + console.info(ts.formatDiagnostic(diagnostic, formatHost)); +} + +watchMain(); diff --git a/tests/cases/compiler/APISample_WatchWithDefaults.ts b/tests/cases/compiler/APISample_WatchWithDefaults.ts new file mode 100644 index 00000000000..24f251daca2 --- /dev/null +++ b/tests/cases/compiler/APISample_WatchWithDefaults.ts @@ -0,0 +1,53 @@ +// @module: commonjs +// @skipLibCheck: true +// @includebuiltfile: typescript_standalone.d.ts +// @noImplicitAny:true +// @strict:true + +/* + * Note: This test is a public API sample. This uses default sys interface without having to pass anything + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ + +declare var console: any; + +import ts = require("typescript"); + +function watchMain() { + const configPath = ts.findConfigFile(/*searchPath*/ "./", ts.sys.fileExists, "tsconfig.json"); + if (!configPath) { + throw new Error("Could not find a valid 'tsconfig.json'."); + } + + // TypeScript can use several different program creation "strategies": + // * ts.createEmitAndSemanticDiagnosticsBuilderProgram, + // * ts.createSemanticDiagnosticsBuilderProgram + // * ts.createAbstractBuilder + // The first two produce "builder programs". These use an incremental strategy to only re-check and emit files whose + // contents may have changed, or whose dependencies may have changes which may impact change the result of prior type-check and emit. + // The last uses an ordinary program which does a full type check after every change. + // Between `createEmitAndSemanticDiagnosticsBuilderProgram` and `createSemanticDiagnosticsBuilderProgram`, the only difference is emit. + // For pure type-checking scenarios, or when another tool/process handles emit, using `createSemanticDiagnosticsBuilderProgram` may be more desirable. + + // Note that there is another overload for `createWatchCompilerHost` that takes a set of root files. + const host = ts.createWatchCompilerHost(configPath, {}, ts.sys); + + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + const origCreateProgram = host.createProgram; + host.createProgram = (rootNames, options, host, oldProgram) => { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + } + const origPostProgramCreate = host.afterProgramCreate; + + host.afterProgramCreate = program => { + console.log("** We finished making the program! **"); + origPostProgramCreate!(program); + }; + + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} + +watchMain(); diff --git a/tests/cases/compiler/APISample_WatchWithOwnWatchHost.ts b/tests/cases/compiler/APISample_WatchWithOwnWatchHost.ts new file mode 100644 index 00000000000..18f170bd5f6 --- /dev/null +++ b/tests/cases/compiler/APISample_WatchWithOwnWatchHost.ts @@ -0,0 +1,60 @@ +// @module: commonjs +// @skipLibCheck: true +// @includebuiltfile: typescript_standalone.d.ts +// @noImplicitAny:true +// @strict:true + +/* + * Note: This test is a public API sample. This sample verifies creating abstract builder to watch list of root files + * Please log a "breaking change" issue for any API breaking change affecting this issue + */ + +declare var console: any; + +import ts = require("typescript"); + +function watchMain() { + // get list of files and compiler options somehow + const files: string[] = []; + const options: ts.CompilerOptions = {}; + + const host: ts.WatchCompilerHostOfFilesAndCompilerOptions = { + rootFiles: files, + options, + + useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames, + getNewLine: () => ts.sys.newLine, + getCurrentDirectory: ts.sys.getCurrentDirectory, + getDefaultLibFileName: options => ts.getDefaultLibFilePath(options), + + fileExists: ts.sys.fileExists, + readFile: ts.sys.readFile, + directoryExists: ts.sys.directoryExists, + getDirectories: ts.sys.getDirectories, + readDirectory: ts.sys.readDirectory, + realpath: ts.sys.realpath, + + watchFile: ts.sys.watchFile!, + watchDirectory: ts.sys.watchDirectory!, + createProgram: ts.createAbstractBuilder + }; + + // You can technically override any given hook on the host, though you probably don't need to. + // Note that we're assuming `origCreateProgram` and `origPostProgramCreate` doesn't use `this` at all. + const origCreateProgram = host.createProgram; + host.createProgram = (rootNames, options, host, oldProgram) => { + console.log("** We're about to create the program! **"); + return origCreateProgram(rootNames, options, host, oldProgram); + } + const origPostProgramCreate = host.afterProgramCreate; + + host.afterProgramCreate = program => { + console.log("** We finished making the program! **"); + origPostProgramCreate!(program); + }; + + // `createWatchProgram` creates an initial program, watches files, and updates the program over time. + ts.createWatchProgram(host); +} + +watchMain(); diff --git a/tests/cases/compiler/destructuringTempOccursAfterPrologue.ts b/tests/cases/compiler/destructuringTempOccursAfterPrologue.ts new file mode 100644 index 00000000000..96dec6e6083 --- /dev/null +++ b/tests/cases/compiler/destructuringTempOccursAfterPrologue.ts @@ -0,0 +1,4 @@ +function test(p: any) { + 'use strict'; + p = { prop: p } = p; +} \ No newline at end of file diff --git a/tests/cases/compiler/importNotElidedWhenNotFound.ts b/tests/cases/compiler/importNotElidedWhenNotFound.ts new file mode 100644 index 00000000000..2ff7cd64d0d --- /dev/null +++ b/tests/cases/compiler/importNotElidedWhenNotFound.ts @@ -0,0 +1,8 @@ +import X from 'file'; +import Z from 'other_file'; + +class Y extends Z { + constructor() { + super(X); + } +} \ No newline at end of file diff --git a/tests/cases/compiler/jsdocResolveNameFailureInTypedef.ts b/tests/cases/compiler/jsdocResolveNameFailureInTypedef.ts new file mode 100644 index 00000000000..016893cfd7b --- /dev/null +++ b/tests/cases/compiler/jsdocResolveNameFailureInTypedef.ts @@ -0,0 +1,13 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true + +// @Filename: /a.js +/** + * @param {Ty} x + */ +function f(x) {} + +/** + * @typedef {CantResolveThis} Ty + */ diff --git a/tests/cases/compiler/reexportDefaultIsCallable.ts b/tests/cases/compiler/reexportDefaultIsCallable.ts new file mode 100644 index 00000000000..f37c79401de --- /dev/null +++ b/tests/cases/compiler/reexportDefaultIsCallable.ts @@ -0,0 +1,8 @@ +// @esModuleInterop: true +// @filename: schema.d.ts +export default class Schema {} +// @filename: reexporter.d.ts +export { default } from "./schema"; +// @filename: usage.ts +import Base from "./reexporter"; +export default class Mine extends Base {} diff --git a/tests/cases/compiler/requireOfJsonFileWithAlwaysStrictWithoutErrors.ts b/tests/cases/compiler/requireOfJsonFileWithAlwaysStrictWithoutErrors.ts new file mode 100644 index 00000000000..705590412eb --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithAlwaysStrictWithoutErrors.ts @@ -0,0 +1,19 @@ +// @module: commonjs +// @outdir: out/ +// @resolveJsonModule: true +// @alwaysStrict: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithDeclaration.ts b/tests/cases/compiler/requireOfJsonFileWithDeclaration.ts new file mode 100644 index 00000000000..5a288ce76ca --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithDeclaration.ts @@ -0,0 +1,20 @@ +// @module: commonjs +// @outdir: out/ +// @fullEmitPaths: true +// @resolveJsonModule: true +// @declaration: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithSourceMap.ts b/tests/cases/compiler/requireOfJsonFileWithSourceMap.ts new file mode 100644 index 00000000000..d83fbda47a0 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithSourceMap.ts @@ -0,0 +1,21 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true +// @fullEmitPaths: true +// @resolveJsonModule: true +// @sourceMap: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello" +} \ No newline at end of file diff --git a/tests/cases/compiler/requireOfJsonFileWithTraillingComma.ts b/tests/cases/compiler/requireOfJsonFileWithTraillingComma.ts new file mode 100644 index 00000000000..de1f3b24a78 --- /dev/null +++ b/tests/cases/compiler/requireOfJsonFileWithTraillingComma.ts @@ -0,0 +1,20 @@ +// @module: commonjs +// @outdir: out/ +// @allowJs: true +// @fullEmitPaths: true +// @resolveJsonModule: true + +// @Filename: file1.ts +import b1 = require('./b.json'); +let x = b1.a; +import b2 = require('./b.json'); +if (x) { + let b = b2.b; + x = (b1.b === b); +} + +// @Filename: b.json +{ + "a": true, + "b": "hello", +} \ No newline at end of file diff --git a/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfFunction.ts b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfFunction.ts new file mode 100644 index 00000000000..cbacf60ce68 --- /dev/null +++ b/tests/cases/conformance/expressions/typeGuards/typeGuardOfFormTypeOfFunction.ts @@ -0,0 +1,73 @@ + +function f1(x: any) { + if (typeof x === "function") { + x; // any + } +} + +function f2(x: unknown) { + if (typeof x === "function") { + x; // Function + } +} + +function f3(x: {}) { + if (typeof x === "function") { + x; // Function + } +} + +function f4(x: T) { + if (typeof x === "function") { + x; // T & Function + } +} + +function f5(x: { s: string }) { + if (typeof x === "function") { + x; // never + } +} + +function f6(x: () => string) { + if (typeof x === "function") { + x; // () => string + } +} + +function f10(x: string | (() => string)) { + if (typeof x === "function") { + x; // () => string + } + else { + x; // string + } +} + +function f11(x: { s: string } | (() => string)) { + if (typeof x === "function") { + x; // () => string + } + else { + x; // { s: string } + } +} + +function f12(x: { s: string } | { n: number }) { + if (typeof x === "function") { + x; // never + } + else { + x; // { s: string } | { n: number } + } +} + +// Repro from #18238 + +function f100(obj: T, keys: K[]) : void { + for (const k of keys) { + const item = obj[k]; + if (typeof item == 'function') + item.call(obj); + } +} diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateClass.ts b/tests/cases/conformance/jsdoc/jsdocTemplateClass.ts index b13303d6def..08297262cca 100644 --- a/tests/cases/conformance/jsdoc/jsdocTemplateClass.ts +++ b/tests/cases/conformance/jsdoc/jsdocTemplateClass.ts @@ -4,7 +4,7 @@ // @Filename: templateTagOnClasses.js /** - * @template {T} + * @template T * @typedef {(t: T) => T} Id */ /** @template T */ diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts index a2a7a48c1cb..016607490a8 100644 --- a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts +++ b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction.ts @@ -4,12 +4,12 @@ // @Filename: templateTagOnConstructorFunctions.js /** - * @template {U} + * @template U * @typedef {(u: U) => U} Id */ /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { /** @type {T} */ diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts index c736962de39..d0418661bb7 100644 --- a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts +++ b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts @@ -5,7 +5,7 @@ /** * @param {T} t - * @template {T} + * @template T */ function Zet(t) { /** @type {T} */ diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateTag3.ts b/tests/cases/conformance/jsdoc/jsdocTemplateTag3.ts new file mode 100644 index 00000000000..e05438d304d --- /dev/null +++ b/tests/cases/conformance/jsdoc/jsdocTemplateTag3.ts @@ -0,0 +1,33 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: a.js +/** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @param {T} t + * @param {U} u + * @param {V} v + * @param {W} w + * @param {X} x + * @return {W | X} + */ +function f(t, u, v, w, x) { + if(t.a + t.b.length > u.a - u.b.length && v.c) { + return w; + } + return x; +} + +f({ a: 12, b: 'hi', c: null }, undefined, { c: false, d: 12, b: undefined }, 101, 'nope'); +f({ a: 12 }, undefined, undefined, 101, 'nope'); + +/** + * @template {NoLongerAllowed} + * @template T preceding line's syntax is no longer allowed + * @param {T} x + */ +function g(x) { } + diff --git a/tests/cases/conformance/jsdoc/typedefMultipleTypeParameters.ts b/tests/cases/conformance/jsdoc/typedefMultipleTypeParameters.ts new file mode 100644 index 00000000000..9fc7c0d0d41 --- /dev/null +++ b/tests/cases/conformance/jsdoc/typedefMultipleTypeParameters.ts @@ -0,0 +1,24 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: a.js +/** + * @template {{ a: number, b: string }} T,U A Comment + * @template {{ c: boolean }} V uh ... are comments even supported?? + * @template W + * @template X That last one had no comment + * @typedef {{ t: T, u: U, v: V, w: W, x: X }} Everything + */ + +/** @type {Everything<{ a: number, b: 'hi', c: never }, undefined, { c: true, d: 1 }, number, string>} */ +var tuvwx; + +// TODO: will error when #24592 is fixed +/** @type {Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>} */ +var wrong; + +/** @type {Everything<{ a: number }>} */ +var insufficient; + +// @Filename: test.ts +declare var actually: Everything<{ a: number }, undefined, { c: 1, d: 1 }, number, string>; diff --git a/tests/cases/conformance/salsa/inferringClassStaticMembersFromAssignments.ts b/tests/cases/conformance/salsa/inferringClassStaticMembersFromAssignments.ts index 7ed3a81dcfe..925f9de5305 100644 --- a/tests/cases/conformance/salsa/inferringClassStaticMembersFromAssignments.ts +++ b/tests/cases/conformance/salsa/inferringClassStaticMembersFromAssignments.ts @@ -40,4 +40,4 @@ var n = a.F2.staticProp; var n = C3.staticProp; var n = C4.staticProp; var n = F3.staticProp; -var n = F4.staticProp; \ No newline at end of file +var n = F4.staticProp; diff --git a/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration.ts b/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration.ts index 5a5ba7f49d5..a3b0289608f 100644 --- a/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration.ts +++ b/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration.ts @@ -1,5 +1,6 @@ // @allowJs: true // @checkJs: true +// @noEmit: true // @Filename: a.js var /*1*/x = function foo() { } diff --git a/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration2.ts b/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration2.ts new file mode 100644 index 00000000000..f4fc9a9c92d --- /dev/null +++ b/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration2.ts @@ -0,0 +1,10 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: a.d.ts +declare namespace C { + function bar(): void +} +// @Filename: b.js +C.prototype = {}; +C.bar = 2; diff --git a/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration3.ts b/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration3.ts new file mode 100644 index 00000000000..ca3b952f532 --- /dev/null +++ b/tests/cases/conformance/salsa/jsContainerMergeTsDeclaration3.ts @@ -0,0 +1,8 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: a.d.ts +declare class A {} +// @Filename: b.js +const A = { }; +A.d = { }; diff --git a/tests/cases/conformance/salsa/nestedPrototypeAssignment.ts b/tests/cases/conformance/salsa/nestedPrototypeAssignment.ts new file mode 100644 index 00000000000..ea17ef15da2 --- /dev/null +++ b/tests/cases/conformance/salsa/nestedPrototypeAssignment.ts @@ -0,0 +1,9 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @noImplicitAny: true +// @Filename: mod.js + +// #24111 -- shouldn't assert +C.prototype = {} +C.prototype.bar.foo = {}; diff --git a/tests/cases/conformance/salsa/propertyAssignmentOnImportedSymbol.ts b/tests/cases/conformance/salsa/propertyAssignmentOnImportedSymbol.ts new file mode 100644 index 00000000000..083cf23baac --- /dev/null +++ b/tests/cases/conformance/salsa/propertyAssignmentOnImportedSymbol.ts @@ -0,0 +1,8 @@ +// @allowJs: true +// @checkJs: true +// @noEmit: true +// @Filename: mod1.js +export var hurk = {} +// @Filename: bug24658.js +import { hurk } from './mod1' +hurk.expando = 4 diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts index 07aa3c1994f..c76071f7d99 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess.ts @@ -637,3 +637,17 @@ interface I7 { } type Foo7 = T; declare function f7(type: K): Foo7; + +// Repro from #21770 + +type Dict = { [key in T]: number }; +type DictDict = { [key in V]: Dict }; + +function ff1(dd: DictDict, k1: V, k2: T): number { + return dd[k1][k2]; +} + +function ff2(dd: DictDict, k1: V, k2: T): number { + const d: Dict = dd[k1]; + return d[k2]; +} diff --git a/tests/cases/fourslash/annotateWithTypeFromJSDoc9.5.ts b/tests/cases/fourslash/annotateWithTypeFromJSDoc9.5.ts index 33750e4f3e0..d0319bee614 100644 --- a/tests/cases/fourslash/annotateWithTypeFromJSDoc9.5.ts +++ b/tests/cases/fourslash/annotateWithTypeFromJSDoc9.5.ts @@ -1,7 +1,7 @@ /// /////** -//// * @template {T} +//// * @template T //// * @param {T} x //// * @returns {T} //// */ @@ -11,7 +11,7 @@ verify.codeFix({ description: "Annotate with type from JSDoc", newFileContent: `/** - * @template {T} + * @template T * @param {T} x * @returns {T} */ diff --git a/tests/cases/fourslash/autoCloseTag.ts b/tests/cases/fourslash/autoCloseTag.ts new file mode 100644 index 00000000000..ba828f207a2 --- /dev/null +++ b/tests/cases/fourslash/autoCloseTag.ts @@ -0,0 +1,20 @@ +/// + +// @Filename: /a.tsx +////const x =
/*0*/; +////const x =
foo/*1*/
; +////const x =
/*2*/; +////const x =
/*3*/; +////const x =
+////

/*4*/ +////

+////

; +////const x =
text /*5*/; + +verify.jsxClosingTag({ + 0: { newText: "
" }, + 1: undefined, + 2: undefined, + 3: undefined, + 4: { newText: "

" }, +}); diff --git a/tests/cases/fourslash/completionsImport_default_fromMergedDeclarations.ts b/tests/cases/fourslash/completionsImport_default_fromMergedDeclarations.ts new file mode 100644 index 00000000000..ca4c993d511 --- /dev/null +++ b/tests/cases/fourslash/completionsImport_default_fromMergedDeclarations.ts @@ -0,0 +1,31 @@ +/// + +// @module: esnext + +// @Filename: /a.ts +////declare module "m" { +//// export default class M {} +////} + +// @Filename: /b.ts +////declare module "m" { +//// export default interface M {} +////} + +// @Filename: /c.ts +/////**/ + +goTo.marker(""); +verify.completionListContains({ name: "M", source: "m" }, "class M", "", "class", /*spanIndex*/ undefined, /*hasAction*/ true, { + includeCompletionsForModuleExports: true, + sourceDisplay: "m", +}); + +verify.applyCodeActionFromCompletion("", { + name: "M", + source: "m", + description: `Import 'M' from module "m"`, + newFileContent: `import M from "m"; + +`, +}); diff --git a/tests/cases/fourslash/completionsTypeKeywords.ts b/tests/cases/fourslash/completionsTypeKeywords.ts index 198d6dddab4..5148f2ae7c3 100644 --- a/tests/cases/fourslash/completionsTypeKeywords.ts +++ b/tests/cases/fourslash/completionsTypeKeywords.ts @@ -1,7 +1,10 @@ /// +// @noLib: true + ////type T = /**/ -goTo.marker(); -verify.completionListContains("undefined", "undefined", undefined, "keyword"); -verify.not.completionListContains("await"); +verify.completions({ + marker: "", + exact: ["T", "null", "void", "any", "boolean", "keyof", "never", "number", "object", "string", "symbol", "undefined", "unique", "unknown"], +}); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index de1ca0afd8c..a104e2fde0f 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -174,6 +174,7 @@ declare namespace FourSlashInterface { typeDefinitionCountIs(expectedCount: number): void; implementationListIsEmpty(): void; isValidBraceCompletionAtPosition(openingBrace?: string): void; + jsxClosingTag(map: { [markerName: string]: { readonly newText: string } | undefined }): void; isInCommentAtPosition(onlyMultiLineDiverges?: boolean): void; codeFix(options: { description: string, diff --git a/tests/cases/fourslash/getEditsForFileRename.ts b/tests/cases/fourslash/getEditsForFileRename.ts index 8e53883b37e..03aab260978 100644 --- a/tests/cases/fourslash/getEditsForFileRename.ts +++ b/tests/cases/fourslash/getEditsForFileRename.ts @@ -14,8 +14,11 @@ /////// ////import old from "../old"; +// @Filename: /src/new.ts +//// + // @Filename: /tsconfig.json -////{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/old.ts"] } +////{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/old.ts"] } verify.getEditsForFileRename({ oldPath: "/src/old.ts", @@ -24,6 +27,6 @@ verify.getEditsForFileRename({ "/a.ts": '/// \nimport old from "./src/new";', "/src/a.ts": '/// \nimport old from "./new";', "/src/foo/a.ts": '/// \nimport old from "../new";', - "/tsconfig.json": '{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/new.ts"] }', + "/tsconfig.json": '{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/new.ts"] }', }, }); diff --git a/tests/cases/fourslash/getEditsForFileRename_amd.ts b/tests/cases/fourslash/getEditsForFileRename_amd.ts new file mode 100644 index 00000000000..22bf01e823c --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_amd.ts @@ -0,0 +1,18 @@ +/// + +// @moduleResolution: classic + +// @Filename: /src/user.ts +////import { x } from "old"; + +// @Filename: /src/old.ts +//// + +verify.getEditsForFileRename({ + oldPath: "/src/old.ts", + newPath: "/src/new.ts", + newFileContents: { + "/src/user.ts": +`import { x } from "./new";`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_caseInsensitive.ts b/tests/cases/fourslash/getEditsForFileRename_caseInsensitive.ts new file mode 100644 index 00000000000..506c93ad344 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_caseInsensitive.ts @@ -0,0 +1,15 @@ +/// + +// @Filename: /a.ts +////export const a = 0; + +// @Filename: /b.ts +////import { a } from "./A"; + +verify.getEditsForFileRename({ + oldPath: "/a.ts", + newPath: "/eh.ts", + newFileContents: { + "/b.ts": 'import { a } from "./eh";', + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_directory.ts b/tests/cases/fourslash/getEditsForFileRename_directory.ts new file mode 100644 index 00000000000..8089d6fa138 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_directory.ts @@ -0,0 +1,61 @@ +/// + +// @Filename: /a.ts +/////// +////import old from "./src/old"; +////import old2 from "./src/old/file"; +////export default 0; + +// @Filename: /src/b.ts +/////// +////import old from "./old"; +////import old2 from "./old/file"; +////export default 0; + +// @Filename: /src/foo/c.ts +/////// +////import old from "../old"; +////import old2 from "../old/file"; +////export default 0; + +// @Filename: /src/new/index.ts +////import a from "../../a"; +////import a2 from "../b"; +////import a3 from "../foo/c"; +////import f from "./file"; +////export default 0; + +// @Filename: /src/new/file.ts +//// + +// @Filename: /tsconfig.json +////{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/old/index.ts", "src/old/file.ts"] } + +verify.getEditsForFileRename({ + oldPath: "/src/old", + newPath: "/src/new", + newFileContents: { + "/a.ts": +`/// +import old from "./src/new"; +import old2 from "./src/new/file"; +export default 0;`, + + "/src/b.ts": +`/// +import old from "./new"; +import old2 from "./new/file"; +export default 0;`, + + "/src/foo/c.ts": +`/// +import old from "../new"; +import old2 from "../new/file"; +export default 0;`, + + // No change to /src/new + + "/tsconfig.json": +`{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/new/index.ts", "src/new/file.ts"] }`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_directory_down.ts b/tests/cases/fourslash/getEditsForFileRename_directory_down.ts new file mode 100644 index 00000000000..c4f42e3cc52 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_directory_down.ts @@ -0,0 +1,66 @@ +/// + +// @Filename: /a.ts +/////// +////import old from "./src/old"; +////import old2 from "./src/old/file"; +////export default 0; + +// @Filename: /src/b.ts +/////// +////import old from "./old"; +////import old2 from "./old/file"; +////export default 0; + +// @Filename: /src/foo/c.ts +/////// +////import old from "../old"; +////import old2 from "../old/file"; +////export default 0; + +// @Filename: /src/newDir/new/index.ts +////import a from "../../a"; +////import a2 from "../b"; +////import a3 from "../foo/c"; +////import f from "./file"; +////export default 0; + +// @Filename: /src/newDir/new/file.ts +//// + +// @Filename: /tsconfig.json +////{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/old/index.ts", "src/old/file.ts"] } + +verify.getEditsForFileRename({ + oldPath: "/src/old", + newPath: "/src/newDir/new", + newFileContents: { + "/a.ts": +`/// +import old from "./src/newDir/new"; +import old2 from "./src/newDir/new/file"; +export default 0;`, + + "/src/b.ts": +`/// +import old from "./newDir/new"; +import old2 from "./newDir/new/file"; +export default 0;`, + + "/src/foo/c.ts": +`/// +import old from "../newDir/new"; +import old2 from "../newDir/new/file"; +export default 0;`, + + "/src/newDir/new/index.ts": +`import a from "../../../a"; +import a2 from "../../b"; +import a3 from "../../foo/c"; +import f from "./file"; +export default 0;`, + + "/tsconfig.json": +`{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/newDir/new/index.ts", "src/newDir/new/file.ts"] }`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_directory_noUpdateNodeModulesImport.ts b/tests/cases/fourslash/getEditsForFileRename_directory_noUpdateNodeModulesImport.ts new file mode 100644 index 00000000000..c2674cc1670 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_directory_noUpdateNodeModulesImport.ts @@ -0,0 +1,13 @@ +/// + +// @Filename: /a/b/file1.ts +////import { foo } from "foo"; + +// @Filename: /a/b/node_modules/foo/index.d.ts +////export const foo = 0; + +verify.getEditsForFileRename({ + oldPath: "/a/b", + newPath: "/a/d", + newFileContents: {}, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_directory_up.ts b/tests/cases/fourslash/getEditsForFileRename_directory_up.ts new file mode 100644 index 00000000000..c63cfe888f1 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_directory_up.ts @@ -0,0 +1,66 @@ +/// + +// @Filename: /a.ts +/////// +////import old from "./src/old"; +////import old2 from "./src/old/file"; +////export default 0; + +// @Filename: /src/b.ts +/////// +////import old from "./old"; +////import old2 from "./old/file"; +////export default 0; + +// @Filename: /src/foo/c.ts +/////// +////import old from "../old"; +////import old2 from "../old/file"; +////export default 0; + +// @Filename: /newDir/new/index.ts +////import a from "../../a"; +////import a2 from "../b"; +////import a3 from "../foo/c"; +////import f from "./file"; +////export default 0; + +// @Filename: /newDir/new/file.ts +//// + +// @Filename: /tsconfig.json +////{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "src/old/index.ts", "src/old/file.ts"] } + +verify.getEditsForFileRename({ + oldPath: "/src/old", + newPath: "/newDir/new", + newFileContents: { + "/a.ts": +`/// +import old from "./newDir/new"; +import old2 from "./newDir/new/file"; +export default 0;`, + + "/src/b.ts": +`/// +import old from "../newDir/new"; +import old2 from "../newDir/new/file"; +export default 0;`, + + "/src/foo/c.ts": +`/// +import old from "../../newDir/new"; +import old2 from "../../newDir/new/file"; +export default 0;`, + + "/newDir/new/index.ts": +`import a from "../../a"; +import a2 from "../../src/b"; +import a3 from "../../src/foo/c"; +import f from "./file"; +export default 0;`, + + "/tsconfig.json": +`{ "files": ["a.ts", "src/b.ts", "src/foo/c.ts", "newDir/new/index.ts", "newDir/new/file.ts"] }`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_jsExtension.ts b/tests/cases/fourslash/getEditsForFileRename_jsExtension.ts new file mode 100644 index 00000000000..9c4e423a76a --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_jsExtension.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /src/a.js +////export const a = 0; + +// @Filename: /b.js +////import { a } from "./src/a.js"; + +verify.getEditsForFileRename({ + oldPath: "/b.js", + newPath: "/src/b.js", + newFileContents: { + "/b.js": +`import { a } from "./a.js";`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_oldFileStillPresent.ts b/tests/cases/fourslash/getEditsForFileRename_oldFileStillPresent.ts index c4ebf341a5e..34084d9d9df 100644 --- a/tests/cases/fourslash/getEditsForFileRename_oldFileStillPresent.ts +++ b/tests/cases/fourslash/getEditsForFileRename_oldFileStillPresent.ts @@ -18,7 +18,7 @@ ////import old from "../old"; // @Filename: /tsconfig.json -////{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/old.ts"] } +////{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/old.ts"] } verify.getEditsForFileRename({ oldPath: "/src/old.ts", @@ -27,6 +27,6 @@ verify.getEditsForFileRename({ "/a.ts": '/// \nimport old from "./src/new";', "/src/a.ts": '/// \nimport old from "./new";', "/src/foo/a.ts": '/// \nimport old from "../new";', - "/tsconfig.json": '{ "files": ["/a.ts", "/src/a.ts", "/src/foo/a.ts", "/src/new.ts"] }', + "/tsconfig.json": '{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/new.ts"] }', }, }); diff --git a/tests/cases/fourslash/getEditsForFileRename_renameFromIndex.ts b/tests/cases/fourslash/getEditsForFileRename_renameFromIndex.ts new file mode 100644 index 00000000000..cddf212128c --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_renameFromIndex.ts @@ -0,0 +1,43 @@ +/// + +// @Filename: /a.ts +/////// +////import old from "./src"; +////import old2 from "./src/index"; + +// @Filename: /src/a.ts +/////// +////import old from "."; +////import old2 from "./index"; + +// @Filename: /src/foo/a.ts +/////// +////import old from ".."; +////import old2 from "../index"; + +// @Filename: /src/index.ts +//// + +// @Filename: /tsconfig.json +////{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/index.ts"] } + +verify.getEditsForFileRename({ + oldPath: "/src/index.ts", + newPath: "/src/new.ts", + newFileContents: { + "/a.ts": +`/// +import old from "./src/new"; +import old2 from "./src/new";`, + "/src/a.ts": +`/// +import old from "./new"; +import old2 from "./new";`, + "/src/foo/a.ts": +`/// +import old from "../new"; +import old2 from "../new";`, + "/tsconfig.json": +'{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/new.ts"] }', + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_renameToIndex.ts b/tests/cases/fourslash/getEditsForFileRename_renameToIndex.ts new file mode 100644 index 00000000000..a1a052ee557 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_renameToIndex.ts @@ -0,0 +1,37 @@ +/// + +// @Filename: /a.ts +/////// +////import old from "./src/old"; + +// @Filename: /src/a.ts +/////// +////import old from "./old"; + +// @Filename: /src/foo/a.ts +/////// +////import old from "../old"; + +// @Filename: /src/old.ts +//// + +// @Filename: /tsconfig.json +////{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/old.ts"] } + +verify.getEditsForFileRename({ + oldPath: "/src/old.ts", + newPath: "/src/index.ts", + newFileContents: { + "/a.ts": +`/// +import old from "./src";`, + "/src/a.ts": +`/// +import old from ".";`, + "/src/foo/a.ts": +`/// +import old from "..";`, + "/tsconfig.json": +'{ "files": ["a.ts", "src/a.ts", "src/foo/a.ts", "src/index.ts"] }', + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_shortenRelativePaths.ts b/tests/cases/fourslash/getEditsForFileRename_shortenRelativePaths.ts new file mode 100644 index 00000000000..d5a62f219d5 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_shortenRelativePaths.ts @@ -0,0 +1,16 @@ +/// + +// @Filename: /src/foo/x.ts +//// + +// @Filename: /src/foo/new.ts +////import { x } from "./foo/x"; + +verify.getEditsForFileRename({ + oldPath: "/src/old.ts", + newPath: "/src/foo/new.ts", + newFileContents: { + "/src/foo/new.ts": +`import { x } from "./x";`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_subDir.ts b/tests/cases/fourslash/getEditsForFileRename_subDir.ts new file mode 100644 index 00000000000..ae75f190b9d --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_subDir.ts @@ -0,0 +1,16 @@ +/// + +// @Filename: /src/foo/a.ts +//// + +// @Filename: /src/dir/new.ts +////import a from "./foo/a"; + +verify.getEditsForFileRename({ + oldPath: "/src/old.ts", + newPath: "/src/dir/new.ts", + newFileContents: { + "/src/dir/new.ts": +`import a from "../foo/a";`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_tsconfig.ts b/tests/cases/fourslash/getEditsForFileRename_tsconfig.ts new file mode 100644 index 00000000000..611bff18539 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_tsconfig.ts @@ -0,0 +1,41 @@ +/// + +// @Filename: /src/tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": "./old", +//// "mapRoot": "../src/old", +//// "paths": { +//// "foo": ["old"], +//// }, +//// "rootDir": "old", +//// "rootDirs": ["old"], +//// "typeRoots": ["old"], +//// }, +//// "files": ["old/a.ts"], +//// "include": ["old/*.ts"], +//// "exclude": ["old"], +////} + +verify.getEditsForFileRename({ + oldPath: "/src/old", + newPath: "/src/new", + newFileContents: { + "/src/tsconfig.json": +`{ + "compilerOptions": { + "baseUrl": "new", + "mapRoot": "new", + "paths": { + "foo": ["new"], + }, + "rootDir": "new", + "rootDirs": ["new"], + "typeRoots": ["new"], + }, + "files": ["new/a.ts"], + "include": ["new/*.ts"], + "exclude": ["new"], +}`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_tsconfig_include_add.ts b/tests/cases/fourslash/getEditsForFileRename_tsconfig_include_add.ts new file mode 100644 index 00000000000..5b1ef6791c0 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_tsconfig_include_add.ts @@ -0,0 +1,17 @@ +/// + +// @Filename: /src/tsconfig.json +////{ +//// "include": ["dir"], +////} + +verify.getEditsForFileRename({ + oldPath: "/src/dir/a.ts", + newPath: "/src/newDir/b.ts", + newFileContents: { + "/src/tsconfig.json": +`{ + "include": ["dir", "newDir/b.ts"], +}`, + }, +}); diff --git a/tests/cases/fourslash/getEditsForFileRename_tsconfig_include_noChange.ts b/tests/cases/fourslash/getEditsForFileRename_tsconfig_include_noChange.ts new file mode 100644 index 00000000000..dc2200e17e8 --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_tsconfig_include_noChange.ts @@ -0,0 +1,12 @@ +/// + +// @Filename: /src/tsconfig.json +////{ +//// "include": ["dir"], +////} + +verify.getEditsForFileRename({ + oldPath: "/src/dir/a.ts", + newPath: "/src/dir/b.ts", + newFileContents: {}, +}); diff --git a/tests/cases/fourslash/getOccurrencesAsyncAwait.ts b/tests/cases/fourslash/getOccurrencesAsyncAwait.ts index f337e755096..c41b2079749 100644 --- a/tests/cases/fourslash/getOccurrencesAsyncAwait.ts +++ b/tests/cases/fourslash/getOccurrencesAsyncAwait.ts @@ -20,8 +20,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesAsyncAwait2.ts b/tests/cases/fourslash/getOccurrencesAsyncAwait2.ts index 530f26bc18d..039cade46d0 100644 --- a/tests/cases/fourslash/getOccurrencesAsyncAwait2.ts +++ b/tests/cases/fourslash/getOccurrencesAsyncAwait2.ts @@ -9,8 +9,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesConstructor.ts b/tests/cases/fourslash/getOccurrencesConstructor.ts index 41d72c533a3..8eb05b6a91e 100644 --- a/tests/cases/fourslash/getOccurrencesConstructor.ts +++ b/tests/cases/fourslash/getOccurrencesConstructor.ts @@ -19,8 +19,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesConstructor2.ts b/tests/cases/fourslash/getOccurrencesConstructor2.ts index b34ffa4a190..3329a59e0a2 100644 --- a/tests/cases/fourslash/getOccurrencesConstructor2.ts +++ b/tests/cases/fourslash/getOccurrencesConstructor2.ts @@ -19,8 +19,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesIfElse.ts b/tests/cases/fourslash/getOccurrencesIfElse.ts index 9251a59d130..66622be4008 100644 --- a/tests/cases/fourslash/getOccurrencesIfElse.ts +++ b/tests/cases/fourslash/getOccurrencesIfElse.ts @@ -23,8 +23,3 @@ ////[|else|] { } verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts index 88621cd4cf4..eef8454f7ca 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue.ts @@ -64,9 +64,3 @@ ////label7: while (true) continue label5; verify.rangesAreOccurrences(false); - -goTo.marker(); -verify.occurrencesAtPositionCount(test.ranges().length); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts index 225346f8077..1a546730e2b 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue2.ts @@ -64,9 +64,3 @@ ////label7: while (true) continue label5; verify.rangesAreOccurrences(false); - -goTo.marker(); -verify.occurrencesAtPositionCount(test.ranges().length); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts index c1aeef315f9..6cb54f708dc 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue3.ts @@ -64,8 +64,3 @@ ////label7: while (true) continue label5; verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts index b183b2b3fde..2c4ef310bad 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue4.ts @@ -64,9 +64,3 @@ ////label7: while (true) continue label5; verify.rangesAreOccurrences(false); - -goTo.marker(); -verify.occurrencesAtPositionCount(test.ranges().length); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts b/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts index 3353d6c96dc..9dc4c6b04c6 100644 --- a/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts +++ b/tests/cases/fourslash/getOccurrencesLoopBreakContinue5.ts @@ -64,9 +64,3 @@ ////label7: while (true) continue label5; verify.rangesAreOccurrences(false); - -goTo.marker(); -verify.occurrencesAtPositionCount(test.ranges().length); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesReturn.ts b/tests/cases/fourslash/getOccurrencesReturn.ts index 44b3679ba2e..08467d88f9c 100644 --- a/tests/cases/fourslash/getOccurrencesReturn.ts +++ b/tests/cases/fourslash/getOccurrencesReturn.ts @@ -20,8 +20,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesReturn2.ts b/tests/cases/fourslash/getOccurrencesReturn2.ts index 750648838a2..81c5e3f8985 100644 --- a/tests/cases/fourslash/getOccurrencesReturn2.ts +++ b/tests/cases/fourslash/getOccurrencesReturn2.ts @@ -20,8 +20,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesSuper.ts b/tests/cases/fourslash/getOccurrencesSuper.ts index 6f5c51715f3..17089b61f22 100644 --- a/tests/cases/fourslash/getOccurrencesSuper.ts +++ b/tests/cases/fourslash/getOccurrencesSuper.ts @@ -51,8 +51,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesSuper2.ts b/tests/cases/fourslash/getOccurrencesSuper2.ts index 2da702acbc6..310eac02aac 100644 --- a/tests/cases/fourslash/getOccurrencesSuper2.ts +++ b/tests/cases/fourslash/getOccurrencesSuper2.ts @@ -51,8 +51,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} \ No newline at end of file diff --git a/tests/cases/fourslash/getOccurrencesThis.ts b/tests/cases/fourslash/getOccurrencesThis.ts index 156fde2c4ac..bb60e7a1c64 100644 --- a/tests/cases/fourslash/getOccurrencesThis.ts +++ b/tests/cases/fourslash/getOccurrencesThis.ts @@ -141,8 +141,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThis2.ts b/tests/cases/fourslash/getOccurrencesThis2.ts index 9a40eb39fb0..67dc0b82be1 100644 --- a/tests/cases/fourslash/getOccurrencesThis2.ts +++ b/tests/cases/fourslash/getOccurrencesThis2.ts @@ -141,8 +141,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThis3.ts b/tests/cases/fourslash/getOccurrencesThis3.ts index 66c80241e4a..432bdaeb8c7 100644 --- a/tests/cases/fourslash/getOccurrencesThis3.ts +++ b/tests/cases/fourslash/getOccurrencesThis3.ts @@ -141,8 +141,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThis4.ts b/tests/cases/fourslash/getOccurrencesThis4.ts index 42ddd7984a8..462c5269a0d 100644 --- a/tests/cases/fourslash/getOccurrencesThis4.ts +++ b/tests/cases/fourslash/getOccurrencesThis4.ts @@ -141,8 +141,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThis5.ts b/tests/cases/fourslash/getOccurrencesThis5.ts index 845e8342fa5..ee9153c39b5 100644 --- a/tests/cases/fourslash/getOccurrencesThis5.ts +++ b/tests/cases/fourslash/getOccurrencesThis5.ts @@ -141,8 +141,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThrow.ts b/tests/cases/fourslash/getOccurrencesThrow.ts index db80e3c51a0..5c955bb8772 100644 --- a/tests/cases/fourslash/getOccurrencesThrow.ts +++ b/tests/cases/fourslash/getOccurrencesThrow.ts @@ -43,8 +43,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThrow2.ts b/tests/cases/fourslash/getOccurrencesThrow2.ts index 21425990e2f..4a629b7b2b4 100644 --- a/tests/cases/fourslash/getOccurrencesThrow2.ts +++ b/tests/cases/fourslash/getOccurrencesThrow2.ts @@ -43,8 +43,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThrow3.ts b/tests/cases/fourslash/getOccurrencesThrow3.ts index d601123f7bd..5bef04c6abb 100644 --- a/tests/cases/fourslash/getOccurrencesThrow3.ts +++ b/tests/cases/fourslash/getOccurrencesThrow3.ts @@ -43,8 +43,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThrow4.ts b/tests/cases/fourslash/getOccurrencesThrow4.ts index c348685b4ed..741a9d8cc06 100644 --- a/tests/cases/fourslash/getOccurrencesThrow4.ts +++ b/tests/cases/fourslash/getOccurrencesThrow4.ts @@ -43,8 +43,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesThrow5.ts b/tests/cases/fourslash/getOccurrencesThrow5.ts index b4b51b677bc..91011e5eb12 100644 --- a/tests/cases/fourslash/getOccurrencesThrow5.ts +++ b/tests/cases/fourslash/getOccurrencesThrow5.ts @@ -43,8 +43,3 @@ ////} verify.rangesAreOccurrences(false); - -goTo.marker(); -for (const range of test.ranges()) { - verify.occurrencesAtPositionContains(range, false); -} diff --git a/tests/cases/fourslash/getOccurrencesYield.ts b/tests/cases/fourslash/getOccurrencesYield.ts new file mode 100644 index 00000000000..001434c8bd0 --- /dev/null +++ b/tests/cases/fourslash/getOccurrencesYield.ts @@ -0,0 +1,17 @@ +/// + +////function* f() { +//// [|yield|] 100; +//// [|y/**/ield|] [|yield|] 200; +//// class Foo { +//// *memberFunction() { +//// return yield 1; +//// } +//// } +//// return function* g() { +//// yield 1; +//// } +////} + + +verify.rangesAreOccurrences(false); diff --git a/tests/cases/fourslash/goToImplementationClassMethod_00.ts b/tests/cases/fourslash/goToImplementationClassMethod_00.ts index 09bece0c1a2..8c8ad0723ee 100644 --- a/tests/cases/fourslash/goToImplementationClassMethod_00.ts +++ b/tests/cases/fourslash/goToImplementationClassMethod_00.ts @@ -3,7 +3,7 @@ // Should handle calls made on members declared in a class //// class Bar { -//// [|{|"parts": ["(","method",")"," ","Bar",".","hello","(",")",":"," ","void"], "kind": "method"|}hello() {}|] +//// [|{|"parts": ["(","method",")"," ","Bar",".","hello","(",")",":"," ","void"], "kind": "method"|}hello|]() {} //// } //// //// new Bar().hel/*reference*/lo; diff --git a/tests/cases/fourslash/goToImplementationClassMethod_01.ts b/tests/cases/fourslash/goToImplementationClassMethod_01.ts index 7f59376a6ae..5aa9deace63 100644 --- a/tests/cases/fourslash/goToImplementationClassMethod_01.ts +++ b/tests/cases/fourslash/goToImplementationClassMethod_01.ts @@ -7,7 +7,7 @@ //// } //// //// class Bar extends AbstractBar{ -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// function whatever(x: AbstractBar) { diff --git a/tests/cases/fourslash/goToImplementationEnum_00.ts b/tests/cases/fourslash/goToImplementationEnum_00.ts index 81e72b871a2..ee5750ed04d 100644 --- a/tests/cases/fourslash/goToImplementationEnum_00.ts +++ b/tests/cases/fourslash/goToImplementationEnum_00.ts @@ -3,7 +3,7 @@ // Should handle calls made on members of an enum //// enum Foo { -//// [|Foo1 = function initializer() { return 5 } ()|], +//// [|Foo1|] = function initializer() { return 5 } (), //// Foo2 = 6 //// } //// diff --git a/tests/cases/fourslash/goToImplementationEnum_01.ts b/tests/cases/fourslash/goToImplementationEnum_01.ts index 43273b6b03a..cf21420609b 100644 --- a/tests/cases/fourslash/goToImplementationEnum_01.ts +++ b/tests/cases/fourslash/goToImplementationEnum_01.ts @@ -2,10 +2,10 @@ // Should handle calls made on enum name -//// [|enum Foo { +//// enum [|Foo|] { //// Foo1 = function initializer() { return 5 } (), //// Foo2 = 6 -//// }|] +//// } //// //// Fo/*reference*/o; diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts index 7ec63c4e94b..0a50197d7ad 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_00.ts @@ -6,19 +6,19 @@ //// he/*declaration*/llo: () => void //// } //// -//// var bar: Foo = { [|hello: helloImpl|] }; -//// var baz: Foo = { [|"hello": helloImpl|] }; +//// var bar: Foo = { [|hello|]: helloImpl }; +//// var baz: Foo = { "[|hello|]": helloImpl }; //// //// function helloImpl () {} //// -//// function whatever(x: Foo = { [|hello() {/**1*/}|] }) { +//// function whatever(x: Foo = { [|hello|]() {/**1*/} }) { //// x.he/*function_call*/llo() //// } //// //// class Bar { -//// x: Foo = { [|hello() {/*2*/}|] } +//// x: Foo = { [|hello|]() {/*2*/} } //// -//// constructor(public f: Foo = { [|hello() {/**3*/}|] } ) {} +//// constructor(public f: Foo = { [|hello|]() {/**3*/} } ) {} //// } verify.allRangesAppearInImplementationList("function_call"); diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts index 8bd328bcb54..d7626b3bf74 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_01.ts @@ -8,7 +8,7 @@ //// } //// //// class Bar implements Foo { -//// [|hello() {}|] +//// [|hello|]() {} //// public sure() {} //// } //// diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts index 82dceaad91c..d672f1c8f48 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_02.ts @@ -11,7 +11,7 @@ //// } //// //// class Bar extends AbstractBar { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// function whatever(a: AbstractBar) { diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts index 8826cc1eab4..3753fe4e351 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_03.ts @@ -7,7 +7,7 @@ //// } //// //// class Bar extends SuperBar { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// class SuperBar implements Foo { diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts index a9b825c717f..a4c832b43ae 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_04.ts @@ -7,11 +7,11 @@ //// } //// //// class Bar extends SuperBar { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// class SuperBar implements Foo { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// class OtherBar implements Foo { diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts index b051e16a929..c8cc432c161 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_05.ts @@ -7,7 +7,7 @@ //// } //// //// class SuperBar implements Foo { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// class Bar extends SuperBar { diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts index b340270096d..ac39ed70928 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_06.ts @@ -11,19 +11,19 @@ //// } //// //// class Bar implements Foo { -//// [|hello() {}|] +//// [|hello|]() {} //// someOtherFunction() {} //// } //// //// function createFoo(): Foo { //// return { -//// [|hello() {}|], +//// [|hello|]() {}, //// someOtherFunction() {} //// }; //// } //// //// var y: Foo = { -//// [|hello() {}|], +//// [|hello|]() {}, //// someOtherFunction() {} //// }; //// diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts index d2038f99efd..ed1a4b34f50 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_08.ts @@ -7,7 +7,7 @@ //// } //// //// class SuperBar implements Foo { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// class Bar extends SuperBar { @@ -15,7 +15,7 @@ //// } //// //// class SubBar extends Bar { -//// [|hello() {}|] +//// [|hello|]() {} //// } diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts index 84c57ec2bce..b507be3fe2b 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_09.ts @@ -20,7 +20,7 @@ //// } //// //// class SuperBar extends MegaBar { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// class MegaBar implements Foo { diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts index 0604d2511f2..ebc0f0e713a 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_10.ts @@ -16,7 +16,7 @@ //// } //// //// class FooImpl implements Foo { -//// [|hello() {/**FooImpl*/}|] +//// [|hello|]() {/**FooImpl*/} //// aloha() {} //// } //// @@ -25,12 +25,12 @@ //// } //// //// class BarImpl implements Bar { -//// [|hello() {/**BarImpl*/}|] +//// [|hello|]() {/**BarImpl*/} //// goodbye() {} //// } //// //// class FooAndBarImpl implements Foo, Bar { -//// [|hello() {/**FooAndBarImpl*/}|] +//// [|hello|]() {/**FooAndBarImpl*/} //// aloha() {} //// goodbye() {} //// } diff --git a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts index 9528aa409b4..07f06a6d76d 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceMethod_11.ts @@ -6,7 +6,7 @@ //// hel/*reference*/lo(): void; //// } //// -//// var x = { [|hello: () => {}|] }; -//// var y = (((({ [|hello: () => {}|] })))); +//// var x = { [|hello|]: () => {} }; +//// var y = (((({ [|hello|]: () => {} })))); verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts index 70e49c10b45..547d14d493e 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_00.ts @@ -6,17 +6,17 @@ //// hello: number //// } //// -//// var bar: Foo = { [|hello: 5|] }; +//// var bar: Foo = { [|hello|]: 5 }; //// //// -//// function whatever(x: Foo = { [|hello: 5 * 9|] }) { +//// function whatever(x: Foo = { [|hello|]: 5 * 9 }) { //// x.he/*reference*/llo //// } //// //// class Bar { -//// x: Foo = { [|hello: 6|] } +//// x: Foo = { [|hello|]: 6 } //// -//// constructor(public f: Foo = { [|hello: 7|] } ) {} +//// constructor(public f: Foo = { [|hello|]: 7 } ) {} //// } verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file diff --git a/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts index 14b80362917..46cb696d3de 100644 --- a/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts +++ b/tests/cases/fourslash/goToImplementationInterfaceProperty_01.ts @@ -5,7 +5,7 @@ //// interface Foo { hello: number } //// //// class Bar implements Foo { -//// [|hello = 5 * 9;|] +//// [|hello|] = 5 * 9; //// } //// //// function whatever(foo: Foo) { diff --git a/tests/cases/fourslash/goToImplementationInterface_01.ts b/tests/cases/fourslash/goToImplementationInterface_01.ts index 62d01da6ca8..9f76e9db5cd 100644 --- a/tests/cases/fourslash/goToImplementationInterface_01.ts +++ b/tests/cases/fourslash/goToImplementationInterface_01.ts @@ -2,13 +2,13 @@ //// interface Fo/*interface_definition*/o { hello(): void } //// -//// [|class SuperBar implements Foo { +//// class [|SuperBar|] implements Foo { //// hello () {} -//// }|] +//// } //// -//// [|abstract class AbstractBar implements Foo { +//// abstract class [|AbstractBar|] implements Foo { //// abstract hello (): void; -//// }|] +//// } //// //// class Bar extends SuperBar { //// } diff --git a/tests/cases/fourslash/goToImplementationInterface_07.ts b/tests/cases/fourslash/goToImplementationInterface_07.ts index 960072004b4..3ebf76d1e3e 100644 --- a/tests/cases/fourslash/goToImplementationInterface_07.ts +++ b/tests/cases/fourslash/goToImplementationInterface_07.ts @@ -20,11 +20,11 @@ //// let x8: Foo[] = [|[{ hello () { /**arrayType*/} }]|]; //// let x9: { y: Foo } = [|{ y: { hello () { /**typeLiteral*/} } }|]; //// let x10 = [|{|"parts": ["(","anonymous local class",")"], "kind": "local class"|}class implements Foo { hello() {} }|] -//// let x11 = [|{|"parts": ["(","local class",")"," ","C"], "kind": "local class"|}class C implements Foo { hello() {} }|] +//// let x11 = class [|{|"parts": ["(","local class",")"," ","C"], "kind": "local class"|}C|] implements Foo { hello() {} } //// //// // Should not do anything for type predicates //// function isFoo(a: any): a is Foo { //// return true; //// } -verify.allRangesAppearInImplementationList("interface_definition"); \ No newline at end of file +verify.allRangesAppearInImplementationList("interface_definition"); diff --git a/tests/cases/fourslash/goToImplementationInterface_08.ts b/tests/cases/fourslash/goToImplementationInterface_08.ts index 652cfe46246..470776c737b 100644 --- a/tests/cases/fourslash/goToImplementationInterface_08.ts +++ b/tests/cases/fourslash/goToImplementationInterface_08.ts @@ -11,7 +11,7 @@ //// interface C extends B, A {} //// //// class X implements B { -//// [|hello() {}|] +//// [|hello|]() {} //// } //// //// function someFunction(d : A) { diff --git a/tests/cases/fourslash/goToImplementationLocal_00.ts b/tests/cases/fourslash/goToImplementationLocal_00.ts index b97fadfcb02..f5e01b89cee 100644 --- a/tests/cases/fourslash/goToImplementationLocal_00.ts +++ b/tests/cases/fourslash/goToImplementationLocal_00.ts @@ -3,6 +3,6 @@ // Should return definition of locally declared functions //// he/*function_call*/llo(); -//// [|function hello() {}|] +//// function [|hello|]() {} -verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); diff --git a/tests/cases/fourslash/goToImplementationLocal_01.ts b/tests/cases/fourslash/goToImplementationLocal_01.ts index 0bda3418354..fe83db9b887 100644 --- a/tests/cases/fourslash/goToImplementationLocal_01.ts +++ b/tests/cases/fourslash/goToImplementationLocal_01.ts @@ -2,7 +2,7 @@ // Should return the defintion of locally defined variables -//// const [|hello = function() {}|]; +//// const [|hello|] = function() {}; //// he/*function_call*/llo(); -verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); diff --git a/tests/cases/fourslash/goToImplementationLocal_02.ts b/tests/cases/fourslash/goToImplementationLocal_02.ts index 62bb8a71a10..6ec1bf0380d 100644 --- a/tests/cases/fourslash/goToImplementationLocal_02.ts +++ b/tests/cases/fourslash/goToImplementationLocal_02.ts @@ -1,8 +1,8 @@ /// -//// const x = { [|hello: () => {}|] }; +//// const x = { [|hello|]: () => {} }; //// //// x.he/*function_call*/llo(); //// -verify.allRangesAppearInImplementationList("function_call"); \ No newline at end of file +verify.allRangesAppearInImplementationList("function_call"); diff --git a/tests/cases/fourslash/goToImplementationLocal_03.ts b/tests/cases/fourslash/goToImplementationLocal_03.ts index d3f25ea29dc..6f40437a8bb 100644 --- a/tests/cases/fourslash/goToImplementationLocal_03.ts +++ b/tests/cases/fourslash/goToImplementationLocal_03.ts @@ -2,11 +2,11 @@ // Should return the definition when invoked on variable assignment -//// let [|he/*local_var*/llo = {}|]; +//// let [|he/*local_var*/llo|] = {}; //// //// x.hello(); //// //// hello = {}; //// -verify.allRangesAppearInImplementationList("local_var"); \ No newline at end of file +verify.allRangesAppearInImplementationList("local_var"); diff --git a/tests/cases/fourslash/goToImplementationLocal_04.ts b/tests/cases/fourslash/goToImplementationLocal_04.ts index 9de9dcd0a9f..e564a375592 100644 --- a/tests/cases/fourslash/goToImplementationLocal_04.ts +++ b/tests/cases/fourslash/goToImplementationLocal_04.ts @@ -2,9 +2,9 @@ // Should return definition of function when invoked on the declaration -//// [|function he/*local_var*/llo() {}|] +//// function [|he/*local_var*/llo|]() {} //// //// hello(); //// -verify.allRangesAppearInImplementationList("local_var"); \ No newline at end of file +verify.allRangesAppearInImplementationList("local_var"); diff --git a/tests/cases/fourslash/goToImplementationLocal_05.ts b/tests/cases/fourslash/goToImplementationLocal_05.ts index 969f4c25fc7..c8e07ab7a74 100644 --- a/tests/cases/fourslash/goToImplementationLocal_05.ts +++ b/tests/cases/fourslash/goToImplementationLocal_05.ts @@ -6,7 +6,7 @@ //// public hello() {} //// } //// -//// var [|someVar = new Bar()|]; +//// var [|someVar|] = new Bar(); //// someVa/*reference*/r.hello(); -verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationLocal_06.ts b/tests/cases/fourslash/goToImplementationLocal_06.ts index acdbaffc36f..90c489bcf54 100644 --- a/tests/cases/fourslash/goToImplementationLocal_06.ts +++ b/tests/cases/fourslash/goToImplementationLocal_06.ts @@ -2,7 +2,7 @@ // Should be able to go to ambient variable declarations -//// declare var [|someVar: string|]; +//// declare var [|someVar|]: string; //// someVa/*reference*/r -verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationLocal_07.ts b/tests/cases/fourslash/goToImplementationLocal_07.ts index 3556c25abc0..b24b463e107 100644 --- a/tests/cases/fourslash/goToImplementationLocal_07.ts +++ b/tests/cases/fourslash/goToImplementationLocal_07.ts @@ -2,7 +2,7 @@ // Should be able to go to ambient function declarations -//// [|declare function someFunction(): () => void;|] +//// declare function [|someFunction|](): () => void; //// someFun/*reference*/ction(); -verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationLocal_08.ts b/tests/cases/fourslash/goToImplementationLocal_08.ts index 3556c25abc0..b24b463e107 100644 --- a/tests/cases/fourslash/goToImplementationLocal_08.ts +++ b/tests/cases/fourslash/goToImplementationLocal_08.ts @@ -2,7 +2,7 @@ // Should be able to go to ambient function declarations -//// [|declare function someFunction(): () => void;|] +//// declare function [|someFunction|](): () => void; //// someFun/*reference*/ction(); -verify.allRangesAppearInImplementationList("reference"); \ No newline at end of file +verify.allRangesAppearInImplementationList("reference"); diff --git a/tests/cases/fourslash/goToImplementationNamespace_00.ts b/tests/cases/fourslash/goToImplementationNamespace_00.ts index 5b71b7bbf9f..c1e05398e22 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_00.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_00.ts @@ -2,11 +2,11 @@ // Should handle namespace and module implementations -//// /*implementation0*/namespace Foo { +//// namespace /*implementation0*/Foo { //// export function hello() {} //// } //// -//// /*implementation1*/module Bar { +//// module /*implementation1*/Bar { //// export function sure() {} //// } //// diff --git a/tests/cases/fourslash/goToImplementationNamespace_01.ts b/tests/cases/fourslash/goToImplementationNamespace_01.ts index b2e267d5378..7d1d36ecde7 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_01.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_01.ts @@ -3,7 +3,7 @@ // Should handle property access expressions on namespaces //// namespace Foo { -//// [|export function hello() {}|] +//// export function [|hello|]() {} //// } //// //// Foo.hell/*reference*/o(); diff --git a/tests/cases/fourslash/goToImplementationNamespace_02.ts b/tests/cases/fourslash/goToImplementationNamespace_02.ts index 2d2ae960a99..c2c4318493e 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_02.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_02.ts @@ -3,7 +3,7 @@ // Should handle property access expressions on namespaces //// module Foo { -//// [|export function hello() {}|] +//// export function [|hello|]() {} //// } //// //// Foo.hell/*reference*/o(); diff --git a/tests/cases/fourslash/goToImplementationNamespace_03.ts b/tests/cases/fourslash/goToImplementationNamespace_03.ts index 751d182ec00..1cc6039933d 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_03.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_03.ts @@ -7,14 +7,14 @@ //// hello(): void; //// } //// -//// [|class BarImpl implements Bar { +//// class [|BarImpl|] implements Bar { //// hello() {} -//// }|] +//// } //// } //// -//// [|class Baz implements Foo.Bar { +//// class [|Baz|] implements Foo.Bar { //// hello() {} -//// }|] +//// } //// //// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; //// diff --git a/tests/cases/fourslash/goToImplementationNamespace_04.ts b/tests/cases/fourslash/goToImplementationNamespace_04.ts index ac0b85e43fe..557b690a42d 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_04.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_04.ts @@ -7,14 +7,14 @@ //// hello(): void; //// } //// -//// [|class BarImpl implements Bar { +//// class [|BarImpl|] implements Bar { //// hello() {} -//// }|] +//// } //// } //// -//// [|class Baz implements Foo.Bar { +//// class [|Baz|] implements Foo.Bar { //// hello() {} -//// }|] +//// } //// //// var someVar1 : Foo.Bar = [|{ hello: () => {/**1*/} }|]; //// diff --git a/tests/cases/fourslash/goToImplementationNamespace_05.ts b/tests/cases/fourslash/goToImplementationNamespace_05.ts index 6936b79bd9b..6fcdb7a396d 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_05.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_05.ts @@ -2,11 +2,11 @@ // Should handle namespace and module implementations with qualified names -//// /*implementation0*/namespace Foo./*implementation2*/Baz { +//// namespace /*implementation0*/Foo./*implementation2*/Baz { //// export function hello() {} //// } //// -//// /*implementation1*/module Bar./*implementation3*/Baz { +//// module /*implementation1*/Bar./*implementation3*/Baz { //// export function sure() {} //// } //// diff --git a/tests/cases/fourslash/goToImplementationNamespace_06.ts b/tests/cases/fourslash/goToImplementationNamespace_06.ts index f5e52d90b1c..62ee4999758 100644 --- a/tests/cases/fourslash/goToImplementationNamespace_06.ts +++ b/tests/cases/fourslash/goToImplementationNamespace_06.ts @@ -2,9 +2,9 @@ // Should handle type queries -//// [|namespace F/*declaration*/oo { +//// namespace [|F/*declaration*/oo|] { //// declare function hello(): void; -//// }|] +//// } //// //// //// let x: typeof Foo = [|{ hello() {} }|]; diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts index ad4a0cd6b51..4fed473c46b 100644 --- a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_00.ts @@ -14,7 +14,7 @@ //// Foo: FooConstructor; //// } //// -//// var x = /*classExpression*/class Foo { +//// var x = class /*classExpression*/Foo { //// createBarInClassExpression(): Bar { //// return { //// Fo/*classExpressionRef*/o @@ -24,7 +24,7 @@ //// someFunction() {} //// } //// -//// /*declaredClass*/class Foo { +//// class /*declaredClass*/Foo { //// //// } //// @@ -40,4 +40,4 @@ verify.caretAtMarker("classExpression"); goTo.marker("declaredClassRef"); goTo.implementation(); -verify.caretAtMarker("declaredClass"); \ No newline at end of file +verify.caretAtMarker("declaredClass"); diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts index fb4763619a4..23af9ea1591 100644 --- a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_01.ts @@ -15,7 +15,7 @@ //// } //// //// // Class expression that gets used in a bar implementation -//// var x = [|class Foo { +//// var x = class [|Foo|] { //// createBarInClassExpression(): Bar { //// return { //// Foo @@ -23,13 +23,13 @@ //// } //// //// someFunction() {} -//// }|]; +//// }; //// //// // Class declaration that gets used in a bar implementation. This class has multiple definitions //// // (the class declaration and the interface above), but we only want the class returned -//// [|class Foo { +//// class [|Foo|] { //// -//// }|] +//// } //// //// function createBarUsingClassDeclaration(): Bar { //// return { diff --git a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts index a27480c8272..30542c0c52b 100644 --- a/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts +++ b/tests/cases/fourslash/goToImplementationShorthandPropertyAssignment_02.ts @@ -11,7 +11,7 @@ //// hello //// }; //// -//// [|function hello() {}|] +//// function [|hello|]() {} //// } //// //// function whatever(x: Foo) { diff --git a/tests/cases/fourslash/goToImplementationSuper_00.ts b/tests/cases/fourslash/goToImplementationSuper_00.ts index 53377bdcdb0..16e059e43f1 100644 --- a/tests/cases/fourslash/goToImplementationSuper_00.ts +++ b/tests/cases/fourslash/goToImplementationSuper_00.ts @@ -2,9 +2,9 @@ // Should go to super class declaration when invoked on a super call expression -//// [|class Foo { +//// class [|Foo|] { //// constructor() {} -//// }|] +//// } //// //// class Bar extends Foo { //// constructor() { diff --git a/tests/cases/fourslash/goToImplementationSuper_01.ts b/tests/cases/fourslash/goToImplementationSuper_01.ts index fffa7caf716..6313b3930d9 100644 --- a/tests/cases/fourslash/goToImplementationSuper_01.ts +++ b/tests/cases/fourslash/goToImplementationSuper_01.ts @@ -2,9 +2,9 @@ // Should go to the super class declaration when invoked on the super keyword in a property access expression -//// [|class Foo { +//// class [|Foo|] { //// hello() {} -//// }|] +//// } //// //// class Bar extends Foo { //// hello() { diff --git a/tests/cases/fourslash/goToImplementationThis_00.ts b/tests/cases/fourslash/goToImplementationThis_00.ts index 19212c9a77a..5162eee9b46 100644 --- a/tests/cases/fourslash/goToImplementationThis_00.ts +++ b/tests/cases/fourslash/goToImplementationThis_00.ts @@ -2,12 +2,12 @@ // Should go to class declaration when invoked on this keyword in property access expression -//// [|class Bar extends Foo { +//// class [|Bar|] extends Foo { //// hello() { //// thi/*this_call*/s.whatever(); //// } //// //// whatever() {} -//// }|] +//// } -verify.allRangesAppearInImplementationList("this_call"); \ No newline at end of file +verify.allRangesAppearInImplementationList("this_call"); diff --git a/tests/cases/fourslash/goToImplementationThis_01.ts b/tests/cases/fourslash/goToImplementationThis_01.ts index 6761c6ec6c9..cd5ab3bfaaa 100644 --- a/tests/cases/fourslash/goToImplementationThis_01.ts +++ b/tests/cases/fourslash/goToImplementationThis_01.ts @@ -2,10 +2,10 @@ // Should go to class declaration when invoked on a this type reference -//// [|class Bar extends Foo { +//// class [|Bar|] extends Foo { //// hello(): th/*this_type*/is { //// return this; //// } -//// }|] +//// } -verify.allRangesAppearInImplementationList("this_type"); \ No newline at end of file +verify.allRangesAppearInImplementationList("this_type"); diff --git a/tests/cases/fourslash/jsdocReturnsTag.ts b/tests/cases/fourslash/jsdocReturnsTag.ts index e91d3509222..3f78e275e93 100644 --- a/tests/cases/fourslash/jsdocReturnsTag.ts +++ b/tests/cases/fourslash/jsdocReturnsTag.ts @@ -17,7 +17,7 @@ verify.signatureHelp({ text: "find(l: T[], x: T): T", docComment: "Find an item", tags: [ - // TODO: GH#24130 + // TODO: GH#24130 (see PR #24600's commits for potential fix) { name: "template", text: "T\n " }, { name: "param", text: "l" }, { name: "param", text: "x" }, diff --git a/tests/cases/fourslash/moveToNewFile.ts b/tests/cases/fourslash/moveToNewFile.ts index 8caa8538a13..9175e37889d 100644 --- a/tests/cases/fourslash/moveToNewFile.ts +++ b/tests/cases/fourslash/moveToNewFile.ts @@ -4,7 +4,7 @@ ////import './foo'; ////import { a, b, alreadyUnused } from './other'; ////const p = 0; -////[|const y = p + b;|] +////[|const y: Date = p + b;|] ////a; y; verify.moveToNewFile({ @@ -20,7 +20,7 @@ a; y;`, "/y.ts": `import { b } from './other'; import { p } from './a'; -export const y = p + b;`, +export const y: Date = p + b;`, }, preferences: { diff --git a/tests/cases/fourslash/moveToNewFile_namespaceImport.ts b/tests/cases/fourslash/moveToNewFile_namespaceImport.ts new file mode 100644 index 00000000000..152d1fcaeb5 --- /dev/null +++ b/tests/cases/fourslash/moveToNewFile_namespaceImport.ts @@ -0,0 +1,49 @@ +/// + +// @allowJs: true + +// @Filename: /a.ts +////[|export const x = 0;|] +////export const y = 0; + +// @Filename: /b.ts +////import * as a from "./a"; +////a.x; +////a.y; + +// @Filename: /c.ts +////import a = require("./a"); +////a.x; +////a.y; + +// @Filename: /d.js +////const a = require("./a"); +////a.x; +////a.y; + +verify.moveToNewFile({ + newFileContents: { + "/a.ts": +`export const y = 0;`, + + "/x.ts": +`export const x = 0;`, + + "/b.ts": +`import * as a from "./a"; +import * as x from "./x"; +x.x; +a.y;`, + + "/c.ts": +`import a = require("./a"); +import x = require("./x"); +x.x; +a.y;`, + + "/d.js": +`const a = require("./a"), x = require("./x"); +x.x; +a.y;`, + }, +}); diff --git a/tests/cases/fourslash/quickInfoJsDocTags.ts b/tests/cases/fourslash/quickInfoJsDocTags.ts index ce045ab2940..798a850a310 100644 --- a/tests/cases/fourslash/quickInfoJsDocTags.ts +++ b/tests/cases/fourslash/quickInfoJsDocTags.ts @@ -5,7 +5,7 @@ //// * Doc //// * @author Me //// * @augments {C} Augments it -//// * @template {T} A template +//// * @template T A template //// * @type {number | string} A type //// * @typedef {number | string} NumOrStr //// * @property {number} x The prop diff --git a/tests/cases/fourslash/server/goToImplementation_inDifferentFiles.ts b/tests/cases/fourslash/server/goToImplementation_inDifferentFiles.ts index e4289b83102..591e8de3608 100644 --- a/tests/cases/fourslash/server/goToImplementation_inDifferentFiles.ts +++ b/tests/cases/fourslash/server/goToImplementation_inDifferentFiles.ts @@ -3,13 +3,13 @@ // @Filename: /bar.ts ////import {Foo} from './foo' //// -////[|class A implements Foo { +////class [|A|] implements Foo { //// func() {} -////}|] +////} //// -////[|class B implements Foo { +////class [|B|] implements Foo { //// func() {} -////}|] +////} // @Filename: /foo.ts ////export interface /**/Foo { diff --git a/tests/cases/fourslash/server/implementation01.ts b/tests/cases/fourslash/server/implementation01.ts index 24d5f935bda..ddd8c792324 100644 --- a/tests/cases/fourslash/server/implementation01.ts +++ b/tests/cases/fourslash/server/implementation01.ts @@ -1,8 +1,7 @@ /// -// @Filename: a.ts -//// interface Fo/*1*/o {} -//// /*2*/class Bar implements Foo {} +////interface Fo/*1*/o {} +////class /*2*/Bar implements Foo {} goTo.marker('1'); goTo.implementation(); diff --git a/tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts b/tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts index a509922f919..22de573d2c9 100644 --- a/tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts +++ b/tests/cases/fourslash/shims-pp/getImplementationAtPosition.ts @@ -1,9 +1,9 @@ -/// +/// // @Filename: goToImplementationDifferentFile_Implementation.ts -//// /*fooClassImplementation*/class FooImpl implements Foo {} +//// class /*fooClassImplementation*/FooImpl implements Foo {} //// -//// /*barClassImplementation*/class Bar { +//// class /*barClassImplementation*/Bar { //// /*barHelloFunctionImplementation*/hello() {} //// } //// @@ -15,21 +15,14 @@ //// //// x.hel/*barHelloFunctionReference*/lo(); //// -//// /*thisImplementation*/class SomeClass { +//// class /*thisImplementation*/SomeClass { //// someMethod() { //// thi/*thisReference*/s.someMethod(); //// } //// } -var markerList = [ - "fooClass", - "barClass", - "barHelloFunction", - "this" -]; - -markerList.forEach((marker) => { +for (const marker of ["fooClass", "barClass", "barHelloFunction", "this"]) { goTo.marker(marker + 'Reference'); goTo.implementation(); verify.caretAtMarker(marker + 'Implementation'); -}); +}; diff --git a/tests/cases/fourslash/shims/getImplementationAtPosition.ts b/tests/cases/fourslash/shims/getImplementationAtPosition.ts index a509922f919..22de573d2c9 100644 --- a/tests/cases/fourslash/shims/getImplementationAtPosition.ts +++ b/tests/cases/fourslash/shims/getImplementationAtPosition.ts @@ -1,9 +1,9 @@ -/// +/// // @Filename: goToImplementationDifferentFile_Implementation.ts -//// /*fooClassImplementation*/class FooImpl implements Foo {} +//// class /*fooClassImplementation*/FooImpl implements Foo {} //// -//// /*barClassImplementation*/class Bar { +//// class /*barClassImplementation*/Bar { //// /*barHelloFunctionImplementation*/hello() {} //// } //// @@ -15,21 +15,14 @@ //// //// x.hel/*barHelloFunctionReference*/lo(); //// -//// /*thisImplementation*/class SomeClass { +//// class /*thisImplementation*/SomeClass { //// someMethod() { //// thi/*thisReference*/s.someMethod(); //// } //// } -var markerList = [ - "fooClass", - "barClass", - "barHelloFunction", - "this" -]; - -markerList.forEach((marker) => { +for (const marker of ["fooClass", "barClass", "barHelloFunction", "this"]) { goTo.marker(marker + 'Reference'); goTo.implementation(); verify.caretAtMarker(marker + 'Implementation'); -}); +};