[PATCH] D65526: [Clangd] Initial prototype version of ExtractFunction
Sam McCall via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 2 05:55:01 PDT 2019
sammccall added a comment.
I guess you're looking for design review at this point.
But the most important part of that is the documentation of the high-level structure, which is entirely missing. I can't really infer it from the code because most of the design is (presumably) not implemented at this point :-)
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:36
+
+class ExtractionTarget {
+public:
----------------
I think "range" or "region" may be a clearer name here than "target".
(In extract variable, target was used to refer to the destination of extraction)
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:110
+ // FIXME: Bail out when it's partial selected. Wait for selectiontree
+ // semicolon fix.
+ if (CommonAnc->Selected == SelectionTree::Selection::Partial &&
----------------
what is the fix you're waiting for?
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:155
+public:
+ enum LocType { PRETARGET, TARGET, POSTTARGET, OUTSIDECONTEXT };
+ struct Reference {
----------------
These are important domain structures, can we move them out of the RecursiveASTVisitor? (which should be mostly restricted to managing state of the traversal itself)
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:156
+ enum LocType { PRETARGET, TARGET, POSTTARGET, OUTSIDECONTEXT };
+ struct Reference {
+ Decl *TheDecl = nullptr;
----------------
You've called this "reference", but I think it's actually a "referenceddecl" - you don't store one of these for each reference do you?
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:189
+
+TargetAnalyzer::Reference &TargetAnalyzer::getReferenceFor(VarDecl *D) {
+ assert(D && "D shouldn't be null!");
----------------
why does D need to be a vardecl?
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:190
+TargetAnalyzer::Reference &TargetAnalyzer::getReferenceFor(VarDecl *D) {
+ assert(D && "D shouldn't be null!");
+ // Don't add Decls that are outside the extraction context or in PostTarget.
----------------
please don't add messages to asserts that just echo the code. In order of preference:
- take a reference so it clearly can't be null
- add a message explaining at a *high level* what variant is violated
- add the assertion with no message
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:197
+
+void TargetAnalyzer::checkIfRecursiveCall(DeclRefExpr *DRE) {
+ if (Target->isInTarget(DRE->getBeginLoc()) &&
----------------
why is this handled specially, instead of being part of the general case of "referring to a decl not visible in the target scope"?
(in particular, if the context is forward-declared elsewhere, what's the problem?
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:203
+
+void TargetAnalyzer::updateReferenceFor(DeclRefExpr *DRE) {
+ VarDecl *D = dyn_cast_or_null<VarDecl>(DRE->getDecl());
----------------
DRE is just one of the cases where we want to handle names.
I think it'll be easier to handle more cases by changing this to accept a Decl* and moving the DRE->getDecl() to the caller
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:207
+ return;
+ LocType DRELocType = getLocType(DRE->getBeginLoc());
+ LocType DeclLocType = getLocType(D->getBeginLoc());
----------------
(why beginloc rather than loc, throughout?)
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:211
+ // Note that DRELocType is never OUTSIDECONTEXT.
+ if (DeclLocType + 1 != DRELocType)
+ return;
----------------
this line seems very suspect, what are you trying to do and why?
================
Comment at: clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp:214
+ Reference &Ref = getReferenceFor(D);
+ if (DRELocType == POSTTARGET)
+ Ref.IsReferencedInPostTarget = true;
----------------
can't we skip the indirection here and just have something like Ref.markOccurrence(DRE->getBeginLoc()), and avoid dealing with the enum here at all?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D65526/new/
https://reviews.llvm.org/D65526
More information about the cfe-commits
mailing list