mirror of
git://sourceware.org/git/libabigail.git
synced 2025-01-30 05:12:51 +00:00
Support diffing entities of different kinds.
* include/abg-comparison.h (class distinct_diff): Declare new type. (compute_diff_for_distinct_kinds): Declare new function. * src/abg-comparison.cc (distinct_diff::{distinct_diff, first, second, entities_are_of_distinct_kinds, length, report}): Define new member functions. (compute_diff_for_distinct_kinds, try_to_diff_distinct_kinds): Define new function. (compute_diff_for_types, compute_diff_for_decls): Support diffing entities of different kinds. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
parent
421719b075
commit
6f3506215b
@ -294,6 +294,52 @@ compute_diff(const type_base_sptr,
|
||||
const type_base_sptr,
|
||||
diff_context_sptr ctxt);
|
||||
|
||||
class distinct_diff;
|
||||
|
||||
/// Convenience typedef for a shared pointer to distinct_types_diff
|
||||
typedef shared_ptr<distinct_diff> distinct_diff_sptr;
|
||||
|
||||
/// An abstraction of a diff between entities that are of a different
|
||||
/// kind (disctinct).
|
||||
class distinct_diff : public diff
|
||||
{
|
||||
struct priv;
|
||||
typedef shared_ptr<priv> priv_sptr;
|
||||
priv_sptr priv_;
|
||||
|
||||
protected:
|
||||
distinct_diff(decl_base_sptr first,
|
||||
decl_base_sptr second,
|
||||
diff_context_sptr ctxt = diff_context_sptr());
|
||||
public:
|
||||
|
||||
const decl_base_sptr
|
||||
first() const;
|
||||
|
||||
const decl_base_sptr
|
||||
second() const;
|
||||
|
||||
virtual unsigned
|
||||
length() const;
|
||||
|
||||
virtual void
|
||||
report(ostream& out, const string& indent = "") const;
|
||||
|
||||
static bool
|
||||
entities_are_of_distinct_kinds(decl_base_sptr first,
|
||||
decl_base_sptr second);
|
||||
|
||||
friend distinct_diff_sptr
|
||||
compute_diff_for_distinct_kinds(const decl_base_sptr first,
|
||||
const decl_base_sptr second,
|
||||
diff_context_sptr ctxt);
|
||||
};// end class distinct_types_diff
|
||||
|
||||
distinct_diff_sptr
|
||||
compute_diff_for_distinct_kinds(const decl_base_sptr,
|
||||
const decl_base_sptr,
|
||||
diff_context_sptr ctxt);
|
||||
|
||||
class var_diff;
|
||||
|
||||
/// Convenience typedef for a shared pointer to var_diff.
|
||||
|
@ -142,6 +142,124 @@ diff_context::add_diff(decl_base_sptr first,
|
||||
diff_sptr d)
|
||||
{priv_->decls_diff_map[std::make_pair(first, second)] = d;}
|
||||
|
||||
/// <distinct_diff stuff>
|
||||
|
||||
/// The private data structure for @ref distinct_diff.
|
||||
struct distinct_diff::priv
|
||||
{
|
||||
};// end struct distinct_diff
|
||||
|
||||
/// Constructor for @ref distinct_diff.
|
||||
///
|
||||
/// Note that the two entities considered for the diff (and passed in
|
||||
/// parameter) must be of different kinds.
|
||||
///
|
||||
/// @param first the first entity to consider for the diff.
|
||||
///
|
||||
/// @param second the second entity to consider for the diff.
|
||||
///
|
||||
/// @param ctxt the context of the diff.
|
||||
distinct_diff::distinct_diff(decl_base_sptr first,
|
||||
decl_base_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
: diff(first, second, ctxt),
|
||||
priv_(new priv)
|
||||
{assert(entities_are_of_distinct_kinds(first, second));}
|
||||
|
||||
/// Getter for the first subject of the diff.
|
||||
///
|
||||
/// @return the first subject of the diff.
|
||||
const decl_base_sptr
|
||||
distinct_diff::first() const
|
||||
{return first_subject();}
|
||||
|
||||
/// Getter for the second subject of the diff.
|
||||
///
|
||||
/// @return the second subject of the diff.
|
||||
const decl_base_sptr
|
||||
distinct_diff::second() const
|
||||
{return second_subject();}
|
||||
|
||||
/// Test if the two arguments are of different kind.
|
||||
///
|
||||
/// @param first the first argument to test for similarity in kind.
|
||||
///
|
||||
/// @param second the second argument to test for similarity in kind.
|
||||
///
|
||||
/// @return true iff the two arguments are of different kind.
|
||||
bool
|
||||
distinct_diff::entities_are_of_distinct_kinds(decl_base_sptr first,
|
||||
decl_base_sptr second)
|
||||
{
|
||||
if (!!first != !!second)
|
||||
return true;
|
||||
if (first == second)
|
||||
return true;
|
||||
|
||||
return typeid(*first.get()) != typeid(*second.get());
|
||||
}
|
||||
|
||||
/// @return 1 if the two subjects of the diff are different, 0
|
||||
/// otherwise.
|
||||
unsigned
|
||||
distinct_diff::length() const
|
||||
{
|
||||
if (first() == second())
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Emit a report about the current diff instance.
|
||||
///
|
||||
/// @param out the output stream to send the diff report to.
|
||||
///
|
||||
/// @param indent the indentation string to use in the report.
|
||||
void
|
||||
distinct_diff::report(ostream& out, const string& indent) const
|
||||
{
|
||||
if (length() == 0)
|
||||
return;
|
||||
|
||||
decl_base_sptr f = first(), s = second();
|
||||
|
||||
string f_repr = f ? f->get_pretty_representation() : "'void'";
|
||||
string s_repr = s ? s->get_pretty_representation() : "'void'";
|
||||
|
||||
out << indent << "entity changed from " << f_repr << " to " << s_repr << "\n";
|
||||
}
|
||||
|
||||
/// Try to diff entities that are of distinct kinds.
|
||||
///
|
||||
/// @param first the first entity to consider for the diff.
|
||||
///
|
||||
/// @param second the second entity to consider for the diff.
|
||||
///
|
||||
/// @param ctxt the context of the diff.
|
||||
///
|
||||
/// @return a non-null diff if a diff object could be built, null
|
||||
/// otherwise.
|
||||
distinct_diff_sptr
|
||||
compute_diff_for_distinct_kinds(const decl_base_sptr first,
|
||||
const decl_base_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{
|
||||
if (!distinct_diff::entities_are_of_distinct_kinds(first, second))
|
||||
return distinct_diff_sptr();
|
||||
|
||||
if (diff_sptr dif = ctxt->has_diff_for(first, second))
|
||||
{
|
||||
distinct_diff_sptr d = dynamic_pointer_cast<distinct_diff>(dif);
|
||||
assert(d);
|
||||
return d;
|
||||
}
|
||||
distinct_diff_sptr result(new distinct_diff(first, second, ctxt));
|
||||
|
||||
ctxt->add_diff(first, second, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// </distinct_diff stuff>
|
||||
|
||||
/// Try to compute a diff on two instances of DiffType representation.
|
||||
///
|
||||
/// The function template performs the diff if and only if the decl
|
||||
@ -214,6 +332,22 @@ try_to_diff<class_decl>(const decl_base_sptr first,
|
||||
return diff_sptr();
|
||||
}
|
||||
|
||||
/// Try to diff entities that are of distinct kinds.
|
||||
///
|
||||
/// @param first the first entity to consider for the diff.
|
||||
///
|
||||
/// @param second the second entity to consider for the diff.
|
||||
///
|
||||
/// @param ctxt the context of the diff.
|
||||
///
|
||||
/// @return a non-null diff if a diff object could be built, null
|
||||
/// otherwise.
|
||||
static diff_sptr
|
||||
try_to_diff_distinct_kinds(const decl_base_sptr first,
|
||||
const decl_base_sptr second,
|
||||
diff_context_sptr ctxt)
|
||||
{return compute_diff_for_distinct_kinds(first, second, ctxt);}
|
||||
|
||||
/// Compute the difference between two types.
|
||||
///
|
||||
/// The function considers every possible types known to libabigail
|
||||
@ -238,13 +372,19 @@ compute_diff_for_types(const decl_base_sptr first,
|
||||
{
|
||||
diff_sptr d;
|
||||
|
||||
((d = try_to_diff<type_decl>(first, second, ctxt))
|
||||
||(d = try_to_diff<enum_type_decl>(first, second, ctxt))
|
||||
||(d = try_to_diff<class_decl>(first, second,ctxt))
|
||||
||(d = try_to_diff<pointer_type_def>(first, second, ctxt))
|
||||
||(d = try_to_diff<reference_type_def>(first, second, ctxt))
|
||||
||(d = try_to_diff<qualified_type_def>(first, second, ctxt))
|
||||
||(d = try_to_diff<typedef_decl>(first, second, ctxt)));
|
||||
const decl_base_sptr f = get_type_declaration(as_non_member_type(first));
|
||||
const decl_base_sptr s = get_type_declaration(as_non_member_type(second));
|
||||
|
||||
((d = try_to_diff_distinct_kinds(f, s, ctxt))
|
||||
||(d = try_to_diff<type_decl>(f, s, ctxt))
|
||||
||(d = try_to_diff<enum_type_decl>(f, s, ctxt))
|
||||
||(d = try_to_diff<class_decl>(f, s,ctxt))
|
||||
||(d = try_to_diff<pointer_type_def>(f, s, ctxt))
|
||||
||(d = try_to_diff<reference_type_def>(f, s, ctxt))
|
||||
||(d = try_to_diff<qualified_type_def>(f, s, ctxt))
|
||||
||(d = try_to_diff<typedef_decl>(f, s, ctxt)));
|
||||
|
||||
assert(d);
|
||||
|
||||
return d;
|
||||
}
|
||||
@ -307,9 +447,12 @@ compute_diff_for_decls(const decl_base_sptr first,
|
||||
|
||||
diff_sptr d;
|
||||
|
||||
((d = try_to_diff<function_decl>(first, second, ctxt))
|
||||
((d = try_to_diff_distinct_kinds(first, second, ctxt))
|
||||
|| (d = try_to_diff<function_decl>(first, second, ctxt))
|
||||
|| (d = try_to_diff<var_decl>(first, second, ctxt)));
|
||||
|
||||
assert(d);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user