// file : CCF/IDL2/SemanticGraph/Elements.hpp // author : Boris Kolpackov // cvs-id : $Id$ #ifndef CCF_IDL2_SEMANTIC_GRAPH_ELEMENTS_HPP #define CCF_IDL2_SEMANTIC_GRAPH_ELEMENTS_HPP #include #include #include #include "Graph.hpp" #include "CCF/CompilerElements/FileSystem.hpp" #include "CCF/CompilerElements/Introspection.hpp" #include "CCF/CompilerElements/Context.hpp" #include "CCF/IDL2/SemanticGraph/Name.hpp" namespace CCF { namespace IDL2 { namespace SemanticGraph { // // typedef fs::path Path; // // // class Node; class Edge; // Node & Edge // // class Edge : public virtual Introspection::Object { public: CompilerElements::Context const& context () const { return context_; } CompilerElements::Context& context () { return context_; } public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; virtual ~Edge (); Edge (); private: CompilerElements::Context context_; }; inline bool operator== (Edge const& x, Edge const& y) { return &x == &y; } class Node : public virtual Introspection::Object { public: CompilerElements::Context const& context () const { return context_; } CompilerElements::Context& context () { return context_; } public: Path const& file () const { return file_; } unsigned long line () const { return line_; } public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; virtual ~Node () = 0; Node (Path const& path, unsigned long line); Node (); // For virtual inheritance only. // This is a bunch of experimantal sink functions that allow // extensions in the form of one-way edges (see Executor stuff // in CIDL for example). // void add_edge_left (Edge&) { } void add_edge_right (Edge&) { } private: Path file_; unsigned long line_; CompilerElements::Context context_; }; inline bool operator== (Node const& x, Node const& y) { return &x == &y; } // // // class Scope; class Nameable; class Names : public virtual Edge { public: SimpleName name () const { return name_; } Scope& scope () const { return *scope_; } Nameable& named () const { return *named_; } public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Names (SimpleName const& name) : name_ (name) { type_info (static_type_info ()); } void set_left_node (Scope& n) { scope_ = &n; } void set_right_node (Nameable& n) { named_ = &n; } private: Scope* scope_; Nameable* named_; SimpleName name_; }; class Defines : public virtual Names { public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Defines (SimpleName const& name) : Names (name) { type_info (static_type_info ()); } }; class Mentions : public virtual Names { public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Mentions (SimpleName const& name) : Names (name) { type_info (static_type_info ()); } }; class Aliases : public virtual Names { public: SimpleName synonym () const { return name (); } /* Let me know if you need this function. ScopedName eponym () const { } */ public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Aliases (SimpleName const& synonym) : Names (synonym) { type_info (static_type_info ()); } }; class Nameable : public virtual Node { typedef std::vector Named_; public: virtual SimpleName name () const; virtual ScopedName scoped_name () const; bool defined () const { return defined_; } typedef Named_::const_iterator NamedIterator; NamedIterator named_begin () const { return named_.begin (); } NamedIterator named_end () const { return named_.end (); } public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Nameable () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Nameable () = 0; void add_edge_right (Defines& e) { defined_ = true; named_.push_back (&e); } void add_edge_right (Names& e) { named_.push_back (&e); } private: Named_ named_; bool defined_; }; typedef std::set Nameables; class Scope; class Extends : public virtual Edge { public: Scope& extender () const { return *extender_; } Scope& extendee () const { return *extendee_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Extends () { type_info (static_type_info ()); } void set_left_node (Scope& s) { extender_ = &s; } void set_right_node (Scope& s) { extendee_ = &s; } private: Scope* extender_; Scope* extendee_; }; class Scope : public virtual Nameable { private: typedef std::vector Extends_; typedef std::vector Names_; typedef std::map NamesMap_; public: // // typedef Extends_::const_iterator ExtendsIterator; ExtendsIterator extends_begin () const { return extends_.begin (); } ExtendsIterator extends_end () const { return extends_.end (); } // // typedef Names_::const_iterator NamesIterator; typedef std::pair NamesIteratorPair; NamesIterator names_begin () const { return names_.begin (); } NamesIterator names_end () const { return names_.end (); } NamesIteratorPair find (SimpleName const& name) const { NamesMap_::const_iterator i (names_map_.find (name)); if (i == names_map_.end ()) { return NamesIteratorPair (names_.end (), names_.end ()); } else { return NamesIteratorPair (i->second.begin (), i->second.end ()); } } Nameables lookup (Name const& name) const; void lookup (Name const& name, Nameables& result) const; public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Scope () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Scope () = 0; void add_edge_left (Names& e); void add_edge_left (Extends& e) { extends_.push_back (&e); } void add_edge_right (Extends&) { } using Nameable::add_edge_right; private: Extends_ extends_; Names_ names_; NamesMap_ names_map_; }; // // // class Belongs; class ArgumentsWithType; //@@ I can make an alias Classifies for Belongs? // class Type : public virtual Nameable { public: virtual bool complete () const = 0; static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Type () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Type () = 0; using Nameable::add_edge_right; void add_edge_right (Belongs& e) { slassifies_.push_back (&e); } void add_edge_left (ArgumentsWithType&) { } using Node::add_edge_right; using Node::add_edge_left; private: typedef std::vector Classifies_; Classifies_ slassifies_; }; class Instance : public virtual Node { public: Belongs& belongs () const { return *belongs_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Instance () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Instance () = 0; void add_edge_left (Belongs& e) { belongs_ = &e; } private: Belongs* belongs_; }; class Belongs : public virtual Edge { public: Instance& instance () const { return *instance_; } Type& type () const { return *type_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Belongs () { type_info (static_type_info ()); } void set_left_node (Instance& n) { instance_ = &n; } void set_right_node (Type& n) { type_ = &n; } private: Instance* instance_; Type* type_; }; // // class Arguments; class ArgumentsWithType; class ArgumentsWithValue; class Specialization: public virtual Type { typedef std::vector Arguments_; public: typedef Arguments_::const_iterator ArgumentsIterator; ArgumentsIterator arguments_begin () const { return arguments_.begin (); } ArgumentsIterator arguments_end () const { return arguments_.end (); } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Specialization () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Specialization () = 0; void add_edge_right (ArgumentsWithType& e); void add_edge_right (ArgumentsWithValue& e); private: Arguments_ arguments_; }; class Arguments: public virtual Edge { public: Specialization& specialization () const { return *specialization_; } Node& argument () const { return *argument_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Arguments () { type_info (static_type_info ()); } void set_left_node (Node& n) { argument_ = &n; } void set_right_node (Specialization& n) { specialization_ = &n; } private: Specialization* specialization_; Node* argument_; }; class ArgumentsWithType: public virtual Arguments { public: Type& type () const { return dynamic_cast (argument ()); } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; ArgumentsWithType () { type_info (static_type_info ()); } void set_left_node (Type& n) { Arguments::set_left_node (n); } }; class Expression; class ArgumentsWithValue: public virtual Arguments { public: Expression& value () const; static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; ArgumentsWithValue () { type_info (static_type_info ()); } void set_left_node (Expression& n); }; // // // class IsA : public virtual Edge { public: virtual Type& subject () const { return *subject_; } virtual Type& object () const { return *object_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; IsA () { type_info (static_type_info ()); } void set_left_node (Type& n) { subject_ = &n; } void set_right_node (Type& n) { object_ = &n; } private: Type* subject_; Type* object_; }; // // // class Inherits : public virtual IsA { public: virtual Type& inheritor () const { return subject (); } virtual Type& inheritee () const { return object (); } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Inherits () { type_info (static_type_info ()); } }; // // class Expression; class Const; class Initializes: public virtual Edge { public: Expression& expression () const { return *expression_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Initializes () { type_info (static_type_info ()); } void set_left_node (Expression& e) { expression_ = &e; } void set_right_node (Const&) { } private: Expression* expression_; }; class Expression: public virtual Node { public: static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Expression () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Expression () = 0; void add_edge_left (Initializes&) { } void add_edge_left (ArgumentsWithValue&) { } }; class Const: public virtual Instance, public virtual Nameable, public virtual Expression { public: Initializes& initialized () const { return *initialized_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Const () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Const () = 0; using Instance::add_edge_left; using Expression::add_edge_left; void add_edge_right (Initializes& i) { initialized_ = &i; } using Nameable::add_edge_right; private: Initializes* initialized_; }; // // // class Container; class Contains : public virtual Edge { public: Node& element () const { return *element_; } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Contains () { type_info (static_type_info ()); } void set_left_node (Container& n) { container_ = &n; } void set_right_node (Node& n) { element_ = &n; } private: Container* container_; Node* element_; }; class Container : public virtual Node { typedef std::vector Contains_; public: typedef Contains_::const_iterator ContainsIterator; ContainsIterator contains_begin () const { return contains_.begin (); } ContainsIterator contains_end () const { return contains_.end (); } static Introspection::TypeInfo const& static_type_info (); protected: friend class Graph; Container () // For virtual inheritance only. { type_info (static_type_info ()); } virtual ~Container () = 0; void add_edge_left (Contains& e) { contains_.push_back (&e); } private: Contains_ contains_; }; } } } // ADL won't find it because Path is a typedef. Note that this // function prints in native format. // std::ostream& operator<< (std::ostream& os, CCF::IDL2::SemanticGraph::Path const& path); #include "CCF/IDL2/SemanticGraph/Elements.tpp" #endif // CCF_IDL2_SEMANTIC_GRAPH_ELEMENTS_HPP