diff options
Diffstat (limited to 'src/ast/attrs.hpp')
-rw-r--r-- | src/ast/attrs.hpp | 107 |
1 files changed, 69 insertions, 38 deletions
diff --git a/src/ast/attrs.hpp b/src/ast/attrs.hpp index 28bfec96..4afbdbc1 100644 --- a/src/ast/attrs.hpp +++ b/src/ast/attrs.hpp @@ -1,3 +1,10 @@ +/* + * MRustC - Rust Compiler + * - By John Hodge (Mutabah/thePowersGang) + * + * ast/attrs.hpp + * - AST Attributes (#[foo] and #![foo]) + */ #ifndef _AST_ATTRS_HPP_ #define _AST_ATTRS_HPP_ @@ -5,93 +12,117 @@ namespace AST { // -class MetaItem; +class Attribute; +::std::ostream& operator<<(::std::ostream& os, const Attribute& x); -class MetaItems +/// A list of attributes on an item (searchable by the attribute name) +class AttributeList { public: - Span m_span; - ::std::vector<MetaItem> m_items; - - virtual ~MetaItems(); - MetaItems() {} - MetaItems(MetaItems&&) = default; - MetaItems& operator=(MetaItems&&) = default; - MetaItems(const MetaItems&) = delete; - MetaItems(Span sp, ::std::vector<MetaItem> items): - m_span( mv$(sp) ), + ::std::vector<Attribute> m_items; + + AttributeList() {} + AttributeList(::std::vector<Attribute> items): m_items( mv$(items) ) { } - void push_back(MetaItem i); + // Move present + AttributeList(AttributeList&&) = default; + AttributeList& operator=(AttributeList&&) = default; + // No copy + AttributeList(const AttributeList&) = delete; + AttributeList& operator=(const AttributeList&) = delete; + // Explicit clone + AttributeList clone() const; - MetaItems clone() const; + void push_back(Attribute i); - MetaItem* get(const char *name) { return const_cast<MetaItem*>( const_cast<const MetaItems*>(this)->get(name)); } - const MetaItem* get(const char *name) const; + const Attribute* get(const char *name) const; + Attribute* get(const char *name) { + return const_cast<Attribute*>( const_cast<const AttributeList*>(this)->get(name)); + } bool has(const char *name) const { return get(name) != 0; } - friend ::std::ostream& operator<<(::std::ostream& os, const MetaItems& x) { - return os << "[" << x.m_items << "]"; + friend ::std::ostream& operator<<(::std::ostream& os, const AttributeList& x) { + for(const auto& i : x.m_items) { + os << "#[" << i << "]"; + } + return os; } }; -TAGGED_UNION(MetaItemData, None, +TAGGED_UNION(AttributeData, None, (None, struct {}), (String, struct { ::std::string val; }), (List, struct { - ::std::vector<MetaItem> sub_items; + ::std::vector<Attribute> sub_items; }) ); -class MetaItem +// An attribute can has a name, and optional data: +// Data can be: +// - A parenthesised token tree +// > In 1.19 this was actually just sub-attributes +// - an associated (string) literal + +class Attribute { + Span m_span; ::std::string m_name; - MetaItemData m_data; + AttributeData m_data; + mutable bool m_is_used; public: - virtual ~MetaItem(); - MetaItem() {} - MetaItem(MetaItem&& ) = default; - MetaItem& operator=(MetaItem&& ) = default; - MetaItem(::std::string name): + Attribute(Span sp, ::std::string name): + m_span(::std::move(sp)), m_name(name), - m_data( MetaItemData::make_None({}) ) + m_data( AttributeData::make_None({}) ) { } - MetaItem(::std::string name, ::std::string str_val): + Attribute(Span sp, ::std::string name, ::std::string str_val): + m_span(::std::move(sp)), m_name(name), - m_data( MetaItemData::make_String({mv$(str_val)}) ) + m_data( AttributeData::make_String({mv$(str_val)}) ) { } - MetaItem(::std::string name, ::std::vector<MetaItem> items): + Attribute(Span sp, ::std::string name, ::std::vector<Attribute> items): + m_span(::std::move(sp)), m_name(name), - m_data( MetaItemData::make_List({mv$(items)}) ) + m_data( AttributeData::make_List({mv$(items)}) ) { } - MetaItem clone() const; + Attribute(const Attribute& ) = delete; + Attribute& operator=(const Attribute&& ) = delete; + Attribute(Attribute&& ) = default; + Attribute& operator=(Attribute&& ) = default; + Attribute clone() const; + + void mark_used() const { m_is_used = true; } + bool is_used() const { return m_is_used; } - void mark_used() {} + const Span& span() const { return m_span; } const ::std::string& name() const { return m_name; } + const AttributeData& data() const { return m_data; } + // Legacy accessors/checkers bool has_noarg() const { return m_data.is_None(); } bool has_string() const { return m_data.is_String(); } const ::std::string& string() const { return m_data.as_String().val; } bool has_sub_items() const { return m_data.is_List(); } - const ::std::vector<MetaItem>& items() const { return m_data.as_List().sub_items; } - ::std::vector<MetaItem>& items() { return m_data.as_List().sub_items; } + const ::std::vector<Attribute>& items() const { return m_data.as_List().sub_items; } + ::std::vector<Attribute>& items() { return m_data.as_List().sub_items; } - friend ::std::ostream& operator<<(::std::ostream& os, const MetaItem& x) { + friend ::std::ostream& operator<<(::std::ostream& os, const Attribute& x) { os << x.m_name; - TU_MATCH(MetaItemData, (x.m_data), (e), + TU_MATCHA( (x.m_data), (e), (None, ), (String, |