mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 21:06:50 -05:00
extract symbol
This commit is contained in:
@@ -8,7 +8,7 @@ namespace ts.refactor.extractSymbol {
|
||||
* Exported for tests.
|
||||
*/
|
||||
export function getAvailableActions(context: RefactorContext): readonly ApplicableRefactorInfo[] {
|
||||
const rangeToExtract = getRangeToExtract(context.file, getRefactorContextSpan(context));
|
||||
const rangeToExtract = getRangeToExtract(context.file, getRefactorContextSpan(context), context.triggerReason);
|
||||
|
||||
const targetRange = rangeToExtract.targetRange;
|
||||
if (targetRange === undefined) {
|
||||
@@ -87,7 +87,7 @@ namespace ts.refactor.extractSymbol {
|
||||
|
||||
/* Exported for tests */
|
||||
export function getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined {
|
||||
const rangeToExtract = getRangeToExtract(context.file, getRefactorContextSpan(context));
|
||||
const rangeToExtract = getRangeToExtract(context.file, getRefactorContextSpan(context), /* triggerReason*/ { kind: "invoked" });
|
||||
const targetRange = rangeToExtract.targetRange!; // TODO:GH#18217
|
||||
|
||||
const parsedFunctionIndexMatch = /^function_scope_(\d+)$/.exec(actionName);
|
||||
@@ -186,18 +186,20 @@ namespace ts.refactor.extractSymbol {
|
||||
* not shown to the user, but can be used by us diagnostically)
|
||||
*/
|
||||
// exported only for tests
|
||||
export function getRangeToExtract(sourceFile: SourceFile, span: TextSpan): RangeToExtract {
|
||||
export function getRangeToExtract(sourceFile: SourceFile, span: TextSpan, triggerReason?: RefactorTriggerReason): RangeToExtract {
|
||||
const { length } = span;
|
||||
|
||||
if (length === 0) {
|
||||
if (length === 0 && triggerReason?.kind !== "invoked") {
|
||||
return { errors: [createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractEmpty)] };
|
||||
}
|
||||
const explicitCursorRequest = length === 0 && triggerReason?.kind === "invoked";
|
||||
|
||||
// Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
|
||||
// This may fail (e.g. you select two statements in the root of a source file)
|
||||
const start = getParentNodeInSpan(getTokenAtPosition(sourceFile, span.start), sourceFile, span);
|
||||
const startToken = getTokenAtPosition(sourceFile, span.start);
|
||||
const start = explicitCursorRequest ? getExtractableParent(startToken): getParentNodeInSpan(startToken, sourceFile, span);
|
||||
// Do the same for the ending position
|
||||
const end = getParentNodeInSpan(findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span)), sourceFile, span);
|
||||
const endToken = findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span));
|
||||
const end = explicitCursorRequest ? start : getParentNodeInSpan(endToken, sourceFile, span);
|
||||
|
||||
const declarations: Symbol[] = [];
|
||||
|
||||
@@ -1832,6 +1834,10 @@ namespace ts.refactor.extractSymbol {
|
||||
}
|
||||
}
|
||||
|
||||
function getExtractableParent(node: Node | undefined): Node | undefined {
|
||||
return findAncestor(node, node => node.parent && isExtractableExpression(node) && !isBinaryExpression(node.parent));
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes whether or not a node represents an expression in a position where it could
|
||||
* be extracted.
|
||||
|
||||
Reference in New Issue
Block a user