diff --git a/.mailmap b/.mailmap index 4f27b3087b8..774aa4174c3 100644 --- a/.mailmap +++ b/.mailmap @@ -139,7 +139,6 @@ Michael Mike Busyrev Mine Starks Mine Starks Mohamed Hegazy -ncoley # Natalie Coley Nathan Shively-Sanders Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Nathan Yee Nima Zahedi diff --git a/Gulpfile.js b/Gulpfile.js index 1ba05048578..89fe32fed2e 100644 --- a/Gulpfile.js +++ b/Gulpfile.js @@ -128,7 +128,7 @@ const generatedLCGFile = "built/local/enu/diagnosticMessages.generated.json.lcg" * 2. 'src\compiler\diagnosticMessages.generated.json' => 'built\local\ENU\diagnosticMessages.generated.json.lcg' * generate the lcg file (source of messages to localize) from the diagnosticMessages.generated.json */ -const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"] +const localizationTargets = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"] .map(f => `built/local/${f}/diagnosticMessages.generated.json`) .concat(generatedLCGFile); diff --git a/Jakefile.js b/Jakefile.js index 0793659183b..ce5576036f4 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -21,7 +21,7 @@ else if (process.env.PATH !== undefined) { const host = process.env.TYPESCRIPT_HOST || process.env.host || "node"; -const locales = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-br", "ru", "tr", "zh-cn", "zh-tw"]; +const locales = ["cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]; const defaultTestTimeout = 40000; @@ -69,10 +69,10 @@ Paths.tsserverLibraryDefinitionFile = "built/local/tsserverlibrary.d.ts"; Paths.baselines = {}; Paths.baselines.local = "tests/baselines/local"; Paths.baselines.localTest262 = "tests/baselines/test262/local"; -Paths.baselines.localRwc = "tests/baselines/rwc/local"; +Paths.baselines.localRwc = "internal/baselines/rwc/local"; Paths.baselines.reference = "tests/baselines/reference"; Paths.baselines.referenceTest262 = "tests/baselines/test262/reference"; -Paths.baselines.referenceRwc = "tests/baselines/rwc/reference"; +Paths.baselines.referenceRwc = "internal/baselines/rwc/reference"; Paths.copyright = "CopyrightNotice.txt"; Paths.thirdParty = "ThirdPartyNoticeText.txt"; Paths.processDiagnosticMessagesJs = "scripts/processDiagnosticMessages.js"; @@ -174,7 +174,7 @@ task(TaskNames.lkg, [ if (sizeAfter > (sizeBefore * 1.10)) { throw new Error("The lib folder increased by 10% or more. This likely indicates a bug."); } - + complete(); }); }, { async: true }); @@ -349,7 +349,7 @@ file(Paths.servicesDefinitionFile, [TaskNames.coreBuild], function() { }, files }; - + const configFilePath = `built/local/typescriptServices.tsconfig.json`; fs.writeFileSync(configFilePath, JSON.stringify(config, undefined, 2)); tsbuild(configFilePath, false, () => { @@ -696,8 +696,8 @@ function diagnosticsToString(diagnostics, pretty) { /** * Concatenate a list of sourceFiles to a destinationFile - * @param {string} destinationFile - * @param {string[]} sourceFiles + * @param {string} destinationFile + * @param {string[]} sourceFiles * @param {string} extraContent */ function concatenateFiles(destinationFile, sourceFiles, extraContent) { @@ -724,8 +724,8 @@ function appendToFile(path, content) { } /** - * - * @param {string} path + * + * @param {string} path * @returns string */ function readFileSync(path) { @@ -742,7 +742,7 @@ function getDiffTool() { /** * Replaces const enum declarations with non-const enums - * @param {string} text + * @param {string} text */ function removeConstModifierFromEnumDeclarations(text) { return text.replace(/^(\s*)(export )?const enum (\S+) {(\s*)$/gm, '$1$2enum $3 {$4'); diff --git a/scripts/generateLocalizedDiagnosticMessages.ts b/scripts/generateLocalizedDiagnosticMessages.ts index 566eb557fd5..09d117d533b 100644 --- a/scripts/generateLocalizedDiagnosticMessages.ts +++ b/scripts/generateLocalizedDiagnosticMessages.ts @@ -65,11 +65,10 @@ function main(): void { * There are three exceptions, zh-CN, zh-TW and pt-BR. */ function getPreferedLocaleName(localeName: string) { - localeName = localeName.toLowerCase(); switch (localeName) { - case "zh-cn": - case "zh-tw": - case "pt-br": + case "zh-CN": + case "zh-TW": + case "pt-BR": return localeName; default: return localeName.split("-")[0]; diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ecf30690a0..3867a26c023 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2283,16 +2283,24 @@ namespace ts { } function errorOnImplicitAnyModule(isError: boolean, errorNode: Node, { packageId, resolvedFileName }: ResolvedModuleFull, moduleReference: string): void { - const errorInfo = packageId && chainDiagnosticMessages( - /*details*/ undefined, - Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, - getMangledNameForScopedPackage(packageId.name)); + const errorInfo = packageId + ? chainDiagnosticMessages( + /*details*/ undefined, + typesPackageExists(packageId.name) + ? Diagnostics.If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_0 + : Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, + getMangledNameForScopedPackage(packageId.name)) + : undefined; errorOrSuggestion(isError, errorNode, chainDiagnosticMessages( errorInfo, Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedFileName)); } + function typesPackageExists(packageName: string): boolean { + return host.getSourceFiles().some(sf => !!sf.resolvedModules && !!forEachEntry(sf.resolvedModules, r => + r && r.packageId && r.packageId.name === getTypesPackageName(packageName))); + } // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, // and an external module with no 'export =' declaration resolves to the module itself. @@ -2589,7 +2597,7 @@ namespace ts { return type; } - function createBooleanType(trueFalseTypes: Type[]): IntrinsicType & UnionType { + function createBooleanType(trueFalseTypes: ReadonlyArray): IntrinsicType & UnionType { const type = getUnionType(trueFalseTypes); type.flags |= TypeFlags.Boolean; type.intrinsicName = "boolean"; @@ -2631,7 +2639,7 @@ namespace ts { return result || emptyArray; } - function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType { + function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: ReadonlyArray, constructSignatures: ReadonlyArray, stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType { (type).members = members; (type).properties = getNamedMembers(members); (type).callSignatures = callSignatures; @@ -2641,7 +2649,7 @@ namespace ts { return type; } - function createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType { + function createAnonymousType(symbol: Symbol | undefined, members: SymbolTable, callSignatures: ReadonlyArray, constructSignatures: ReadonlyArray, stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType { return setStructuredTypeMembers(createObjectType(ObjectFlags.Anonymous, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } @@ -3387,7 +3395,7 @@ namespace ts { } function typeReferenceToTypeNode(type: TypeReference) { - const typeArguments: Type[] = type.typeArguments || emptyArray; + const typeArguments: ReadonlyArray = type.typeArguments || emptyArray; if (type.target === globalArrayType) { if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) { const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context); @@ -3583,7 +3591,7 @@ namespace ts { } } - function mapToTypeNodes(types: Type[] | undefined, context: NodeBuilderContext): TypeNode[] | undefined { + function mapToTypeNodes(types: ReadonlyArray | undefined, context: NodeBuilderContext): TypeNode[] | undefined { if (some(types)) { const result = []; for (const type of types) { @@ -3992,7 +4000,7 @@ namespace ts { } } - function formatUnionTypes(types: Type[]): Type[] { + function formatUnionTypes(types: ReadonlyArray): Type[] { const result: Type[] = []; let flags: TypeFlags = 0; for (let i = 0; i < types.length; i++) { @@ -4110,15 +4118,14 @@ namespace ts { if (declaration.parent && declaration.parent.kind === SyntaxKind.VariableDeclaration) { return declarationNameToString((declaration.parent).name); } - if (context && !context.encounteredError && !(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier)) { - context.encounteredError = true; - } switch (declaration.kind) { case SyntaxKind.ClassExpression: - return "(Anonymous class)"; case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: - return "(Anonymous function)"; + if (context && !context.encounteredError && !(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier)) { + context.encounteredError = true; + } + return declaration.kind === SyntaxKind.ClassExpression ? "(Anonymous class)" : "(Anonymous function)"; } } const nameType = symbol.nameType; @@ -5393,26 +5400,17 @@ namespace ts { } function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments | undefined { - const decl = type.symbol.valueDeclaration; - if (isInJavaScriptFile(decl)) { - // Prefer an @augments tag because it may have type parameters. - const tag = getJSDocAugmentsTag(decl); - if (tag) { - return tag.class; - } - } - - return getClassExtendsHeritageClauseElement(decl); + return getEffectiveBaseTypeNode(type.symbol.valueDeclaration as ClassLikeDeclaration); } - function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): Signature[] { + function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): ReadonlyArray { const typeArgCount = length(typeArgumentNodes); const isJavaScript = isInJavaScriptFile(location); return filter(getSignaturesOfType(type, SignatureKind.Construct), sig => (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= length(sig.typeParameters)); } - function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): Signature[] { + function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: ReadonlyArray | undefined, location: Node): ReadonlyArray { const signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); const typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); return sameMap(signatures, sig => some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, isInJavaScriptFile(location)) : sig); @@ -5429,7 +5427,7 @@ namespace ts { function getBaseConstructorTypeOfClass(type: InterfaceType): Type { if (!type.resolvedBaseConstructorType) { const decl = type.symbol.valueDeclaration; - const extended = getClassExtendsHeritageClauseElement(decl); + const extended = getEffectiveBaseTypeNode(decl); const baseTypeNode = getBaseTypeNodeOfClass(type); if (!baseTypeNode) { return type.resolvedBaseConstructorType = undefinedType; @@ -6162,11 +6160,11 @@ namespace ts { return needApparentType ? getApparentType(type) : type; } - function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: TypeParameter[], typeArguments: Type[]) { + function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: ReadonlyArray, typeArguments: ReadonlyArray) { let mapper: TypeMapper; let members: SymbolTable; - let callSignatures: Signature[]; - let constructSignatures: Signature[] | undefined; + let callSignatures: ReadonlyArray; + let constructSignatures: ReadonlyArray | undefined; let stringIndexInfo: IndexInfo | undefined; let numberIndexInfo: IndexInfo | undefined; if (rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) { @@ -6222,9 +6220,9 @@ namespace ts { function createSignature( declaration: SignatureDeclaration | JSDocSignature | undefined, - typeParameters: TypeParameter[] | undefined, + typeParameters: ReadonlyArray | undefined, thisParameter: Symbol | undefined, - parameters: Symbol[], + parameters: ReadonlyArray, resolvedReturnType: Type | undefined, resolvedTypePredicate: TypePredicate | undefined, minArgumentCount: number, @@ -6275,7 +6273,7 @@ namespace ts { return result; } - function findMatchingSignature(signatureList: Signature[], signature: Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean): Signature | undefined { + function findMatchingSignature(signatureList: ReadonlyArray, signature: Signature, partialMatch: boolean, ignoreThisTypes: boolean, ignoreReturnTypes: boolean): Signature | undefined { for (const s of signatureList) { if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypesIdentical)) { return s; @@ -6283,7 +6281,7 @@ namespace ts { } } - function findMatchingSignatures(signatureLists: Signature[][], signature: Signature, listIndex: number): Signature[] | undefined { + function findMatchingSignatures(signatureLists: ReadonlyArray>, signature: Signature, listIndex: number): Signature[] | undefined { if (signature.typeParameters) { // We require an exact match for generic signatures, so we only return signatures from the first // signature list and only if they have exact matches in the other signature lists. @@ -6313,7 +6311,7 @@ namespace ts { // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional // parameters and may differ in return types. When signatures differ in return types, the resulting return // type is the union of the constituent return types. - function getUnionSignatures(types: Type[], kind: SignatureKind): Signature[] { + function getUnionSignatures(types: ReadonlyArray, kind: SignatureKind): Signature[] { const signatureLists = map(types, t => getSignaturesOfType(t, kind)); let result: Signature[] | undefined; for (let i = 0; i < signatureLists.length; i++) { @@ -6343,7 +6341,7 @@ namespace ts { return result || emptyArray; } - function getUnionIndexInfo(types: Type[], kind: IndexKind): IndexInfo | undefined { + function getUnionIndexInfo(types: ReadonlyArray, kind: IndexKind): IndexInfo | undefined { const indexTypes: Type[] = []; let isAnyReadonly = false; for (const type of types) { @@ -6383,7 +6381,7 @@ namespace ts { getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly); } - function includeMixinType(type: Type, types: Type[], index: number): Type { + function includeMixinType(type: Type, types: ReadonlyArray, index: number): Type { const mixedTypes: Type[] = []; for (let i = 0; i < types.length; i++) { if (i === index) { @@ -6399,8 +6397,8 @@ namespace ts { function resolveIntersectionTypeMembers(type: IntersectionType) { // The members and properties collections are empty for intersection types. To get all properties of an // intersection type use getPropertiesOfType (only the language service uses this). - let callSignatures: Signature[] = emptyArray; - let constructSignatures: Signature[] = emptyArray; + let callSignatures: ReadonlyArray = emptyArray; + let constructSignatures: ReadonlyArray = emptyArray; let stringIndexInfo: IndexInfo | undefined; let numberIndexInfo: IndexInfo | undefined; const types = type.types; @@ -6738,7 +6736,7 @@ namespace ts { getPropertiesOfObjectType(type); } - function getAllPossiblePropertiesOfTypes(types: Type[]): Symbol[] { + function getAllPossiblePropertiesOfTypes(types: ReadonlyArray): Symbol[] { const unionType = getUnionType(types); if (!(unionType.flags & TypeFlags.Union)) { return getAugmentedPropertiesOfType(unionType); @@ -7142,7 +7140,7 @@ namespace ts { return undefined; } - function getSignaturesOfStructuredType(type: Type, kind: SignatureKind): Signature[] { + function getSignaturesOfStructuredType(type: Type, kind: SignatureKind): ReadonlyArray { if (type.flags & TypeFlags.StructuredType) { const resolved = resolveStructuredTypeMembers(type); return kind === SignatureKind.Call ? resolved.callSignatures : resolved.constructSignatures; @@ -7154,7 +7152,7 @@ namespace ts { * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and * maps primitive types and type parameters are to their apparent types. */ - function getSignaturesOfType(type: Type, kind: SignatureKind): Signature[] { + function getSignaturesOfType(type: Type, kind: SignatureKind): ReadonlyArray { return getSignaturesOfStructuredType(getApparentType(type), kind); } @@ -7289,7 +7287,7 @@ namespace ts { * Gets the minimum number of type arguments needed to satisfy all non-optional type * parameters. */ - function getMinTypeArgumentCount(typeParameters: TypeParameter[] | undefined): number { + function getMinTypeArgumentCount(typeParameters: ReadonlyArray | undefined): number { let minTypeArgumentCount = 0; if (typeParameters) { for (let i = 0; i < typeParameters.length; i++) { @@ -7309,9 +7307,9 @@ namespace ts { * @param typeParameters The requested type parameters. * @param minTypeArgumentCount The minimum number of required type arguments. */ - function fillMissingTypeArguments(typeArguments: Type[], typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[]; - function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[] | undefined; - function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean) { + function fillMissingTypeArguments(typeArguments: Type[], typeParameters: ReadonlyArray | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[]; + function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: ReadonlyArray | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean): Type[] | undefined; + function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: ReadonlyArray | undefined, minTypeArgumentCount: number, isJavaScriptImplicitAny: boolean) { const numTypeParameters = length(typeParameters); if (numTypeParameters) { const numTypeArguments = length(typeArguments); @@ -7606,7 +7604,9 @@ namespace ts { } function getSignatureInstantiation(signature: Signature, typeArguments: Type[] | undefined, isJavascript: boolean): Signature { - typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript)!; + return getSignatureInstantiationWithoutFillingInTypeArguments(signature, fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript)); + } + function getSignatureInstantiationWithoutFillingInTypeArguments(signature: Signature, typeArguments: ReadonlyArray | undefined): Signature { const instantiations = signature.instantiations || (signature.instantiations = createMap()); const id = getTypeListId(typeArguments); let instantiation = instantiations.get(id); @@ -7616,10 +7616,10 @@ namespace ts { return instantiation; } - function createSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature { + function createSignatureInstantiation(signature: Signature, typeArguments: ReadonlyArray | undefined): Signature { return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true); } - function createSignatureTypeMapper(signature: Signature, typeArguments: Type[]): TypeMapper { + function createSignatureTypeMapper(signature: Signature, typeArguments: ReadonlyArray | undefined): TypeMapper { return createTypeMapper(signature.typeParameters!, typeArguments); } @@ -7776,7 +7776,7 @@ namespace ts { return getSymbolOfNode(getDeclarationOfKind(typeParameter.symbol, SyntaxKind.TypeParameter)!.parent); } - function getTypeListId(types: Type[] | undefined) { + function getTypeListId(types: ReadonlyArray | undefined) { let result = ""; if (types) { const length = types.length; @@ -7804,7 +7804,7 @@ namespace ts { // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type // of an object literal or the anyFunctionType. This is because there are operations in the type checker // that care about the presence of such types at arbitrary depth in a containing type. - function getPropagatingFlagsOfTypes(types: Type[], excludeKinds: TypeFlags): TypeFlags { + function getPropagatingFlagsOfTypes(types: ReadonlyArray, excludeKinds: TypeFlags): TypeFlags { let result: TypeFlags = 0; for (const type of types) { if (!(type.flags & excludeKinds)) { @@ -7814,7 +7814,7 @@ namespace ts { return result & TypeFlags.PropagatingFlags; } - function createTypeReference(target: GenericType, typeArguments: Type[] | undefined): TypeReference { + function createTypeReference(target: GenericType, typeArguments: ReadonlyArray | undefined): TypeReference { const id = getTypeListId(typeArguments); let type = target.instantiations.get(id); if (!type) { @@ -8261,7 +8261,7 @@ namespace ts { /** * Instantiates a global type that is generic with some element type, and returns that instantiation. */ - function createTypeFromGenericGlobalType(genericGlobalType: GenericType, typeArguments: Type[]): ObjectType { + function createTypeFromGenericGlobalType(genericGlobalType: GenericType, typeArguments: ReadonlyArray): ObjectType { return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType; } @@ -8340,7 +8340,7 @@ namespace ts { return tupleTypes[arity] || (tupleTypes[arity] = createTupleTypeOfArity(arity)); } - function createTupleType(elementTypes: Type[]) { + function createTupleType(elementTypes: ReadonlyArray) { return createTypeReference(getTupleTypeOfArity(elementTypes.length), elementTypes); } @@ -8356,7 +8356,7 @@ namespace ts { return type.id; } - function containsType(types: Type[], type: Type): boolean { + function containsType(types: ReadonlyArray, type: Type): boolean { return binarySearch(types, type, getTypeId, compareValues) >= 0; } @@ -8420,14 +8420,14 @@ namespace ts { // Add the given types to the given type set. Order is preserved, duplicates are removed, // and nested types of the given kind are flattened into the set. - function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: Type[]): TypeFlags { + function addTypesToUnion(typeSet: Type[], includes: TypeFlags, types: ReadonlyArray): TypeFlags { for (const type of types) { includes = addTypeToUnion(typeSet, includes, type); } return includes; } - function containsIdenticalType(types: Type[], type: Type) { + function containsIdenticalType(types: ReadonlyArray, type: Type) { for (const t of types) { if (isTypeIdenticalTo(t, type)) { return true; @@ -8436,7 +8436,7 @@ namespace ts { return false; } - function isSubtypeOfAny(source: Type, targets: Type[]): boolean { + function isSubtypeOfAny(source: Type, targets: ReadonlyArray): boolean { for (const target of targets) { if (source !== target && isTypeSubtypeOf(source, target) && ( !(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) || @@ -8448,7 +8448,7 @@ namespace ts { return false; } - function isSetOfLiteralsFromSameEnum(types: Type[]): boolean { + function isSetOfLiteralsFromSameEnum(types: ReadonlyArray): boolean { const first = types[0]; if (first.flags & TypeFlags.EnumLiteral) { const firstEnum = getParentOfSymbol(first.symbol); @@ -8500,7 +8500,7 @@ namespace ts { // expression constructs such as array literals and the || and ?: operators). Named types can // circularly reference themselves and therefore cannot be subtype reduced during their declaration. // For example, "type Item = string | (() => Item" is a named type that circularly references itself. - function getUnionType(types: Type[], unionReduction: UnionReduction = UnionReduction.Literal, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { + function getUnionType(types: ReadonlyArray, unionReduction: UnionReduction = UnionReduction.Literal, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray): Type { if (types.length === 0) { return neverType; } @@ -8567,7 +8567,7 @@ namespace ts { } // This function assumes the constituent type list is sorted and deduplicated. - function getUnionTypeFromSortedList(types: Type[], unionOfUnitTypes: TypeFlags, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { + function getUnionTypeFromSortedList(types: Type[], unionOfUnitTypes: TypeFlags, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray): Type { if (types.length === 0) { return neverType; } @@ -8628,7 +8628,7 @@ namespace ts { // Add the given types to the given type set. Order is preserved, freshness is removed from literal // types, duplicates are removed, and nested types of the given kind are flattened into the set. - function addTypesToIntersection(typeSet: Type[], includes: TypeFlags, types: Type[]) { + function addTypesToIntersection(typeSet: Type[], includes: TypeFlags, types: ReadonlyArray) { for (const type of types) { includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(type)); } @@ -8683,7 +8683,7 @@ namespace ts { // a type alias of the form "type List = T & { next: List }" cannot be reduced during its declaration. // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution // for intersections of types with signatures can be deterministic. - function getIntersectionType(types: Type[], aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { + function getIntersectionType(types: ReadonlyArray, aliasSymbol?: Symbol, aliasTypeArguments?: ReadonlyArray): Type { const typeSet: Type[] = []; const includes = addTypesToIntersection(typeSet, 0, types); if (includes & TypeFlags.Never) { @@ -9586,9 +9586,9 @@ namespace ts { } } - function instantiateList(items: T[], mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[]; - function instantiateList(items: T[] | undefined, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] | undefined; - function instantiateList(items: T[] | undefined, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): T[] | undefined { + function instantiateList(items: ReadonlyArray, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): ReadonlyArray; + function instantiateList(items: ReadonlyArray | undefined, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): ReadonlyArray | undefined; + function instantiateList(items: ReadonlyArray | undefined, mapper: TypeMapper, instantiator: (item: T, mapper: TypeMapper) => T): ReadonlyArray | undefined { if (items && items.length) { for (let i = 0; i < items.length; i++) { const item = items[i]; @@ -9606,14 +9606,14 @@ namespace ts { return items; } - function instantiateTypes(types: Type[], mapper: TypeMapper): Type[]; - function instantiateTypes(types: Type[] | undefined, mapper: TypeMapper): Type[] | undefined; - function instantiateTypes(types: Type[] | undefined, mapper: TypeMapper) { - return instantiateList(types, mapper, instantiateType); + function instantiateTypes(types: ReadonlyArray, mapper: TypeMapper): ReadonlyArray; + function instantiateTypes(types: ReadonlyArray | undefined, mapper: TypeMapper): ReadonlyArray | undefined; + function instantiateTypes(types: ReadonlyArray | undefined, mapper: TypeMapper): ReadonlyArray | undefined { + return instantiateList(types, mapper, instantiateType); } - function instantiateSignatures(signatures: Signature[], mapper: TypeMapper): Signature[] { - return instantiateList(signatures, mapper, instantiateSignature); + function instantiateSignatures(signatures: ReadonlyArray, mapper: TypeMapper): ReadonlyArray { + return instantiateList(signatures, mapper, instantiateSignature); } function makeUnaryTypeMapper(source: Type, target: Type) { @@ -9624,7 +9624,7 @@ namespace ts { return (t: Type) => t === source1 ? target1 : t === source2 ? target2 : t; } - function makeArrayTypeMapper(sources: Type[], targets: Type[] | undefined) { + function makeArrayTypeMapper(sources: ReadonlyArray, targets: ReadonlyArray | undefined) { return (t: Type) => { for (let i = 0; i < sources.length; i++) { if (t === sources[i]) { @@ -9635,14 +9635,14 @@ namespace ts { }; } - function createTypeMapper(sources: TypeParameter[], targets: Type[] | undefined): TypeMapper { + function createTypeMapper(sources: ReadonlyArray, targets: ReadonlyArray | undefined): TypeMapper { Debug.assert(targets === undefined || sources.length === targets.length); return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : makeArrayTypeMapper(sources, targets); } - function createTypeEraser(sources: TypeParameter[]): TypeMapper { + function createTypeEraser(sources: ReadonlyArray): TypeMapper { return createTypeMapper(sources, /*targets*/ undefined); } @@ -9650,7 +9650,7 @@ namespace ts { * Maps forward-references to later types parameters to the empty object type. * This is used during inference when instantiating type parameter defaults. */ - function createBackreferenceMapper(typeParameters: TypeParameter[], index: number): TypeMapper { + function createBackreferenceMapper(typeParameters: ReadonlyArray, index: number): TypeMapper { return t => typeParameters.indexOf(t) >= index ? emptyObjectType : t; } @@ -12414,7 +12414,7 @@ namespace ts { } } - function createInferenceContext(typeParameters: TypeParameter[], signature: Signature | undefined, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext { + function createInferenceContext(typeParameters: ReadonlyArray, signature: Signature | undefined, flags: InferenceFlags, compareTypes?: TypeComparer, baseInferences?: InferenceInfo[]): InferenceContext { const inferences = baseInferences ? baseInferences.map(cloneInferenceInfo) : typeParameters.map(createInferenceInfo); const context = mapper as InferenceContext; context.typeParameters = typeParameters; @@ -14257,7 +14257,7 @@ namespace ts { if (!targetType) { // Target type is type of construct signature - let constructSignatures: Signature[] | undefined; + let constructSignatures: ReadonlyArray | undefined; if (getObjectFlags(rightType) & ObjectFlags.Interface) { constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; } @@ -14765,7 +14765,7 @@ namespace ts { function checkThisBeforeSuper(node: Node, container: Node, diagnosticMessage: DiagnosticMessage) { const containingClassDecl = container.parent; - const baseTypeNode = getClassExtendsHeritageClauseElement(containingClassDecl); + const baseTypeNode = getEffectiveBaseTypeNode(containingClassDecl); // If a containing class does not have extends clause or the class extends null // skip checking whether super statement is called before "this" accessing. @@ -15041,7 +15041,7 @@ namespace ts { // at this point the only legal case for parent is ClassLikeDeclaration const classLikeDeclaration = container.parent; - if (!getClassExtendsHeritageClauseElement(classLikeDeclaration)) { + if (!getEffectiveBaseTypeNode(classLikeDeclaration)) { error(node, Diagnostics.super_can_only_be_referenced_in_a_derived_class); return errorType; } @@ -16454,7 +16454,7 @@ namespace ts { return links.resolvedSymbol; } - function instantiateJsxSignatures(node: JsxOpeningLikeElement, signatures: Signature[]) { + function instantiateJsxSignatures(node: JsxOpeningLikeElement, signatures: ReadonlyArray) { const instantiatedSignatures = []; let candidateForTypeArgumentError: Signature | undefined; let hasTypeArgumentError: boolean = !!node.typeArguments; @@ -17684,7 +17684,7 @@ namespace ts { // interface B extends A { (x: 'foo'): string } // const b: B; // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void] - function reorderCandidates(signatures: Signature[], result: Signature[]): void { + function reorderCandidates(signatures: ReadonlyArray, result: Signature[]): void { let lastParent: Node | undefined; let lastSymbol: Symbol | undefined; let cutoffIndex = 0; @@ -17893,7 +17893,7 @@ namespace ts { // Above, the type of the 'value' parameter is inferred to be 'A'. const contextualSignature = getSingleCallSignature(instantiatedType); const inferenceSourceType = contextualSignature && contextualSignature.typeParameters ? - getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters, isInJavaScriptFile(node))) : + getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) : instantiatedType; const inferenceTargetType = getReturnTypeOfSignature(signature); // Inferences made from return types have lower priority than all other inferences. @@ -18383,7 +18383,7 @@ namespace ts { } } - function getTypeArgumentArityError(node: Node, signatures: Signature[], typeArguments: NodeArray) { + function getTypeArgumentArityError(node: Node, signatures: ReadonlyArray, typeArguments: NodeArray) { let min = Infinity; let max = -Infinity; for (const sig of signatures) { @@ -18394,7 +18394,7 @@ namespace ts { return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length); } - function resolveCall(node: CallLikeExpression, signatures: Signature[], candidatesOutArray: Signature[] | undefined, fallbackError?: DiagnosticMessage): Signature { + function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray, candidatesOutArray: Signature[] | undefined, fallbackError?: DiagnosticMessage): Signature { const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; const isDecorator = node.kind === SyntaxKind.Decorator; const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node); @@ -18679,7 +18679,7 @@ namespace ts { if (superType !== errorType) { // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated // with the type arguments specified in the extends clause. - const baseTypeNode = getClassExtendsHeritageClauseElement(getContainingClass(node)!); + const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!); if (baseTypeNode) { const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode); return resolveCall(node, baseConstructors, candidatesOutArray); @@ -18979,7 +18979,7 @@ namespace ts { * but is receiving too many arguments as part of the decorator invocation. * In those cases, a user may have meant to *call* the expression before using it as a decorator. */ - function isPotentiallyUncalledDecorator(decorator: Decorator, signatures: Signature[]) { + function isPotentiallyUncalledDecorator(decorator: Decorator, signatures: ReadonlyArray) { return signatures.length && every(signatures, signature => signature.minArgumentCount === 0 && !signature.hasRestParameter && @@ -21475,7 +21475,7 @@ namespace ts { // Constructors of classes with no extends clause may not contain super calls, whereas // constructors of derived classes must contain at least one super call somewhere in their function body. const containingClassDecl = node.parent; - if (getClassExtendsHeritageClauseElement(containingClassDecl)) { + if (getEffectiveBaseTypeNode(containingClassDecl)) { captureLexicalThis(node.parent, containingClassDecl); const classExtendsNull = classDeclarationExtendsNull(containingClassDecl); const superCall = getSuperCallInConstructor(node); @@ -21580,12 +21580,12 @@ namespace ts { checkDecorators(node); } - function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: TypeParameter[]): Type[] { + function getEffectiveTypeArguments(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: ReadonlyArray): Type[] { return fillMissingTypeArguments(map(node.typeArguments!, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isInJavaScriptFile(node)); } - function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: TypeParameter[]): boolean { + function checkTypeArgumentConstraints(node: TypeReferenceNode | ExpressionWithTypeArguments, typeParameters: ReadonlyArray): boolean { let typeArguments: Type[] | undefined; let mapper: TypeMapper | undefined; let result = true; @@ -22652,7 +22652,7 @@ namespace ts { } const name = getIdentifierFromEntityNameExpression(node.class.expression); - const extend = getClassExtendsHeritageClauseElement(classLike); + const extend = getClassExtendsHeritageElement(classLike); if (extend) { const className = getIdentifierFromEntityNameExpression(extend.expression); if (className && name.escapedText !== className.escapedText) { @@ -22815,11 +22815,7 @@ namespace ts { addDiagnostic(UnusedKind.Local, createDiagnosticForNode(node, message, name)); } - function parameterNameStartsWithUnderscore(parameterName: DeclarationName) { - return parameterName && isIdentifierThatStartsWithUnderScore(parameterName); - } - - function isIdentifierThatStartsWithUnderScore(node: Node) { + function isIdentifierThatStartsWithUnderscore(node: Node) { return isIdentifier(node) && idText(node).charCodeAt(0) === CharacterCodes._; } @@ -22867,7 +22863,7 @@ namespace ts { const typeParameters = getEffectiveTypeParameterDeclarations(node); if (!(node.flags & NodeFlags.Ambient) && last(getSymbolOfNode(node).declarations) === node) { for (const typeParameter of typeParameters) { - if (!(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) { + if (!(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name)) { addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol))); } } @@ -22905,7 +22901,7 @@ namespace ts { for (const declaration of local.declarations) { if (isAmbientModule(declaration) || - (isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderScore(declaration.name!)) { + (isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!)) { continue; } @@ -22924,9 +22920,9 @@ namespace ts { } else { const parameter = local.valueDeclaration && tryGetRootParameterDeclaration(local.valueDeclaration); - if (parameter) { - const name = getNameOfDeclaration(local.valueDeclaration); - if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(name)) { + const name = getNameOfDeclaration(local.valueDeclaration); + if (parameter && name) { + if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) { addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local))); } } @@ -24221,18 +24217,19 @@ namespace ts { } const propDeclaration = prop.valueDeclaration; + const name = getNameOfDeclaration(propDeclaration); // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && !(propDeclaration ? isNumericName(getNameOfDeclaration(propDeclaration)) : isNumericLiteralName(prop.escapedName))) { + if (indexKind === IndexKind.Number && !(name ? isNumericName(name) : isNumericLiteralName(prop.escapedName))) { return; } // perform property check if property or indexer is declared in 'type' // this allows us to rule out cases when both property and indexer are inherited from the base class let errorNode: Node | undefined; - if (propDeclaration && + if (propDeclaration && name && (propDeclaration.kind === SyntaxKind.BinaryExpression || - getNameOfDeclaration(propDeclaration).kind === SyntaxKind.ComputedPropertyName || + name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol)) { errorNode = propDeclaration; } @@ -24427,7 +24424,7 @@ namespace ts { checkClassForStaticPropertyNameConflicts(node); } - const baseTypeNode = getClassExtendsHeritageClauseElement(node); + const baseTypeNode = getEffectiveBaseTypeNode(node); if (baseTypeNode) { if (languageVersion < ScriptTarget.ES2015) { checkExternalEmitHelpers(baseTypeNode.parent, ExternalEmitHelpers.Extends); @@ -24440,6 +24437,10 @@ namespace ts { const staticBaseType = getApparentType(baseConstructorType); checkBaseTypeAccessibility(staticBaseType, baseTypeNode); checkSourceElement(baseTypeNode.expression); + const extendsNode = getClassExtendsHeritageElement(node); + if (extendsNode && extendsNode !== baseTypeNode) { + checkExpression(extendsNode.expression); + } if (some(baseTypeNode.typeArguments)) { forEach(baseTypeNode.typeArguments, checkSourceElement); for (const constructor of getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode)) { @@ -27353,7 +27354,7 @@ namespace ts { } switch (modifier.kind) { case SyntaxKind.ConstKeyword: - if (node.kind !== SyntaxKind.EnumDeclaration && node.parent.kind === SyntaxKind.ClassDeclaration) { + if (node.kind !== SyntaxKind.EnumDeclaration) { return grammarErrorOnNode(node, Diagnostics.A_class_member_cannot_have_the_0_keyword, tokenToString(SyntaxKind.ConstKeyword)); } break; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index f8648636c8a..98cbaca5e6f 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -44,6 +44,7 @@ namespace ts { ["esnext.array", "lib.esnext.array.d.ts"], ["esnext.symbol", "lib.esnext.symbol.d.ts"], ["esnext.asynciterable", "lib.esnext.asynciterable.d.ts"], + ["esnext.intl", "lib.esnext.intl.d.ts"] ]; /** diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 24b3031b877..7d08fd5caf1 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3636,7 +3636,7 @@ "category": "Message", "code": 6353 }, - + "Project '{0}' is up to date with .d.ts files from its dependencies": { "category": "Message", "code": 6354 @@ -3836,6 +3836,10 @@ "category": "Error", "code": 7039 }, + "If the '{0}' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/{0}`": { + "category": "Error", + "code": 7040 + }, "You cannot rename this element.": { "category": "Error", "code": 8000 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 7269462578e..1857fa05f60 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -192,6 +192,11 @@ namespace ts { // Setup and perform the transformation to retrieve declarations from the input files const nonJsFiles = filter(sourceFiles, isSourceFileNotJavaScript); const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles; + if (emitOnlyDtsFiles && !compilerOptions.declaration) { + // Checker wont collect the linked aliases since thats only done when declaration is enabled. + // Do that here when emitting only dts files + nonJsFiles.forEach(collectLinkedAliases); + } const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, concatenate([transformDeclarations], declarationTransformers), /*allowDtsFiles*/ false); if (length(declarationTransform.diagnostics)) { for (const diagnostic of declarationTransform.diagnostics!) { @@ -221,6 +226,20 @@ namespace ts { declarationTransform.dispose(); } + function collectLinkedAliases(node: Node) { + if (isExportAssignment(node)) { + if (node.expression.kind === SyntaxKind.Identifier) { + resolver.collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true); + } + return; + } + else if (isExportSpecifier(node)) { + resolver.collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true); + return; + } + forEachChild(node, collectLinkedAliases); + } + function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, bundleInfoPath: string | undefined, printer: Printer, mapRecorder: SourceMapWriter) { const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined; const sourceFile = sourceFileOrBundle.kind === SyntaxKind.SourceFile ? sourceFileOrBundle : undefined; diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 91ff766678a..7b8a50ef603 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -194,10 +194,10 @@ namespace ts { } /** Create a unique name generated for a node. */ - export function getGeneratedNameForNode(node: Node): Identifier; - /* @internal */ export function getGeneratedNameForNode(node: Node, flags: GeneratedIdentifierFlags): Identifier; // tslint:disable-line unified-signatures - export function getGeneratedNameForNode(node: Node, flags?: GeneratedIdentifierFlags): Identifier { - const name = createIdentifier(isIdentifier(node) ? idText(node) : ""); + export function getGeneratedNameForNode(node: Node | undefined): Identifier; + /* @internal */ export function getGeneratedNameForNode(node: Node | undefined, flags: GeneratedIdentifierFlags): Identifier; // tslint:disable-line unified-signatures + export function getGeneratedNameForNode(node: Node | undefined, flags?: GeneratedIdentifierFlags): Identifier { + const name = createIdentifier(node && isIdentifier(node) ? idText(node) : ""); name.autoGenerateFlags = GeneratedIdentifierFlags.Node | flags!; name.autoGenerateId = nextAutoGenerateId; name.original = node; diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 8e2e3727c60..35fb8e99170 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1022,7 +1022,7 @@ namespace ts { } const members = createNodeArray(concatenate(parameterProperties, visitNodes(input.members, visitDeclarationSubtree))); - const extendsClause = getClassExtendsHeritageClauseElement(input); + const extendsClause = getEffectiveBaseTypeNode(input); if (extendsClause && !isEntityNameExpression(extendsClause.expression) && extendsClause.expression.kind !== SyntaxKind.NullKeyword) { // We must add a temporary declaration for the extends clause expression diff --git a/src/compiler/transformers/es2015.ts b/src/compiler/transformers/es2015.ts index 8624beae643..8e2b487f13f 100644 --- a/src/compiler/transformers/es2015.ts +++ b/src/compiler/transformers/es2015.ts @@ -770,7 +770,7 @@ namespace ts { enableSubstitutionsForBlockScopedBindings(); } - const extendsClauseElement = getClassExtendsHeritageClauseElement(node); + const extendsClauseElement = getEffectiveBaseTypeNode(node); const classFunction = createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 6d41e3d36cd..4712be940fe 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -586,7 +586,7 @@ namespace ts { function getClassFacts(node: ClassDeclaration, staticProperties: ReadonlyArray) { let facts = ClassFacts.None; if (some(staticProperties)) facts |= ClassFacts.HasStaticInitializedProperties; - const extendsClauseElement = getClassExtendsHeritageClauseElement(node); + const extendsClauseElement = getEffectiveBaseTypeNode(node); if (extendsClauseElement && skipOuterExpressions(extendsClauseElement.expression).kind !== SyntaxKind.NullKeyword) facts |= ClassFacts.IsDerivedClass; if (shouldEmitDecorateCallForClass(node)) facts |= ClassFacts.HasConstructorDecorators; if (childIsDecorated(node)) facts |= ClassFacts.HasMemberDecorators; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 764aadc37af..7cd4e50365c 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2861,7 +2861,7 @@ namespace ts { getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; - getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; + getSignaturesOfType(type: Type, kind: SignatureKind): ReadonlyArray; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; getBaseTypes(type: InterfaceType): BaseType[]; getBaseTypeOfLiteralType(type: Type): Type; @@ -3073,6 +3073,7 @@ namespace ts { Subtype } + // NOTE: If modifying this enum, must modify `TypeFormatFlags` too! export const enum NodeBuilderFlags { None = 0, // Options @@ -3337,7 +3338,7 @@ namespace ts { getNodeCheckFlags(node: Node): NodeCheckFlags; isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; isLateBound(node: Declaration): node is LateBoundDeclaration; - collectLinkedAliases(node: Identifier): Node[] | undefined; + collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined; isImplementationOfOverload(node: FunctionLike): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; @@ -3741,7 +3742,7 @@ namespace ts { symbol: Symbol; // Symbol associated with type (if any) pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any) aliasSymbol?: Symbol; // Alias associated with type - aliasTypeArguments?: Type[]; // Alias type arguments (if any) + aliasTypeArguments?: ReadonlyArray; // Alias type arguments (if any) /* @internal */ wildcardInstantiation?: Type; // Instantiation with type parameters mapped to wildcard type } @@ -3835,7 +3836,7 @@ namespace ts { */ export interface TypeReference extends ObjectType { target: GenericType; // Type reference target - typeArguments?: Type[]; // Type reference type arguments (undefined if none) + typeArguments?: ReadonlyArray; // Type reference type arguments (undefined if none) } /* @internal */ @@ -3912,8 +3913,8 @@ namespace ts { export interface ResolvedType extends ObjectType, UnionOrIntersectionType { members: SymbolTable; // Properties by name properties: Symbol[]; // Properties - callSignatures: Signature[]; // Call signatures of type - constructSignatures: Signature[]; // Construct signatures of type + callSignatures: ReadonlyArray; // Call signatures of type + constructSignatures: ReadonlyArray; // Construct signatures of type stringIndexInfo?: IndexInfo; // String indexing info numberIndexInfo?: IndexInfo; // Numeric indexing info } @@ -4038,8 +4039,8 @@ namespace ts { export interface Signature { declaration?: SignatureDeclaration | JSDocSignature; // Originating declaration - typeParameters?: TypeParameter[]; // Type parameters (undefined if non-generic) - parameters: Symbol[]; // Parameters + typeParameters?: ReadonlyArray; // Type parameters (undefined if non-generic) + parameters: ReadonlyArray; // Parameters /* @internal */ thisParameter?: Symbol; // symbol of this-type parameter /* @internal */ @@ -4138,11 +4139,11 @@ namespace ts { /* @internal */ export interface InferenceContext extends TypeMapper { - typeParameters: TypeParameter[]; // Type parameters for which inferences are made - signature?: Signature; // Generic signature for which inferences are made (if any) - inferences: InferenceInfo[]; // Inferences made for each type parameter - flags: InferenceFlags; // Inference flags - compareTypes: TypeComparer; // Type comparer function + typeParameters: ReadonlyArray; // Type parameters for which inferences are made + signature?: Signature; // Generic signature for which inferences are made (if any) + inferences: InferenceInfo[]; // Inferences made for each type parameter + flags: InferenceFlags; // Inference flags + compareTypes: TypeComparer; // Type comparer function } /* @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 49769953f02..93415815e74 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -745,8 +745,8 @@ namespace ts { // Return display name of an identifier // Computed property names will just be emitted as "[]", where is the source // text of the expression in the computed property. - export function declarationNameToString(name: DeclarationName | QualifiedName) { - return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); + export function declarationNameToString(name: DeclarationName | QualifiedName | undefined) { + return !name || getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); } export function getNameFromIndexInfo(info: IndexInfo): string | undefined { @@ -2067,53 +2067,51 @@ namespace ts { export function getJSDocCommentsAndTags(hostNode: Node): ReadonlyArray { let result: (JSDoc | JSDocTag)[] | undefined; - getJSDocCommentsAndTagsWorker(hostNode); - return result || emptyArray; + // Pull parameter comments from declaring function as well + if (isVariableLike(hostNode) && hasInitializer(hostNode) && hasJSDocNodes(hostNode.initializer!)) { + result = addRange(result, (hostNode.initializer as HasJSDoc).jsDoc!); + } - function getJSDocCommentsAndTagsWorker(node: Node): void { - const parent = node.parent; - if (!parent) return; - if (parent.kind === SyntaxKind.PropertyAssignment || parent.kind === SyntaxKind.PropertyDeclaration || getNestedModuleDeclaration(parent)) { - getJSDocCommentsAndTagsWorker(parent); - } - // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. - // /** - // * @param {number} name - // * @returns {number} - // */ - // var x = function(name) { return name.length; } - if (parent.parent && (getSingleVariableOfVariableStatement(parent.parent) === node)) { - getJSDocCommentsAndTagsWorker(parent.parent); - } - if (parent.parent && parent.parent.parent && - (getSingleVariableOfVariableStatement(parent.parent.parent) || - getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node || - getSourceOfDefaultedAssignment(parent.parent.parent))) { - getJSDocCommentsAndTagsWorker(parent.parent.parent); - } - if (isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.EqualsToken || - isBinaryExpression(parent) && parent.operatorToken.kind === SyntaxKind.EqualsToken || - node.kind === SyntaxKind.PropertyAccessExpression && node.parent && node.parent.kind === SyntaxKind.ExpressionStatement) { - if (isBinaryExpression(parent)) { - getJSDocCommentsAndTagsWorker(parent.parent); - } - else { - getJSDocCommentsAndTagsWorker(parent); - } + let node: Node | undefined = hostNode; + while (node && node.parent) { + if (hasJSDocNodes(node)) { + result = addRange(result, node.jsDoc!); } - // Pull parameter comments from declaring function as well if (node.kind === SyntaxKind.Parameter) { result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration)); + break; } + node = getNextJSDocCommentLocation(node); + } + return result || emptyArray; + } - if (isVariableLike(node) && hasInitializer(node) && node.initializer !== hostNode && hasJSDocNodes(node.initializer!)) { - result = addRange(result, (node.initializer as HasJSDoc).jsDoc); - } - - if (hasJSDocNodes(node)) { - result = addRange(result, node.jsDoc); - } + function getNextJSDocCommentLocation(node: Node) { + const parent = node.parent; + if (parent.kind === SyntaxKind.PropertyAssignment || + parent.kind === SyntaxKind.PropertyDeclaration || + parent.kind === SyntaxKind.ExpressionStatement && node.kind === SyntaxKind.PropertyAccessExpression || + getNestedModuleDeclaration(parent) || + isBinaryExpression(node) && node.operatorToken.kind === SyntaxKind.EqualsToken) { + return parent; + } + // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. + // /** + // * @param {number} name + // * @returns {number} + // */ + // var x = function(name) { return name.length; } + else if (parent.parent && + (getSingleVariableOfVariableStatement(parent.parent) === node || + isBinaryExpression(parent) && parent.operatorToken.kind === SyntaxKind.EqualsToken)) { + return parent.parent; + } + else if (parent.parent && parent.parent.parent && + (getSingleVariableOfVariableStatement(parent.parent.parent) || + getSingleInitializerOfVariableStatementOrPropertyDeclaration(parent.parent.parent) === node || + getSourceOfDefaultedAssignment(parent.parent.parent))) { + return parent.parent.parent; } } @@ -2415,7 +2413,18 @@ namespace ts { return isEntityNameExpression(e) || isClassExpression(e); } - export function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration) { + export function getEffectiveBaseTypeNode(node: ClassLikeDeclaration | InterfaceDeclaration) { + if (isInJavaScriptFile(node)) { + // Prefer an @augments tag because it may have type parameters. + const tag = getJSDocAugmentsTag(node); + if (tag) { + return tag.class; + } + } + return getClassExtendsHeritageElement(node); + } + + export function getClassExtendsHeritageElement(node: ClassLikeDeclaration | InterfaceDeclaration) { const heritageClause = getHeritageClause(node.heritageClauses, SyntaxKind.ExtendsKeyword); return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined; } @@ -2428,7 +2437,7 @@ namespace ts { /** Returns the node in an `extends` or `implements` clause of a class or interface. */ export function getAllSuperTypeNodes(node: Node): ReadonlyArray { return isInterfaceDeclaration(node) ? getInterfaceBaseTypeNodes(node) || emptyArray - : isClassLike(node) ? concatenate(singleElementArray(getClassExtendsHeritageClauseElement(node)), getClassImplementsHeritageClauseElements(node)) || emptyArray + : isClassLike(node) ? concatenate(singleElementArray(getEffectiveBaseTypeNode(node)), getClassImplementsHeritageClauseElements(node)) || emptyArray : emptyArray; } @@ -4849,7 +4858,7 @@ namespace ts { function getDeclarationIdentifier(node: Declaration | Expression): Identifier | undefined { const name = getNameOfDeclaration(node); - return isIdentifier(name) ? name : undefined; + return name && isIdentifier(name) ? name : undefined; } export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined { @@ -4861,16 +4870,15 @@ namespace ts { return !!(node as NamedDeclaration).name; // A 'name' property should always be a DeclarationName. } - // TODO: GH#18217 This is often used as if it returns a defined result - export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName { + export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined { if (!declaration) { - return undefined!; + return undefined; } switch (declaration.kind) { case SyntaxKind.ClassExpression: case SyntaxKind.FunctionExpression: if (!(declaration as ClassExpression | FunctionExpression).name) { - return getAssignedName(declaration)!; + return getAssignedName(declaration); } break; case SyntaxKind.Identifier: @@ -4892,19 +4900,19 @@ namespace ts { case SpecialPropertyAssignmentKind.PrototypeProperty: return (expr.left as PropertyAccessExpression).name; default: - return undefined!; + return undefined; } } case SyntaxKind.JSDocCallbackTag: - return (declaration as JSDocCallbackTag).name!; + return (declaration as JSDocCallbackTag).name; case SyntaxKind.JSDocTypedefTag: - return getNameOfJSDocTypedef(declaration as JSDocTypedefTag)!; + return getNameOfJSDocTypedef(declaration as JSDocTypedefTag); case SyntaxKind.ExportAssignment: { const { expression } = declaration as ExportAssignment; - return isIdentifier(expression) ? expression : undefined!; + return isIdentifier(expression) ? expression : undefined; } } - return (declaration as NamedDeclaration).name!; + return (declaration as NamedDeclaration).name; } function getAssignedName(node: Node): DeclarationName | undefined { diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 0ca37715b9f..177d98c37ba 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -3045,6 +3045,10 @@ Actual: ${stringify(fullActual)}`); } } + public verifyRefactorsAvailable(names: ReadonlyArray): void { + assert.deepEqual(unique(this.getApplicableRefactors(this.getSelection()), r => r.name), names); + } + public verifyRefactor({ name, actionName, refactors }: FourSlashInterface.VerifyRefactorOptions) { const actualRefactors = this.getApplicableRefactors(this.getSelection()).filter(r => r.name === name && r.actions.some(a => a.name === actionName)); this.assertObjectsEqual(actualRefactors, refactors); @@ -3815,7 +3819,7 @@ ${code} } /** Collects an array of unique outputs. */ - function unique(inputs: T[], getOutput: (t: T) => string): string[] { + function unique(inputs: ReadonlyArray, getOutput: (t: T) => string): string[] { const set = ts.createMap(); for (const input of inputs) { const out = getOutput(input); @@ -4106,6 +4110,10 @@ namespace FourSlashInterface { this.state.verifyApplicableRefactorAvailableForRange(this.negative); } + public refactorsAvailable(names: ReadonlyArray): void { + this.state.verifyRefactorsAvailable(names); + } + public refactor(options: VerifyRefactorOptions) { this.state.verifyRefactor(options); } diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index 467a3474100..6645e12c832 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -571,7 +571,9 @@ interface Array {}` } private addFileOrFolderInFolder(folder: FsFolder, fileOrDirectory: FsFile | FsFolder | FsSymLink, ignoreWatch?: boolean) { - insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path))); + if (!this.fs.has(fileOrDirectory.path)) { + insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path))); + } folder.modifiedTime = this.now(); this.fs.set(fileOrDirectory.path, fileOrDirectory); diff --git a/src/lib/esnext.d.ts b/src/lib/esnext.d.ts index 99e71158f6a..970e1b32b3e 100644 --- a/src/lib/esnext.d.ts +++ b/src/lib/esnext.d.ts @@ -2,3 +2,4 @@ /// /// /// +/// diff --git a/src/lib/esnext.intl.d.ts b/src/lib/esnext.intl.d.ts new file mode 100644 index 00000000000..99e202bd91b --- /dev/null +++ b/src/lib/esnext.intl.d.ts @@ -0,0 +1,12 @@ +declare namespace Intl { + type NumberFormatPartTypes = "currency" | "decimal" | "fraction" | "group" | "infinity" | "integer" | "literal" | "minusSign" | "nan" | "plusSign" | "percentSign"; + + interface NumberFormatPart { + type: NumberFormatPartTypes; + value: string; + } + + interface NumberFormat { + formatToParts(number?: number): NumberFormatPart[]; + } + } diff --git a/src/lib/libs.json b/src/lib/libs.json index 07c99278c14..1f2079e33a3 100644 --- a/src/lib/libs.json +++ b/src/lib/libs.json @@ -35,6 +35,7 @@ "esnext.asynciterable", "esnext.array", "esnext.symbol", + "esnext.intl", // Default libraries "es5.full", "es2015.full", @@ -50,4 +51,4 @@ "es5.full": "lib.d.ts", "es2015.full": "lib.es6.d.ts" } -} \ No newline at end of file +} diff --git a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl index 5f7122bd70c..c735834474e 100644 --- a/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/cht/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -487,7 +487,7 @@ - + @@ -496,7 +496,7 @@ - + diff --git a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl index 43e457e6907..e0e6e4a2b1a 100644 --- a/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/plk/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -480,7 +480,7 @@ - + @@ -489,7 +489,7 @@ - + diff --git a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl index 54b82d0468e..d0086211c52 100644 --- a/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl +++ b/src/loc/lcl/ptb/diagnosticMessages/diagnosticMessages.generated.json.lcl @@ -480,7 +480,7 @@ - + @@ -489,7 +489,7 @@ - + diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 2f128aa1663..49fb54a6b10 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -14,7 +14,9 @@ namespace ts.server.protocol { GetSpanOfEnclosingComment = "getSpanOfEnclosingComment", Change = "change", Close = "close", + /** @deprecated Prefer CompletionInfo -- see comment on CompletionsResponse */ Completions = "completions", + CompletionInfo = "completionInfo", /* @internal */ CompletionsFull = "completions-full", CompletionDetails = "completionEntryDetails", @@ -1943,10 +1945,22 @@ namespace ts.server.protocol { source?: SymbolDisplayPart[]; } + /** @deprecated Prefer CompletionInfoResponse, which supports several top-level fields in addition to the array of entries. */ export interface CompletionsResponse extends Response { body?: CompletionEntry[]; } + export interface CompletionInfoResponse extends Response { + body?: CompletionInfo; + } + + export interface CompletionInfo { + readonly isGlobalCompletion: boolean; + readonly isMemberCompletion: boolean; + readonly isNewIdentifierLocation: boolean; + readonly entries: ReadonlyArray; + } + export interface CompletionDetailsResponse extends Response { body?: CompletionEntryDetails[]; } diff --git a/src/server/session.ts b/src/server/session.ts index 74629d97e48..c6934bb8d82 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -1343,8 +1343,7 @@ namespace ts.server { }); } - private getCompletions(args: protocol.CompletionsRequestArgs, simplifiedResult: boolean): ReadonlyArray | CompletionInfo | undefined { - const prefix = args.prefix || ""; + private getCompletions(args: protocol.CompletionsRequestArgs, kind: protocol.CommandTypes.CompletionInfo | protocol.CommandTypes.Completions | protocol.CommandTypes.CompletionsFull): ReadonlyArray | protocol.CompletionInfo | CompletionInfo | undefined { const { file, project } = this.getFileAndProject(args); const scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file)!; const position = this.getPosition(args, scriptInfo); @@ -1355,19 +1354,27 @@ namespace ts.server { includeExternalModuleExports: args.includeExternalModuleExports, includeInsertTextCompletions: args.includeInsertTextCompletions }); - if (simplifiedResult) { - return mapDefined(completions && completions.entries, entry => { - if (completions!.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { - const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry; - const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; - // Use `hasAction || undefined` to avoid serializing `false`. - return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; - } - }).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name)); - } - else { - return completions; - } + if (completions === undefined) return undefined; + + if (kind === protocol.CommandTypes.CompletionsFull) return completions; + + const prefix = args.prefix || ""; + const entries = mapDefined(completions.entries, entry => { + if (completions.isMemberCompletion || startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { + const { name, kind, kindModifiers, sortText, insertText, replacementSpan, hasAction, source, isRecommended } = entry; + const convertedSpan = replacementSpan ? this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; + // Use `hasAction || undefined` to avoid serializing `false`. + return { name, kind, kindModifiers, sortText, insertText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source, isRecommended }; + } + }).sort((a, b) => compareStringsCaseSensitiveUI(a.name, b.name)); + + if (kind === protocol.CommandTypes.Completions) return entries; + + const res: protocol.CompletionInfo = { + ...completions, + entries, + }; + return res; } private getCompletionEntryDetails(args: protocol.CompletionDetailsRequestArgs, simplifiedResult: boolean): ReadonlyArray | ReadonlyArray { @@ -2035,11 +2042,14 @@ namespace ts.server { [CommandNames.FormatRangeFull]: (request: protocol.FormatRequest) => { return this.requiredResponse(this.getFormattingEditsForRangeFull(request.arguments)); }, + [CommandNames.CompletionInfo]: (request: protocol.CompletionsRequest) => { + return this.requiredResponse(this.getCompletions(request.arguments, CommandNames.CompletionInfo)); + }, [CommandNames.Completions]: (request: protocol.CompletionsRequest) => { - return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ true)); + return this.requiredResponse(this.getCompletions(request.arguments, CommandNames.Completions)); }, [CommandNames.CompletionsFull]: (request: protocol.CompletionsRequest) => { - return this.requiredResponse(this.getCompletions(request.arguments, /*simplifiedResult*/ false)); + return this.requiredResponse(this.getCompletions(request.arguments, CommandNames.CompletionsFull)); }, [CommandNames.CompletionDetails]: (request: protocol.CompletionDetailsRequest) => { return this.requiredResponse(this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ true)); diff --git a/src/services/codefixes/fixAddMissingMember.ts b/src/services/codefixes/fixAddMissingMember.ts index 53492211042..7dbb43b94c7 100644 --- a/src/services/codefixes/fixAddMissingMember.ts +++ b/src/services/codefixes/fixAddMissingMember.ts @@ -32,7 +32,7 @@ namespace ts.codefix { // Always prefer to add a method declaration if possible. if (call) { - addMethodDeclaration(changes, classDeclarationSourceFile, classDeclaration, token, call, makeStatic, inJs, preferences); + addMethodDeclaration(context, changes, classDeclarationSourceFile, classDeclaration, token, call, makeStatic, inJs, preferences); } else { if (inJs) { @@ -184,11 +184,12 @@ namespace ts.codefix { inJs: boolean, preferences: UserPreferences, ): CodeFixAction | undefined { - const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(t, classDeclarationSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences)); + const changes = textChanges.ChangeTracker.with(context, t => addMethodDeclaration(context, t, classDeclarationSourceFile, classDeclaration, token, callExpression, makeStatic, inJs, preferences)); return createCodeFixAction(fixName, changes, [makeStatic ? Diagnostics.Declare_static_method_0 : Diagnostics.Declare_method_0, token.text], fixId, Diagnostics.Add_all_missing_members); } function addMethodDeclaration( + context: CodeFixContextBase, changeTracker: textChanges.ChangeTracker, classDeclarationSourceFile: SourceFile, classDeclaration: ClassLikeDeclaration, @@ -198,7 +199,7 @@ namespace ts.codefix { inJs: boolean, preferences: UserPreferences, ): void { - const methodDeclaration = createMethodFromCallExpression(callExpression, token.text, inJs, makeStatic, preferences); + const methodDeclaration = createMethodFromCallExpression(context, callExpression, token.text, inJs, makeStatic, preferences); const containingMethodDeclaration = getAncestor(callExpression, SyntaxKind.MethodDeclaration); if (containingMethodDeclaration && containingMethodDeclaration.parent === classDeclaration) { diff --git a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts index 95de8857eb2..c0624c5529b 100644 --- a/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts +++ b/src/services/codefixes/fixClassDoesntImplementInheritedAbstractMember.ts @@ -33,7 +33,7 @@ namespace ts.codefix { } function addMissingMembers(classDeclaration: ClassLikeDeclaration, sourceFile: SourceFile, checker: TypeChecker, changeTracker: textChanges.ChangeTracker, preferences: UserPreferences): void { - const extendsNode = getClassExtendsHeritageClauseElement(classDeclaration)!; + const extendsNode = getEffectiveBaseTypeNode(classDeclaration)!; const instantiatedExtendsType = checker.getTypeAtLocation(extendsNode)!; // Note that this is ultimately derived from a map indexed by symbol names, diff --git a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts index 781f14566c9..ad093de6327 100644 --- a/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts +++ b/src/services/codefixes/fixClassIncorrectlyImplementsInterface.ts @@ -71,7 +71,7 @@ namespace ts.codefix { } function getHeritageClauseSymbolTable (classDeclaration: ClassLikeDeclaration, checker: TypeChecker): SymbolTable { - const heritageClauseNode = getClassExtendsHeritageClauseElement(classDeclaration); + const heritageClauseNode = getEffectiveBaseTypeNode(classDeclaration); if (!heritageClauseNode) return createSymbolTable(); const heritageClauseType = checker.getTypeAtLocation(heritageClauseNode) as InterfaceType; const heritageClauseTypeSymbols = checker.getPropertiesOfType(heritageClauseType); diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index ad3e2e36f5b..505a09813c3 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -173,8 +173,8 @@ namespace ts.codefix { const typeParameters = getEffectiveTypeParameterDeclarations(parent.parent); if (typeParameters.length === 1) { const { pos, end } = cast(typeParameters, isNodeArray); - const previousToken = getTokenAtPosition(sourceFile, pos - 1, /*includeJsDocComment*/ false); - const nextToken = getTokenAtPosition(sourceFile, end, /*includeJsDocComment*/ false); + const previousToken = getTokenAtPosition(sourceFile, pos - 1, /*includeJsDocComment*/ true); + const nextToken = getTokenAtPosition(sourceFile, end, /*includeJsDocComment*/ true); Debug.assert(previousToken.kind === SyntaxKind.LessThanToken); Debug.assert(nextToken.kind === SyntaxKind.GreaterThanToken); diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 58e0d2bebbf..5f26336a117 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -111,12 +111,27 @@ namespace ts.codefix { } export function createMethodFromCallExpression( + context: CodeFixContextBase, { typeArguments, arguments: args, parent: parent }: CallExpression, methodName: string, inJs: boolean, makeStatic: boolean, preferences: UserPreferences, ): MethodDeclaration { + const checker = context.program.getTypeChecker(); + const types = map(args, + arg => { + let type = checker.getTypeAtLocation(arg); + if (type === undefined) { + return undefined; + } + // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" + type = checker.getBaseTypeOfLiteralType(type); + return checker.typeToTypeNode(type); + }); + const names = map(args, arg => + isIdentifier(arg) ? arg.text : + isPropertyAccessExpression(arg) ? arg.name.text : undefined); return createMethod( /*decorators*/ undefined, /*modifiers*/ makeStatic ? [createToken(SyntaxKind.StaticKeyword)] : undefined, @@ -125,12 +140,12 @@ namespace ts.codefix { /*questionToken*/ undefined, /*typeParameters*/ inJs ? undefined : map(typeArguments, (_, i) => createTypeParameterDeclaration(CharacterCodes.T + typeArguments!.length - 1 <= CharacterCodes.Z ? String.fromCharCode(CharacterCodes.T + i) : `T${i}`)), - /*parameters*/ createDummyParameters(args.length, /*names*/ undefined, /*minArgumentCount*/ undefined, inJs), + /*parameters*/ createDummyParameters(args.length, names, types, /*minArgumentCount*/ undefined, inJs), /*type*/ inJs ? undefined : createKeywordTypeNode(SyntaxKind.AnyKeyword), createStubbedMethodBody(preferences)); } - function createDummyParameters(argCount: number, names: string[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] { + function createDummyParameters(argCount: number, names: (string | undefined)[] | undefined, types: (TypeNode | undefined)[] | undefined, minArgumentCount: number | undefined, inJs: boolean): ParameterDeclaration[] { const parameters: ParameterDeclaration[] = []; for (let i = 0; i < argCount; i++) { const newParameter = createParameter( @@ -139,7 +154,7 @@ namespace ts.codefix { /*dotDotDotToken*/ undefined, /*name*/ names && names[i] || `arg${i}`, /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? createToken(SyntaxKind.QuestionToken) : undefined, - /*type*/ inJs ? undefined : createKeywordTypeNode(SyntaxKind.AnyKeyword), + /*type*/ inJs ? undefined : types && types[i] || createKeywordTypeNode(SyntaxKind.AnyKeyword), /*initializer*/ undefined); parameters.push(newParameter); } @@ -172,7 +187,7 @@ namespace ts.codefix { const maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0); const maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(symbol => symbol.name); - const parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, minArgumentCount, /*inJs*/ false); + const parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, /* types */ undefined, minArgumentCount, /*inJs*/ false); if (someSigHasRestParameter) { const anyArrayType = createArrayTypeNode(createKeywordTypeNode(SyntaxKind.AnyKeyword)); diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index c58c001b403..3e26e4cdd32 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -33,8 +33,9 @@ namespace ts.codefix { const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); let declaration!: Declaration | undefined; const changes = textChanges.ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeenseen*/ returnTrue); }); - return changes.length === 0 ? undefined - : [createCodeFixAction(fixId, changes, [getDiagnostic(errorCode, token), getNameOfDeclaration(declaration!).getText(sourceFile)], fixId, Diagnostics.Infer_all_types_from_usage)]; + const name = getNameOfDeclaration(declaration!); + return !name || changes.length === 0 ? undefined + : [createCodeFixAction(fixId, changes, [getDiagnostic(errorCode, token), name.getText(sourceFile)], fixId, Diagnostics.Infer_all_types_from_usage)]; }, fixIds: [fixId], getAllCodeActions(context) { diff --git a/src/services/completions.ts b/src/services/completions.ts index e31ac4e81f3..21d704661b2 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1122,7 +1122,7 @@ namespace ts.Completions { // If this is e.g. [Symbol.iterator], add a completion for `Symbol`. const symbolSymbol = firstDefined(symbol.declarations, decl => { const name = getNameOfDeclaration(decl); - const leftName = name.kind === SyntaxKind.ComputedPropertyName ? getLeftMostName(name.expression) : undefined; + const leftName = name && name.kind === SyntaxKind.ComputedPropertyName ? getLeftMostName(name.expression) : undefined; return leftName && typeChecker.getSymbolAtLocation(leftName); }); if (symbolSymbol) { @@ -1966,7 +1966,7 @@ namespace ts.Completions { // NOTE: if one only performs this step when m.name is an identifier, // things like '__proto__' are not filtered out. const name = getNameOfDeclaration(m); - existingName = isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined; + existingName = name && isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined; } existingMemberNames.set(existingName!, true); // TODO: GH#18217 diff --git a/src/services/findAllReferences.ts b/src/services/findAllReferences.ts index 46dd83851c1..0fbcd5cd6e9 100644 --- a/src/services/findAllReferences.ts +++ b/src/services/findAllReferences.ts @@ -981,6 +981,7 @@ namespace ts.FindAllReferences.Core { function getReferenceForShorthandProperty({ flags, valueDeclaration }: Symbol, search: Search, state: State): void { const shorthandValueSymbol = state.checker.getShorthandAssignmentValueSymbol(valueDeclaration)!; + const name = getNameOfDeclaration(valueDeclaration); /* * Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment * has two meanings: property name and property value. Therefore when we do findAllReference at the position where @@ -988,8 +989,8 @@ namespace ts.FindAllReferences.Core { * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the * position of property accessing, the referenceEntry of such position will be handled in the first case. */ - if (!(flags & SymbolFlags.Transient) && search.includes(shorthandValueSymbol)) { - addReference(getNameOfDeclaration(valueDeclaration), shorthandValueSymbol, state); + if (!(flags & SymbolFlags.Transient) && name && search.includes(shorthandValueSymbol)) { + addReference(name, shorthandValueSymbol, state); } } diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index eeec4b15ea7..f37fb1bc5dd 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -512,7 +512,10 @@ namespace ts.formatting { // falls through case SyntaxKind.PropertyDeclaration: case SyntaxKind.Parameter: - return getNameOfDeclaration(node).kind; + const name = getNameOfDeclaration(node); + if (name) { + return name.kind; + } } } diff --git a/src/services/navigateTo.ts b/src/services/navigateTo.ts index 723d7f59b3a..dc03c736f3c 100644 --- a/src/services/navigateTo.ts +++ b/src/services/navigateTo.ts @@ -113,7 +113,7 @@ namespace ts.NavigateTo { // First, if we started with a computed property name, then add all but the last // portion into the container array. const name = getNameOfDeclaration(declaration); - if (name.kind === SyntaxKind.ComputedPropertyName && !tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) { + if (name && name.kind === SyntaxKind.ComputedPropertyName && !tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) { return undefined; } diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index f381be9b7d1..d97004b80c5 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -277,7 +277,7 @@ namespace ts.NavigationBar { case SpecialPropertyAssignmentKind.PrototypeProperty: case SpecialPropertyAssignmentKind.Prototype: addNodeWithRecursiveChild(node, (node as BinaryExpression).right); - break; + return; case SpecialPropertyAssignmentKind.ThisProperty: case SpecialPropertyAssignmentKind.Property: case SpecialPropertyAssignmentKind.None: diff --git a/src/services/refactors/generateGetAccessorAndSetAccessor.ts b/src/services/refactors/generateGetAccessorAndSetAccessor.ts index 2e4f11c4b27..b7240f2e985 100644 --- a/src/services/refactors/generateGetAccessorAndSetAccessor.ts +++ b/src/services/refactors/generateGetAccessorAndSetAccessor.ts @@ -9,20 +9,19 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { type ContainerDeclaration = ClassLikeDeclaration | ObjectLiteralExpression; interface Info { - container: ContainerDeclaration; - isStatic: boolean; - isReadonly: boolean; - type: TypeNode | undefined; - declaration: AcceptedDeclaration; - fieldName: AcceptedNameType; - accessorName: AcceptedNameType; - originalName: AcceptedNameType; - renameAccessor: boolean; + readonly container: ContainerDeclaration; + readonly isStatic: boolean; + readonly isReadonly: boolean; + readonly type: TypeNode | undefined; + readonly declaration: AcceptedDeclaration; + readonly fieldName: AcceptedNameType; + readonly accessorName: AcceptedNameType; + readonly originalName: AcceptedNameType; + readonly renameAccessor: boolean; } function getAvailableActions(context: RefactorContext): ApplicableRefactorInfo[] | undefined { - const { file } = context; - if (!getConvertibleFieldAtPosition(context, file)) return undefined; + if (!getConvertibleFieldAtPosition(context)) return undefined; return [{ name: actionName, @@ -39,7 +38,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { function getEditsForAction(context: RefactorContext, _actionName: string): RefactorEditInfo | undefined { const { file } = context; - const fieldInfo = getConvertibleFieldAtPosition(context, file); + const fieldInfo = getConvertibleFieldAtPosition(context); if (!fieldInfo) return undefined; const isJS = isSourceFileJavaScript(file); @@ -117,14 +116,14 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor { return name.charCodeAt(0) === CharacterCodes._; } - function getConvertibleFieldAtPosition(context: RefactorContext, file: SourceFile): Info | undefined { - const { startPosition, endPosition } = context; + function getConvertibleFieldAtPosition(context: RefactorContext): Info | undefined { + const { file, startPosition, endPosition } = context; const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); const declaration = findAncestor(node.parent, isAcceptedDeclaration); // make sure declaration have AccessibilityModifier or Static Modifier or Readonly Modifier const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static | ModifierFlags.Readonly; - if (!declaration || !rangeOverlapsWithStartEnd(declaration.name, startPosition, endPosition!) // TODO: GH#18217 + if (!declaration || !nodeOverlapsWithStartEnd(declaration.name, file, startPosition, endPosition!) // TODO: GH#18217 || !isConvertibleName(declaration.name) || (getModifierFlags(declaration) | meaning) !== meaning) return undefined; const name = declaration.name.text; diff --git a/src/services/services.ts b/src/services/services.ts index 24feaac17c6..2e275813585 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -391,10 +391,10 @@ namespace ts { getApparentProperties(): Symbol[] { return this.checker.getAugmentedPropertiesOfType(this); } - getCallSignatures(): Signature[] { + getCallSignatures(): ReadonlyArray { return this.checker.getSignaturesOfType(this, SignatureKind.Call); } - getConstructSignatures(): Signature[] { + getConstructSignatures(): ReadonlyArray { return this.checker.getSignaturesOfType(this, SignatureKind.Construct); } getStringIndexType(): Type | undefined { diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index 2945d641c09..5eb26dc21d6 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -600,7 +600,7 @@ namespace ts.SymbolDisplay { } } - function addSignatureDisplayParts(signature: Signature, allSignatures: Signature[], flags = TypeFormatFlags.None) { + function addSignatureDisplayParts(signature: Signature, allSignatures: ReadonlyArray, flags = TypeFormatFlags.None) { addRange(displayParts, signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | TypeFormatFlags.WriteTypeArgumentsOfSignature)); if (allSignatures.length > 1) { displayParts.push(spacePart()); diff --git a/src/services/types.ts b/src/services/types.ts index 9ae51a4ea61..be897f20cd4 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -44,8 +44,8 @@ namespace ts { getProperties(): Symbol[]; getProperty(propertyName: string): Symbol | undefined; getApparentProperties(): Symbol[]; - getCallSignatures(): Signature[]; - getConstructSignatures(): Signature[]; + getCallSignatures(): ReadonlyArray; + getConstructSignatures(): ReadonlyArray; getStringIndexType(): Type | undefined; getNumberIndexType(): Type | undefined; getBaseTypes(): BaseType[] | undefined; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 9715d124d7e..481d20e91bd 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -439,6 +439,10 @@ namespace ts { return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end); } + export function nodeOverlapsWithStartEnd(node: Node, sourceFile: SourceFile, start: number, end: number) { + return startEndOverlapsWithStartEnd(node.getStart(sourceFile), node.end, start, end); + } + export function startEndOverlapsWithStartEnd(start1: number, end1: number, start2: number, end2: number) { const start = Math.max(start1, start2); const end = Math.min(end1, end2); @@ -944,7 +948,7 @@ namespace ts { token = findPrecedingToken(token.getFullStart(), sourceFile); if (!token || !isIdentifier(token)) return undefined; if (!remainingLessThanTokens) { - return { called: token, nTypeArguments }; + return isDeclarationName(token) ? undefined : { called: token, nTypeArguments }; } remainingLessThanTokens--; break; diff --git a/src/testRunner/unittests/commandLineParsing.ts b/src/testRunner/unittests/commandLineParsing.ts index cf7cabdd26d..7145b9e5ec4 100644 --- a/src/testRunner/unittests/commandLineParsing.ts +++ b/src/testRunner/unittests/commandLineParsing.ts @@ -57,7 +57,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.symbol', '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', 'esnext.intl'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, @@ -259,7 +259,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.symbol', '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', 'esnext.intl'.", category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category, code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, file: undefined, @@ -278,7 +278,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.symbol', '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', 'esnext.intl'.", 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/testRunner/unittests/convertCompilerOptionsFromJson.ts b/src/testRunner/unittests/convertCompilerOptionsFromJson.ts index b1695ad01f5..3b422e9a645 100644 --- a/src/testRunner/unittests/convertCompilerOptionsFromJson.ts +++ b/src/testRunner/unittests/convertCompilerOptionsFromJson.ts @@ -263,7 +263,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.symbol', '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', 'esnext.intl'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -294,7 +294,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.symbol', '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', 'esnext.intl'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -325,7 +325,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.symbol', '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', 'esnext.intl'.", code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code, category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category }] @@ -356,7 +356,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.symbol', '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', 'esnext.intl'.", 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/testRunner/unittests/tscWatchMode.ts b/src/testRunner/unittests/tscWatchMode.ts index 2aaef43f2d9..ed03c6ad48d 100644 --- a/src/testRunner/unittests/tscWatchMode.ts +++ b/src/testRunner/unittests/tscWatchMode.ts @@ -1218,6 +1218,58 @@ namespace ts.tscWatch { checkWatchedFiles(host, files.map(f => f.path)); } }); + + it("updates errors correctly when declaration emit is disabled in compiler options", () => { + const currentDirectory = "/user/username/projects/myproject"; + const aFile: File = { + path: `${currentDirectory}/a.ts`, + content: `import test from './b'; +test(4, 5);` + }; + const bFileContent = `function test(x: number, y: number) { + return x + y / 5; +} +export default test;`; + const bFile: File = { + path: `${currentDirectory}/b.ts`, + content: bFileContent + }; + const tsconfigFile: File = { + path: `${currentDirectory}/tsconfig.json`, + content: JSON.stringify({ + compilerOptions: { + module: "commonjs", + noEmit: true, + strict: true, + } + }) + }; + const files = [aFile, bFile, libFile, tsconfigFile]; + const host = createWatchedSystem(files, { currentDirectory }); + const watch = createWatchOfConfigFile("tsconfig.json", host); + checkOutputErrorsInitial(host, emptyArray); + + changeParameterType("x", "string", [ + getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.indexOf("4"), 1, Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1, "4", "string") + ]); + changeParameterType("y", "string", [ + getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.indexOf("5"), 1, Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1, "5", "string"), + getDiagnosticOfFileFromProgram(watch(), bFile.path, bFile.content.indexOf("y /"), 1, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type) + ]); + + function changeParameterType(parameterName: string, toType: string, expectedErrors: ReadonlyArray) { + const newContent = bFileContent.replace(new RegExp(`${parameterName}\: [a-z]*`), `${parameterName}: ${toType}`); + + verifyErrorsWithBFileContents(newContent, expectedErrors); + verifyErrorsWithBFileContents(bFileContent, emptyArray); + } + + function verifyErrorsWithBFileContents(content: string, expectedErrors: ReadonlyArray) { + host.writeFile(bFile.path, content); + host.runQueuedTimeoutCallbacks(); + checkOutputErrorsIncremental(host, expectedErrors); + } + }); }); describe("tsc-watch emit with outFile or out setting", () => { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index f5e20f96480..2946e354f4d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2552,7 +2552,7 @@ declare namespace ts { getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; - getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; + getSignaturesOfType(type: Type, kind: SignatureKind): ReadonlyArray; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; getBaseTypes(type: InterfaceType): BaseType[]; getBaseTypeOfLiteralType(type: Type): Type; @@ -2923,7 +2923,7 @@ declare namespace ts { getNodeCheckFlags(node: Node): NodeCheckFlags; isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean; isLateBound(node: Declaration): node is LateBoundDeclaration; - collectLinkedAliases(node: Identifier): Node[] | undefined; + collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined; isImplementationOfOverload(node: FunctionLike): boolean | undefined; isRequiredInitializedParameter(node: ParameterDeclaration): boolean; isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean; @@ -3254,7 +3254,7 @@ declare namespace ts { symbol: Symbol; pattern?: DestructuringPattern; aliasSymbol?: Symbol; - aliasTypeArguments?: Type[]; + aliasTypeArguments?: ReadonlyArray; wildcardInstantiation?: Type; } interface IntrinsicType extends Type { @@ -3325,7 +3325,7 @@ declare namespace ts { */ interface TypeReference extends ObjectType { target: GenericType; - typeArguments?: Type[]; + typeArguments?: ReadonlyArray; } enum Variance { Invariant = 0, @@ -3375,8 +3375,8 @@ declare namespace ts { interface ResolvedType extends ObjectType, UnionOrIntersectionType { members: SymbolTable; properties: Symbol[]; - callSignatures: Signature[]; - constructSignatures: Signature[]; + callSignatures: ReadonlyArray; + constructSignatures: ReadonlyArray; stringIndexInfo?: IndexInfo; numberIndexInfo?: IndexInfo; } @@ -3455,8 +3455,8 @@ declare namespace ts { } interface Signature { declaration?: SignatureDeclaration | JSDocSignature; - typeParameters?: TypeParameter[]; - parameters: Symbol[]; + typeParameters?: ReadonlyArray; + parameters: ReadonlyArray; thisParameter?: Symbol; resolvedReturnType?: Type; resolvedTypePredicate?: TypePredicate; @@ -3522,7 +3522,7 @@ declare namespace ts { } type TypeComparer = (s: Type, t: Type, reportErrors?: boolean) => Ternary; interface InferenceContext extends TypeMapper { - typeParameters: TypeParameter[]; + typeParameters: ReadonlyArray; signature?: Signature; inferences: InferenceInfo[]; flags: InferenceFlags; @@ -5768,6 +5768,7 @@ declare namespace ts { Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports: DiagnosticMessage; Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead: DiagnosticMessage; Mapped_object_type_implicitly_has_an_any_template_type: DiagnosticMessage; + If_the_0_package_actually_exposes_this_module_consider_sending_a_pull_request_to_amend_https_Colon_Slash_Slashgithub_com_SlashDefinitelyTyped_SlashDefinitelyTyped_Slashtree_Slashmaster_Slashtypes_Slash_0: DiagnosticMessage; You_cannot_rename_this_element: DiagnosticMessage; You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: DiagnosticMessage; import_can_only_be_used_in_a_ts_file: DiagnosticMessage; @@ -6122,7 +6123,7 @@ declare namespace ts { function isLateVisibilityPaintedStatement(node: Node): node is LateVisibilityPaintedStatement; function isAnyImportOrReExport(node: Node): node is AnyImportOrReExport; function getEnclosingBlockScopeContainer(node: Node): Node; - function declarationNameToString(name: DeclarationName | QualifiedName): string; + function declarationNameToString(name: DeclarationName | QualifiedName | undefined): string; function getNameFromIndexInfo(info: IndexInfo): string | undefined; function getTextOfPropertyName(name: PropertyName): __String; function entityNameToString(name: EntityNameOrEntityNameExpression): string; @@ -6309,7 +6310,8 @@ declare namespace ts { function isIdentifierName(node: Identifier): boolean; function isAliasSymbolDeclaration(node: Node): boolean; function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean; - function getClassExtendsHeritageClauseElement(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments | undefined; + function getEffectiveBaseTypeNode(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments | undefined; + function getClassExtendsHeritageElement(node: ClassLikeDeclaration | InterfaceDeclaration): ExpressionWithTypeArguments | undefined; function getClassImplementsHeritageClauseElements(node: ClassLikeDeclaration): NodeArray | undefined; /** Returns the node in an `extends` or `implements` clause of a class or interface. */ function getAllSuperTypeNodes(node: Node): ReadonlyArray; @@ -6700,7 +6702,7 @@ declare namespace ts { function isNamedDeclaration(node: Node): node is NamedDeclaration & { name: DeclarationName; }; - function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName; + function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** * Gets the JSDoc parameter tags for the node if present. * @@ -7717,8 +7719,8 @@ declare namespace ts { /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */ function createFileLevelUniqueName(text: string): Identifier; /** Create a unique name generated for a node. */ - function getGeneratedNameForNode(node: Node): Identifier; - function getGeneratedNameForNode(node: Node, flags: GeneratedIdentifierFlags): Identifier; + function getGeneratedNameForNode(node: Node | undefined): Identifier; + function getGeneratedNameForNode(node: Node | undefined, flags: GeneratedIdentifierFlags): Identifier; function createToken(token: TKind): Token; function createSuper(): SuperExpression; function createThis(): ThisExpression & Token; @@ -9813,8 +9815,8 @@ declare namespace ts { getProperties(): Symbol[]; getProperty(propertyName: string): Symbol | undefined; getApparentProperties(): Symbol[]; - getCallSignatures(): Signature[]; - getConstructSignatures(): Signature[]; + getCallSignatures(): ReadonlyArray; + getConstructSignatures(): ReadonlyArray; getStringIndexType(): Type | undefined; getNumberIndexType(): Type | undefined; getBaseTypes(): BaseType[] | undefined; @@ -10684,6 +10686,7 @@ declare namespace ts { function startEndContainsRange(start: number, end: number, range: TextRange): boolean; function rangeContainsStartEnd(range: TextRange, start: number, end: number): boolean; function rangeOverlapsWithStartEnd(r1: TextRange, start: number, end: number): boolean; + function nodeOverlapsWithStartEnd(node: Node, sourceFile: SourceFile, start: number, end: number): boolean; function startEndOverlapsWithStartEnd(start1: number, end1: number, start2: number, end2: number): boolean; /** * Assumes `candidate.start <= position` holds. @@ -11639,7 +11642,7 @@ declare namespace ts.codefix { * @returns Empty string iff there are no member insertions. */ function createMissingMemberNodes(classDeclaration: ClassLikeDeclaration, possiblyMissingSymbols: ReadonlyArray, checker: TypeChecker, preferences: UserPreferences, out: (node: ClassElement) => void): void; - function createMethodFromCallExpression({ typeArguments, arguments: args, parent: parent }: CallExpression, methodName: string, inJs: boolean, makeStatic: boolean, preferences: UserPreferences): MethodDeclaration; + function createMethodFromCallExpression(context: CodeFixContextBase, { typeArguments, arguments: args, parent: parent }: CallExpression, methodName: string, inJs: boolean, makeStatic: boolean, preferences: UserPreferences): MethodDeclaration; } declare namespace ts.codefix { } @@ -12188,6 +12191,7 @@ declare namespace ts.server.protocol { Change = "change", Close = "close", Completions = "completions", + CompletionInfo = "completionInfo", CompletionsFull = "completions-full", CompletionDetails = "completionEntryDetails", CompletionDetailsFull = "completionEntryDetails-full", @@ -12889,6 +12893,15 @@ declare namespace ts.server.protocol { interface CompletionsResponse extends Response { body?: CompletionEntry[]; } + interface CompletionInfoResponse extends Response { + body?: CompletionInfo; + } + interface CompletionInfo { + readonly isGlobalCompletion: boolean; + readonly isMemberCompletion: boolean; + readonly isNewIdentifierLocation: boolean; + readonly entries: ReadonlyArray; + } interface CompletionDetailsResponse extends Response { body?: CompletionEntryDetails[]; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 62413b0753b..86215a7b7ba 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1822,7 +1822,7 @@ declare namespace ts { getPropertiesOfType(type: Type): Symbol[]; getPropertyOfType(type: Type, propertyName: string): Symbol | undefined; getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined; - getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; + getSignaturesOfType(type: Type, kind: SignatureKind): ReadonlyArray; getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined; getBaseTypes(type: InterfaceType): BaseType[]; getBaseTypeOfLiteralType(type: Type): Type; @@ -2198,7 +2198,7 @@ declare namespace ts { symbol: Symbol; pattern?: DestructuringPattern; aliasSymbol?: Symbol; - aliasTypeArguments?: Type[]; + aliasTypeArguments?: ReadonlyArray; } interface LiteralType extends Type { value: string | number; @@ -2263,7 +2263,7 @@ declare namespace ts { */ interface TypeReference extends ObjectType { target: GenericType; - typeArguments?: Type[]; + typeArguments?: ReadonlyArray; } interface GenericType extends InterfaceType, TypeReference { } @@ -2323,8 +2323,8 @@ declare namespace ts { } interface Signature { declaration?: SignatureDeclaration | JSDocSignature; - typeParameters?: TypeParameter[]; - parameters: Symbol[]; + typeParameters?: ReadonlyArray; + parameters: ReadonlyArray; } enum IndexKind { String = 0, @@ -3204,7 +3204,7 @@ declare namespace ts { */ function unescapeIdentifier(id: string): string; function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined; - function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName; + function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined; /** * Gets the JSDoc parameter tags for the node if present. * @@ -3639,7 +3639,7 @@ declare namespace ts { /** Create a unique name based on the supplied text. This does not consider names injected by the transformer. */ function createFileLevelUniqueName(text: string): Identifier; /** Create a unique name generated for a node. */ - function getGeneratedNameForNode(node: Node): Identifier; + function getGeneratedNameForNode(node: Node | undefined): Identifier; function createToken(token: TKind): Token; function createSuper(): SuperExpression; function createThis(): ThisExpression & Token; @@ -4613,8 +4613,8 @@ declare namespace ts { getProperties(): Symbol[]; getProperty(propertyName: string): Symbol | undefined; getApparentProperties(): Symbol[]; - getCallSignatures(): Signature[]; - getConstructSignatures(): Signature[]; + getCallSignatures(): ReadonlyArray; + getConstructSignatures(): ReadonlyArray; getStringIndexType(): Type | undefined; getNumberIndexType(): Type | undefined; getBaseTypes(): BaseType[] | undefined; diff --git a/tests/baselines/reference/constInClassExpression.errors.txt b/tests/baselines/reference/constInClassExpression.errors.txt new file mode 100644 index 00000000000..b3b66cba3a5 --- /dev/null +++ b/tests/baselines/reference/constInClassExpression.errors.txt @@ -0,0 +1,10 @@ +tests/cases/compiler/constInClassExpression.ts(2,11): error TS1248: A class member cannot have the 'const' keyword. + + +==== tests/cases/compiler/constInClassExpression.ts (1 errors) ==== + let C = class { + const a = 4; + ~ +!!! error TS1248: A class member cannot have the 'const' keyword. + }; + \ No newline at end of file diff --git a/tests/baselines/reference/constInClassExpression.js b/tests/baselines/reference/constInClassExpression.js new file mode 100644 index 00000000000..1da4605687a --- /dev/null +++ b/tests/baselines/reference/constInClassExpression.js @@ -0,0 +1,13 @@ +//// [constInClassExpression.ts] +let C = class { + const a = 4; +}; + + +//// [constInClassExpression.js] +var C = /** @class */ (function () { + function class_1() { + this.a = 4; + } + return class_1; +}()); diff --git a/tests/baselines/reference/constInClassExpression.symbols b/tests/baselines/reference/constInClassExpression.symbols new file mode 100644 index 00000000000..7468772edfb --- /dev/null +++ b/tests/baselines/reference/constInClassExpression.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/constInClassExpression.ts === +let C = class { +>C : Symbol(C, Decl(constInClassExpression.ts, 0, 3)) + + const a = 4; +>a : Symbol(C.a, Decl(constInClassExpression.ts, 0, 15)) + +}; + diff --git a/tests/baselines/reference/constInClassExpression.types b/tests/baselines/reference/constInClassExpression.types new file mode 100644 index 00000000000..1efe8527e04 --- /dev/null +++ b/tests/baselines/reference/constInClassExpression.types @@ -0,0 +1,11 @@ +=== tests/cases/compiler/constInClassExpression.ts === +let C = class { +>C : typeof C +>class { const a = 4;} : typeof C + + const a = 4; +>a : number +>4 : 4 + +}; + diff --git a/tests/baselines/reference/extendsTag1.symbols b/tests/baselines/reference/extendsTag1.symbols new file mode 100644 index 00000000000..f38683338b1 --- /dev/null +++ b/tests/baselines/reference/extendsTag1.symbols @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/bug25101.js === +/** + * @template T + * @extends {Set} Should prefer this Set, not the Set in the heritage clause + */ +class My extends Set {} +>My : Symbol(My, Decl(bug25101.js, 0, 0)) +>Set : Symbol(Set, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + diff --git a/tests/baselines/reference/extendsTag1.types b/tests/baselines/reference/extendsTag1.types new file mode 100644 index 00000000000..440861dd47b --- /dev/null +++ b/tests/baselines/reference/extendsTag1.types @@ -0,0 +1,9 @@ +=== tests/cases/conformance/jsdoc/bug25101.js === +/** + * @template T + * @extends {Set} Should prefer this Set, not the Set in the heritage clause + */ +class My extends Set {} +>My : My +>Set : Set + diff --git a/tests/baselines/reference/typedefInnerNamepaths.errors.txt b/tests/baselines/reference/typedefInnerNamepaths.errors.txt new file mode 100644 index 00000000000..179c36b0edd --- /dev/null +++ b/tests/baselines/reference/typedefInnerNamepaths.errors.txt @@ -0,0 +1,28 @@ +tests/cases/conformance/jsdoc/bug25104.js(1,7): error TS2300: Duplicate identifier 'C'. +tests/cases/conformance/jsdoc/bug25104.js(3,19): error TS1005: '}' expected. +tests/cases/conformance/jsdoc/bug25104.js(4,26): error TS2300: Duplicate identifier 'C'. +tests/cases/conformance/jsdoc/bug25104.js(6,18): error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name. +tests/cases/conformance/jsdoc/bug25104.js(6,18): error TS1005: '}' expected. + + +==== tests/cases/conformance/jsdoc/bug25104.js (5 errors) ==== + class C { + ~ +!!! error TS2300: Duplicate identifier 'C'. + /** + * @typedef {C~A} C~B + ~ +!!! error TS1005: '}' expected. + * @typedef {object} C~A + ~ +!!! error TS2300: Duplicate identifier 'C'. + */ + /** @param {C~A} o */ + +!!! error TS8024: JSDoc '@param' tag has name '', but there is no parameter with that name. + ~ +!!! error TS1005: '}' expected. + constructor(o) { + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/typedefInnerNamepaths.symbols b/tests/baselines/reference/typedefInnerNamepaths.symbols new file mode 100644 index 00000000000..2ddcf419734 --- /dev/null +++ b/tests/baselines/reference/typedefInnerNamepaths.symbols @@ -0,0 +1,14 @@ +=== tests/cases/conformance/jsdoc/bug25104.js === +class C { +>C : Symbol(C, Decl(bug25104.js, 0, 0)) + + /** + * @typedef {C~A} C~B + * @typedef {object} C~A + */ + /** @param {C~A} o */ + constructor(o) { +>o : Symbol(o, Decl(bug25104.js, 6, 16)) + } +} + diff --git a/tests/baselines/reference/typedefInnerNamepaths.types b/tests/baselines/reference/typedefInnerNamepaths.types new file mode 100644 index 00000000000..16e8ab556a7 --- /dev/null +++ b/tests/baselines/reference/typedefInnerNamepaths.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/jsdoc/bug25104.js === +class C { +>C : C + + /** + * @typedef {C~A} C~B + * @typedef {object} C~A + */ + /** @param {C~A} o */ + constructor(o) { +>o : any + } +} + diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.errors.txt b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.errors.txt new file mode 100644 index 00000000000..ef5997f8f5e --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.errors.txt @@ -0,0 +1,35 @@ +/a.ts(2,25): error TS7016: Could not find a declaration file for module 'foo/sub'. '/node_modules/foo/sub.js' implicitly has an 'any' type. + If the 'foo' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/foo` +/a.ts(3,25): error TS7016: Could not find a declaration file for module 'bar/sub'. '/node_modules/bar/sub.js' implicitly has an 'any' type. + Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar';` + + +==== /a.ts (2 errors) ==== + import * as foo from "foo"; + import * as fooSub from "foo/sub"; + ~~~~~~~~~ +!!! error TS7016: Could not find a declaration file for module 'foo/sub'. '/node_modules/foo/sub.js' implicitly has an 'any' type. +!!! error TS7016: If the 'foo' package actually exposes this module, consider sending a pull request to amend 'https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/foo` + import * as barSub from "bar/sub"; + ~~~~~~~~~ +!!! error TS7016: Could not find a declaration file for module 'bar/sub'. '/node_modules/bar/sub.js' implicitly has an 'any' type. +!!! error TS7016: Try `npm install @types/bar` if it exists or add a new declaration (.d.ts) file containing `declare module 'bar';` + +==== /node_modules/@types/foo/index.d.ts (0 errors) ==== + export const foo: number; + +==== /node_modules/@types/foo/package.json (0 errors) ==== + { "name": "@types/foo", "version": "1.2.3" } + +==== /node_modules/foo/sub.js (0 errors) ==== + const x = 0; + +==== /node_modules/foo/package.json (0 errors) ==== + { "name": "foo", "version": "1.2.3" } + +==== /node_modules/bar/sub.js (0 errors) ==== + const x = 0; + +==== /node_modules/bar/package.json (0 errors) ==== + { "name": "bar", "version": "1.2.3" } + \ No newline at end of file diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.js b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.js new file mode 100644 index 00000000000..fe1a85730cd --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.js @@ -0,0 +1,29 @@ +//// [tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_typesForPackageExist.ts] //// + +//// [index.d.ts] +export const foo: number; + +//// [package.json] +{ "name": "@types/foo", "version": "1.2.3" } + +//// [sub.js] +const x = 0; + +//// [package.json] +{ "name": "foo", "version": "1.2.3" } + +//// [sub.js] +const x = 0; + +//// [package.json] +{ "name": "bar", "version": "1.2.3" } + +//// [a.ts] +import * as foo from "foo"; +import * as fooSub from "foo/sub"; +import * as barSub from "bar/sub"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.symbols b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.symbols new file mode 100644 index 00000000000..59153d03f54 --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.symbols @@ -0,0 +1,14 @@ +=== /a.ts === +import * as foo from "foo"; +>foo : Symbol(foo, Decl(a.ts, 0, 6)) + +import * as fooSub from "foo/sub"; +>fooSub : Symbol(fooSub, Decl(a.ts, 1, 6)) + +import * as barSub from "bar/sub"; +>barSub : Symbol(barSub, Decl(a.ts, 2, 6)) + +=== /node_modules/@types/foo/index.d.ts === +export const foo: number; +>foo : Symbol(foo, Decl(index.d.ts, 0, 12)) + diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.types b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.types new file mode 100644 index 00000000000..9a6b7b7e690 --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_typesForPackageExist.types @@ -0,0 +1,14 @@ +=== /a.ts === +import * as foo from "foo"; +>foo : typeof foo + +import * as fooSub from "foo/sub"; +>fooSub : any + +import * as barSub from "bar/sub"; +>barSub : any + +=== /node_modules/@types/foo/index.d.ts === +export const foo: number; +>foo : number + diff --git a/tests/baselines/reference/user/TypeScript-Node-Starter.log b/tests/baselines/reference/user/TypeScript-Node-Starter.log index affbd99af1e..9a0b3b00726 100644 --- a/tests/baselines/reference/user/TypeScript-Node-Starter.log +++ b/tests/baselines/reference/user/TypeScript-Node-Starter.log @@ -1,7 +1,5 @@ Exit Code: 1 Standard output: -node_modules/@types/jquery/index.d.ts(6366,66): error TS2344: Type '"timeout" | "onreadystatechange" | "responseType" | "withCredentials" | "msCaching"' does not satisfy the constraint '"abort" | "open" | "timeout" | "send" | "DONE" | "response" | "getAllResponseHeaders" | "getRespo...'. - Type '"msCaching"' is not assignable to type '"abort" | "open" | "timeout" | "send" | "DONE" | "response" | "getAllResponseHeaders" | "getRespo...'. node_modules/@types/passport-facebook/index.d.ts(50,31): error TS2689: Cannot extend an interface 'passport.Strategy'. Did you mean 'implements'? diff --git a/tests/baselines/reference/user/uglify-js.log b/tests/baselines/reference/user/uglify-js.log index 4fb7b01a2c9..f37d91c289a 100644 --- a/tests/baselines/reference/user/uglify-js.log +++ b/tests/baselines/reference/user/uglify-js.log @@ -1,95 +1,95 @@ Exit Code: 1 Standard output: -node_modules/uglify-js/lib/ast.js(210,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/ast.js(332,33): error TS2339: Property 'transform' does not exist on type 'string'. -node_modules/uglify-js/lib/ast.js(877,5): error TS2322: Type '{ [x: string]: any; _visit: (node: any, descend: any) => any; parent: (n: any) => any; push: type...' is not assignable to type 'TreeWalker'. +node_modules/uglify-js/lib/ast.js(209,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/ast.js(331,33): error TS2339: Property 'transform' does not exist on type 'string'. +node_modules/uglify-js/lib/ast.js(872,5): error TS2322: Type '{ [x: string]: any; _visit: (node: any, descend: any) => any; parent: (n: any) => any; push: type...' is not assignable to type 'TreeWalker'. Object literal may only specify known properties, but '_visit' does not exist in type 'TreeWalker'. Did you mean to write 'visit'? node_modules/uglify-js/lib/compress.js(165,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(514,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(829,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1084,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1098,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures. -node_modules/uglify-js/lib/compress.js(1162,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1204,112): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(1205,29): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(1214,87): error TS2322: Type 'false' is not assignable to type 'number'. -node_modules/uglify-js/lib/compress.js(1222,29): error TS2322: Type 'false' is not assignable to type 'never'. -node_modules/uglify-js/lib/compress.js(1325,38): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1417,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(1514,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1546,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(1960,44): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2152,19): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(2412,27): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3152,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3165,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. -node_modules/uglify-js/lib/compress.js(3302,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3312,33): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3316,32): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3322,40): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3331,41): error TS2339: Property 'add' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3348,14): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3350,40): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3358,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3432,63): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3621,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(3638,36): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3644,38): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3648,40): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. -node_modules/uglify-js/lib/compress.js(3673,22): error TS2339: Property 'each' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3678,30): error TS2339: Property 'del' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3683,30): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3694,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3696,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3708,41): error TS2339: Property 'has' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3710,48): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3816,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(3818,36): error TS2339: Property 'get' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3847,22): error TS2339: Property 'set' does not exist on type 'Dictionary'. -node_modules/uglify-js/lib/compress.js(3867,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. -node_modules/uglify-js/lib/compress.js(3892,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4030,18): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4329,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(4413,22): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4761,30): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(4768,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'. -node_modules/uglify-js/lib/compress.js(4772,36): error TS2532: Object is possibly 'undefined'. -node_modules/uglify-js/lib/compress.js(4777,41): error TS2339: Property 'get' does not exist on type 'string'. -node_modules/uglify-js/lib/compress.js(5264,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. -node_modules/uglify-js/lib/compress.js(5703,25): error TS2365: Operator '==' cannot be applied to types 'boolean' and '"f"'. -node_modules/uglify-js/lib/compress.js(5730,32): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5790,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5862,24): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(5868,26): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/compress.js(6218,43): error TS2454: Variable 'property' is used before being assigned. -node_modules/uglify-js/lib/compress.js(6232,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6235,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. -node_modules/uglify-js/lib/compress.js(6242,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. -node_modules/uglify-js/lib/compress.js(6295,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(501,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(816,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1071,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1085,51): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'true | ((node: any) => any)' has no compatible call signatures. +node_modules/uglify-js/lib/compress.js(1149,53): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1191,112): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(1192,29): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(1201,87): error TS2322: Type 'false' is not assignable to type 'number'. +node_modules/uglify-js/lib/compress.js(1209,29): error TS2322: Type 'false' is not assignable to type 'never'. +node_modules/uglify-js/lib/compress.js(1312,38): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1407,38): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(1503,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1535,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(1949,44): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2141,19): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(2401,27): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3141,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3154,33): error TS2322: Type '"f"' is not assignable to type 'boolean'. +node_modules/uglify-js/lib/compress.js(3291,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3301,33): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3305,32): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3311,40): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3320,41): error TS2339: Property 'add' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3337,14): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3339,40): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3347,33): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3421,63): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3608,23): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(3629,24): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3635,26): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3639,28): error TS2339: Property 'parent' does not exist on type 'TreeTransformer'. +node_modules/uglify-js/lib/compress.js(3657,18): error TS2339: Property 'each' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3662,26): error TS2339: Property 'del' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3667,26): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3678,37): error TS2339: Property 'has' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3680,44): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3692,37): error TS2339: Property 'has' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3694,44): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3798,21): error TS2403: Subsequent variable declarations must have the same type. Variable 'defs' must be of type 'Dictionary', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(3800,36): error TS2339: Property 'get' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3830,22): error TS2339: Property 'set' does not exist on type 'Dictionary'. +node_modules/uglify-js/lib/compress.js(3850,17): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. +node_modules/uglify-js/lib/compress.js(3875,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4013,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4312,17): error TS2403: Subsequent variable declarations must have the same type. Variable 'body' must be of type 'any[]', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(4396,22): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4746,30): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(4753,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'code' must be of type 'string', but here has type '{ [x: string]: any; get: () => string; toString: () => string; indent: () => void; indentation: (...'. +node_modules/uglify-js/lib/compress.js(4757,36): error TS2532: Object is possibly 'undefined'. +node_modules/uglify-js/lib/compress.js(4762,41): error TS2339: Property 'get' does not exist on type 'string'. +node_modules/uglify-js/lib/compress.js(5249,18): error TS2454: Variable 'is_strict_comparison' is used before being assigned. +node_modules/uglify-js/lib/compress.js(5688,25): error TS2365: Operator '==' cannot be applied to types 'boolean' and '"f"'. +node_modules/uglify-js/lib/compress.js(5715,32): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5775,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5847,24): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(5853,26): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/compress.js(6213,43): error TS2454: Variable 'property' is used before being assigned. +node_modules/uglify-js/lib/compress.js(6228,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6231,46): error TS2339: Property 'has_side_effects' does not exist on type 'number'. +node_modules/uglify-js/lib/compress.js(6237,25): error TS2403: Subsequent variable declarations must have the same type. Variable 'value' must be of type 'number', but here has type 'any'. +node_modules/uglify-js/lib/compress.js(6290,19): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/minify.js(170,75): error TS2339: Property 'compress' does not exist on type 'Compressor'. -node_modules/uglify-js/lib/mozilla-ast.js(569,18): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/mozilla-ast.js(566,18): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/output.js(481,22): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/output.js(774,23): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/output.js(1186,29): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/output.js(1480,58): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -node_modules/uglify-js/lib/parse.js(365,20): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. +node_modules/uglify-js/lib/output.js(1170,29): error TS2554: Expected 0 arguments, but got 1. +node_modules/uglify-js/lib/output.js(1452,58): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +node_modules/uglify-js/lib/parse.js(367,20): error TS2345: Argument of type 'number | undefined' is not assignable to parameter of type 'number'. Type 'undefined' is not assignable to type 'number'. -node_modules/uglify-js/lib/parse.js(447,32): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. -node_modules/uglify-js/lib/parse.js(458,32): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. -node_modules/uglify-js/lib/parse.js(509,20): error TS2339: Property 'raw_source' does not exist on type 'RegExp'. -node_modules/uglify-js/lib/parse.js(620,57): error TS2339: Property 'push' does not exist on type 'never'. -node_modules/uglify-js/lib/parse.js(630,32): error TS2345: Argument of type 'never[]' is not assignable to parameter of type 'never'. -node_modules/uglify-js/lib/parse.js(636,40): error TS2339: Property 'length' does not exist on type 'never'. -node_modules/uglify-js/lib/parse.js(740,13): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(772,52): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(772,74): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(814,31): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(820,17): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(824,21): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(829,43): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(848,21): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(867,21): error TS2531: Object is possibly 'null'. -node_modules/uglify-js/lib/parse.js(982,23): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. +node_modules/uglify-js/lib/parse.js(449,32): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. +node_modules/uglify-js/lib/parse.js(460,32): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. +node_modules/uglify-js/lib/parse.js(511,20): error TS2339: Property 'raw_source' does not exist on type 'RegExp'. +node_modules/uglify-js/lib/parse.js(622,57): error TS2339: Property 'push' does not exist on type 'never'. +node_modules/uglify-js/lib/parse.js(632,32): error TS2345: Argument of type 'never[]' is not assignable to parameter of type 'never'. +node_modules/uglify-js/lib/parse.js(638,40): error TS2339: Property 'length' does not exist on type 'never'. +node_modules/uglify-js/lib/parse.js(739,13): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(771,52): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(771,74): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(815,31): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(821,17): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(825,21): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(830,43): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(849,21): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(868,21): error TS2531: Object is possibly 'null'. +node_modules/uglify-js/lib/parse.js(983,23): error TS2345: Argument of type 'any' is not assignable to parameter of type 'never'. node_modules/uglify-js/lib/parse.js(1097,9): error TS2322: Type 'any[]' is not assignable to type 'never[]'. Type 'any' is not assignable to type 'never'. node_modules/uglify-js/lib/parse.js(1156,17): error TS2531: Object is possibly 'null'. @@ -111,8 +111,8 @@ node_modules/uglify-js/lib/scope.js(202,19): error TS2554: Expected 0 arguments, node_modules/uglify-js/lib/scope.js(410,14): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/scope.js(465,15): error TS2554: Expected 0 arguments, but got 1. node_modules/uglify-js/lib/scope.js(490,15): error TS2554: Expected 0 arguments, but got 1. -node_modules/uglify-js/lib/sourcemap.js(56,25): error TS2304: Cannot find name 'MOZ_SourceMap'. -node_modules/uglify-js/lib/sourcemap.js(62,23): error TS2304: Cannot find name 'MOZ_SourceMap'. +node_modules/uglify-js/lib/sourcemap.js(55,25): error TS2304: Cannot find name 'MOZ_SourceMap'. +node_modules/uglify-js/lib/sourcemap.js(61,23): error TS2304: Cannot find name 'MOZ_SourceMap'. node_modules/uglify-js/tools/exit.js(7,32): error TS2339: Property 'bufferSize' does not exist on type 'WriteStream'. node_modules/uglify-js/tools/exit.js(7,61): error TS2339: Property 'bufferSize' does not exist on type 'WriteStream'. node_modules/uglify-js/tools/node.js(68,27): error TS2339: Property 'minify' does not exist on type 'typeof import("/uglify-js/node_modules/uglify-js/tools/node")'. diff --git a/tests/cases/compiler/constInClassExpression.ts b/tests/cases/compiler/constInClassExpression.ts new file mode 100644 index 00000000000..b00b085e079 --- /dev/null +++ b/tests/cases/compiler/constInClassExpression.ts @@ -0,0 +1,3 @@ +let C = class { + const a = 4; +}; diff --git a/tests/cases/conformance/jsdoc/extendsTag1.ts b/tests/cases/conformance/jsdoc/extendsTag1.ts new file mode 100644 index 00000000000..194982760e9 --- /dev/null +++ b/tests/cases/conformance/jsdoc/extendsTag1.ts @@ -0,0 +1,10 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @lib: esnext +// @Filename: bug25101.js +/** + * @template T + * @extends {Set} Should prefer this Set, not the Set in the heritage clause + */ +class My extends Set {} diff --git a/tests/cases/compiler/jsdocAugmentsMissingType.ts b/tests/cases/conformance/jsdoc/jsdocAugmentsMissingType.ts similarity index 100% rename from tests/cases/compiler/jsdocAugmentsMissingType.ts rename to tests/cases/conformance/jsdoc/jsdocAugmentsMissingType.ts diff --git a/tests/cases/compiler/jsdocAugments_errorInExtendsExpression.ts b/tests/cases/conformance/jsdoc/jsdocAugments_errorInExtendsExpression.ts similarity index 100% rename from tests/cases/compiler/jsdocAugments_errorInExtendsExpression.ts rename to tests/cases/conformance/jsdoc/jsdocAugments_errorInExtendsExpression.ts diff --git a/tests/cases/compiler/jsdocAugments_nameMismatch.ts b/tests/cases/conformance/jsdoc/jsdocAugments_nameMismatch.ts similarity index 100% rename from tests/cases/compiler/jsdocAugments_nameMismatch.ts rename to tests/cases/conformance/jsdoc/jsdocAugments_nameMismatch.ts diff --git a/tests/cases/compiler/jsdocAugments_noExtends.ts b/tests/cases/conformance/jsdoc/jsdocAugments_noExtends.ts similarity index 100% rename from tests/cases/compiler/jsdocAugments_noExtends.ts rename to tests/cases/conformance/jsdoc/jsdocAugments_noExtends.ts diff --git a/tests/cases/compiler/jsdocAugments_notAClass.ts b/tests/cases/conformance/jsdoc/jsdocAugments_notAClass.ts similarity index 100% rename from tests/cases/compiler/jsdocAugments_notAClass.ts rename to tests/cases/conformance/jsdoc/jsdocAugments_notAClass.ts diff --git a/tests/cases/compiler/jsdocAugments_qualifiedName.ts b/tests/cases/conformance/jsdoc/jsdocAugments_qualifiedName.ts similarity index 100% rename from tests/cases/compiler/jsdocAugments_qualifiedName.ts rename to tests/cases/conformance/jsdoc/jsdocAugments_qualifiedName.ts diff --git a/tests/cases/compiler/jsdocAugments_withTypeParameter.ts b/tests/cases/conformance/jsdoc/jsdocAugments_withTypeParameter.ts similarity index 100% rename from tests/cases/compiler/jsdocAugments_withTypeParameter.ts rename to tests/cases/conformance/jsdoc/jsdocAugments_withTypeParameter.ts diff --git a/tests/cases/conformance/jsdoc/typedefInnerNamepaths.ts b/tests/cases/conformance/jsdoc/typedefInnerNamepaths.ts new file mode 100644 index 00000000000..ee71909c2ed --- /dev/null +++ b/tests/cases/conformance/jsdoc/typedefInnerNamepaths.ts @@ -0,0 +1,13 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @Filename: bug25104.js +class C { + /** + * @typedef {C~A} C~B + * @typedef {object} C~A + */ + /** @param {C~A} o */ + constructor(o) { + } +} diff --git a/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_typesForPackageExist.ts b/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_typesForPackageExist.ts new file mode 100644 index 00000000000..74e9da10804 --- /dev/null +++ b/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_typesForPackageExist.ts @@ -0,0 +1,25 @@ +// @noImplicitReferences: true +// @strict: true + +// @Filename: /node_modules/@types/foo/index.d.ts +export const foo: number; + +// @Filename: /node_modules/@types/foo/package.json +{ "name": "@types/foo", "version": "1.2.3" } + +// @Filename: /node_modules/foo/sub.js +const x = 0; + +// @Filename: /node_modules/foo/package.json +{ "name": "foo", "version": "1.2.3" } + +// @Filename: /node_modules/bar/sub.js +const x = 0; + +// @Filename: /node_modules/bar/package.json +{ "name": "bar", "version": "1.2.3" } + +// @Filename: /a.ts +import * as foo from "foo"; +import * as fooSub from "foo/sub"; +import * as barSub from "bar/sub"; diff --git a/tests/cases/fourslash/codeFixAddMissingMember9.ts b/tests/cases/fourslash/codeFixAddMissingMember9.ts new file mode 100644 index 00000000000..b583cd28e9a --- /dev/null +++ b/tests/cases/fourslash/codeFixAddMissingMember9.ts @@ -0,0 +1,25 @@ +/// + +////class C { +//// z: boolean = true; +//// method() { +//// const x = 0; +//// this.y(x, "a", this.z); +//// } +////} + +verify.codeFixAll({ + fixId: "addMissingMember", + fixAllDescription: "Add all missing members", + newFileContent: +`class C { + z: boolean = true; + method() { + const x = 0; + this.y(x, "a", this.z); + } + y(x: number, arg1: string, z: boolean): any { + throw new Error("Method not implemented."); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixClassImplementInterface_typeInOtherFile.ts b/tests/cases/fourslash/codeFixClassImplementInterface_typeInOtherFile.ts new file mode 100644 index 00000000000..712bf48e059 --- /dev/null +++ b/tests/cases/fourslash/codeFixClassImplementInterface_typeInOtherFile.ts @@ -0,0 +1,25 @@ +/// + +// @Filename: /I.ts +////export interface J {} +////export interface I { +//// x: J; +//// m(): J; +////} + +// @Filename: /C.ts +////import { I } from "./I"; +////export class C implements I {} + +goTo.file("/C.ts"); +verify.codeFix({ + description: "Implement interface 'I'", + newFileContent: +`import { I } from "./I"; +export class C implements I { + x: import("/I").J; + m(): import("/I").J { + throw new Error("Method not implemented."); + } +}`, +}); diff --git a/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts b/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts index 9e56fc70734..b56c6e05f69 100644 --- a/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts +++ b/tests/cases/fourslash/codeFixInferFromUsageSetterWithInaccessibleType.ts @@ -13,4 +13,13 @@ ////} goTo.file("/b.ts"); -verify.not.codeFixAvailable(); +verify.codeFix({ + index: 0, + description: "Infer type of 'x' from usage", + newFileContent: +`export class C { + set x(val: Promise) { val; } + method() { this.x = import("./a"); } +}`, +}); + diff --git a/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts index 29dcc2a5048..0b2669e41f8 100644 --- a/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts +++ b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles1.ts @@ -10,6 +10,7 @@ //// let c = new X.C; //// c.m1(); //// c.y = {}; +//// c.m2(c); // @Filename: f1.ts //// export class C {[| @@ -21,14 +22,18 @@ verify.getAndApplyCodeFix(/*errorCode*/undefined, 0); verify.getAndApplyCodeFix(/*errorCode*/undefined, 0); verify.getAndApplyCodeFix(/*errorCode*/undefined, 0); verify.getAndApplyCodeFix(/*errorCode*/undefined, 0); +verify.getAndApplyCodeFix(/*errorCode*/undefined, 0); verify.rangeIs(` + m2(c: C): any { + throw new Error("Method not implemented."); + } y: { [x: string]: any; }; m1(): any { throw new Error("Method not implemented."); } static x: any; - static m0(arg0: any, arg1: any, arg2: any): any { + static m0(arg0: number, arg1: string, arg2: undefined[]): any { throw new Error("Method not implemented."); } `); diff --git a/tests/cases/fourslash/codeFixUndeclaredAcrossFiles3.ts b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles3.ts new file mode 100644 index 00000000000..2b07493f923 --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredAcrossFiles3.ts @@ -0,0 +1,26 @@ +/// + +// @allowJs: true +// @checkJs: true + +// @Filename: f3.ts +//// import { C } from "./f1"; +//// import { D } from "./f2"; +//// const c = new C(); +//// c.m0(new D()); + +// @Filename: f2.ts +//// export class D { } + +// @Filename: f1.ts +//// export class C {[| +//// |]x: number; +//// } + +verify.getAndApplyCodeFix(/*errorCode*/ undefined, 0); + +verify.rangeIs(` + m0(arg0: D): any { + throw new Error("Method not implemented."); + } +`); \ No newline at end of file diff --git a/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts b/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts index 9faa15745fc..a4ac2488350 100644 --- a/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts +++ b/tests/cases/fourslash/codeFixUndeclaredInStaticMethod.ts @@ -20,7 +20,7 @@ verify.codeFix({ this.prop1 = 10; A.prop2 = "asdf"; } - static m1(arg0: any, arg1: any, arg2: any): any { + static m1(arg0: number, arg1: number, arg2: number): any { throw new Error("Method not implemented."); } }`, @@ -37,10 +37,10 @@ verify.codeFix({ this.prop1 = 10; A.prop2 = "asdf"; } - static m2(arg0: any, arg1: any): any { + static m2(arg0: number, arg1: number): any { throw new Error("Method not implemented."); } - static m1(arg0: any, arg1: any, arg2: any): any { + static m1(arg0: number, arg1: number, arg2: number): any { throw new Error("Method not implemented."); } }`, @@ -58,10 +58,10 @@ verify.codeFix({ this.prop1 = 10; A.prop2 = "asdf"; } - static m2(arg0: any, arg1: any): any { + static m2(arg0: number, arg1: number): any { throw new Error("Method not implemented."); } - static m1(arg0: any, arg1: any, arg2: any): any { + static m1(arg0: number, arg1: number, arg2: number): any { throw new Error("Method not implemented."); } }`, @@ -80,10 +80,10 @@ verify.codeFix({ this.prop1 = 10; A.prop2 = "asdf"; } - static m2(arg0: any, arg1: any): any { + static m2(arg0: number, arg1: number): any { throw new Error("Method not implemented."); } - static m1(arg0: any, arg1: any, arg2: any): any { + static m1(arg0: number, arg1: number, arg2: number): any { throw new Error("Method not implemented."); } }`, diff --git a/tests/cases/fourslash/codeFixUndeclaredMethod.ts b/tests/cases/fourslash/codeFixUndeclaredMethod.ts index 41e27dcf207..bf276379b0a 100644 --- a/tests/cases/fourslash/codeFixUndeclaredMethod.ts +++ b/tests/cases/fourslash/codeFixUndeclaredMethod.ts @@ -15,7 +15,7 @@ verify.codeFix({ index: 0, newFileContent: `class A { - foo1(arg0: any, arg1: any, arg2: any): any { + foo1(arg0: number, arg1: number, arg2: number): any { throw new Error("Method not implemented."); } constructor() { @@ -36,7 +36,7 @@ verify.codeFix({ foo2(): any { throw new Error("Method not implemented."); } - foo1(arg0: any, arg1: any, arg2: any): any { + foo1(arg0: number, arg1: number, arg2: number): any { throw new Error("Method not implemented."); } constructor() { @@ -60,7 +60,7 @@ verify.codeFix({ foo2(): any { throw new Error("Method not implemented."); } - foo1(arg0: any, arg1: any, arg2: any): any { + foo1(arg0: number, arg1: number, arg2: number): any { throw new Error("Method not implemented."); } constructor() { diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs.ts b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs.ts new file mode 100644 index 00000000000..1c06cfc3afd --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredMethodFunctionArgs.ts @@ -0,0 +1,31 @@ +/// + +//// class A {[| +//// |]constructor() { +//// this.foo1(() => 1, () => "2", () => false); +//// this.foo2((a: number) => a, (b: string) => b, (c: boolean) => c); +//// } +//// } + +verify.codeFix({ + description: "Declare method 'foo1'", + index: 0, + newRangeContent: ` + foo1(arg0: () => number, arg1: () => string, arg2: () => boolean): any { + throw new Error("Method not implemented."); + } + `, +}); + +verify.codeFix({ + description: "Declare method 'foo2'", + index: 0, + newRangeContent: ` + foo2(arg0: (a: number) => number, arg1: (b: string) => string, arg2: (c: boolean) => boolean): any { + throw new Error("Method not implemented."); + } + foo1(arg0: () => number, arg1: () => string, arg2: () => boolean): any { + throw new Error("Method not implemented."); + } + ` +}); diff --git a/tests/cases/fourslash/codeFixUndeclaredMethodObjectLiteralArgs.ts b/tests/cases/fourslash/codeFixUndeclaredMethodObjectLiteralArgs.ts new file mode 100644 index 00000000000..bd434cf9d9d --- /dev/null +++ b/tests/cases/fourslash/codeFixUndeclaredMethodObjectLiteralArgs.ts @@ -0,0 +1,17 @@ +/// + +//// class A {[| +//// |]constructor() { +//// this.foo1(null, {}, { a: 1, b: "2"}); +//// } +//// } + +verify.codeFix({ + description: "Declare method 'foo1'", + index: 0, + newRangeContent: ` + foo1(arg0: null, arg1: {}, arg2: { a: number; b: string; }): any { + throw new Error("Method not implemented."); + } + ` +}); diff --git a/tests/cases/fourslash/commentsClassMembers.ts b/tests/cases/fourslash/commentsClassMembers.ts index 6b598ab458c..b0ed3e9e48b 100644 --- a/tests/cases/fourslash/commentsClassMembers.ts +++ b/tests/cases/fourslash/commentsClassMembers.ts @@ -572,12 +572,12 @@ verify.quickInfos({ }); goTo.marker('114'); -verify.completionListContains("a", "(property) cWithConstructorProperty.a: number", "this is first parameter a\nmore info about a"); -verify.quickInfoIs("(property) cWithConstructorProperty.a: number", "this is first parameter a\nmore info about a"); +verify.completionListContains("a", "(property) cWithConstructorProperty.a: number", "more info about a\nthis is first parameter a"); +verify.quickInfoIs("(property) cWithConstructorProperty.a: number", "more info about a\nthis is first parameter a"); goTo.marker('115'); -verify.completionListContains("a", "(parameter) a: number", "this is first parameter a\nmore info about a"); -verify.quickInfoIs("(parameter) a: number", "this is first parameter a\nmore info about a"); +verify.completionListContains("a", "(parameter) a: number", "more info about a\nthis is first parameter a"); +verify.quickInfoIs("(parameter) a: number", "more info about a\nthis is first parameter a"); verify.quickInfos({ 116: "this: this", diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index 6b0c880e9bb..bba86fea299 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -420,7 +420,7 @@ verify.signatureHelp({ marker: "38", docComment: concatDoc, parameterDocComment: verify.quickInfoAt("38aq", "(parameter) bar: string", "is second string"); goTo.marker('39'); -verify.completionListContains("a", "(parameter) a: number", "it is first parameter\nthis is inline comment for a "); +verify.completionListContains("a", "(parameter) a: number", "this is inline comment for a \nit is first parameter"); verify.completionListContains("b", "(parameter) b: number", "this is inline comment for b"); verify.completionListContains("c", "(parameter) c: number", "it is third parameter"); verify.completionListContains("d", "(parameter) d: number", ""); @@ -430,7 +430,7 @@ const jsdocTestTags: ReadonlyArray = [ { name: "param", text: "a it is first parameter" }, { name: "param", text: "c it is third parameter" }, ]; -verify.signatureHelp({ marker: "40", docComment: jsdocTestDocComment, parameterDocComment: "it is first parameter\nthis is inline comment for a ", tags: jsdocTestTags }); +verify.signatureHelp({ marker: "40", docComment: jsdocTestDocComment, parameterDocComment: "this is inline comment for a \nit is first parameter", tags: jsdocTestTags }); verify.quickInfos({ "40q": [ "function jsDocParamTest(a: number, b: number, c: number, d: number): number", @@ -438,7 +438,7 @@ verify.quickInfos({ ], "40aq": [ "(parameter) a: number", - "it is first parameter\nthis is inline comment for a " + "this is inline comment for a \nit is first parameter" ] }); diff --git a/tests/cases/fourslash/commentsFunctionExpression.ts b/tests/cases/fourslash/commentsFunctionExpression.ts index bd9a5c93433..257b8345756 100644 --- a/tests/cases/fourslash/commentsFunctionExpression.ts +++ b/tests/cases/fourslash/commentsFunctionExpression.ts @@ -32,7 +32,7 @@ ////} ////assig/*16*/ned/*17*/(/*18*/"hey"); -verify.quickInfoAt("1", "var lambdaFoo: (a: number, b: number) => number", "lambdaFoo var comment\nthis is lambda comment"); +verify.quickInfoAt("1", "var lambdaFoo: (a: number, b: number) => number", "this is lambda comment\nlambdaFoo var comment"); goTo.marker('2'); verify.completionListContains('a', '(parameter) a: number', 'param a'); @@ -42,18 +42,18 @@ verify.completionListContains('b', '(parameter) b: number', 'param b'); verify.quickInfoAt("3", "var lambddaNoVarComment: (a: number, b: number) => number", "this is lambda multiplication"); goTo.marker('4'); -verify.completionListContains('lambdaFoo', 'var lambdaFoo: (a: number, b: number) => number', 'lambdaFoo var comment\nthis is lambda comment'); +verify.completionListContains('lambdaFoo', 'var lambdaFoo: (a: number, b: number) => number', "this is lambda comment\nlambdaFoo var comment"); verify.completionListContains('lambddaNoVarComment', 'var lambddaNoVarComment: (a: number, b: number) => number', 'this is lambda multiplication'); verify.signatureHelp( { marker: "5", - docComment: "lambdaFoo var comment\nthis is lambda comment", + docComment: "this is lambda comment\nlambdaFoo var comment", parameterDocComment: "param a", }, { marker: "6", - docComment: "lambdaFoo var comment\nthis is lambda comment", + docComment: "this is lambda comment\nlambdaFoo var comment", parameterDocComment: "param b", }, ); @@ -61,31 +61,31 @@ verify.signatureHelp( // no documentation from nested lambda verify.quickInfos({ 7: "function anotherFunc(a: number): string", - 8: ["(local var) lambdaVar: (b: string) => string", "documentation\ninner docs "], + 8: ["(local var) lambdaVar: (b: string) => string", "inner docs \ndocumentation"], 9: ["(parameter) b: string", "inner parameter "], 10: "(local var) localVar: string", 11: "(local var) localVar: string", 12: ["(parameter) b: string", "inner parameter "], - 13: ["(local var) lambdaVar: (b: string) => string", "documentation\ninner docs "], + 13: ["(local var) lambdaVar: (b: string) => string", "inner docs \ndocumentation"], 14: [ "var assigned: (s: string) => number", - "On variable\nSummary on expression" + "Summary on expression\nOn variable" ] }); goTo.marker('15'); -verify.completionListContains('s', '(parameter) s: string', "the first parameter!\nparam on expression\nOn parameter "); -verify.quickInfoAt("16", "var assigned: (s: string) => number", "On variable\nSummary on expression"); +verify.completionListContains('s', '(parameter) s: string', "On parameter \nparam on expression\nthe first parameter!"); +verify.quickInfoAt("16", "var assigned: (s: string) => number", "Summary on expression\nOn variable"); goTo.marker('17'); -verify.completionListContains("assigned", "var assigned: (s: string) => number", "On variable\nSummary on expression"); +verify.completionListContains("assigned", "var assigned: (s: string) => number", "Summary on expression\nOn variable"); verify.signatureHelp({ marker: "18", - docComment: "On variable\nSummary on expression", - parameterDocComment: "the first parameter!\nparam on expression\nOn parameter ", + docComment: "Summary on expression\nOn variable", + parameterDocComment: "On parameter \nparam on expression\nthe first parameter!", tags: [ - { name: "param", text: "s the first parameter!" }, - { name: "returns", text: "the parameter's length" }, { name: "param", text: "s param on expression" }, { name: "returns", text: "return on expression" }, + { name: "param", text: "s the first parameter!" }, + { name: "returns", text: "the parameter's length" }, ], }); diff --git a/tests/cases/fourslash/fixUnusedIdentifier_jsdocTypeParameter.ts b/tests/cases/fourslash/fixUnusedIdentifier_jsdocTypeParameter.ts new file mode 100644 index 00000000000..efa096e81a1 --- /dev/null +++ b/tests/cases/fourslash/fixUnusedIdentifier_jsdocTypeParameter.ts @@ -0,0 +1,18 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +/////** +//// * @type {() => void} +//// */ +////export const x = 0; + +verify.codeFix({ + description: "Remove declaration for: 'T'", + newFileContent: +`/** + * @type {() => void} + */ +export const x = 0;`, +}); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index a70d6dcf424..89e1948ce77 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -190,6 +190,7 @@ declare namespace FourSlashInterface { applicableRefactorAvailableForRange(): void; refactorAvailable(name: string, actionName?: string): void; + refactorsAvailable(names: ReadonlyArray): void; refactor(options: { name: string; actionName: string; diff --git a/tests/cases/fourslash/navbarNestedCommonJsExports.ts b/tests/cases/fourslash/navbarNestedCommonJsExports.ts new file mode 100644 index 00000000000..3c2d4499172 --- /dev/null +++ b/tests/cases/fourslash/navbarNestedCommonJsExports.ts @@ -0,0 +1,35 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////exports.a = exports.b = exports.c = 0; + +verify.navigationTree({ + text: "", + kind: "script", + childItems: [ + { + text: "a", + kind: "const", + childItems: [ + { + text: "b", + kind: "const", + childItems: [{ text: "c", kind: "const" }], + }, + ], + }, + ], +}); + +verify.navigationBar([ + { + text: "", + kind: "script", + childItems: [ + { text: "a", kind: "const" }, + ], + }, +]); + diff --git a/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_notOnWhitespace.ts b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_notOnWhitespace.ts new file mode 100644 index 00000000000..9ba208b8e95 --- /dev/null +++ b/tests/cases/fourslash/refactorConvertToGetAccessAndSetAccess_notOnWhitespace.ts @@ -0,0 +1,8 @@ +/// + +////class A { +/////*a*/ /*b*/p = 0; +////} + +goTo.select("a", "b"); +verify.refactorsAvailable([]); diff --git a/tests/cases/fourslash/signatureHelpOnDeclaration.ts b/tests/cases/fourslash/signatureHelpOnDeclaration.ts new file mode 100644 index 00000000000..7fc68174383 --- /dev/null +++ b/tests/cases/fourslash/signatureHelpOnDeclaration.ts @@ -0,0 +1,6 @@ +/// + +////function f