mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-04-17 01:49:41 -05:00
Don't capture type parameters defined inside the extraction range with "Extract to function" (#53543)
This commit is contained in:
committed by
GitHub
parent
85ef01d31a
commit
6e44db7d1d
@@ -111,6 +111,7 @@ import {
|
||||
LabeledStatement,
|
||||
last,
|
||||
map,
|
||||
mapDefined,
|
||||
MethodDeclaration,
|
||||
Modifier,
|
||||
ModifierFlags,
|
||||
@@ -1070,12 +1071,12 @@ function extractFunctionInScope(
|
||||
callArguments.push(factory.createIdentifier(name));
|
||||
});
|
||||
|
||||
const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values(), type => ({ type, declaration: getFirstDeclaration(type) }));
|
||||
const typeParametersAndDeclarations = arrayFrom(typeParameterUsages.values(), type => ({ type, declaration: getFirstDeclarationBeforePosition(type, context.startPosition) }));
|
||||
const sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder);
|
||||
|
||||
const typeParameters: readonly TypeParameterDeclaration[] | undefined = sortedTypeParametersAndDeclarations.length === 0
|
||||
? undefined
|
||||
: sortedTypeParametersAndDeclarations.map(t => t.declaration as TypeParameterDeclaration);
|
||||
: mapDefined(sortedTypeParametersAndDeclarations, ({ declaration }) => declaration as TypeParameterDeclaration);
|
||||
|
||||
// Strictly speaking, we should check whether each name actually binds to the appropriate type
|
||||
// parameter. In cases of shadowing, they may not.
|
||||
@@ -1547,13 +1548,13 @@ function getContainingVariableDeclarationIfInList(node: Node, scope: Scope) {
|
||||
}
|
||||
}
|
||||
|
||||
function getFirstDeclaration(type: Type): Declaration | undefined {
|
||||
function getFirstDeclarationBeforePosition(type: Type, position: number): Declaration | undefined {
|
||||
let firstDeclaration;
|
||||
|
||||
const symbol = type.symbol;
|
||||
if (symbol && symbol.declarations) {
|
||||
for (const declaration of symbol.declarations) {
|
||||
if (firstDeclaration === undefined || declaration.pos < firstDeclaration.pos) {
|
||||
if ((firstDeclaration === undefined || declaration.pos < firstDeclaration.pos) && declaration.pos < position) {
|
||||
firstDeclaration = declaration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f() {
|
||||
//// let g = /*start*/<T>(x: T) => x/*end*/;
|
||||
//// return g;
|
||||
////}
|
||||
|
||||
goTo.select('start', 'end');
|
||||
edit.applyRefactor({
|
||||
refactorName: "Extract Symbol",
|
||||
actionName: "function_scope_1",
|
||||
actionDescription: "Extract to function in global scope",
|
||||
newContent:
|
||||
`function f() {
|
||||
let g = /*RENAME*/newFunction();
|
||||
return g;
|
||||
}
|
||||
|
||||
function newFunction() {
|
||||
return <T>(x: T) => x;
|
||||
}
|
||||
`});
|
||||
@@ -0,0 +1,20 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function satisfies<A>() {
|
||||
//// return /*start*/<T extends A>(x: T) => x/*end*/;
|
||||
////}
|
||||
|
||||
goTo.select('start', 'end');
|
||||
edit.applyRefactor({
|
||||
refactorName: "Extract Symbol",
|
||||
actionName: "function_scope_1",
|
||||
actionDescription: "Extract to function in global scope",
|
||||
newContent:
|
||||
`function satisfies<A>() {
|
||||
return /*RENAME*/newFunction<A>();
|
||||
}
|
||||
|
||||
function newFunction<A>() {
|
||||
return <T extends A>(x: T) => x;
|
||||
}
|
||||
`});
|
||||
Reference in New Issue
Block a user