forked from OSchip/llvm-project
[refactor][selection] canonicalize member expr callee to the full
member call expression We would like to extract the full call when just the callee is selected. llvm-svn: 318205
This commit is contained in:
parent
383fbd050c
commit
f64d0a4d00
|
@ -115,6 +115,11 @@ public:
|
|||
return true;
|
||||
if (auto *Opaque = dyn_cast<OpaqueValueExpr>(S))
|
||||
return TraverseOpaqueValueExpr(Opaque);
|
||||
// Avoid selecting implicit 'this' expressions.
|
||||
if (auto *TE = dyn_cast<CXXThisExpr>(S)) {
|
||||
if (TE->isImplicit())
|
||||
return true;
|
||||
}
|
||||
// FIXME (Alex Lorenz): Improve handling for macro locations.
|
||||
SourceSelectionKind SelectionKind =
|
||||
selectionKindFor(CharSourceRange::getTokenRange(S->getSourceRange()));
|
||||
|
@ -268,9 +273,15 @@ void SelectedNodeWithParents::canonicalize() {
|
|||
// ~~~~~~ ~~~~~~~
|
||||
if (isa<StringLiteral>(S) && isa<ObjCStringLiteral>(Parent))
|
||||
Node = Parents.pop_back_val();
|
||||
// The entire call should be selected when just the member expression
|
||||
// that refers to the method is selected.
|
||||
// f.call(args) becomes f.call(args)
|
||||
// ~~~~ ~~~~~~~~~~~~
|
||||
else if (isa<MemberExpr>(S) && isa<CXXMemberCallExpr>(Parent) &&
|
||||
cast<CXXMemberCallExpr>(Parent)->getCallee() == S)
|
||||
Node = Parents.pop_back_val();
|
||||
// FIXME: Syntactic form -> Entire pseudo-object expr.
|
||||
// FIXME: Callee -> Call.
|
||||
// FIXME: Callee member expr -> Call.
|
||||
}
|
||||
|
||||
/// Finds the set of bottom-most selected AST nodes that are in the selection
|
||||
|
|
|
@ -1004,4 +1004,56 @@ void foo() {
|
|||
SelectionFinderVisitor::Lang_OBJC);
|
||||
}
|
||||
|
||||
TEST(ASTSelectionFinder, CanonicalizeMemberCalleeToCall) {
|
||||
StringRef Source = R"(
|
||||
class AClass { public:
|
||||
void method();
|
||||
int afield;
|
||||
void selectWholeCallWhenJustMethodSelected(int &i) {
|
||||
method();
|
||||
}
|
||||
};
|
||||
void selectWholeCallWhenJustMethodSelected() {
|
||||
AClass a;
|
||||
a.method();
|
||||
}
|
||||
void dontSelectArgument(AClass &a) {
|
||||
a.selectWholeCallWhenJustMethodSelected(a.afield);
|
||||
}
|
||||
)";
|
||||
// Just 'method' with implicit 'this':
|
||||
findSelectedASTNodesWithRange(
|
||||
Source, {6, 5}, FileRange{{6, 5}, {6, 11}},
|
||||
[](SourceRange SelectionRange, Optional<SelectedASTNode> Node) {
|
||||
EXPECT_TRUE(Node);
|
||||
Optional<CodeRangeASTSelection> SelectedCode =
|
||||
CodeRangeASTSelection::create(SelectionRange, std::move(*Node));
|
||||
EXPECT_TRUE(SelectedCode);
|
||||
EXPECT_EQ(SelectedCode->size(), 1u);
|
||||
EXPECT_TRUE(isa<CXXMemberCallExpr>((*SelectedCode)[0]));
|
||||
});
|
||||
// Just 'method':
|
||||
findSelectedASTNodesWithRange(
|
||||
Source, {11, 5}, FileRange{{11, 5}, {11, 11}},
|
||||
[](SourceRange SelectionRange, Optional<SelectedASTNode> Node) {
|
||||
EXPECT_TRUE(Node);
|
||||
Optional<CodeRangeASTSelection> SelectedCode =
|
||||
CodeRangeASTSelection::create(SelectionRange, std::move(*Node));
|
||||
EXPECT_TRUE(SelectedCode);
|
||||
EXPECT_EQ(SelectedCode->size(), 1u);
|
||||
EXPECT_TRUE(isa<CXXMemberCallExpr>((*SelectedCode)[0]));
|
||||
});
|
||||
// Just 'afield', which should not select the call.
|
||||
findSelectedASTNodesWithRange(
|
||||
Source, {14, 5}, FileRange{{14, 45}, {14, 51}},
|
||||
[](SourceRange SelectionRange, Optional<SelectedASTNode> Node) {
|
||||
EXPECT_TRUE(Node);
|
||||
Optional<CodeRangeASTSelection> SelectedCode =
|
||||
CodeRangeASTSelection::create(SelectionRange, std::move(*Node));
|
||||
EXPECT_TRUE(SelectedCode);
|
||||
EXPECT_EQ(SelectedCode->size(), 1u);
|
||||
EXPECT_FALSE(isa<CXXMemberCallExpr>((*SelectedCode)[0]));
|
||||
});
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
|
Loading…
Reference in New Issue