-
Notifications
You must be signed in to change notification settings - Fork 12.8k
extractMethod: Support renameLocation #18050
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
const { scopes, readsAndWrites: { errorsPerScope } } = getPossibleExtractionsWorker(targetRange, context); | ||
// Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547 | ||
return scopes.map((scope, i): PossibleExtraction => { | ||
const errors = errorsPerScope[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be inlined
Debug.assert(fileName === renameFilename); | ||
for (const change of textChanges) { | ||
const { span, newText } = change; | ||
const index = newText.indexOf(functionNameText); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we do not know if the name is really unique text wise. we only look if it was declared as an identifier, but not in a comment or string literal for instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this also relies on the use site being inserted in the file before the definition. we should add a comment to that meaning in case we change where the function declaration is added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would definitely be preferable not to assume that the new declaration is inserted after the extracted range because that will almost certainly not be the case when we start extracting locals.
src/harness/fourslash.ts
Outdated
} | ||
} | ||
else { | ||
// TODO: test editInfo.renameFilename too |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe just assert that it's non-empty for now?
@@ -691,9 +691,12 @@ function test(x: number) { | |||
data.push(`// ==ORIGINAL==`); | |||
data.push(sourceFile.text); | |||
for (const r of results) { | |||
const changes = refactor.extractMethod.getPossibleExtractions(result.targetRange, context, results.indexOf(r))[0].changes; | |||
const { renameLocation, edits } = refactor.extractMethod.getPossibleExtractionAtIndex(result.targetRange, context, results.indexOf(r)); | |||
Debug.assert(edits.length === 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use assert.equal
?
Please port this to release-2.5 |
@@ -494,12 +481,32 @@ namespace ts.refactor.extractMethod { | |||
return scopes; | |||
} | |||
|
|||
// exported only for tests | |||
export function getPossibleExtractionAtIndex(targetRange: TargetRange, context: RefactorContext, requestedChangesIndex: number): RefactorEditInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just "getExtractionAtIndex"?
@@ -582,34 +568,33 @@ namespace ts.refactor.extractMethod { | |||
} | |||
} | |||
|
|||
function getUniqueName(isNameOkay: (name: string) => boolean) { | |||
function getUniqueName(fileText: string): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, somewhat ironically, if you were to add a comment //TODO newFunction_1 goes here
, we would call the new function "newFunction_2"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be easier to use something temporary, like a GUID, until the replacement has been accomplished and then swap it for the name we would originally have generated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That might be doable, but we might (might not) need the GUID to have an identical length. But you could still calculate them together inside getUniqueName
.
isClassLike(scope) ? createPropertyAccess(range.facts & RangeFacts.InStaticRegion ? createIdentifier(scope.name.getText()) : createThis(), functionReference) : functionReference, | ||
const called = getCalledExpression(scope, range, functionNameText); | ||
|
||
let call: Expression = createCall(called, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing linebreak before argument?
Debug.assert(fileName === renameFilename); | ||
for (const change of textChanges) { | ||
const { span, newText } = change; | ||
// Note: We are assuming that the call expression comes before the function declaration, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please add TODO (acasey)
(or TODO (17098)
)? This assumption will be incorrect as soon as we implement Extract Local.
usages: Map<UsageEntry>; | ||
typeParameterUsages: Map<TypeParameter>; // Key is type ID | ||
substitutions: Map<Node>; | ||
readonly usages: Map<UsageEntry>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when a property of an exported type depends on a non-exported type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users can't reference the type itself, but they can get a variable of the type. Pretty annoying. But it looks like this doesn't actually need to be exported.
var i = 10; | ||
var __return: any; | ||
({ __return, i } = newFunction(i)); | ||
({ __return, i } = n/*RENAME*/ewFunction(i)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the location within the identifier?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added #18349
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our method of coming up with a unique name seems slightly crazy to me (esp for large files), but this generally makes sense.
Fixes #17852
Does not fix #18048
EDIT: Now fixes both