Prototype of a new rename rule for renaming qualified symbol.
Details
Diff Detail
- Build Status
Buildable 11752 Build 11752: arc lint + arc unit
Event Timeline
Implementation LG.
My questions are mostly framework-level:
- should this be an Action, or just a Rule under the existing rename Action?
- {qname vs selection} x {local vs global} x ... seems like a combinatorial explosion in the number of rules. Shouldn't concerns like format of the input be taken care of before we get to the Rule?
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
98 | if this is a local refactor, and there are no USRs (symbol doesn't exist), is this an error that needs to be signaled somehow? | |
109 | As discussed offline, it's not clear why this is a separate Action, rather than a different Rule that's part of the same Action. @arphaman how does the framework answer this question? |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
98 | This case should not be happened IMO. If we find the ND, we will rename ND at least. | |
109 | There is a document describing it, but still ambiguous. We also had some questions about local-rename from the discussion, need @arphaman's input:
|
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
98 | Oops, of course. Maybe an assert? |
I've committed https://reviews.llvm.org/D38985, so you'd have to rebase unfortunately. Things are still somewhat unstable :)
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
109 | I think that this should be just a rule in local-rename. So you'd be able to call: clang-refactor local-rename -selection=X -new-name=foo |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
109 | We need your help to understand how exactly local-rename is intended to be used. From the current code and previous conversations we had, it seems to me that the action would support the use case where a user selects an identifier in the editor (say, with cursor) and initiates a local-rename action but without providing the new name in the beginning. The rename rule finds and returns all occurrences (including token ranges) to the editor, and users can then start typing in the new name, and in the same time, the editor performs text replacements according to ranges of occurrences and the new name typed in. Is this how RenameOccurrences is intended to be used in the future? If this is how local-rename is expected to be used, it would be hard to merge qualified rename into it, because both qualified old name and new name are required in order to calculate the range of a symbol reference, and this doesn't fit with the above workflow. But if my understanding is simply wrong (e.g. the editor would invoke local-rename again to perform the actual refactoring), then I think it makes a lot of sense to merge qualified rename into the current local-rename action. |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
109 | You're right that rename should deal with occurrences conceptually, but I believe that's more of requirement imposed onto the editor clients. Rename in particular is basically impossible to map to all clients using just one generic model, so I think it's fine if RenameOccurrences class returns source replacements that local-rename in clang-refactor consumes. I don't think this will change in the future, if anything we will lift OccurrenceFinderclass into the header so that the editor clients can use it. |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
109 | Thanks for the clarification! In that case, I agree that qualified rename should be a rule in the local-rename action. |
- rebase to master
- move the implementation to a refactoring rule in local-rename
- support non-selection based refactoring action invocation call path
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
109 | Thanks for the explanation, that makes sense. Moved to local-rename action. |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
101 | It might be better to find the declaration (and report error if needed) during in initiation, and then pass the ND to the class. Maybe then both RenameOccurrences and QualifiedRenameRule could subclass from one base class that actually does just this: auto USRs = getUSRsForDeclaration(ND, Context.getASTContext()); assert(!USRs.empty()); return tooling::createRenameAtomicChanges( USRs, NewQualifiedName, Context.getASTContext().getTranslationUnitDecl()); |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
101 | USRRenameRule doesn't seem to be a very useful abstraction. I think what Alex proposed is a base class that implements createSourceReplacements which could be shared by both RenameOccurrences and QualifiedRenameRule. Intuitively, un-qualified rename is a special case of qualified rename (maybe?), where namespace is not changed. | |
115 | We should also document the behavior when namespace is changed. What would happen to symbol definitions and symbol references? |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
101 | Yep, I meant that indeed. |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
101 | Ah, sorry for the misunderstanding. Unfortunately, RenameOccurrences and QualifiedRenameRule could not share the same createSourceReplacements implementation,
| |
115 | Sound good! Done. |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
101 | That makes sense (I think), but then we should remove USRRenameRule again if we're not actually reusing anything. (And ideally we can hide any such future reuse as functions in the cc file, rather than a class hierarchy exposed in the header) |
lib/Tooling/Refactoring/Rename/RenamingAction.cpp | ||
---|---|---|
101 | Done. Reverted it back. | |
104 | I think using StringError is sufficient here -- didn't see much value using diagnostic:
|
There is a typo here → "qualified name to change"