Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d3ffa844 authored by Adam Lesinski's avatar Adam Lesinski
Browse files

AAPT2: Cleanup Visitors for XML and Values

Test: make aapt2_tests
Change-Id: Ib61f64c155a380115610edeaf2d65e60258a2426
parent 43ddc05b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@ namespace aapt {

namespace {

class PrintVisitor : public ValueVisitor {
class PrintVisitor : public DescendingValueVisitor {
 public:
  using ValueVisitor::Visit;
  using DescendingValueVisitor::Visit;

  void Visit(Attribute* attr) override {
    std::cout << "(attr) type=";
+12 −2
Original line number Diff line number Diff line
@@ -35,15 +35,25 @@ std::ostream& operator<<(std::ostream& out, const Value& value) {
}

template <typename Derived>
void BaseValue<Derived>::Accept(RawValueVisitor* visitor) {
void BaseValue<Derived>::Accept(ValueVisitor* visitor) {
  visitor->Visit(static_cast<Derived*>(this));
}

template <typename Derived>
void BaseItem<Derived>::Accept(RawValueVisitor* visitor) {
void BaseValue<Derived>::Accept(ConstValueVisitor* visitor) const {
  visitor->Visit(static_cast<const Derived*>(this));
}

template <typename Derived>
void BaseItem<Derived>::Accept(ValueVisitor* visitor) {
  visitor->Visit(static_cast<Derived*>(this));
}

template <typename Derived>
void BaseItem<Derived>::Accept(ConstValueVisitor* visitor) const {
  visitor->Visit(static_cast<const Derived*>(this));
}

RawString::RawString(const StringPool::Ref& ref) : value(ref) {}

bool RawString::Equals(const Value* value) const {
+45 −17
Original line number Diff line number Diff line
@@ -33,7 +33,8 @@

namespace aapt {

struct RawValueVisitor;
class ValueVisitor;
class ConstValueVisitor;

// A resource value. This is an all-encompassing representation
// of Item and Map and their subclasses. The way to do
@@ -45,36 +46,58 @@ class Value {
  virtual ~Value() = default;

  // Whether this value is weak and can be overridden without warning or error. Default is false.
  bool IsWeak() const { return weak_; }
  bool IsWeak() const {
    return weak_;
  }

  void SetWeak(bool val) { weak_ = val; }
  void SetWeak(bool val) {
    weak_ = val;
  }

  // Whether the value is marked as translatable.
  // This does not persist when flattened.
  // Whether the value is marked as translatable. This does not persist when flattened to binary.
  // It is only used during compilation phase.
  void SetTranslatable(bool val) { translatable_ = val; }
  void SetTranslatable(bool val) {
    translatable_ = val;
  }

  // Default true.
  bool IsTranslatable() const { return translatable_; }
  bool IsTranslatable() const {
    return translatable_;
  }

  // Returns the source where this value was defined.
  const Source& GetSource() const { return source_; }
  const Source& GetSource() const {
    return source_;
  }

  void SetSource(const Source& source) { source_ = source; }
  void SetSource(const Source& source) {
    source_ = source;
  }

  void SetSource(Source&& source) { source_ = std::move(source); }
  void SetSource(Source&& source) {
    source_ = std::move(source);
  }

  // Returns the comment that was associated with this resource.
  const std::string& GetComment() const { return comment_; }
  const std::string& GetComment() const {
    return comment_;
  }

  void SetComment(const android::StringPiece& str) { comment_ = str.to_string(); }
  void SetComment(const android::StringPiece& str) {
    comment_ = str.to_string();
  }

  void SetComment(std::string&& str) { comment_ = std::move(str); }
  void SetComment(std::string&& str) {
    comment_ = std::move(str);
  }

  virtual bool Equals(const Value* value) const = 0;

  // Calls the appropriate overload of ValueVisitor.
  virtual void Accept(RawValueVisitor* visitor) = 0;
  virtual void Accept(ValueVisitor* visitor) = 0;

  // Calls the appropriate overload of ConstValueVisitor.
  virtual void Accept(ConstValueVisitor* visitor) const = 0;

  // Clone the value. `new_pool` is the new StringPool that
  // any resources with strings should use when copying their string.
@@ -95,7 +118,8 @@ class Value {
// Inherit from this to get visitor accepting implementations for free.
template <typename Derived>
struct BaseValue : public Value {
  void Accept(RawValueVisitor* visitor) override;
  void Accept(ValueVisitor* visitor) override;
  void Accept(ConstValueVisitor* visitor) const override;
};

// A resource item with a single value. This maps to android::ResTable_entry.
@@ -111,7 +135,8 @@ struct Item : public Value {
// Inherit from this to get visitor accepting implementations for free.
template <typename Derived>
struct BaseItem : public Item {
  void Accept(RawValueVisitor* visitor) override;
  void Accept(ValueVisitor* visitor) override;
  void Accept(ConstValueVisitor* visitor) const override;
};

// A reference to another resource. This maps to android::Res_value::TYPE_REFERENCE.
@@ -144,7 +169,10 @@ bool operator==(const Reference&, const Reference&);

// An ID resource. Has no real value, just a place holder.
struct Id : public BaseItem<Id> {
  Id() { weak_ = true; }
  Id() {
    weak_ = true;
  }

  bool Equals(const Value* value) const override;
  bool Flatten(android::Res_value* out) const override;
  Id* Clone(StringPool* new_pool) const override;
+79 −37
Original line number Diff line number Diff line
@@ -22,12 +22,11 @@

namespace aapt {

/**
 * Visits a value and invokes the appropriate method based on its type. Does not
 * traverse into compound types. Use ValueVisitor for that.
 */
struct RawValueVisitor {
  virtual ~RawValueVisitor() = default;
// Visits a value and invokes the appropriate method based on its type.
// Does not traverse into compound types. Use ValueVisitor for that.
class ValueVisitor {
 public:
  virtual ~ValueVisitor() = default;

  virtual void VisitAny(Value* value) {}
  virtual void VisitItem(Item* value) { VisitAny(value); }
@@ -46,21 +45,67 @@ struct RawValueVisitor {
  virtual void Visit(Styleable* value) { VisitAny(value); }
};

// Const version of ValueVisitor.
class ConstValueVisitor {
 public:
  virtual ~ConstValueVisitor() = default;

  virtual void VisitAny(const Value* value) {
  }
  virtual void VisitItem(const Item* value) {
    VisitAny(value);
  }
  virtual void Visit(const Reference* value) {
    VisitItem(value);
  }
  virtual void Visit(const RawString* value) {
    VisitItem(value);
  }
  virtual void Visit(const String* value) {
    VisitItem(value);
  }
  virtual void Visit(const StyledString* value) {
    VisitItem(value);
  }
  virtual void Visit(const FileReference* value) {
    VisitItem(value);
  }
  virtual void Visit(const Id* value) {
    VisitItem(value);
  }
  virtual void Visit(const BinaryPrimitive* value) {
    VisitItem(value);
  }

  virtual void Visit(const Attribute* value) {
    VisitAny(value);
  }
  virtual void Visit(const Style* value) {
    VisitAny(value);
  }
  virtual void Visit(const Array* value) {
    VisitAny(value);
  }
  virtual void Visit(const Plural* value) {
    VisitAny(value);
  }
  virtual void Visit(const Styleable* value) {
    VisitAny(value);
  }
};

// NOLINT, do not add parentheses around T.
#define DECL_VISIT_COMPOUND_VALUE(T)                   \
  virtual void Visit(T* value) override { /* NOLINT */ \
    VisitSubValues(value);                             \
  }

/**
 * Visits values, and if they are compound values, visits the components as
 * well.
 */
struct ValueVisitor : public RawValueVisitor {
// Visits values, and if they are compound values, descends into their components as well.
struct DescendingValueVisitor : public ValueVisitor {
  // The compiler will think we're hiding an overload, when we actually intend
  // to call into RawValueVisitor. This will expose the visit methods in the
  // super class so the compiler knows we are trying to call them.
  using RawValueVisitor::Visit;
  using ValueVisitor::Visit;

  void VisitSubValues(Attribute* attribute) {
    for (Attribute::Symbol& symbol : attribute->symbols) {
@@ -106,37 +151,30 @@ struct ValueVisitor : public RawValueVisitor {
  DECL_VISIT_COMPOUND_VALUE(Styleable);
};

/**
 * Do not use directly. Helper struct for dyn_cast.
 */
// Do not use directly. Helper struct for dyn_cast.
template <typename T>
struct DynCastVisitor : public RawValueVisitor {
  T* value = nullptr;
struct DynCastVisitor : public ConstValueVisitor {
  const T* value = nullptr;

  void Visit(T* v) override { value = v; }
  void Visit(const T* v) override {
    value = v;
  }
};

/**
 * Specialization that checks if the value is an Item.
 */
// Specialization that checks if the value is an Item.
template <>
struct DynCastVisitor<Item> : public RawValueVisitor {
  Item* value = nullptr;
struct DynCastVisitor<Item> : public ConstValueVisitor {
  const Item* value = nullptr;

  void VisitItem(Item* item) override { value = item; }
  void VisitItem(const Item* item) override {
    value = item;
  }
};

// Returns a valid pointer to T if the value is an instance of T. Returns nullptr if value is
// nullptr of if value is not an instance of T.
template <typename T>
const T* ValueCast(const Value* value) {
  return ValueCast<T>(const_cast<Value*>(value));
}

/**
 * Returns a valid pointer to T if the Value is of subtype T.
 * Otherwise, returns nullptr.
 */
template <typename T>
T* ValueCast(Value* value) {
  if (!value) {
    return nullptr;
  }
@@ -145,8 +183,13 @@ T* ValueCast(Value* value) {
  return visitor.value;
}

inline void VisitAllValuesInPackage(ResourceTablePackage* pkg,
                                    RawValueVisitor* visitor) {
// Non-const version of ValueCast.
template <typename T>
T* ValueCast(Value* value) {
  return const_cast<T*>(ValueCast<T>(static_cast<const Value*>(value)));
}

inline void VisitAllValuesInPackage(ResourceTablePackage* pkg, ValueVisitor* visitor) {
  for (auto& type : pkg->types) {
    for (auto& entry : type->entries) {
      for (auto& config_value : entry->values) {
@@ -156,8 +199,7 @@ inline void VisitAllValuesInPackage(ResourceTablePackage* pkg,
  }
}

inline void VisitAllValuesInTable(ResourceTable* table,
                                  RawValueVisitor* visitor) {
inline void VisitAllValuesInTable(ResourceTable* table, ValueVisitor* visitor) {
  for (auto& pkg : table->packages) {
    VisitAllValuesInPackage(pkg.get(), visitor);
  }
+5 −5
Original line number Diff line number Diff line
@@ -24,16 +24,16 @@

namespace aapt {

struct SingleReferenceVisitor : public ValueVisitor {
  using ValueVisitor::Visit;
struct SingleReferenceVisitor : public DescendingValueVisitor {
  using DescendingValueVisitor::Visit;

  Reference* visited = nullptr;

  void Visit(Reference* ref) override { visited = ref; }
};

struct StyleVisitor : public ValueVisitor {
  using ValueVisitor::Visit;
struct StyleVisitor : public DescendingValueVisitor {
  using DescendingValueVisitor::Visit;

  std::list<Reference*> visited_refs;
  Style* visited_style = nullptr;
@@ -42,7 +42,7 @@ struct StyleVisitor : public ValueVisitor {

  void Visit(Style* style) override {
    visited_style = style;
    ValueVisitor::Visit(style);
    DescendingValueVisitor::Visit(style);
  }
};

Loading