diff --git a/.mailmap b/.mailmap index 98f004c58dc..b246515e467 100644 --- a/.mailmap +++ b/.mailmap @@ -140,7 +140,7 @@ Mike Busyrev Mine Starks Mine Starks Mohamed Hegazy ncoley # Natalie Coley -Nathan Shively-Sanders +Nathan Shively-Sanders Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Nathan Yee Nima Zahedi Noah Chen @@ -287,4 +287,29 @@ Stas Vilchik Taras Mankovski Thomas den Hollander Vakhurin Sergey -Zeeshan Ahmed \ No newline at end of file +Zeeshan Ahmed +Orta # Orta Therox +IdeaHunter # @IdeaHunter +kujon # Jakub Korzeniowski +Matt @begincalendar +meyer # @meyer +micbou # @micbou +Alan Agius +Alex Khomchenko +Oussama Ben Brahim benbraou +Cameron Taggart +csigs csigs +Eugene Timokhov +Kris Zyp +Jing Ma +Martin Hiller +Mike Morearty +Priyantha Lankapura <403912+lankaapura@users.noreply.github.com> +Remo H. Jansen +Sean Barag +Sharon Rolel +Stanislav Iliev +Wenlu Wang <805037171@163.com> wenlu.wang <805037171@163.com> kingwl <805037171@163.com> +Wilson Hobbs +Yuval Greenfield +Daniel # @nieltg \ No newline at end of file diff --git a/AUTHORS.md b/AUTHORS.md index c554a588715..7662a5642e7 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -6,8 +6,10 @@ TypeScript is authored by: * Adrian Leonhard * Ahmad Farid * Akshar Patel +* Alan Agius * Alex Chugaev * Alex Eagle +* Alex Khomchenko * Alexander Kuvaev * Alexander Rusakov * Ali Sabzevari @@ -47,6 +49,7 @@ TypeScript is authored by: * Brett Mayen * Bryan Forbes * Caitlin Potter +* Cameron Taggart * @cedvdb * Charles Pierce * Charly POLY @@ -56,6 +59,7 @@ TypeScript is authored by: * Colby Russell * Colin Snover * Cotton Hou +* csigs * Cyrus Najmabadi * Dafrok Zhang * Dahan Gong @@ -85,6 +89,7 @@ TypeScript is authored by: * Erik McClenney * Ethan Resnick * Ethan Rubio +* Eugene Timokhov * Evan Martin * Evan Sebastian * Eyas Sharaiha @@ -111,6 +116,7 @@ TypeScript is authored by: * Herrington Darkholme * Homa Wong * Iain Monro +* @IdeaHunter * Igor Novozhilov * Ika * Ingvar Stepanyan @@ -118,6 +124,7 @@ TypeScript is authored by: * Ivan Enderlin * Ivo Gabe de Wolff * Iwata Hidetaka +* Jakub Korzeniowski * Jakub Młokosiewicz * James Henry * James Whitney @@ -130,6 +137,7 @@ TypeScript is authored by: * Jed Mao * Jeffrey Morlan * Jesse Schalken +* Jing Ma * Jiri Tobisek * Joe Calzaretta * Joe Chung @@ -160,6 +168,7 @@ TypeScript is authored by: * Kevin Lang * Kitson Kelly * Klaus Meinhardt +* Kris Zyp * Kyle Kelley * Kārlis Gaņģis * Lorant Pinter @@ -170,8 +179,10 @@ TypeScript is authored by: * Manish Giri * Marin Marinov * Marius Schulz +* Martin Hiller * Martin Vseticka * Masahiro Wakame +* Matt * Matt Bierner * Matt McCutchen * Matt Mitchell @@ -179,10 +190,13 @@ TypeScript is authored by: * Mattias Buelens * Max Deepfield * Maxwell Paul Brickner +* @meyer * Micah Zoltu +* @micbou * Michael * Michael Bromley * Mike Busyrev +* Mike Morearty * Mine Starks * Mohamed Hegazy * Mohsen Azimi @@ -191,6 +205,7 @@ TypeScript is authored by: * Nathan Shively-Sanders * Nathan Yee * Nicolas Henry +* @nieltg * Nima Zahedi * Noah Chen * Noel Varanda @@ -198,7 +213,9 @@ TypeScript is authored by: * Oleg Mihailik * Oleksandr Chekhovskyi * Omer Sheikh +* Orta Therox * Oskar Segersva¨rd +* Oussama Ben Brahim * Patrick Zhong * Paul Jolly * Paul van Brenk @@ -210,11 +227,13 @@ TypeScript is authored by: * Piero Cangianiello * @piloopin * Prayag Verma +* Priyantha Lankapura * @progre * Punya Biswal * Rado Kirov * Raj Dosanjh * Reiner Dolp +* Remo H. Jansen * Richard Karmazín * Richard Knoll * Richard Sentino @@ -227,8 +246,10 @@ TypeScript is authored by: * Ryohei Ikegami * Sam El-Husseini * Sarangan Rajamanickam +* Sean Barag * Sergey Rubanov * Sergey Shandar +* Sharon Rolel * Sheetal Nandi * Shengping Zhong * Shyyko Serhiy @@ -237,6 +258,7 @@ TypeScript is authored by: * Solal Pirelli * Soo Jae Hwang * Stan Thomas +* Stanislav Iliev * Stanislav Sysoev * Stas Vilchik * Steve Lucco @@ -268,11 +290,14 @@ TypeScript is authored by: * Vilic Vane * Vladimir Kurchatkin * Vladimir Matveev +* Wenlu Wang * Wesley Wigham * William Orr +* Wilson Hobbs * York Yao * @yortus * Yuichi Nukiyama +* Yuval Greenfield * Zeeshan Ahmed * Zev Spitz * Zhengbo Li \ No newline at end of file diff --git a/Gulpfile.ts b/Gulpfile.ts index 2909b10471a..0c410bdfb08 100644 --- a/Gulpfile.ts +++ b/Gulpfile.ts @@ -528,7 +528,7 @@ gulp.task(tsserverLibraryFile, /*help*/ false, [servicesFile, typesMapJson], (do const serverLibraryProject = tsc.createProject("src/server/tsconfig.library.json", getCompilerSettings({ removeComments: false }, /*useBuiltCompiler*/ true)); const {js, dts}: { js: NodeJS.ReadableStream, dts: NodeJS.ReadableStream } = serverLibraryProject.src() .pipe(sourcemaps.init()) - .pipe(newer(tsserverLibraryFile)) + .pipe(newer({ dest: tsserverLibraryFile, extra: ["src/compiler/**/*.ts", "src/services/**/*.ts"] })) .pipe(serverLibraryProject()); return merge2([ diff --git a/scripts/authors.ts b/scripts/authors.ts index fd9d27acd00..b616ceb8601 100644 --- a/scripts/authors.ts +++ b/scripts/authors.ts @@ -164,7 +164,7 @@ namespace Commands { } }); }; - listAuthors.description = "List known and unknown authors for a given spec"; + listAuthors.description = "List known and unknown authors for a given spec, e.g. 'node authors.js listAuthors origin/release-2.6..origin/release-2.7'"; } var args = process.argv.slice(2); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 541443e467b..ac20eb7d6f0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -295,6 +295,10 @@ namespace ts { getAccessibleSymbolChain, getTypePredicateOfSignature, resolveExternalModuleSymbol, + tryGetThisTypeAt: node => { + node = getParseTreeNode(node); + return node && tryGetThisTypeAt(node); + }, }; const tupleTypes: GenericType[] = []; @@ -2061,9 +2065,9 @@ namespace ts { error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName); } else if (noImplicitAny && moduleNotFoundError) { - let errorInfo = !resolvedModule.isExternalLibraryImport ? undefined : chainDiagnosticMessages(/*details*/ undefined, + let errorInfo = resolvedModule.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, - moduleReference); + resolvedModule.packageId.name); errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, @@ -2533,6 +2537,11 @@ namespace ts { return access.accessibility === SymbolAccessibility.Accessible; } + function isValueSymbolAccessible(typeSymbol: Symbol, enclosingDeclaration: Node): boolean { + const access = isSymbolAccessible(typeSymbol, enclosingDeclaration, SymbolFlags.Value, /*shouldComputeAliasesToMakeVisible*/ false); + return access.accessibility === SymbolAccessibility.Accessible; + } + /** * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * @@ -2995,7 +3004,8 @@ namespace ts { declaration.parent.kind === SyntaxKind.SourceFile || declaration.parent.kind === SyntaxKind.ModuleBlock)); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions - return !!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively + return (!!(context.flags & NodeBuilderFlags.UseTypeOfFunction) || contains(context.symbolStack, symbol)) && // it is type of the symbol uses itself recursively + (!(context.flags & NodeBuilderFlags.UseStructuralFallback) || isValueSymbolAccessible(symbol, context.enclosingDeclaration)); // And the build is going to succeed without visibility error or there is no structural fallback allowed } } } @@ -5408,18 +5418,19 @@ namespace ts { return symbol; } - function getTypeWithThisArgument(type: Type, thisArgument?: Type): Type { + function getTypeWithThisArgument(type: Type, thisArgument?: Type, needApparentType?: boolean): Type { if (getObjectFlags(type) & ObjectFlags.Reference) { const target = (type).target; const typeArguments = (type).typeArguments; if (length(target.typeParameters) === length(typeArguments)) { - return createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType])); + const ref = createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType])); + return needApparentType ? getApparentType(ref) : ref; } } else if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(map((type).types, t => getTypeWithThisArgument(t, thisArgument))); + return getIntersectionType(map((type).types, t => getTypeWithThisArgument(t, thisArgument, needApparentType))); } - return type; + return needApparentType ? getApparentType(type) : type; } function resolveObjectTypeMembers(type: ObjectType, source: InterfaceTypeWithDeclaredMembers, typeParameters: TypeParameter[], typeArguments: Type[]) { @@ -6099,7 +6110,7 @@ namespace ts { } function getApparentTypeOfIntersectionType(type: IntersectionType) { - return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); + return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type, /*apparentType*/ true)); } function getResolvedTypeParameterDefault(typeParameter: TypeParameter): Type | undefined { @@ -10913,6 +10924,7 @@ namespace ts { return { typeParameter, candidates: undefined, + contraCandidates: undefined, inferredType: undefined, priority: undefined, topLevel: true, @@ -10924,6 +10936,7 @@ namespace ts { return { typeParameter: inference.typeParameter, candidates: inference.candidates && inference.candidates.slice(), + contraCandidates: inference.contraCandidates && inference.contraCandidates.slice(), inferredType: inference.inferredType, priority: inference.priority, topLevel: inference.topLevel, @@ -11037,6 +11050,7 @@ namespace ts { function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { let symbolStack: Symbol[]; let visited: Map; + let contravariant = false; inferFromTypes(originalSource, originalTarget); function inferFromTypes(source: Type, target: Type) { @@ -11104,18 +11118,20 @@ namespace ts { const inference = getInferenceInfoForType(target); if (inference) { if (!inference.isFixed) { - // We give lowest priority to inferences of implicitNeverType (which is used as the - // element type for empty array literals). Thus, inferences from empty array literals - // only matter when no other inferences are made. - const p = priority | (source === implicitNeverType ? InferencePriority.NeverType : 0); - if (!inference.candidates || p < inference.priority) { - inference.candidates = [source]; - inference.priority = p; + if (inference.priority === undefined || priority < inference.priority) { + inference.candidates = undefined; + inference.contraCandidates = undefined; + inference.priority = priority; } - else if (p === inference.priority) { - inference.candidates.push(source); + if (priority === inference.priority) { + if (contravariant) { + inference.contraCandidates = append(inference.contraCandidates, source); + } + else { + inference.candidates = append(inference.candidates, source); + } } - if (!(p & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { + if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, target)) { inference.topLevel = false; } } @@ -11138,15 +11154,15 @@ namespace ts { } } else if (source.flags & TypeFlags.Index && target.flags & TypeFlags.Index) { - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes((source).type, (target).type); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else if ((isLiteralType(source) || source.flags & TypeFlags.String) && target.flags & TypeFlags.Index) { const empty = createEmptyObjectTypeFromStringLiteral(source); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes(empty, (target as IndexType).type); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else if (source.flags & TypeFlags.IndexedAccess && target.flags & TypeFlags.IndexedAccess) { inferFromTypes((source).objectType, (target).objectType); @@ -11215,9 +11231,9 @@ namespace ts { function inferFromContravariantTypes(source: Type, target: Type) { if (strictFunctionTypes) { - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; inferFromTypes(source, target); - priority ^= InferencePriority.Contravariant; + contravariant = !contravariant; } else { inferFromTypes(source, target); @@ -11396,10 +11412,19 @@ namespace ts { // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a // union type. Otherwise, infer a common supertype. - const unwidenedType = inference.priority & InferencePriority.Contravariant ? getCommonSubtype(baseCandidates) : - context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? getUnionType(baseCandidates, UnionReduction.Subtype) : + const unwidenedType = context.flags & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.ReturnType ? + getUnionType(baseCandidates, UnionReduction.Subtype) : getCommonSupertype(baseCandidates); inferredType = getWidenedType(unwidenedType); + // If we have inferred 'never' but have contravariant candidates. To get a more specific type we + // infer from the contravariant candidates instead. + if (inferredType.flags & TypeFlags.Never && inference.contraCandidates) { + inferredType = getCommonSubtype(inference.contraCandidates); + } + } + else if (inference.contraCandidates) { + // We only have contravariant inferences, infer the best common subtype of those + inferredType = getCommonSubtype(inference.contraCandidates); } else if (context.flags & InferenceFlags.NoDefault) { // We use silentNeverType as the wildcard that signals no inferences. @@ -13250,6 +13275,16 @@ namespace ts { if (needToCaptureLexicalThis) { captureLexicalThis(node, container); } + + const type = tryGetThisTypeAt(node, container); + if (!type && noImplicitThis) { + // With noImplicitThis, functions may not reference 'this' if it has type 'any' + error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation); + } + return type || anyType; + } + + function tryGetThisTypeAt(node: Node, container = getThisContainer(node, /*includeArrowFunctions*/ false)): Type | undefined { if (isFunctionLike(container) && (!isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container))) { // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated. @@ -13288,12 +13323,6 @@ namespace ts { return type; } } - - if (noImplicitThis) { - // With noImplicitThis, functions may not reference 'this' if it has type 'any' - error(node, Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation); - } - return anyType; } function getTypeForThisExpressionFromJSDoc(node: Node) { @@ -14042,7 +14071,7 @@ namespace ts { // If the given type is an object or union type with a single signature, and if that signature has at // least as many parameters as the given function, return the signature. Otherwise return undefined. function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature { - const signatures = getSignaturesOfStructuredType(type, SignatureKind.Call); + const signatures = getSignaturesOfType(type, SignatureKind.Call); if (signatures.length === 1) { const signature = signatures[0]; if (!isAritySmaller(signature, node)) { @@ -15797,7 +15826,7 @@ namespace ts { } function isValidMethodAccess(method: Symbol, type: Type) { const propType = getTypeOfFuncClassEnumModule(method); - const signatures = getSignaturesOfType(propType, SignatureKind.Call); + const signatures = getSignaturesOfType(getNonNullableType(propType), SignatureKind.Call); Debug.assert(signatures.length !== 0); return signatures.some(sig => { const thisType = getThisTypeOfSignature(sig); @@ -22280,7 +22309,8 @@ namespace ts { indexType: Type, indexKind: IndexKind): void { - if (!indexType) { + // ESSymbol properties apply to neither string nor numeric indexers. + if (!indexType || isKnownSymbol(prop)) { return; } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 4813d4b4300..eb9f1e3cf34 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -151,7 +151,7 @@ namespace ts { }, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, - description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon + description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation }, { name: "allowJs", diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6813aec55a5..376d9a242fa 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -20,6 +20,7 @@ namespace ts { /* @internal */ namespace ts { + export const emptyArray: never[] = [] as never[]; /** Create a MapLike with good performance. */ function createDictionaryObject(): MapLike { const map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword @@ -1341,7 +1342,8 @@ namespace ts { export function cloneMap(map: SymbolTable): SymbolTable; export function cloneMap(map: ReadonlyMap): Map; - export function cloneMap(map: ReadonlyMap | SymbolTable): Map | SymbolTable { + export function cloneMap(map: ReadonlyUnderscoreEscapedMap): UnderscoreEscapedMap; + export function cloneMap(map: ReadonlyMap | ReadonlyUnderscoreEscapedMap | SymbolTable): Map | UnderscoreEscapedMap | SymbolTable { const clone = createMap(); copyEntries(map as Map, clone); return clone; @@ -1912,7 +1914,7 @@ namespace ts { return p2 + 1; } if (path.charCodeAt(1) === CharacterCodes.colon) { - if (path.charCodeAt(2) === CharacterCodes.slash) return 3; + if (path.charCodeAt(2) === CharacterCodes.slash || path.charCodeAt(2) === CharacterCodes.backslash) return 3; } // Per RFC 1738 'file' URI schema has the shape file:/// // if is omitted then it is assumed that host value is 'localhost', @@ -3053,6 +3055,11 @@ namespace ts { export function assertTypeIsNever(_: never): void { } // tslint:disable-line no-empty + export const emptyFileSystemEntries: FileSystemEntries = { + files: emptyArray, + directories: emptyArray + }; + export function singleElementArray(t: T | undefined): T[] | undefined { return t === undefined ? undefined : [t]; } diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index a9c238a230a..1a35f520ce5 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -358,7 +358,7 @@ namespace ts { } else { errorNameNode = declaration.name; - const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteDefaultSymbolWithoutName | + const format = TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteDefaultSymbolWithoutName | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | (shouldUseResolverType ? TypeFormatFlags.AddUndefined : 0); resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer); @@ -378,7 +378,7 @@ namespace ts { resolver.writeReturnTypeOfSignatureDeclaration( signature, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); errorNameNode = undefined; } @@ -643,7 +643,7 @@ namespace ts { resolver.writeTypeOfExpression( expr, enclosingDeclaration, - TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, + TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseStructuralFallback | TypeFormatFlags.WriteClassExpressionAsTypeLiteral | TypeFormatFlags.WriteDefaultSymbolWithoutName, writer); write(";"); writeLine(); diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index cf5ccb1397d..6a14aab2aee 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3015,7 +3015,7 @@ "category": "Message", "code": 6078 }, - "Specify library files to be included in the compilation: ": { + "Specify library files to be included in the compilation.": { "category": "Message", "code": 6079 }, @@ -3451,6 +3451,10 @@ "category": "Error", "code": 6189 }, + "Found 'package.json' at '{0}'. Package ID is '{1}'.": { + "category": "Message", + "code": 6190 + }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 8a1de17826c..705c0811cdc 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -289,6 +289,9 @@ namespace ts { let generatedNames: Map; // Set of names generated by the NameGenerator. let tempFlagsStack: TempFlags[]; // Stack of enclosing name generation scopes. let tempFlags: TempFlags; // TempFlags for the current name generation scope. + let reservedNamesStack: Map[]; // Stack of TempFlags reserved in enclosing name generation scopes. + let reservedNames: Map; // TempFlags to reserve in nested name generation scopes. + let writer: EmitTextWriter; let ownWriter: EmitTextWriter; let write = writeBase; @@ -434,6 +437,7 @@ namespace ts { generatedNames = createMap(); tempFlagsStack = []; tempFlags = TempFlags.Auto; + reservedNamesStack = []; comments.reset(); setWriter(/*output*/ undefined); } @@ -3083,6 +3087,7 @@ namespace ts { } tempFlagsStack.push(tempFlags); tempFlags = 0; + reservedNamesStack.push(reservedNames); } /** @@ -3093,16 +3098,24 @@ namespace ts { return; } tempFlags = tempFlagsStack.pop(); + reservedNames = reservedNamesStack.pop(); + } + + function reserveNameInNestedScopes(name: string) { + if (!reservedNames || reservedNames === lastOrUndefined(reservedNamesStack)) { + reservedNames = createMap(); + } + reservedNames.set(name, true); } /** * Generate the text for a generated identifier. */ function generateName(name: GeneratedIdentifier) { - if (name.autoGenerateKind === GeneratedIdentifierKind.Node) { + if ((name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) === GeneratedIdentifierFlags.Node) { // Node names generate unique names based on their original node // and are cached based on that node's id. - if (name.skipNameGenerationScope) { + if (name.autoGenerateFlags & GeneratedIdentifierFlags.SkipNameGenerationScope) { const savedTempFlags = tempFlags; popNameGenerationScope(/*node*/ undefined); const result = generateNameCached(getNodeForGeneratedName(name)); @@ -3134,7 +3147,8 @@ namespace ts { function isUniqueName(name: string): boolean { return !(hasGlobalName && hasGlobalName(name)) && !currentSourceFile.identifiers.has(name) - && !generatedNames.has(name); + && !generatedNames.has(name) + && !(reservedNames && reservedNames.has(name)); } /** @@ -3158,11 +3172,14 @@ namespace ts { * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name. * Note that names generated by makeTempVariableName and makeUniqueName will never conflict. */ - function makeTempVariableName(flags: TempFlags): string { + function makeTempVariableName(flags: TempFlags, reservedInNestedScopes?: boolean): string { if (flags && !(tempFlags & flags)) { const name = flags === TempFlags._i ? "_i" : "_n"; if (isUniqueName(name)) { tempFlags |= flags; + if (reservedInNestedScopes) { + reserveNameInNestedScopes(name); + } return name; } } @@ -3175,6 +3192,9 @@ namespace ts { ? "_" + String.fromCharCode(CharacterCodes.a + count) : "_" + (count - 26); if (isUniqueName(name)) { + if (reservedInNestedScopes) { + reserveNameInNestedScopes(name); + } return name; } } @@ -3275,12 +3295,12 @@ namespace ts { * Generates a unique identifier for a node. */ function makeName(name: GeneratedIdentifier) { - switch (name.autoGenerateKind) { - case GeneratedIdentifierKind.Auto: - return makeTempVariableName(TempFlags.Auto); - case GeneratedIdentifierKind.Loop: - return makeTempVariableName(TempFlags._i); - case GeneratedIdentifierKind.Unique: + switch (name.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) { + case GeneratedIdentifierFlags.Auto: + return makeTempVariableName(TempFlags.Auto, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); + case GeneratedIdentifierFlags.Loop: + return makeTempVariableName(TempFlags._i, !!(name.autoGenerateFlags & GeneratedIdentifierFlags.ReservedInNestedScopes)); + case GeneratedIdentifierFlags.Unique: return makeUniqueName(idText(name)); } @@ -3300,7 +3320,7 @@ namespace ts { // if "node" is a different generated name (having a different // "autoGenerateId"), use it and stop traversing. if (isIdentifier(node) - && node.autoGenerateKind === GeneratedIdentifierKind.Node + && node.autoGenerateFlags === GeneratedIdentifierFlags.Node && node.autoGenerateId !== autoGenerateId) { break; } diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 14c8ad91eeb..c622ddfb2bf 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -117,7 +117,7 @@ namespace ts { const node = createSynthesizedNode(SyntaxKind.Identifier); node.escapedText = escapeLeadingUnderscores(text); node.originalKeywordKind = text ? stringToToken(text) : SyntaxKind.Unknown; - node.autoGenerateKind = GeneratedIdentifierKind.None; + node.autoGenerateFlags = GeneratedIdentifierFlags.None; node.autoGenerateId = 0; if (typeArguments) { node.typeArguments = createNodeArray(typeArguments as ReadonlyArray); @@ -137,21 +137,26 @@ namespace ts { let nextAutoGenerateId = 0; /** Create a unique temporary variable. */ - export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier { + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined): Identifier; + /* @internal */ export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes: boolean): Identifier; // tslint:disable-line unified-signatures + export function createTempVariable(recordTempVariable: ((node: Identifier) => void) | undefined, reservedInNestedScopes?: boolean): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Auto; + name.autoGenerateFlags = GeneratedIdentifierFlags.Auto; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; if (recordTempVariable) { recordTempVariable(name); } + if (reservedInNestedScopes) { + name.autoGenerateFlags |= GeneratedIdentifierFlags.ReservedInNestedScopes; + } return name; } /** Create a unique temporary variable for use in a loop. */ export function createLoopVariable(): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Loop; + name.autoGenerateFlags = GeneratedIdentifierFlags.Loop; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; @@ -160,7 +165,7 @@ namespace ts { /** Create a unique name based on the supplied text. */ export function createUniqueName(text: string): Identifier { const name = createIdentifier(text); - name.autoGenerateKind = GeneratedIdentifierKind.Unique; + name.autoGenerateFlags = GeneratedIdentifierFlags.Unique; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; @@ -168,14 +173,15 @@ namespace ts { /** Create a unique name generated for a node. */ export function getGeneratedNameForNode(node: Node): Identifier; - // tslint:disable-next-line unified-signatures - /*@internal*/ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; + /* @internal */ export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier; // tslint:disable-line unified-signatures export function getGeneratedNameForNode(node: Node, shouldSkipNameGenerationScope?: boolean): Identifier { const name = createIdentifier(""); - name.autoGenerateKind = GeneratedIdentifierKind.Node; + name.autoGenerateFlags = GeneratedIdentifierFlags.Node; name.autoGenerateId = nextAutoGenerateId; name.original = node; - name.skipNameGenerationScope = !!shouldSkipNameGenerationScope; + if (shouldSkipNameGenerationScope) { + name.autoGenerateFlags |= GeneratedIdentifierFlags.SkipNameGenerationScope; + } nextAutoGenerateId++; return name; } @@ -3954,7 +3960,9 @@ namespace ts { // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions // so in case when comma expression is introduced as a part of previous transformations // if should be wrapped in parens since comma operator has the lowest precedence - return e.kind === SyntaxKind.BinaryExpression && (e).operatorToken.kind === SyntaxKind.CommaToken + const emittedExpression = skipPartiallyEmittedExpressions(e); + return emittedExpression.kind === SyntaxKind.BinaryExpression && (emittedExpression).operatorToken.kind === SyntaxKind.CommaToken || + emittedExpression.kind === SyntaxKind.CommaListExpression ? createParen(e) : e; } diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 018bddd420b..f72876bd5fc 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -801,7 +801,9 @@ namespace ts { } const resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { - return noPackageId(resolvedFromFile); + const nm = considerPackageJson ? parseNodeModuleFromPath(resolvedFromFile.path) : undefined; + const packageId = nm && getPackageJsonInfo(nm.packageDirectory, nm.subModuleName, failedLookupLocations, /*onlyRecordFailures*/ false, state).packageId; + return withPackageId(packageId, resolvedFromFile); } } if (!onlyRecordFailures) { @@ -816,6 +818,45 @@ namespace ts { return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } + const nodeModulesPathPart = "/node_modules/"; + + /** + * This will be called on the successfully resolved path from `loadModuleFromFile`. + * (Not neeeded for `loadModuleFromNodeModules` as that looks up the `package.json` as part of resolution.) + * + * packageDirectory is the directory of the package itself. + * subModuleName is the path within the package. + * For `blah/node_modules/foo/index.d.ts` this is { packageDirectory: "foo", subModuleName: "" }. (Part before "/node_modules/" is ignored.) + * For `/node_modules/foo/bar.d.ts` this is { packageDirectory: "foo", subModuleName": "bar" }. + * For `/node_modules/@types/foo/bar/index.d.ts` this is { packageDirectory: "@types/foo", subModuleName: "bar" }. + */ + function parseNodeModuleFromPath(path: string): { packageDirectory: string, subModuleName: string } | undefined { + path = normalizePath(path); + const idx = path.lastIndexOf(nodeModulesPathPart); + if (idx === -1) { + return undefined; + } + + const indexAfterNodeModules = idx + nodeModulesPathPart.length; + let indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterNodeModules); + if (path.charCodeAt(indexAfterNodeModules) === CharacterCodes.at) { + indexAfterPackageName = moveToNextDirectorySeparatorIfAvailable(path, indexAfterPackageName); + } + const packageDirectory = path.slice(0, indexAfterPackageName); + const subModuleName = removeExtensionAndIndex(path.slice(indexAfterPackageName + 1)); + return { packageDirectory, subModuleName }; + } + + function moveToNextDirectorySeparatorIfAvailable(path: string, prevSeparatorIndex: number): number { + const nextSeparatorIndex = path.indexOf(directorySeparator, prevSeparatorIndex + 1); + return nextSeparatorIndex === -1 ? prevSeparatorIndex : nextSeparatorIndex; + } + + function removeExtensionAndIndex(path: string): string { + const noExtension = removeFileExtension(path); + return noExtension === "index" ? "" : removeSuffix(noExtension, "/index"); + } + /* @internal */ export function directoryProbablyExists(directoryName: string, host: { directoryExists?: (directoryName: string) => boolean }): boolean { // if host does not support 'directoryExists' assume that directory will exist @@ -919,13 +960,18 @@ namespace ts { const directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host); const packageJsonPath = pathToPackageJson(nodeModuleDirectory); if (directoryExists && host.fileExists(packageJsonPath)) { - if (traceEnabled) { - trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); - } const packageJsonContent = readJson(packageJsonPath, host); const packageId: PackageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string" ? { name: packageJsonContent.name, subModuleName, version: packageJsonContent.version } : undefined; + if (traceEnabled) { + if (packageId) { + trace(host, Diagnostics.Found_package_json_at_0_Package_ID_is_1, packageJsonPath, packageIdToString(packageId)); + } + else { + trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath); + } + } return { found: true, packageJsonContent, packageId }; } else { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index e54bae619ae..bd45857fc51 100755 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1818,7 +1818,7 @@ namespace ts { }, shouldCreateNewSourceFile); if (packageId) { - const packageIdKey = `${packageId.name}/${packageId.subModuleName}@${packageId.version}`; + const packageIdKey = packageIdToString(packageId); const fileFromPackageId = packageIdToSourceFile.get(packageIdKey); if (fileFromPackageId) { // Some other SourceFile already exists with this package name and version. diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index c8bb2ec0a25..5001ea58336 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -725,10 +725,14 @@ namespace ts { return accumulator; } + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state); } + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; export function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state); } diff --git a/src/compiler/sys.ts b/src/compiler/sys.ts index f744b9ab0eb..3256eef4dc2 100644 --- a/src/compiler/sys.ts +++ b/src/compiler/sys.ts @@ -392,7 +392,7 @@ namespace ts { return { files, directories }; } catch (e) { - return { files: [], directories: [] }; + return emptyFileSystemEntries; } } @@ -518,7 +518,12 @@ namespace ts { process.exit(exitCode); }, realpath(path: string): string { - return _fs.realpathSync(path); + try { + return _fs.realpathSync(path); + } + catch { + return path; + } }, debugMode: some(process.execArgv, arg => /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg)), tryEnableSourceMapsForHost() { diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index a283275d066..bafe43b0b15 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -70,7 +70,13 @@ namespace ts { if (value) { value = visitNode(value, visitor, isExpression); - if (needsValue) { + + if (isIdentifier(value) && bindingOrAssignmentElementAssignsToName(node, value.escapedText)) { + // If the right-hand value of the assignment is also an assignment target then + // we need to cache the right-hand value. + value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ false, location); + } + else if (needsValue) { // If the right-hand value of the destructuring assignment needs to be preserved (as // is the case when the destructuring assignment is part of a larger expression), // then we need to cache the right-hand value. @@ -123,6 +129,27 @@ namespace ts { } } + function bindingOrAssignmentElementAssignsToName(element: BindingOrAssignmentElement, escapedName: __String): boolean { + const target = getTargetOfBindingOrAssignmentElement(element); + if (isBindingOrAssignmentPattern(target)) { + return bindingOrAssignmentPatternAssignsToName(target, escapedName); + } + else if (isIdentifier(target)) { + return target.escapedText === escapedName; + } + return false; + } + + function bindingOrAssignmentPatternAssignsToName(pattern: BindingOrAssignmentPattern, escapedName: __String): boolean { + const elements = getElementsOfBindingOrAssignmentPattern(pattern); + for (const element of elements) { + if (bindingOrAssignmentElementAssignsToName(element, escapedName)) { + return true; + } + } + return false; + } + /** * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations. * @@ -157,6 +184,17 @@ namespace ts { createArrayBindingOrAssignmentElement: makeBindingElement, visitor }; + + if (isVariableDeclaration(node)) { + let initializer = getInitializerOfBindingOrAssignmentElement(node); + if (initializer && isIdentifier(initializer) && bindingOrAssignmentElementAssignsToName(node, initializer.escapedText)) { + // If the right-hand value of the assignment is also an assignment target then + // we need to cache the right-hand value. + initializer = ensureIdentifier(flattenContext, initializer, /*reuseIdentifierExpressions*/ false, initializer); + node = updateVariableDeclaration(node, node.name, node.type, initializer); + } + } + flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer); if (pendingExpressions) { const temp = createTempVariable(/*recordTempVariable*/ undefined); diff --git a/src/compiler/transformers/es2017.ts b/src/compiler/transformers/es2017.ts index 9fa39da2d23..905686c8861 100644 --- a/src/compiler/transformers/es2017.ts +++ b/src/compiler/transformers/es2017.ts @@ -12,9 +12,9 @@ namespace ts { export function transformES2017(context: TransformationContext) { const { - startLexicalEnvironment, resumeLexicalEnvironment, - endLexicalEnvironment + endLexicalEnvironment, + hoistVariableDeclaration } = context; const resolver = context.getEmitResolver(); @@ -33,6 +33,8 @@ namespace ts { */ let enclosingSuperContainerFlags: NodeCheckFlags = 0; + let enclosingFunctionParameterNames: UnderscoreEscapedMap; + // Save the previous transformation hooks. const previousOnEmitNode = context.onEmitNode; const previousOnSubstituteNode = context.onSubstituteNode; @@ -83,6 +85,108 @@ namespace ts { } } + function asyncBodyVisitor(node: Node): VisitResult { + if (isNodeWithPossibleHoistedDeclaration(node)) { + switch (node.kind) { + case SyntaxKind.VariableStatement: + return visitVariableStatementInAsyncBody(node); + case SyntaxKind.ForStatement: + return visitForStatementInAsyncBody(node); + case SyntaxKind.ForInStatement: + return visitForInStatementInAsyncBody(node); + case SyntaxKind.ForOfStatement: + return visitForOfStatementInAsyncBody(node); + case SyntaxKind.CatchClause: + return visitCatchClauseInAsyncBody(node); + case SyntaxKind.Block: + case SyntaxKind.SwitchStatement: + case SyntaxKind.CaseBlock: + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + case SyntaxKind.TryStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.IfStatement: + case SyntaxKind.WithStatement: + case SyntaxKind.LabeledStatement: + return visitEachChild(node, asyncBodyVisitor, context); + default: + return Debug.assertNever(node, "Unhandled node."); + } + } + return visitor(node); + } + + function visitCatchClauseInAsyncBody(node: CatchClause) { + const catchClauseNames = createUnderscoreEscapedMap(); + recordDeclarationName(node.variableDeclaration, catchClauseNames); + + // names declared in a catch variable are block scoped + let catchClauseUnshadowedNames: UnderscoreEscapedMap; + catchClauseNames.forEach((_, escapedName) => { + if (enclosingFunctionParameterNames.has(escapedName)) { + if (!catchClauseUnshadowedNames) { + catchClauseUnshadowedNames = cloneMap(enclosingFunctionParameterNames); + } + catchClauseUnshadowedNames.delete(escapedName); + } + }); + + if (catchClauseUnshadowedNames) { + const savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames; + enclosingFunctionParameterNames = catchClauseUnshadowedNames; + const result = visitEachChild(node, asyncBodyVisitor, context); + enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames; + return result; + } + else { + return visitEachChild(node, asyncBodyVisitor, context); + } + } + + function visitVariableStatementInAsyncBody(node: VariableStatement) { + if (isVariableDeclarationListWithCollidingName(node.declarationList)) { + const expression = visitVariableDeclarationListWithCollidingNames(node.declarationList, /*hasReceiver*/ false); + return expression ? createStatement(expression) : undefined; + } + return visitEachChild(node, visitor, context); + } + + function visitForInStatementInAsyncBody(node: ForInStatement) { + return updateForIn( + node, + isVariableDeclarationListWithCollidingName(node.initializer) + ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true) + : visitNode(node.initializer, visitor, isForInitializer), + visitNode(node.expression, visitor, isExpression), + visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock) + ); + } + + function visitForOfStatementInAsyncBody(node: ForOfStatement) { + return updateForOf( + node, + visitNode(node.awaitModifier, visitor, isToken), + isVariableDeclarationListWithCollidingName(node.initializer) + ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ true) + : visitNode(node.initializer, visitor, isForInitializer), + visitNode(node.expression, visitor, isExpression), + visitNode(node.statement, asyncBodyVisitor, isStatement, liftToBlock) + ); + } + + function visitForStatementInAsyncBody(node: ForStatement) { + return updateFor( + node, + isVariableDeclarationListWithCollidingName(node.initializer) + ? visitVariableDeclarationListWithCollidingNames(node.initializer, /*hasReceiver*/ false) + : visitNode(node.initializer, visitor, isForInitializer), + visitNode(node.condition, visitor, isExpression), + visitNode(node.incrementor, visitor, isExpression), + visitNode((node).statement, asyncBodyVisitor, isStatement, liftToBlock) + ); + } + /** * Visits an AwaitExpression node. * @@ -197,6 +301,82 @@ namespace ts { ); } + function recordDeclarationName({ name }: ParameterDeclaration | VariableDeclaration | BindingElement, names: UnderscoreEscapedMap) { + if (isIdentifier(name)) { + names.set(name.escapedText, true); + } + else { + for (const element of name.elements) { + if (!isOmittedExpression(element)) { + recordDeclarationName(element, names); + } + } + } + } + + function isVariableDeclarationListWithCollidingName(node: ForInitializer): node is VariableDeclarationList { + return node + && isVariableDeclarationList(node) + && !(node.flags & NodeFlags.BlockScoped) + && forEach(node.declarations, collidesWithParameterName); + } + + function visitVariableDeclarationListWithCollidingNames(node: VariableDeclarationList, hasReceiver: boolean) { + hoistVariableDeclarationList(node); + + const variables = getInitializedVariables(node); + if (variables.length === 0) { + if (hasReceiver) { + return visitNode(convertToAssignmentElementTarget(node.declarations[0].name), visitor, isExpression); + } + return undefined; + } + + return inlineExpressions(map(variables, transformInitializedVariable)); + } + + function hoistVariableDeclarationList(node: VariableDeclarationList) { + forEach(node.declarations, hoistVariable); + } + + function hoistVariable({ name }: VariableDeclaration | BindingElement) { + if (isIdentifier(name)) { + hoistVariableDeclaration(name); + } + else { + for (const element of name.elements) { + if (!isOmittedExpression(element)) { + hoistVariable(element); + } + } + } + } + + function transformInitializedVariable(node: VariableDeclaration) { + const converted = setSourceMapRange( + createAssignment( + convertToAssignmentElementTarget(node.name), + node.initializer + ), + node + ); + return visitNode(converted, visitor, isExpression); + } + + function collidesWithParameterName({ name }: VariableDeclaration | BindingElement): boolean { + if (isIdentifier(name)) { + return enclosingFunctionParameterNames.has(name.escapedText); + } + else { + for (const element of name.elements) { + if (!isOmittedExpression(element) && collidesWithParameterName(element)) { + return true; + } + } + } + return false; + } + function transformAsyncFunctionBody(node: MethodDeclaration | AccessorDeclaration | FunctionDeclaration | FunctionExpression): FunctionBody; function transformAsyncFunctionBody(node: ArrowFunction): ConciseBody; function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody { @@ -214,6 +394,13 @@ namespace ts { // passed to `__awaiter` is executed inside of the callback to the // promise constructor. + const savedEnclosingFunctionParameterNames = enclosingFunctionParameterNames; + enclosingFunctionParameterNames = createUnderscoreEscapedMap(); + for (const parameter of node.parameters) { + recordDeclarationName(parameter, enclosingFunctionParameterNames); + } + + let result: ConciseBody; if (!isArrowFunction) { const statements: Statement[] = []; const statementOffset = addPrologue(statements, (node.body).statements, /*ensureUseStrict*/ false, visitor); @@ -223,7 +410,7 @@ namespace ts { context, hasLexicalArguments, promiseConstructor, - transformFunctionBodyWorker(node.body, statementOffset) + transformAsyncFunctionBodyWorker(node.body, statementOffset) ) ) ); @@ -246,35 +433,36 @@ namespace ts { } } - return block; + result = block; } else { const expression = createAwaiterHelper( context, hasLexicalArguments, promiseConstructor, - transformFunctionBodyWorker(node.body) + transformAsyncFunctionBodyWorker(node.body) ); const declarations = endLexicalEnvironment(); if (some(declarations)) { const block = convertToFunctionBody(expression); - return updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements)); + result = updateBlock(block, setTextRange(createNodeArray(concatenate(block.statements, declarations)), block.statements)); + } + else { + result = expression; } - - return expression; } + + enclosingFunctionParameterNames = savedEnclosingFunctionParameterNames; + return result; } - function transformFunctionBodyWorker(body: ConciseBody, start?: number) { + function transformAsyncFunctionBodyWorker(body: ConciseBody, start?: number) { if (isBlock(body)) { - return updateBlock(body, visitLexicalEnvironment(body.statements, visitor, context, start)); + return updateBlock(body, visitNodes(body.statements, asyncBodyVisitor, isStatement, start)); } else { - startLexicalEnvironment(); - const visited = convertToFunctionBody(visitNode(body, visitor, isConciseBody)); - const declarations = endLexicalEnvironment(); - return updateBlock(visited, setTextRange(createNodeArray(concatenate(visited.statements, declarations)), visited.statements)); + return convertToFunctionBody(visitNode(body, asyncBodyVisitor, isConciseBody)); } } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index cdb0d0667ad..f6c5d145a90 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -893,11 +893,14 @@ namespace ts { if (some(staticProperties) || some(pendingExpressions)) { const expressions: Expression[] = []; - const temp = createTempVariable(hoistVariableDeclaration); - if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference) { + const isClassWithConstructorReference = resolver.getNodeCheckFlags(node) & NodeCheckFlags.ClassWithConstructorReference; + const temp = createTempVariable(hoistVariableDeclaration, !!isClassWithConstructorReference); + if (isClassWithConstructorReference) { // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); - classAliases[getOriginalNodeId(node)] = getSynthesizedClone(temp); + const alias = getSynthesizedClone(temp); + alias.autoGenerateFlags &= ~GeneratedIdentifierFlags.ReservedInNestedScopes; + classAliases[getOriginalNodeId(node)] = alias; } // To preserve the behavior of the old emitter, we explicitly indent diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 13b2b63c1de..d9bce9381be 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -676,12 +676,18 @@ namespace ts { export type ModifiersArray = NodeArray; /*@internal*/ - export const enum GeneratedIdentifierKind { - None, // Not automatically generated. - Auto, // Automatically generated identifier. - Loop, // Automatically generated identifier with a preference for '_i'. - Unique, // Unique name based on the 'text' property. - Node, // Unique name based on the node in the 'original' property. + export const enum GeneratedIdentifierFlags { + // Kinds + None = 0, // Not automatically generated. + Auto = 1, // Automatically generated identifier. + Loop = 2, // Automatically generated identifier with a preference for '_i'. + Unique = 3, // Unique name based on the 'text' property. + Node = 4, // Unique name based on the node in the 'original' property. + KindMask = 7, // Mask to extract the kind of identifier from its flags. + + // Flags + SkipNameGenerationScope = 1 << 3, // Should skip a name generation scope when generating the name for this identifier + ReservedInNestedScopes = 1 << 4, // Reserve the generated name in nested scopes } export interface Identifier extends PrimaryExpression, Declaration { @@ -692,12 +698,11 @@ namespace ts { */ escapedText: __String; originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later - /*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier. + /*@internal*/ autoGenerateFlags?: GeneratedIdentifierFlags; // Specifies whether to auto-generate the text for an identifier. /*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name. isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace /*@internal*/ typeArguments?: NodeArray; // Only defined on synthesized nodes. Though not syntactically valid, used in emitting diagnostics, quickinfo, and signature help. /*@internal*/ jsdocDotPos?: number; // Identifier occurs in JSDoc-style generic: Id. - /*@internal*/ skipNameGenerationScope?: boolean; // Should skip a name generation scope when generating the name for this identifier } // Transient identifier node (marked by id === -1) @@ -707,10 +712,7 @@ namespace ts { /*@internal*/ export interface GeneratedIdentifier extends Identifier { - autoGenerateKind: GeneratedIdentifierKind.Auto - | GeneratedIdentifierKind.Loop - | GeneratedIdentifierKind.Unique - | GeneratedIdentifierKind.Node; + autoGenerateFlags: GeneratedIdentifierFlags; } export interface QualifiedName extends Node { @@ -1465,7 +1467,7 @@ namespace ts { | SpreadAssignment // AssignmentRestProperty ; - export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + export type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; export type ObjectBindingOrAssignmentPattern = ObjectBindingPattern @@ -2919,6 +2921,8 @@ namespace ts { /* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined; /* @internal */ getTypePredicateOfSignature(signature: Signature): TypePredicate; /* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol; + /** @param node A location where we might consider accessing `this`. Not necessarily a ThisExpression. */ + /* @internal */ tryGetThisTypeAt(node: Node): Type | undefined; } /* @internal */ @@ -2934,6 +2938,7 @@ namespace ts { NoTruncation = 1 << 0, // Don't truncate result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] WriteDefaultSymbolWithoutName = 1 << 2, // Write `default`-named symbols as `default` instead of how they were written + UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible // empty space WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) @@ -2968,6 +2973,7 @@ namespace ts { NoTruncation = 1 << 0, // Don't truncate typeToString result WriteArrayAsGenericType = 1 << 1, // Write Array instead T[] WriteDefaultSymbolWithoutName = 1 << 2, // Write all `defaut`-named symbols as `default` instead of their written name + UseStructuralFallback = 1 << 3, // When an alias cannot be named by its symbol, rather than report an error, fallback to a structural printout if possible // hole because there's a hole in node builder flags WriteTypeArgumentsOfSignature = 1 << 5, // Write the type arguments instead of type parameters of the signature UseFullyQualifiedType = 1 << 6, // Write out the fully qualified type name (eg. Module.Type, instead of Type) @@ -2997,7 +3003,7 @@ namespace ts { /** @deprecated */ WriteOwnNameForAnyLike = 0, // Does nothing NodeBuilderFlagsMask = - NoTruncation | WriteArrayAsGenericType | WriteDefaultSymbolWithoutName | WriteTypeArgumentsOfSignature | + NoTruncation | WriteArrayAsGenericType | WriteDefaultSymbolWithoutName | UseStructuralFallback | WriteTypeArgumentsOfSignature | UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias, } @@ -3824,20 +3830,19 @@ namespace ts { export type TypeMapper = (t: TypeParameter) => Type; export const enum InferencePriority { - Contravariant = 1 << 0, // Inference from contravariant position - NakedTypeVariable = 1 << 1, // Naked type variable in union or intersection type - MappedType = 1 << 2, // Reverse inference for mapped type - ReturnType = 1 << 3, // Inference made from return type of generic function - NeverType = 1 << 4, // Inference made from the never type + NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type + MappedType = 1 << 1, // Reverse inference for mapped type + ReturnType = 1 << 2, // Inference made from return type of generic function } export interface InferenceInfo { - typeParameter: TypeParameter; - candidates: Type[]; - inferredType: Type; - priority: InferencePriority; - topLevel: boolean; - isFixed: boolean; + typeParameter: TypeParameter; // Type parameter for which inferences are being made + candidates: Type[]; // Candidates in covariant positions (or undefined) + contraCandidates: Type[]; // Candidates in contravariant positions (or undefined) + inferredType: Type; // Cache for resolved inferred type + priority: InferencePriority; // Priority of current inference set + topLevel: boolean; // True if all inferences are to top level occurrences + isFixed: boolean; // True if inferences are fixed } export const enum InferenceFlags { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 73a740b6fba..4d7d7c7bdca 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2,7 +2,6 @@ /* @internal */ namespace ts { - export const emptyArray: never[] = [] as never[]; export const resolvingEmptyArray: never[] = [] as never[]; export const emptyMap: ReadonlyMap = createMap(); export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap = emptyMap as ReadonlyUnderscoreEscapedMap; @@ -116,6 +115,11 @@ namespace ts { return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version; } + export function packageIdToString({ name, subModuleName, version }: PackageId): string { + const fullName = subModuleName ? `${name}/${subModuleName}` : name; + return `${fullName}@${version}`; + } + export function typeDirectiveIsEqualTo(oldResolution: ResolvedTypeReferenceDirective, newResolution: ResolvedTypeReferenceDirective): boolean { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } @@ -1761,6 +1765,51 @@ namespace ts { return getAssignmentTargetKind(node) !== AssignmentKind.None; } + export type NodeWithPossibleHoistedDeclaration = + | Block + | VariableStatement + | WithStatement + | IfStatement + | SwitchStatement + | CaseBlock + | CaseClause + | DefaultClause + | LabeledStatement + | ForStatement + | ForInStatement + | ForOfStatement + | DoStatement + | WhileStatement + | TryStatement + | CatchClause; + + /** + * Indicates whether a node could contain a `var` VariableDeclarationList that contributes to + * the same `var` declaration scope as the node's parent. + */ + export function isNodeWithPossibleHoistedDeclaration(node: Node): node is NodeWithPossibleHoistedDeclaration { + switch (node.kind) { + case SyntaxKind.Block: + case SyntaxKind.VariableStatement: + case SyntaxKind.WithStatement: + case SyntaxKind.IfStatement: + case SyntaxKind.SwitchStatement: + case SyntaxKind.CaseBlock: + case SyntaxKind.CaseClause: + case SyntaxKind.DefaultClause: + case SyntaxKind.LabeledStatement: + case SyntaxKind.ForStatement: + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.TryStatement: + case SyntaxKind.CatchClause: + return true; + } + return false; + } + function walkUp(node: Node, kind: SyntaxKind) { while (node && node.kind === kind) { node = node.parent; @@ -5134,7 +5183,7 @@ namespace ts { /* @internal */ export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier { // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`. - return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None; + return isIdentifier(node) && (node.autoGenerateFlags & GeneratedIdentifierFlags.KindMask) > GeneratedIdentifierFlags.None; } // Keywords diff --git a/src/compiler/watchUtilities.ts b/src/compiler/watchUtilities.ts index d104fcc6c70..f5c614d9d57 100644 --- a/src/compiler/watchUtilities.ts +++ b/src/compiler/watchUtilities.ts @@ -179,7 +179,7 @@ namespace ts { if (path === rootDirPath) { return result; } - return getCachedFileSystemEntries(path) || createCachedFileSystemEntries(dir, path); + return tryReadDirectory(dir, path) || emptyFileSystemEntries; } } diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index 4c0c72a200f..df870034270 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1535,8 +1535,8 @@ Actual: ${stringify(fullActual)}`); const addSpanInfoString = () => { if (previousSpanInfo) { resultString += currentLine; - let thisLineMarker = repeatString(startColumn, " ") + repeatString(length, "~"); - thisLineMarker += repeatString(this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1, " "); + let thisLineMarker = ts.repeatString(" ", startColumn) + ts.repeatString("~", length); + thisLineMarker += ts.repeatString(" ", this.alignmentForExtraInfo - thisLineMarker.length - prefixString.length + 1); resultString += thisLineMarker; resultString += "=> Pos: (" + (pos - length) + " to " + (pos - 1) + ") "; resultString += " " + previousSpanInfo; @@ -1551,7 +1551,7 @@ Actual: ${stringify(fullActual)}`); if (resultString.length) { resultString += "\n--------------------------------"; } - currentLine = "\n" + nextLine.toString() + repeatString(3 - nextLine.toString().length, " ") + ">" + this.activeFile.content.substring(pos, fileLineMap[nextLine]) + "\n "; + currentLine = "\n" + nextLine.toString() + ts.repeatString(" ", 3 - nextLine.toString().length) + ">" + this.activeFile.content.substring(pos, fileLineMap[nextLine]) + "\n "; startColumn = 0; length = 0; } @@ -2787,7 +2787,7 @@ Actual: ${stringify(fullActual)}`); const items = this.languageService.getNavigationBarItems(this.activeFile.fileName); Harness.IO.log(`Navigation bar (${items.length} items)`); for (const item of items) { - Harness.IO.log(`${repeatString(item.indent, " ")}name: ${item.text}, kind: ${item.kind}, childItems: ${item.childItems.map(child => child.text)}`); + Harness.IO.log(`${ts.repeatString(" ", item.indent)}name: ${item.text}, kind: ${item.kind}, childItems: ${item.childItems.map(child => child.text)}`); } } @@ -3152,8 +3152,9 @@ Actual: ${stringify(fullActual)}`); assert.isTrue(TestState.textSpansEqual(span, item.replacementSpan), this.assertionMessageAtLastKnownMarker(stringify(span) + " does not equal " + stringify(item.replacementSpan) + " replacement span for " + entryId)); } - assert.equal(item.hasAction, hasAction); + assert.equal(item.hasAction, hasAction, "hasAction"); assert.equal(item.isRecommended, options && options.isRecommended, "isRecommended"); + assert.equal(item.insertText, options && options.insertText, "insertText"); } private findFile(indexOrName: string | number) { @@ -3688,14 +3689,6 @@ ${code} }; } - function repeatString(count: number, char: string) { - let result = ""; - for (let i = 0; i < count; i++) { - result += char; - } - return result; - } - function stringify(data: any, replacer?: (key: string, value: any) => any): string { return JSON.stringify(data, replacer, 2); } @@ -4615,6 +4608,7 @@ namespace FourSlashInterface { export interface VerifyCompletionListContainsOptions extends ts.GetCompletionsAtPositionOptions { sourceDisplay: string; isRecommended?: true; + insertText?: string; } export interface NewContentOptions { diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 565c20ac9cd..af69e35ec18 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2821,6 +2821,31 @@ namespace ts.projectSystem { checkWatchedDirectories(host, watchedRecursiveDirectories, /*recursive*/ true); }); + it("Properly handle Windows-style outDir", () => { + const configFile: FileOrFolder = { + path: "C:\\a\\tsconfig.json", + content: JSON.stringify({ + compilerOptions: { + outDir: `C:\\a\\b` + }, + include: ["*.ts"] + }) + }; + const file1: FileOrFolder = { + path: "C:\\a\\f1.ts", + content: "let x = 1;" + }; + + const host = createServerHost([file1, configFile], { useWindowsStylePaths: true }); + const projectService = createProjectService(host); + + projectService.openClientFile(file1.path); + checkNumberOfProjects(projectService, { configuredProjects: 1 }); + const project = configuredProjectAt(projectService, 0); + checkProjectActualFiles(project, [normalizePath(file1.path), normalizePath(configFile.path)]); + const options = project.getCompilerOptions(); + assert.equal(options.outDir, "C:/a/b", ""); + }); }); describe("tsserverProjectSystem Proper errors", () => { @@ -3485,6 +3510,38 @@ namespace ts.projectSystem { it("works when project root is used with case-insensitive system", () => { verifyOpenFileWorks(/*useCaseSensitiveFileNames*/ false); }); + + it("uses existing project even if project refresh is pending", () => { + const projectFolder = "/user/someuser/projects/myproject"; + const aFile: FileOrFolder = { + path: `${projectFolder}/src/a.ts`, + content: "export const x = 0;" + }; + const configFile: FileOrFolder = { + path: `${projectFolder}/tsconfig.json`, + content: "{}" + }; + const files = [aFile, configFile, libFile]; + const host = createServerHost(files); + const service = createProjectService(host); + service.openClientFile(aFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder); + verifyProject(); + + const bFile: FileOrFolder = { + path: `${projectFolder}/src/b.ts`, + content: `export {}; declare module "./a" { export const y: number; }` + }; + files.push(bFile); + host.reloadFS(files); + service.openClientFile(bFile.path, /*fileContent*/ undefined, ScriptKind.TS, projectFolder); + verifyProject(); + + function verifyProject() { + assert.isDefined(service.configuredProjects.get(configFile.path)); + const project = service.configuredProjects.get(configFile.path); + checkProjectActualFiles(project, files.map(f => f.path)); + } + }); }); describe("tsserverProjectSystem Language service", () => { @@ -4143,6 +4200,32 @@ namespace ts.projectSystem { // Since no file from the configured project is open, it would be closed immediately projectService.checkNumberOfProjects({ configuredProjects: 0, inferredProjects: 1 }); }); + + it("should tolerate invalid include files that start in subDirectory", () => { + const projectFolder = "/user/username/projects/myproject"; + const f = { + path: `${projectFolder}/src/server/index.ts`, + content: "let x = 1" + }; + const config = { + path: `${projectFolder}/src/server/tsconfig.json`, + content: JSON.stringify({ + compiler: { + module: "commonjs", + outDir: "../../build" + }, + include: [ + "../src/**/*.ts" + ] + }) + }; + const host = createServerHost([f, config, libFile], { useCaseSensitiveFileNames: true }); + const projectService = createProjectService(host); + + projectService.openClientFile(f.path); + // Since no file from the configured project is open, it would be closed immediately + projectService.checkNumberOfProjects({ configuredProjects: 0, inferredProjects: 1 }); + }); }); describe("tsserverProjectSystem reload", () => { @@ -6559,4 +6642,118 @@ namespace ts.projectSystem { checkProjectActualFiles(project, [file.path]); }); }); + + describe("tsserverProjectSystem with symLinks", () => { + it("rename in common file renames all project", () => { + const projects = "/users/username/projects"; + const folderA = `${projects}/a`; + const aFile: FileOrFolder = { + path: `${folderA}/a.ts`, + content: `import {C} from "./c/fc"; console.log(C)` + }; + const aTsconfig: FileOrFolder = { + path: `${folderA}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { module: "commonjs" } }) + }; + const aC: FileOrFolder = { + path: `${folderA}/c`, + symLink: "../c" + }; + const aFc = `${folderA}/c/fc.ts`; + + const folderB = `${projects}/b`; + const bFile: FileOrFolder = { + path: `${folderB}/b.ts`, + content: `import {C} from "./c/fc"; console.log(C)` + }; + const bTsconfig: FileOrFolder = { + path: `${folderB}/tsconfig.json`, + content: JSON.stringify({ compilerOptions: { module: "commonjs" } }) + }; + const bC: FileOrFolder = { + path: `${folderB}/c`, + symLink: "../c" + }; + const bFc = `${folderB}/c/fc.ts`; + + const folderC = `${projects}/c`; + const cFile: FileOrFolder = { + path: `${folderC}/fc.ts`, + content: `export const C = 8` + }; + + const files = [cFile, libFile, aFile, aTsconfig, aC, bFile, bTsconfig, bC]; + const host = createServerHost(files); + const session = createSession(host); + const projectService = session.getProjectService(); + debugger; + session.executeCommandSeq({ + command: protocol.CommandTypes.Open, + arguments: { + file: aFile.path, + projectRootPath: folderA + } + }); + session.executeCommandSeq({ + command: protocol.CommandTypes.Open, + arguments: { + file: bFile.path, + projectRootPath: folderB + } + }); + + session.executeCommandSeq({ + command: protocol.CommandTypes.Open, + arguments: { + file: aFc, + projectRootPath: folderA + } + }); + session.executeCommandSeq({ + command: protocol.CommandTypes.Open, + arguments: { + file: bFc, + projectRootPath: folderB + } + }); + checkNumberOfProjects(projectService, { configuredProjects: 2 }); + assert.isDefined(projectService.configuredProjects.get(aTsconfig.path)); + assert.isDefined(projectService.configuredProjects.get(bTsconfig.path)); + + debugger; + verifyRenameResponse(session.executeCommandSeq({ + command: protocol.CommandTypes.Rename, + arguments: { + file: aFc, + line: 1, + offset: 14, + findInStrings: false, + findInComments: false + } + }).response as protocol.RenameResponseBody); + + function verifyRenameResponse({ info, locs }: protocol.RenameResponseBody) { + assert.isTrue(info.canRename); + assert.equal(locs.length, 4); + verifyLocations(0, aFile.path, aFc); + verifyLocations(2, bFile.path, bFc); + + function verifyLocations(locStartIndex: number, firstFile: string, secondFile: string) { + assert.deepEqual(locs[locStartIndex], { + file: firstFile, + locs: [ + { start: { line: 1, offset: 39 }, end: { line: 1, offset: 40 } }, + { start: { line: 1, offset: 9 }, end: { line: 1, offset: 10 } } + ] + }); + assert.deepEqual(locs[locStartIndex + 1], { + file: secondFile, + locs: [ + { start: { line: 1, offset: 14 }, end: { line: 1, offset: 15 } } + ] + }); + } + } + }); + }); } diff --git a/src/harness/virtualFileSystemWithWatch.ts b/src/harness/virtualFileSystemWithWatch.ts index eb79f7468d9..381917d71c7 100644 --- a/src/harness/virtualFileSystemWithWatch.ts +++ b/src/harness/virtualFileSystemWithWatch.ts @@ -70,6 +70,7 @@ interface Array {}` path: string; content?: string; fileSize?: number; + symLink?: string; } interface FSEntry { @@ -86,6 +87,10 @@ interface Array {}` entries: FSEntry[]; } + interface SymLink extends FSEntry { + symLink: string; + } + function isFolder(s: FSEntry): s is Folder { return s && isArray((s).entries); } @@ -94,6 +99,10 @@ interface Array {}` return s && isString((s).content); } + function isSymLink(s: FSEntry): s is SymLink { + return s && isString((s).symLink); + } + function invokeWatcherCallbacks(callbacks: T[], invokeCallback: (cb: T) => void): void { if (callbacks) { // The array copy is made to ensure that even if one of the callback removes the callbacks, @@ -316,9 +325,12 @@ interface Array {}` } } else { - // TODO: Changing from file => folder + // TODO: Changing from file => folder/Symlink } } + else if (isSymLink(currentEntry)) { + // TODO: update symlinks + } else { // Folder if (isString(fileOrDirectory.content)) { @@ -339,7 +351,7 @@ interface Array {}` // If this entry is not from the new file or folder if (!mapNewLeaves.get(path)) { // Leaf entries that arent in new list => remove these - if (isFile(fileOrDirectory) || isFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) { + if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory) || isFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) { this.removeFileOrFolder(fileOrDirectory, folder => !mapNewLeaves.get(folder.path)); } } @@ -387,6 +399,12 @@ interface Array {}` const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath)); this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate); } + else if (isString(fileOrDirectory.symLink)) { + const symLink = this.toSymLink(fileOrDirectory); + Debug.assert(!this.fs.get(symLink.path)); + const baseFolder = this.ensureFolder(getDirectoryPath(symLink.fullPath)); + this.addFileOrFolderInFolder(baseFolder, symLink, ignoreWatchInvokedWithTriggerAsFileCreate); + } else { const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory); this.ensureFolder(fullPath); @@ -414,20 +432,20 @@ interface Array {}` return folder; } - private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder, ignoreWatch?: boolean) { + private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder | SymLink, ignoreWatch?: boolean) { folder.entries.push(fileOrDirectory); this.fs.set(fileOrDirectory.path, fileOrDirectory); if (ignoreWatch) { return; } - if (isFile(fileOrDirectory)) { + if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory)) { this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Created); } this.invokeDirectoryWatcher(folder.fullPath, fileOrDirectory.fullPath); } - private removeFileOrFolder(fileOrDirectory: File | Folder, isRemovableLeafFolder: (folder: Folder) => boolean, isRenaming?: boolean) { + private removeFileOrFolder(fileOrDirectory: File | Folder | SymLink, isRemovableLeafFolder: (folder: Folder) => boolean, isRenaming?: boolean) { const basePath = getDirectoryPath(fileOrDirectory.path); const baseFolder = this.fs.get(basePath) as Folder; if (basePath !== fileOrDirectory.path) { @@ -436,7 +454,7 @@ interface Array {}` } this.fs.delete(fileOrDirectory.path); - if (isFile(fileOrDirectory)) { + if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory)) { this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Deleted); } else { @@ -503,6 +521,15 @@ interface Array {}` }; } + private toSymLink(fileOrDirectory: FileOrFolder): SymLink { + const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory); + return { + path: this.toPath(fullPath), + fullPath, + symLink: getNormalizedAbsolutePath(fileOrDirectory.symLink, getDirectoryPath(fullPath)) + }; + } + private toFolder(path: string): Folder { const fullPath = getNormalizedAbsolutePath(path, this.currentDirectory); return { @@ -512,14 +539,52 @@ interface Array {}` }; } - fileExists(s: string) { - const path = this.toFullPath(s); - return isFile(this.fs.get(path)); + private getRealFsEntry(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)): T | undefined { + if (isFsEntry(fsEntry)) { + return fsEntry; + } + + if (isSymLink(fsEntry)) { + return this.getRealFsEntry(isFsEntry, this.toPath(fsEntry.symLink)); + } + + if (fsEntry) { + // This fs entry is something else + return undefined; + } + + const realpath = this.realpath(path); + if (path !== realpath) { + return this.getRealFsEntry(isFsEntry, realpath as Path); + } + + return undefined; } - readFile(s: string) { - const fsEntry = this.fs.get(this.toFullPath(s)); - return isFile(fsEntry) ? fsEntry.content : undefined; + private isFile(fsEntry: FSEntry) { + return !!this.getRealFile(fsEntry.path, fsEntry); + } + + private getRealFile(path: Path, fsEntry?: FSEntry): File | undefined { + return this.getRealFsEntry(isFile, path, fsEntry); + } + + private isFolder(fsEntry: FSEntry) { + return !!this.getRealFolder(fsEntry.path, fsEntry); + } + + private getRealFolder(path: Path, fsEntry = this.fs.get(path)): Folder | undefined { + return this.getRealFsEntry(isFolder, path, fsEntry); + } + + fileExists(s: string) { + const path = this.toFullPath(s); + return !!this.getRealFile(path); + } + + readFile(s: string): string { + const fsEntry = this.getRealFile(this.toFullPath(s)); + return fsEntry ? fsEntry.content : undefined; } getFileSize(s: string) { @@ -533,14 +598,14 @@ interface Array {}` directoryExists(s: string) { const path = this.toFullPath(s); - return isFolder(this.fs.get(path)); + return !!this.getRealFolder(path); } - getDirectories(s: string) { + getDirectories(s: string): string[] { const path = this.toFullPath(s); - const folder = this.fs.get(path); - if (isFolder(folder)) { - return mapDefined(folder.entries, entry => isFolder(entry) ? getBaseFileName(entry.fullPath) : undefined); + const folder = this.getRealFolder(path); + if (folder) { + return mapDefined(folder.entries, entry => this.isFolder(entry) ? getBaseFileName(entry.fullPath) : undefined); } Debug.fail(folder ? "getDirectories called on file" : "getDirectories called on missing folder"); return []; @@ -550,13 +615,13 @@ interface Array {}` return ts.matchFiles(path, extensions, exclude, include, this.useCaseSensitiveFileNames, this.getCurrentDirectory(), depth, (dir) => { const directories: string[] = []; const files: string[] = []; - const dirEntry = this.fs.get(this.toPath(dir)); - if (isFolder(dirEntry)) { - dirEntry.entries.forEach((entry) => { - if (isFolder(entry)) { + const folder = this.getRealFolder(this.toPath(dir)); + if (folder) { + folder.entries.forEach((entry) => { + if (this.isFolder(entry)) { directories.push(getBaseFileName(entry.fullPath)); } - else if (isFile(entry)) { + else if (this.isFile(entry)) { files.push(getBaseFileName(entry.fullPath)); } else { @@ -682,6 +747,23 @@ interface Array {}` clear(this.output); } + realpath(s: string): string { + const fullPath = this.toNormalizedAbsolutePath(s); + const path = this.toPath(fullPath); + if (getDirectoryPath(path) === path) { + // Root + return s; + } + const dirFullPath = this.realpath(getDirectoryPath(fullPath)); + const realFullPath = combinePaths(dirFullPath, getBaseFileName(fullPath)); + const fsEntry = this.fs.get(this.toPath(realFullPath)); + if (isSymLink(fsEntry)) { + return this.realpath(fsEntry.symLink); + } + + return realFullPath; + } + readonly existMessage = "System Exit"; exitCode: number; readonly resolvePath = (s: string) => s; diff --git a/src/lib/es2017.object.d.ts b/src/lib/es2017.object.d.ts index 775aaece7f6..1790ce76894 100644 --- a/src/lib/es2017.object.d.ts +++ b/src/lib/es2017.object.d.ts @@ -3,7 +3,7 @@ interface ObjectConstructor { * Returns an array of values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - values(o: { [s: string]: T } | { [n: number]: T }): T[]; + values(o: { [s: string]: T } | ArrayLike): T[]; /** * Returns an array of values of the enumerable properties of an object @@ -15,7 +15,7 @@ interface ObjectConstructor { * Returns an array of key/values of the enumerable properties of an object * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. */ - entries(o: { [s: string]: T } | { [n: number]: T }): [string, T][]; + entries(o: { [s: string]: T } | ArrayLike): [string, T][]; /** * Returns an array of key/values of the enumerable properties of an object diff --git a/src/server/client.ts b/src/server/client.ts index 7a64d9b528c..8203475b06d 100644 --- a/src/server/client.ts +++ b/src/server/client.ts @@ -558,8 +558,7 @@ namespace ts.server { const request = this.processRequest(CommandNames.GetCodeFixes, args); const response = this.processResponse(request); - // TODO: GH#20538 shouldn't need cast - return (response.body as ReadonlyArray).map(({ description, changes, fixId }) => ({ description, changes: this.convertChanges(changes, file), fixId })); + return response.body.map(({ description, changes, fixId }) => ({ description, changes: this.convertChanges(changes, file), fixId })); } getCombinedCodeFix = notImplemented; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 9843b50dbb3..905521c851a 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -198,16 +198,6 @@ namespace ts.server { } } - /** - * This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. - */ - export function combineProjectOutput(projects: ReadonlyArray, action: (project: Project) => ReadonlyArray, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean) { - const outputs = flatMap(projects, action); - return comparer - ? sortAndDeduplicate(outputs, comparer, areEqual) - : deduplicate(outputs, areEqual); - } - export interface HostConfiguration { formatCodeOptions: FormatCodeSettings; hostInfo: string; @@ -335,6 +325,11 @@ namespace ts.server { * Container of all known scripts */ private readonly filenameToScriptInfo = createMap(); + /** + * Map to the real path of the infos + */ + /* @internal */ + readonly realpathToScriptInfos: MultiMap | undefined; /** * maps external project file name to list of config files that were the part of this project */ @@ -427,7 +422,9 @@ namespace ts.server { this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation; Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService"); - + if (this.host.realpath) { + this.realpathToScriptInfos = createMultiMap(); + } this.currentDirectory = this.host.getCurrentDirectory(); this.toCanonicalFileName = createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); this.throttledOperations = new ThrottledOperations(this.host, this.logger); @@ -727,15 +724,6 @@ namespace ts.server { } } - private findContainingExternalProject(fileName: NormalizedPath): ExternalProject { - for (const proj of this.externalProjects) { - if (proj.containsFile(fileName)) { - return proj; - } - } - return undefined; - } - getFormatCodeOptions(file?: NormalizedPath) { let formatCodeSettings: FormatCodeSettings; if (file) { @@ -768,7 +756,7 @@ namespace ts.server { if (info.containingProjects.length === 0) { // Orphan script info, remove it as we can always reload it on next open file request this.stopWatchingScriptInfo(info); - this.filenameToScriptInfo.delete(info.path); + this.deleteScriptInfo(info); } else { // file has been changed which might affect the set of referenced files in projects that include @@ -785,7 +773,7 @@ namespace ts.server { // TODO: handle isOpen = true case if (!info.isScriptOpen()) { - this.filenameToScriptInfo.delete(info.path); + this.deleteScriptInfo(info); // capture list of projects since detachAllProjects will wipe out original list const containingProjects = info.containingProjects.slice(); @@ -1019,11 +1007,19 @@ namespace ts.server { if (!info.isScriptOpen() && info.isOrphan()) { // if there are not projects that include this script info - delete it this.stopWatchingScriptInfo(info); - this.filenameToScriptInfo.delete(info.path); + this.deleteScriptInfo(info); } }); } + private deleteScriptInfo(info: ScriptInfo) { + this.filenameToScriptInfo.delete(info.path); + const realpath = info.getRealpathIfDifferent(); + if (realpath) { + this.realpathToScriptInfos.remove(realpath, info); + } + } + private configFileExists(configFileName: NormalizedPath, canonicalConfigFilePath: string, info: ScriptInfo) { let configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (configFileExistenceInfo) { @@ -1736,6 +1732,43 @@ namespace ts.server { return this.getScriptInfoForNormalizedPath(toNormalizedPath(uncheckedFileName)); } + /** + * Returns the projects that contain script info through SymLink + * Note that this does not return projects in info.containingProjects + */ + /*@internal*/ + getSymlinkedProjects(info: ScriptInfo): MultiMap | undefined { + let projects: MultiMap | undefined; + if (this.realpathToScriptInfos) { + const realpath = info.getRealpathIfDifferent(); + if (realpath) { + forEach(this.realpathToScriptInfos.get(realpath), combineProjects); + } + forEach(this.realpathToScriptInfos.get(info.path), combineProjects); + } + + return projects; + + function combineProjects(toAddInfo: ScriptInfo) { + if (toAddInfo !== info) { + for (const project of toAddInfo.containingProjects) { + // Add the projects only if they can use symLink targets and not already in the list + if (project.languageServiceEnabled && + !project.getCompilerOptions().preserveSymlinks && + !contains(info.containingProjects, project)) { + if (!projects) { + projects = createMultiMap(); + projects.add(toAddInfo.path, project); + } + else if (!forEachEntry(projects, (projs, path) => path === toAddInfo.path ? false : contains(projs, project))) { + projects.add(toAddInfo.path, project); + } + } + } + } + } + } + private watchClosedScriptInfo(info: ScriptInfo) { Debug.assert(!info.fileWatcher); // do not watch files with mixed content - server doesn't know how to interpret it @@ -1994,13 +2027,24 @@ namespace ts.server { return this.openClientFileWithNormalizedPath(toNormalizedPath(fileName), fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ? toNormalizedPath(projectRootPath) : undefined); } + private findExternalProjetContainingOpenScriptInfo(info: ScriptInfo): ExternalProject { + for (const proj of this.externalProjects) { + // Ensure project structure is uptodate to check if info is present in external project + proj.updateGraph(); + if (proj.containsScriptInfo(info)) { + return proj; + } + } + return undefined; + } + openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult { let configFileName: NormalizedPath; let sendConfigFileDiagEvent = false; let configFileErrors: ReadonlyArray; const info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent); - let project: ConfiguredProject | ExternalProject = this.findContainingExternalProject(fileName); + let project: ConfiguredProject | ExternalProject = this.findExternalProjetContainingOpenScriptInfo(info); if (!project) { configFileName = this.getConfigFileNameForFile(info, projectRootPath); if (configFileName) { @@ -2010,6 +2054,10 @@ namespace ts.server { // Send the event only if the project got created as part of this open request sendConfigFileDiagEvent = true; } + else { + // Ensure project is ready to check if it contains opened script info + project.updateGraph(); + } } } if (project && !project.languageServiceEnabled) { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index b3cbba27a20..b4ff0aa4037 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -102,8 +102,6 @@ namespace ts.server.protocol { GetCodeFixes = "getCodeFixes", /* @internal */ GetCodeFixesFull = "getCodeFixes-full", - // TODO: GH#20538 - /* @internal */ GetCombinedCodeFix = "getCombinedCodeFix", /* @internal */ GetCombinedCodeFixFull = "getCombinedCodeFix-full", @@ -557,15 +555,11 @@ namespace ts.server.protocol { arguments: CodeFixRequestArgs; } - // TODO: GH#20538 - /* @internal */ export interface GetCombinedCodeFixRequest extends Request { command: CommandTypes.GetCombinedCodeFix; arguments: GetCombinedCodeFixRequestArgs; } - // TODO: GH#20538 - /* @internal */ export interface GetCombinedCodeFixResponse extends Response { body: CombinedCodeActions; } @@ -622,15 +616,11 @@ namespace ts.server.protocol { errorCodes?: ReadonlyArray; } - // TODO: GH#20538 - /* @internal */ export interface GetCombinedCodeFixRequestArgs { scope: GetCombinedCodeFixScope; fixId: {}; } - // TODO: GH#20538 - /* @internal */ export interface GetCombinedCodeFixScope { type: "file"; args: FileRequestArgs; @@ -1619,7 +1609,7 @@ namespace ts.server.protocol { export interface CodeFixResponse extends Response { /** The code actions that are available */ - body?: CodeAction[]; // TODO: GH#20538 CodeFixAction[] + body?: CodeFixAction[]; } export interface CodeAction { @@ -1631,15 +1621,11 @@ namespace ts.server.protocol { commands?: {}[]; } - // TODO: GH#20538 - /* @internal */ export interface CombinedCodeActions { changes: ReadonlyArray; commands?: ReadonlyArray<{}>; } - // TODO: GH#20538 - /* @internal */ export interface CodeFixAction extends CodeAction { /** * If present, one may call 'getCombinedCodeFix' with this fixId. diff --git a/src/server/scriptInfo.ts b/src/server/scriptInfo.ts index 454a8e552a1..dbadf5c88e7 100644 --- a/src/server/scriptInfo.ts +++ b/src/server/scriptInfo.ts @@ -213,6 +213,10 @@ namespace ts.server { /*@internal*/ readonly isDynamic: boolean; + /*@internal*/ + /** Set to real path if path is different from info.path */ + private realpath: Path | undefined; + constructor( private readonly host: ServerHost, readonly fileName: NormalizedPath, @@ -224,6 +228,7 @@ namespace ts.server { this.textStorage = new TextStorage(host, fileName); if (hasMixedContent || this.isDynamic) { this.textStorage.reload(""); + this.realpath = this.path; } this.scriptKind = scriptKind ? scriptKind @@ -264,6 +269,30 @@ namespace ts.server { return this.textStorage.getSnapshot(); } + private ensureRealPath() { + if (this.realpath === undefined) { + // Default is just the path + this.realpath = this.path; + if (this.host.realpath) { + Debug.assert(!!this.containingProjects.length); + const project = this.containingProjects[0]; + const realpath = this.host.realpath(this.path); + if (realpath) { + this.realpath = project.toPath(realpath); + // If it is different from this.path, add to the map + if (this.realpath !== this.path) { + project.projectService.realpathToScriptInfos.add(this.realpath, this); + } + } + } + } + } + + /*@internal*/ + getRealpathIfDifferent(): Path | undefined { + return this.realpath && this.realpath !== this.path ? this.realpath : undefined; + } + getFormatCodeSettings() { return this.formatCodeSettings; } @@ -272,6 +301,9 @@ namespace ts.server { const isNew = !this.isAttached(project); if (isNew) { this.containingProjects.push(project); + if (!project.getCompilerOptions().preserveSymlinks) { + this.ensureRealPath(); + } } return isNew; } diff --git a/src/server/session.ts b/src/server/session.ts index b66bd83c19f..aef2aced1c4 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -255,6 +255,32 @@ namespace ts.server { }; } + type Projects = ReadonlyArray | { + projects: ReadonlyArray; + symLinkedProjects: MultiMap; + }; + + function isProjectsArray(projects: Projects): projects is ReadonlyArray { + return !!(>projects).length; + } + + /** + * This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. + */ + function combineProjectOutput(defaultValue: T, getValue: (path: Path) => T, projects: Projects, action: (project: Project, value: T) => ReadonlyArray | U | undefined, comparer?: (a: U, b: U) => number, areEqual?: (a: U, b: U) => boolean) { + const outputs = flatMap(isProjectsArray(projects) ? projects : projects.projects, project => action(project, defaultValue)); + if (!isProjectsArray(projects) && projects.symLinkedProjects) { + projects.symLinkedProjects.forEach((projects, path) => { + const value = getValue(path as Path); + outputs.push(...flatMap(projects, project => action(project, value))); + }); + } + + return comparer + ? sortAndDeduplicate(outputs, comparer, areEqual) + : deduplicate(outputs, areEqual); + } + export interface SessionOptions { host: ServerHost; cancellationToken: ServerCancellationToken; @@ -789,8 +815,9 @@ namespace ts.server { return project.getLanguageService().getRenameInfo(file, position); } - private getProjects(args: protocol.FileRequestArgs) { - let projects: Project[]; + private getProjects(args: protocol.FileRequestArgs): Projects { + let projects: ReadonlyArray; + let symLinkedProjects: MultiMap | undefined; if (args.projectFileName) { const project = this.getProject(args.projectFileName); if (project) { @@ -800,13 +827,14 @@ namespace ts.server { else { const scriptInfo = this.projectService.getScriptInfo(args.file); projects = scriptInfo.containingProjects; + symLinkedProjects = this.projectService.getSymlinkedProjects(scriptInfo); } // filter handles case when 'projects' is undefined projects = filter(projects, p => p.languageServiceEnabled); - if (!projects || !projects.length) { + if ((!projects || !projects.length) && !symLinkedProjects) { return Errors.ThrowNoProject(); } - return projects; + return symLinkedProjects ? { projects, symLinkedProjects } : projects; } private getDefaultProject(args: protocol.FileRequestArgs) { @@ -841,8 +869,10 @@ namespace ts.server { } const fileSpans = combineProjectOutput( + file, + path => this.projectService.getScriptInfoForPath(path).fileName, projects, - (project: Project) => { + (project, file) => { const renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments); if (!renameLocations) { return emptyArray; @@ -881,8 +911,10 @@ namespace ts.server { } else { return combineProjectOutput( + file, + path => this.projectService.getScriptInfoForPath(path).fileName, projects, - p => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments), + (p, file) => p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments), /*comparer*/ undefined, renameLocationIsEqualTo ); @@ -938,9 +970,11 @@ namespace ts.server { const nameSpan = nameInfo.textSpan; const nameColStart = scriptInfo.positionToLineOffset(nameSpan.start).offset; const nameText = scriptInfo.getSnapshot().getText(nameSpan.start, textSpanEnd(nameSpan)); - const refs = combineProjectOutput( + const refs = combineProjectOutput( + file, + path => this.projectService.getScriptInfoForPath(path).fileName, projects, - (project: Project) => { + (project, file) => { const references = project.getLanguageService().getReferencesAtPosition(file, position); if (!references) { return emptyArray; @@ -974,8 +1008,10 @@ namespace ts.server { } else { return combineProjectOutput( + file, + path => this.projectService.getScriptInfoForPath(path).fileName, projects, - project => project.getLanguageService().findReferences(file, position), + (project, file) => project.getLanguageService().findReferences(file, position), /*comparer*/ undefined, equateValues ); @@ -1240,20 +1276,25 @@ namespace ts.server { return emptyArray; } - const result: protocol.CompileOnSaveAffectedFileListSingleProject[] = []; - // if specified a project, we only return affected file list in this project - const projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects; - for (const project of projectsToSearch) { - if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) { - result.push({ - projectFileName: project.getProjectName(), - fileNames: project.getCompileOnSaveAffectedFileList(info), - projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out - }); + const projects = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects; + const symLinkedProjects = !args.projectFileName && this.projectService.getSymlinkedProjects(info); + return combineProjectOutput( + info, + path => this.projectService.getScriptInfoForPath(path), + symLinkedProjects ? { projects, symLinkedProjects } : projects, + (project, info) => { + let result: protocol.CompileOnSaveAffectedFileListSingleProject; + if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) { + result = { + projectFileName: project.getProjectName(), + fileNames: project.getCompileOnSaveAffectedFileList(info), + projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out + }; + } + return result; } - } - return result; + ); } private emitFile(args: protocol.CompileOnSaveEmitFileRequestArgs) { @@ -1406,8 +1447,14 @@ namespace ts.server { const fileName = args.currentFileOnly ? args.file && normalizeSlashes(args.file) : undefined; if (simplifiedResult) { return combineProjectOutput( + fileName, + () => undefined, projects, - project => { + (project, file) => { + if (fileName && !file) { + return undefined; + } + const navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()); if (!navItems) { return emptyArray; @@ -1443,8 +1490,15 @@ namespace ts.server { } else { return combineProjectOutput( + fileName, + () => undefined, projects, - project => project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()), + (project, file) => { + if (fileName && !file) { + return undefined; + } + return project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()); + }, /*comparer*/ undefined, navigateToItemIsEqualTo); } diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index b7d948b3deb..59d19a1bd9b 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -121,9 +121,26 @@ namespace ts.codefix { break; case SyntaxKind.Parameter: - const functionDeclaration = parent.parent; - if (functionDeclaration.parameters.length === 1) { - changes.deleteNode(sourceFile, parent); + const oldFunction = parent.parent; + if (isArrowFunction(oldFunction) && oldFunction.parameters.length === 1) { + // Lambdas with exactly one parameter are special because, after removal, there + // must be an empty parameter list (i.e. `()`) and this won't necessarily be the + // case if the parameter is simply removed (e.g. in `x => 1`). + const newFunction = updateArrowFunction( + oldFunction, + oldFunction.modifiers, + oldFunction.typeParameters, + /*parameters*/ undefined, + oldFunction.type, + oldFunction.equalsGreaterThanToken, + oldFunction.body); + + // Drop leading and trailing trivia of the new function because we're only going + // to replace the span (vs the full span) of the old function - the old leading + // and trailing trivia will remain. + suppressLeadingAndTrailingTrivia(newFunction); + + changes.replaceRange(sourceFile, { pos: oldFunction.getStart(), end: oldFunction.end }, newFunction); } else { changes.deleteNodeInList(sourceFile, parent); diff --git a/src/services/completions.ts b/src/services/completions.ts index ac1eb8f6a46..36a10a1b578 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -4,7 +4,9 @@ namespace ts.Completions { export type Log = (message: string) => void; - interface SymbolOriginInfo { + type SymbolOriginInfo = { type: "this-type" } | SymbolOriginInfoExport; + interface SymbolOriginInfoExport { + type: "export"; moduleSymbol: Symbol; isDefaultExport: boolean; } @@ -35,11 +37,14 @@ namespace ts.Completions { return entries && pathCompletionsInfo(entries); } - if (isInString(sourceFile, position)) { - return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log); + const contextToken = findPrecedingToken(position, sourceFile); + + if (isInString(sourceFile, position, contextToken)) { + return !contextToken || !isStringLiteral(contextToken) && !isNoSubstitutionTemplateLiteral(contextToken) + ? undefined + : getStringLiteralCompletionEntries(sourceFile, contextToken, position, typeChecker, compilerOptions, host, log); } - const contextToken = findPrecedingToken(position, sourceFile); if (contextToken && isBreakOrContinueStatement(contextToken.parent) && (contextToken.kind === SyntaxKind.BreakKeyword || contextToken.kind === SyntaxKind.ContinueKeyword || contextToken.kind === SyntaxKind.Identifier)) { return getLabelCompletionAtPosition(contextToken.parent); @@ -167,11 +172,21 @@ namespace ts.Completions { return undefined; } const { name, needsConvertPropertyAccess } = info; - Debug.assert(!(needsConvertPropertyAccess && !propertyAccessToConvert)); if (needsConvertPropertyAccess && !includeInsertTextCompletions) { return undefined; } + let insertText: string | undefined; + let replacementSpan: TextSpan | undefined; + if (kind === CompletionKind.Global && origin && origin.type === "this-type") { + insertText = needsConvertPropertyAccess ? `this["${name}"]` : `this.${name}`; + } + else if (needsConvertPropertyAccess) { + // TODO: GH#20619 Use configured quote style + insertText = `["${name}"]`; + replacementSpan = createTextSpanFromBounds(findChildOfKind(propertyAccessToConvert!, SyntaxKind.DotToken, sourceFile)!.getStart(sourceFile), propertyAccessToConvert!.name.end); + } + // TODO(drosen): Right now we just permit *all* semantic meanings when calling // 'getSymbolKind' which is permissible given that it is backwards compatible; but // really we should consider passing the meaning for the node so that we don't report @@ -186,13 +201,10 @@ namespace ts.Completions { kindModifiers: SymbolDisplay.getSymbolModifiers(symbol), sortText: "0", source: getSourceFromOrigin(origin), - // TODO: GH#20619 Use configured quote style - insertText: needsConvertPropertyAccess ? `["${name}"]` : undefined, - replacementSpan: needsConvertPropertyAccess - ? createTextSpanFromBounds(findChildOfKind(propertyAccessToConvert, SyntaxKind.DotToken, sourceFile)!.getStart(sourceFile), propertyAccessToConvert.name.end) - : undefined, - hasAction: trueOrUndefined(needsConvertPropertyAccess || origin !== undefined), + hasAction: trueOrUndefined(!!origin && origin.type === "export"), isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)), + insertText, + replacementSpan, }; } @@ -207,7 +219,7 @@ namespace ts.Completions { } function getSourceFromOrigin(origin: SymbolOriginInfo | undefined): string | undefined { - return origin && stripQuotes(origin.moduleSymbol.name); + return origin && origin.type === "export" ? stripQuotes(origin.moduleSymbol.name) : undefined; } function getCompletionEntriesFromSymbols( @@ -261,70 +273,87 @@ namespace ts.Completions { } } - function getStringLiteralCompletionEntries(sourceFile: SourceFile, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { - const node = findPrecedingToken(position, sourceFile); - if (!node || !isStringLiteral(node) && !isNoSubstitutionTemplateLiteral(node)) { - return undefined; - } + function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringLiteralLike, position: number, typeChecker: TypeChecker, compilerOptions: CompilerOptions, host: LanguageServiceHost, log: Log): CompletionInfo | undefined { + switch (node.parent.kind) { + case SyntaxKind.LiteralType: + switch (node.parent.parent.kind) { + case SyntaxKind.TypeReference: + // TODO: GH#21168 + return undefined; + case SyntaxKind.IndexedAccessType: + // Get all apparent property names + // i.e. interface Foo { + // foo: string; + // bar: string; + // } + // let x: Foo["/*completion position*/"] + const type = typeChecker.getTypeFromTypeNode((node.parent.parent as IndexedAccessTypeNode).objectType); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); + default: + return undefined; + } - if (node.parent.kind === SyntaxKind.PropertyAssignment && - node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && - (node.parent).name === node) { - // Get quoted name of properties of the object literal expression - // i.e. interface ConfigFiles { - // 'jspm:dev': string - // } - // let files: ConfigFiles = { - // '/*completion position*/' - // } - // - // function foo(c: ConfigFiles) {} - // foo({ - // '/*completion position*/' - // }); - return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, sourceFile, typeChecker, compilerOptions.target, log); - } - else if (isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) { - // Get all names of properties on the expression - // i.e. interface A { - // 'prop1': string - // } - // let a: A; - // a['/*completion position*/'] - const type = typeChecker.getTypeAtLocation(node.parent.expression); - return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); - } - else if (node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration - || isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || isImportCall(node.parent) - || isExpressionOfExternalModuleImportEqualsDeclaration(node)) { - // Get all known external module names or complete a path to a module - // i.e. import * as ns from "/*completion position*/"; - // var y = import("/*completion position*/"); - // import x = require("/*completion position*/"); - // var y = require("/*completion position*/"); - // export * from "/*completion position*/"; - const entries = PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker); - return pathCompletionsInfo(entries); - } - else if (isIndexedAccessTypeNode(node.parent.parent)) { - // Get all apparent property names - // i.e. interface Foo { - // foo: string; - // bar: string; - // } - // let x: Foo["/*completion position*/"] - const type = typeChecker.getTypeFromTypeNode(node.parent.parent.objectType); - return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); - } - else { - const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); - if (argumentInfo) { - // Get string literal completions from specialized signatures of the target - // i.e. declare function f(a: 'A'); - // f("/*completion position*/") - return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker); + case SyntaxKind.PropertyAssignment: + if (node.parent.parent.kind === SyntaxKind.ObjectLiteralExpression && + (node.parent).name === node) { + // Get quoted name of properties of the object literal expression + // i.e. interface ConfigFiles { + // 'jspm:dev': string + // } + // let files: ConfigFiles = { + // '/*completion position*/' + // } + // + // function foo(c: ConfigFiles) {} + // foo({ + // '/*completion position*/' + // }); + return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, sourceFile, typeChecker, compilerOptions.target, log); + } + return fromContextualType(); + + case SyntaxKind.ElementAccessExpression: { + const { expression, argumentExpression } = node.parent as ElementAccessExpression; + if (node === argumentExpression) { + // Get all names of properties on the expression + // i.e. interface A { + // 'prop1': string + // } + // let a: A; + // a['/*completion position*/'] + const type = typeChecker.getTypeAtLocation(expression); + return getStringLiteralCompletionEntriesFromElementAccessOrIndexedAccess(node, sourceFile, type, typeChecker, compilerOptions.target, log); + } + break; } + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + if (!isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) && !isImportCall(node.parent)) { + const argumentInfo = SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); + // Get string literal completions from specialized signatures of the target + // i.e. declare function f(a: 'A'); + // f("/*completion position*/") + return argumentInfo ? getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker) : fromContextualType(); + } + // falls through + + case SyntaxKind.ImportDeclaration: + case SyntaxKind.ExportDeclaration: + case SyntaxKind.ExternalModuleReference: + // Get all known external module names or complete a path to a module + // i.e. import * as ns from "/*completion position*/"; + // var y = import("/*completion position*/"); + // import x = require("/*completion position*/"); + // var y = require("/*completion position*/"); + // export * from "/*completion position*/"; + return pathCompletionsInfo(PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node as StringLiteral, compilerOptions, host, typeChecker)); + + default: + return fromContextualType(); + } + + function fromContextualType(): CompletionInfo { // Get completion for string literal from string literal type // i.e. var x: "hi" | "hello" = "/*completion position*/" return getStringLiteralCompletionEntriesFromType(getContextualTypeFromParent(node, typeChecker), typeChecker); @@ -484,7 +513,7 @@ namespace ts.Completions { } function getSymbolName(symbol: Symbol, origin: SymbolOriginInfo | undefined, target: ScriptTarget): string { - return origin && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default + return origin && origin.type === "export" && origin.isDefaultExport && symbol.escapedName === InternalSymbolName.Default // Name of "export default foo;" is "foo". Name of "export default 0" is the filename converted to camelCase. ? firstDefined(symbol.declarations, d => isExportAssignment(d) && isIdentifier(d.expression) ? d.expression.text : undefined) || codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) @@ -570,13 +599,13 @@ namespace ts.Completions { allSourceFiles: ReadonlyArray, ): CodeActionsAndSourceDisplay { const symbolOriginInfo = symbolToOriginInfoMap[getSymbolId(symbol)]; - return symbolOriginInfo + return symbolOriginInfo && symbolOriginInfo.type === "export" ? getCodeActionsAndSourceDisplayForImport(symbolOriginInfo, symbol, program, checker, host, compilerOptions, sourceFile, previousToken, formatContext, getCanonicalFileName, allSourceFiles) : { codeActions: undefined, sourceDisplay: undefined }; } function getCodeActionsAndSourceDisplayForImport( - symbolOriginInfo: SymbolOriginInfo, + symbolOriginInfo: SymbolOriginInfoExport, symbol: Symbol, program: Program, checker: TypeChecker, @@ -1097,6 +1126,18 @@ namespace ts.Completions { const symbolMeanings = SymbolFlags.Type | SymbolFlags.Value | SymbolFlags.Namespace | SymbolFlags.Alias; symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); + + // Need to insert 'this.' before properties of `this` type, so only do that if `includeInsertTextCompletions` + if (options.includeInsertTextCompletions && scopeNode.kind !== SyntaxKind.SourceFile) { + const thisType = typeChecker.tryGetThisTypeAt(scopeNode); + if (thisType) { + for (const symbol of getPropertiesForCompletion(thisType, typeChecker, /*isForAccess*/ true)) { + symbolToOriginInfoMap[getSymbolId(symbol)] = { type: "this-type" }; + symbols.push(symbol); + } + } + } + if (options.includeExternalModuleExports) { getSymbolsFromOtherSourceFileExports(symbols, previousToken && isIdentifier(previousToken) ? previousToken.text : "", target); } @@ -1210,10 +1251,10 @@ namespace ts.Completions { symbol = getLocalSymbolForExportDefault(symbol) || symbol; } - const origin: SymbolOriginInfo = { moduleSymbol, isDefaultExport }; + const origin: SymbolOriginInfo = { type: "export", moduleSymbol, isDefaultExport }; if (stringContainsCharactersInOrder(getSymbolName(symbol, origin, target).toLowerCase(), tokenTextLowerCase)) { symbols.push(symbol); - symbolToOriginInfoMap[getSymbolId(symbol)] = { moduleSymbol, isDefaultExport }; + symbolToOriginInfoMap[getSymbolId(symbol)] = origin; } } }); @@ -2052,13 +2093,13 @@ namespace ts.Completions { if (isIdentifierText(name, target)) return validIdentiferResult; switch (kind) { case CompletionKind.None: - case CompletionKind.Global: case CompletionKind.MemberLike: return undefined; case CompletionKind.ObjectPropertyDeclaration: // TODO: GH#18169 return { name: JSON.stringify(name), needsConvertPropertyAccess: false }; case CompletionKind.PropertyAccess: + case CompletionKind.Global: // Don't add a completion for a name starting with a space. See https://github.com/Microsoft/TypeScript/pull/20547 return name.charCodeAt(0) === CharacterCodes.space ? undefined : { name, needsConvertPropertyAccess: true }; case CompletionKind.String: diff --git a/src/services/formatting/formatting.ts b/src/services/formatting/formatting.ts index 49fb1420db8..2a8af916e09 100644 --- a/src/services/formatting/formatting.ts +++ b/src/services/formatting/formatting.ts @@ -537,70 +537,56 @@ namespace ts.formatting { case SyntaxKind.CloseBraceToken: case SyntaxKind.CloseBracketToken: case SyntaxKind.CloseParenToken: - return indentation + getEffectiveDelta(delta, container); + return indentation + getDelta(container); } return tokenIndentation !== Constants.Unknown ? tokenIndentation : indentation; }, - getIndentationForToken: (line, kind, container) => { - if (nodeStartLine !== line && node.decorators) { - if (kind === getFirstNonDecoratorTokenOfNode(node)) { - // if this token is the first token following the list of decorators, we do not need to indent - return indentation; - } - } - switch (kind) { - // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent - case SyntaxKind.OpenBraceToken: - case SyntaxKind.CloseBraceToken: - case SyntaxKind.OpenParenToken: - case SyntaxKind.CloseParenToken: - case SyntaxKind.ElseKeyword: - case SyntaxKind.WhileKeyword: - case SyntaxKind.AtToken: - return indentation; - case SyntaxKind.SlashToken: - case SyntaxKind.GreaterThanToken: { - if (container.kind === SyntaxKind.JsxOpeningElement || - container.kind === SyntaxKind.JsxClosingElement || - container.kind === SyntaxKind.JsxSelfClosingElement - ) { - return indentation; - } - break; - } - case SyntaxKind.OpenBracketToken: - case SyntaxKind.CloseBracketToken: { - if (container.kind !== SyntaxKind.MappedType) { - return indentation; - } - break; - } - } - // if token line equals to the line of containing node (this is a first token in the node) - use node indentation - return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation; - }, + getIndentationForToken: (line, kind, container) => + shouldAddDelta(line, kind, container) ? indentation + getDelta(container) : indentation, getIndentation: () => indentation, - getDelta: child => getEffectiveDelta(delta, child), + getDelta, recomputeIndentation: lineAdded => { if (node.parent && SmartIndenter.shouldIndentChildNode(node.parent, node)) { - if (lineAdded) { - indentation += options.indentSize; - } - else { - indentation -= options.indentSize; - } - - if (SmartIndenter.shouldIndentChildNode(node)) { - delta = options.indentSize; - } - else { - delta = 0; - } + indentation += lineAdded ? options.indentSize : -options.indentSize; + delta = SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0; } } }; - function getEffectiveDelta(delta: number, child: TextRangeWithKind) { + function shouldAddDelta(line: number, kind: SyntaxKind, container: Node): boolean { + switch (kind) { + // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent + case SyntaxKind.OpenBraceToken: + case SyntaxKind.CloseBraceToken: + case SyntaxKind.OpenParenToken: + case SyntaxKind.CloseParenToken: + case SyntaxKind.ElseKeyword: + case SyntaxKind.WhileKeyword: + case SyntaxKind.AtToken: + return false; + case SyntaxKind.SlashToken: + case SyntaxKind.GreaterThanToken: + switch (container.kind) { + case SyntaxKind.JsxOpeningElement: + case SyntaxKind.JsxClosingElement: + case SyntaxKind.JsxSelfClosingElement: + return false; + } + break; + case SyntaxKind.OpenBracketToken: + case SyntaxKind.CloseBracketToken: + if (container.kind !== SyntaxKind.MappedType) { + return false; + } + break; + } + // if token line equals to the line of containing node (this is a first token in the node) - use node indentation + return nodeStartLine !== line + // if this token is the first token following the list of decorators, we do not need to indent + && !(node.decorators && kind === getFirstNonDecoratorTokenOfNode(node)); + } + + function getDelta(child: TextRangeWithKind) { // Delta value should be zero when the node explicitly prevents indentation of the child node return SmartIndenter.nodeWillIndentChild(node, child, /*indentByDefault*/ true) ? delta : 0; } @@ -922,24 +908,25 @@ namespace ts.formatting { let trimTrailingWhitespaces: boolean; let lineAction = LineAction.None; if (rule) { - applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine); - - if (rule.action & (RuleAction.Space | RuleAction.Delete) && currentStartLine !== previousStartLine) { - lineAction = LineAction.LineRemoved; - // Handle the case where the next line is moved to be the end of this line. - // In this case we don't indent the next line in the next pass. - if (currentParent.getStart(sourceFile) === currentItem.pos) { - dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false); - } - } - else if (rule.action & RuleAction.NewLine && currentStartLine === previousStartLine) { - lineAction = LineAction.LineAdded; - // Handle the case where token2 is moved to the new line. - // In this case we indent token2 in the next pass but we set - // sameLineIndent flag to notify the indenter that the indentation is within the line. - if (currentParent.getStart(sourceFile) === currentItem.pos) { - dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true); - } + lineAction = applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine); + switch (lineAction) { + case LineAction.LineRemoved: + // Handle the case where the next line is moved to be the end of this line. + // In this case we don't indent the next line in the next pass. + if (currentParent.getStart(sourceFile) === currentItem.pos) { + dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false); + } + break; + case LineAction.LineAdded: + // Handle the case where token2 is moved to the new line. + // In this case we indent token2 in the next pass but we set + // sameLineIndent flag to notify the indenter that the indentation is within the line. + if (currentParent.getStart(sourceFile) === currentItem.pos) { + dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true); + } + break; + default: + Debug.assert(lineAction === LineAction.None); } // We need to trim trailing whitespace between the tokens if they were on different lines, and no rule was applied to put them on the same line @@ -1116,16 +1103,18 @@ namespace ts.formatting { previousRange: TextRangeWithKind, previousStartLine: number, currentRange: TextRangeWithKind, - currentStartLine: number): void { - + currentStartLine: number, + ): LineAction { + const onLaterLine = currentStartLine !== previousStartLine; switch (rule.action) { case RuleAction.Ignore: // no action required - return; + return LineAction.None; case RuleAction.Delete: if (previousRange.end !== currentRange.pos) { // delete characters starting from t1.end up to t2.pos exclusive recordDelete(previousRange.end, currentRange.pos - previousRange.end); + return onLaterLine ? LineAction.LineRemoved : LineAction.None; } break; case RuleAction.NewLine: @@ -1133,27 +1122,29 @@ namespace ts.formatting { // if line1 and line2 are on subsequent lines then no edits are required - ok to exit // if line1 and line2 are separated with more than one newline - ok to exit since we cannot delete extra new lines if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { - return; + return LineAction.None; } // edit should not be applied if we have one line feed between elements const lineDelta = currentStartLine - previousStartLine; if (lineDelta !== 1) { recordReplace(previousRange.end, currentRange.pos - previousRange.end, options.newLineCharacter); + return onLaterLine ? LineAction.None : LineAction.LineAdded; } break; case RuleAction.Space: // exit early if we on different lines and rule cannot change number of newlines if (rule.flags !== RuleFlags.CanDeleteNewLines && previousStartLine !== currentStartLine) { - return; + return LineAction.None; } const posDelta = currentRange.pos - previousRange.end; if (posDelta !== 1 || sourceFile.text.charCodeAt(previousRange.end) !== CharacterCodes.space) { recordReplace(previousRange.end, currentRange.pos - previousRange.end, " "); + return onLaterLine ? LineAction.LineRemoved : LineAction.None; } - break; } + return LineAction.None; } } @@ -1277,13 +1268,13 @@ namespace ts.formatting { } if (internedTabsIndentation[tabs] === undefined) { - internedTabsIndentation[tabs] = tabString = repeat("\t", tabs); + internedTabsIndentation[tabs] = tabString = repeatString("\t", tabs); } else { tabString = internedTabsIndentation[tabs]; } - return spaces ? tabString + repeat(" ", spaces) : tabString; + return spaces ? tabString + repeatString(" ", spaces) : tabString; } else { let spacesString: string; @@ -1294,23 +1285,14 @@ namespace ts.formatting { } if (internedSpacesIndentation[quotient] === undefined) { - spacesString = repeat(" ", options.indentSize * quotient); + spacesString = repeatString(" ", options.indentSize * quotient); internedSpacesIndentation[quotient] = spacesString; } else { spacesString = internedSpacesIndentation[quotient]; } - return remainder ? spacesString + repeat(" ", remainder) : spacesString; - } - - function repeat(value: string, count: number): string { - let s = ""; - for (let i = 0; i < count; i++) { - s += value; - } - - return s; + return remainder ? spacesString + repeatString(" ", remainder) : spacesString; } } } diff --git a/src/services/types.ts b/src/services/types.ts index 597709a7c79..4ebd4a3e76a 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -295,10 +295,7 @@ namespace ts { getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - // TODO: GH#20538 return `ReadonlyArray` - getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings): ReadonlyArray; - // TODO: GH#20538 - /* @internal */ + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings): ReadonlyArray; getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings): CombinedCodeActions; applyCodeActionCommand(action: CodeActionCommand): Promise; applyCodeActionCommand(action: CodeActionCommand[]): Promise; @@ -327,8 +324,6 @@ namespace ts { dispose(): void; } - // TODO: GH#20538 - /* @internal */ export interface CombinedCodeFixScope { type: "file"; fileName: string; } export interface GetCompletionsAtPositionOptions { @@ -419,8 +414,6 @@ namespace ts { commands?: CodeActionCommand[]; } - // TODO: GH#20538 - /* @internal */ export interface CodeFixAction extends CodeAction { /** * If present, one may call 'getCombinedCodeFix' with this fixId. @@ -429,8 +422,6 @@ namespace ts { fixId?: {}; } - // TODO: GH#20538 - /* @internal */ export interface CombinedCodeActions { changes: ReadonlyArray; commands: ReadonlyArray | undefined; diff --git a/src/services/utilities.ts b/src/services/utilities.ts index c5694625493..344a44a9f18 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -833,8 +833,7 @@ namespace ts { } } - export function isInString(sourceFile: SourceFile, position: number): boolean { - const previousToken = findPrecedingToken(position, sourceFile); + export function isInString(sourceFile: SourceFile, position: number, previousToken = findPrecedingToken(position, sourceFile)): boolean { if (previousToken && isStringTextContainingNode(previousToken)) { const start = previousToken.getStart(); const end = previousToken.getEnd(); @@ -1111,6 +1110,14 @@ namespace ts { export function getSnapshotText(snap: IScriptSnapshot): string { return snap.getText(0, snap.getLength()); } + + export function repeatString(str: string, count: number): string { + let result = ""; + for (let i = 0; i < count; i++) { + result += str; + } + return result; + } } // Display-part writer helpers diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index d06e48b840b..2ea2defee8b 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -877,7 +877,7 @@ declare namespace ts { type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; - type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; type ArrayBindingOrAssignmentPattern = ArrayBindingPattern | ArrayLiteralExpression; type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; @@ -1800,6 +1800,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, UseOnlyExternalAliasing = 128, @@ -1826,6 +1827,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, @@ -1842,7 +1844,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469287, + NodeBuilderFlagsMask = 9469295, } enum SymbolFormatFlags { None = 0, @@ -2176,15 +2178,14 @@ declare namespace ts { declaration?: SignatureDeclaration; } enum InferencePriority { - Contravariant = 1, - NakedTypeVariable = 2, - MappedType = 4, - ReturnType = 8, - NeverType = 16, + NakedTypeVariable = 1, + MappedType = 2, + ReturnType = 4, } interface InferenceInfo { typeParameter: TypeParameter; candidates: Type[]; + contraCandidates: Type[]; inferredType: Type; priority: InferencePriority; topLevel: boolean; @@ -3249,8 +3250,10 @@ declare namespace ts { function isWhiteSpaceSingleLine(ch: number): boolean; function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; - function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; - function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; @@ -4072,7 +4075,8 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings): ReadonlyArray; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings): ReadonlyArray; + getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings): CombinedCodeActions; applyCodeActionCommand(action: CodeActionCommand): Promise; applyCodeActionCommand(action: CodeActionCommand[]): Promise; applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise; @@ -4088,6 +4092,10 @@ declare namespace ts { getProgram(): Program; dispose(): void; } + interface CombinedCodeFixScope { + type: "file"; + fileName: string; + } interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; includeInsertTextCompletions: boolean; @@ -4165,6 +4173,17 @@ declare namespace ts { */ commands?: CodeActionCommand[]; } + interface CodeFixAction extends CodeAction { + /** + * If present, one may call 'getCombinedCodeFix' with this fixId. + * This may be omitted to indicate that the code fix can't be applied in a group. + */ + fixId?: {}; + } + interface CombinedCodeActions { + changes: ReadonlyArray; + commands: ReadonlyArray | undefined; + } type CodeActionCommand = InstallPackageAction; interface InstallPackageAction { } @@ -5010,6 +5029,7 @@ declare namespace ts.server.protocol { DocCommentTemplate = "docCommentTemplate", CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects", GetCodeFixes = "getCodeFixes", + GetCombinedCodeFix = "getCombinedCodeFix", ApplyCodeActionCommand = "applyCodeActionCommand", GetSupportedCodeFixes = "getSupportedCodeFixes", GetApplicableRefactors = "getApplicableRefactors", @@ -5372,6 +5392,13 @@ declare namespace ts.server.protocol { command: CommandTypes.GetCodeFixes; arguments: CodeFixRequestArgs; } + interface GetCombinedCodeFixRequest extends Request { + command: CommandTypes.GetCombinedCodeFix; + arguments: GetCombinedCodeFixRequestArgs; + } + interface GetCombinedCodeFixResponse extends Response { + body: CombinedCodeActions; + } interface ApplyCodeActionCommandRequest extends Request { command: CommandTypes.ApplyCodeActionCommand; arguments: ApplyCodeActionCommandRequestArgs; @@ -5405,6 +5432,14 @@ declare namespace ts.server.protocol { */ errorCodes?: ReadonlyArray; } + interface GetCombinedCodeFixRequestArgs { + scope: GetCombinedCodeFixScope; + fixId: {}; + } + interface GetCombinedCodeFixScope { + type: "file"; + args: FileRequestArgs; + } interface ApplyCodeActionCommandRequestArgs { /** May also be an array of commands. */ command: {}; @@ -6147,7 +6182,7 @@ declare namespace ts.server.protocol { } interface CodeFixResponse extends Response { /** The code actions that are available */ - body?: CodeAction[]; + body?: CodeFixAction[]; } interface CodeAction { /** Description of the code action to display in the UI of the editor */ @@ -6157,6 +6192,17 @@ declare namespace ts.server.protocol { /** A command is an opaque object that should be passed to `ApplyCodeActionCommandRequestArgs` without modification. */ commands?: {}[]; } + interface CombinedCodeActions { + changes: ReadonlyArray; + commands?: ReadonlyArray<{}>; + } + interface CodeFixAction extends CodeAction { + /** + * If present, one may call 'getCombinedCodeFix' with this fixId. + * This may be omitted to indicate that the code fix can't be applied in a group. + */ + fixId?: {}; + } /** * Format and format on key response message. */ @@ -7237,6 +7283,7 @@ declare namespace ts.server { open(newText: string): void; close(fileExists?: boolean): void; getSnapshot(): IScriptSnapshot; + private ensureRealPath(); getFormatCodeSettings(): FormatCodeSettings; attachToProject(project: Project): boolean; isAttached(project: Project): boolean; @@ -7618,10 +7665,6 @@ declare namespace ts.server { function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin; function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind; function convertScriptKindName(scriptKindName: protocol.ScriptKindName): ScriptKind.Unknown | ScriptKind.JS | ScriptKind.JSX | ScriptKind.TS | ScriptKind.TSX; - /** - * This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. - */ - function combineProjectOutput(projects: ReadonlyArray, action: (project: Project) => ReadonlyArray, comparer?: (a: T, b: T) => number, areEqual?: (a: T, b: T) => boolean): T[]; interface HostConfiguration { formatCodeOptions: FormatCodeSettings; hostInfo: string; @@ -7738,7 +7781,6 @@ declare namespace ts.server { * @param forceInferredProjectsRefresh when true updates the inferred projects even if there is no pending work to update the files/project structures */ private ensureProjectStructuresUptoDate(forceInferredProjectsRefresh?); - private findContainingExternalProject(fileName); getFormatCodeOptions(file?: NormalizedPath): FormatCodeSettings; private updateProjectGraphs(projects); private onSourceFileChanged(fileName, eventKind); @@ -7757,6 +7799,7 @@ declare namespace ts.server { */ private closeOpenFile(info); private deleteOrphanScriptInfoNotInAnyProject(); + private deleteScriptInfo(info); private configFileExists(configFileName, canonicalConfigFilePath, info); private setConfigFileExistenceByNewConfiguredProject(project); /** @@ -7858,6 +7901,7 @@ declare namespace ts.server { * @param fileContent is a known version of the file content that is more up to date than the one on disk */ openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: string): OpenConfiguredProjectResult; + private findExternalProjetContainingOpenScriptInfo(info); openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult; /** * Close file whose contents is managed by the client diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index ae710adb854..dc06cee198e 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -877,7 +877,7 @@ declare namespace ts { type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment; type BindingOrAssignmentElement = VariableDeclaration | ParameterDeclaration | BindingElement | PropertyAssignment | ShorthandPropertyAssignment | SpreadAssignment | OmittedExpression | SpreadElement | ArrayLiteralExpression | ObjectLiteralExpression | AssignmentExpression | Identifier | PropertyAccessExpression | ElementAccessExpression; type BindingOrAssignmentElementRestIndicator = DotDotDotToken | SpreadElement | SpreadAssignment; - type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Expression; + type BindingOrAssignmentElementTarget = BindingOrAssignmentPattern | Identifier | PropertyAccessExpression | ElementAccessExpression | OmittedExpression; type ObjectBindingOrAssignmentPattern = ObjectBindingPattern | ObjectLiteralExpression; type ArrayBindingOrAssignmentPattern = ArrayBindingPattern | ArrayLiteralExpression; type AssignmentPattern = ObjectLiteralExpression | ArrayLiteralExpression; @@ -1800,6 +1800,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, UseOnlyExternalAliasing = 128, @@ -1826,6 +1827,7 @@ declare namespace ts { NoTruncation = 1, WriteArrayAsGenericType = 2, WriteDefaultSymbolWithoutName = 4, + UseStructuralFallback = 8, WriteTypeArgumentsOfSignature = 32, UseFullyQualifiedType = 64, SuppressAnyReturnType = 256, @@ -1842,7 +1844,7 @@ declare namespace ts { InFirstTypeArgument = 4194304, InTypeAlias = 8388608, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 9469287, + NodeBuilderFlagsMask = 9469295, } enum SymbolFormatFlags { None = 0, @@ -2176,15 +2178,14 @@ declare namespace ts { declaration?: SignatureDeclaration; } enum InferencePriority { - Contravariant = 1, - NakedTypeVariable = 2, - MappedType = 4, - ReturnType = 8, - NeverType = 16, + NakedTypeVariable = 1, + MappedType = 2, + ReturnType = 4, } interface InferenceInfo { typeParameter: TypeParameter; candidates: Type[]; + contraCandidates: Type[]; inferredType: Type; priority: InferencePriority; topLevel: boolean; @@ -2910,8 +2911,10 @@ declare namespace ts { function isWhiteSpaceSingleLine(ch: number): boolean; function isLineBreak(ch: number): boolean; function couldStartTrivia(text: string, pos: number): boolean; - function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; - function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state?: T): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean) => U): U | undefined; + function forEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T) => U, state: T): U | undefined; function reduceEachLeadingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function reduceEachTrailingCommentRange(text: string, pos: number, cb: (pos: number, end: number, kind: CommentKind, hasTrailingNewLine: boolean, state: T, memo: U) => U, state: T, initial: U): U; function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined; @@ -4324,7 +4327,8 @@ declare namespace ts { getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean; getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan; - getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings): ReadonlyArray; + getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray, formatOptions: FormatCodeSettings): ReadonlyArray; + getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings): CombinedCodeActions; applyCodeActionCommand(action: CodeActionCommand): Promise; applyCodeActionCommand(action: CodeActionCommand[]): Promise; applyCodeActionCommand(action: CodeActionCommand | CodeActionCommand[]): Promise; @@ -4340,6 +4344,10 @@ declare namespace ts { getProgram(): Program; dispose(): void; } + interface CombinedCodeFixScope { + type: "file"; + fileName: string; + } interface GetCompletionsAtPositionOptions { includeExternalModuleExports: boolean; includeInsertTextCompletions: boolean; @@ -4417,6 +4425,17 @@ declare namespace ts { */ commands?: CodeActionCommand[]; } + interface CodeFixAction extends CodeAction { + /** + * If present, one may call 'getCombinedCodeFix' with this fixId. + * This may be omitted to indicate that the code fix can't be applied in a group. + */ + fixId?: {}; + } + interface CombinedCodeActions { + changes: ReadonlyArray; + commands: ReadonlyArray | undefined; + } type CodeActionCommand = InstallPackageAction; interface InstallPackageAction { } diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.js b/tests/baselines/reference/asyncAwaitNestedClasses_es5.js new file mode 100644 index 00000000000..ff806b76ff1 --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.js @@ -0,0 +1,52 @@ +//// [asyncAwaitNestedClasses_es5.ts] +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { + static B = class B { + static func2(): Promise { + return new Promise((resolve) => { resolve(null); }); + } + static C = class C { + static async func() { + await B.func2(); + } + } + } +} + +A.B.C.func(); + +//// [asyncAwaitNestedClasses_es5.js] +// https://github.com/Microsoft/TypeScript/issues/20744 +var A = /** @class */ (function () { + function A() { + } + A.B = (_a = /** @class */ (function () { + function B() { + } + B.func2 = function () { + return new Promise(function (resolve) { resolve(null); }); + }; + return B; + }()), + _a.C = /** @class */ (function () { + function C() { + } + C.func = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_b) { + switch (_b.label) { + case 0: return [4 /*yield*/, _a.func2()]; + case 1: + _b.sent(); + return [2 /*return*/]; + } + }); + }); + }; + return C; + }()), + _a); + return A; + var _a; +}()); +A.B.C.func(); diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols b/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols new file mode 100644 index 00000000000..339b2617fbf --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.symbols @@ -0,0 +1,43 @@ +=== tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { +>A : Symbol(A, Decl(asyncAwaitNestedClasses_es5.ts, 0, 0)) + + static B = class B { +>B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>B : Symbol(B, Decl(asyncAwaitNestedClasses_es5.ts, 2, 14)) + + static func2(): Promise { +>func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) +>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + return new Promise((resolve) => { resolve(null); }); +>Promise : Symbol(Promise, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>resolve : Symbol(resolve, Decl(asyncAwaitNestedClasses_es5.ts, 4, 32)) +>resolve : Symbol(resolve, Decl(asyncAwaitNestedClasses_es5.ts, 4, 32)) + } + static C = class C { +>C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>C : Symbol(C, Decl(asyncAwaitNestedClasses_es5.ts, 6, 18)) + + static async func() { +>func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) + + await B.func2(); +>B.func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) +>B : Symbol(B, Decl(asyncAwaitNestedClasses_es5.ts, 2, 14)) +>func2 : Symbol(B.func2, Decl(asyncAwaitNestedClasses_es5.ts, 2, 24)) + } + } + } +} + +A.B.C.func(); +>A.B.C.func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) +>A.B.C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>A.B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>A : Symbol(A, Decl(asyncAwaitNestedClasses_es5.ts, 0, 0)) +>B : Symbol(A.B, Decl(asyncAwaitNestedClasses_es5.ts, 1, 9)) +>C : Symbol(B.C, Decl(asyncAwaitNestedClasses_es5.ts, 5, 9)) +>func : Symbol(C.func, Decl(asyncAwaitNestedClasses_es5.ts, 6, 28)) + diff --git a/tests/baselines/reference/asyncAwaitNestedClasses_es5.types b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types new file mode 100644 index 00000000000..fd61951d5cc --- /dev/null +++ b/tests/baselines/reference/asyncAwaitNestedClasses_es5.types @@ -0,0 +1,52 @@ +=== tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts === +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { +>A : A + + static B = class B { +>B : typeof B +>class B { static func2(): Promise { return new Promise((resolve) => { resolve(null); }); } static C = class C { static async func() { await B.func2(); } } } : typeof B +>B : typeof B + + static func2(): Promise { +>func2 : () => Promise +>Promise : Promise + + return new Promise((resolve) => { resolve(null); }); +>new Promise((resolve) => { resolve(null); }) : Promise +>Promise : PromiseConstructor +>(resolve) => { resolve(null); } : (resolve: (value?: void | PromiseLike) => void) => void +>resolve : (value?: void | PromiseLike) => void +>resolve(null) : void +>resolve : (value?: void | PromiseLike) => void +>null : null + } + static C = class C { +>C : typeof C +>class C { static async func() { await B.func2(); } } : typeof C +>C : typeof C + + static async func() { +>func : () => Promise + + await B.func2(); +>await B.func2() : void +>B.func2() : Promise +>B.func2 : () => Promise +>B : typeof B +>func2 : () => Promise + } + } + } +} + +A.B.C.func(); +>A.B.C.func() : Promise +>A.B.C.func : () => Promise +>A.B.C : typeof C +>A.B : typeof B +>A : typeof A +>B : typeof B +>C : typeof C +>func : () => Promise + diff --git a/tests/baselines/reference/asyncWithVarShadowing_es6.js b/tests/baselines/reference/asyncWithVarShadowing_es6.js new file mode 100644 index 00000000000..392bed9d294 --- /dev/null +++ b/tests/baselines/reference/asyncWithVarShadowing_es6.js @@ -0,0 +1,497 @@ +//// [asyncWithVarShadowing_es6.ts] +// https://github.com/Microsoft/TypeScript/issues/20461 +declare const y: any; + +async function fn1(x) { + var x; +} + +async function fn2(x) { + var x, z; +} + +async function fn3(x) { + var z; +} + +async function fn4(x) { + var x = y; +} + +async function fn5(x) { + var { x } = y; +} + +async function fn6(x) { + var { x, z } = y; +} + +async function fn7(x) { + var { x = y } = y; +} + +async function fn8(x) { + var { z: x } = y; +} + +async function fn9(x) { + var { z: { x } } = y; +} + +async function fn10(x) { + var { z: { x } = y } = y; +} + +async function fn11(x) { + var { ...x } = y; +} + +async function fn12(x) { + var [x] = y; +} + +async function fn13(x) { + var [x = y] = y; +} + +async function fn14(x) { + var [, x] = y; +} + +async function fn15(x) { + var [...x] = y; +} + +async function fn16(x) { + var [[x]] = y; +} + +async function fn17(x) { + var [[x] = y] = y; +} + +async function fn18({ x }) { + var x; +} + +async function fn19([x]) { + var x; +} + +async function fn20(x) { + { + var x; + } +} + +async function fn21(x) { + if (y) { + var x; + } +} + +async function fn22(x) { + if (y) { + } + else { + var x; + } +} + +async function fn23(x) { + try { + var x; + } + catch (e) { + } +} + +async function fn24(x) { + try { + + } + catch (e) { + var x; + } +} + +async function fn25(x) { + try { + + } + catch (x) { + var x; + } +} + +async function fn26(x) { + try { + + } + catch ({ x }) { + var x; + } +} + +async function fn27(x) { + try { + } + finally { + var x; + } +} + +async function fn28(x) { + while (y) { + var x; + } +} + +async function fn29(x) { + do { + var x; + } + while (y); +} + +async function fn30(x) { + for (var x = y;;) { + + } +} + +async function fn31(x) { + for (var { x } = y;;) { + } +} + +async function fn32(x) { + for (;;) { + var x; + } +} + +async function fn33(x: string) { + for (var x in y) { + } +} + +async function fn34(x) { + for (var z in y) { + var x; + } +} + +async function fn35(x) { + for (var x of y) { + } +} + +async function fn36(x) { + for (var { x } of y) { + } +} + +async function fn37(x) { + for (var z of y) { + var x; + } +} + +async function fn38(x) { + switch (y) { + case y: + var x; + } +} + +async function fn39(x) { + foo: { + var x; + break foo; + } +} + +async function fn40(x) { + try { + + } + catch { + var x; + } +} + + +//// [asyncWithVarShadowing_es6.js] +function fn1(x) { + return __awaiter(this, void 0, void 0, function* () { + }); + var x; +} +function fn2(x) { + return __awaiter(this, void 0, void 0, function* () { + }); + var x, z; +} +function fn3(x) { + return __awaiter(this, void 0, void 0, function* () { + var z; + }); +} +function fn4(x) { + return __awaiter(this, void 0, void 0, function* () { + x = y; + }); + var x; +} +function fn5(x) { + return __awaiter(this, void 0, void 0, function* () { + ({ x } = y); + }); + var x; +} +function fn6(x) { + return __awaiter(this, void 0, void 0, function* () { + ({ x, z } = y); + }); + var x, z; +} +function fn7(x) { + return __awaiter(this, void 0, void 0, function* () { + ({ x = y } = y); + }); + var x; +} +function fn8(x) { + return __awaiter(this, void 0, void 0, function* () { + ({ z: x } = y); + }); + var x; +} +function fn9(x) { + return __awaiter(this, void 0, void 0, function* () { + ({ z: { x } } = y); + }); + var x; +} +function fn10(x) { + return __awaiter(this, void 0, void 0, function* () { + ({ z: { x } = y } = y); + }); + var x; +} +function fn11(x) { + return __awaiter(this, void 0, void 0, function* () { + x = __rest(y, []); + }); + var x; +} +function fn12(x) { + return __awaiter(this, void 0, void 0, function* () { + [x] = y; + }); + var x; +} +function fn13(x) { + return __awaiter(this, void 0, void 0, function* () { + [x = y] = y; + }); + var x; +} +function fn14(x) { + return __awaiter(this, void 0, void 0, function* () { + [, x] = y; + }); + var x; +} +function fn15(x) { + return __awaiter(this, void 0, void 0, function* () { + [...x] = y; + }); + var x; +} +function fn16(x) { + return __awaiter(this, void 0, void 0, function* () { + [[x]] = y; + }); + var x; +} +function fn17(x) { + return __awaiter(this, void 0, void 0, function* () { + [[x] = y] = y; + }); + var x; +} +function fn18({ x }) { + return __awaiter(this, void 0, void 0, function* () { + }); + var x; +} +function fn19([x]) { + return __awaiter(this, void 0, void 0, function* () { + }); + var x; +} +function fn20(x) { + return __awaiter(this, void 0, void 0, function* () { + { + } + }); + var x; +} +function fn21(x) { + return __awaiter(this, void 0, void 0, function* () { + if (y) { + } + }); + var x; +} +function fn22(x) { + return __awaiter(this, void 0, void 0, function* () { + if (y) { + } + else { + } + }); + var x; +} +function fn23(x) { + return __awaiter(this, void 0, void 0, function* () { + try { + } + catch (e) { + } + }); + var x; +} +function fn24(x) { + return __awaiter(this, void 0, void 0, function* () { + try { + } + catch (e) { + } + }); + var x; +} +function fn25(x) { + return __awaiter(this, void 0, void 0, function* () { + try { + } + catch (x) { + var x; + } + }); +} +function fn26(x) { + return __awaiter(this, void 0, void 0, function* () { + try { + } + catch ({ x }) { + var x; + } + }); +} +function fn27(x) { + return __awaiter(this, void 0, void 0, function* () { + try { + } + finally { + } + }); + var x; +} +function fn28(x) { + return __awaiter(this, void 0, void 0, function* () { + while (y) { + } + }); + var x; +} +function fn29(x) { + return __awaiter(this, void 0, void 0, function* () { + do { + } while (y); + }); + var x; +} +function fn30(x) { + return __awaiter(this, void 0, void 0, function* () { + for (x = y;;) { + } + }); + var x; +} +function fn31(x) { + return __awaiter(this, void 0, void 0, function* () { + for ({ x } = y;;) { + } + }); + var x; +} +function fn32(x) { + return __awaiter(this, void 0, void 0, function* () { + for (;;) { + } + }); + var x; +} +function fn33(x) { + return __awaiter(this, void 0, void 0, function* () { + for (x in y) { + } + }); + var x; +} +function fn34(x) { + return __awaiter(this, void 0, void 0, function* () { + for (var z in y) { + } + }); + var x; +} +function fn35(x) { + return __awaiter(this, void 0, void 0, function* () { + for (x of y) { + } + }); + var x; +} +function fn36(x) { + return __awaiter(this, void 0, void 0, function* () { + for ({ x } of y) { + } + }); + var x; +} +function fn37(x) { + return __awaiter(this, void 0, void 0, function* () { + for (var z of y) { + } + }); + var x; +} +function fn38(x) { + return __awaiter(this, void 0, void 0, function* () { + switch (y) { + case y: + } + }); + var x; +} +function fn39(x) { + return __awaiter(this, void 0, void 0, function* () { + foo: { + break foo; + } + }); + var x; +} +function fn40(x) { + return __awaiter(this, void 0, void 0, function* () { + try { + } + catch (_a) { + } + }); + var x; +} diff --git a/tests/baselines/reference/asyncWithVarShadowing_es6.symbols b/tests/baselines/reference/asyncWithVarShadowing_es6.symbols new file mode 100644 index 00000000000..ff95648722f --- /dev/null +++ b/tests/baselines/reference/asyncWithVarShadowing_es6.symbols @@ -0,0 +1,432 @@ +=== tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts === +// https://github.com/Microsoft/TypeScript/issues/20461 +declare const y: any; +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + +async function fn1(x) { +>fn1 : Symbol(fn1, Decl(asyncWithVarShadowing_es6.ts, 1, 21)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 3, 19), Decl(asyncWithVarShadowing_es6.ts, 4, 7)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 3, 19), Decl(asyncWithVarShadowing_es6.ts, 4, 7)) +} + +async function fn2(x) { +>fn2 : Symbol(fn2, Decl(asyncWithVarShadowing_es6.ts, 5, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 7, 19), Decl(asyncWithVarShadowing_es6.ts, 8, 7)) + + var x, z; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 7, 19), Decl(asyncWithVarShadowing_es6.ts, 8, 7)) +>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 8, 10)) +} + +async function fn3(x) { +>fn3 : Symbol(fn3, Decl(asyncWithVarShadowing_es6.ts, 9, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 11, 19)) + + var z; +>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 12, 7)) +} + +async function fn4(x) { +>fn4 : Symbol(fn4, Decl(asyncWithVarShadowing_es6.ts, 13, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 15, 19), Decl(asyncWithVarShadowing_es6.ts, 16, 7)) + + var x = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 15, 19), Decl(asyncWithVarShadowing_es6.ts, 16, 7)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn5(x) { +>fn5 : Symbol(fn5, Decl(asyncWithVarShadowing_es6.ts, 17, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 19, 19), Decl(asyncWithVarShadowing_es6.ts, 20, 9)) + + var { x } = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 19, 19), Decl(asyncWithVarShadowing_es6.ts, 20, 9)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn6(x) { +>fn6 : Symbol(fn6, Decl(asyncWithVarShadowing_es6.ts, 21, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 23, 19), Decl(asyncWithVarShadowing_es6.ts, 24, 9)) + + var { x, z } = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 23, 19), Decl(asyncWithVarShadowing_es6.ts, 24, 9)) +>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 24, 12)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn7(x) { +>fn7 : Symbol(fn7, Decl(asyncWithVarShadowing_es6.ts, 25, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 27, 19), Decl(asyncWithVarShadowing_es6.ts, 28, 9)) + + var { x = y } = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 27, 19), Decl(asyncWithVarShadowing_es6.ts, 28, 9)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn8(x) { +>fn8 : Symbol(fn8, Decl(asyncWithVarShadowing_es6.ts, 29, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 31, 19), Decl(asyncWithVarShadowing_es6.ts, 32, 9)) + + var { z: x } = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 31, 19), Decl(asyncWithVarShadowing_es6.ts, 32, 9)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn9(x) { +>fn9 : Symbol(fn9, Decl(asyncWithVarShadowing_es6.ts, 33, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 35, 19), Decl(asyncWithVarShadowing_es6.ts, 36, 14)) + + var { z: { x } } = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 35, 19), Decl(asyncWithVarShadowing_es6.ts, 36, 14)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn10(x) { +>fn10 : Symbol(fn10, Decl(asyncWithVarShadowing_es6.ts, 37, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 39, 20), Decl(asyncWithVarShadowing_es6.ts, 40, 14)) + + var { z: { x } = y } = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 39, 20), Decl(asyncWithVarShadowing_es6.ts, 40, 14)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn11(x) { +>fn11 : Symbol(fn11, Decl(asyncWithVarShadowing_es6.ts, 41, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 43, 20), Decl(asyncWithVarShadowing_es6.ts, 44, 9)) + + var { ...x } = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 43, 20), Decl(asyncWithVarShadowing_es6.ts, 44, 9)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn12(x) { +>fn12 : Symbol(fn12, Decl(asyncWithVarShadowing_es6.ts, 45, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 47, 20), Decl(asyncWithVarShadowing_es6.ts, 48, 9)) + + var [x] = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 47, 20), Decl(asyncWithVarShadowing_es6.ts, 48, 9)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn13(x) { +>fn13 : Symbol(fn13, Decl(asyncWithVarShadowing_es6.ts, 49, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 51, 20), Decl(asyncWithVarShadowing_es6.ts, 52, 9)) + + var [x = y] = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 51, 20), Decl(asyncWithVarShadowing_es6.ts, 52, 9)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn14(x) { +>fn14 : Symbol(fn14, Decl(asyncWithVarShadowing_es6.ts, 53, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 55, 20), Decl(asyncWithVarShadowing_es6.ts, 56, 10)) + + var [, x] = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 55, 20), Decl(asyncWithVarShadowing_es6.ts, 56, 10)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn15(x) { +>fn15 : Symbol(fn15, Decl(asyncWithVarShadowing_es6.ts, 57, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 59, 20), Decl(asyncWithVarShadowing_es6.ts, 60, 9)) + + var [...x] = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 59, 20), Decl(asyncWithVarShadowing_es6.ts, 60, 9)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn16(x) { +>fn16 : Symbol(fn16, Decl(asyncWithVarShadowing_es6.ts, 61, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 63, 20), Decl(asyncWithVarShadowing_es6.ts, 64, 10)) + + var [[x]] = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 63, 20), Decl(asyncWithVarShadowing_es6.ts, 64, 10)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn17(x) { +>fn17 : Symbol(fn17, Decl(asyncWithVarShadowing_es6.ts, 65, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 67, 20), Decl(asyncWithVarShadowing_es6.ts, 68, 10)) + + var [[x] = y] = y; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 67, 20), Decl(asyncWithVarShadowing_es6.ts, 68, 10)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn18({ x }) { +>fn18 : Symbol(fn18, Decl(asyncWithVarShadowing_es6.ts, 69, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 71, 21), Decl(asyncWithVarShadowing_es6.ts, 72, 7)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 71, 21), Decl(asyncWithVarShadowing_es6.ts, 72, 7)) +} + +async function fn19([x]) { +>fn19 : Symbol(fn19, Decl(asyncWithVarShadowing_es6.ts, 73, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 75, 21), Decl(asyncWithVarShadowing_es6.ts, 76, 7)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 75, 21), Decl(asyncWithVarShadowing_es6.ts, 76, 7)) +} + +async function fn20(x) { +>fn20 : Symbol(fn20, Decl(asyncWithVarShadowing_es6.ts, 77, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 79, 20), Decl(asyncWithVarShadowing_es6.ts, 81, 11)) + { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 79, 20), Decl(asyncWithVarShadowing_es6.ts, 81, 11)) + } +} + +async function fn21(x) { +>fn21 : Symbol(fn21, Decl(asyncWithVarShadowing_es6.ts, 83, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 85, 20), Decl(asyncWithVarShadowing_es6.ts, 87, 11)) + + if (y) { +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 85, 20), Decl(asyncWithVarShadowing_es6.ts, 87, 11)) + } +} + +async function fn22(x) { +>fn22 : Symbol(fn22, Decl(asyncWithVarShadowing_es6.ts, 89, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 91, 20), Decl(asyncWithVarShadowing_es6.ts, 95, 11)) + + if (y) { +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + } + else { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 91, 20), Decl(asyncWithVarShadowing_es6.ts, 95, 11)) + } +} + +async function fn23(x) { +>fn23 : Symbol(fn23, Decl(asyncWithVarShadowing_es6.ts, 97, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 99, 20), Decl(asyncWithVarShadowing_es6.ts, 101, 11)) + + try { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 99, 20), Decl(asyncWithVarShadowing_es6.ts, 101, 11)) + } + catch (e) { +>e : Symbol(e, Decl(asyncWithVarShadowing_es6.ts, 103, 11)) + } +} + +async function fn24(x) { +>fn24 : Symbol(fn24, Decl(asyncWithVarShadowing_es6.ts, 105, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 107, 20), Decl(asyncWithVarShadowing_es6.ts, 112, 11)) + + try { + + } + catch (e) { +>e : Symbol(e, Decl(asyncWithVarShadowing_es6.ts, 111, 11)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 107, 20), Decl(asyncWithVarShadowing_es6.ts, 112, 11)) + } +} + +async function fn25(x) { +>fn25 : Symbol(fn25, Decl(asyncWithVarShadowing_es6.ts, 114, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 116, 20), Decl(asyncWithVarShadowing_es6.ts, 121, 11)) + + try { + + } + catch (x) { +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 120, 11)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 116, 20), Decl(asyncWithVarShadowing_es6.ts, 121, 11)) + } +} + +async function fn26(x) { +>fn26 : Symbol(fn26, Decl(asyncWithVarShadowing_es6.ts, 123, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 125, 20), Decl(asyncWithVarShadowing_es6.ts, 130, 11)) + + try { + + } + catch ({ x }) { +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 129, 12)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 125, 20), Decl(asyncWithVarShadowing_es6.ts, 130, 11)) + } +} + +async function fn27(x) { +>fn27 : Symbol(fn27, Decl(asyncWithVarShadowing_es6.ts, 132, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 134, 20), Decl(asyncWithVarShadowing_es6.ts, 138, 11)) + + try { + } + finally { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 134, 20), Decl(asyncWithVarShadowing_es6.ts, 138, 11)) + } +} + +async function fn28(x) { +>fn28 : Symbol(fn28, Decl(asyncWithVarShadowing_es6.ts, 140, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 142, 20), Decl(asyncWithVarShadowing_es6.ts, 144, 11)) + + while (y) { +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 142, 20), Decl(asyncWithVarShadowing_es6.ts, 144, 11)) + } +} + +async function fn29(x) { +>fn29 : Symbol(fn29, Decl(asyncWithVarShadowing_es6.ts, 146, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 148, 20), Decl(asyncWithVarShadowing_es6.ts, 150, 11)) + + do { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 148, 20), Decl(asyncWithVarShadowing_es6.ts, 150, 11)) + } + while (y); +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) +} + +async function fn30(x) { +>fn30 : Symbol(fn30, Decl(asyncWithVarShadowing_es6.ts, 153, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 155, 20), Decl(asyncWithVarShadowing_es6.ts, 156, 12)) + + for (var x = y;;) { +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 155, 20), Decl(asyncWithVarShadowing_es6.ts, 156, 12)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + + } +} + +async function fn31(x) { +>fn31 : Symbol(fn31, Decl(asyncWithVarShadowing_es6.ts, 159, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 161, 20), Decl(asyncWithVarShadowing_es6.ts, 162, 14)) + + for (var { x } = y;;) { +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 161, 20), Decl(asyncWithVarShadowing_es6.ts, 162, 14)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + } +} + +async function fn32(x) { +>fn32 : Symbol(fn32, Decl(asyncWithVarShadowing_es6.ts, 164, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 166, 20), Decl(asyncWithVarShadowing_es6.ts, 168, 11)) + + for (;;) { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 166, 20), Decl(asyncWithVarShadowing_es6.ts, 168, 11)) + } +} + +async function fn33(x: string) { +>fn33 : Symbol(fn33, Decl(asyncWithVarShadowing_es6.ts, 170, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 172, 20), Decl(asyncWithVarShadowing_es6.ts, 173, 12)) + + for (var x in y) { +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 172, 20), Decl(asyncWithVarShadowing_es6.ts, 173, 12)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + } +} + +async function fn34(x) { +>fn34 : Symbol(fn34, Decl(asyncWithVarShadowing_es6.ts, 175, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 177, 20), Decl(asyncWithVarShadowing_es6.ts, 179, 11)) + + for (var z in y) { +>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 178, 12)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 177, 20), Decl(asyncWithVarShadowing_es6.ts, 179, 11)) + } +} + +async function fn35(x) { +>fn35 : Symbol(fn35, Decl(asyncWithVarShadowing_es6.ts, 181, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 183, 20), Decl(asyncWithVarShadowing_es6.ts, 184, 12)) + + for (var x of y) { +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 183, 20), Decl(asyncWithVarShadowing_es6.ts, 184, 12)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + } +} + +async function fn36(x) { +>fn36 : Symbol(fn36, Decl(asyncWithVarShadowing_es6.ts, 186, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 188, 20), Decl(asyncWithVarShadowing_es6.ts, 189, 14)) + + for (var { x } of y) { +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 188, 20), Decl(asyncWithVarShadowing_es6.ts, 189, 14)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + } +} + +async function fn37(x) { +>fn37 : Symbol(fn37, Decl(asyncWithVarShadowing_es6.ts, 191, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 193, 20), Decl(asyncWithVarShadowing_es6.ts, 195, 11)) + + for (var z of y) { +>z : Symbol(z, Decl(asyncWithVarShadowing_es6.ts, 194, 12)) +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 193, 20), Decl(asyncWithVarShadowing_es6.ts, 195, 11)) + } +} + +async function fn38(x) { +>fn38 : Symbol(fn38, Decl(asyncWithVarShadowing_es6.ts, 197, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 199, 20), Decl(asyncWithVarShadowing_es6.ts, 202, 15)) + + switch (y) { +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + + case y: +>y : Symbol(y, Decl(asyncWithVarShadowing_es6.ts, 1, 13)) + + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 199, 20), Decl(asyncWithVarShadowing_es6.ts, 202, 15)) + } +} + +async function fn39(x) { +>fn39 : Symbol(fn39, Decl(asyncWithVarShadowing_es6.ts, 204, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 206, 20), Decl(asyncWithVarShadowing_es6.ts, 208, 11)) + + foo: { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 206, 20), Decl(asyncWithVarShadowing_es6.ts, 208, 11)) + + break foo; + } +} + +async function fn40(x) { +>fn40 : Symbol(fn40, Decl(asyncWithVarShadowing_es6.ts, 211, 1)) +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 213, 20), Decl(asyncWithVarShadowing_es6.ts, 218, 11)) + + try { + + } + catch { + var x; +>x : Symbol(x, Decl(asyncWithVarShadowing_es6.ts, 213, 20), Decl(asyncWithVarShadowing_es6.ts, 218, 11)) + } +} + diff --git a/tests/baselines/reference/asyncWithVarShadowing_es6.types b/tests/baselines/reference/asyncWithVarShadowing_es6.types new file mode 100644 index 00000000000..f87e452b2a1 --- /dev/null +++ b/tests/baselines/reference/asyncWithVarShadowing_es6.types @@ -0,0 +1,439 @@ +=== tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts === +// https://github.com/Microsoft/TypeScript/issues/20461 +declare const y: any; +>y : any + +async function fn1(x) { +>fn1 : (x: any) => Promise +>x : any + + var x; +>x : any +} + +async function fn2(x) { +>fn2 : (x: any) => Promise +>x : any + + var x, z; +>x : any +>z : any +} + +async function fn3(x) { +>fn3 : (x: any) => Promise +>x : any + + var z; +>z : any +} + +async function fn4(x) { +>fn4 : (x: any) => Promise +>x : any + + var x = y; +>x : any +>y : any +} + +async function fn5(x) { +>fn5 : (x: any) => Promise +>x : any + + var { x } = y; +>x : any +>y : any +} + +async function fn6(x) { +>fn6 : (x: any) => Promise +>x : any + + var { x, z } = y; +>x : any +>z : any +>y : any +} + +async function fn7(x) { +>fn7 : (x: any) => Promise +>x : any + + var { x = y } = y; +>x : any +>y : any +>y : any +} + +async function fn8(x) { +>fn8 : (x: any) => Promise +>x : any + + var { z: x } = y; +>z : any +>x : any +>y : any +} + +async function fn9(x) { +>fn9 : (x: any) => Promise +>x : any + + var { z: { x } } = y; +>z : any +>x : any +>y : any +} + +async function fn10(x) { +>fn10 : (x: any) => Promise +>x : any + + var { z: { x } = y } = y; +>z : any +>x : any +>y : any +>y : any +} + +async function fn11(x) { +>fn11 : (x: any) => Promise +>x : any + + var { ...x } = y; +>x : any +>y : any +} + +async function fn12(x) { +>fn12 : (x: any) => Promise +>x : any + + var [x] = y; +>x : any +>y : any +} + +async function fn13(x) { +>fn13 : (x: any) => Promise +>x : any + + var [x = y] = y; +>x : any +>y : any +>y : any +} + +async function fn14(x) { +>fn14 : (x: any) => Promise +>x : any + + var [, x] = y; +> : undefined +>x : any +>y : any +} + +async function fn15(x) { +>fn15 : (x: any) => Promise +>x : any + + var [...x] = y; +>x : any +>y : any +} + +async function fn16(x) { +>fn16 : (x: any) => Promise +>x : any + + var [[x]] = y; +>x : any +>y : any +} + +async function fn17(x) { +>fn17 : (x: any) => Promise +>x : any + + var [[x] = y] = y; +>x : any +>y : any +>y : any +} + +async function fn18({ x }) { +>fn18 : ({ x }: { x: any; }) => Promise +>x : any + + var x; +>x : any +} + +async function fn19([x]) { +>fn19 : ([x]: [any]) => Promise +>x : any + + var x; +>x : any +} + +async function fn20(x) { +>fn20 : (x: any) => Promise +>x : any + { + var x; +>x : any + } +} + +async function fn21(x) { +>fn21 : (x: any) => Promise +>x : any + + if (y) { +>y : any + + var x; +>x : any + } +} + +async function fn22(x) { +>fn22 : (x: any) => Promise +>x : any + + if (y) { +>y : any + } + else { + var x; +>x : any + } +} + +async function fn23(x) { +>fn23 : (x: any) => Promise +>x : any + + try { + var x; +>x : any + } + catch (e) { +>e : any + } +} + +async function fn24(x) { +>fn24 : (x: any) => Promise +>x : any + + try { + + } + catch (e) { +>e : any + + var x; +>x : any + } +} + +async function fn25(x) { +>fn25 : (x: any) => Promise +>x : any + + try { + + } + catch (x) { +>x : any + + var x; +>x : any + } +} + +async function fn26(x) { +>fn26 : (x: any) => Promise +>x : any + + try { + + } + catch ({ x }) { +>x : any + + var x; +>x : any + } +} + +async function fn27(x) { +>fn27 : (x: any) => Promise +>x : any + + try { + } + finally { + var x; +>x : any + } +} + +async function fn28(x) { +>fn28 : (x: any) => Promise +>x : any + + while (y) { +>y : any + + var x; +>x : any + } +} + +async function fn29(x) { +>fn29 : (x: any) => Promise +>x : any + + do { + var x; +>x : any + } + while (y); +>y : any +} + +async function fn30(x) { +>fn30 : (x: any) => Promise +>x : any + + for (var x = y;;) { +>x : any +>y : any + + } +} + +async function fn31(x) { +>fn31 : (x: any) => Promise +>x : any + + for (var { x } = y;;) { +>x : any +>y : any + } +} + +async function fn32(x) { +>fn32 : (x: any) => Promise +>x : any + + for (;;) { + var x; +>x : any + } +} + +async function fn33(x: string) { +>fn33 : (x: string) => Promise +>x : string + + for (var x in y) { +>x : string +>y : any + } +} + +async function fn34(x) { +>fn34 : (x: any) => Promise +>x : any + + for (var z in y) { +>z : string +>y : any + + var x; +>x : any + } +} + +async function fn35(x) { +>fn35 : (x: any) => Promise +>x : any + + for (var x of y) { +>x : any +>y : any + } +} + +async function fn36(x) { +>fn36 : (x: any) => Promise +>x : any + + for (var { x } of y) { +>x : any +>y : any + } +} + +async function fn37(x) { +>fn37 : (x: any) => Promise +>x : any + + for (var z of y) { +>z : any +>y : any + + var x; +>x : any + } +} + +async function fn38(x) { +>fn38 : (x: any) => Promise +>x : any + + switch (y) { +>y : any + + case y: +>y : any + + var x; +>x : any + } +} + +async function fn39(x) { +>fn39 : (x: any) => Promise +>x : any + + foo: { +>foo : any + + var x; +>x : any + + break foo; +>foo : any + } +} + +async function fn40(x) { +>fn40 : (x: any) => Promise +>x : any + + try { + + } + catch { + var x; +>x : any + } +} + diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js new file mode 100644 index 00000000000..6faa0bfca60 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.js @@ -0,0 +1,26 @@ +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.ts] +namespace foo { + function bar(): void {} + + export const obj = { + bar + } +} + + +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.js] +var foo; +(function (foo) { + function bar() { } + foo.obj = { + bar: bar + }; +})(foo || (foo = {})); + + +//// [declarationFunctionTypeNonlocalShouldNotBeAnError.d.ts] +declare namespace foo { + const obj: { + bar: () => void; + }; +} diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols new file mode 100644 index 00000000000..74ce59284e0 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.symbols @@ -0,0 +1,15 @@ +=== tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts === +namespace foo { +>foo : Symbol(foo, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 0, 0)) + + function bar(): void {} +>bar : Symbol(bar, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 0, 15)) + + export const obj = { +>obj : Symbol(obj, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 3, 16)) + + bar +>bar : Symbol(bar, Decl(declarationFunctionTypeNonlocalShouldNotBeAnError.ts, 3, 24)) + } +} + diff --git a/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types new file mode 100644 index 00000000000..e86ead184c9 --- /dev/null +++ b/tests/baselines/reference/declarationFunctionTypeNonlocalShouldNotBeAnError.types @@ -0,0 +1,16 @@ +=== tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts === +namespace foo { +>foo : typeof foo + + function bar(): void {} +>bar : () => void + + export const obj = { +>obj : { bar: () => void; } +>{ bar } : { bar: () => void; } + + bar +>bar : () => void + } +} + diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.js b/tests/baselines/reference/destructuringReassignsRightHandSide.js new file mode 100644 index 00000000000..b893202aa1e --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.js @@ -0,0 +1,18 @@ +//// [destructuringReassignsRightHandSide.ts] +var foo: any = { foo: 1, bar: 2 }; +var bar: any; + +// reassignment in destructuring pattern +({ foo, bar } = foo); + +// reassignment in subsequent var +var { foo, baz } = foo; + +//// [destructuringReassignsRightHandSide.js] +var foo = { foo: 1, bar: 2 }; +var bar; +// reassignment in destructuring pattern +(_a = foo, foo = _a.foo, bar = _a.bar); +// reassignment in subsequent var +var _b = foo, foo = _b.foo, baz = _b.baz; +var _a; diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.symbols b/tests/baselines/reference/destructuringReassignsRightHandSide.symbols new file mode 100644 index 00000000000..a0b68b7fe53 --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.symbols @@ -0,0 +1,21 @@ +=== tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts === +var foo: any = { foo: 1, bar: 2 }; +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 16)) +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 0, 24)) + +var bar: any; +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 1, 3)) + +// reassignment in destructuring pattern +({ foo, bar } = foo); +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 4, 2)) +>bar : Symbol(bar, Decl(destructuringReassignsRightHandSide.ts, 4, 7)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) + +// reassignment in subsequent var +var { foo, baz } = foo; +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) +>baz : Symbol(baz, Decl(destructuringReassignsRightHandSide.ts, 7, 10)) +>foo : Symbol(foo, Decl(destructuringReassignsRightHandSide.ts, 0, 3), Decl(destructuringReassignsRightHandSide.ts, 7, 5)) + diff --git a/tests/baselines/reference/destructuringReassignsRightHandSide.types b/tests/baselines/reference/destructuringReassignsRightHandSide.types new file mode 100644 index 00000000000..f5ba19820e0 --- /dev/null +++ b/tests/baselines/reference/destructuringReassignsRightHandSide.types @@ -0,0 +1,27 @@ +=== tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts === +var foo: any = { foo: 1, bar: 2 }; +>foo : any +>{ foo: 1, bar: 2 } : { foo: number; bar: number; } +>foo : number +>1 : 1 +>bar : number +>2 : 2 + +var bar: any; +>bar : any + +// reassignment in destructuring pattern +({ foo, bar } = foo); +>({ foo, bar } = foo) : any +>{ foo, bar } = foo : any +>{ foo, bar } : { foo: any; bar: any; } +>foo : any +>bar : any +>foo : any + +// reassignment in subsequent var +var { foo, baz } = foo; +>foo : any +>baz : any +>foo : any + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js new file mode 100644 index 00000000000..5236a93f931 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts] //// + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "foo"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "foo", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "foo/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("foo/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols new file mode 100644 index 00000000000..19809675af2 --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/foo/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json new file mode 100644 index 00000000000..ae3917e931a --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module 'foo/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/use@1.2.3'.", + "File '/node_modules/foo/use.ts' does not exist.", + "File '/node_modules/foo/use.tsx' does not exist.", + "File '/node_modules/foo/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/foo/use.d.ts', result '/node_modules/foo/use.d.ts'.", + "======== Module name 'foo/use' was successfully resolved to '/node_modules/foo/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/foo/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/foo/index', target file type 'TypeScript'.", + "File '/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", + "======== Module name './index' was successfully resolved to '/node_modules/foo/index.d.ts'. ========", + "======== Resolving module 'foo' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'foo' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/foo/package.json'. Package ID is 'foo@1.2.3'.", + "File '/node_modules/a/node_modules/foo.ts' does not exist.", + "File '/node_modules/a/node_modules/foo.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/foo/index.ts' does not exist.", + "File '/node_modules/a/node_modules/foo/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/foo/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/foo/index.d.ts', result '/node_modules/a/node_modules/foo/index.d.ts'.", + "======== Module name 'foo' was successfully resolved to '/node_modules/a/node_modules/foo/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types new file mode 100644 index 00000000000..33931774a1b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "foo/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "foo"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/foo/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/foo/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js new file mode 100644 index 00000000000..822c03ca18d --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.js @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts] //// + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [index.d.ts] +import { C } from "@foo/bar"; +export const o: C; + +//// [use.d.ts] +import { C } from "./index"; +export function use(o: C): void; + +//// [index.d.ts] +export class C { + private x: number; +} + +//// [package.json] +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +//// [index.ts] +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o); + + +//// [index.js] +"use strict"; +exports.__esModule = true; +var use_1 = require("@foo/bar/use"); +var a_1 = require("a"); +use_1.use(a_1.o); diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols new file mode 100644 index 00000000000..38cd37e023b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.symbols @@ -0,0 +1,44 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : Symbol(use, Decl(index.ts, 0, 8)) + +import { o } from "a"; +>o : Symbol(o, Decl(index.ts, 1, 8)) + +use(o); +>use : Symbol(use, Decl(index.ts, 0, 8)) +>o : Symbol(o, Decl(index.ts, 1, 8)) + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +export const o: C; +>o : Symbol(o, Decl(index.d.ts, 1, 12)) +>C : Symbol(C, Decl(index.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +export function use(o: C): void; +>use : Symbol(use, Decl(use.d.ts, 0, 28)) +>o : Symbol(o, Decl(use.d.ts, 1, 20)) +>C : Symbol(C, Decl(use.d.ts, 0, 8)) + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : Symbol(C, Decl(index.d.ts, 0, 0)) + + private x: number; +>x : Symbol(C.x, Decl(index.d.ts, 0, 16)) +} + diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json new file mode 100644 index 00000000000..a753e3dfb9a --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.trace.json @@ -0,0 +1,45 @@ +[ + "======== Resolving module '@foo/bar/use' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar/use' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar/use@1.2.3'.", + "File '/node_modules/@foo/bar/use.ts' does not exist.", + "File '/node_modules/@foo/bar/use.tsx' does not exist.", + "File '/node_modules/@foo/bar/use.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/@foo/bar/use.d.ts', result '/node_modules/@foo/bar/use.d.ts'.", + "======== Module name '@foo/bar/use' was successfully resolved to '/node_modules/@foo/bar/use.d.ts'. ========", + "======== Resolving module 'a' from '/index.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module 'a' from 'node_modules' folder, target file type 'TypeScript'.", + "File '/node_modules/a/package.json' does not exist.", + "File '/node_modules/a.ts' does not exist.", + "File '/node_modules/a.tsx' does not exist.", + "File '/node_modules/a.d.ts' does not exist.", + "File '/node_modules/a/index.ts' does not exist.", + "File '/node_modules/a/index.tsx' does not exist.", + "File '/node_modules/a/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/index.d.ts', result '/node_modules/a/index.d.ts'.", + "======== Module name 'a' was successfully resolved to '/node_modules/a/index.d.ts'. ========", + "======== Resolving module './index' from '/node_modules/@foo/bar/use.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module as file / folder, candidate module location '/node_modules/@foo/bar/index', target file type 'TypeScript'.", + "File '/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Found 'package.json' at '/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", + "======== Module name './index' was successfully resolved to '/node_modules/@foo/bar/index.d.ts'. ========", + "======== Resolving module '@foo/bar' from '/node_modules/a/index.d.ts'. ========", + "Module resolution kind is not specified, using 'NodeJs'.", + "Loading module '@foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", + "Found 'package.json' at '/node_modules/a/node_modules/@foo/bar/package.json'. Package ID is '@foo/bar@1.2.3'.", + "File '/node_modules/a/node_modules/@foo/bar.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar.d.ts' does not exist.", + "'package.json' does not have a 'typings' field.", + "'package.json' does not have a 'types' field.", + "File '/node_modules/a/node_modules/@foo/bar/index.ts' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.tsx' does not exist.", + "File '/node_modules/a/node_modules/@foo/bar/index.d.ts' exist - use it as a name resolution result.", + "Resolving real path for '/node_modules/a/node_modules/@foo/bar/index.d.ts', result '/node_modules/a/node_modules/@foo/bar/index.d.ts'.", + "======== Module name '@foo/bar' was successfully resolved to '/node_modules/a/node_modules/@foo/bar/index.d.ts'. ========" +] \ No newline at end of file diff --git a/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types new file mode 100644 index 00000000000..7be2442bf3b --- /dev/null +++ b/tests/baselines/reference/duplicatePackage_relativeImportWithinPackage_scoped.types @@ -0,0 +1,45 @@ +=== /index.ts === +import { use } from "@foo/bar/use"; +>use : (o: C) => void + +import { o } from "a"; +>o : C + +use(o); +>use(o) : void +>use : (o: C) => void +>o : C + +=== /node_modules/a/node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + +=== /node_modules/a/index.d.ts === +import { C } from "@foo/bar"; +>C : typeof C + +export const o: C; +>o : C +>C : C + +=== /node_modules/@foo/bar/use.d.ts === +import { C } from "./index"; +>C : typeof C + +export function use(o: C): void; +>use : (o: C) => void +>o : C +>C : C + +=== /node_modules/@foo/bar/index.d.ts === +export class C { +>C : C + + private x: number; +>x : number +} + diff --git a/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.js b/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.js new file mode 100644 index 00000000000..b0f224b5591 --- /dev/null +++ b/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.js @@ -0,0 +1,25 @@ +//// [intersectionOfTypeVariableHasApparentSignatures.ts] +interface Component

{ + props: Readonly

& Readonly<{ children?: {} }>; +} + +interface Props { + children?: (items: {x: number}) => void +} + +declare function f(i: Component): void; + +f({ + props: { + children: (({ x }) => { }) + } +}); + +//// [intersectionOfTypeVariableHasApparentSignatures.js] +f({ + props: { + children: (function (_a) { + var x = _a.x; + }) + } +}); diff --git a/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.symbols b/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.symbols new file mode 100644 index 00000000000..8dc4781c865 --- /dev/null +++ b/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.symbols @@ -0,0 +1,41 @@ +=== tests/cases/compiler/intersectionOfTypeVariableHasApparentSignatures.ts === +interface Component

{ +>Component : Symbol(Component, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 0, 0)) +>P : Symbol(P, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 0, 20)) + + props: Readonly

& Readonly<{ children?: {} }>; +>props : Symbol(Component.props, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 0, 24)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>P : Symbol(P, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 0, 20)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>children : Symbol(children, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 1, 35)) +} + +interface Props { +>Props : Symbol(Props, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 2, 1)) + + children?: (items: {x: number}) => void +>children : Symbol(Props.children, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 4, 17)) +>items : Symbol(items, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 5, 16)) +>x : Symbol(x, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 5, 24)) +} + +declare function f(i: Component): void; +>f : Symbol(f, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 6, 1)) +>T : Symbol(T, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 8, 19)) +>Props : Symbol(Props, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 2, 1)) +>i : Symbol(i, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 8, 36)) +>Component : Symbol(Component, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 0, 0)) +>T : Symbol(T, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 8, 19)) + +f({ +>f : Symbol(f, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 6, 1)) + + props: { +>props : Symbol(props, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 10, 3)) + + children: (({ x }) => { }) +>children : Symbol(children, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 11, 12)) +>x : Symbol(x, Decl(intersectionOfTypeVariableHasApparentSignatures.ts, 12, 21)) + } +}); diff --git a/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.types b/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.types new file mode 100644 index 00000000000..927839de2e7 --- /dev/null +++ b/tests/baselines/reference/intersectionOfTypeVariableHasApparentSignatures.types @@ -0,0 +1,46 @@ +=== tests/cases/compiler/intersectionOfTypeVariableHasApparentSignatures.ts === +interface Component

{ +>Component : Component

+>P : P + + props: Readonly

& Readonly<{ children?: {} }>; +>props : Readonly

& Readonly<{ children?: {} | undefined; }> +>Readonly : Readonly +>P : P +>Readonly : Readonly +>children : {} | undefined +} + +interface Props { +>Props : Props + + children?: (items: {x: number}) => void +>children : ((items: { x: number; }) => void) | undefined +>items : { x: number; } +>x : number +} + +declare function f(i: Component): void; +>f : (i: Component) => void +>T : T +>Props : Props +>i : Component +>Component : Component

+>T : T + +f({ +>f({ props: { children: (({ x }) => { }) }}) : void +>f : (i: Component) => void +>{ props: { children: (({ x }) => { }) }} : { props: { children: ({ x }: { x: number; }) => void; }; } + + props: { +>props : { children: ({ x }: { x: number; }) => void; } +>{ children: (({ x }) => { }) } : { children: ({ x }: { x: number; }) => void; } + + children: (({ x }) => { }) +>children : ({ x }: { x: number; }) => void +>(({ x }) => { }) : ({ x }: { x: number; }) => void +>({ x }) => { } : ({ x }: { x: number; }) => void +>x : number + } +}); diff --git a/tests/baselines/reference/jsxCallbackWithDestructuring.js b/tests/baselines/reference/jsxCallbackWithDestructuring.js new file mode 100644 index 00000000000..f8f7173aa30 --- /dev/null +++ b/tests/baselines/reference/jsxCallbackWithDestructuring.js @@ -0,0 +1,52 @@ +//// [jsxCallbackWithDestructuring.tsx] +// minimal component +interface Component

{ } +declare class Component { + constructor(props: P, context?: any); + render(): {}; + props: Readonly<{ children?: {} }> & Readonly

; +} + +declare global { + namespace JSX { + interface Element { } + interface ElementClass { + render(): {}; + } + interface ElementAttributesProperty { props: {}; } + interface ElementChildrenAttribute { children: {}; } + interface IntrinsicAttributes { } + interface IntrinsicClassAttributes { } + } +} + +export interface RouteProps { + children?: (props: { x: number }) => any; +} +export class MyComponent extends Component { } + {}}/> + +//// [jsxCallbackWithDestructuring.jsx] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +exports.__esModule = true; +var MyComponent = /** @class */ (function (_super) { + __extends(MyComponent, _super); + function MyComponent() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MyComponent; +}(Component)); +exports.MyComponent = MyComponent; +; diff --git a/tests/baselines/reference/jsxCallbackWithDestructuring.symbols b/tests/baselines/reference/jsxCallbackWithDestructuring.symbols new file mode 100644 index 00000000000..d879f256e13 --- /dev/null +++ b/tests/baselines/reference/jsxCallbackWithDestructuring.symbols @@ -0,0 +1,81 @@ +=== tests/cases/compiler/jsxCallbackWithDestructuring.tsx === +// minimal component +interface Component

{ } +>Component : Symbol(Component, Decl(jsxCallbackWithDestructuring.tsx, 0, 0), Decl(jsxCallbackWithDestructuring.tsx, 1, 39)) +>P : Symbol(P, Decl(jsxCallbackWithDestructuring.tsx, 1, 20), Decl(jsxCallbackWithDestructuring.tsx, 2, 24)) +>S : Symbol(S, Decl(jsxCallbackWithDestructuring.tsx, 1, 27), Decl(jsxCallbackWithDestructuring.tsx, 2, 26)) + +declare class Component { +>Component : Symbol(Component, Decl(jsxCallbackWithDestructuring.tsx, 0, 0), Decl(jsxCallbackWithDestructuring.tsx, 1, 39)) +>P : Symbol(P, Decl(jsxCallbackWithDestructuring.tsx, 1, 20), Decl(jsxCallbackWithDestructuring.tsx, 2, 24)) +>S : Symbol(S, Decl(jsxCallbackWithDestructuring.tsx, 1, 27), Decl(jsxCallbackWithDestructuring.tsx, 2, 26)) + + constructor(props: P, context?: any); +>props : Symbol(props, Decl(jsxCallbackWithDestructuring.tsx, 3, 16)) +>P : Symbol(P, Decl(jsxCallbackWithDestructuring.tsx, 1, 20), Decl(jsxCallbackWithDestructuring.tsx, 2, 24)) +>context : Symbol(context, Decl(jsxCallbackWithDestructuring.tsx, 3, 25)) + + render(): {}; +>render : Symbol(Component.render, Decl(jsxCallbackWithDestructuring.tsx, 3, 41)) + + props: Readonly<{ children?: {} }> & Readonly

; +>props : Symbol(Component.props, Decl(jsxCallbackWithDestructuring.tsx, 4, 17)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>children : Symbol(children, Decl(jsxCallbackWithDestructuring.tsx, 5, 21)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>P : Symbol(P, Decl(jsxCallbackWithDestructuring.tsx, 1, 20), Decl(jsxCallbackWithDestructuring.tsx, 2, 24)) +} + +declare global { +>global : Symbol(global, Decl(jsxCallbackWithDestructuring.tsx, 6, 1)) + + namespace JSX { +>JSX : Symbol(JSX, Decl(jsxCallbackWithDestructuring.tsx, 8, 16)) + + interface Element { } +>Element : Symbol(Element, Decl(jsxCallbackWithDestructuring.tsx, 9, 19)) + + interface ElementClass { +>ElementClass : Symbol(ElementClass, Decl(jsxCallbackWithDestructuring.tsx, 10, 30)) + + render(): {}; +>render : Symbol(ElementClass.render, Decl(jsxCallbackWithDestructuring.tsx, 11, 33)) + } + interface ElementAttributesProperty { props: {}; } +>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(jsxCallbackWithDestructuring.tsx, 13, 9)) +>props : Symbol(ElementAttributesProperty.props, Decl(jsxCallbackWithDestructuring.tsx, 14, 45)) + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(jsxCallbackWithDestructuring.tsx, 14, 58)) +>children : Symbol(ElementChildrenAttribute.children, Decl(jsxCallbackWithDestructuring.tsx, 15, 44)) + + interface IntrinsicAttributes { } +>IntrinsicAttributes : Symbol(IntrinsicAttributes, Decl(jsxCallbackWithDestructuring.tsx, 15, 60)) + + interface IntrinsicClassAttributes { } +>IntrinsicClassAttributes : Symbol(IntrinsicClassAttributes, Decl(jsxCallbackWithDestructuring.tsx, 16, 42)) +>T : Symbol(T, Decl(jsxCallbackWithDestructuring.tsx, 17, 43)) + } +} + +export interface RouteProps { +>RouteProps : Symbol(RouteProps, Decl(jsxCallbackWithDestructuring.tsx, 19, 1)) + + children?: (props: { x: number }) => any; +>children : Symbol(RouteProps.children, Decl(jsxCallbackWithDestructuring.tsx, 21, 29)) +>props : Symbol(props, Decl(jsxCallbackWithDestructuring.tsx, 22, 16)) +>x : Symbol(x, Decl(jsxCallbackWithDestructuring.tsx, 22, 24)) +} +export class MyComponent extends Component { } +>MyComponent : Symbol(MyComponent, Decl(jsxCallbackWithDestructuring.tsx, 23, 1)) +>T : Symbol(T, Decl(jsxCallbackWithDestructuring.tsx, 24, 25)) +>RouteProps : Symbol(RouteProps, Decl(jsxCallbackWithDestructuring.tsx, 19, 1)) +>RouteProps : Symbol(RouteProps, Decl(jsxCallbackWithDestructuring.tsx, 19, 1)) +>Component : Symbol(Component, Decl(jsxCallbackWithDestructuring.tsx, 0, 0), Decl(jsxCallbackWithDestructuring.tsx, 1, 39)) +>T : Symbol(T, Decl(jsxCallbackWithDestructuring.tsx, 24, 25)) + + {}}/> +>MyComponent : Symbol(MyComponent, Decl(jsxCallbackWithDestructuring.tsx, 23, 1)) +>children : Symbol(children, Decl(jsxCallbackWithDestructuring.tsx, 25, 12)) +>x : Symbol(x, Decl(jsxCallbackWithDestructuring.tsx, 25, 25)) + diff --git a/tests/baselines/reference/jsxCallbackWithDestructuring.types b/tests/baselines/reference/jsxCallbackWithDestructuring.types new file mode 100644 index 00000000000..3ee99e72aa3 --- /dev/null +++ b/tests/baselines/reference/jsxCallbackWithDestructuring.types @@ -0,0 +1,83 @@ +=== tests/cases/compiler/jsxCallbackWithDestructuring.tsx === +// minimal component +interface Component

{ } +>Component : Component +>P : P +>S : S + +declare class Component { +>Component : Component +>P : P +>S : S + + constructor(props: P, context?: any); +>props : P +>P : P +>context : any + + render(): {}; +>render : () => {} + + props: Readonly<{ children?: {} }> & Readonly

; +>props : Readonly<{ children?: {} | undefined; }> & Readonly

+>Readonly : Readonly +>children : {} | undefined +>Readonly : Readonly +>P : P +} + +declare global { +>global : any + + namespace JSX { +>JSX : any + + interface Element { } +>Element : Element + + interface ElementClass { +>ElementClass : ElementClass + + render(): {}; +>render : () => {} + } + interface ElementAttributesProperty { props: {}; } +>ElementAttributesProperty : ElementAttributesProperty +>props : {} + + interface ElementChildrenAttribute { children: {}; } +>ElementChildrenAttribute : ElementChildrenAttribute +>children : {} + + interface IntrinsicAttributes { } +>IntrinsicAttributes : IntrinsicAttributes + + interface IntrinsicClassAttributes { } +>IntrinsicClassAttributes : IntrinsicClassAttributes +>T : T + } +} + +export interface RouteProps { +>RouteProps : RouteProps + + children?: (props: { x: number }) => any; +>children : ((props: { x: number; }) => any) | undefined +>props : { x: number; } +>x : number +} +export class MyComponent extends Component { } +>MyComponent : MyComponent +>T : T +>RouteProps : RouteProps +>RouteProps : RouteProps +>Component : Component +>T : T + + {}}/> +> {}}/> : JSX.Element +>MyComponent : typeof MyComponent +>children : ({ x }: { x: number; }) => void +>({ x }) => {} : ({ x }: { x: number; }) => void +>x : number + diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json index 3a87769891b..e852d58f2b3 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", "File '/node_modules/foo/bar.ts' does not exist.", "File '/node_modules/foo/bar.tsx' does not exist.", "File '/node_modules/foo/bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/bar@1.2.3'.", "File '/node_modules/foo/bar.js' does not exist.", "File '/node_modules/foo/bar.jsx' does not exist.", "File '/node_modules/foo/bar/index.js' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json index c28189a1f7d..19fe1f125bc 100644 --- a/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json +++ b/tests/baselines/reference/moduleResolution_packageJson_yesAtPackageRoot_fakeScopedPackage.trace.json @@ -3,7 +3,7 @@ "Module resolution kind is not specified, using 'NodeJs'.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'TypeScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", "File '/node_modules/foo/@bar.ts' does not exist.", "File '/node_modules/foo/@bar.tsx' does not exist.", "File '/node_modules/foo/@bar.d.ts' does not exist.", @@ -13,7 +13,7 @@ "Directory '/node_modules/@types' does not exist, skipping all lookups in it.", "Loading module 'foo/@bar' from 'node_modules' folder, target file type 'JavaScript'.", "File '/node_modules/foo/@bar/package.json' does not exist.", - "Found 'package.json' at '/node_modules/foo/package.json'.", + "Found 'package.json' at '/node_modules/foo/package.json'. Package ID is 'foo/@bar@1.2.3'.", "File '/node_modules/foo/@bar.js' does not exist.", "File '/node_modules/foo/@bar.jsx' does not exist.", "File '/node_modules/foo/@bar/index.js' exist - use it as a name resolution result.", diff --git a/tests/baselines/reference/objectRest.js b/tests/baselines/reference/objectRest.js index 3576ffb286c..c314377f807 100644 --- a/tests/baselines/reference/objectRest.js +++ b/tests/baselines/reference/objectRest.js @@ -85,10 +85,10 @@ var i = removable; var { removed } = i, removableRest2 = __rest(i, ["removed"]); let computed = 'b'; let computed2 = 'a'; -var _g = computed, stillNotGreat = o[_g], _h = computed2, soSo = o[_h], o = __rest(o, [typeof _g === "symbol" ? _g : _g + "", typeof _h === "symbol" ? _h : _h + ""]); -(_j = computed, stillNotGreat = o[_j], _k = computed2, soSo = o[_k], o = __rest(o, [typeof _j === "symbol" ? _j : _j + "", typeof _k === "symbol" ? _k : _k + ""])); +var _g = o, _h = computed, stillNotGreat = _g[_h], _j = computed2, soSo = _g[_j], o = __rest(_g, [typeof _h === "symbol" ? _h : _h + "", typeof _j === "symbol" ? _j : _j + ""]); +(_k = o, _l = computed, stillNotGreat = _k[_l], _m = computed2, soSo = _k[_m], o = __rest(_k, [typeof _l === "symbol" ? _l : _l + "", typeof _m === "symbol" ? _m : _m + ""])); var noContextualType = (_a) => { var { aNumber = 12 } = _a, notEmptyObject = __rest(_a, ["aNumber"]); return aNumber + notEmptyObject.anythingGoes; }; -var _d, _f, _j, _k; +var _d, _f, _k, _l, _m; diff --git a/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt b/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt index 88801e06dfd..f901d08b462 100644 --- a/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt +++ b/tests/baselines/reference/privacyCheckTypeOfFunction.errors.txt @@ -1,14 +1,11 @@ tests/cases/compiler/privacyCheckTypeOfFunction.ts(3,22): error TS4025: Exported variable 'x' has or is using private name 'foo'. -tests/cases/compiler/privacyCheckTypeOfFunction.ts(4,12): error TS4025: Exported variable 'b' has or is using private name 'foo'. -==== tests/cases/compiler/privacyCheckTypeOfFunction.ts (2 errors) ==== +==== tests/cases/compiler/privacyCheckTypeOfFunction.ts (1 errors) ==== function foo() { } export var x: typeof foo; ~~~ !!! error TS4025: Exported variable 'x' has or is using private name 'foo'. export var b = foo; - ~ -!!! error TS4025: Exported variable 'b' has or is using private name 'foo'. \ No newline at end of file diff --git a/tests/baselines/reference/strictFunctionTypes1.js b/tests/baselines/reference/strictFunctionTypes1.js index e802c443561..94ee06f88f8 100644 --- a/tests/baselines/reference/strictFunctionTypes1.js +++ b/tests/baselines/reference/strictFunctionTypes1.js @@ -15,6 +15,16 @@ const x1 = f1(fo, fs); // (x: string) => void const x2 = f2("abc", fo, fs); // "abc" const x3 = f3("abc", fo, fx); // "abc" | "def" const x4 = f4(fo, fs); // Func + +declare const never: never; + +const x10 = f2(never, fo, fs); // string +const x11 = f3(never, fo, fx); // "def" + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +let x = foo([]); // never //// [strictFunctionTypes1.js] @@ -23,6 +33,9 @@ var x1 = f1(fo, fs); // (x: string) => void var x2 = f2("abc", fo, fs); // "abc" var x3 = f3("abc", fo, fx); // "abc" | "def" var x4 = f4(fo, fs); // Func +var x10 = f2(never, fo, fs); // string +var x11 = f3(never, fo, fx); // "def" +var x = foo([]); // never //// [strictFunctionTypes1.d.ts] @@ -40,3 +53,8 @@ declare const x1: (x: string) => void; declare const x2 = "abc"; declare const x3: string; declare const x4: Func; +declare const never: never; +declare const x10: string; +declare const x11: "def"; +declare function foo(a: ReadonlyArray): T; +declare let x: never; diff --git a/tests/baselines/reference/strictFunctionTypes1.symbols b/tests/baselines/reference/strictFunctionTypes1.symbols index 70253411201..715ea287734 100644 --- a/tests/baselines/reference/strictFunctionTypes1.symbols +++ b/tests/baselines/reference/strictFunctionTypes1.symbols @@ -94,3 +94,34 @@ const x4 = f4(fo, fs); // Func >fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) >fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) +declare const never: never; +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) + +const x10 = f2(never, fo, fs); // string +>x10 : Symbol(x10, Decl(strictFunctionTypes1.ts, 19, 5)) +>f2 : Symbol(f2, Decl(strictFunctionTypes1.ts, 0, 79)) +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fs : Symbol(fs, Decl(strictFunctionTypes1.ts, 8, 37)) + +const x11 = f3(never, fo, fx); // "def" +>x11 : Symbol(x11, Decl(strictFunctionTypes1.ts, 20, 5)) +>f3 : Symbol(f3, Decl(strictFunctionTypes1.ts, 1, 74)) +>never : Symbol(never, Decl(strictFunctionTypes1.ts, 17, 13)) +>fo : Symbol(fo, Decl(strictFunctionTypes1.ts, 6, 58)) +>fx : Symbol(fx, Decl(strictFunctionTypes1.ts, 9, 37)) + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +>foo : Symbol(foo, Decl(strictFunctionTypes1.ts, 20, 30)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) +>a : Symbol(a, Decl(strictFunctionTypes1.ts, 24, 24)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) +>T : Symbol(T, Decl(strictFunctionTypes1.ts, 24, 21)) + +let x = foo([]); // never +>x : Symbol(x, Decl(strictFunctionTypes1.ts, 25, 3)) +>foo : Symbol(foo, Decl(strictFunctionTypes1.ts, 20, 30)) + diff --git a/tests/baselines/reference/strictFunctionTypes1.types b/tests/baselines/reference/strictFunctionTypes1.types index 9701d78cff0..b915e0b5f6b 100644 --- a/tests/baselines/reference/strictFunctionTypes1.types +++ b/tests/baselines/reference/strictFunctionTypes1.types @@ -100,3 +100,38 @@ const x4 = f4(fo, fs); // Func >fo : (x: Object) => void >fs : (x: string) => void +declare const never: never; +>never : never + +const x10 = f2(never, fo, fs); // string +>x10 : string +>f2(never, fo, fs) : string +>f2 : (obj: T, f1: (x: T) => void, f2: (x: T) => void) => T +>never : never +>fo : (x: Object) => void +>fs : (x: string) => void + +const x11 = f3(never, fo, fx); // "def" +>x11 : "def" +>f3(never, fo, fx) : "def" +>f3 : (obj: T, f1: (x: T) => void, f2: (f: (x: T) => void) => void) => T +>never : never +>fo : (x: Object) => void +>fx : (f: (x: "def") => void) => void + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +>foo : (a: ReadonlyArray) => T +>T : T +>a : ReadonlyArray +>ReadonlyArray : ReadonlyArray +>T : T +>T : T + +let x = foo([]); // never +>x : never +>foo([]) : never +>foo : (a: ReadonlyArray) => T +>[] : never[] + diff --git a/tests/baselines/reference/symbolProperty60.js b/tests/baselines/reference/symbolProperty60.js new file mode 100644 index 00000000000..d2a1ac92dd8 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.js @@ -0,0 +1,25 @@ +//// [symbolProperty60.ts] +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { + [Symbol.toStringTag]: string; + [key: string]: number; +} + +interface I2 { + [Symbol.toStringTag]: string; + [key: number]: boolean; +} + +declare const mySymbol: unique symbol; + +interface I3 { + [mySymbol]: string; + [key: string]: number; +} + +interface I4 { + [mySymbol]: string; + [key: number]: boolean; +} + +//// [symbolProperty60.js] diff --git a/tests/baselines/reference/symbolProperty60.symbols b/tests/baselines/reference/symbolProperty60.symbols new file mode 100644 index 00000000000..fca43277e97 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/es6/Symbols/symbolProperty60.ts === +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { +>I1 : Symbol(I1, Decl(symbolProperty60.ts, 0, 0)) + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [key: string]: number; +>key : Symbol(key, Decl(symbolProperty60.ts, 3, 5)) +} + +interface I2 { +>I2 : Symbol(I2, Decl(symbolProperty60.ts, 4, 1)) + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) +>toStringTag : Symbol(SymbolConstructor.toStringTag, Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + + [key: number]: boolean; +>key : Symbol(key, Decl(symbolProperty60.ts, 8, 5)) +} + +declare const mySymbol: unique symbol; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + +interface I3 { +>I3 : Symbol(I3, Decl(symbolProperty60.ts, 11, 38)) + + [mySymbol]: string; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + + [key: string]: number; +>key : Symbol(key, Decl(symbolProperty60.ts, 15, 5)) +} + +interface I4 { +>I4 : Symbol(I4, Decl(symbolProperty60.ts, 16, 1)) + + [mySymbol]: string; +>mySymbol : Symbol(mySymbol, Decl(symbolProperty60.ts, 11, 13)) + + [key: number]: boolean; +>key : Symbol(key, Decl(symbolProperty60.ts, 20, 5)) +} diff --git a/tests/baselines/reference/symbolProperty60.types b/tests/baselines/reference/symbolProperty60.types new file mode 100644 index 00000000000..c81c003bd35 --- /dev/null +++ b/tests/baselines/reference/symbolProperty60.types @@ -0,0 +1,48 @@ +=== tests/cases/conformance/es6/Symbols/symbolProperty60.ts === +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { +>I1 : I1 + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + [key: string]: number; +>key : string +} + +interface I2 { +>I2 : I2 + + [Symbol.toStringTag]: string; +>Symbol.toStringTag : symbol +>Symbol : SymbolConstructor +>toStringTag : symbol + + [key: number]: boolean; +>key : number +} + +declare const mySymbol: unique symbol; +>mySymbol : unique symbol + +interface I3 { +>I3 : I3 + + [mySymbol]: string; +>mySymbol : unique symbol + + [key: string]: number; +>key : string +} + +interface I4 { +>I4 : I4 + + [mySymbol]: string; +>mySymbol : unique symbol + + [key: number]: boolean; +>key : number +} diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js new file mode 100644 index 00000000000..4f102f14ed4 --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.js @@ -0,0 +1,10 @@ +//// [transformParenthesizesConditionalSubexpression.ts] +var K = 'k' +var a = { p : (true ? { [K] : 'v'} : null) } +var b = { p : (true ? { [K] : 'v'} as any : null) } + +//// [transformParenthesizesConditionalSubexpression.js] +var K = 'k'; +var a = { p: (true ? (_a = {}, _a[K] = 'v', _a) : null) }; +var b = { p: (true ? (_b = {}, _b[K] = 'v', _b) : null) }; +var _a, _b; diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols new file mode 100644 index 00000000000..d3ae64c40d5 --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts === +var K = 'k' +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + +var a = { p : (true ? { [K] : 'v'} : null) } +>a : Symbol(a, Decl(transformParenthesizesConditionalSubexpression.ts, 1, 3)) +>p : Symbol(p, Decl(transformParenthesizesConditionalSubexpression.ts, 1, 9)) +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + +var b = { p : (true ? { [K] : 'v'} as any : null) } +>b : Symbol(b, Decl(transformParenthesizesConditionalSubexpression.ts, 2, 3)) +>p : Symbol(p, Decl(transformParenthesizesConditionalSubexpression.ts, 2, 9)) +>K : Symbol(K, Decl(transformParenthesizesConditionalSubexpression.ts, 0, 3)) + diff --git a/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types new file mode 100644 index 00000000000..0ba4268d80a --- /dev/null +++ b/tests/baselines/reference/transformParenthesizesConditionalSubexpression.types @@ -0,0 +1,30 @@ +=== tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts === +var K = 'k' +>K : string +>'k' : "k" + +var a = { p : (true ? { [K] : 'v'} : null) } +>a : { p: { [x: string]: string; }; } +>{ p : (true ? { [K] : 'v'} : null) } : { p: { [x: string]: string; }; } +>p : { [x: string]: string; } +>(true ? { [K] : 'v'} : null) : { [x: string]: string; } +>true ? { [K] : 'v'} : null : { [x: string]: string; } +>true : true +>{ [K] : 'v'} : { [x: string]: string; } +>K : string +>'v' : "v" +>null : null + +var b = { p : (true ? { [K] : 'v'} as any : null) } +>b : { p: any; } +>{ p : (true ? { [K] : 'v'} as any : null) } : { p: any; } +>p : any +>(true ? { [K] : 'v'} as any : null) : any +>true ? { [K] : 'v'} as any : null : any +>true : true +>{ [K] : 'v'} as any : any +>{ [K] : 'v'} : { [x: string]: string; } +>K : string +>'v' : "v" +>null : null + diff --git a/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.js b/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.js new file mode 100644 index 00000000000..3e719abde5f --- /dev/null +++ b/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.js @@ -0,0 +1,14 @@ +//// [tests/cases/compiler/tripleSlashReferenceAbsoluteWindowsPath.ts] //// + +//// [c.ts] +const x = 5; + +//// [d.ts] +/// +const y = x + 3; + +//// [c.js] +var x = 5; +//// [d.js] +/// +var y = x + 3; diff --git a/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.symbols b/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.symbols new file mode 100644 index 00000000000..0a3b6aedc6b --- /dev/null +++ b/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.symbols @@ -0,0 +1,10 @@ +=== C:/a/b/d.ts === +/// +const y = x + 3; +>y : Symbol(y, Decl(d.ts, 1, 5)) +>x : Symbol(x, Decl(c.ts, 0, 5)) + +=== C:/a/b/c.ts === +const x = 5; +>x : Symbol(x, Decl(c.ts, 0, 5)) + diff --git a/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.types b/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.types new file mode 100644 index 00000000000..fdc37ae2faf --- /dev/null +++ b/tests/baselines/reference/tripleSlashReferenceAbsoluteWindowsPath.types @@ -0,0 +1,13 @@ +=== C:/a/b/d.ts === +/// +const y = x + 3; +>y : number +>x + 3 : number +>x : 5 +>3 : 3 + +=== C:/a/b/c.ts === +const x = 5; +>x : 5 +>5 : 5 + diff --git a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json index 26cf24cc2e4..cb57cd1366b 100644 --- a/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Default initialized TSConfig/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json index 5d7960c8254..6614dd9e48e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with boolean value compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json index 353cb68ea95..8c19ad58bed 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with enum value compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ "jsx": "react", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json index 4a28e6f2491..f5e2b163a21 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with files options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json index 46ae199430d..ced3eae17b8 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option value/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation: */ + "lib": ["es5","es2015.promise"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json index 26cf24cc2e4..cb57cd1366b 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with incorrect compiler option/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json index 069305e2d35..1356e2258f7 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options with enum value/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation: */ + "lib": ["es5","es2015.core"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json index 9e1c409f56e..473280f675e 100644 --- a/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json +++ b/tests/baselines/reference/tsConfig/Initialized TSConfig with list compiler options/tsconfig.json @@ -3,7 +3,7 @@ /* Basic Options */ "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ - // "lib": [], /* Specify library files to be included in the compilation: */ + // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt index 2e502868093..ec6e70cc4a1 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentsWithTypeArguments4.errors.txt @@ -3,7 +3,7 @@ tests/cases/conformance/jsx/file.tsx(9,33): error TS2322: Type '{ a: number; }' Property 'b' is missing in type '{ a: number; }'. tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type 'T & { ignore-prop: true; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: {}; }'. Type 'T & { ignore-prop: true; }' is not assignable to type '{ b: {}; a: {}; }'. - Property 'a' is missing in type 'T & { ignore-prop: true; }'. + Property 'a' is missing in type '{ b: number; } & { ignore-prop: true; }'. ==== tests/cases/conformance/jsx/file.tsx (2 errors) ==== @@ -24,5 +24,5 @@ tests/cases/conformance/jsx/file.tsx(10,33): error TS2322: Type 'T & { ignore-pr ~~~~~~~~~~~~~~~~~~~~~ !!! error TS2322: Type 'T & { ignore-prop: true; }' is not assignable to type 'IntrinsicAttributes & { b: {}; a: {}; }'. !!! error TS2322: Type 'T & { ignore-prop: true; }' is not assignable to type '{ b: {}; a: {}; }'. -!!! error TS2322: Property 'a' is missing in type 'T & { ignore-prop: true; }'. +!!! error TS2322: Property 'a' is missing in type '{ b: number; } & { ignore-prop: true; }'. } \ No newline at end of file diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny.errors.txt b/tests/baselines/reference/untypedModuleImport_noImplicitAny.errors.txt index 0f451941bd7..5137ea4ae5f 100644 --- a/tests/baselines/reference/untypedModuleImport_noImplicitAny.errors.txt +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny.errors.txt @@ -8,8 +8,11 @@ !!! error TS7016: Could not find a declaration file for module 'foo'. '/node_modules/foo/index.js' implicitly has an 'any' type. !!! error TS7016: Try `npm install @types/foo` if it exists or add a new declaration (.d.ts) file containing `declare module 'foo';` -==== /node_modules/foo/index.js (0 errors) ==== +==== /node_modules/foo/package.json (0 errors) ==== // This tests that `--noImplicitAny` disables untyped modules. + { "name": "foo", "version": "1.2.3" } + +==== /node_modules/foo/index.js (0 errors) ==== This file is not processed. \ No newline at end of file diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny.js b/tests/baselines/reference/untypedModuleImport_noImplicitAny.js index 86e2ae3c175..378ebee6d7a 100644 --- a/tests/baselines/reference/untypedModuleImport_noImplicitAny.js +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny.js @@ -1,8 +1,11 @@ //// [tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny.ts] //// -//// [index.js] +//// [package.json] // This tests that `--noImplicitAny` disables untyped modules. +{ "name": "foo", "version": "1.2.3" } + +//// [index.js] This file is not processed. //// [a.ts] diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.errors.txt b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.errors.txt new file mode 100644 index 00000000000..1aeb8489b8d --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.errors.txt @@ -0,0 +1,16 @@ +/a.ts(1,22): error TS7016: Could not find a declaration file for module './node_modules/foo'. '/node_modules/foo/index.js' implicitly has an 'any' type. + Try `npm install @types/foo` if it exists or add a new declaration (.d.ts) file containing `declare module 'foo';` + + +==== /a.ts (1 errors) ==== + import * as foo from "./node_modules/foo"; + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS7016: Could not find a declaration file for module './node_modules/foo'. '/node_modules/foo/index.js' implicitly has an 'any' type. +!!! error TS7016: Try `npm install @types/foo` if it exists or add a new declaration (.d.ts) file containing `declare module 'foo';` + +==== /node_modules/foo/package.json (0 errors) ==== + { "name": "foo", "version": "1.2.3" } + +==== /node_modules/foo/index.js (0 errors) ==== + This file is not processed. + \ No newline at end of file diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.js b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.js new file mode 100644 index 00000000000..7e8c52a3bfb --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.js @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_relativePath.ts] //// + +//// [package.json] +{ "name": "foo", "version": "1.2.3" } + +//// [index.js] +This file is not processed. + +//// [a.ts] +import * as foo from "./node_modules/foo"; + + +//// [a.js] +"use strict"; +exports.__esModule = true; diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.symbols b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.symbols new file mode 100644 index 00000000000..0b9aff6bbef --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.symbols @@ -0,0 +1,4 @@ +=== /a.ts === +import * as foo from "./node_modules/foo"; +>foo : Symbol(foo, Decl(a.ts, 0, 6)) + diff --git a/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.types b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.types new file mode 100644 index 00000000000..d9b7333550d --- /dev/null +++ b/tests/baselines/reference/untypedModuleImport_noImplicitAny_relativePath.types @@ -0,0 +1,4 @@ +=== /a.ts === +import * as foo from "./node_modules/foo"; +>foo : any + diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.js b/tests/baselines/reference/useObjectValuesAndEntries1.js index a10fb9a2d32..7b18fb1fcd9 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.js +++ b/tests/baselines/reference/useObjectValuesAndEntries1.js @@ -5,11 +5,30 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); -var entries1 = Object.entries(1); -var entries2 = Object.entries({a: true, b: 2}) -var entries3 = Object.entries({}) - +var entries = Object.entries(o); // [string, number][] +var values = Object.values(o); // number[] + +var entries1 = Object.entries(1); // [string, any][] +var values1 = Object.values(1); // any[] + +var entries2 = Object.entries({ a: true, b: 2 }); // [string, number|boolean][] +var values2 = Object.values({ a: true, b: 2 }); // (number|boolean)[] + +var entries3 = Object.entries({}); // [string, {}][] +var values3 = Object.values({}); // {}[] + +var a = ["a", "b", "c"]; +var entries4 = Object.entries(a); // [string, string][] +var values4 = Object.values(a); // string[] + +enum E { A, B } +var entries5 = Object.entries(E); // [string, any][] +var values5 = Object.values(E); // any[] + +interface I { } +var i: I = {}; +var entries6 = Object.entries(i); // [string, any][] +var values6 = Object.values(i); // any[] //// [useObjectValuesAndEntries1.js] var o = { a: 1, b: 2 }; @@ -17,7 +36,24 @@ for (var _i = 0, _a = Object.values(o); _i < _a.length; _i++) { var x = _a[_i]; var y = x; } -var entries = Object.entries(o); -var entries1 = Object.entries(1); -var entries2 = Object.entries({ a: true, b: 2 }); -var entries3 = Object.entries({}); +var entries = Object.entries(o); // [string, number][] +var values = Object.values(o); // number[] +var entries1 = Object.entries(1); // [string, any][] +var values1 = Object.values(1); // any[] +var entries2 = Object.entries({ a: true, b: 2 }); // [string, number|boolean][] +var values2 = Object.values({ a: true, b: 2 }); // (number|boolean)[] +var entries3 = Object.entries({}); // [string, {}][] +var values3 = Object.values({}); // {}[] +var a = ["a", "b", "c"]; +var entries4 = Object.entries(a); // [string, string][] +var values4 = Object.values(a); // string[] +var E; +(function (E) { + E[E["A"] = 0] = "A"; + E[E["B"] = 1] = "B"; +})(E || (E = {})); +var entries5 = Object.entries(E); // [string, any][] +var values5 = Object.values(E); // any[] +var i = {}; +var entries6 = Object.entries(i); // [string, any][] +var values6 = Object.values(i); // any[] diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.symbols b/tests/baselines/reference/useObjectValuesAndEntries1.symbols index 538e3f69d78..ee9adbdac8f 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.symbols +++ b/tests/baselines/reference/useObjectValuesAndEntries1.symbols @@ -16,30 +16,114 @@ for (var x of Object.values(o)) { >x : Symbol(x, Decl(useObjectValuesAndEntries1.ts, 2, 8)) } -var entries = Object.entries(o); +var entries = Object.entries(o); // [string, number][] >entries : Symbol(entries, Decl(useObjectValuesAndEntries1.ts, 6, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >o : Symbol(o, Decl(useObjectValuesAndEntries1.ts, 0, 3)) -var entries1 = Object.entries(1); ->entries1 : Symbol(entries1, Decl(useObjectValuesAndEntries1.ts, 7, 3)) +var values = Object.values(o); // number[] +>values : Symbol(values, Decl(useObjectValuesAndEntries1.ts, 7, 3)) +>Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>o : Symbol(o, Decl(useObjectValuesAndEntries1.ts, 0, 3)) + +var entries1 = Object.entries(1); // [string, any][] +>entries1 : Symbol(entries1, Decl(useObjectValuesAndEntries1.ts, 9, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) -var entries2 = Object.entries({a: true, b: 2}) ->entries2 : Symbol(entries2, Decl(useObjectValuesAndEntries1.ts, 8, 3)) +var values1 = Object.values(1); // any[] +>values1 : Symbol(values1, Decl(useObjectValuesAndEntries1.ts, 10, 3)) +>Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) + +var entries2 = Object.entries({ a: true, b: 2 }); // [string, number|boolean][] +>entries2 : Symbol(entries2, Decl(useObjectValuesAndEntries1.ts, 12, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) ->a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 8, 31)) ->b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 8, 39)) +>a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 12, 31)) +>b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 12, 40)) -var entries3 = Object.entries({}) ->entries3 : Symbol(entries3, Decl(useObjectValuesAndEntries1.ts, 9, 3)) +var values2 = Object.values({ a: true, b: 2 }); // (number|boolean)[] +>values2 : Symbol(values2, Decl(useObjectValuesAndEntries1.ts, 13, 3)) +>Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 13, 29)) +>b : Symbol(b, Decl(useObjectValuesAndEntries1.ts, 13, 38)) + +var entries3 = Object.entries({}); // [string, {}][] +>entries3 : Symbol(entries3, Decl(useObjectValuesAndEntries1.ts, 15, 3)) >Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) >Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +var values3 = Object.values({}); // {}[] +>values3 : Symbol(values3, Decl(useObjectValuesAndEntries1.ts, 16, 3)) +>Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) + +var a = ["a", "b", "c"]; +>a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 18, 3)) + +var entries4 = Object.entries(a); // [string, string][] +>entries4 : Symbol(entries4, Decl(useObjectValuesAndEntries1.ts, 19, 3)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 18, 3)) + +var values4 = Object.values(a); // string[] +>values4 : Symbol(values4, Decl(useObjectValuesAndEntries1.ts, 20, 3)) +>Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>a : Symbol(a, Decl(useObjectValuesAndEntries1.ts, 18, 3)) + +enum E { A, B } +>E : Symbol(E, Decl(useObjectValuesAndEntries1.ts, 20, 31)) +>A : Symbol(E.A, Decl(useObjectValuesAndEntries1.ts, 22, 8)) +>B : Symbol(E.B, Decl(useObjectValuesAndEntries1.ts, 22, 11)) + +var entries5 = Object.entries(E); // [string, any][] +>entries5 : Symbol(entries5, Decl(useObjectValuesAndEntries1.ts, 23, 3)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>E : Symbol(E, Decl(useObjectValuesAndEntries1.ts, 20, 31)) + +var values5 = Object.values(E); // any[] +>values5 : Symbol(values5, Decl(useObjectValuesAndEntries1.ts, 24, 3)) +>Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>E : Symbol(E, Decl(useObjectValuesAndEntries1.ts, 20, 31)) + +interface I { } +>I : Symbol(I, Decl(useObjectValuesAndEntries1.ts, 24, 31)) + +var i: I = {}; +>i : Symbol(i, Decl(useObjectValuesAndEntries1.ts, 27, 3)) +>I : Symbol(I, Decl(useObjectValuesAndEntries1.ts, 24, 31)) + +var entries6 = Object.entries(i); // [string, any][] +>entries6 : Symbol(entries6, Decl(useObjectValuesAndEntries1.ts, 28, 3)) +>Object.entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>entries : Symbol(ObjectConstructor.entries, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>i : Symbol(i, Decl(useObjectValuesAndEntries1.ts, 27, 3)) + +var values6 = Object.values(i); // any[] +>values6 : Symbol(values6, Decl(useObjectValuesAndEntries1.ts, 29, 3)) +>Object.values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>values : Symbol(ObjectConstructor.values, Decl(lib.es2017.object.d.ts, --, --), Decl(lib.es2017.object.d.ts, --, --)) +>i : Symbol(i, Decl(useObjectValuesAndEntries1.ts, 27, 3)) + diff --git a/tests/baselines/reference/useObjectValuesAndEntries1.types b/tests/baselines/reference/useObjectValuesAndEntries1.types index c52d0ce872e..60ad86bcb43 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries1.types +++ b/tests/baselines/reference/useObjectValuesAndEntries1.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >o : { a: number; b: number; } let y = x; @@ -20,39 +20,143 @@ for (var x of Object.values(o)) { >x : number } -var entries = Object.entries(o); +var entries = Object.entries(o); // [string, number][] >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >o : { a: number; b: number; } -var entries1 = Object.entries(1); +var values = Object.values(o); // number[] +>values : number[] +>Object.values(o) : number[] +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>Object : ObjectConstructor +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>o : { a: number; b: number; } + +var entries1 = Object.entries(1); // [string, any][] >entries1 : [string, any][] >Object.entries(1) : [string, any][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >1 : 1 -var entries2 = Object.entries({a: true, b: 2}) ->entries2 : [string, number | boolean][] ->Object.entries({a: true, b: 2}) : [string, number | boolean][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +var values1 = Object.values(1); // any[] +>values1 : any[] +>Object.values(1) : any[] +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } ->{a: true, b: 2} : { a: boolean; b: number; } +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>1 : 1 + +var entries2 = Object.entries({ a: true, b: 2 }); // [string, number|boolean][] +>entries2 : [string, number | boolean][] +>Object.entries({ a: true, b: 2 }) : [string, number | boolean][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>{ a: true, b: 2 } : { a: boolean; b: number; } >a : boolean >true : true >b : number >2 : 2 -var entries3 = Object.entries({}) +var values2 = Object.values({ a: true, b: 2 }); // (number|boolean)[] +>values2 : (number | boolean)[] +>Object.values({ a: true, b: 2 }) : (number | boolean)[] +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>Object : ObjectConstructor +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>{ a: true, b: 2 } : { a: boolean; b: number; } +>a : boolean +>true : true +>b : number +>2 : 2 + +var entries3 = Object.entries({}); // [string, {}][] >entries3 : [string, {}][] >Object.entries({}) : [string, {}][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >{} : {} +var values3 = Object.values({}); // {}[] +>values3 : {}[] +>Object.values({}) : {}[] +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>Object : ObjectConstructor +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>{} : {} + +var a = ["a", "b", "c"]; +>a : string[] +>["a", "b", "c"] : string[] +>"a" : "a" +>"b" : "b" +>"c" : "c" + +var entries4 = Object.entries(a); // [string, string][] +>entries4 : [string, string][] +>Object.entries(a) : [string, string][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>a : string[] + +var values4 = Object.values(a); // string[] +>values4 : string[] +>Object.values(a) : string[] +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>Object : ObjectConstructor +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>a : string[] + +enum E { A, B } +>E : E +>A : E.A +>B : E.B + +var entries5 = Object.entries(E); // [string, any][] +>entries5 : [string, any][] +>Object.entries(E) : [string, any][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>E : typeof E + +var values5 = Object.values(E); // any[] +>values5 : any[] +>Object.values(E) : any[] +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>Object : ObjectConstructor +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>E : typeof E + +interface I { } +>I : I + +var i: I = {}; +>i : I +>I : I +>{} : {} + +var entries6 = Object.entries(i); // [string, any][] +>entries6 : [string, any][] +>Object.entries(i) : [string, any][] +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>Object : ObjectConstructor +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } +>i : I + +var values6 = Object.values(i); // any[] +>values6 : any[] +>Object.values(i) : any[] +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>Object : ObjectConstructor +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } +>i : I + diff --git a/tests/baselines/reference/useObjectValuesAndEntries4.types b/tests/baselines/reference/useObjectValuesAndEntries4.types index 33a427760a8..58aac10e52b 100644 --- a/tests/baselines/reference/useObjectValuesAndEntries4.types +++ b/tests/baselines/reference/useObjectValuesAndEntries4.types @@ -10,9 +10,9 @@ var o = { a: 1, b: 2 }; for (var x of Object.values(o)) { >x : number >Object.values(o) : number[] ->Object.values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } +>Object.values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >Object : ObjectConstructor ->values : { (o: { [s: string]: T; } | { [n: number]: T; }): T[]; (o: {}): any[]; } +>values : { (o: { [s: string]: T; } | ArrayLike): T[]; (o: {}): any[]; } >o : { a: number; b: number; } let y = x; @@ -23,8 +23,8 @@ for (var x of Object.values(o)) { var entries = Object.entries(o); >entries : [string, number][] >Object.entries(o) : [string, number][] ->Object.entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>Object.entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >Object : ObjectConstructor ->entries : { (o: { [s: string]: T; } | { [n: number]: T; }): [string, T][]; (o: {}): [string, any][]; } +>entries : { (o: { [s: string]: T; } | ArrayLike): [string, T][]; (o: {}): [string, any][]; } >o : { a: number; b: number; } diff --git a/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts b/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts new file mode 100644 index 00000000000..8d70a435e4d --- /dev/null +++ b/tests/cases/compiler/declarationFunctionTypeNonlocalShouldNotBeAnError.ts @@ -0,0 +1,8 @@ +// @declaration: true +namespace foo { + function bar(): void {} + + export const obj = { + bar + } +} diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts new file mode 100644 index 00000000000..02ae0c58d02 --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "foo"; +export const o: C; + +// @Filename: /node_modules/foo/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/foo/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/foo/package.json +{ + "name": "foo", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "foo/use"; +import { o } from "a"; + +use(o); diff --git a/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts new file mode 100644 index 00000000000..5ccf69a5a8d --- /dev/null +++ b/tests/cases/compiler/duplicatePackage_relativeImportWithinPackage_scoped.ts @@ -0,0 +1,38 @@ +// @noImplicitReferences: true +// @traceResolution: true + +// @Filename: /node_modules/a/node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /node_modules/a/node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/a/index.d.ts +import { C } from "@foo/bar"; +export const o: C; + +// @Filename: /node_modules/@foo/bar/use.d.ts +import { C } from "./index"; +export function use(o: C): void; + +// @Filename: /node_modules/@foo/bar/index.d.ts +export class C { + private x: number; +} + +// @Filename: /node_modules/@foo/bar/package.json +{ + "name": "@foo/bar", + "version": "1.2.3" +} + +// @Filename: /index.ts +import { use } from "@foo/bar/use"; +import { o } from "a"; + +use(o); diff --git a/tests/cases/compiler/intersectionOfTypeVariableHasApparentSignatures.ts b/tests/cases/compiler/intersectionOfTypeVariableHasApparentSignatures.ts new file mode 100644 index 00000000000..7bfaaed10c5 --- /dev/null +++ b/tests/cases/compiler/intersectionOfTypeVariableHasApparentSignatures.ts @@ -0,0 +1,17 @@ +// @strictNullChecks: true +// @noImplicitAny: true +interface Component

{ + props: Readonly

& Readonly<{ children?: {} }>; +} + +interface Props { + children?: (items: {x: number}) => void +} + +declare function f(i: Component): void; + +f({ + props: { + children: (({ x }) => { }) + } +}); \ No newline at end of file diff --git a/tests/cases/compiler/jsxCallbackWithDestructuring.tsx b/tests/cases/compiler/jsxCallbackWithDestructuring.tsx new file mode 100644 index 00000000000..c89ff5279c3 --- /dev/null +++ b/tests/cases/compiler/jsxCallbackWithDestructuring.tsx @@ -0,0 +1,31 @@ +// @jsx: preserve +// @noImplicitAny: true +// @strictNullChecks: true + + +// minimal component +interface Component

{ } +declare class Component { + constructor(props: P, context?: any); + render(): {}; + props: Readonly<{ children?: {} }> & Readonly

; +} + +declare global { + namespace JSX { + interface Element { } + interface ElementClass { + render(): {}; + } + interface ElementAttributesProperty { props: {}; } + interface ElementChildrenAttribute { children: {}; } + interface IntrinsicAttributes { } + interface IntrinsicClassAttributes { } + } +} + +export interface RouteProps { + children?: (props: { x: number }) => any; +} +export class MyComponent extends Component { } + {}}/> \ No newline at end of file diff --git a/tests/cases/compiler/strictFunctionTypes1.ts b/tests/cases/compiler/strictFunctionTypes1.ts index 6c07bc51ffe..ad8836fcf05 100644 --- a/tests/cases/compiler/strictFunctionTypes1.ts +++ b/tests/cases/compiler/strictFunctionTypes1.ts @@ -17,3 +17,13 @@ const x1 = f1(fo, fs); // (x: string) => void const x2 = f2("abc", fo, fs); // "abc" const x3 = f3("abc", fo, fx); // "abc" | "def" const x4 = f4(fo, fs); // Func + +declare const never: never; + +const x10 = f2(never, fo, fs); // string +const x11 = f3(never, fo, fx); // "def" + +// Repro from #21112 + +declare function foo(a: ReadonlyArray): T; +let x = foo([]); // never diff --git a/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts b/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts new file mode 100644 index 00000000000..d844a910279 --- /dev/null +++ b/tests/cases/compiler/transformParenthesizesConditionalSubexpression.ts @@ -0,0 +1,4 @@ +// @target: es5 +var K = 'k' +var a = { p : (true ? { [K] : 'v'} : null) } +var b = { p : (true ? { [K] : 'v'} as any : null) } \ No newline at end of file diff --git a/tests/cases/compiler/tripleSlashReferenceAbsoluteWindowsPath.ts b/tests/cases/compiler/tripleSlashReferenceAbsoluteWindowsPath.ts new file mode 100644 index 00000000000..b45e2a52b65 --- /dev/null +++ b/tests/cases/compiler/tripleSlashReferenceAbsoluteWindowsPath.ts @@ -0,0 +1,6 @@ +//@Filename: C:\a\b\c.ts +const x = 5; + +//@Filename: C:\a\b\d.ts +/// +const y = x + 3; \ No newline at end of file diff --git a/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts b/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts new file mode 100644 index 00000000000..222718122ef --- /dev/null +++ b/tests/cases/conformance/async/es5/asyncAwaitNestedClasses_es5.ts @@ -0,0 +1,18 @@ +// @target: ES5 +// @lib: es5,es2015.promise +// @noEmitHelpers: true +// https://github.com/Microsoft/TypeScript/issues/20744 +class A { + static B = class B { + static func2(): Promise { + return new Promise((resolve) => { resolve(null); }); + } + static C = class C { + static async func() { + await B.func2(); + } + } + } +} + +A.B.C.func(); \ No newline at end of file diff --git a/tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts b/tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts new file mode 100644 index 00000000000..9083246dd18 --- /dev/null +++ b/tests/cases/conformance/async/es6/asyncWithVarShadowing_es6.ts @@ -0,0 +1,223 @@ +// @target: es2015 +// @noEmitHelpers: true +// https://github.com/Microsoft/TypeScript/issues/20461 +declare const y: any; + +async function fn1(x) { + var x; +} + +async function fn2(x) { + var x, z; +} + +async function fn3(x) { + var z; +} + +async function fn4(x) { + var x = y; +} + +async function fn5(x) { + var { x } = y; +} + +async function fn6(x) { + var { x, z } = y; +} + +async function fn7(x) { + var { x = y } = y; +} + +async function fn8(x) { + var { z: x } = y; +} + +async function fn9(x) { + var { z: { x } } = y; +} + +async function fn10(x) { + var { z: { x } = y } = y; +} + +async function fn11(x) { + var { ...x } = y; +} + +async function fn12(x) { + var [x] = y; +} + +async function fn13(x) { + var [x = y] = y; +} + +async function fn14(x) { + var [, x] = y; +} + +async function fn15(x) { + var [...x] = y; +} + +async function fn16(x) { + var [[x]] = y; +} + +async function fn17(x) { + var [[x] = y] = y; +} + +async function fn18({ x }) { + var x; +} + +async function fn19([x]) { + var x; +} + +async function fn20(x) { + { + var x; + } +} + +async function fn21(x) { + if (y) { + var x; + } +} + +async function fn22(x) { + if (y) { + } + else { + var x; + } +} + +async function fn23(x) { + try { + var x; + } + catch (e) { + } +} + +async function fn24(x) { + try { + + } + catch (e) { + var x; + } +} + +async function fn25(x) { + try { + + } + catch (x) { + var x; + } +} + +async function fn26(x) { + try { + + } + catch ({ x }) { + var x; + } +} + +async function fn27(x) { + try { + } + finally { + var x; + } +} + +async function fn28(x) { + while (y) { + var x; + } +} + +async function fn29(x) { + do { + var x; + } + while (y); +} + +async function fn30(x) { + for (var x = y;;) { + + } +} + +async function fn31(x) { + for (var { x } = y;;) { + } +} + +async function fn32(x) { + for (;;) { + var x; + } +} + +async function fn33(x: string) { + for (var x in y) { + } +} + +async function fn34(x) { + for (var z in y) { + var x; + } +} + +async function fn35(x) { + for (var x of y) { + } +} + +async function fn36(x) { + for (var { x } of y) { + } +} + +async function fn37(x) { + for (var z of y) { + var x; + } +} + +async function fn38(x) { + switch (y) { + case y: + var x; + } +} + +async function fn39(x) { + foo: { + var x; + break foo; + } +} + +async function fn40(x) { + try { + + } + catch { + var x; + } +} diff --git a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts index 719f10bbbcc..7422826be16 100644 --- a/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts +++ b/tests/cases/conformance/es2017/useObjectValuesAndEntries1.ts @@ -7,7 +7,27 @@ for (var x of Object.values(o)) { let y = x; } -var entries = Object.entries(o); -var entries1 = Object.entries(1); -var entries2 = Object.entries({a: true, b: 2}) -var entries3 = Object.entries({}) +var entries = Object.entries(o); // [string, number][] +var values = Object.values(o); // number[] + +var entries1 = Object.entries(1); // [string, any][] +var values1 = Object.values(1); // any[] + +var entries2 = Object.entries({ a: true, b: 2 }); // [string, number|boolean][] +var values2 = Object.values({ a: true, b: 2 }); // (number|boolean)[] + +var entries3 = Object.entries({}); // [string, {}][] +var values3 = Object.values({}); // {}[] + +var a = ["a", "b", "c"]; +var entries4 = Object.entries(a); // [string, string][] +var values4 = Object.values(a); // string[] + +enum E { A, B } +var entries5 = Object.entries(E); // [string, any][] +var values5 = Object.values(E); // any[] + +interface I { } +var i: I = {}; +var entries6 = Object.entries(i); // [string, any][] +var values6 = Object.values(i); // any[] \ No newline at end of file diff --git a/tests/cases/conformance/es6/Symbols/symbolProperty60.ts b/tests/cases/conformance/es6/Symbols/symbolProperty60.ts new file mode 100644 index 00000000000..4086223f69c --- /dev/null +++ b/tests/cases/conformance/es6/Symbols/symbolProperty60.ts @@ -0,0 +1,23 @@ +// @target: es2015 +// https://github.com/Microsoft/TypeScript/issues/20146 +interface I1 { + [Symbol.toStringTag]: string; + [key: string]: number; +} + +interface I2 { + [Symbol.toStringTag]: string; + [key: number]: boolean; +} + +declare const mySymbol: unique symbol; + +interface I3 { + [mySymbol]: string; + [key: string]: number; +} + +interface I4 { + [mySymbol]: string; + [key: number]: boolean; +} \ No newline at end of file diff --git a/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts b/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts new file mode 100644 index 00000000000..042ed5d5248 --- /dev/null +++ b/tests/cases/conformance/es6/destructuring/destructuringReassignsRightHandSide.ts @@ -0,0 +1,9 @@ +// @target: es5 +var foo: any = { foo: 1, bar: 2 }; +var bar: any; + +// reassignment in destructuring pattern +({ foo, bar } = foo); + +// reassignment in subsequent var +var { foo, baz } = foo; \ No newline at end of file diff --git a/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny.ts b/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny.ts index 1aee7c069de..39208624a72 100644 --- a/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny.ts +++ b/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny.ts @@ -1,8 +1,10 @@ // @noImplicitReferences: true -// @currentDirectory: / // @noImplicitAny: true // This tests that `--noImplicitAny` disables untyped modules. +// @filename: /node_modules/foo/package.json +{ "name": "foo", "version": "1.2.3" } + // @filename: /node_modules/foo/index.js This file is not processed. diff --git a/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_relativePath.ts b/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_relativePath.ts new file mode 100644 index 00000000000..ae38be5dfa0 --- /dev/null +++ b/tests/cases/conformance/moduleResolution/untypedModuleImport_noImplicitAny_relativePath.ts @@ -0,0 +1,11 @@ +// @noImplicitReferences: true +// @noImplicitAny: true + +// @filename: /node_modules/foo/package.json +{ "name": "foo", "version": "1.2.3" } + +// @filename: /node_modules/foo/index.js +This file is not processed. + +// @filename: /a.ts +import * as foo from "./node_modules/foo"; diff --git a/tests/cases/fourslash/completionListInScope.ts b/tests/cases/fourslash/completionListInScope.ts index 8773f6d4588..70f82b80f5f 100644 --- a/tests/cases/fourslash/completionListInScope.ts +++ b/tests/cases/fourslash/completionListInScope.ts @@ -13,7 +13,7 @@ //// interface localInterface {} //// export interface exportedInterface {} //// -//// module localModule { +//// module localModule { //// export var x = 0; //// } //// export module exportedModule { @@ -38,7 +38,7 @@ //// interface localInterface2 {} //// export interface exportedInterface2 {} //// -//// module localModule2 { +//// module localModule2 { //// export var x = 0; //// } //// export module exportedModule2 { diff --git a/tests/cases/fourslash/completionsOptionalMethod.ts b/tests/cases/fourslash/completionsOptionalMethod.ts new file mode 100644 index 00000000000..72399f177f2 --- /dev/null +++ b/tests/cases/fourslash/completionsOptionalMethod.ts @@ -0,0 +1,8 @@ +/// + +// @strictNullChecks: true + +////declare const x: { m?(): void }; +////x./**/ + +verify.completionsAt("", ["m"]); diff --git a/tests/cases/fourslash/completionsThisType.ts b/tests/cases/fourslash/completionsThisType.ts new file mode 100644 index 00000000000..58325182a22 --- /dev/null +++ b/tests/cases/fourslash/completionsThisType.ts @@ -0,0 +1,29 @@ +/// + +////class C { +//// "foo bar": number; +//// xyz() { +//// /**/ +//// } +////} +//// +////function f(this: { x: number }) { /*f*/ } + +goTo.marker(""); + +verify.completionListContains("xyz", "(method) C.xyz(): void", "", "method", undefined, undefined, { + includeInsertTextCompletions: true, + insertText: "this.xyz", +}); + +verify.completionListContains("foo bar", '(property) C["foo bar"]: number', "", "property", undefined, undefined, { + includeInsertTextCompletions: true, + insertText: 'this["foo bar"]', +}); + +goTo.marker("f"); + +verify.completionListContains("x", "(property) x: number", "", "property", undefined, undefined, { + includeInsertTextCompletions: true, + insertText: "this.x", +}); diff --git a/tests/cases/fourslash/formatObjectBindingPattern.ts b/tests/cases/fourslash/formatObjectBindingPattern.ts new file mode 100644 index 00000000000..f17bb17c3c8 --- /dev/null +++ b/tests/cases/fourslash/formatObjectBindingPattern.ts @@ -0,0 +1,14 @@ +/// + +////const { +////x, +////y, +////} = 0; + +format.document(); +verify.currentFileContentIs( +`const { + x, + y, +} = 0;` +); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 97379957cbf..0bf62eaef92 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -151,7 +151,13 @@ declare namespace FourSlashInterface { kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, - options?: { includeExternalModuleExports?: boolean, sourceDisplay?: string, isRecommended?: true }, + options?: { + includeExternalModuleExports?: boolean, + includeInsertTextCompletions?: boolean, + sourceDisplay?: string, + isRecommended?: true, + insertText?: string, + }, ): void; completionListItemsCountIsGreaterThan(count: number): void; completionListIsEmpty(): void; diff --git a/tests/cases/fourslash/unusedParameterInLambda1.ts b/tests/cases/fourslash/unusedParameterInLambda1.ts index ace79adae46..fdb53a8a05f 100644 --- a/tests/cases/fourslash/unusedParameterInLambda1.ts +++ b/tests/cases/fourslash/unusedParameterInLambda1.ts @@ -2,12 +2,11 @@ // @noUnusedLocals: true // @noUnusedParameters: true -//// function f1() { -//// [|return (x:number) => {}|] -//// } +////[|/*~a*/(/*~b*/x/*~c*/:/*~d*/number/*~e*/)/*~f*/ => /*~g*/{/*~h*/}/*~i*/|] +// In a perfect world, /*~f*/ and /*~h*/ would probably be retained. verify.codeFix({ description: "Remove declaration for: 'x'", index: 0, - newRangeContent: "return () => {}", + newRangeContent: "/*~a*/() => /*~g*/ { }/*~i*/", }); diff --git a/tests/cases/fourslash/unusedParameterInLambda2.ts b/tests/cases/fourslash/unusedParameterInLambda2.ts new file mode 100644 index 00000000000..e2b1be346b8 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInLambda2.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////[|/*~a*/x/*~b*/ /*~c*/=>/*~d*/ {/*~e*/}/*~f*/|] + +// In a perfect world, /*~c*/ and /*~e*/ would probably be retained. +verify.codeFix({ + description: "Remove declaration for: 'x'", + index: 0, + newRangeContent: "/*~a*/() => /*~d*/ { }/*~f*/", +}); diff --git a/tests/cases/fourslash/unusedParameterInLambda3.ts b/tests/cases/fourslash/unusedParameterInLambda3.ts new file mode 100644 index 00000000000..f95d142d436 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInLambda3.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////[|/*~a*/(/*~b*/x/*~c*/,/*~d*/y/*~e*/)/*~f*/ => /*~g*/x/*~h*/|] + +// In a perfect world, /*~c*/ would probably be retained, rather than /*~e*/. +verify.codeFix({ + description: "Remove declaration for: 'y'", + index: 0, + newRangeContent: "/*~a*/(/*~b*/x/*~e*/)/*~f*/ => /*~g*/x/*~h*/", +}); diff --git a/tests/cases/fourslash/unusedParameterInLambda4.ts b/tests/cases/fourslash/unusedParameterInLambda4.ts new file mode 100644 index 00000000000..015f081891a --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInLambda4.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////[|/*~a*/(/*~b*/x/*~c*/,/*~d*/y/*~e*/)/*~f*/ => /*~g*/y/*~h*/|] + +verify.codeFix({ + description: "Remove declaration for: 'x'", + index: 0, + newRangeContent: "/*~a*/(/*~d*/y/*~e*/)/*~f*/ => /*~g*/y/*~h*/", +});