mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-12-10 00:20:22 -06:00
Include source node inferences in string literal completions deeper in arguments (#56182)
This commit is contained in:
parent
b2327c0f19
commit
69a0879743
@ -32706,7 +32706,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return getContextualTypeForAwaitOperand(parent as AwaitExpression, contextFlags);
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.NewExpression:
|
||||
return getContextualTypeForArgument(parent as CallExpression | NewExpression | Decorator, node);
|
||||
return getContextualTypeForArgument(parent as CallExpression | NewExpression, node);
|
||||
case SyntaxKind.Decorator:
|
||||
return getContextualTypeForDecorator(parent as Decorator);
|
||||
case SyntaxKind.TypeAssertionExpression:
|
||||
|
||||
@ -91,6 +91,7 @@ import {
|
||||
isApplicableVersionedTypesKey,
|
||||
isArray,
|
||||
isCallExpression,
|
||||
isCallLikeExpression,
|
||||
isIdentifier,
|
||||
isIdentifierText,
|
||||
isImportCall,
|
||||
@ -429,7 +430,15 @@ function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringL
|
||||
// });
|
||||
return stringLiteralCompletionsForObjectLiteral(typeChecker, parent.parent);
|
||||
}
|
||||
return fromContextualType() || fromContextualType(ContextFlags.None);
|
||||
if (findAncestor(parent.parent, isCallLikeExpression)) {
|
||||
const uniques = new Set<string>();
|
||||
const stringLiteralTypes = concatenate(
|
||||
getStringLiteralTypes(typeChecker.getContextualType(node, ContextFlags.None), uniques),
|
||||
getStringLiteralTypes(typeChecker.getContextualType(node, ContextFlags.Completions), uniques),
|
||||
);
|
||||
return toStringLiteralCompletionsFromTypes(stringLiteralTypes);
|
||||
}
|
||||
return fromContextualType(ContextFlags.None);
|
||||
|
||||
case SyntaxKind.ElementAccessExpression: {
|
||||
const { expression, argumentExpression } = parent as ElementAccessExpression;
|
||||
@ -556,14 +565,14 @@ function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringL
|
||||
function fromContextualType(contextFlags: ContextFlags = ContextFlags.IgnoreNodeInferences): StringLiteralCompletionsFromTypes | undefined {
|
||||
// Get completion for string literal from string literal type
|
||||
// i.e. var x: "hi" | "hello" = "/*completion position*/"
|
||||
const types = getStringLiteralTypes(getContextualTypeFromParent(node, typeChecker, contextFlags));
|
||||
if (!types.length) {
|
||||
return;
|
||||
}
|
||||
return { kind: StringLiteralCompletionKind.Types, types, isNewIdentifier: false };
|
||||
return toStringLiteralCompletionsFromTypes(getStringLiteralTypes(getContextualTypeFromParent(node, typeChecker, contextFlags)));
|
||||
}
|
||||
}
|
||||
|
||||
function toStringLiteralCompletionsFromTypes(types: readonly StringLiteralType[]): StringLiteralCompletionsFromTypes | undefined {
|
||||
return types.length ? { kind: StringLiteralCompletionKind.Types, types, isNewIdentifier: false } : undefined;
|
||||
}
|
||||
|
||||
function walkUpParentheses(node: Node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
|
||||
35
tests/baselines/reference/generatorTypeCheck64.symbols
Normal file
35
tests/baselines/reference/generatorTypeCheck64.symbols
Normal file
@ -0,0 +1,35 @@
|
||||
//// [tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck64.ts] ////
|
||||
|
||||
=== generatorTypeCheck64.ts ===
|
||||
function* g3(): Generator<Generator<(x: string) => number>> {
|
||||
>g3 : Symbol(g3, Decl(generatorTypeCheck64.ts, 0, 0))
|
||||
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
|
||||
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(generatorTypeCheck64.ts, 0, 37))
|
||||
|
||||
yield function* () {
|
||||
yield x => x.length;
|
||||
>x : Symbol(x, Decl(generatorTypeCheck64.ts, 2, 13))
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(generatorTypeCheck64.ts, 2, 13))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
} ()
|
||||
}
|
||||
|
||||
function* g4(): Iterator<Iterable<(x: string) => number>> {
|
||||
>g4 : Symbol(g4, Decl(generatorTypeCheck64.ts, 4, 1))
|
||||
>Iterator : Symbol(Iterator, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.esnext.iterator.d.ts, --, --))
|
||||
>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(generatorTypeCheck64.ts, 6, 35))
|
||||
|
||||
yield (function* () {
|
||||
yield (x) => x.length;
|
||||
>x : Symbol(x, Decl(generatorTypeCheck64.ts, 8, 11))
|
||||
>x.length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(generatorTypeCheck64.ts, 8, 11))
|
||||
>length : Symbol(String.length, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
})();
|
||||
}
|
||||
|
||||
67
tests/baselines/reference/generatorTypeCheck64.types
Normal file
67
tests/baselines/reference/generatorTypeCheck64.types
Normal file
@ -0,0 +1,67 @@
|
||||
//// [tests/cases/conformance/es6/yieldExpressions/generatorTypeCheck64.ts] ////
|
||||
|
||||
=== Performance Stats ===
|
||||
Type Count: 1,000
|
||||
Instantiation count: 2,500
|
||||
|
||||
=== generatorTypeCheck64.ts ===
|
||||
function* g3(): Generator<Generator<(x: string) => number>> {
|
||||
>g3 : () => Generator<Generator<(x: string) => number>>
|
||||
> : ^^^^^^
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
|
||||
yield function* () {
|
||||
>yield function* () { yield x => x.length; } () : any
|
||||
>function* () { yield x => x.length; } () : Generator<(x: string) => number, void, any>
|
||||
> : ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>function* () { yield x => x.length; } : () => Generator<(x: string) => number, void, any>
|
||||
> : ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
yield x => x.length;
|
||||
>yield x => x.length : any
|
||||
>x => x.length : (x: string) => number
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
>x.length : number
|
||||
> : ^^^^^^
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
>length : number
|
||||
> : ^^^^^^
|
||||
|
||||
} ()
|
||||
}
|
||||
|
||||
function* g4(): Iterator<Iterable<(x: string) => number>> {
|
||||
>g4 : () => Iterator<Iterable<(x: string) => number>>
|
||||
> : ^^^^^^
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
|
||||
yield (function* () {
|
||||
>yield (function* () { yield (x) => x.length; })() : any
|
||||
>(function* () { yield (x) => x.length; })() : Generator<(x: string) => number, void, any>
|
||||
> : ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>(function* () { yield (x) => x.length; }) : () => Generator<(x: string) => number, void, any>
|
||||
> : ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>function* () { yield (x) => x.length; } : () => Generator<(x: string) => number, void, any>
|
||||
> : ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
yield (x) => x.length;
|
||||
>yield (x) => x.length : any
|
||||
>(x) => x.length : (x: string) => number
|
||||
> : ^ ^^^^^^^^^^^^^^^^^^^
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
>x.length : number
|
||||
> : ^^^^^^
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
>length : number
|
||||
> : ^^^^^^
|
||||
|
||||
})();
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
// @strict: true
|
||||
// @target: esnext
|
||||
// @noEmit: true
|
||||
|
||||
function* g3(): Generator<Generator<(x: string) => number>> {
|
||||
yield function* () {
|
||||
yield x => x.length;
|
||||
} ()
|
||||
}
|
||||
|
||||
function* g4(): Iterator<Iterable<(x: string) => number>> {
|
||||
yield (function* () {
|
||||
yield (x) => x.length;
|
||||
})();
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @strict: true
|
||||
|
||||
//// declare function createMachine<T>(config: {
|
||||
//// initial: keyof T;
|
||||
//// states: {
|
||||
//// [K in keyof T]: {
|
||||
//// on?: Record<string, keyof T>;
|
||||
//// };
|
||||
//// };
|
||||
//// }): void;
|
||||
////
|
||||
//// createMachine({
|
||||
//// initial: "a",
|
||||
//// states: {
|
||||
//// a: {
|
||||
//// on: {
|
||||
//// NEXT: "/*1*/",
|
||||
//// },
|
||||
//// },
|
||||
//// b: {
|
||||
//// on: {
|
||||
//// NEXT: "/*2*/",
|
||||
//// },
|
||||
//// },
|
||||
//// },
|
||||
//// });
|
||||
|
||||
verify.completions({
|
||||
marker: ["1", "2"],
|
||||
exact: ["a", "b"]
|
||||
})
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
goTo.marker("1");
|
||||
edit.insert(`x`)
|
||||
verify.completions({ exact: ["MORNING", "LUNCH_TIME", "ALOHA"] });
|
||||
verify.completions({ exact: ["ALOHAx", "MORNING", "LUNCH_TIME", "ALOHA"] });
|
||||
verify.getSemanticDiagnostics([{
|
||||
code: 2322,
|
||||
message: `Type 'RaiseActionObject<{ type: "ALOHAx"; }>' is not assignable to type 'RaiseActionObject<GreetingEvent>'.\n Type '{ type: "ALOHAx"; }' is not assignable to type 'GreetingEvent'.\n Type '{ type: "ALOHAx"; }' is not assignable to type '{ type: "ALOHA"; }'.\n Types of property 'type' are incompatible.\n Type '"ALOHAx"' is not assignable to type '"ALOHA"'.`,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user