summaryrefslogtreecommitdiff
path: root/src/ast/attrs.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast/attrs.hpp')
-rw-r--r--src/ast/attrs.hpp107
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,