r309737 - [clang-diff] Move data declarations to the public header
Johannes Altmanninger via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 1 13:17:40 PDT 2017
Author: krobelus
Date: Tue Aug 1 13:17:40 2017
New Revision: 309737
URL: http://llvm.org/viewvc/llvm-project?rev=309737&view=rev
Log:
[clang-diff] Move data declarations to the public header
Modified:
cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h
cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiffInternal.h
cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp
Modified: cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h?rev=309737&r1=309736&r2=309737&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h (original)
+++ cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiff.h Tue Aug 1 13:17:40 2017
@@ -25,7 +25,42 @@
namespace clang {
namespace diff {
-class SyntaxTree;
+/// This represents a match between two nodes in the source and destination
+/// trees, meaning that they are likely to be related.
+struct Match {
+ NodeId Src, Dst;
+};
+
+enum ChangeKind {
+ Delete, // (Src): delete node Src.
+ Update, // (Src, Dst): update the value of node Src to match Dst.
+ Insert, // (Src, Dst, Pos): insert Src as child of Dst at offset Pos.
+ Move // (Src, Dst, Pos): move Src to be a child of Dst at offset Pos.
+};
+
+struct Change {
+ ChangeKind Kind;
+ NodeId Src, Dst;
+ size_t Position;
+
+ Change(ChangeKind Kind, NodeId Src, NodeId Dst, size_t Position)
+ : Kind(Kind), Src(Src), Dst(Dst), Position(Position) {}
+ Change(ChangeKind Kind, NodeId Src) : Kind(Kind), Src(Src) {}
+ Change(ChangeKind Kind, NodeId Src, NodeId Dst)
+ : Kind(Kind), Src(Src), Dst(Dst) {}
+};
+
+/// Represents a Clang AST node, alongside some additional information.
+struct Node {
+ NodeId Parent, LeftMostDescendant, RightMostDescendant;
+ int Depth, Height;
+ ast_type_traits::DynTypedNode ASTNode;
+ SmallVector<NodeId, 4> Children;
+
+ ast_type_traits::ASTNodeKind getType() const { return ASTNode.getNodeKind(); }
+ const StringRef getTypeLabel() const { return getType().asStringRef(); }
+ bool isLeaf() const { return Children.empty(); }
+};
class ASTDiff {
public:
@@ -58,6 +93,9 @@ public:
template <class T>
SyntaxTree(T *Node, const ASTContext &AST)
: TreeImpl(llvm::make_unique<SyntaxTreeImpl>(this, Node, AST)) {}
+ ~SyntaxTree();
+
+ const Node &getNode(NodeId Id) const;
/// Serialize the node attributes to a string representation. This should
/// uniquely distinguish nodes of the same kind. Note that this function just
@@ -89,17 +127,6 @@ struct ComparisonOptions {
bool isMatchingAllowed(const DynTypedNode &N1, const DynTypedNode &N2) const {
return N1.getNodeKind().isSame(N2.getNodeKind());
}
-
- /// Returns zero if the nodes are considered to be equal. Returns a value
- /// indicating the editing distance between the nodes otherwise.
- /// There is no need to consider nodes that cannot be matched as input for
- /// this function (see isMatchingAllowed).
- double getNodeDistance(const SyntaxTree &T1, const DynTypedNode &N1,
- const SyntaxTree &T2, const DynTypedNode &N2) const {
- if (T1.getNodeValue(N1) == T2.getNodeValue(N2))
- return 0;
- return 1;
- }
};
} // end namespace diff
Modified: cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiffInternal.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiffInternal.h?rev=309737&r1=309736&r2=309737&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiffInternal.h (original)
+++ cfe/trunk/include/clang/Tooling/ASTDiff/ASTDiffInternal.h Tue Aug 1 13:17:40 2017
@@ -20,8 +20,9 @@ namespace diff {
using DynTypedNode = ast_type_traits::DynTypedNode;
-struct ComparisonOptions;
class SyntaxTree;
+class SyntaxTreeImpl;
+struct ComparisonOptions;
/// Within a tree, this identifies a node by its preorder offset.
struct NodeId {
@@ -42,151 +43,6 @@ public:
bool isInvalid() const { return Id == InvalidNodeId; }
};
-/// This represents a match between two nodes in the source and destination
-/// trees, meaning that they are likely to be related.
-struct Match {
- NodeId Src, Dst;
-};
-
-enum ChangeKind {
- Delete, // (Src): delete node Src.
- Update, // (Src, Dst): update the value of node Src to match Dst.
- Insert, // (Src, Dst, Pos): insert Src as child of Dst at offset Pos.
- Move // (Src, Dst, Pos): move Src to be a child of Dst at offset Pos.
-};
-
-struct Change {
- ChangeKind Kind;
- NodeId Src, Dst;
- size_t Position;
-
- Change(ChangeKind Kind, NodeId Src, NodeId Dst, size_t Position)
- : Kind(Kind), Src(Src), Dst(Dst), Position(Position) {}
- Change(ChangeKind Kind, NodeId Src) : Kind(Kind), Src(Src) {}
- Change(ChangeKind Kind, NodeId Src, NodeId Dst)
- : Kind(Kind), Src(Src), Dst(Dst) {}
-};
-
-/// Represents a Clang AST node, alongside some additional information.
-struct Node {
- NodeId Parent, LeftMostDescendant, RightMostDescendant;
- int Depth, Height;
- DynTypedNode ASTNode;
- SmallVector<NodeId, 4> Children;
-
- ast_type_traits::ASTNodeKind getType() const { return ASTNode.getNodeKind(); }
- const StringRef getTypeLabel() const { return getType().asStringRef(); }
- bool isLeaf() const { return Children.empty(); }
-};
-
-/// Maps nodes of the left tree to ones on the right, and vice versa.
-class Mapping {
-public:
- Mapping() = default;
- Mapping(Mapping &&Other) = default;
- Mapping &operator=(Mapping &&Other) = default;
- Mapping(int Size1, int Size2) {
- // Maximum possible size after patching one tree.
- int Size = Size1 + Size2;
- SrcToDst = llvm::make_unique<SmallVector<NodeId, 2>[]>(Size);
- DstToSrc = llvm::make_unique<SmallVector<NodeId, 2>[]>(Size);
- }
-
- void link(NodeId Src, NodeId Dst) {
- SrcToDst[Src].push_back(Dst);
- DstToSrc[Dst].push_back(Src);
- }
-
- NodeId getDst(NodeId Src) const {
- if (hasSrc(Src))
- return SrcToDst[Src][0];
- return NodeId();
- }
- NodeId getSrc(NodeId Dst) const {
- if (hasDst(Dst))
- return DstToSrc[Dst][0];
- return NodeId();
- }
- const SmallVector<NodeId, 2> &getAllDsts(NodeId Src) const {
- return SrcToDst[Src];
- }
- const SmallVector<NodeId, 2> &getAllSrcs(NodeId Dst) const {
- return DstToSrc[Dst];
- }
- bool hasSrc(NodeId Src) const { return !SrcToDst[Src].empty(); }
- bool hasDst(NodeId Dst) const { return !DstToSrc[Dst].empty(); }
- bool hasSrcDst(NodeId Src, NodeId Dst) const {
- for (NodeId DstId : SrcToDst[Src])
- if (DstId == Dst)
- return true;
- for (NodeId SrcId : DstToSrc[Dst])
- if (SrcId == Src)
- return true;
- return false;
- }
-
-private:
- std::unique_ptr<SmallVector<NodeId, 2>[]> SrcToDst, DstToSrc;
-};
-
-/// Represents the AST of a TranslationUnit.
-class SyntaxTreeImpl {
-public:
- /// Constructs a tree from the entire translation unit.
- SyntaxTreeImpl(SyntaxTree *Parent, const ASTContext &AST);
- /// Constructs a tree from an AST node.
- SyntaxTreeImpl(SyntaxTree *Parent, Decl *N, const ASTContext &AST);
- SyntaxTreeImpl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST);
- template <class T>
- SyntaxTreeImpl(
- SyntaxTree *Parent,
- typename std::enable_if<std::is_base_of<Stmt, T>::value, T>::type *Node,
- const ASTContext &AST)
- : SyntaxTreeImpl(Parent, dyn_cast<Stmt>(Node), AST) {}
- template <class T>
- SyntaxTreeImpl(
- SyntaxTree *Parent,
- typename std::enable_if<std::is_base_of<Decl, T>::value, T>::type *Node,
- const ASTContext &AST)
- : SyntaxTreeImpl(Parent, dyn_cast<Decl>(Node), AST) {}
-
- SyntaxTree *Parent;
- const ASTContext &AST;
- std::vector<NodeId> Leaves;
- // Maps preorder indices to postorder ones.
- std::vector<int> PostorderIds;
-
- int getSize() const { return Nodes.size(); }
- NodeId root() const { return 0; }
-
- const Node &getNode(NodeId Id) const { return Nodes[Id]; }
- Node &getMutableNode(NodeId Id) { return Nodes[Id]; }
- bool isValidNodeId(NodeId Id) const { return Id >= 0 && Id < getSize(); }
- void addNode(Node &N) { Nodes.push_back(N); }
- int getNumberOfDescendants(NodeId Id) const;
- bool isInSubtree(NodeId Id, NodeId SubtreeRoot) const;
-
- std::string getNodeValueImpl(NodeId Id) const;
- std::string getNodeValueImpl(const DynTypedNode &DTN) const;
- /// Prints the node as "<type>[: <value>](<postorder-id)"
- void printNode(NodeId Id) const { printNode(llvm::outs(), Id); }
- void printNode(raw_ostream &OS, NodeId Id) const;
-
- void printTree() const;
- void printTree(NodeId Root) const;
- void printTree(raw_ostream &OS, NodeId Root) const;
-
- void printAsJsonImpl(raw_ostream &OS) const;
- void printNodeAsJson(raw_ostream &OS, NodeId Id) const;
-
-private:
- /// Nodes in preorder.
- std::vector<Node> Nodes;
-
- void initTree();
- void setLeftMostDescendants();
-};
-
} // end namespace diff
} // end namespace clang
#endif
Modified: cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp?rev=309737&r1=309736&r2=309737&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp (original)
+++ cfe/trunk/lib/Tooling/ASTDiff/ASTDiff.cpp Tue Aug 1 13:17:40 2017
@@ -27,6 +27,56 @@ using namespace clang;
namespace clang {
namespace diff {
+/// Maps nodes of the left tree to ones on the right, and vice versa.
+class Mapping {
+public:
+ Mapping() = default;
+ Mapping(Mapping &&Other) = default;
+ Mapping &operator=(Mapping &&Other) = default;
+ Mapping(int Size1, int Size2) {
+ // Maximum possible size after patching one tree.
+ int Size = Size1 + Size2;
+ SrcToDst = llvm::make_unique<SmallVector<NodeId, 2>[]>(Size);
+ DstToSrc = llvm::make_unique<SmallVector<NodeId, 2>[]>(Size);
+ }
+
+ void link(NodeId Src, NodeId Dst) {
+ SrcToDst[Src].push_back(Dst);
+ DstToSrc[Dst].push_back(Src);
+ }
+
+ NodeId getDst(NodeId Src) const {
+ if (hasSrc(Src))
+ return SrcToDst[Src][0];
+ return NodeId();
+ }
+ NodeId getSrc(NodeId Dst) const {
+ if (hasDst(Dst))
+ return DstToSrc[Dst][0];
+ return NodeId();
+ }
+ const SmallVector<NodeId, 2> &getAllDsts(NodeId Src) const {
+ return SrcToDst[Src];
+ }
+ const SmallVector<NodeId, 2> &getAllSrcs(NodeId Dst) const {
+ return DstToSrc[Dst];
+ }
+ bool hasSrc(NodeId Src) const { return !SrcToDst[Src].empty(); }
+ bool hasDst(NodeId Dst) const { return !DstToSrc[Dst].empty(); }
+ bool hasSrcDst(NodeId Src, NodeId Dst) const {
+ for (NodeId DstId : SrcToDst[Src])
+ if (DstId == Dst)
+ return true;
+ for (NodeId SrcId : DstToSrc[Dst])
+ if (SrcId == Src)
+ return true;
+ return false;
+ }
+
+private:
+ std::unique_ptr<SmallVector<NodeId, 2>[]> SrcToDst, DstToSrc;
+};
+
class ASTDiff::Impl {
public:
SyntaxTreeImpl &T1, &T2;
@@ -82,6 +132,64 @@ private:
friend class ZhangShashaMatcher;
};
+/// Represents the AST of a TranslationUnit.
+class SyntaxTreeImpl {
+public:
+ /// Constructs a tree from the entire translation unit.
+ SyntaxTreeImpl(SyntaxTree *Parent, const ASTContext &AST);
+ /// Constructs a tree from an AST node.
+ SyntaxTreeImpl(SyntaxTree *Parent, Decl *N, const ASTContext &AST);
+ SyntaxTreeImpl(SyntaxTree *Parent, Stmt *N, const ASTContext &AST);
+ template <class T>
+ SyntaxTreeImpl(
+ SyntaxTree *Parent,
+ typename std::enable_if<std::is_base_of<Stmt, T>::value, T>::type *Node,
+ const ASTContext &AST)
+ : SyntaxTreeImpl(Parent, dyn_cast<Stmt>(Node), AST) {}
+ template <class T>
+ SyntaxTreeImpl(
+ SyntaxTree *Parent,
+ typename std::enable_if<std::is_base_of<Decl, T>::value, T>::type *Node,
+ const ASTContext &AST)
+ : SyntaxTreeImpl(Parent, dyn_cast<Decl>(Node), AST) {}
+
+ SyntaxTree *Parent;
+ const ASTContext &AST;
+ std::vector<NodeId> Leaves;
+ // Maps preorder indices to postorder ones.
+ std::vector<int> PostorderIds;
+
+ int getSize() const { return Nodes.size(); }
+ NodeId root() const { return 0; }
+
+ const Node &getNode(NodeId Id) const { return Nodes[Id]; }
+ Node &getMutableNode(NodeId Id) { return Nodes[Id]; }
+ bool isValidNodeId(NodeId Id) const { return Id >= 0 && Id < getSize(); }
+ void addNode(Node &N) { Nodes.push_back(N); }
+ int getNumberOfDescendants(NodeId Id) const;
+ bool isInSubtree(NodeId Id, NodeId SubtreeRoot) const;
+
+ std::string getNodeValueImpl(NodeId Id) const;
+ std::string getNodeValueImpl(const DynTypedNode &DTN) const;
+ /// Prints the node as "<type>[: <value>](<postorder-id)"
+ void printNode(NodeId Id) const { printNode(llvm::outs(), Id); }
+ void printNode(raw_ostream &OS, NodeId Id) const;
+
+ void printTree() const;
+ void printTree(NodeId Root) const;
+ void printTree(raw_ostream &OS, NodeId Root) const;
+
+ void printAsJsonImpl(raw_ostream &OS) const;
+ void printNodeAsJson(raw_ostream &OS, NodeId Id) const;
+
+private:
+ /// Nodes in preorder.
+ std::vector<Node> Nodes;
+
+ void initTree();
+ void setLeftMostDescendants();
+};
+
template <class T>
static bool isNodeExcluded(const SourceManager &SrcMgr, T *N) {
if (!N)
@@ -402,6 +510,9 @@ public:
NodeId getPostorderOffset() const {
return Tree.PostorderIds[getIdInRoot(SNodeId(1))];
}
+ std::string getNodeValue(SNodeId Id) const {
+ return Tree.getNodeValueImpl(getIdInRoot(Id));
+ }
private:
/// Returns the number of leafs in the subtree.
@@ -527,12 +638,9 @@ private:
static constexpr double InsertionCost = 1;
double getUpdateCost(SNodeId Id1, SNodeId Id2) {
- const DynTypedNode &DTN1 = S1.getNode(Id1).ASTNode,
- &DTN2 = S2.getNode(Id2).ASTNode;
- if (!DiffImpl.Options.isMatchingAllowed(DTN1, DTN2))
+ if (!DiffImpl.isMatchingPossible(S1.getIdInRoot(Id1), S2.getIdInRoot(Id2)))
return std::numeric_limits<double>::max();
- return DiffImpl.Options.getNodeDistance(*DiffImpl.T1.Parent, DTN1,
- *DiffImpl.T2.Parent, DTN2);
+ return S1.getNodeValue(Id1) != S2.getNodeValue(Id2);
}
void computeTreeDist() {
@@ -624,8 +732,7 @@ bool ASTDiff::Impl::isomorphic(NodeId Id
const Node &N2 = T2.getNode(Id2);
if (N1.Children.size() != N2.Children.size() ||
!isMatchingPossible(Id1, Id2) ||
- Options.getNodeDistance(*T1.Parent, N1.ASTNode, *T2.Parent, N2.ASTNode) !=
- 0)
+ T1.getNodeValueImpl(Id1) != T2.getNodeValueImpl(Id2))
return false;
for (size_t Id = 0, E = N1.Children.size(); Id < E; ++Id)
if (!isomorphic(N1.Children[Id], N2.Children[Id]))
@@ -900,6 +1007,8 @@ void ASTDiff::printMatch(raw_ostream &OS
DiffImpl->printMatchImpl(OS, M);
}
+SyntaxTree::~SyntaxTree() = default;
+
void SyntaxTree::printAsJson(raw_ostream &OS) { TreeImpl->printAsJsonImpl(OS); }
std::string SyntaxTree::getNodeValue(const DynTypedNode &DTN) const {
More information about the cfe-commits
mailing list