diff options
author | Johannes Altmanninger <aclopte@gmail.com> | 2017-08-20 12:09:07 +0000 |
---|---|---|
committer | Johannes Altmanninger <aclopte@gmail.com> | 2017-08-20 12:09:07 +0000 |
commit | d196930799224f906ba4c5d3c64bafa1cad8d156 (patch) | |
tree | 1734d5463a02b3d25c6a372c7d3f9ba78dc4f3e8 /clang/lib/Tooling/ASTDiff/ASTDiff.cpp | |
parent | 6c9ce223ea0cd092ffbe0a913a5796b0c40be1f4 (diff) | |
download | bcm5719-llvm-d196930799224f906ba4c5d3c64bafa1cad8d156.tar.gz bcm5719-llvm-d196930799224f906ba4c5d3c64bafa1cad8d156.zip |
[clang-diff] Fix similarity computation
Summary:
Add separate tests for the top-down and the bottom-up phase, as well as
one for the optimal matching.
Reviewers: arphaman
Subscribers: klimek
Differential Revision: https://reviews.llvm.org/D36185
llvm-svn: 311284
Diffstat (limited to 'clang/lib/Tooling/ASTDiff/ASTDiff.cpp')
-rw-r--r-- | clang/lib/Tooling/ASTDiff/ASTDiff.cpp | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp index ada7cbcfc55..22f3a4e4f06 100644 --- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp +++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp @@ -92,7 +92,7 @@ private: // Computes the ratio of common descendants between the two nodes. // Descendants are only considered to be equal when they are mapped in M. - double getSimilarity(const Mapping &M, NodeId Id1, NodeId Id2) const; + double getJaccardSimilarity(const Mapping &M, NodeId Id1, NodeId Id2) const; // Returns the node that has the highest degree of similarity. NodeId findCandidate(const Mapping &M, NodeId Id1) const; @@ -714,8 +714,8 @@ bool ASTDiff::Impl::haveSameParents(const Mapping &M, NodeId Id1, void ASTDiff::Impl::addOptimalMapping(Mapping &M, NodeId Id1, NodeId Id2) const { - if (std::max(T1.getNumberOfDescendants(Id1), - T2.getNumberOfDescendants(Id2)) >= Options.MaxSize) + if (std::max(T1.getNumberOfDescendants(Id1), T2.getNumberOfDescendants(Id2)) > + Options.MaxSize) return; ZhangShashaMatcher Matcher(*this, T1, T2, Id1, Id2); std::vector<std::pair<NodeId, NodeId>> R = Matcher.getMatchingNodes(); @@ -727,16 +727,23 @@ void ASTDiff::Impl::addOptimalMapping(Mapping &M, NodeId Id1, } } -double ASTDiff::Impl::getSimilarity(const Mapping &M, NodeId Id1, - NodeId Id2) const { - if (Id1.isInvalid() || Id2.isInvalid()) - return 0.0; +double ASTDiff::Impl::getJaccardSimilarity(const Mapping &M, NodeId Id1, + NodeId Id2) const { int CommonDescendants = 0; const Node &N1 = T1.getNode(Id1); - for (NodeId Id = Id1 + 1; Id <= N1.RightMostDescendant; ++Id) - CommonDescendants += int(T2.isInSubtree(M.getDst(Id), Id2)); - return 2.0 * CommonDescendants / - (T1.getNumberOfDescendants(Id1) + T2.getNumberOfDescendants(Id2)); + // Count the common descendants, excluding the subtree root. + for (NodeId Src = Id1 + 1; Src <= N1.RightMostDescendant; ++Src) { + NodeId Dst = M.getDst(Src); + CommonDescendants += int(Dst.isValid() && T2.isInSubtree(Dst, Id2)); + } + // We need to subtract 1 to get the number of descendants excluding the root. + double Denominator = T1.getNumberOfDescendants(Id1) - 1 + + T2.getNumberOfDescendants(Id2) - 1 - CommonDescendants; + // CommonDescendants is less than the size of one subtree. + assert(Denominator >= 0 && "Expected non-negative denominator."); + if (Denominator == 0) + return 0; + return CommonDescendants / Denominator; } NodeId ASTDiff::Impl::findCandidate(const Mapping &M, NodeId Id1) const { @@ -747,7 +754,7 @@ NodeId ASTDiff::Impl::findCandidate(const Mapping &M, NodeId Id1) const { continue; if (M.hasDst(Id2)) continue; - double Similarity = getSimilarity(M, Id1, Id2); + double Similarity = getJaccardSimilarity(M, Id1, Id2); if (Similarity >= Options.MinSimilarity && Similarity > HighestSimilarity) { HighestSimilarity = Similarity; Candidate = Id2; @@ -767,8 +774,8 @@ void ASTDiff::Impl::matchBottomUp(Mapping &M) const { } break; } - const Node &N1 = T1.getNode(Id1); bool Matched = M.hasSrc(Id1); + const Node &N1 = T1.getNode(Id1); bool MatchedChildren = std::any_of(N1.Children.begin(), N1.Children.end(), [&](NodeId Child) { return M.hasSrc(Child); }); @@ -836,6 +843,8 @@ ASTDiff::Impl::Impl(SyntaxTree::Impl &T1, SyntaxTree::Impl &T2, void ASTDiff::Impl::computeMapping() { TheMapping = matchTopDown(); + if (Options.StopAfterTopDown) + return; matchBottomUp(TheMapping); } |