From 6852bea7cc8f02c8b6be43aef8a90fc6dab8a452 Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Wed, 30 Aug 2017 15:00:27 +0000 Subject: [refactor] AST selection tree should contain syntactic form of PseudoObjectExpr The AST selection finder now constructs a selection tree that contains only the syntactic form of PseudoObjectExpr. This form of selection tree is more meaningful when doing downstream analysis as we're interested in the syntactic features of the AST and the correct lexical parent relation. llvm-svn: 312127 --- clang/unittests/Tooling/ASTSelectionTest.cpp | 136 +++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) (limited to 'clang/unittests/Tooling/ASTSelectionTest.cpp') diff --git a/clang/unittests/Tooling/ASTSelectionTest.cpp b/clang/unittests/Tooling/ASTSelectionTest.cpp index bde052e849c..6b76bf06cb5 100644 --- a/clang/unittests/Tooling/ASTSelectionTest.cpp +++ b/clang/unittests/Tooling/ASTSelectionTest.cpp @@ -513,4 +513,140 @@ TEST(ASTSelectionFinder, CorrectEndForObjectiveCImplementation) { SelectionFinderVisitor::Lang_OBJC); } +const SelectedASTNode &checkFnBody(const Optional &Node, + StringRef Name) { + EXPECT_TRUE(Node); + EXPECT_EQ(Node->Children.size(), 1u); + const auto &Fn = checkNode( + Node->Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1, Name); + return checkNode(Fn.Children[0], + SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); +} + +TEST(ASTSelectionFinder, SelectObjectiveCPseudoObjectExprs) { + StringRef Source = R"( +@interface I +@property(readwrite) int prop; +@end +void selectProp(I *i) { +(void)i.prop; +i.prop = 21; +} + +typedef unsigned int size_t; +@interface NSMutableArray +- (id)objectAtIndexedSubscript:(size_t)index; +- (void)setObject:(id)object atIndexedSubscript:(size_t)index; +@end + +void selectSubscript(NSMutableArray *array, I *i) { + (void)array[10]; + array[i.prop] = i; +} +)"; + // Just 'i.prop'. + findSelectedASTNodes( + Source, {6, 7}, FileRange{{6, 7}, {6, 13}}, + [](Optional Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectProp"); + const auto &CCast = checkNode( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &POE = checkNode( + CCast.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &PRE = checkNode( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &Cast = checkNode( + PRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode(Cast.Children[0], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); + // Just 'i.prop = 21' + findSelectedASTNodes( + Source, {7, 1}, FileRange{{7, 1}, {7, 12}}, + [](Optional Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectProp"); + const auto &POE = checkNode( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &BinOp = checkNode( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/2); + const auto &PRE = checkNode( + BinOp.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + const auto &Cast = checkNode( + PRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode(Cast.Children[0], + SourceSelectionKind::InsideSelection); + checkNode(BinOp.Children[1], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); + // Just 'array[10]' + findSelectedASTNodes( + Source, {17, 9}, FileRange{{17, 9}, {17, 18}}, + [](Optional Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectSubscript"); + const auto &CCast = checkNode( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &POE = checkNode( + CCast.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &SRE = checkNode( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/2); + const auto &Cast = checkNode( + SRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode(Cast.Children[0], + SourceSelectionKind::InsideSelection); + checkNode(SRE.Children[1], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); + // Just 'array[i.prop] = array' + findSelectedASTNodes( + Source, {18, 3}, FileRange{{18, 3}, {18, 20}}, + [](Optional Node) { + const auto &CS = checkFnBody(Node, /*Name=*/"selectSubscript"); + const auto &POE = checkNode( + CS.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/1); + const auto &BinOp = checkNode( + POE.Children[0], SourceSelectionKind::ContainsSelection, + /*NumChildren=*/2); + const auto &SRE = checkNode( + BinOp.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/2); + const auto &Cast = checkNode( + SRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode(Cast.Children[0], + SourceSelectionKind::InsideSelection); + const auto &POE2 = checkNode( + SRE.Children[1], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + const auto &PRE = checkNode( + POE2.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + const auto &Cast2 = checkNode( + PRE.Children[0], SourceSelectionKind::InsideSelection, + /*NumChildren=*/1); + checkNode(Cast2.Children[0], + SourceSelectionKind::InsideSelection); + checkNode(BinOp.Children[1], + SourceSelectionKind::InsideSelection); + }, + SelectionFinderVisitor::Lang_OBJC); +} + } // end anonymous namespace -- cgit v1.2.3