diff options
author | Alex Lorenz <arphaman@gmail.com> | 2017-10-24 17:18:45 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2017-10-24 17:18:45 +0000 |
commit | 58538f115416ae2ce6cc4cfa794d243bade5458d (patch) | |
tree | ec24dbb374fbc882e2168b3e71efa4ff0e9921fa /lib/Tooling/Refactoring/ASTSelection.cpp | |
parent | 53710bdec511dfcfb69ee4d234b7f579b4955101 (diff) |
[refactor] Initial outline of implementation of "extract function" refactoring
This commit adds an initial, skeleton outline of the "extract function"
refactoring. The extracted function doesn't capture variables / rewrite code
yet, it just basically does a simple copy-paste.
The following initiation rules are specified:
- extraction can only be done for executable code in a function/method/block.
This means that you can't extract a global variable initialize into a function
right now.
- simple literals and references are not extractable.
This commit also adds support for full source ranges to clang-refactor's test
mode.
Differential Revision: https://reviews.llvm.org/D38982
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@316465 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Tooling/Refactoring/ASTSelection.cpp')
-rw-r--r-- | lib/Tooling/Refactoring/ASTSelection.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Tooling/Refactoring/ASTSelection.cpp b/lib/Tooling/Refactoring/ASTSelection.cpp index 2c9c42bfcb..9d0683a285 100644 --- a/lib/Tooling/Refactoring/ASTSelection.cpp +++ b/lib/Tooling/Refactoring/ASTSelection.cpp @@ -322,6 +322,10 @@ CodeRangeASTSelection::create(SourceRange SelectionRange, return CodeRangeASTSelection(Selected.Node, Selected.Parents, /*AreChildrenSelected=*/false); } + // FIXME (Alex L): First selected SwitchCase means that first case statement. + // is selected actually + // (See https://github.com/apple/swift-clang & CompoundStmtRange). + // FIXME (Alex L): Tweak selection rules for compound statements, see: // https://github.com/apple/swift-clang/blob/swift-4.1-branch/lib/Tooling/ // Refactor/ASTSlice.cpp#L513 @@ -330,3 +334,36 @@ CodeRangeASTSelection::create(SourceRange SelectionRange, return CodeRangeASTSelection(Selected.Node, Selected.Parents, /*AreChildrenSelected=*/true); } + +bool CodeRangeASTSelection::isInFunctionLikeBodyOfCode() const { + bool IsPrevCompound = false; + // Scan through the parents (bottom-to-top) and check if the selection is + // contained in a compound statement that's a body of a function/method + // declaration. + for (const auto &Parent : llvm::reverse(Parents)) { + const DynTypedNode &Node = Parent.get().Node; + if (const auto *D = Node.get<Decl>()) { + // FIXME (Alex L): Test for BlockDecl && ObjCMethodDecl. + if (isa<FunctionDecl>(D)) + return IsPrevCompound; + // FIXME (Alex L): We should return false on top-level decls in functions + // e.g. we don't want to extract: + // function foo() { struct X { + // int m = /*selection:*/ 1 + 2 /*selection end*/; }; }; + } + IsPrevCompound = Node.get<CompoundStmt>() != nullptr; + } + return false; +} + +const Decl *CodeRangeASTSelection::getFunctionLikeNearestParent() const { + for (const auto &Parent : llvm::reverse(Parents)) { + const DynTypedNode &Node = Parent.get().Node; + if (const auto *D = Node.get<Decl>()) { + // FIXME (Alex L): Test for BlockDecl && ObjCMethodDecl. + if (isa<FunctionDecl>(D)) + return D; + } + } + return nullptr; +} |