- Use ad-hoc Decl canonicalization from Clang-Rename to allow renaming constructors and destructors while using cross-file rename.
- Manually handle the destructor selection
- Add unit tests to prevent regressions and ensure the correct behaviour
Details
Diff Detail
Event Timeline
clang-tools-extra/clangd/unittests/RenameTests.cpp | ||
---|---|---|
754 | could you also add a case with ~^Foo() |
clang-tools-extra/clangd/refactor/Rename.cpp | ||
---|---|---|
86–87 | Braindump from an offline conversation... The TokenStartLoc check is a bit unfortunate to begin with - it's subject to all the heuristic-token-rewinding problems we've encountered in the past. Its one advantage over plain selectiontree is that it works at the end of the identifier. Better approach seems to be:
I don't think there's a better TokenBuffer API than calling spelledTokens() and binary-searching, at the moment. This touches more code, but is less special-case-y overall. I'd consider putting the getIdentifierTouching(SourceLocation, TokenBuffer, SourceManager) in SourceCode.h |
clang-tools-extra/clangd/refactor/Rename.cpp | ||
---|---|---|
91 | why is this code being moved? | |
453 | so getting an invalid location from the editor isn't the same thing as the symbol being used outside the file! Here we already have an Error to return. if (!Offset) return Offset.takeError(); but really there's a helper to do this: SourceLocation Loc = sourceLocationInMainFile(SM, RInputs.Pos); if (!Loc) return Loc.takeError(); const syntax::Token *IdentifierToken = spelledIdentifierTouching(Loc, AST.getTokens()); | |
456 | nit: auto* for pointers, but spelling out the type here would be clearer I think | |
458 | this is an invariant of the function we're calling, not this one - no need to document it (next line is good though) | |
462 | This unwrapping doesn't seem necessary, - it doesn't make a difference for macros (which we don't support anyway), nor for selectiontree. Just inline usages of IdentifierToken->location() below? |
clang-tools-extra/clangd/refactor/Rename.cpp | ||
---|---|---|
91 | So, this code was previously only in the within-file rename path and hence triggering rename from a constructor/destructor-s was only possible there. Moving the code here improves overall "symbol selection" and fixes it for global renames, too. |
clang-tools-extra/clangd/refactor/Rename.cpp | ||
---|---|---|
91 | Clangd as a whole actually canonicalizes in the other direction (templatedecl -> templated decl). Certainly up for discussion which is better (behavior is historical) but that's a larger change. | |
96 | dyn_cast then unconditionally inserting seems dodgy - if it can be null, it must be checked, and if it can't, it should be plain cast |
clang-tools-extra/clangd/refactor/Rename.cpp | ||
---|---|---|
91 | OK, this can definitely fail though - just select 'friend X' in a class body or so. Need to check for ND and bail out. | |
223 | you removed this comment and the fixme, but it still applies? | |
clang-tools-extra/clangd/unittests/RenameTests.cpp | ||
732 | nit: put these after "class methods" rather than at the top? | |
750 | 4 is too many cases for constructor/destructor. What about 2: Constructor at start, destructor at end? |
Braindump from an offline conversation...
This seems like an unfortunate place to put a complicated special case and it doesn't generalize well.
The TokenStartLoc check is a bit unfortunate to begin with - it's subject to all the heuristic-token-rewinding problems we've encountered in the past. Its one advantage over plain selectiontree is that it works at the end of the identifier.
Better approach seems to be:
I don't think there's a better TokenBuffer API than calling spelledTokens() and binary-searching, at the moment.
This touches more code, but is less special-case-y overall. I'd consider putting the getIdentifierTouching(SourceLocation, TokenBuffer, SourceManager) in SourceCode.h