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