This patch allows detecting conflicts with variables defined in the current
CompoundStmt or If/While/For variable init statements.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Thanks, this looks right to me.
| clang-tools-extra/clangd/refactor/Rename.cpp | ||
|---|---|---|
| 340 | I found that the current structure (we have two places of this If cases, and they are separated) is a bit hard to follow, I'd suggest union them, just like the code below, it seems straight-forward to me, and easy to extend. if (const auto* CompoundStmtEnclosing = Parents.begin()->get<CompoundStmt>()) {
CheckCompoundStmt(CompoundStmtEnclosing);
// below we detect conflicts in conditions or others (if the CompoundStmt is a function body, we could detect the parameter decls as well)
getParents(CompoundStmtEnclosing);
if ( ...<IfStmt>()) {
CheckConditionVariable();
} else if (...) {
}
} else if (const auto* IfEnclosing = ... <IfStmt>()) {
CheckCompoundStmt(If->getThen());
// possibly CheckCompoundStmt(If->getElse)
} else {
...
} | |
| 341 | thinking more about the if case, I think else should be included as well? no need to address in this patch. like if (int a = 0) {
} else {
int s; // rename s=>a will cause a compiling error.
} | |
| 354 | nit: VarDecl => NamedDecl | |
Resolve review comments.
| clang-tools-extra/clangd/refactor/Rename.cpp | ||
|---|---|---|
| 341 | This case is already supported: else's CompoundStmt is attached to the same IfStmt with variable declaration and is checked just like the "main" branch. The other one wasn't (renaming a into s) but I've added this and also added tests for this. | |
thanks, looks better now, just some nits to improve the code readability.
| clang-tools-extra/clangd/refactor/Rename.cpp | ||
|---|---|---|
| 332 | since we repeat this code multiple times, I think we can use wrap it with a lambda (e.g. getSingleParent etc). | |
| 338 | maybe name it LookupInDeclStmt and pass the Name as a parameter, the same below. | |
| 345 | the same lookupInCompoundStmt. | |
| 350 | nit: can be just return CheckDeclStmt(DS); | |
| 355 | nit: explicit spell out the auto type? | |
| 359 | nit: the same here, return CheckDeclStmt (Scope->getConditionVariableDeclStmt()), just adding the nullptr handling in CheckDeclStmt. | |
| 364 | I understand all cases of these if branches at the moment, but I think we'd better to add some comments, or examples here -- help us understand this code in case that we forget the context in the future :) | |
| 382 | I think we need a return null here (or use if-else pattern), otherwise, the following if-stmt will be examined as well, which seems no necessary. | |
Resolve most comments but one: some comments & examples in the code incoming in
the next diff.
| clang-tools-extra/clangd/refactor/Rename.cpp | ||
|---|---|---|
| 355 | That's the idea behind this helper: it's used both on IfStmt and WhileStmt, so the point here is that getConditionVariableDeclStmt() is available in both but not via interface/inheritance. | |
| clang-tools-extra/clangd/refactor/Rename.cpp | ||
|---|---|---|
| 333 | If the intention is for storage, maybe call it Storage. | |
| 334 | const DynTypedNode & | |
| 362 | I think we need to iterate *all* children, rather than the first one. looks like our testcase doesn't cover this, maybe add one. | |
| 372 | CompoundStmt is the most common enclosing scope for function-local symbols. | |
| 378 | maybe just GetSingleParent(Parent), rather than creating a new DynTypeNode. | |
| 390 | be careful about nullptr here, the init-statement could be a nullptr, which will trigger a crash in dyn_cast, thinking about the case below: for (; ; ;) {
int var;
}use dyn_cast_or_null. | |
Fix a couple problems pointed out during the review.
| clang-tools-extra/clangd/refactor/Rename.cpp | ||
|---|---|---|
| 334 | Sorry, I'm a bit confused: this can return nullptr when there are _no parents_. Is there any way I can return the reference safely? | |
| clang-tools-extra/clangd/refactor/Rename.cpp | ||
|---|---|---|
| 411 | another case we could add is FunctionDecl, if we rename a parameter decl, we could check collisions in the function body. this can be addressed in a follow-up. | |
since we repeat this code multiple times, I think we can use wrap it with a lambda (e.g. getSingleParent etc).